gcc/ChangeLog: * gcc/config/riscv/riscv.cc (is_zicfilp_p): New function. (is_zicfiss_p): New function. * gcc/config/riscv/riscv-zicfilp.cc: Update. * gcc/config/riscv/riscv.h: Update. * gcc/config/riscv/riscv.md: Update. --- gcc/config/riscv/riscv-zicfilp.cc | 2 +- gcc/config/riscv/riscv.cc | 52 ++++++++++++++++++++++++------- gcc/config/riscv/riscv.h | 8 +++-- gcc/config/riscv/riscv.md | 10 +++--- 4 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/gcc/config/riscv/riscv-zicfilp.cc b/gcc/config/riscv/riscv-zicfilp.cc index f3015385aa9..1865a90bd04 100644 --- a/gcc/config/riscv/riscv-zicfilp.cc +++ b/gcc/config/riscv/riscv-zicfilp.cc @@ -150,7 +150,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { - return TARGET_ZICFILP; + return is_zicfilp_p (); } virtual unsigned int execute (function *) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index bda982f085c..cb69eaa3c43 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6615,7 +6615,7 @@ riscv_legitimize_call_address (rtx addr) rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode); riscv_emit_move (reg, addr); - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) { rtx sw_guarded = RISCV_CALL_ADDRESS_LPAD (Pmode); emit_insn (gen_set_guarded (Pmode, reg)); @@ -6625,7 +6625,7 @@ riscv_legitimize_call_address (rtx addr) return reg; } - if (TARGET_ZICFILP && REG_P (addr)) + if (is_zicfilp_p () && REG_P (addr)) emit_insn (gen_set_lpl (Pmode, const1_rtx)); return addr; @@ -7391,7 +7391,7 @@ riscv_save_reg_p (unsigned int regno) if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM) return false; - if (regno == RETURN_ADDR_REGNUM && TARGET_ZICFISS) + if (regno == RETURN_ADDR_REGNUM && is_zicfiss_p ()) return true; /* We must save every register used in this function. If this is not a @@ -10202,10 +10202,10 @@ riscv_file_end_indicate_exec_stack () long GNU_PROPERTY_RISCV_FEATURE_1_AND = 0; unsigned long feature_1_and = 0; - if (TARGET_ZICFISS) + if (is_zicfilp_p ()) feature_1_and |= 0x1 << 0; - if (TARGET_ZICFILP) + if (is_zicfiss_p ()) feature_1_and |= 0x1 << 1; if (feature_1_and) @@ -10265,7 +10265,7 @@ riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, /* Mark the end of the (empty) prologue. */ emit_note (NOTE_INSN_PROLOGUE_END); - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) emit_insn(gen_lpad (const1_rtx)); /* Determine if we can use a sibcall to call FUNCTION directly. */ @@ -10488,6 +10488,20 @@ riscv_override_options_internal (struct gcc_options *opts) /* Convert -march and -mrvv-vector-bits to a chunks count. */ riscv_vector_chunks = riscv_convert_vector_chunks (opts); + + if (opts->x_flag_cf_protection != CF_NONE) + { + if ((opts->x_flag_cf_protection & CF_RETURN) == CF_RETURN + && !TARGET_ZICFISS) + error ("%<-fcf-protection%> is not compatible with this target"); + + if ((opts->x_flag_cf_protection & CF_BRANCH) == CF_BRANCH + && !TARGET_ZICFILP) + error ("%<-fcf-protection%> is not compatible with this target"); + + opts->x_flag_cf_protection + = (cf_protection_level) (opts->x_flag_cf_protection | CF_SET); + } } /* Implement TARGET_OPTION_OVERRIDE. */ @@ -10778,7 +10792,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) /* Work out the offsets of the pointers from the start of the trampoline code. */ - if (!TARGET_ZICFILP) + if (!is_zicfilp_p ()) gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE); else gcc_assert (ARRAY_SIZE (trampoline_cfi) * 4 == TRAMPOLINE_CODE_SIZE); @@ -10806,7 +10820,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) unsigned insn_count = 0; /* Insert lpad, if zicfilp is enabled. */ - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) { unsigned HOST_WIDE_INT lpad_code; lpad_code = OPCODE_AUIPC | (0 << SHIFT_RD) | (lp_value << IMM_BITS); @@ -10868,7 +10882,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) insn_count++; /* For zicfilp only, insert lui t2, 1, because use jr t0. */ - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) { unsigned HOST_WIDE_INT set_lpl_code; set_lpl_code = OPCODE_LUI @@ -10898,7 +10912,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) static_chain_offset = TRAMPOLINE_CODE_SIZE; target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode); - if (!TARGET_ZICFILP) + if (!is_zicfilp_p ()) { /* auipc t2, 0 l[wd] t0, (target_function_offset)(t2) @@ -13634,9 +13648,25 @@ riscv_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size, return default_use_by_pieces_infrastructure_p (size, alignment, op, speed_p); } +bool is_zicfiss_p () +{ + if (TARGET_ZICFISS && (flag_cf_protection & CF_RETURN)) + return true; + + return false; +} + +bool is_zicfilp_p () +{ + if (TARGET_ZICFILP && (flag_cf_protection & CF_BRANCH)) + return true; + + return false; +} + bool need_shadow_stack_push_pop_p () { - return TARGET_ZICFISS && riscv_save_return_addr_reg_p (); + return is_zicfilp_p () && riscv_save_return_addr_reg_p (); } /* Initialize the GCC target structure. */ diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index d94245789e0..508ec367b87 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -193,7 +193,7 @@ ASM_MISA_SPEC /* Allocation boundary (in *bits*) for the code of a function. */ #define FUNCTION_BOUNDARY \ - (((TARGET_RVC || TARGET_ZCA) && !TARGET_ZICFILP) ? 16 : 32) + (((TARGET_RVC || TARGET_ZCA) && !is_zicfilp_p ()) ? 16 : 32) /* The smallest supported stack boundary the calling convention supports. */ #define STACK_BOUNDARY \ @@ -417,7 +417,7 @@ ASM_MISA_SPEC /* Register in which static-chain is passed to a function. */ #define STATIC_CHAIN_REGNUM \ - ((TARGET_ZICFILP) ? (GP_TEMP_FIRST + 23) : (GP_TEMP_FIRST + 2)) + ((is_zicfilp_p ()) ? (GP_TEMP_FIRST + 23) : (GP_TEMP_FIRST + 2)) /* Registers used as temporaries in prologue/epilogue code. @@ -823,7 +823,7 @@ extern enum riscv_cc get_riscv_cc (const rtx use); /* Trampolines are a block of code followed by two pointers. */ -#define TRAMPOLINE_CODE_SIZE ((TARGET_ZICFILP) ? 24 : 16) +#define TRAMPOLINE_CODE_SIZE ((is_zicfilp_p ()) ? 24 : 16) #define TRAMPOLINE_SIZE \ ((Pmode == SImode) \ @@ -1192,6 +1192,8 @@ extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int); extern poly_int64 riscv_v_adjust_nunits (machine_mode, bool, int, int); extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int); extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int); +extern bool is_zicfiss_p (); +extern bool is_zicfilp_p (); extern bool need_shadow_stack_push_pop_p (); /* The number of bits and bytes in a RVV vector. */ #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8)) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 9a5149bc941..b7414a0984b 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3681,11 +3681,11 @@ [(set (pc) (match_operand 0 "register_operand"))] "" { - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) emit_insn (gen_set_lpl (Pmode, const1_rtx)); operands[0] = force_reg (Pmode, operands[0]); - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) emit_use (gen_rtx_REG (Pmode, T2_REGNUM)); if (Pmode == SImode) @@ -3713,7 +3713,7 @@ gen_rtx_LABEL_REF (Pmode, operands[1]), NULL_RTX, 0, OPTAB_DIRECT); - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) { rtx t2 = RISCV_CALL_ADDRESS_LPAD (GET_MODE (operands[0])); emit_move_insn (t2, operands[0]); @@ -3736,7 +3736,7 @@ (define_insn "tablejump<mode>" [(set (pc) (match_operand:GPR 0 "register_operand" "l")) (use (label_ref (match_operand 1 "" "")))] - "!TARGET_ZICFILP" + "!is_zicfilp_p ()" "jr\t%0" [(set_attr "type" "jalr") (set_attr "mode" "none")]) @@ -3744,7 +3744,7 @@ (define_insn "tablejump_cfi<mode>" [(set (pc) (reg:GPR T2_REGNUM)) (use (label_ref (match_operand 0 "")))] - "TARGET_ZICFILP" + "is_zicfilp_p ()" "jr\tt2" [(set_attr "type" "jalr") (set_attr "mode" "none")]) -- 2.40.1