From: Julia Koval Date: Sun, 14 May 2017 07:18:38 +0000 (+0200) Subject: i386-builtin-types.def (VOID_FTYPE_INT_INT64): New type. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b9bdd60b8792e2d3173ecfacd5c25aac894a94e5;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8bff6a17c5..e7aa4648af6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2017-05-14 Julia Koval + + * 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 * 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 b3620edd106..8de30862c58 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 1e29198ad07..2663cb9faa7 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 a0d9207c724..a6f20636c43 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 616a0b73671..da79d8fe1b8 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 c136d30aa63..cea8ad9538f 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 4713ecdf534..8dccbe3b33d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-05-14 Julia Koval + + * gcc.target/i386/xgetsetbv.c: New test. + 2017-05-14 Nicolas Koenig PR fortran/80442 diff --git a/gcc/testsuite/gcc.target/i386/rdpid.c b/gcc/testsuite/gcc.target/i386/rdpid.c index 33a8084c6d4..286c2974823 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 diff --git a/gcc/testsuite/gcc.target/i386/xgetsetbv.c b/gcc/testsuite/gcc.target/i386/xgetsetbv.c new file mode 100644 index 00000000000..9a9af1bb48f --- /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 + +unsigned int +xgetsetbv (void) +{ + _xsetbv (0, 0); + return _xgetbv (0); +}