summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2020-08-13 20:54:16 +0200
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 15:08:11 -0300
commite85ed167cdec4b14b11b107ea35628031a70cf51 (patch)
tree024e2faa4e8d4383509cd903e130f9480d6f07b0
parent8e6c081b89e0595e73fd42f3c27bdb37a14ed5f9 (diff)
downloadgcc-e85ed167cdec4b14b11b107ea35628031a70cf51.tar.gz
i386: Improve CET builtin expanders.
Several fixes to CET builtin expanders: a) Split out explicit zeroing of RDSSP output operand. b) Use DImode memory operand for RSTORSSP and CLRSSBSY instructions. c) Use parameterized pattern names to simplify calling of named patterns. 2020-08-13 Uroš Bizjak <ubizjak@gmail.com> gcc/ChangeLog: * config/i386/i386-builtin.def (CET_NORMAL): Merge to CET BDESC array. (__builtin_ia32_rddspd, __builtin_ia32_rddspq, __builtin_ia32_incsspd) (__builtin_ia32_incsspq, __builtin_ia32_wrssd, __builtin_ia32_wrssq) (__builtin_ia32_wrussd, __builtin_ia32_wrussq): Use CODE_FOR_nothing. * config/i386/i386-builtins.c: Remove handling of CET_NORMAL builtins. * config/i386/i386.md (@rdssp<mode>): Implement as parametrized name pattern. Use SWI48 mode iterator. Introduce input operand and remove explicit XOR zeroing from insn template. (@incssp<mode>): Implement as parametrized name pattern. Use SWI48 mode iterator. (@wrss<mode>): Ditto. (@wruss<mode>): Ditto. (rstorssp): Remove expander. Rename insn pattern from *rstorssp<mode>. Use DImode memory operand. (clrssbsy): Remove expander. Rename insn pattern from *clrssbsy<mode>. Use DImode memory operand. (save_stack_nonlocal): Update for parametrized name patterns. Use cleared register as an argument to gen_rddsp. (restore_stack_nonlocal): Update for parametrized name patterns. * config/i386/i386-expand.c (ix86_expand_builtin): [case IX86_BUILTIN_RDSSPD, case IX86_BUILTIN_RDSSPQ]: Expand here. [case IX86_BUILTIN_INCSSPD, case IX86_BUILTIN_INCSSPQ]: Ditto. [case IX86_BUILTIN_RSTORSSP, case IX86_BUILTIN_CLRSSBSY]: Generate DImode memory operand. [case IX86_BUILTIN_WRSSD, case IX86_BUILTIN_WRSSQ] [case IX86_BUILTIN_WRUSSD, case IX86_BUILTIN_WRUSSD]: Update for parameterized name patterns.
-rw-r--r--gcc/config/i386/i386-builtin.def22
-rw-r--r--gcc/config/i386/i386-builtins.c19
-rw-r--r--gcc/config/i386/i386-expand.c80
-rw-r--r--gcc/config/i386/i386.md64
4 files changed, 78 insertions, 107 deletions
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index 6270068fba1..25b80868bd3 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -3126,21 +3126,17 @@ BDESC_END (MULTI_ARG, CET)
/* CET. */
BDESC_FIRST (cet, CET,
- OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_incsspsi, "__builtin_ia32_incsspd", IX86_BUILTIN_INCSSPD, UNKNOWN, (int) VOID_FTYPE_UNSIGNED)
-BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_incsspdi, "__builtin_ia32_incsspq", IX86_BUILTIN_INCSSPQ, UNKNOWN, (int) VOID_FTYPE_UINT64)
+ OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_nothing, "__builtin_ia32_rdsspd", IX86_BUILTIN_RDSSPD, UNKNOWN, (int) UINT_FTYPE_VOID)
+BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_nothing, "__builtin_ia32_rdsspq", IX86_BUILTIN_RDSSPQ, UNKNOWN, (int) UINT64_FTYPE_VOID)
+BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_nothing, "__builtin_ia32_incsspd", IX86_BUILTIN_INCSSPD, UNKNOWN, (int) VOID_FTYPE_UNSIGNED)
+BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_nothing, "__builtin_ia32_incsspq", IX86_BUILTIN_INCSSPQ, UNKNOWN, (int) VOID_FTYPE_UINT64)
BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_saveprevssp, "__builtin_ia32_saveprevssp", IX86_BUILTIN_SAVEPREVSSP, UNKNOWN, (int) VOID_FTYPE_VOID)
BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_rstorssp, "__builtin_ia32_rstorssp", IX86_BUILTIN_RSTORSSP, UNKNOWN, (int) VOID_FTYPE_PVOID)
-BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_wrsssi, "__builtin_ia32_wrssd", IX86_BUILTIN_WRSSD, UNKNOWN, (int) VOID_FTYPE_UNSIGNED_PVOID)
-BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_wrssdi, "__builtin_ia32_wrssq", IX86_BUILTIN_WRSSQ, UNKNOWN, (int) VOID_FTYPE_UINT64_PVOID)
-BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_wrusssi, "__builtin_ia32_wrussd", IX86_BUILTIN_WRUSSD, UNKNOWN, (int) VOID_FTYPE_UNSIGNED_PVOID)
-BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_wrussdi, "__builtin_ia32_wrussq", IX86_BUILTIN_WRUSSQ, UNKNOWN, (int) VOID_FTYPE_UINT64_PVOID)
+BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_nothing, "__builtin_ia32_wrssd", IX86_BUILTIN_WRSSD, UNKNOWN, (int) VOID_FTYPE_UNSIGNED_PVOID)
+BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_nothing, "__builtin_ia32_wrssq", IX86_BUILTIN_WRSSQ, UNKNOWN, (int) VOID_FTYPE_UINT64_PVOID)
+BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_nothing, "__builtin_ia32_wrussd", IX86_BUILTIN_WRUSSD, UNKNOWN, (int) VOID_FTYPE_UNSIGNED_PVOID)
+BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_nothing, "__builtin_ia32_wrussq", IX86_BUILTIN_WRUSSQ, UNKNOWN, (int) VOID_FTYPE_UINT64_PVOID)
BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_setssbsy, "__builtin_ia32_setssbsy", IX86_BUILTIN_SETSSBSY, UNKNOWN, (int) VOID_FTYPE_VOID)
BDESC (OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_clrssbsy, "__builtin_ia32_clrssbsy", IX86_BUILTIN_CLRSSBSY, UNKNOWN, (int) VOID_FTYPE_PVOID)
-BDESC_END (CET, CET_NORMAL)
-
-BDESC_FIRST (cet_rdssp, CET_NORMAL,
- OPTION_MASK_ISA_SHSTK, 0, CODE_FOR_rdsspsi, "__builtin_ia32_rdsspd", IX86_BUILTIN_RDSSPD, UNKNOWN, (int) UINT_FTYPE_VOID)
-BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, 0, CODE_FOR_rdsspdi, "__builtin_ia32_rdsspq", IX86_BUILTIN_RDSSPQ, UNKNOWN, (int) UINT64_FTYPE_VOID)
-
-BDESC_END (CET_NORMAL, MAX)
+BDESC_END (CET, MAX)
diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index 2246507a8d5..834438a6666 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -116,10 +116,8 @@ BDESC_VERIFYS (IX86_BUILTIN__BDESC_MULTI_ARG_FIRST,
IX86_BUILTIN__BDESC_ROUND_ARGS_LAST, 1);
BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_FIRST,
IX86_BUILTIN__BDESC_MULTI_ARG_LAST, 1);
-BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_NORMAL_FIRST,
- IX86_BUILTIN__BDESC_CET_LAST, 1);
BDESC_VERIFYS (IX86_BUILTIN_MAX,
- IX86_BUILTIN__BDESC_CET_NORMAL_LAST, 1);
+ IX86_BUILTIN__BDESC_CET_LAST, 1);
/* Table for the ix86 builtin non-function types. */
@@ -1227,21 +1225,6 @@ ix86_init_mmx_sse_builtins (void)
BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_LAST,
IX86_BUILTIN__BDESC_CET_FIRST,
ARRAY_SIZE (bdesc_cet) - 1);
-
- for (i = 0, d = bdesc_cet_rdssp;
- i < ARRAY_SIZE (bdesc_cet_rdssp);
- i++, d++)
- {
- BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_CET_NORMAL_FIRST, i);
- if (d->name == 0)
- continue;
-
- ftype = (enum ix86_builtin_func_type) d->flag;
- def_builtin (d->mask, d->mask2, d->name, ftype, d->code);
- }
- BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_NORMAL_LAST,
- IX86_BUILTIN__BDESC_CET_NORMAL_FIRST,
- ARRAY_SIZE (bdesc_cet_rdssp) - 1);
}
#undef BDESC_VERIFY
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index f441ba929bc..aec894bbdb4 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -12736,55 +12736,73 @@ rdseed_step:
emit_insn (gen_xabort (op0));
return 0;
+ case IX86_BUILTIN_RDSSPD:
+ case IX86_BUILTIN_RDSSPQ:
+ mode = (fcode == IX86_BUILTIN_RDSSPD ? SImode : DImode);
+
+ if (target == 0
+ || !register_operand (target, mode))
+ target = gen_reg_rtx (mode);
+
+ op0 = force_reg (mode, const0_rtx);
+
+ emit_insn (gen_rdssp (mode, target, op0));
+ return target;
+
+ case IX86_BUILTIN_INCSSPD:
+ case IX86_BUILTIN_INCSSPQ:
+ mode = (fcode == IX86_BUILTIN_INCSSPD ? SImode : DImode);
+
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op0 = expand_normal (arg0);
+
+ op0 = force_reg (mode, op0);
+
+ emit_insn (gen_incssp (mode, op0));
+ return 0;
+
case IX86_BUILTIN_RSTORSSP:
case IX86_BUILTIN_CLRSSBSY:
arg0 = CALL_EXPR_ARG (exp, 0);
op0 = expand_normal (arg0);
icode = (fcode == IX86_BUILTIN_RSTORSSP
- ? CODE_FOR_rstorssp
- : CODE_FOR_clrssbsy);
+ ? CODE_FOR_rstorssp
+ : CODE_FOR_clrssbsy);
+
if (!address_operand (op0, VOIDmode))
{
- op1 = convert_memory_address (Pmode, op0);
- op0 = copy_addr_to_reg (op1);
+ op0 = convert_memory_address (Pmode, op0);
+ op0 = copy_addr_to_reg (op0);
}
- emit_insn (GEN_FCN (icode) (gen_rtx_MEM (Pmode, op0)));
+ emit_insn (GEN_FCN (icode) (gen_rtx_MEM (DImode, op0)));
return 0;
case IX86_BUILTIN_WRSSD:
case IX86_BUILTIN_WRSSQ:
case IX86_BUILTIN_WRUSSD:
case IX86_BUILTIN_WRUSSQ:
+ mode = ((fcode == IX86_BUILTIN_WRSSD
+ || fcode == IX86_BUILTIN_WRUSSD)
+ ? SImode : DImode);
+
arg0 = CALL_EXPR_ARG (exp, 0);
op0 = expand_normal (arg0);
arg1 = CALL_EXPR_ARG (exp, 1);
op1 = expand_normal (arg1);
- switch (fcode)
- {
- case IX86_BUILTIN_WRSSD:
- icode = CODE_FOR_wrsssi;
- mode = SImode;
- break;
- case IX86_BUILTIN_WRSSQ:
- icode = CODE_FOR_wrssdi;
- mode = DImode;
- break;
- case IX86_BUILTIN_WRUSSD:
- icode = CODE_FOR_wrusssi;
- mode = SImode;
- break;
- case IX86_BUILTIN_WRUSSQ:
- icode = CODE_FOR_wrussdi;
- mode = DImode;
- break;
- }
+
op0 = force_reg (mode, op0);
+
if (!address_operand (op1, VOIDmode))
{
- op2 = convert_memory_address (Pmode, op1);
- op1 = copy_addr_to_reg (op2);
+ op1 = convert_memory_address (Pmode, op1);
+ op1 = copy_addr_to_reg (op1);
}
- emit_insn (GEN_FCN (icode) (op0, gen_rtx_MEM (mode, op1)));
+ op1 = gen_rtx_MEM (mode, op1);
+
+ emit_insn ((fcode == IX86_BUILTIN_WRSSD
+ || fcode == IX86_BUILTIN_WRSSQ)
+ ? gen_wrss (mode, op0, op1)
+ : gen_wruss (mode, op0, op1));
return 0;
default:
@@ -13086,14 +13104,6 @@ s4fma_expand:
target);
}
- if (fcode >= IX86_BUILTIN__BDESC_CET_NORMAL_FIRST
- && fcode <= IX86_BUILTIN__BDESC_CET_NORMAL_LAST)
- {
- i = fcode - IX86_BUILTIN__BDESC_CET_NORMAL_FIRST;
- return ix86_expand_special_args_builtin (bdesc_cet_rdssp + i, exp,
- target);
- }
-
gcc_unreachable ();
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 9d4e669e03b..3985c771d00 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -19139,10 +19139,8 @@
to the second slot. */
rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
- rtx ssp = gen_reg_rtx (word_mode);
- emit_insn ((word_mode == SImode)
- ? gen_rdsspsi (ssp)
- : gen_rdsspdi (ssp));
+ rtx ssp = force_reg (word_mode, const0_rtx);
+ emit_insn (gen_rdssp (word_mode, ssp, ssp));
emit_move_insn (ssp_slot, ssp);
}
else
@@ -19170,11 +19168,8 @@
/* Get the current shadow stack pointer. The code below will check if
SHSTK feature is enabled. If it is not enabled the RDSSP instruction
is a NOP. */
- reg_ssp = gen_reg_rtx (word_mode);
- emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
- emit_insn ((word_mode == SImode)
- ? gen_rdsspsi (reg_ssp)
- : gen_rdsspdi (reg_ssp));
+ reg_ssp = force_reg (word_mode, const0_rtx);
+ emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
/* Compare through substraction the saved and the current ssp to decide
if ssp has to be adjusted. */
@@ -19227,9 +19222,7 @@
emit_label (loop_label);
LABEL_NUSES (loop_label) = 1;
- emit_insn ((word_mode == SImode)
- ? gen_incsspsi (reg_255)
- : gen_incsspdi (reg_255));
+ emit_insn (gen_incssp (word_mode, reg_255));
tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
reg_adj,
GEN_INT (255)));
@@ -19251,9 +19244,7 @@
emit_label (inc_label);
LABEL_NUSES (inc_label) = 1;
- emit_insn ((word_mode == SImode)
- ? gen_incsspsi (reg_ssp)
- : gen_incsspdi (reg_ssp));
+ emit_insn (gen_incssp (word_mode, reg_ssp));
emit_label (noadj_label);
LABEL_NUSES (noadj_label) = 1;
@@ -21253,16 +21244,17 @@
(set_attr "memory" "unknown")])
;; CET instructions
-(define_insn "rdssp<mode>"
- [(set (match_operand:SWI48x 0 "register_operand" "=r")
- (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
+(define_insn "@rdssp<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
+ UNSPECV_NOP_RDSSP))]
"TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
- "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
+ "rdssp<mskmodesuffix>\t%0"
[(set_attr "length" "6")
(set_attr "type" "other")])
-(define_insn "incssp<mode>"
- [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
+(define_insn "@incssp<mode>"
+ [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
UNSPECV_INCSSP)]
"TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
"incssp<mskmodesuffix>\t%0"
@@ -21276,31 +21268,26 @@
[(set_attr "length" "5")
(set_attr "type" "other")])
-(define_expand "rstorssp"
- [(unspec_volatile [(match_operand 0 "memory_operand")]
- UNSPECV_RSTORSSP)]
- "TARGET_SHSTK")
-
-(define_insn "*rstorssp<mode>"
- [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
+(define_insn "rstorssp"
+ [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
UNSPECV_RSTORSSP)]
"TARGET_SHSTK"
"rstorssp\t%0"
[(set_attr "length" "5")
(set_attr "type" "other")])
-(define_insn "wrss<mode>"
- [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
- (match_operand:SWI48x 1 "memory_operand" "m")]
+(define_insn "@wrss<mode>"
+ [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
+ (match_operand:SWI48 1 "memory_operand" "m")]
UNSPECV_WRSS)]
"TARGET_SHSTK"
"wrss<mskmodesuffix>\t%0, %1"
[(set_attr "length" "3")
(set_attr "type" "other")])
-(define_insn "wruss<mode>"
- [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
- (match_operand:SWI48x 1 "memory_operand" "m")]
+(define_insn "@wruss<mode>"
+ [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
+ (match_operand:SWI48 1 "memory_operand" "m")]
UNSPECV_WRUSS)]
"TARGET_SHSTK"
"wruss<mskmodesuffix>\t%0, %1"
@@ -21314,13 +21301,8 @@
[(set_attr "length" "4")
(set_attr "type" "other")])
-(define_expand "clrssbsy"
- [(unspec_volatile [(match_operand 0 "memory_operand")]
- UNSPECV_CLRSSBSY)]
- "TARGET_SHSTK")
-
-(define_insn "*clrssbsy<mode>"
- [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
+(define_insn "clrssbsy"
+ [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
UNSPECV_CLRSSBSY)]
"TARGET_SHSTK"
"clrssbsy\t%0"