OSDN Git Service

Add BMI testcases.
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Jul 2011 17:45:41 +0000 (17:45 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Jul 2011 17:45:41 +0000 (17:45 +0000)
2011-07-27  Yukhin Kirill  <kirill.yukhin@intel.com>

* gcc.target/i386/i386.exp (check_effective_target_bmi): New.
* gcc.target/i386/bmi-andn-1.c: New test.
* gcc.target/i386/bmi-andn-1a.c: Likewise.
* gcc.target/i386/bmi-andn-2.c: Likewise.
* gcc.target/i386/bmi-andn-2a.c: Likewise.
* gcc.target/i386/bmi-bextr-1.c: Likewise.
* gcc.target/i386/bmi-bextr-1a.c: Likewise.
* gcc.target/i386/bmi-bextr-2.c: Likewise.
* gcc.target/i386/bmi-bextr-2a.c: Likewise.
* gcc.target/i386/bmi-blsi-1.c: Likewise.
* gcc.target/i386/bmi-blsi-1a.c: Likewise.
* gcc.target/i386/bmi-blsi-2.c: Likewise.
* gcc.target/i386/bmi-blsi-2a.c: Likewise.
* gcc.target/i386/bmi-blsmsk-1.c: Likewise.
* gcc.target/i386/bmi-blsmsk-1a.c: Likewise.
* gcc.target/i386/bmi-blsmsk-2.c: Likewise.
* gcc.target/i386/bmi-blsmsk-2a.c: Likewise.
* gcc.target/i386/bmi-blsr-1.c: Likewise.
* gcc.target/i386/bmi-blsr-1a.c: Likewise.
* gcc.target/i386/bmi-blsr-2.c: Likewise.
* gcc.target/i386/bmi-blsr-2a.c: Likewise.
* gcc.target/i386/bmi-tzcnt-1.c: Likewise.
* gcc.target/i386/bmi-tzcnt-1a.c: Likewise.
* gcc.target/i386/bmi-tzcnt-2.c: Likewise.
* gcc.target/i386/bmi-tzcnt-2a.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176840 138bc75d-0d04-0410-961f-82ee72b054a4

27 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/bmi-andn-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-andn-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-andn-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-andn-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-bextr-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-bextr-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-bextr-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-bextr-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsi-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsi-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsi-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsmsk-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsmsk-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsmsk-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsmsk-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsr-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsr-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsr-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-blsr-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-check.h [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-tzcnt-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-tzcnt-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-tzcnt-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bmi-tzcnt-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/i386.exp

index ab08df1..30c86ef 100644 (file)
@@ -1,3 +1,31 @@
+2011-07-27  Yukhin Kirill  <kirill.yukhin@intel.com>
+
+       * gcc.target/i386/i386.exp (check_effective_target_bmi): New.
+       * gcc.target/i386/bmi-andn-1.c: New test.
+       * gcc.target/i386/bmi-andn-1a.c: Likewise.
+       * gcc.target/i386/bmi-andn-2.c: Likewise.
+       * gcc.target/i386/bmi-andn-2a.c: Likewise.
+       * gcc.target/i386/bmi-bextr-1.c: Likewise.
+       * gcc.target/i386/bmi-bextr-1a.c: Likewise.
+       * gcc.target/i386/bmi-bextr-2.c: Likewise.
+       * gcc.target/i386/bmi-bextr-2a.c: Likewise.
+       * gcc.target/i386/bmi-blsi-1.c: Likewise.
+       * gcc.target/i386/bmi-blsi-1a.c: Likewise.
+       * gcc.target/i386/bmi-blsi-2.c: Likewise.
+       * gcc.target/i386/bmi-blsi-2a.c: Likewise.
+       * gcc.target/i386/bmi-blsmsk-1.c: Likewise.
+       * gcc.target/i386/bmi-blsmsk-1a.c: Likewise.
+       * gcc.target/i386/bmi-blsmsk-2.c: Likewise.
+       * gcc.target/i386/bmi-blsmsk-2a.c: Likewise.
+       * gcc.target/i386/bmi-blsr-1.c: Likewise.
+       * gcc.target/i386/bmi-blsr-1a.c: Likewise.
+       * gcc.target/i386/bmi-blsr-2.c: Likewise.
+       * gcc.target/i386/bmi-blsr-2a.c: Likewise.
+       * gcc.target/i386/bmi-tzcnt-1.c: Likewise.
+       * gcc.target/i386/bmi-tzcnt-1a.c: Likewise.
+       * gcc.target/i386/bmi-tzcnt-2.c: Likewise.
+       * gcc.target/i386/bmi-tzcnt-2a.c: Likewise.
+
 2011-07-27  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR middle-end/47691
diff --git a/gcc/testsuite/gcc.target/i386/bmi-andn-1.c b/gcc/testsuite/gcc.target/i386/bmi-andn-1.c
new file mode 100644 (file)
index 0000000..bf0685a
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do run { target { bmi && { ! ia32 } } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+long long calc_andn_u64 (long long src1,
+                        long long src2,
+                        long long dummy)
+{
+  return (~src1 + dummy) & (src2);
+}
+
+static void
+bmi_test()
+{
+  unsigned i;
+
+  long long src = 0xfacec0ffeefacec0;
+  long long res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_andn_u64 (src, src+i, 0);
+    res = __andn_u64 (src, src+i);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-andn-1a.c b/gcc/testsuite/gcc.target/i386/bmi-andn-1a.c
new file mode 100644 (file)
index 0000000..a7ee076
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-andn-1.c"
+
+/* { dg-final { scan-assembler-times "bmi_andn_di" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-andn-2.c b/gcc/testsuite/gcc.target/i386/bmi-andn-2.c
new file mode 100644 (file)
index 0000000..bb998f3
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run { target { bmi } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+long long calc_andn_u32 (int src1, int src2, int dummy)
+{
+  return (~src1+dummy) & (src2);
+}
+
+static void
+bmi_test()
+{
+  unsigned i;
+
+  int src = 0xfacec0ff;
+  int res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_andn_u32 (src, src+i, 0);
+    res = __andn_u32 (src, src+i);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-andn-2a.c b/gcc/testsuite/gcc.target/i386/bmi-andn-2a.c
new file mode 100644 (file)
index 0000000..72fe026
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-andn-2.c"
+
+/* { dg-final { scan-assembler-times "bmi_andn_si" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-bextr-1.c b/gcc/testsuite/gcc.target/i386/bmi-bextr-1.c
new file mode 100644 (file)
index 0000000..4abe63e
--- /dev/null
@@ -0,0 +1,49 @@
+/* { dg-do run { target { bmi && { ! ia32 } } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+long long calc_bextr_u64 (unsigned long long src1,
+                         unsigned long long src2)
+{
+  long long res = 0;
+  unsigned char start = (src2 & 0xff);
+  unsigned char len = (int) ((src2 >> 8) & 0xff);
+  if (start < 64) {
+    unsigned i;
+    unsigned last = (start+len) < 64 ? start+len : 64;
+
+    src1 >>= start;
+    for (i=start; i<last; ++i) {
+      res |= (src1 & 1) << (i-start);
+      src1 >>= 1;
+    }
+  }
+
+  return res;
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  unsigned char start, len;
+  unsigned long long src1 = 0xfacec0ffeefacec0;
+  unsigned long long res, res_ref, src2;
+
+  for (i=0; i<5; ++i) {
+    start = (i * 1983) % 64;
+    len = i + (i * 1983) % 64;
+
+    src1 = src1 * 3;
+    src2 = start | (((long long)len) << 8);
+
+    res_ref = calc_bextr_u64 (src1, src2);
+    res = __bextr_u64 (src1, src2);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-bextr-1a.c b/gcc/testsuite/gcc.target/i386/bmi-bextr-1a.c
new file mode 100644 (file)
index 0000000..4ccfbdc
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-bextr-1.c"
+
+/* { dg-final { scan-assembler-times "bmi_bextr_di" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-bextr-2.c b/gcc/testsuite/gcc.target/i386/bmi-bextr-2.c
new file mode 100644 (file)
index 0000000..2ce6259
--- /dev/null
@@ -0,0 +1,49 @@
+/* { dg-do run { target { bmi } } } */
+/* { dg-require-effective-target bmi  } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+unsigned calc_bextr_u32 (unsigned src1, unsigned src2)
+{
+  unsigned res = 0;
+  unsigned char start = (src2 & 0xff);
+  unsigned char len = (int) ((src2 >> 8) & 0xff);
+  if (start < 32) {
+    unsigned i;
+    unsigned last = (start+len) < 32 ? start+len : 32;
+
+    src1 >>= start;
+    for (i=start; i<last; ++i) {
+      res |= (src1 & 1) << (i-start);
+      src1 >>= 1;
+    }
+  }
+
+  return res;
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  unsigned char start, len;
+  unsigned src1 = 0xfacec0ff;
+  unsigned res, res_ref, src2;
+
+  for (i=0; i<5; ++i) {
+    start = (i * 1983) % 32;
+    len = i + (i * 1983) % 32;
+
+    src1 = src1 * 3;
+    src2 = start | (((unsigned)len) << 8);
+
+    res_ref = calc_bextr_u32 (src1, src2);
+    res = __bextr_u32 (src1, src2);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-bextr-2a.c b/gcc/testsuite/gcc.target/i386/bmi-bextr-2a.c
new file mode 100644 (file)
index 0000000..282a3e4
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-bextr-2.c"
+
+/* { dg-final { scan-assembler-times "bmi_bextr_si" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsi-1.c b/gcc/testsuite/gcc.target/i386/bmi-blsi-1.c
new file mode 100644 (file)
index 0000000..e7f2c89
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run { target { bmi && { ! ia32 } } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+/* To fool compiler, so it not generate blsi here. */
+long long calc_blsi_u64 (long long src1, long long src2)
+{
+  return (-src1) & (src2);
+}
+
+static void
+bmi_test()
+{
+  unsigned i;
+
+  long long src = 0xfacec0ffeefacec0;
+  long long res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_blsi_u64 (src, src);
+    res = __blsi_u64 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsi-1a.c b/gcc/testsuite/gcc.target/i386/bmi-blsi-1a.c
new file mode 100644 (file)
index 0000000..e9e0ecb
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-blsi-1.c"
+
+/* { dg-final { scan-assembler-times "bmi_blsi_di" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsi-2.c b/gcc/testsuite/gcc.target/i386/bmi-blsi-2.c
new file mode 100644 (file)
index 0000000..b6633a9
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run { target { bmi } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+/* To fool compiler, so it not generate blsi here. */
+int calc_blsi_u32 (int src1, int src2)
+{
+  return (-src1) & (src2);
+}
+
+static void
+bmi_test()
+{
+  unsigned i;
+  int src = 0xfacec0ff;
+  int res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_blsi_u32 (src, src);
+    res = __blsi_u32 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsi-2a.c b/gcc/testsuite/gcc.target/i386/bmi-blsi-2a.c
new file mode 100644 (file)
index 0000000..be9ca3f
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-blsi-2.c"
+
+/* { dg-final { scan-assembler-times "bmi_blsi_si" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsmsk-1.c b/gcc/testsuite/gcc.target/i386/bmi-blsmsk-1.c
new file mode 100644 (file)
index 0000000..5498007
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run { target { bmi && { ! ia32 } } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+/*  Trick compiler in order not to generate target insn here. */
+long long calc_blsmsk_u64 (long long src1, long long src2)
+{
+  return (src1-1) ^ (src2);
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  long long src = 0xfacec0ffeefacec0;
+  long long res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_blsmsk_u64 (src, src);
+    res = __blsmsk_u64 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsmsk-1a.c b/gcc/testsuite/gcc.target/i386/bmi-blsmsk-1a.c
new file mode 100644 (file)
index 0000000..4e6cb7b
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-blsmsk-1.c"
+
+/* { dg-final { scan-assembler-times "bmi_blsmsk_di" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsmsk-2.c b/gcc/testsuite/gcc.target/i386/bmi-blsmsk-2.c
new file mode 100644 (file)
index 0000000..be0ebf9
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run { target { bmi } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+/*  Trick compiler in order not to generate target insn here. */
+int calc_blsmsk_u32 (int src1, int src2)
+{
+  return (src1-1) ^ (src2);
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  int src = 0xfacec0ff;
+  int res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_blsmsk_u32 (src, src);
+    res = __blsmsk_u32 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsmsk-2a.c b/gcc/testsuite/gcc.target/i386/bmi-blsmsk-2a.c
new file mode 100644 (file)
index 0000000..f6f6bab
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-blsmsk-2.c"
+
+/* { dg-final { scan-assembler-times "bmi_blsmsk_si" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsr-1.c b/gcc/testsuite/gcc.target/i386/bmi-blsr-1.c
new file mode 100644 (file)
index 0000000..68e01f3
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do run { target { bmi && { ! ia32 } } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+long long calc_blsr_u64 (long long src1, long long src2)
+{
+  return (src1-1) & (src2);
+}
+
+static void
+bmi_test()
+{
+  unsigned i;
+  long long src = 0xfacec0ffeefacec0;
+  long long res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_blsr_u64 (src, src);
+    res = __blsr_u64 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsr-1a.c b/gcc/testsuite/gcc.target/i386/bmi-blsr-1a.c
new file mode 100644 (file)
index 0000000..79241ca
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-blsr-1.c"
+
+/* { dg-final { scan-assembler-times "bmi_blsr_di" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsr-2.c b/gcc/testsuite/gcc.target/i386/bmi-blsr-2.c
new file mode 100644 (file)
index 0000000..b3fc4e5
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do run { target { bmi } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+int calc_blsr_u32 (int src1, int src2)
+{
+  return (src1-1) & (src2);
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  int src = 0xfacec0ff;
+  int res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_blsr_u32 (src, src);
+    res = __blsr_u32 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-blsr-2a.c b/gcc/testsuite/gcc.target/i386/bmi-blsr-2a.c
new file mode 100644 (file)
index 0000000..d88c16e
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-inline -dp" } */
+
+#include "bmi-blsr-2.c"
+
+/* { dg-final { scan-assembler-times "bmi_blsr_si" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-check.h b/gcc/testsuite/gcc.target/i386/bmi-check.h
new file mode 100644 (file)
index 0000000..8fad38a
--- /dev/null
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cpuid.h"
+
+static void bmi_test (void);
+
+static void
+__attribute__ ((noinline))
+do_test (void)
+{
+  bmi_test ();
+}
+
+int
+main ()
+{
+  unsigned int eax, ebx, ecx, edx;
+
+  if (__get_cpuid_max (0, NULL) < 7)
+    return 0;
+
+  __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+  /* Run BMI test only if host has BMI support.  */
+  if (ebx & bit_BMI)
+    {
+      do_test ();
+#ifdef DEBUG
+    printf ("PASSED\n");
+#endif
+    }
+#ifdef DEBUG
+  else
+    printf ("SKIPPED\n");
+#endif
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-tzcnt-1.c b/gcc/testsuite/gcc.target/i386/bmi-tzcnt-1.c
new file mode 100644 (file)
index 0000000..a9fce15
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run { target { bmi && { ! ia32 } } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+long long calc_tzcnt_u64 (long long src)
+{
+  int i;
+  int res = 0;
+
+  while ( (res<64) && ((src&1) == 0)) {
+    ++res;
+    src >>= 1;
+  }
+
+  return res;
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  long long src = 0xfacec0ffeefacec0;
+  long long res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_tzcnt_u64 (src);
+    res = __tzcnt_u64 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-tzcnt-1a.c b/gcc/testsuite/gcc.target/i386/bmi-tzcnt-1a.c
new file mode 100644 (file)
index 0000000..e283c31
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include "bmi-tzcnt-1.c"
+
+/* { dg-final { scan-assembler-times "tzcntq" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/bmi-tzcnt-2.c b/gcc/testsuite/gcc.target/i386/bmi-tzcnt-2.c
new file mode 100644 (file)
index 0000000..1a9235b
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do run { target { bmi } } } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+int calc_tzcnt_u32 (int src)
+{
+  int i;
+  int res = 0;
+
+  while ( (res<32) && ((src&1) == 0)) {
+    ++res;
+    src >>= 1;
+  }
+  return res;
+}
+
+static void
+bmi_test ()
+{
+  unsigned i;
+  int src = 0xfacec0ff;
+  int res, res_ref;
+
+  for (i=0; i<5; ++i) {
+    src = i + src << i;
+
+    res_ref = calc_tzcnt_u32 (src);
+    res = __tzcnt_u32 (src);
+
+    if (res != res_ref)
+      abort();
+  }
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi-tzcnt-2a.c b/gcc/testsuite/gcc.target/i386/bmi-tzcnt-2a.c
new file mode 100644 (file)
index 0000000..2cdb3f4
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-inline" } */
+
+#include "bmi-tzcnt-2.c"
+
+/* { dg-final { scan-assembler-times "tzcntl" 1 } } */
index 32dbf5e..86c7549 100644 (file)
@@ -186,6 +186,16 @@ proc check_effective_target_xop { } {
     } "-O2 -mxop" ]
 }
 
+# Return 1 if bmi instructions can be compiled.
+proc check_effective_target_bmi { } {
+    return [check_no_compiler_messages bmi object {
+       void __bextr_u32 (void)
+       {
+         __builtin_ia32_bextr_u32 (0, 0);
+       }
+    } "-mbmi" ]
+}
+
 # If the linker used understands -M <mapfile>, pass it to clear hardware
 # capabilities set by the Sun assembler.
 set clearcap_ldflags "-Wl,-M,$srcdir/$subdir/clearcap.map"