From b5034abbaa49f15646c83224711447aa1ed31756 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 13 Aug 2020 20:54:16 +0200 Subject: [PATCH] i386: Improve CET builtin expanders. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 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): Implement as parametrized name pattern. Use SWI48 mode iterator. Introduce input operand and remove explicit XOR zeroing from insn template. (@incssp): Implement as parametrized name pattern. Use SWI48 mode iterator. (@wrss): Ditto. (@wruss): Ditto. (rstorssp): Remove expander. Rename insn pattern from *rstorssp. Use DImode memory operand. (clrssbsy): Remove expander. Rename insn pattern from *clrssbsy. 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. --- gcc/config/i386/i386-builtin.def | 22 +++++------ gcc/config/i386/i386-builtins.c | 19 +--------- gcc/config/i386/i386-expand.c | 80 ++++++++++++++++++++++------------------ gcc/config/i386/i386.md | 64 ++++++++++++-------------------- 4 files changed, 78 insertions(+), 107 deletions(-) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index 6270068..25b80868 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 2246507..834438a 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 f441ba9..aec894b 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 9d4e669..3985c77 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" - [(set (match_operand:SWI48x 0 "register_operand" "=r") - (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))] +(define_insn "@rdssp" + [(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\t%0" + "rdssp\t%0" [(set_attr "length" "6") (set_attr "type" "other")]) -(define_insn "incssp" - [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")] +(define_insn "@incssp" + [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] UNSPECV_INCSSP)] "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" "incssp\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" - [(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" - [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") - (match_operand:SWI48x 1 "memory_operand" "m")] +(define_insn "@wrss" + [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") + (match_operand:SWI48 1 "memory_operand" "m")] UNSPECV_WRSS)] "TARGET_SHSTK" "wrss\t%0, %1" [(set_attr "length" "3") (set_attr "type" "other")]) -(define_insn "wruss" - [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") - (match_operand:SWI48x 1 "memory_operand" "m")] +(define_insn "@wruss" + [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") + (match_operand:SWI48 1 "memory_operand" "m")] UNSPECV_WRUSS)] "TARGET_SHSTK" "wruss\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" - [(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" -- 2.7.4