diff options
author | Kirill Yukhin <kirill.yukhin@intel.com> | 2013-12-05 11:23:39 +0000 |
---|---|---|
committer | Kirill Yukhin <kyukhin@gcc.gnu.org> | 2013-12-05 11:23:39 +0000 |
commit | 9bbd48d120d203e8eade09e0bb830370b6d69801 (patch) | |
tree | 3ba8009e419b90953be79c501271dcc9db592b66 /gcc | |
parent | 46db94aa6a7619350c9d8b75fe0cc4fa3c4d2182 (diff) | |
download | gcc-9bbd48d120d203e8eade09e0bb830370b6d69801.zip gcc-9bbd48d120d203e8eade09e0bb830370b6d69801.tar.gz gcc-9bbd48d120d203e8eade09e0bb830370b6d69801.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 37 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 17 | ||||
-rw-r--r-- | gcc/config/i386/ia32intrin.h | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/readeflags-1.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/writeeflags-1.c | 30 |
7 files changed, 175 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ae50704..6440950 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7bf8c1e..848b8508 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 5ff66cc..7075332 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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. diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h index b26dc46..65642e4 100644 --- a/gcc/config/i386/ia32intrin.h +++ b/gcc/config/i386/ia32intrin.h @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 592f64c..699ff7e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.target/i386/readeflags-1.c b/gcc/testsuite/gcc.target/i386/readeflags-1.c new file mode 100644 index 0000000..6b2fa7e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/readeflags-1.c @@ -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; +} + diff --git a/gcc/testsuite/gcc.target/i386/writeeflags-1.c b/gcc/testsuite/gcc.target/i386/writeeflags-1.c new file mode 100644 index 0000000..446840c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/writeeflags-1.c @@ -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; +} + |