diff options
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r-- | gcc/config/i386/i386.md | 449 |
1 files changed, 397 insertions, 52 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 3413b90028f..d48decbb7d9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -62,7 +62,7 @@ ;; ; -- print a semicolon (after prefixes due to bug in older gas). ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise. ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode -;; ! -- print MPX prefix for jxx/call/ret instructions if required. +;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required. (define_c_enum "unspec" [ ;; Relocation specifiers @@ -99,6 +99,7 @@ UNSPEC_SCAS UNSPEC_FNSTSW UNSPEC_SAHF + UNSPEC_NOTRAP UNSPEC_PARITY UNSPEC_FSTCW UNSPEC_FLDCW @@ -112,6 +113,7 @@ UNSPEC_STOS UNSPEC_PEEPSIB UNSPEC_INSN_FALSE_DEP + UNSPEC_SBB ;; For SSE/MMX support: UNSPEC_FIX_NOTRUNC @@ -274,6 +276,17 @@ ;; For RDPID support UNSPECV_RDPID + + ;; For CET support + UNSPECV_NOP_ENDBR + UNSPECV_NOP_RDSSP + UNSPECV_INCSSP + UNSPECV_SAVEPREVSSP + UNSPECV_RSTORSSP + UNSPECV_WRSS + UNSPECV_WRUSS + UNSPECV_SETSSBSY + UNSPECV_CLRSSBSY ]) ;; Constants to represent rounding modes in the ROUND instruction @@ -798,7 +811,7 @@ (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64, sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx, avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f, - fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq, + avx512bw,noavx512bw,avx512dq,noavx512dq, avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw" (const_string "base")) @@ -832,8 +845,6 @@ (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F") (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F") - (eq_attr "isa" "fma_avx512f") - (symbol_ref "TARGET_FMA || TARGET_AVX512F") (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW") (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW") (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ") @@ -1468,9 +1479,6 @@ ;; FP compares, step 1: ;; Set the FP condition codes. -;; -;; CCFPmode compare with exceptions -;; CCFPUmode compare with no exceptions ;; We may not use "#" to split and emit these, since the REG_DEAD notes ;; used to manage the reg stack popping would not be preserved. @@ -1577,9 +1585,11 @@ (define_insn "*cmpu<mode>_i387" [(set (match_operand:HI 0 "register_operand" "=a") (unspec:HI - [(compare:CCFPU - (match_operand:X87MODEF 1 "register_operand" "f") - (match_operand:X87MODEF 2 "register_operand" "f"))] + [(unspec:CCFP + [(compare:CCFP + (match_operand:X87MODEF 1 "register_operand" "f") + (match_operand:X87MODEF 2 "register_operand" "f"))] + UNSPEC_NOTRAP)] UNSPEC_FNSTSW))] "TARGET_80387" "* return output_fp_compare (insn, operands, false, true);" @@ -1588,18 +1598,22 @@ (set_attr "mode" "<MODE>")]) (define_insn_and_split "*cmpu<mode>_cc_i387" - [(set (reg:CCFPU FLAGS_REG) - (compare:CCFPU - (match_operand:X87MODEF 1 "register_operand" "f") - (match_operand:X87MODEF 2 "register_operand" "f"))) + [(set (reg:CCFP FLAGS_REG) + (unspec:CCFP + [(compare:CCFP + (match_operand:X87MODEF 1 "register_operand" "f") + (match_operand:X87MODEF 2 "register_operand" "f"))] + UNSPEC_NOTRAP)) (clobber (match_operand:HI 0 "register_operand" "=a"))] "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" "#" "&& reload_completed" [(set (match_dup 0) (unspec:HI - [(compare:CCFPU (match_dup 1)(match_dup 2))] - UNSPEC_FNSTSW)) + [(unspec:CCFP + [(compare:CCFP (match_dup 1)(match_dup 2))] + UNSPEC_NOTRAP)] + UNSPEC_FNSTSW)) (set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] "" @@ -1685,21 +1699,30 @@ (set_attr "mode" "SI")]) ;; Pentium Pro can do steps 1 through 3 in one go. -;; comi*, ucomi*, fcomi*, ficomi*, fucomi* -;; (these i387 instructions set flags directly) +;; (these instructions set flags directly) -(define_mode_iterator FPCMP [CCFP CCFPU]) -(define_mode_attr unord [(CCFP "") (CCFPU "u")]) +(define_subst_attr "unord" "unord_subst" "" "u") +(define_subst_attr "unordered" "unord_subst" "false" "true") + +(define_subst "unord_subst" + [(set (match_operand:CCFP 0) + (match_operand:CCFP 1))] + "" + [(set (match_dup 0) + (unspec:CCFP + [(match_dup 1)] + UNSPEC_NOTRAP))]) -(define_insn "*cmpi<FPCMP:unord><MODEF:mode>" - [(set (reg:FPCMP FLAGS_REG) - (compare:FPCMP +(define_insn "*cmpi<unord><MODEF:mode>" + [(set (reg:CCFP FLAGS_REG) + (compare:CCFP (match_operand:MODEF 0 "register_operand" "f,v") (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))] "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) || (TARGET_80387 && TARGET_CMOVE)" - "* return output_fp_compare (insn, operands, true, - <FPCMP:MODE>mode == CCFPUmode);" + "@ + * return output_fp_compare (insn, operands, true, <unordered>); + %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}" [(set_attr "type" "fcmp,ssecomi") (set_attr "prefix" "orig,maybe_vex") (set_attr "mode" "<MODEF:MODE>") @@ -1728,13 +1751,12 @@ (symbol_ref "false"))))]) (define_insn "*cmpi<unord>xf_i387" - [(set (reg:FPCMP FLAGS_REG) - (compare:FPCMP + [(set (reg:CCFP FLAGS_REG) + (compare:CCFP (match_operand:XF 0 "register_operand" "f") (match_operand:XF 1 "register_operand" "f")))] "TARGET_80387 && TARGET_CMOVE" - "* return output_fp_compare (insn, operands, true, - <MODE>mode == CCFPUmode);" + "* return output_fp_compare (insn, operands, true, <unordered>);" [(set_attr "type" "fcmp") (set_attr "mode" "XF") (set_attr "athlon_decode" "vector") @@ -3564,8 +3586,10 @@ /* movaps is one byte shorter for non-AVX targets. */ (eq_attr "alternative" "13,17") - (cond [(ior (match_operand 0 "ext_sse_reg_operand") - (match_operand 1 "ext_sse_reg_operand")) + (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256")) + (not (match_test "TARGET_AVX512VL"))) + (ior (match_operand 0 "ext_sse_reg_operand") + (match_operand 1 "ext_sse_reg_operand"))) (const_string "V8DF") (ior (not (match_test "TARGET_SSE2")) (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) @@ -3739,8 +3763,10 @@ better to maintain the whole registers in single format to avoid problems on using packed logical operations. */ (eq_attr "alternative" "6") - (cond [(ior (match_operand 0 "ext_sse_reg_operand") - (match_operand 1 "ext_sse_reg_operand")) + (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256")) + (not (match_test "TARGET_AVX512VL"))) + (ior (match_operand 0 "ext_sse_reg_operand") + (match_operand 1 "ext_sse_reg_operand"))) (const_string "V16SF") (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") (match_test "TARGET_SSE_SPLIT_REGS")) @@ -6765,6 +6791,17 @@ [(set_attr "type" "alu") (set_attr "mode" "<MODE>")]) +(define_peephole2 + [(parallel + [(set (reg:CC FLAGS_REG) + (compare:CC (match_operand:SWI 0 "general_reg_operand") + (match_operand:SWI 1 "general_gr_operand"))) + (set (match_dup 0) + (minus:SWI (match_dup 0) (match_dup 1)))])] + "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0" + [(set (reg:CC FLAGS_REG) + (compare:CC (match_dup 0) (match_dup 1)))]) + (define_insn "*subsi_3_zext" [(set (reg FLAGS_REG) (compare (match_operand:SI 1 "register_operand" "0") @@ -6818,15 +6855,19 @@ (define_insn "addcarry<mode>" [(set (reg:CCC FLAGS_REG) (compare:CCC - (plus:SWI48 + (zero_extend:<DWI> (plus:SWI48 - (match_operator:SWI48 4 "ix86_carry_flag_operator" - [(match_operand 3 "flags_reg_operand") (const_int 0)]) - (match_operand:SWI48 1 "nonimmediate_operand" "%0")) - (match_operand:SWI48 2 "nonimmediate_operand" "rm")) - (match_dup 1))) + (plus:SWI48 + (match_operator:SWI48 5 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI48 1 "nonimmediate_operand" "%0")) + (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) + (plus:<DWI> + (zero_extend:<DWI> (match_dup 2)) + (match_operator:<DWI> 4 "ix86_carry_flag_operator" + [(match_dup 3) (const_int 0)])))) (set (match_operand:SWI48 0 "register_operand" "=r") - (plus:SWI48 (plus:SWI48 (match_op_dup 4 + (plus:SWI48 (plus:SWI48 (match_op_dup 5 [(match_dup 3) (const_int 0)]) (match_dup 1)) (match_dup 2)))] @@ -6837,6 +6878,18 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_expand "addcarry<mode>_0" + [(parallel + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand") + (match_operand:SWI48 2 "x86_64_general_operand")) + (match_dup 1))) + (set (match_operand:SWI48 0 "register_operand") + (plus:SWI48 (match_dup 1) (match_dup 2)))])] + "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)") + (define_insn "sub<mode>3_carry" [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (minus:SWI @@ -6870,18 +6923,67 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) +(define_insn "sub<mode>3_carry_ccc" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0")) + (plus:<DWI> + (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) + (zero_extend:<DWI> + (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe"))))) + (clobber (match_scratch:DWIH 0 "=r"))] + "" + "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "<MODE>")]) + +(define_insn "*sub<mode>3_carry_ccc_1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0")) + (plus:<DWI> + (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) + (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf")))) + (clobber (match_scratch:DWIH 0 "=r"))] + "" +{ + operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0); + return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}"; +} + [(set_attr "type" "alu") + (set_attr "mode" "<MODE>")]) + +;; The sign flag is set from the +;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2))) +;; result, the overflow flag likewise, but the overflow flag is also +;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows. +(define_insn "sub<mode>3_carry_ccgz" + [(set (reg:CCGZ FLAGS_REG) + (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0") + (match_operand:DWIH 2 "x86_64_general_operand" "rme") + (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))] + UNSPEC_SBB)) + (clobber (match_scratch:DWIH 0 "=r"))] + "" + "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "<MODE>")]) + (define_insn "subborrow<mode>" [(set (reg:CCC FLAGS_REG) (compare:CCC - (match_operand:SWI48 1 "nonimmediate_operand" "0") - (plus:SWI48 - (match_operator:SWI48 4 "ix86_carry_flag_operator" - [(match_operand 3 "flags_reg_operand") (const_int 0)]) - (match_operand:SWI48 2 "nonimmediate_operand" "rm")))) + (zero_extend:<DWI> + (match_operand:SWI48 1 "nonimmediate_operand" "0")) + (plus:<DWI> + (match_operator:<DWI> 4 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)]) + (zero_extend:<DWI> + (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))) (set (match_operand:SWI48 0 "register_operand" "=r") - (minus:SWI48 (minus:SWI48 (match_dup 1) - (match_op_dup 4 - [(match_dup 3) (const_int 0)])) + (minus:SWI48 (minus:SWI48 + (match_dup 1) + (match_operator:SWI48 5 "ix86_carry_flag_operator" + [(match_dup 3) (const_int 0)])) (match_dup 2)))] "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" @@ -6889,6 +6991,16 @@ (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) + +(define_expand "subborrow<mode>_0" + [(parallel + [(set (reg:CC FLAGS_REG) + (compare:CC + (match_operand:SWI48 1 "nonimmediate_operand") + (match_operand:SWI48 2 "<general_operand>"))) + (set (match_operand:SWI48 0 "register_operand") + (minus:SWI48 (match_dup 1) (match_dup 2)))])] + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)") ;; Overflow setting add instructions @@ -12286,6 +12398,34 @@ ix86_expand_clear (operands[3]); }) +(define_peephole2 + [(set (reg FLAGS_REG) (match_operand 0)) + (parallel [(set (reg FLAGS_REG) (match_operand 1)) + (match_operand 5)]) + (set (match_operand:QI 2 "register_operand") + (match_operator:QI 3 "ix86_comparison_operator" + [(reg FLAGS_REG) (const_int 0)])) + (set (match_operand 4 "any_QIreg_operand") + (zero_extend (match_dup 2)))] + "(peep2_reg_dead_p (4, operands[2]) + || operands_match_p (operands[2], operands[4])) + && ! reg_overlap_mentioned_p (operands[4], operands[0]) + && ! reg_overlap_mentioned_p (operands[4], operands[1]) + && ! reg_set_p (operands[4], operands[5]) + && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) + && peep2_regno_dead_p (0, FLAGS_REG)" + [(set (match_dup 6) (match_dup 0)) + (parallel [(set (match_dup 7) (match_dup 1)) + (match_dup 5)]) + (set (strict_low_part (match_dup 8)) + (match_dup 3))] +{ + operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); + operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); + operands[8] = gen_lowpart (QImode, operands[4]); + ix86_expand_clear (operands[4]); +}) + ;; Similar, but match zero extend with andsi3. (define_peephole2 @@ -12331,6 +12471,35 @@ operands[6] = gen_lowpart (QImode, operands[3]); ix86_expand_clear (operands[3]); }) + +(define_peephole2 + [(set (reg FLAGS_REG) (match_operand 0)) + (parallel [(set (reg FLAGS_REG) (match_operand 1)) + (match_operand 5)]) + (set (match_operand:QI 2 "register_operand") + (match_operator:QI 3 "ix86_comparison_operator" + [(reg FLAGS_REG) (const_int 0)])) + (parallel [(set (match_operand 4 "any_QIreg_operand") + (zero_extend (match_dup 2))) + (clobber (reg:CC FLAGS_REG))])] + "(peep2_reg_dead_p (4, operands[2]) + || operands_match_p (operands[2], operands[4])) + && ! reg_overlap_mentioned_p (operands[4], operands[0]) + && ! reg_overlap_mentioned_p (operands[4], operands[1]) + && ! reg_set_p (operands[4], operands[5]) + && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) + && peep2_regno_dead_p (0, FLAGS_REG)" + [(set (match_dup 6) (match_dup 0)) + (parallel [(set (match_dup 7) (match_dup 1)) + (match_dup 5)]) + (set (strict_low_part (match_dup 8)) + (match_dup 3))] +{ + operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); + operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); + operands[8] = gen_lowpart (QImode, operands[4]); + ix86_expand_clear (operands[4]); +}) ;; Call instructions. @@ -18135,6 +18304,28 @@ "* return output_probe_stack_range (operands[0], operands[2]);" [(set_attr "type" "multi")]) +/* Additional processing for builtin_setjmp. Store the shadow stack pointer + as a forth element in jmpbuf. */ +(define_expand "builtin_setjmp_setup" + [(match_operand 0 "address_operand")] + "TARGET_SHSTK" +{ + if (flag_cf_protection & CF_RETURN) + { + rtx mem, reg_ssp; + + mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], + 3 * GET_MODE_SIZE (Pmode))); + reg_ssp = gen_reg_rtx (Pmode); + emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); + emit_insn ((Pmode == SImode) + ? gen_rdsspsi (reg_ssp, reg_ssp) + : gen_rdsspdi (reg_ssp, reg_ssp)); + emit_move_insn (mem, reg_ssp); + } + DONE; +}) + (define_expand "builtin_setjmp_receiver" [(label_ref (match_operand 0))] "!TARGET_64BIT && flag_pic" @@ -18155,6 +18346,83 @@ DONE; }) +(define_expand "builtin_longjmp" + [(match_operand 0 "address_operand")] + "TARGET_SHSTK" +{ + rtx fp, lab, stack; + rtx jump, label, reg_adj, reg_ssp, reg_minus, mem_buf, tmp, clob; + machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); + + /* Adjust the shadow stack pointer (ssp) to the value saved in the + jmp_buf. The saving was done in the builtin_setjmp_setup. */ + if (flag_cf_protection & CF_RETURN) + { + /* Get current shadow stack pointer. The code below will check if + SHSTK feature is enabled. If it's not enabled RDSSP instruction + is a NOP. */ + reg_ssp = gen_reg_rtx (Pmode); + emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); + emit_insn ((Pmode == SImode) + ? gen_rdsspsi (reg_ssp, reg_ssp) + : gen_rdsspdi (reg_ssp, reg_ssp)); + mem_buf = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], + 3 * GET_MODE_SIZE (Pmode))), + + /* Compare through substraction the saved and the current ssp to decide + if ssp has to be adjusted. */ + reg_minus = gen_reg_rtx (Pmode); + tmp = gen_rtx_SET (reg_minus, gen_rtx_MINUS (Pmode, reg_ssp, mem_buf)); + clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); + tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); + emit_insn (tmp); + + /* Jump over adjustment code. */ + label = gen_label_rtx (); + tmp = gen_rtx_REG (CCmode, FLAGS_REG); + tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); + tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, + gen_rtx_LABEL_REF (VOIDmode, label), + pc_rtx); + jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); + JUMP_LABEL (jump) = label; + + /* Adjust the ssp. */ + reg_adj = gen_reg_rtx (Pmode); + tmp = gen_rtx_SET (reg_adj, + gen_rtx_LSHIFTRT (Pmode, negate_rtx (Pmode, reg_minus), + GEN_INT (3))); + clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); + tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); + emit_insn (tmp); + emit_insn ((Pmode == SImode) + ? gen_incsspsi (reg_adj) + : gen_incsspdi (reg_adj)); + + emit_label (label); + LABEL_NUSES (label) = 1; + } + + /* This code is the same as in expand_buildin_longjmp. */ + fp = gen_rtx_MEM (Pmode, operands[0]); + lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], + GET_MODE_SIZE (Pmode))); + stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0], + 2 * GET_MODE_SIZE (Pmode))); + lab = copy_to_reg (lab); + + emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); + emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); + + emit_move_insn (hard_frame_pointer_rtx, fp); + emit_stack_restore (SAVE_NONLOCAL, stack); + + emit_use (hard_frame_pointer_rtx); + emit_use (stack_pointer_rtx); + emit_indirect_jump (lab); +}) + + ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. ;; Do not split instructions with mask registers. (define_split @@ -18814,7 +19082,7 @@ (clobber (mem:BLK (scratch)))])] "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) - && !ix86_using_red_zone ()" + && ix86_red_zone_size == 0" [(clobber (match_dup 1)) (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (clobber (mem:BLK (scratch)))])]) @@ -18828,7 +19096,7 @@ (clobber (mem:BLK (scratch)))])] "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) - && !ix86_using_red_zone ()" + && ix86_red_zone_size == 0" [(clobber (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) @@ -18843,7 +19111,7 @@ (clobber (reg:CC FLAGS_REG))])] "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) - && !ix86_using_red_zone ()" + && ix86_red_zone_size == 0" [(clobber (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) @@ -18855,7 +19123,7 @@ (clobber (reg:CC FLAGS_REG))])] "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) - && !ix86_using_red_zone ()" + && ix86_red_zone_size == 0" [(clobber (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) @@ -19775,6 +20043,83 @@ [(set_attr "length" "2") (set_attr "memory" "unknown")]) +;; CET instructions +(define_insn "rdssp<mode>" + [(set (match_operand:SWI48x 0 "register_operand" "=r") + (unspec_volatile:SWI48x + [(match_operand:SWI48x 1 "register_operand" "0")] + UNSPECV_NOP_RDSSP))] + "TARGET_SHSTK" + "rdssp<mskmodesuffix>\t%0" + [(set_attr "length" "4") + (set_attr "type" "other")]) + +(define_insn "incssp<mode>" + [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")] + UNSPECV_INCSSP)] + "TARGET_SHSTK" + "incssp<mskmodesuffix>\t%0" + [(set_attr "length" "4") + (set_attr "type" "other")]) + +(define_insn "saveprevssp" + [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)] + "TARGET_SHSTK" + "saveprevssp" + [(set_attr "length" "5") + (set_attr "type" "other")]) + +(define_insn "rstorssp" + [(unspec_volatile [(match_operand 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")] + 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")] + UNSPECV_WRUSS)] + "TARGET_SHSTK" + "wruss<mskmodesuffix>\t%0, %1" + [(set_attr "length" "4") + (set_attr "type" "other")]) + +(define_insn "setssbsy" + [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)] + "TARGET_SHSTK" + "setssbsy" + [(set_attr "length" "4") + (set_attr "type" "other")]) + +(define_insn "clrssbsy" + [(unspec_volatile [(match_operand 0 "memory_operand" "m")] + UNSPECV_CLRSSBSY)] + "TARGET_SHSTK" + "clrssbsy\t%0" + [(set_attr "length" "4") + (set_attr "type" "other")]) + +(define_insn "nop_endbr" + [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)] + "TARGET_IBT" + "* +{ return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }" + [(set_attr "length" "4") + (set_attr "length_immediate" "0") + (set_attr "modrm" "0")]) + +;; For RTM support (define_expand "xbegin" [(set (match_operand:SI 0 "register_operand") (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))] |