===================================================================
@@ -37085,7 +37085,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
case IX86_BUILTIN_RDPID:
- op0 = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
+ op0 = gen_reg_rtx (word_mode);
if (TARGET_64BIT)
{
@@ -37094,18 +37094,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
}
else
insn = gen_rdpid (op0);
+
emit_insn (insn);
- if (target == 0)
- {
- /* mode is VOIDmode if __builtin_rdpid has been called
- without lhs. */
- if (mode == VOIDmode)
- return target;
- target = gen_reg_rtx (mode);
- }
+ if (target == 0
+ || !register_operand (target, SImode))
+ target = gen_reg_rtx (SImode);
+
emit_move_insn (target, op0);
return target;
+
case IX86_BUILTIN_RDPMC:
case IX86_BUILTIN_RDTSC:
case IX86_BUILTIN_RDTSCP:
@@ -37164,14 +37162,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
emit_move_insn (gen_rtx_MEM (SImode, op4), op2);
}
- if (target == 0)
- {
- /* mode is VOIDmode if __builtin_rd* has been called
- without lhs. */
- if (mode == VOIDmode)
- return target;
- target = gen_reg_rtx (mode);
- }
+ if (target == 0
+ || !register_operand (target, DImode))
+ target = gen_reg_rtx (DImode);
if (TARGET_64BIT)
{
@@ -37260,25 +37253,23 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
if (!REG_P (op0))
op0 = copy_to_mode_reg (SImode, op0);
+ op1 = force_reg (DImode, op1);
+
if (TARGET_64BIT)
{
op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32),
NULL, 1, OPTAB_DIRECT);
+ icode = CODE_FOR_xsetbv_rex64;
+
op2 = gen_lowpart (SImode, op2);
op1 = gen_lowpart (SImode, op1);
- if (!REG_P (op1))
- op1 = copy_to_mode_reg (SImode, op1);
- if (!REG_P (op2))
- op2 = copy_to_mode_reg (SImode, op2);
- icode = CODE_FOR_xsetbv_rex64;
pat = GEN_FCN (icode) (op0, op1, op2);
}
else
{
- if (!REG_P (op1))
- op1 = copy_to_mode_reg (DImode, op1);
icode = CODE_FOR_xsetbv;
+
pat = GEN_FCN (icode) (op0, op1);
}
if (pat)
===================================================================
@@ -59,7 +59,7 @@ extern __inline long long
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_xgetbv (unsigned int __A)
{
- __builtin_ia32_xgetbv (__A);
+ return __builtin_ia32_xgetbv (__A);
}
#ifdef __x86_64__
===================================================================
@@ -1,13 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mxsave" } */
-/* { dg-final { scan-assembler "xgetbv" } } */
-/* { dg-final { scan-assembler "xsetbv" } } */
+/* { dg-final { scan-assembler-times "xgetbv" 3 } } */
+/* { dg-final { scan-assembler-times "xsetbv" 3 } } */
#include <x86intrin.h>
-unsigned int
-xgetsetbv (void)
+unsigned long long
+foo (unsigned x, unsigned y)
{
+ _xsetbv (x, y);
+ return _xgetbv (x);
+}
+
+unsigned long long
+bar (unsigned x, unsigned long long y)
+{
+ _xsetbv (x, y);
+ return _xgetbv (x);
+}
+
+unsigned long long
+baz (void)
+{
_xsetbv (0, 0);
return _xgetbv (0);
}