diff mbox series

[committed] : i386: Improve CET builtin expanders.

Message ID CAFULd4bTNucMWjroB-zoR=jO0-=uf5hn0HqMyuW+KOm3owhH4A@mail.gmail.com
State New
Headers show
Series [committed] : i386: Improve CET builtin expanders. | expand

Commit Message

Uros Bizjak Aug. 13, 2020, 6:57 p.m. UTC
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.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff mbox series

Patch

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"