1 /* { dg-do run { target { bmi2 && { ! ia32 } } } } */
2 /* { dg-options "-mbmi2 -O2" } */
3
4 #include <x86intrin.h>
5 #include "bmi2-check.h"
6
7 __attribute__((noinline))
8 unsigned __int128
calc_mul_u64(unsigned long long volatile a,unsigned long long b)9 calc_mul_u64 (unsigned long long volatile a, unsigned long long b)
10 {
11 unsigned __int128 res = 0;
12 int i;
13 for (i = 0; i < b; ++i)
14 res += (unsigned __int128) a;
15
16 return res;
17 }
18
19 __attribute__((noinline))
20 unsigned long long
calc_mulx_u64(unsigned long long x,unsigned long long y,unsigned long long * res_h)21 calc_mulx_u64 (unsigned long long x,
22 unsigned long long y,
23 unsigned long long *res_h)
24 {
25 return _mulx_u64 (x, y, res_h);
26 }
27
28
29 static void
bmi2_test()30 bmi2_test ()
31 {
32 unsigned i;
33 unsigned long long a = 0xce7ace0ce7ace0;
34 unsigned long long b = 0xface;
35 unsigned long long res_l, res_h;
36 unsigned __int128 res, res_ref;
37
38 for (i=0; i<5; ++i) {
39 a = a * (i + 1);
40 b = b / (i + 1);
41
42 res_ref = calc_mul_u64 (a, b);
43
44 res_l = calc_mulx_u64 (a, b, &res_h);
45
46 res = ((unsigned __int128) res_h << 64) | res_l;
47
48 if (res != res_ref)
49 abort();
50 }
51 }
52