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/testsuite/ChangeLog: * gcc/testsuite/c-c++-common/fcf-protection-1.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-2.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-3.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-4.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-5.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-6.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-7.c: Update. * gcc/testsuite/gcc.target/riscv/ssp-1.c: Update. * gcc/testsuite/gcc.target/riscv/ssp-2.c: Update. * gcc/testsuite/gcc.target/riscv/zicfilp-call.c: Update. * gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c: 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 ++-- gcc/testsuite/c-c++-common/fcf-protection-1.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-2.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-3.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-4.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-5.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-6.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-7.c | 1 + .../gcc.target/riscv/interrupt-no-lpad.c | 2 +- gcc/testsuite/gcc.target/riscv/ssp-1.c | 2 +- gcc/testsuite/gcc.target/riscv/ssp-2.c | 2 +- gcc/testsuite/gcc.target/riscv/zicfilp-call.c | 2 +- 15 files changed, 63 insertions(+), 24 deletions(-) diff --git a/gcc/config/riscv/riscv-zicfilp.cc b/gcc/config/riscv/riscv-zicfilp.cc index 42b129920b3..834d6e5c778 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 cb448aba9c0..8a4e23851d7 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6682,7 +6682,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)); @@ -6692,7 +6692,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, const0_rtx)); return addr; @@ -7508,7 +7508,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 @@ -10341,10 +10341,10 @@ riscv_file_end () 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) @@ -10404,7 +10404,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 (const0_rtx)); /* Determine if we can use a sibcall to call FUNCTION directly. */ @@ -10631,6 +10631,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. */ @@ -10925,7 +10939,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); @@ -10953,7 +10967,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); @@ -11015,7 +11029,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 @@ -11045,7 +11059,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) @@ -13960,9 +13974,25 @@ expand_reversed_crc_using_clmul (scalar_mode crc_mode, scalar_mode data_mode, riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0)); } +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_zicfiss_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 073b9e4f2bd..2bcabd03517 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -191,7 +191,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 \ @@ -415,7 +415,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. @@ -827,7 +827,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) \ @@ -1196,6 +1196,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 5b4c81bb9e0..d626a350ee4 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3716,11 +3716,11 @@ [(set (pc) (match_operand 0 "register_operand"))] "" { - if (TARGET_ZICFILP) + if (is_zicfilp_p ()) emit_insn (gen_set_lpl (Pmode, const0_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) @@ -3748,7 +3748,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]); @@ -3771,7 +3771,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")]) @@ -3779,7 +3779,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")]) diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c index f59a8fbdfdc..cc30c921a16 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-1.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c @@ -1,3 +1,4 @@ /* { dg-do compile } */ /* { dg-options "-fcf-protection=full" } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c index 61059725af6..e318989f290 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-2.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c @@ -1,3 +1,4 @@ /* { dg-do compile } */ /* { dg-options "-fcf-protection=branch" } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c index 257e944c4a6..dd60017dde0 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-3.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c @@ -1,3 +1,4 @@ /* { dg-do compile } */ /* { dg-options "-fcf-protection=return" } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-4.c b/gcc/testsuite/c-c++-common/fcf-protection-4.c index af4fc0b2812..2bde6e1e767 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-4.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-4.c @@ -1,2 +1,3 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-options "-fcf-protection=none" } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c index dc317f84b07..8c675c5f483 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-5.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c @@ -1,3 +1,4 @@ /* { dg-do compile } */ /* { dg-options "-fcf-protection" } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-6.c b/gcc/testsuite/c-c++-common/fcf-protection-6.c index 61059725af6..e318989f290 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-6.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-6.c @@ -1,3 +1,4 @@ /* { dg-do compile } */ /* { dg-options "-fcf-protection=branch" } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-7.c b/gcc/testsuite/c-c++-common/fcf-protection-7.c index 257e944c4a6..dd60017dde0 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-7.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-7.c @@ -1,3 +1,4 @@ /* { dg-do compile } */ /* { dg-options "-fcf-protection=return" } */ +/* { dg-skip-if "" { "riscv*-*-*" } } */ /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */ diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c b/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c index ff512b98c61..1290b373f08 100644 --- a/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c +++ b/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { riscv64*-*-* } } } */ -/* { dg-options "-march=rv64gc_zicfilp -mabi=lp64d" } */ +/* { dg-options "-march=rv64gc_zicfilp -mabi=lp64d -fcf-protection=branch" } */ void __attribute__ ((interrupt)) foo (void) { diff --git a/gcc/testsuite/gcc.target/riscv/ssp-1.c b/gcc/testsuite/gcc.target/riscv/ssp-1.c index abf47ec6442..24e3010c3cc 100644 --- a/gcc/testsuite/gcc.target/riscv/ssp-1.c +++ b/gcc/testsuite/gcc.target/riscv/ssp-1.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { riscv64*-*-* } } } */ -/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d" } */ +/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d -fcf-protection=return" } */ /* { dg-skip-if "" { *-*-* } { "-O0" } } */ struct ad { void *ae; diff --git a/gcc/testsuite/gcc.target/riscv/ssp-2.c b/gcc/testsuite/gcc.target/riscv/ssp-2.c index 7c6098357e9..9d3d6b27038 100644 --- a/gcc/testsuite/gcc.target/riscv/ssp-2.c +++ b/gcc/testsuite/gcc.target/riscv/ssp-2.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { riscv64*-*-* } } } */ -/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d" } */ +/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d -fcf-protection=return" } */ void __attribute__ ((interrupt)) foo (void) diff --git a/gcc/testsuite/gcc.target/riscv/zicfilp-call.c b/gcc/testsuite/gcc.target/riscv/zicfilp-call.c index 75c8b32faa3..eb9e1468e7f 100644 --- a/gcc/testsuite/gcc.target/riscv/zicfilp-call.c +++ b/gcc/testsuite/gcc.target/riscv/zicfilp-call.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { riscv64*-*-* } } } */ -/* { dg-options "-O2 -fPIE -march=rv64gc_zicfilp -mabi=lp64d" } */ +/* { dg-options "-O2 -fPIE -march=rv64gc_zicfilp -mabi=lp64d -fcf-protection=branch" } */ /* { dg-skip-if "" { *-*-* } { "-O0" } } */ extern void _dl_find_object_init (void); -- 2.47.1