aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulia Koval <julia.koval@intel.com>2017-05-14 09:18:38 +0200
committerUros Bizjak <uros@gcc.gnu.org>2017-05-14 09:18:38 +0200
commitb9bdd60b8792e2d3173ecfacd5c25aac894a94e5 (patch)
tree2daf342d4400b4c11dbf2d5ca6a48bb7e22ecd82
parent6fa95e0961bc15efa5ff52fc7358aee78a16a33c (diff)
downloadgcc-b9bdd60b8792e2d3173ecfacd5c25aac894a94e5.zip
gcc-b9bdd60b8792e2d3173ecfacd5c25aac894a94e5.tar.gz
gcc-b9bdd60b8792e2d3173ecfacd5c25aac894a94e5.tar.bz2
i386-builtin-types.def (VOID_FTYPE_INT_INT64): New type.
* config/i386/i386-builtin-types.def (VOID_FTYPE_INT_INT64): New type. * config/i386/i386-builtin.def (__builtin_ia32_xgetbv) (__builtin_ia32_xsetbv): New builtins. * config/i386/i386.c (ix86_expand_special_args_builtin): Process new types. (ix86_expand_builtin): Special expand for new intrinsics. * config/i386/i386.md (UNSPECV_XGETBV, UNSPECV_XSETBV): New. (xsetbv, xsetbv_rex64, xgetbv, xgetbv_rex64): New insn patterns. * config/i386/xsaveintrin.h (_xsetbv, _getbv): New intrinsics. testsuite/ChangeLog: * gcc.target/i386/xgetsetbv.c: New test. From-SVN: r248028
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/i386/i386-builtin-types.def1
-rw-r--r--gcc/config/i386/i386-builtin.def2
-rw-r--r--gcc/config/i386/i386.c48
-rw-r--r--gcc/config/i386/i386.md39
-rw-r--r--gcc/config/i386/xsaveintrin.h14
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/i386/rdpid.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/xgetsetbv.c13
9 files changed, 134 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8bff6a..e7aa464 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2017-05-14 Julia Koval <julia.koval@intel.com>
+
+ * config/i386/i386-builtin-types.def (VOID_FTYPE_INT_INT64): New type.
+ * config/i386/i386-builtin.def (__builtin_ia32_xgetbv)
+ (__builtin_ia32_xsetbv): New builtins.
+ * config/i386/i386.c (ix86_expand_special_args_builtin):
+ Process new types.
+ (ix86_expand_builtin): Special expand for new intrinsics.
+ * config/i386/i386.md (UNSPECV_XGETBV, UNSPECV_XSETBV): New.
+ (xsetbv, xsetbv_rex64, xgetbv, xgetbv_rex64): New insn patterns.
+ * config/i386/xsaveintrin.h (_xsetbv, _getbv): New intrinsics.
+
2017-05-13 Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
* cfganal.c (inverted_post_order_compute): Change argument type
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index b3620ed..8de3086 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -311,6 +311,7 @@ DEF_FUNCTION_TYPE (V8DI, V8DI, V8DI, UQI)
DEF_FUNCTION_TYPE (V8DI, PV8DI)
DEF_FUNCTION_TYPE (V8DI, V8DI)
+DEF_FUNCTION_TYPE (VOID, INT, INT64)
DEF_FUNCTION_TYPE (DI, V2DI, INT)
DEF_FUNCTION_TYPE (DOUBLE, V2DF, INT)
DEF_FUNCTION_TYPE (FLOAT, V4SF, INT)
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index 1e29198..2663cb9 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -113,6 +113,8 @@ BDESC (OPTION_MASK_ISA_XSAVEOPT, CODE_FOR_nothing, "__builtin_ia32_xsaveopt", IX
BDESC (OPTION_MASK_ISA_XSAVES, CODE_FOR_nothing, "__builtin_ia32_xsaves", IX86_BUILTIN_XSAVES, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64)
BDESC (OPTION_MASK_ISA_XSAVES, CODE_FOR_nothing, "__builtin_ia32_xrstors", IX86_BUILTIN_XRSTORS, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64)
BDESC (OPTION_MASK_ISA_XSAVEC, CODE_FOR_nothing, "__builtin_ia32_xsavec", IX86_BUILTIN_XSAVEC, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64)
+BDESC (OPTION_MASK_ISA_XSAVE, CODE_FOR_nothing, "__builtin_ia32_xgetbv", IX86_BUILTIN_XGETBV, UNKNOWN, (int) UINT64_FTYPE_INT)
+BDESC (OPTION_MASK_ISA_XSAVE, CODE_FOR_nothing, "__builtin_ia32_xsetbv", IX86_BUILTIN_XSETBV, UNKNOWN, (int) VOID_FTYPE_INT_INT64)
BDESC (OPTION_MASK_ISA_FXSR | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_fxsave64", IX86_BUILTIN_FXSAVE64, UNKNOWN, (int) VOID_FTYPE_PVOID)
BDESC (OPTION_MASK_ISA_FXSR | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_fxrstor64", IX86_BUILTIN_FXRSTOR64, UNKNOWN, (int) VOID_FTYPE_PVOID)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a0d9207..a6f2063 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -36220,6 +36220,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case V4DI_FTYPE_PCV4DI_V4DI:
case V4SI_FTYPE_PCV4SI_V4SI:
case V2DI_FTYPE_PCV2DI_V2DI:
+ case VOID_FTYPE_INT_INT64:
nargs = 2;
klass = load;
memory = 0;
@@ -37227,6 +37228,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
case IX86_BUILTIN_RDPMC:
case IX86_BUILTIN_RDTSC:
case IX86_BUILTIN_RDTSCP:
+ case IX86_BUILTIN_XGETBV:
op0 = gen_reg_rtx (DImode);
op1 = gen_reg_rtx (DImode);
@@ -37243,6 +37245,18 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
: gen_rdpmc (op0, op2));
emit_insn (insn);
}
+ else if (fcode == IX86_BUILTIN_XGETBV)
+ {
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op2 = expand_normal (arg0);
+ if (!register_operand (op2, SImode))
+ op2 = copy_to_mode_reg (SImode, op2);
+
+ insn = (TARGET_64BIT
+ ? gen_xgetbv_rex64 (op0, op1, op2)
+ : gen_xgetbv (op0, op2));
+ emit_insn (insn);
+ }
else if (fcode == IX86_BUILTIN_RDTSC)
{
insn = (TARGET_64BIT
@@ -37335,6 +37349,40 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
emit_insn (pat);
return 0;
+ case IX86_BUILTIN_XSETBV:
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ arg1 = CALL_EXPR_ARG (exp, 1);
+ op0 = expand_normal (arg0);
+ op1 = expand_normal (arg1);
+
+ if (!REG_P (op0))
+ op0 = copy_to_mode_reg (SImode, op0);
+
+ if (TARGET_64BIT)
+ {
+ op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32),
+ NULL, 1, OPTAB_DIRECT);
+
+ 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)
+ emit_insn (pat);
+ return 0;
+
case IX86_BUILTIN_XSAVE:
case IX86_BUILTIN_XRSTOR:
case IX86_BUILTIN_XSAVE64:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 616a0b7..da79d8f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -236,6 +236,8 @@
UNSPECV_XRSTORS64
UNSPECV_XSAVEC
UNSPECV_XSAVEC64
+ UNSPECV_XGETBV
+ UNSPECV_XSETBV
;; For atomic compound assignments.
UNSPECV_FNSTENV
@@ -19029,6 +19031,43 @@
(set (attr "length")
(symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
+(define_insn "xsetbv"
+ [(unspec_volatile:SI
+ [(match_operand:SI 0 "register_operand" "c")
+ (match_operand:DI 1 "register_operand" "A")]
+ UNSPECV_XSETBV)]
+ "!TARGET_64BIT && TARGET_XSAVE"
+ "xsetbv"
+ [(set_attr "type" "other")])
+
+(define_insn "xsetbv_rex64"
+ [(unspec_volatile:SI
+ [(match_operand:SI 0 "register_operand" "c")
+ (match_operand:SI 1 "register_operand" "a")
+ (match_operand:SI 2 "register_operand" "d")]
+ UNSPECV_XSETBV)]
+ "TARGET_64BIT && TARGET_XSAVE"
+ "xsetbv"
+ [(set_attr "type" "other")])
+
+(define_insn "xgetbv"
+ [(set (match_operand:DI 0 "register_operand" "=A")
+ (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
+ UNSPECV_XGETBV))]
+ "!TARGET_64BIT && TARGET_XSAVE"
+ "xgetbv"
+ [(set_attr "type" "other")])
+
+(define_insn "xgetbv_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
+ UNSPECV_XGETBV))
+ (set (match_operand:DI 1 "register_operand" "=d")
+ (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
+ "TARGET_64BIT && TARGET_XSAVE"
+ "xgetbv"
+ [(set_attr "type" "other")])
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Floating-point instructions for atomic compound assignments
diff --git a/gcc/config/i386/xsaveintrin.h b/gcc/config/i386/xsaveintrin.h
index c136d30..cea8ad9 100644
--- a/gcc/config/i386/xsaveintrin.h
+++ b/gcc/config/i386/xsaveintrin.h
@@ -48,6 +48,20 @@ _xrstor (void *__P, long long __M)
__builtin_ia32_xrstor (__P, __M);
}
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_xsetbv (unsigned int __A, long long __V)
+{
+ __builtin_ia32_xsetbv (__A, __V);
+}
+
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_xgetbv (unsigned int __A)
+{
+ __builtin_ia32_xgetbv (__A);
+}
+
#ifdef __x86_64__
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4713ecd..8dccbe3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-14 Julia Koval <julia.koval@intel.com>
+
+ * gcc.target/i386/xgetsetbv.c: New test.
+
2017-05-14 Nicolas Koenig <koenigni@student.ethz.ch>
PR fortran/80442
diff --git a/gcc/testsuite/gcc.target/i386/rdpid.c b/gcc/testsuite/gcc.target/i386/rdpid.c
index 33a8084..286c297 100644
--- a/gcc/testsuite/gcc.target/i386/rdpid.c
+++ b/gcc/testsuite/gcc.target/i386/rdpid.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mrdpid " } */
+/* { dg-options "-O2 -mrdpid" } */
/* { dg-final { scan-assembler "rdpid\[ \t]+(%|)eax" } } */
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/xgetsetbv.c b/gcc/testsuite/gcc.target/i386/xgetsetbv.c
new file mode 100644
index 0000000..9a9af1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/xgetsetbv.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mxsave" } */
+/* { dg-final { scan-assembler "xgetbv" } } */
+/* { dg-final { scan-assembler "xsetbv" } } */
+
+#include <x86intrin.h>
+
+unsigned int
+xgetsetbv (void)
+{
+ _xsetbv (0, 0);
+ return _xgetbv (0);
+}