Add missing Broadwell intrinsics.

Ilya Tocar tocarip.intel@gmail.com
Tue Sep 2 12:36:00 GMT 2014


Hi,

Along with intrinsics for adcx/adox (supported since 4.8) ICC also
added intrinsics for adc/sbb [1]. This patch adds them.
Bootstraps/passes make-check. Ok for trunk?

[1] http://www.xlsoft.com/jp/products/intel/compilers/ccm/2013/Release_Notes_u3.pdf

ChangeLog below:

gcc/

2014-09-02  Ilya Tocar  <ilya.tocar@intel.com>

	* config/i386/adxintrin.h (_subborrow_u32): New.
	(_addcarry_u32): Ditto.
	(_subborrow_u64): Ditto.
	(_addcarry_u64): Ditto.
	* config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_SBB32,
	IX86_BUILTIN_SBB64.
	(ix86_init_mmx_sse_builtins): Handle __builtin_ia32_sbb_u32,
	__builtin_ia32_sbb_u64


testsuite/

2014-09-02  Ilya Tocar  <ilya.tocar@intel.com>

	* gcc.target/i386/adx-addcarryx32-1.c: Test addcarry, subborrow.
	* gcc.target/i386/adx-addcarryx32-2.c: Ditto.
	* gcc.target/i386/adx-addcarryx32-3.c: Ditto.
	* gcc.target/i386/adx-addcarryx64-1.c: Ditto.
	* gcc.target/i386/adx-addcarryx64-2.c: Ditto.
	* gcc.target/i386/adx-addcarryx64-3.c: Ditto.

---
 gcc/config/i386/adxintrin.h                       | 32 +++++++++++++++++++++++
 gcc/config/i386/i386.c                            | 22 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c |  5 +++-
 gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c | 27 +++++++++++++++++++
 gcc/testsuite/gcc.target/i386/adx-addcarryx32-3.c |  5 +++-
 gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c |  5 +++-
 gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c | 27 +++++++++++++++++++
 gcc/testsuite/gcc.target/i386/adx-addcarryx64-3.c |  5 +++-
 8 files changed, 124 insertions(+), 4 deletions(-)

