i386: Improve CET builtin expanders.
authorUros Bizjak <ubizjak@gmail.com>
Thu, 13 Aug 2020 18:54:16 +0000 (20:54 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 13 Aug 2020 18:55:09 +0000 (20:55 +0200)
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.

gcc/config/i386/i386-builtin.def
gcc/config/i386/i386-builtins.c
gcc/config/i386/i386-expand.c
gcc/config/i386/i386.md

index 6270068fba1d815a3c37bde2724cbb202923814a..25b80868bd35313fc750c9e2a7119a26582d16f6 100644 (file)
@@ -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)
index 2246507a8d5a2b7a6e296c0de22ba2538fdaaf77..834438a6666aaa9a6f0ea169caa1ce65ea1ba4d5 100644 (file)
@@ -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
index f441ba929bc178bc6f4534e915ca641f52f4ee49..aec894bbdb40d1da1ffdfe1b00ce7a1e421daeb9 100644 (file)
@@ -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 ();
 }
 
index 9d4e669e03b30b91987f8c8635874e36e0393ede..3985c771d00b8f85ff4b2b64b2f9bf9e86471f53 100644 (file)
         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
       /* 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.  */
       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)));
 
       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;
    (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"
   [(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"
   [(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"