+2018-05-10 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (ix86_expand_builtin) <case IX86_BUILTIN_RDPID>:
+ Generate SImode target register for null target.
+ <case IX86_BUILTIN_XGETBV>: Ditto.
+ <case IX86_BUILTIN_XSETBV>: Optimize LSHIFTRT generation.
+ * config/i386/xsaveintrin.h (_xgetbv): Add missing return.
+
2018-05-10 Carl Love <cel@us.ibm.com>
* config/rs6000/rs6000.md (prefetch): Generate ISA 2.06 instructions
case IX86_BUILTIN_RDPID:
- op0 = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
+ op0 = gen_reg_rtx (word_mode);
if (TARGET_64BIT)
{
}
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:
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)
{
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)
/* { 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);