]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add MULX intrinsics.
authorKirill Yukhin <kirill.yukhin@intel.com>
Wed, 21 Sep 2011 15:57:04 +0000 (15:57 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 21 Sep 2011 15:57:04 +0000 (08:57 -0700)
gcc/

2011-09-21  Kirill Yukhin  <kirill.yukhin@intel.com>

* config/i386/bmi2intrin.h (_mulx_u64): New.
(_mulx_u32): Ditto.

gcc/testsuite/

2011-09-21  Kirill Yukhin  <kirill.yukhin@intel.com>

* gcc.target/i386/bmi2-mulx32-2.c: New test.
* gcc.target/i386/bmi2-mulx32-2a.c: Ditto.
* gcc.target/i386/bmi2-mulx64-2.c: Ditto.
* gcc.target/i386/bmi2-mulx64-2a.c: Ditto.

From-SVN: r179050

gcc/ChangeLog
gcc/config/i386/bmi2intrin.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/bmi2-mulx32-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi2-mulx32-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi2-mulx64-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi2-mulx64-2a.c [new file with mode: 0644]

index 0f4aa869b346e6bfb3bf9767f3fd79e3a669b836..8a3c23adf565a74c931a16dc1ab49fc0c15e0171 100644 (file)
@@ -1,3 +1,8 @@
+2011-09-21  Kirill Yukhin  <kirill.yukhin@intel.com>
+
+       * config/i386/bmi2intrin.h (_mulx_u64): New.
+       (_mulx_u32): Ditto.
+
 2011-09-21  Jan Hubicka  <jh@suse.cz>
 
        PR tree-optimization/50433
index a72c9a985eefa067a9668a91f3433d45b08ee289..4c13a70adabe735cc86187fe0fe6cfdb46b0f553 100644 (file)
@@ -76,6 +76,27 @@ _pext_u64 (unsigned long long __X, unsigned long long __Y)
   return __builtin_ia32_pext_di (__X, __Y);
 }
 
-#endif /* __x86_64__  */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mulx_u64 (unsigned long long __X, unsigned long long __Y,
+          unsigned long long *__P)
+{
+  unsigned __int128 __res = (unsigned __int128) __X * __Y;
+  *__P = (unsigned long long) (__res >> 64);
+  return (unsigned long long) __res;
+}
+
+#else /* !__x86_64__ */
+
+extern __inline unsigned int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mulx_u32 (unsigned int __X, unsigned int __Y, unsigned int *__P)
+{
+  unsigned long long __res = (unsigned long long) __X * __Y;
+  *__P = (unsigned int) (__res >> 32);
+  return (unsigned int) __res;
+}
+
+#endif /* !__x86_64__  */
 
 #endif /* _BMI2INTRIN_H_INCLUDED */
index bfdfe4404618e08c717f1c9d1abdb8871e0c85e2..7022c0b17cbd53458272b5e39afa8facb09bda69 100644 (file)
@@ -1,3 +1,10 @@
+2011-09-21  Kirill Yukhin  <kirill.yukhin@intel.com>
+
+       * gcc.target/i386/bmi2-mulx32-2.c: New test.
+       * gcc.target/i386/bmi2-mulx32-2a.c: Ditto.
+       * gcc.target/i386/bmi2-mulx64-2.c: Ditto.
+       * gcc.target/i386/bmi2-mulx64-2a.c: Ditto.
+
 2011-09-21  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/opt19.adb: New test.
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-mulx32-2.c b/gcc/testsuite/gcc.target/i386/bmi2-mulx32-2.c
new file mode 100644 (file)
index 0000000..c9f159e
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do run { target { bmi2 && { ia32 } } } } */
+/* { dg-options "-mbmi2 -O2" } */
+
+#include <x86intrin.h>
+
+#include "bmi2-check.h"
+
+__attribute__((noinline))
+unsigned long long
+calc_mul_u32 (unsigned volatile a, unsigned b)
+{
+  unsigned long long res = 0;
+  int i;
+  for (i = 0; i < b; ++i)
+    res += a;
+
+  return res;
+}
+
+__attribute__((noinline))
+unsigned calc_mulx_u32 (unsigned x, unsigned y, unsigned *res_h)
+{
+  return (unsigned) _mulx_u32 (x, y, res_h);
+}
+
+static void
+bmi2_test ()
+{
+  unsigned i;
+  unsigned a = 0xce7ace0;
+  unsigned b = 0xfacefff;
+  unsigned res_l, res_h;
+  unsigned long long res, res_ref;
+
+  for (i = 0; i < 5; ++i) {
+    a = a * (i + 1);
+    b = b / (i + 1);
+
+    res_ref = calc_mul_u32 (a, b);
+    res_l = calc_mulx_u32 (a, b, &res_h);
+
+    res = ((unsigned long long) res_h << 32) | res_l;
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-mulx32-2a.c b/gcc/testsuite/gcc.target/i386/bmi2-mulx32-2a.c
new file mode 100644 (file)
index 0000000..356d593
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -mbmi2" } */
+
+#include "bmi2-mulx32-2.c"
+
+/* { dg-final { scan-assembler-times "mulx\[ \\t\]+\[^\n\]*" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-mulx64-2.c b/gcc/testsuite/gcc.target/i386/bmi2-mulx64-2.c
new file mode 100644 (file)
index 0000000..55b3554
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do run { target { bmi2 && { ! ia32 } } } } */
+/* { dg-options "-mbmi2 -O2" } */
+
+#include <x86intrin.h>
+#include "bmi2-check.h"
+
+__attribute__((noinline))
+unsigned __int128
+calc_mul_u64 (unsigned long long volatile a, unsigned long long b)
+{
+  unsigned __int128 res = 0;
+  int i;
+  for (i = 0; i < b; ++i)
+    res += (unsigned __int128) a;
+
+  return res;
+}
+
+__attribute__((noinline))
+unsigned long long
+calc_mulx_u64 (unsigned long long x,
+              unsigned long long y,
+              unsigned long long *res_h)
+{
+  return _mulx_u64 (x, y, res_h);
+}
+
+
+static void
+bmi2_test ()
+{
+  unsigned i;
+  unsigned long long a = 0xce7ace0ce7ace0;
+  unsigned long long b = 0xface;
+  unsigned long long res_l, res_h;
+  unsigned __int128 res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    a = a * (i + 1);
+    b = b / (i + 1);
+
+    res_ref = calc_mul_u64 (a, b);
+
+    res_l = calc_mulx_u64 (a, b, &res_h);
+
+    res = ((unsigned __int128) res_h << 64) | res_l;
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-mulx64-2a.c b/gcc/testsuite/gcc.target/i386/bmi2-mulx64-2a.c
new file mode 100644 (file)
index 0000000..d8b3e0e
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi2" } */
+
+#include "bmi2-mulx64-2.c"
+
+/* { dg-final { scan-assembler-times "mulx\[ \\t\]+\[^\n\]*" 1 } } */