Commit 655d5157 by Kirill Yukhin Committed by H.J. Lu

Add MULX intrinsics.

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
parent 88cc02ff
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
......@@ -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 */
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.
......
/* { 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();
}
}
/* { dg-do compile { target { ia32 } } } */
/* { dg-options "-O2 -mbmi2" } */
#include "bmi2-mulx32-2.c"
/* { dg-final { scan-assembler-times "mulx\[ \\t\]+\[^\n\]*" 1 } } */
/* { 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();
}
}
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -mbmi2" } */
#include "bmi2-mulx64-2.c"
/* { dg-final { scan-assembler-times "mulx\[ \\t\]+\[^\n\]*" 1 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment