Skip to content

Commit 6e5ee4a

Browse files
authored
[RISCV] Save vector registers in interrupt handler. (#143808)
Corresponding gcc bug report https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110665 The generated code is pretty awful.
1 parent 874a02f commit 6e5ee4a

File tree

4 files changed

+7360
-2
lines changed

4 files changed

+7360
-2
lines changed

llvm/lib/Target/RISCV/RISCVCallingConv.td

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,40 @@ def CSR_XLEN_F32_Interrupt: CalleeSavedRegs<(add CSR_Interrupt,
5656
def CSR_XLEN_F64_Interrupt: CalleeSavedRegs<(add CSR_Interrupt,
5757
(sequence "F%u_D", 0, 31))>;
5858

59+
// Same as CSR_Interrupt, but including all vector registers.
60+
def CSR_XLEN_V_Interrupt: CalleeSavedRegs<(add CSR_Interrupt,
61+
(sequence "V%u", 0, 31))>;
62+
63+
// Same as CSR_Interrupt, but including all 32-bit FP registers and all vector
64+
// registers.
65+
def CSR_XLEN_F32_V_Interrupt: CalleeSavedRegs<(add CSR_XLEN_F32_Interrupt,
66+
(sequence "V%u", 0, 31))>;
67+
68+
// Same as CSR_Interrupt, but including all 64-bit FP registers and all vector
69+
// registers.
70+
def CSR_XLEN_F64_V_Interrupt: CalleeSavedRegs<(add CSR_XLEN_F64_Interrupt,
71+
(sequence "V%u", 0, 31))>;
72+
5973
// Same as CSR_Interrupt, but excluding X16-X31.
6074
def CSR_Interrupt_RVE : CalleeSavedRegs<(sub CSR_Interrupt,
6175
(sequence "X%u", 16, 31))>;
6276

6377
// Same as CSR_XLEN_F32_Interrupt, but excluding X16-X31.
6478
def CSR_XLEN_F32_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F32_Interrupt,
65-
(sequence "X%u", 16, 31))>;
79+
(sequence "X%u", 16, 31))>;
6680

6781
// Same as CSR_XLEN_F64_Interrupt, but excluding X16-X31.
6882
def CSR_XLEN_F64_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F64_Interrupt,
69-
(sequence "X%u", 16, 31))>;
83+
(sequence "X%u", 16, 31))>;
84+
85+
// Same as CSR_XLEN_V_Interrupt, but excluding X16-X31.
86+
def CSR_XLEN_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_V_Interrupt,
87+
(sequence "X%u", 16, 31))>;
88+
89+
// Same as CSR_XLEN_F32_V_Interrupt, but excluding X16-X31.
90+
def CSR_XLEN_F32_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F32_V_Interrupt,
91+
(sequence "X%u", 16, 31))>;
92+
93+
// Same as CSR_XLEN_F64_V_Interrupt, but excluding X16-X31.
94+
def CSR_XLEN_F64_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F64_V_Interrupt,
95+
(sequence "X%u", 16, 31))>;

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
6969
if (MF->getFunction().getCallingConv() == CallingConv::GHC)
7070
return CSR_NoRegs_SaveList;
7171
if (MF->getFunction().hasFnAttribute("interrupt")) {
72+
if (Subtarget.hasVInstructions()) {
73+
if (Subtarget.hasStdExtD())
74+
return Subtarget.hasStdExtE() ? CSR_XLEN_F64_V_Interrupt_RVE_SaveList
75+
: CSR_XLEN_F64_V_Interrupt_SaveList;
76+
if (Subtarget.hasStdExtF())
77+
return Subtarget.hasStdExtE() ? CSR_XLEN_F32_V_Interrupt_RVE_SaveList
78+
: CSR_XLEN_F32_V_Interrupt_SaveList;
79+
return Subtarget.hasStdExtE() ? CSR_XLEN_V_Interrupt_RVE_SaveList
80+
: CSR_XLEN_V_Interrupt_SaveList;
81+
}
7282
if (Subtarget.hasStdExtD())
7383
return Subtarget.hasStdExtE() ? CSR_XLEN_F64_Interrupt_RVE_SaveList
7484
: CSR_XLEN_F64_Interrupt_SaveList;

0 commit comments

Comments
 (0)