diff --git a/gcc/config/i386/adxintrin.h b/gcc/config/i386/adxintrin.h
index 6118900..8f2c01a 100644
--- a/gcc/config/i386/adxintrin.h
+++ b/gcc/config/i386/adxintrin.h
@@ -30,6 +30,22 @@
 
 extern __inline unsigned char
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_subborrow_u32 (unsigned char __CF, unsigned int __X,
+	        unsigned int __Y, unsigned int *__P)
+{
+    return __builtin_ia32_sbb_u32 (__CF, __Y, __X, __P);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_addcarry_u32 (unsigned char __CF, unsigned int __X,
+	       unsigned int __Y, unsigned int *__P)
+{
+    return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _addcarryx_u32 (unsigned char __CF, unsigned int __X,
 		unsigned int __Y, unsigned int *__P)
 {
@@ -39,6 +55,22 @@ _addcarryx_u32 (unsigned char __CF, unsigned int __X,
 #ifdef __x86_64__
 extern __inline unsigned char
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_subborrow_u64 (unsigned char __CF, unsigned long __X,
+	        unsigned long __Y, unsigned long long *__P)
+{
+    return __builtin_ia32_sbb_u64 (__CF, __Y, __X, __P);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_addcarry_u64 (unsigned char __CF, unsigned long __X,
+	       unsigned long __Y, unsigned long long *__P)
+{
+    return __builtin_ia32_addcarryx_u64 (__CF, __X, __Y, __P);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _addcarryx_u64 (unsigned char __CF, unsigned long __X,
 		unsigned long __Y, unsigned long long *__P)
 {
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3e4c93e..91b5d06 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -28778,6 +28778,10 @@ enum ix86_builtins
   IX86_BUILTIN_ADDCARRYX32,
   IX86_BUILTIN_ADDCARRYX64,
 
+  /* ADC/SBB instructions.  */
+  IX86_BUILTIN_SBB32,
+  IX86_BUILTIN_SBB64,
+
   /* FSGSBASE instructions.  */
   IX86_BUILTIN_RDFSBASE32,
   IX86_BUILTIN_RDFSBASE64,
@@ -31213,6 +31217,14 @@ ix86_init_mmx_sse_builtins (void)
 	       UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
 	       IX86_BUILTIN_ADDCARRYX64);
 
+  /* ADX/SBB */
+  def_builtin (0, "__builtin_ia32_sbb_u32",
+	       UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_SBB32);
+  def_builtin (OPTION_MASK_ISA_64BIT,
+	       "__builtin_ia32_sbb_u64",
+	       UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
+	       IX86_BUILTIN_SBB64);
+
   /* Read/write FLAGS.  */
   def_builtin (~OPTION_MASK_ISA_64BIT, "__builtin_ia32_readeflags_u32",
                UNSIGNED_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
@@ -35617,6 +35629,16 @@ rdseed_step:
       emit_insn (gen_zero_extendqisi2 (target, op2));
       return target;
 
+    case IX86_BUILTIN_SBB32:
+      icode = CODE_FOR_subsi3_carry;
+      mode0 = SImode;
+      goto addcarryx;
+
+    case IX86_BUILTIN_SBB64:
+      icode = CODE_FOR_subdi3_carry;
+      mode0 = DImode;
+      goto addcarryx;
+
     case IX86_BUILTIN_ADDCARRYX32:
       icode = TARGET_ADX ? CODE_FOR_adcxsi3 : CODE_FOR_addsi3_carry;
       mode0 = SImode;
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c
index daf5779..9fff611 100644
--- a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c
+++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-madx -O2" } */
-/* { dg-final { scan-assembler "adcx" } } */
+/* { dg-final { scan-assembler-times "adcx" 2 } } */
+/* { dg-final { scan-assembler-times "sbbl" 1 } } */
 
 #include <x86intrin.h>
 
@@ -12,4 +13,6 @@ void extern
 adx_test (void)
 {
     c = _addcarryx_u32 (c, x, y, sum);
+    c = _addcarry_u32 (c, x, y, sum);
+    c = _subborrow_u32 (c, x, y, sum);
 }
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c
index d38d7ee..b1da555 100644
--- a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c
+++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c
@@ -24,4 +24,31 @@ adx_test (void)
 
   if (x != sum_ref)
     abort ();
+
+  c = 0;
+  x = y = 0xFFFFFFFF;
+  sum_ref = 0xFFFFFFFE;
+
+  /* X = 0xFFFFFFFF, Y = 0xFFFFFFFF, C = 0.  */
+  c = _addcarry_u32 (c, x, y, &x);
+  /* X = 0xFFFFFFFE, Y = 0xFFFFFFFF, C = 1.  */
+  c = _addcarry_u32 (c, x, y, &x);
+  /* X = 0xFFFFFFFE, Y = 0xFFFFFFFF, C = 1.  */
+
+  if (x != sum_ref)
+    abort ();
+
+  c = 0;
+  x = 1;
+  y = 0;
+  sum_ref = 0x0;
+
+  /* X = 0x00000001, Y = 0x00000000, C = 0.  */
+  c = _subborrow_u32 (c, x, y, &x);
+  /* X = 0xFFFFFFFF, Y = 0x00000000, C = 1.  */
+  c = _subborrow_u32 (c, x, y, &x);
+  /* X = 0xFFFFFFFF, Y = 0xFFFFFFFF, C = 1.  */
+
+  if (x != sum_ref)
+    abort ();
 }
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-3.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-3.c
index 0ed33a9..d804867 100644
--- a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-3.c
+++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-3.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-mno-adx -O2" } */
-/* { dg-final { scan-assembler "adcl" } } */
+/* { dg-final { scan-assembler-times "adcl" 2 } } */
+/* { dg-final { scan-assembler-times "sbbl" 1 } } */
 
 #include <x86intrin.h>
 
@@ -12,4 +13,6 @@ void extern
 adx_test (void)
 {
     c = _addcarryx_u32 (c, x, y, sum);
+    c = _addcarry_u32 (c, x, y, sum);
+    c = _subborrow_u32 (c, x, y, sum);
 }
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c
index 45beca8..3608dea 100644
--- a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c
+++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c
@@ -1,6 +1,7 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-madx -O2" } */
-/* { dg-final { scan-assembler "adcx" } } */
+/* { dg-final { scan-assembler-times "adcx" 2 } } */
+/* { dg-final { scan-assembler-times "sbbq" 1 } } */
 
 #include <x86intrin.h>
 
@@ -12,4 +13,6 @@ void extern
 adx_test (void)
 {
     c = _addcarryx_u64 (c, x, y, sum);
+    c = _addcarry_u64 (c, x, y, sum);
+    c = _subborrow_u64 (c, x, y, sum);
 }
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c
index 6aa2539..b326291 100644
--- a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c
+++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c
@@ -24,4 +24,31 @@ adx_test (void)
 
   if (x != sum_ref)
     abort ();
+
+  c = 0;
+  x = y = 0xFFFFFFFFFFFFFFFFLL;
+  sum_ref = 0xFFFFFFFFFFFFFFFELL;
+
+  /* X = 0xFFFFFFFFFFFFFFFF, Y = 0xFFFFFFFFFFFFFFFF, C = 0.  */
+  c = _addcarry_u64 (c, x, y, &x);
+  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */
+  c = _addcarry_u64 (c, x, y, &x);
+  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */
+
+  if (x != sum_ref)
+    abort ();
+
+  c = 0;
+  x = 1LL;
+  y = 0LL;
+  sum_ref = 0x0LL;
+
+  /* X = 0x0000000000000001, Y = 0x0000000000000000, C = 0.  */
+  c = _subborrow_u64 (c, x, y, &x);
+  /* X = 0xFFFFFFFFFFFFFFFF, Y = 0x0000000000000000, C = 1.  */
+  c = _subborrow_u64 (c, x, y, &x);
+  /* X = 0x0000000000000000, Y = 0x0000000000000000, C = 1.  */
+
+  if (x != sum_ref)
+    abort ();
 }
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-3.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-3.c
index 4bbf74b..9d9809d 100644
--- a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-3.c
+++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-3.c
@@ -1,6 +1,7 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-mno-adx -O2" } */
-/* { dg-final { scan-assembler "adcq" } } */
+/* { dg-final { scan-assembler-times "adcq" 2 } } */
+/* { dg-final { scan-assembler-times "sbbq" 1 } } */
 
 #include <x86intrin.h>
 
@@ -12,4 +13,6 @@ void extern
 adx_test (void)
 {
     c = _addcarryx_u64 (c, x, y, sum);
+    c = _addcarry_u64 (c, x, y, sum);
+    c = _subborrow_u64 (c, x, y, sum);
 }
-- 
1.8.3.1



More information about the Gcc-patches mailing list