diff options
author | Kito Cheng <kito.cheng@sifive.com> | 2023-12-25 16:45:21 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2024-01-04 15:52:33 +0800 |
commit | 73a4f67b9c8c497d87fda44160953293bc4e11e5 (patch) | |
tree | ad51b61713d990a4e4b75d0e0b430fb2936cc9bd /gcc | |
parent | 15053a3e168e112b9e1b0c9be4bba06cf5be964f (diff) | |
download | gcc-73a4f67b9c8c497d87fda44160953293bc4e11e5.zip gcc-73a4f67b9c8c497d87fda44160953293bc4e11e5.tar.gz gcc-73a4f67b9c8c497d87fda44160953293bc4e11e5.tar.bz2 |
RISC-V: Fix misaligned stack offset for interrupt function
`interrupt` function will backup fcsr register, but it fixed to SImode,
it's not big issue since fcsr only used 8 bits so far, however the
offset should still using UNITS_PER_WORD to prevent the stack offset
become non 8 byte aligned, it will cause problem for RV64.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_for_each_saved_reg): Adjust the
offset of fcsr.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/interrupt-misaligned.c: New.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/riscv/riscv.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/interrupt-misaligned.c | 29 |
2 files changed, 32 insertions, 1 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index c4bc9d1..7b63c67 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6718,7 +6718,9 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, || (TARGET_ZFINX && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM))))) { - unsigned int fcsr_size = GET_MODE_SIZE (SImode); + /* Always assume FCSR occupy UNITS_PER_WORD to prevent stack + offset misaligned later. */ + unsigned int fcsr_size = UNITS_PER_WORD; if (!epilogue) { riscv_save_restore_reg (word_mode, regno, offset, fn); diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-misaligned.c b/gcc/testsuite/gcc.target/riscv/interrupt-misaligned.c new file mode 100644 index 0000000..b5f8e6c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/interrupt-misaligned.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-skip-if "" { *-*-* } { "-flto -fno-fat-lto-objects" } } */ + +/* Make sure no stack offset are misaligned. +** interrupt: +** ... +** sd\tt0,40\(sp\) +** frcsr\tt0 +** sw\tt0,32\(sp\) +** sd\tt1,24\(sp\) +** fsd\tft0,8\(sp\) +** ... +** lw\tt0,32\(sp\) +** fscsr\tt0 +** ld\tt0,40\(sp\) +** ld\tt1,24\(sp\) +** fld\tft0,8\(sp\) +** ... +*/ + + +void interrupt(void) __attribute__((interrupt)); +void interrupt(void) +{ + asm volatile ("# clobber!":::"t0", "t1", "ft0"); +} + +/* { dg-final { check-function-bodies "**" "" } } */ |