i386.c (IX86_BUILTIN_READ_FLAGS): New.
ChangeLog/ * config/i386/i386.c(IX86_BUILTIN_READ_FLAGS): New. (IX86_BUILTIN_WRITE_FLAGS): Ditto. (ix86_init_mmx_sse_builtins): Define __builtin_ia32_writeeflags_u32, __builtin_ia32_writeeflags_u64, __builtin_ia32_readeflags_u32, __builtin_ia32_readeflags_u64. (ix86_expand_builtin): Expand them. * config/i386/ia32intrin.h (__readeflags): New. (__writeeflags): Ditto. * gcc/config/i386/i386.md (*pushfl<mode>): Ditto. (*popfl<mode>1): Ditto. testsuite/ChangeLog/ * gcc.target/i386/readeflags-1.c: New. * gcc.target/i386/writeeflags-1.c: Ditto. From-SVN: r205703
This commit is contained in:
parent
46db94aa6a
commit
9bbd48d120
|
@ -1,3 +1,16 @@
|
|||
2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com>
|
||||
|
||||
* config/i386/i386.c(IX86_BUILTIN_READ_FLAGS): New.
|
||||
(IX86_BUILTIN_WRITE_FLAGS): Ditto.
|
||||
(ix86_init_mmx_sse_builtins): Define
|
||||
__builtin_ia32_writeeflags_u32, __builtin_ia32_writeeflags_u64,
|
||||
__builtin_ia32_readeflags_u32, __builtin_ia32_readeflags_u64.
|
||||
(ix86_expand_builtin): Expand them.
|
||||
* config/i386/ia32intrin.h (__readeflags): New.
|
||||
(__writeeflags): Ditto.
|
||||
* gcc/config/i386/i386.md (*pushfl<mode>): Ditto.
|
||||
(*popfl<mode>1): Ditto.
|
||||
|
||||
2013-12-05 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/59374
|
||||
|
|
|
@ -27920,6 +27920,10 @@ enum ix86_builtins
|
|||
IX86_BUILTIN_CPU_IS,
|
||||
IX86_BUILTIN_CPU_SUPPORTS,
|
||||
|
||||
/* Read/write FLAGS register built-ins. */
|
||||
IX86_BUILTIN_READ_FLAGS,
|
||||
IX86_BUILTIN_WRITE_FLAGS,
|
||||
|
||||
IX86_BUILTIN_MAX
|
||||
};
|
||||
|
||||
|
@ -29761,6 +29765,17 @@ ix86_init_mmx_sse_builtins (void)
|
|||
UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
|
||||
IX86_BUILTIN_ADDCARRYX64);
|
||||
|
||||
/* Read/write FLAGS. */
|
||||
def_builtin (~OPTION_MASK_ISA_64BIT, "__builtin_ia32_readeflags_u32",
|
||||
UNSIGNED_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
|
||||
def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_ia32_readeflags_u64",
|
||||
UINT64_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
|
||||
def_builtin (~OPTION_MASK_ISA_64BIT, "__builtin_ia32_writeeflags_u32",
|
||||
VOID_FTYPE_UNSIGNED, IX86_BUILTIN_WRITE_FLAGS);
|
||||
def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_ia32_writeeflags_u64",
|
||||
VOID_FTYPE_UINT64, IX86_BUILTIN_WRITE_FLAGS);
|
||||
|
||||
|
||||
/* Add FMA4 multi-arg argument instructions */
|
||||
for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
|
||||
{
|
||||
|
@ -33439,6 +33454,28 @@ addcarryx:
|
|||
emit_insn (gen_rtx_SET (VOIDmode, target, pat));
|
||||
return target;
|
||||
|
||||
case IX86_BUILTIN_READ_FLAGS:
|
||||
emit_insn (gen_push (gen_rtx_REG (word_mode, FLAGS_REG)));
|
||||
|
||||
if (target == NULL_RTX
|
||||
|| !register_operand (target, word_mode)
|
||||
|| GET_MODE (target) != word_mode)
|
||||
target = gen_reg_rtx (word_mode);
|
||||
|
||||
emit_insn (gen_pop (target));
|
||||
return target;
|
||||
|
||||
case IX86_BUILTIN_WRITE_FLAGS:
|
||||
|
||||
arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
op0 = expand_normal (arg0);
|
||||
if (!general_no_elim_operand (op0, word_mode))
|
||||
op0 = copy_to_mode_reg (word_mode, op0);
|
||||
|
||||
emit_insn (gen_push (op0));
|
||||
emit_insn (gen_pop (gen_rtx_REG (word_mode, FLAGS_REG)));
|
||||
return 0;
|
||||
|
||||
case IX86_BUILTIN_GATHERSIV2DF:
|
||||
icode = CODE_FOR_avx2_gathersiv2df;
|
||||
goto gather_gen;
|
||||
|
|
|
@ -1721,6 +1721,23 @@
|
|||
"pop{<imodesuffix>}\t%0"
|
||||
[(set_attr "type" "pop")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "*pushfl<mode>"
|
||||
[(set (match_operand:DWIH 0 "push_operand" "=<")
|
||||
(match_operand:DWIH 1 "flags_reg_operand"))]
|
||||
""
|
||||
"pushf{<imodesuffix>}"
|
||||
[(set_attr "type" "push")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "*popfl<mode>"
|
||||
[(set (match_operand:DWIH 0 "flags_reg_operand")
|
||||
(match_operand:DWIH 1 "pop_operand" ">"))]
|
||||
""
|
||||
"popf{<imodesuffix>}"
|
||||
[(set_attr "type" "pop")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
|
||||
;; Move instructions.
|
||||
|
||||
|
|
|
@ -238,6 +238,22 @@ __rorq (unsigned long long __X, int __C)
|
|||
return (__X >> __C) | (__X << (64 - __C));
|
||||
}
|
||||
|
||||
/* Read flags register */
|
||||
extern __inline unsigned long long
|
||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__readeflags (void)
|
||||
{
|
||||
return __builtin_ia32_readeflags_u64 ();
|
||||
}
|
||||
|
||||
/* Write flags register */
|
||||
extern __inline void
|
||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__writeeflags (unsigned long long X)
|
||||
{
|
||||
__builtin_ia32_writeeflags_u64 (X);
|
||||
}
|
||||
|
||||
#define _bswap64(a) __bswapq(a)
|
||||
#define _popcnt64(a) __popcntq(a)
|
||||
#define _lrotl(a,b) __rolq((a), (b))
|
||||
|
@ -245,6 +261,23 @@ __rorq (unsigned long long __X, int __C)
|
|||
#else
|
||||
#define _lrotl(a,b) __rold((a), (b))
|
||||
#define _lrotr(a,b) __rord((a), (b))
|
||||
|
||||
/* Read flags register */
|
||||
extern __inline unsigned int
|
||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__readeflags (void)
|
||||
{
|
||||
return __builtin_ia32_readeflags_u32 ();
|
||||
}
|
||||
|
||||
/* Write flags register */
|
||||
extern __inline void
|
||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__writeeflags (unsigned int X)
|
||||
{
|
||||
__builtin_ia32_writeeflags_u32 (X);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define _bit_scan_forward(a) __bsfd(a)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com>
|
||||
|
||||
* gcc.target/i386/readeflags-1.c: New.
|
||||
* gcc.target/i386/writeeflags-1.c: Ditto.
|
||||
|
||||
2013-12-05 Yury Gribov <y.gribov@samsung.com>
|
||||
|
||||
PR sanitizer/59369
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define EFLAGS_TYPE unsigned long long int
|
||||
#else
|
||||
#define EFLAGS_TYPE unsigned int
|
||||
#endif
|
||||
|
||||
static EFLAGS_TYPE
|
||||
readeflags_test (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned x = (a == b);
|
||||
return __readeflags ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
EFLAGS_TYPE flags;
|
||||
|
||||
flags = readeflags_test (100, 100);
|
||||
|
||||
if ((flags & 1) != 0) /* Read CF */
|
||||
abort ();
|
||||
|
||||
flags = readeflags_test (100, 101);
|
||||
|
||||
if ((flags & 1) == 0) /* Read CF */
|
||||
abort ();
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("PASSED\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define EFLAGS_TYPE unsigned long long int
|
||||
#else
|
||||
#define EFLAGS_TYPE unsigned int
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
EFLAGS_TYPE flags = 0xD7; /* 111010111b */
|
||||
|
||||
__writeeflags (flags);
|
||||
|
||||
flags = __readeflags ();
|
||||
|
||||
if ((flags & 0xFF) != 0xD7)
|
||||
abort ();
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("PASSED\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue