summaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsFrameLowering.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanak@gmail.com>2011-06-07 02:17:21 +0000
committerAkira Hatanaka <ahatanak@gmail.com>2011-06-07 02:17:21 +0000
commit8464fff30b16d39227444985bb7c8cc7fd12d66d (patch)
tree09271e68f2927bf9c46f73bd6af62d30b766188f /lib/Target/Mips/MipsFrameLowering.cpp
parent9d507aec07c7e22c6ba83dfd75e23c8630cd25cd (diff)
downloadllvm-8464fff30b16d39227444985bb7c8cc7fd12d66d.tar.gz
llvm-8464fff30b16d39227444985bb7c8cc7fd12d66d.tar.bz2
llvm-8464fff30b16d39227444985bb7c8cc7fd12d66d.tar.xz
Add test case for C++ exception handling and fix the following mistakes in MipsFrameLowering::emitPrologue:
- cfi directives are not inserted at the right location or in the right order. - The source MachineLocation for the cfi directive that changes the cfa register to $fp should be MachineLocation::VirtualFP. - A PROLOG_LABEL that marks the beginning of cfi_offset directives for callee-saved register is emitted even when no callee-saved registers are saved. - When a callee-saved double precision register is saved, two cfi_offset directives, one for each of the paired single precision registers, should be emitted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132703 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsFrameLowering.cpp')
-rw-r--r--lib/Target/Mips/MipsFrameLowering.cpp90
1 files changed, 60 insertions, 30 deletions
diff --git a/lib/Target/Mips/MipsFrameLowering.cpp b/lib/Target/Mips/MipsFrameLowering.cpp
index 091c1b248f..c1ceda7ab0 100644
--- a/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/lib/Target/Mips/MipsFrameLowering.cpp
@@ -173,6 +173,10 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack()) return;
+ MachineModuleInfo &MMI = MF.getMMI();
+ std::vector<MachineMove> &Moves = MMI.getFrameMoves();
+ MachineLocation DstML, SrcML;
+
// Adjust stack : addi sp, sp, (-imm)
ATUsed = expandRegLargeImmPair(Mips::SP, -StackSize, NewReg, NewImm, MBB,
MBBI);
@@ -183,49 +187,75 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
+ // emit ".cfi_def_cfa_offset StackSize"
+ MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl,
+ TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
+ DstML = MachineLocation(MachineLocation::VirtualFP);
+ SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
+ Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
+
// Find the instruction past the last instruction that saves a callee-saved
// register to the stack.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
-
- for (unsigned i = 0; i < CSI.size(); ++i)
- ++MBBI;
+
+ if (CSI.size()) {
+ for (unsigned i = 0; i < CSI.size(); ++i)
+ ++MBBI;
+ // Iterate over list of callee-saved registers and emit .cfi_offset directives.
+ MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl,
+ TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
+
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
+ E = CSI.end(); I != E; ++I) {
+ int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
+ unsigned Reg = I->getReg();
+
+ // If Reg is a double precision register, emit two cfa_offsets,
+ // one for each of the paired single precision registers.
+ if (Mips::AFGR64RegisterClass->contains(Reg)) {
+ const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
+ MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
+ MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
+ MachineLocation SrcML0(*SubRegs);
+ MachineLocation SrcML1(*(SubRegs + 1));
+
+ if (!STI.isLittle())
+ std::swap(SrcML0, SrcML1);
+
+ Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
+ Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
+ }
+ else {
+ // Reg is either in CPURegs or FGR32.
+ DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
+ SrcML = MachineLocation(Reg);
+ Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
+ }
+ }
+ }
+
// if framepointer enabled, set it to point to the stack pointer.
- if (hasFP(MF))
+ if (hasFP(MF)) {
// Insert instruction "move $fp, $sp" at this location.
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP)
.addReg(Mips::SP).addReg(Mips::ZERO);
+ // emit ".cfi_def_cfa_register $fp"
+ MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl,
+ TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
+ DstML = MachineLocation(Mips::FP);
+ SrcML = MachineLocation(MachineLocation::VirtualFP);
+ Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
+ }
+
// Restore GP from the saved stack location
if (MipsFI->needGPSaveRestore())
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE))
.addImm(MFI->getObjectOffset(MipsFI->getGPFI()));
-
- // EH Frame infomation.
- MachineModuleInfo &MMI = MF.getMMI();
- std::vector<MachineMove> &Moves = MMI.getFrameMoves();
- MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
- BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(FrameLabel);
-
- if (hasFP(MF)) {
- MachineLocation SPDst(Mips::FP);
- MachineLocation SPSrc(Mips::SP);
- Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
- }
-
- if (StackSize) {
- MachineLocation SPDst(MachineLocation::VirtualFP);
- MachineLocation SPSrc(MachineLocation::VirtualFP, -StackSize);
- Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
- }
-
- for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
- E = CSI.end(); I != E; ++I) {
- int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
- MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
- MachineLocation CSSrc(I->getReg());
- Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc));
- }
}
void MipsFrameLowering::emitEpilogue(MachineFunction &MF,