aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/riscv
diff options
context:
space:
mode:
authorMonk Chiang <monk.chiang@sifive.com>2024-11-15 13:38:48 +0800
committerMonk Chiang <monk.chiang@sifive.com>2025-01-17 10:49:16 +0800
commitdc76aa0e4d5398104b6b26f08b46524b97de5100 (patch)
tree7210fc03f9544ca682238548dd4768490651e16e /gcc/testsuite/gcc.target/riscv
parent29da6a642402ac64002f5edeab268606b4637103 (diff)
downloadgcc-dc76aa0e4d5398104b6b26f08b46524b97de5100.zip
gcc-dc76aa0e4d5398104b6b26f08b46524b97de5100.tar.gz
gcc-dc76aa0e4d5398104b6b26f08b46524b97de5100.tar.bz2
RISC-V: Add Zicfiss ISA extension.
This patch is implemented according to the RISC-V CFI specification. It supports the generation of shadow stack instructions in the prologue, epilogue, non-local gotos, and unwinding. RISC-V CFI SPEC: https://github.com/riscv/riscv-cfi gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add ZICFISS ISA string. * config/riscv/predicates.md: New predicate x1x5_operand. * config/riscv/riscv.cc (riscv_expand_prologue): Insert shadow stack instructions. (riscv_expand_epilogue): Likewise. (riscv_for_each_saved_reg): Assign t0 or ra register for sspopchk instruction. (need_shadow_stack_push_pop_p): New function. Omit shadow stack operation on leaf function. * config/riscv/riscv.h (need_shadow_stack_push_pop_p): Define. * config/riscv/riscv.md: Add shadow stack patterns. (save_stack_nonlocal): Add shadow stack instructions for setjump. (restore_stack_nonlocal): Add shadow stack instructions for longjump. * config/riscv/riscv.opt (TARGET_ZICFISS): Define. libgcc/ChangeLog: * config/riscv/linux-unwind.h: Include shadow-stack-unwind.h. * config/riscv/shadow-stack-unwind.h (_Unwind_Frames_Extra): Define. (_Unwind_Frames_Increment): Define. gcc/testsuite/ChangeLog: * gcc.target/riscv/ssp-1.c: New test. * gcc.target/riscv/ssp-2.c: New test. Co-Developed-by: Greg McGary <gkm@rivosinc.com>, Kito Cheng <kito.cheng@gmail.com>
Diffstat (limited to 'gcc/testsuite/gcc.target/riscv')
-rw-r--r--gcc/testsuite/gcc.target/riscv/ssp-1.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/ssp-2.c10
2 files changed, 51 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/riscv/ssp-1.c b/gcc/testsuite/gcc.target/riscv/ssp-1.c
new file mode 100644
index 0000000..abf47ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ssp-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+struct ad {
+ void *ae;
+};
+struct af {
+ union {
+ int *ai;
+ int *aj;
+ struct ad *ak;
+ } u;
+ struct {
+ struct {
+ long al : 1;
+ long am : 1;
+ long : 21;
+ } b;
+ long i;
+ } s;
+};
+void fdes (struct af *, void *, long *);
+
+void foo (struct af *bv, long *bw) {
+ bw[0] = bw[1] = 0;
+ if (bv->s.b.al)
+ fdes (bv, bv->u.ak->ae, bw);
+ else if (bv->s.b.am) {
+ int **p = (int**)bv->u.aj;
+ for (; *p; ++p)
+ fdes (bv, *p, bw);
+ } else
+ fdes (bv, bv->u.ai, bw);
+}
+
+/* { dg-final { scan-assembler-times "ld\tt0" 1 } } */
+/* { dg-final { scan-assembler-times "sspopchk\tt0" 1 } } */
+/* { dg-final { scan-assembler-times "jr\tt0" 1 } } */
+/* { dg-final { scan-assembler-times "ld\tra" 2 } } */
+/* { dg-final { scan-assembler-times "sspopchk\tra" 2 } } */
+/* { dg-final { scan-assembler-times "tail" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/ssp-2.c b/gcc/testsuite/gcc.target/riscv/ssp-2.c
new file mode 100644
index 0000000..7c60983
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ssp-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d" } */
+
+void __attribute__ ((interrupt))
+foo (void)
+{
+}
+/* { dg-final { scan-assembler-times "sd\tra" 1 } } */
+/* { dg-final { scan-assembler-times "ld\tra" 1 } } */
+/* { dg-final { scan-assembler-times "sspopchk\tra" 1 } } */