summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
diff options
context:
space:
mode:
authorAlex Bradbury <asb@lowrisc.org>2018-01-10 19:41:03 +0000
committerAlex Bradbury <asb@lowrisc.org>2018-01-10 19:41:03 +0000
commitc85be0de56f8f1f15b6ed17f0b7ee88386cd791e (patch)
tree345fbc8a4a0fe06a7289ce3d91bf8aaa20d753dc /llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
parent29e3f5b7224070bcc8a333b583bb5beb9630c352 (diff)
downloadbcm5719-llvm-c85be0de56f8f1f15b6ed17f0b7ee88386cd791e.tar.gz
bcm5719-llvm-c85be0de56f8f1f15b6ed17f0b7ee88386cd791e.zip
[RISCV] Support for varargs
Includes support for expanding va_copy. Also adds support for using 'aligned' registers when necessary for vararg calls, and ensure the frame pointer always points to the bottom of the vararg spill region. This is necessary to ensure that the saved return address and stack pointer are always available at fixed known offsets of the frame pointer. Differential Revision: https://reviews.llvm.org/D40805 llvm-svn: 322215
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/RISCV/RISCVFrameLowering.cpp15
1 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index e9e003e63d5..e1448ba7e2b 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RISCVFrameLowering.h"
+#include "RISCVMachineFunctionInfo.h"
#include "RISCVSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -91,6 +92,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
}
MachineFrameInfo &MFI = MF.getFrameInfo();
+ auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
unsigned FPReg = getFPReg(STI);
@@ -124,7 +126,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
std::advance(MBBI, CSI.size());
// Generate new FP.
- adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize, MachineInstr::FrameSetup);
+ adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize - RVFI->getVarArgsSaveSize(),
+ MachineInstr::FrameSetup);
}
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
@@ -137,6 +140,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();
+ auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
DebugLoc DL = MBBI->getDebugLoc();
unsigned FPReg = getFPReg(STI);
unsigned SPReg = getSPReg(STI);
@@ -153,7 +157,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
// necessary if the stack pointer was modified, meaning the stack size is
// unknown.
if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) {
- adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -StackSize,
+ adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
+ -StackSize + RVFI->getVarArgsSaveSize(),
MachineInstr::FrameDestroy);
}
@@ -166,6 +171,7 @@ int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,
unsigned &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
+ const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
// Callee-saved registers should be referenced relative to the stack
// pointer (positive offset), otherwise use the frame pointer (negative
@@ -182,10 +188,13 @@ int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,
MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
}
- FrameReg = RI->getFrameRegister(MF);
if (FI >= MinCSFI && FI <= MaxCSFI) {
FrameReg = RISCV::X2;
Offset += MF.getFrameInfo().getStackSize();
+ } else {
+ FrameReg = RI->getFrameRegister(MF);
+ assert(hasFP(MF) && "Offset calculation incorrect if !hasFP");
+ Offset += RVFI->getVarArgsSaveSize();
}
return Offset;
}
OpenPOWER on IntegriCloud