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