[llvm] 9a9c6b8 - [MSP430] Add CFI instructions for MSP430.
Anton Korobeynikov via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 5 15:53:10 PDT 2023
Author: Ilia Kuklin
Date: 2023-04-05T15:53:01-07:00
New Revision: 9a9c6b8e7587d0459393024e793e299c96bde0d2
URL: https://github.com/llvm/llvm-project/commit/9a9c6b8e7587d0459393024e793e299c96bde0d2
DIFF: https://github.com/llvm/llvm-project/commit/9a9c6b8e7587d0459393024e793e299c96bde0d2.diff
LOG: [MSP430] Add CFI instructions for MSP430.
Implement emission of DWARF CFI instructions for MSP430. This includes descriptions of stack frame layout and location of callee-saved registers that could be used for backtracing.
Differential Revision: https://reviews.llvm.org/D146966
Added:
llvm/test/DebugInfo/MSP430/fp-vla-callee-saved.ll
Modified:
llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp
llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h
llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp
llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h
llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp
llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
llvm/lib/Target/MSP430/MSP430FrameLowering.h
llvm/lib/Target/MSP430/MSP430InstrInfo.h
llvm/lib/Target/MSP430/MSP430RegisterInfo.h
llvm/lib/Target/MSP430/MSP430RegisterInfo.td
llvm/lib/Target/MSP430/MSP430Subtarget.cpp
llvm/lib/Target/MSP430/MSP430Subtarget.h
llvm/test/CodeGen/MSP430/asm-clobbers.ll
llvm/test/CodeGen/MSP430/callee-saved.ll
llvm/test/CodeGen/MSP430/interrupt.ll
llvm/test/CodeGen/MSP430/jumptable.ll
llvm/test/DebugInfo/MSP430/dwarf-basics-v5.ll
llvm/test/DebugInfo/MSP430/dwarf-basics.ll
llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_function_name.ll.expected
llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.generated.expected
llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.nogenerated.expected
Removed:
################################################################################
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp
index 420893f65d5b9..3726c600f4a7b 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp
@@ -26,6 +26,10 @@ using namespace llvm;
#define PRINT_ALIAS_INSTR
#include "MSP430GenAsmWriter.inc"
+void MSP430InstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
+ O << getRegisterName(Reg);
+}
+
void MSP430InstPrinter::printInst(const MCInst *MI, uint64_t Address,
StringRef Annot, const MCSubtargetInfo &STI,
raw_ostream &O) {
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h
index 60849d69e04e5..40605b92bcb01 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h
@@ -22,6 +22,8 @@ namespace llvm {
const MCRegisterInfo &MRI)
: MCInstPrinter(MAI, MII, MRI) {}
+ void printRegName(raw_ostream &O, MCRegister Reg) const override;
+
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
const MCSubtargetInfo &STI, raw_ostream &O) override;
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp
index de07b47096d34..d04bb406b9bb8 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp
@@ -15,9 +15,9 @@ using namespace llvm;
void MSP430MCAsmInfo::anchor() { }
-MSP430MCAsmInfo::MSP430MCAsmInfo(const Triple &TT,
- const MCTargetOptions &Options) {
- CodePointerSize = CalleeSaveStackSlotSize = 2;
+MSP430MCAsmInfo::MSP430MCAsmInfo(const Triple &TT) {
+ CodePointerSize = 2;
+ CalleeSaveStackSlotSize = 2;
CommentString = ";";
SeparatorString = "{";
@@ -26,4 +26,6 @@ MSP430MCAsmInfo::MSP430MCAsmInfo(const Triple &TT,
UsesELFSectionDirectiveForBSS = true;
SupportsDebugInformation = true;
+
+ ExceptionsType = ExceptionHandling::DwarfCFI;
}
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h
index c4ff4a9eefb1a..93979df037e64 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h
@@ -22,7 +22,7 @@ class MSP430MCAsmInfo : public MCAsmInfoELF {
void anchor() override;
public:
- explicit MSP430MCAsmInfo(const Triple &TT, const MCTargetOptions &Options);
+ explicit MSP430MCAsmInfo(const Triple &TT);
};
} // namespace llvm
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp
index 13a880de68b56..df182a5459ead 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp
@@ -14,6 +14,7 @@
#include "MSP430InstPrinter.h"
#include "MSP430MCAsmInfo.h"
#include "TargetInfo/MSP430TargetInfo.h"
+#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -43,6 +44,27 @@ static MCRegisterInfo *createMSP430MCRegisterInfo(const Triple &TT) {
return X;
}
+static MCAsmInfo *createMSP430MCAsmInfo(const MCRegisterInfo &MRI,
+ const Triple &TT,
+ const MCTargetOptions &Options) {
+ MCAsmInfo *MAI = new MSP430MCAsmInfo(TT);
+
+ // Initialize initial frame state.
+ int stackGrowth = -2;
+
+ // Initial state of the frame pointer is sp+ptr_size.
+ MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(
+ nullptr, MRI.getDwarfRegNum(MSP430::SP, true), -stackGrowth);
+ MAI->addInitialFrameState(Inst);
+
+ // Add return address to move list
+ MCCFIInstruction Inst2 = MCCFIInstruction::createOffset(
+ nullptr, MRI.getDwarfRegNum(MSP430::PC, true), stackGrowth);
+ MAI->addInitialFrameState(Inst2);
+
+ return MAI;
+}
+
static MCSubtargetInfo *
createMSP430MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
return createMSP430MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
@@ -61,7 +83,7 @@ static MCInstPrinter *createMSP430MCInstPrinter(const Triple &T,
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430TargetMC() {
Target &T = getTheMSP430Target();
- RegisterMCAsmInfo<MSP430MCAsmInfo> X(T);
+ TargetRegistry::RegisterMCAsmInfo(T, createMSP430MCAsmInfo);
TargetRegistry::RegisterMCInstrInfo(T, createMSP430MCInstrInfo);
TargetRegistry::RegisterMCRegInfo(T, createMSP430MCRegisterInfo);
TargetRegistry::RegisterMCSubtargetInfo(T, createMSP430MCSubtargetInfo);
diff --git a/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp b/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
index 6a8dc3502496f..176387d71fcb6 100644
--- a/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
@@ -25,6 +25,11 @@
using namespace llvm;
+MSP430FrameLowering::MSP430FrameLowering(const MSP430Subtarget &STI)
+ : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(2), -2,
+ Align(2)),
+ STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
+
bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -37,6 +42,45 @@ bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const
return !MF.getFrameInfo().hasVarSizedObjects();
}
+void MSP430FrameLowering::BuildCFI(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ const DebugLoc &DL,
+ const MCCFIInstruction &CFIInst,
+ MachineInstr::MIFlag Flag) const {
+ MachineFunction &MF = *MBB.getParent();
+ unsigned CFIIndex = MF.addFrameInst(CFIInst);
+ BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(Flag);
+}
+
+void MSP430FrameLowering::emitCalleeSavedFrameMoves(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ const DebugLoc &DL, bool IsPrologue) const {
+ MachineFunction &MF = *MBB.getParent();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ MachineModuleInfo &MMI = MF.getMMI();
+ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
+
+ // Add callee saved registers to move list.
+ const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
+
+ // Calculate offsets.
+ for (const CalleeSavedInfo &I : CSI) {
+ int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
+ Register Reg = I.getReg();
+ unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
+
+ if (IsPrologue) {
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset));
+ } else {
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::createRestore(nullptr, DwarfReg));
+ }
+ }
+}
+
void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
@@ -50,6 +94,7 @@ void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI.getStackSize();
+ int stackGrowth = -2;
uint64_t NumBytes = 0;
if (hasFP(MF)) {
@@ -64,23 +109,56 @@ void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
// Save FP into the appropriate stack slot...
BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
- .addReg(MSP430::R4, RegState::Kill);
+ .addReg(MSP430::R4, RegState::Kill)
+ .setMIFlag(MachineInstr::FrameSetup);
+
+ // Mark the place where FP was saved.
+ // Define the current CFA rule to use the provided offset.
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, -2 * stackGrowth),
+ MachineInstr::FrameSetup);
+
+ // Change the rule for the FramePtr to be an "offset" rule.
+ unsigned DwarfFramePtr = TRI->getDwarfRegNum(MSP430::R4, true);
+ BuildCFI(
+ MBB, MBBI, DL,
+ MCCFIInstruction::createOffset(nullptr, DwarfFramePtr, 2 * stackGrowth),
+ MachineInstr::FrameSetup);
// Update FP with the new base value...
BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::R4)
- .addReg(MSP430::SP);
+ .addReg(MSP430::SP)
+ .setMIFlag(MachineInstr::FrameSetup);
+
+ // Mark effective beginning of when frame pointer becomes valid.
+ // Define the current CFA to use the FP register.
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr),
+ MachineInstr::FrameSetup);
// Mark the FramePtr as live-in in every block except the entry.
for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF))
MBBJ.addLiveIn(MSP430::R4);
-
} else
NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
// Skip the callee-saved push instructions.
- while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
+ int StackOffset = 2 * stackGrowth;
+ while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup) &&
+ (MBBI->getOpcode() == MSP430::PUSH16r)) {
++MBBI;
+ if (!hasFP(MF)) {
+ // Mark callee-saved push instruction.
+ // Define the current CFA rule to use the provided offset.
+ assert(StackSize && "Expected stack frame");
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, -StackOffset),
+ MachineInstr::FrameSetup);
+ StackOffset += stackGrowth;
+ }
+ }
+
if (MBBI != MBB.end())
DL = MBBI->getDebugLoc();
@@ -94,12 +172,23 @@ void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
if (NumBytes) {
MachineInstr *MI =
- BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
- .addReg(MSP430::SP).addImm(NumBytes);
+ BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
+ .addReg(MSP430::SP)
+ .addImm(NumBytes)
+ .setMIFlag(MachineInstr::FrameSetup);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
+ if (!hasFP(MF)) {
+ // Adjust the previous CFA value if CFA was not redefined by FP
+ BuildCFI(
+ MBB, MBBI, DL,
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize - stackGrowth),
+ MachineInstr::FrameSetup);
+ }
}
+
+ emitCalleeSavedFrameMoves(MBB, MBBI, DL, true);
}
void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
@@ -125,24 +214,43 @@ void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
uint64_t NumBytes = 0;
+ MachineBasicBlock::iterator AfterPop = MBBI;
if (hasFP(MF)) {
// Calculate required stack adjustment
uint64_t FrameSize = StackSize - 2;
NumBytes = FrameSize - CSSize;
// pop FP.
- BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::R4);
+ BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::R4)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ unsigned DwarfStackPtr = TRI->getDwarfRegNum(MSP430::SP, true);
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::cfiDefCfa(nullptr, DwarfStackPtr, 2),
+ MachineInstr::FrameDestroy);
+ --MBBI;
+ if (!MBB.succ_empty() && !MBB.isReturnBlock()) {
+ unsigned DwarfFramePtr = TRI->getDwarfRegNum(MSP430::R4, true);
+ BuildCFI(MBB, AfterPop, DL,
+ MCCFIInstruction::createRestore(nullptr, DwarfFramePtr),
+ MachineInstr::FrameDestroy);
+ --MBBI;
+ --AfterPop;
+ }
} else
NumBytes = StackSize - CSSize;
// Skip the callee-saved pop instructions.
+ MachineBasicBlock::iterator FirstCSPop = MBBI;
while (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PI = std::prev(MBBI);
unsigned Opc = PI->getOpcode();
- if (Opc != MSP430::POP16r && !PI->isTerminator())
+ if ((Opc != MSP430::POP16r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
+ !PI->isTerminator())
break;
+ FirstCSPop = PI;
--MBBI;
}
+ MBBI = FirstCSPop;
DL = MBBI->getDebugLoc();
@@ -152,13 +260,15 @@ void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
// mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
if (MFI.hasVarSizedObjects()) {
- BuildMI(MBB, MBBI, DL,
- TII.get(MSP430::MOV16rr), MSP430::SP).addReg(MSP430::R4);
+ BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::SP)
+ .addReg(MSP430::R4)
+ .setMIFlag(MachineInstr::FrameDestroy);
if (CSSize) {
MachineInstr *MI =
- BuildMI(MBB, MBBI, DL,
- TII.get(MSP430::SUB16ri), MSP430::SP)
- .addReg(MSP430::SP).addImm(CSSize);
+ BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
+ .addReg(MSP430::SP)
+ .addImm(CSSize)
+ .setMIFlag(MachineInstr::FrameDestroy);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
@@ -166,12 +276,40 @@ void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
// adjust stack pointer back: SP += numbytes
if (NumBytes) {
MachineInstr *MI =
- BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
- .addReg(MSP430::SP).addImm(NumBytes);
+ BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
+ .addReg(MSP430::SP)
+ .addImm(NumBytes)
+ .setMIFlag(MachineInstr::FrameDestroy);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
+
+ if (!hasFP(MF)) {
+ // Adjust CFA value if it was defined by SP
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, CSSize + 2),
+ MachineInstr::FrameDestroy);
+ }
+ }
+ }
+
+ if (!hasFP(MF)) {
+ MBBI = FirstCSPop;
+ int64_t Offset = -CSSize - 2;
+ // Mark callee-saved pop instruction.
+ // Define the current CFA rule to use the provided offset.
+ while (MBBI != MBB.end()) {
+ MachineBasicBlock::iterator PI = MBBI;
+ unsigned Opc = PI->getOpcode();
+ ++MBBI;
+ if (Opc == MSP430::POP16r) {
+ Offset += 2;
+ BuildCFI(MBB, MBBI, DL,
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, -Offset),
+ MachineInstr::FrameDestroy);
+ }
}
}
+ emitCalleeSavedFrameMoves(MBB, AfterPop, DL, false);
}
// FIXME: Can we eleminate these in favour of generic code?
@@ -189,12 +327,13 @@ bool MSP430FrameLowering::spillCalleeSavedRegisters(
MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
MFI->setCalleeSavedFrameSize(CSI.size() * 2);
- for (const CalleeSavedInfo &I : llvm::reverse(CSI)) {
+ for (const CalleeSavedInfo &I : CSI) {
Register Reg = I.getReg();
// Add the callee-saved register as live-in. It's killed at the spill.
MBB.addLiveIn(Reg);
BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
- .addReg(Reg, RegState::Kill);
+ .addReg(Reg, RegState::Kill)
+ .setMIFlag(MachineInstr::FrameSetup);
}
return true;
}
@@ -211,8 +350,9 @@ bool MSP430FrameLowering::restoreCalleeSavedRegisters(
MachineFunction &MF = *MBB.getParent();
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
- for (const CalleeSavedInfo &I : CSI)
- BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), I.getReg());
+ for (const CalleeSavedInfo &I : llvm::reverse(CSI))
+ BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), I.getReg())
+ .setMIFlag(MachineInstr::FrameDestroy);
return true;
}
@@ -269,6 +409,11 @@ MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr(
BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
.addReg(MSP430::SP)
.addImm(CalleeAmt);
+ if (!hasFP(MF)) {
+ DebugLoc DL = I->getDebugLoc();
+ BuildCFI(MBB, I, DL,
+ MCCFIInstruction::createAdjustCfaOffset(nullptr, CalleeAmt));
+ }
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
diff --git a/llvm/lib/Target/MSP430/MSP430FrameLowering.h b/llvm/lib/Target/MSP430/MSP430FrameLowering.h
index f6995edf4b0ad..5227d3e731edb 100644
--- a/llvm/lib/Target/MSP430/MSP430FrameLowering.h
+++ b/llvm/lib/Target/MSP430/MSP430FrameLowering.h
@@ -17,13 +17,20 @@
#include "llvm/CodeGen/TargetFrameLowering.h"
namespace llvm {
+
+class MSP430Subtarget;
+class MSP430InstrInfo;
+class MSP430RegisterInfo;
+
class MSP430FrameLowering : public TargetFrameLowering {
protected:
public:
- explicit MSP430FrameLowering()
- : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(2), -2,
- Align(2)) {}
+ MSP430FrameLowering(const MSP430Subtarget &STI);
+
+ const MSP430Subtarget &STI;
+ const MSP430InstrInfo &TII;
+ const MSP430RegisterInfo *TRI;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
@@ -48,6 +55,15 @@ class MSP430FrameLowering : public TargetFrameLowering {
bool hasReservedCallFrame(const MachineFunction &MF) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;
+
+ /// Wraps up getting a CFI index and building a MachineInstr for it.
+ void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ const DebugLoc &DL, const MCCFIInstruction &CFIInst,
+ MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
+
+ void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ const DebugLoc &DL, bool IsPrologue) const;
};
} // End llvm namespace
diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.h b/llvm/lib/Target/MSP430/MSP430InstrInfo.h
index 94cf9f8e1f164..b8d015a21cd15 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrInfo.h
+++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.h
@@ -33,7 +33,7 @@ class MSP430InstrInfo : public MSP430GenInstrInfo {
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).
///
- const TargetRegisterInfo &getRegisterInfo() const { return RI; }
+ const MSP430RegisterInfo &getRegisterInfo() const { return RI; }
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
diff --git a/llvm/lib/Target/MSP430/MSP430RegisterInfo.h b/llvm/lib/Target/MSP430/MSP430RegisterInfo.h
index 78b02cf8ecc0d..51e07f4e8e9ea 100644
--- a/llvm/lib/Target/MSP430/MSP430RegisterInfo.h
+++ b/llvm/lib/Target/MSP430/MSP430RegisterInfo.h
@@ -20,7 +20,7 @@
namespace llvm {
-struct MSP430RegisterInfo : public MSP430GenRegisterInfo {
+class MSP430RegisterInfo : public MSP430GenRegisterInfo {
public:
MSP430RegisterInfo();
diff --git a/llvm/lib/Target/MSP430/MSP430RegisterInfo.td b/llvm/lib/Target/MSP430/MSP430RegisterInfo.td
index 61cc72d494b5b..153df285aebd5 100644
--- a/llvm/lib/Target/MSP430/MSP430RegisterInfo.td
+++ b/llvm/lib/Target/MSP430/MSP430RegisterInfo.td
@@ -32,42 +32,42 @@ class MSP430RegWithSubregs<bits<4> num, string n, list<Register> subregs,
// Registers
//===----------------------------------------------------------------------===//
-def PCB : MSP430Reg<0, "r0", ["pc"]>;
-def SPB : MSP430Reg<1, "r1", ["sp"]>;
-def SRB : MSP430Reg<2, "r2", ["sr"]>;
-def CGB : MSP430Reg<3, "r3", ["cg"]>;
-def R4B : MSP430Reg<4, "r4", ["fp"]>;
-def R5B : MSP430Reg<5, "r5">;
-def R6B : MSP430Reg<6, "r6">;
-def R7B : MSP430Reg<7, "r7">;
-def R8B : MSP430Reg<8, "r8">;
-def R9B : MSP430Reg<9, "r9">;
-def R10B : MSP430Reg<10, "r10">;
-def R11B : MSP430Reg<11, "r11">;
-def R12B : MSP430Reg<12, "r12">;
-def R13B : MSP430Reg<13, "r13">;
-def R14B : MSP430Reg<14, "r14">;
-def R15B : MSP430Reg<15, "r15">;
+def PCB : MSP430Reg<0, "r0", ["pc"]>, DwarfRegNum<[16]>;
+def SPB : MSP430Reg<1, "r1", ["sp"]>, DwarfRegNum<[17]>;
+def SRB : MSP430Reg<2, "r2", ["sr"]>, DwarfRegNum<[18]>;
+def CGB : MSP430Reg<3, "r3", ["cg"]>, DwarfRegNum<[19]>;
+def R4B : MSP430Reg<4, "r4", ["fp"]>, DwarfRegNum<[20]>;
+def R5B : MSP430Reg<5, "r5">, DwarfRegNum<[21]>;
+def R6B : MSP430Reg<6, "r6">, DwarfRegNum<[22]>;
+def R7B : MSP430Reg<7, "r7">, DwarfRegNum<[23]>;
+def R8B : MSP430Reg<8, "r8">, DwarfRegNum<[24]>;
+def R9B : MSP430Reg<9, "r9">, DwarfRegNum<[25]>;
+def R10B : MSP430Reg<10, "r10">, DwarfRegNum<[26]>;
+def R11B : MSP430Reg<11, "r11">, DwarfRegNum<[27]>;
+def R12B : MSP430Reg<12, "r12">, DwarfRegNum<[28]>;
+def R13B : MSP430Reg<13, "r13">, DwarfRegNum<[29]>;
+def R14B : MSP430Reg<14, "r14">, DwarfRegNum<[30]>;
+def R15B : MSP430Reg<15, "r15">, DwarfRegNum<[31]>;
def subreg_8bit : SubRegIndex<8> { let Namespace = "MSP430"; }
let SubRegIndices = [subreg_8bit] in {
-def PC : MSP430RegWithSubregs<0, "r0", [PCB], ["pc"]>;
-def SP : MSP430RegWithSubregs<1, "r1", [SPB], ["sp"]>;
-def SR : MSP430RegWithSubregs<2, "r2", [SRB], ["sr"]>;
-def CG : MSP430RegWithSubregs<3, "r3", [CGB], ["cg"]>;
-def R4 : MSP430RegWithSubregs<4, "r4", [R4B], ["fp"]>;
-def R5 : MSP430RegWithSubregs<5, "r5", [R5B]>;
-def R6 : MSP430RegWithSubregs<6, "r6", [R6B]>;
-def R7 : MSP430RegWithSubregs<7, "r7", [R7B]>;
-def R8 : MSP430RegWithSubregs<8, "r8", [R8B]>;
-def R9 : MSP430RegWithSubregs<9, "r9", [R9B]>;
-def R10 : MSP430RegWithSubregs<10, "r10", [R10B]>;
-def R11 : MSP430RegWithSubregs<11, "r11", [R11B]>;
-def R12 : MSP430RegWithSubregs<12, "r12", [R12B]>;
-def R13 : MSP430RegWithSubregs<13, "r13", [R13B]>;
-def R14 : MSP430RegWithSubregs<14, "r14", [R14B]>;
-def R15 : MSP430RegWithSubregs<15, "r15", [R15B]>;
+def PC : MSP430RegWithSubregs<0, "r0", [PCB], ["pc"]>, DwarfRegNum<[0]>;
+def SP : MSP430RegWithSubregs<1, "r1", [SPB], ["sp"]>, DwarfRegNum<[1]>;
+def SR : MSP430RegWithSubregs<2, "r2", [SRB], ["sr"]>, DwarfRegNum<[2]>;
+def CG : MSP430RegWithSubregs<3, "r3", [CGB], ["cg"]>, DwarfRegNum<[3]>;
+def R4 : MSP430RegWithSubregs<4, "r4", [R4B], ["fp"]>, DwarfRegNum<[4]>;
+def R5 : MSP430RegWithSubregs<5, "r5", [R5B]>, DwarfRegNum<[5]>;
+def R6 : MSP430RegWithSubregs<6, "r6", [R6B]>, DwarfRegNum<[6]>;
+def R7 : MSP430RegWithSubregs<7, "r7", [R7B]>, DwarfRegNum<[7]>;
+def R8 : MSP430RegWithSubregs<8, "r8", [R8B]>, DwarfRegNum<[8]>;
+def R9 : MSP430RegWithSubregs<9, "r9", [R9B]>, DwarfRegNum<[9]>;
+def R10 : MSP430RegWithSubregs<10, "r10", [R10B]>, DwarfRegNum<[10]>;
+def R11 : MSP430RegWithSubregs<11, "r11", [R11B]>, DwarfRegNum<[11]>;
+def R12 : MSP430RegWithSubregs<12, "r12", [R12B]>, DwarfRegNum<[12]>;
+def R13 : MSP430RegWithSubregs<13, "r13", [R13B]>, DwarfRegNum<[13]>;
+def R14 : MSP430RegWithSubregs<14, "r14", [R14B]>, DwarfRegNum<[14]>;
+def R15 : MSP430RegWithSubregs<15, "r15", [R15B]>, DwarfRegNum<[15]>;
}
def GR8 : RegisterClass<"MSP430", [i8], 8,
diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
index 0604d47597e25..2d208cdf3f05c 100644
--- a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
+++ b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
@@ -58,4 +58,5 @@ MSP430Subtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) {
MSP430Subtarget::MSP430Subtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, const TargetMachine &TM)
: MSP430GenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
- InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this) {}
+ InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
+ FrameLowering(*this) {}
diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.h b/llvm/lib/Target/MSP430/MSP430Subtarget.h
index 079af2c75ec13..d99545a2224d4 100644
--- a/llvm/lib/Target/MSP430/MSP430Subtarget.h
+++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h
@@ -38,10 +38,10 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
virtual void anchor();
bool ExtendedInsts = false;
HWMultEnum HWMultMode = NoHWMult;
- MSP430FrameLowering FrameLowering;
MSP430InstrInfo InstrInfo;
MSP430TargetLowering TLInfo;
SelectionDAGTargetInfo TSInfo;
+ MSP430FrameLowering FrameLowering;
public:
/// This constructor initializes the data members to match that
@@ -64,9 +64,10 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
return &FrameLowering;
}
const MSP430InstrInfo *getInstrInfo() const override { return &InstrInfo; }
- const TargetRegisterInfo *getRegisterInfo() const override {
- return &InstrInfo.getRegisterInfo();
+ const MSP430RegisterInfo *getRegisterInfo() const override {
+ return &getInstrInfo()->getRegisterInfo();
}
+
const MSP430TargetLowering *getTargetLowering() const override {
return &TLInfo;
}
diff --git a/llvm/test/CodeGen/MSP430/asm-clobbers.ll b/llvm/test/CodeGen/MSP430/asm-clobbers.ll
index bd6f88cc2436c..3e411192fd6a8 100644
--- a/llvm/test/CodeGen/MSP430/asm-clobbers.ll
+++ b/llvm/test/CodeGen/MSP430/asm-clobbers.ll
@@ -16,26 +16,50 @@ entry:
define void @test_1() {
entry:
; CHECK-LABEL: test_1:
-; CHECK: push r8
-; CHECK: push r6
; CHECK: push r4
+; CHECK: .cfi_def_cfa_offset 4
+; CHECK: push r6
+; CHECK: .cfi_def_cfa_offset 6
+; CHECK: push r8
+; CHECK: .cfi_def_cfa_offset 8
+; CHECK: .cfi_offset r4, -4
+; CHECK: .cfi_offset r6, -6
+; CHECK: .cfi_offset r8, -8
call void asm sideeffect "", "~{r4},~{r6},~{r8}"()
-; CHECK: pop r4
-; CHECK: pop r6
; CHECK: pop r8
+; CHECK: .cfi_def_cfa_offset 6
+; CHECK: pop r6
+; CHECK: .cfi_def_cfa_offset 4
+; CHECK: pop r4
+; CHECK: .cfi_def_cfa_offset 2
+; CHECK: .cfi_restore r4
+; CHECK: .cfi_restore r6
+; CHECK: .cfi_restore r8
ret void
}
define void @test_2() {
entry:
; CHECK-LABEL: test_2:
-; CHECK: push r9
-; CHECK: push r7
-; CHECK: push r5
+; CHECK: push r5
+; CHECK: .cfi_def_cfa_offset 4
+; CHECK: push r7
+; CHECK: .cfi_def_cfa_offset 6
+; CHECK: push r9
+; CHECK: .cfi_def_cfa_offset 8
+; CHECK: .cfi_offset r5, -4
+; CHECK: .cfi_offset r7, -6
+; CHECK: .cfi_offset r9, -8
call void asm sideeffect "", "~{r5},~{r7},~{r9}"()
-; CHECK: pop r5
-; CHECK: pop r7
; CHECK: pop r9
+; CHECK: .cfi_def_cfa_offset 6
+; CHECK: pop r7
+; CHECK: .cfi_def_cfa_offset 4
+; CHECK: pop r5
+; CHECK: .cfi_def_cfa_offset 2
+; CHECK: .cfi_restore r5
+; CHECK: .cfi_restore r7
+; CHECK: .cfi_restore r9
ret void
}
@@ -50,7 +74,11 @@ define void @test_r10() {
entry:
; CHECK-LABEL: test_r10:
; CHECK: push r10
+; CHECK: .cfi_def_cfa_offset 4
+; CHECK: .cfi_offset r10, -4
call void asm sideeffect "", "~{r10}"()
; CHECK: pop r10
+; CHECK: .cfi_def_cfa_offset 2
+; CHECK: .cfi_restore r10
ret void
}
diff --git a/llvm/test/CodeGen/MSP430/callee-saved.ll b/llvm/test/CodeGen/MSP430/callee-saved.ll
index 76db4dcdfe886..4f323298dd42e 100644
--- a/llvm/test/CodeGen/MSP430/callee-saved.ll
+++ b/llvm/test/CodeGen/MSP430/callee-saved.ll
@@ -9,18 +9,34 @@ target triple = "msp430-generic-generic"
define void @foo() {
; CHECK-LABEL: foo:
-; CHECK-NOT: push r15
-; CHECK-NOT: push r14
-; CHECK-NOT: push r13
-; CHECK-NOT: push r12
; CHECK-NOT: push r11
-; CHECK: push r10
-; CHECK: push r9
-; CHECK: push r8
-; CHECK: push r7
-; CHECK: push r6
-; CHECK: push r5
-; CHECK: push r4
+; CHECK-NOT: push r12
+; CHECK-NOT: push r13
+; CHECK-NOT: push r14
+; CHECK-NOT: push r15
+; CHECK: push r4
+; CHECK: .cfi_def_cfa_offset 4
+; CHECK: push r5
+; CHECK: .cfi_def_cfa_offset 6
+; CHECK: push r6
+; CHECK: .cfi_def_cfa_offset 8
+; CHECK: push r7
+; CHECK: .cfi_def_cfa_offset 10
+; CHECK: push r8
+; CHECK: .cfi_def_cfa_offset 12
+; CHECK: push r9
+; CHECK: .cfi_def_cfa_offset 14
+; CHECK: push r10
+; CHECK: .cfi_def_cfa_offset 16
+
+; CHECK: .cfi_offset r4, -4
+; CHECK: .cfi_offset r5, -6
+; CHECK: .cfi_offset r6, -8
+; CHECK: .cfi_offset r7, -10
+; CHECK: .cfi_offset r8, -12
+; CHECK: .cfi_offset r9, -14
+; CHECK: .cfi_offset r10, -16
+
%t1 = load volatile float, float* @g
%t2 = load volatile float, float* @g
%t3 = load volatile float, float* @g
diff --git a/llvm/test/CodeGen/MSP430/interrupt.ll b/llvm/test/CodeGen/MSP430/interrupt.ll
index dac3e14321d70..47e72dd1cefc8 100644
--- a/llvm/test/CodeGen/MSP430/interrupt.ll
+++ b/llvm/test/CodeGen/MSP430/interrupt.ll
@@ -21,18 +21,18 @@ target triple = "msp430-generic-generic"
define msp430_intrcc void @ISR() #0 {
entry:
; CHECK-LABEL: ISR:
-; CHECK: push r15
-; CHECK: push r14
-; CHECK: push r13
-; CHECK: push r12
-; CHECK: push r11
-; CHECK: push r10
-; CHECK: push r9
-; CHECK: push r8
-; CHECK: push r7
-; CHECK: push r6
-; CHECK: push r5
-; CHECK: push r4
+; CHECK: push r4
+; CHECK: push r5
+; CHECK: push r6
+; CHECK: push r7
+; CHECK: push r8
+; CHECK: push r9
+; CHECK: push r10
+; CHECK: push r11
+; CHECK: push r12
+; CHECK: push r13
+; CHECK: push r14
+; CHECK: push r15
%t1 = load volatile float, float* @g
%t2 = load volatile float, float* @g
%t3 = load volatile float, float* @g
diff --git a/llvm/test/CodeGen/MSP430/jumptable.ll b/llvm/test/CodeGen/MSP430/jumptable.ll
index 6121f7ebed67c..3e50123957726 100644
--- a/llvm/test/CodeGen/MSP430/jumptable.ll
+++ b/llvm/test/CodeGen/MSP430/jumptable.ll
@@ -8,7 +8,7 @@ define i16 @test(i16 %i) #0 {
entry:
; CHECK-LABEL: test:
; CHECK: sub #4, r1
-; CHECK-NEXT: mov r12, 0(r1)
+; CHECK: mov r12, 0(r1)
; CHECK-NEXT: cmp #4, r12
; CHECK-NEXT: jhs .LBB0_3
%retval = alloca i16, align 2
diff --git a/llvm/test/DebugInfo/MSP430/dwarf-basics-v5.ll b/llvm/test/DebugInfo/MSP430/dwarf-basics-v5.ll
index 98922f1b7d088..2e61566c7993b 100644
--- a/llvm/test/DebugInfo/MSP430/dwarf-basics-v5.ll
+++ b/llvm/test/DebugInfo/MSP430/dwarf-basics-v5.ll
@@ -38,7 +38,7 @@
; CHECK: DW_TAG_subprogram
; CHECK: DW_AT_low_pc (0x{{.*}})
; CHECK: DW_AT_high_pc (0x{{.*}})
-; CHECK: DW_AT_frame_base (DW_OP_reg1 SPB)
+; CHECK: DW_AT_frame_base (DW_OP_reg1 SP)
; CHECK: DW_AT_call_all_calls (true)
; CHECK: DW_AT_name ("f")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics-v5.c")
@@ -49,14 +49,14 @@
; CHECK: DW_TAG_formal_parameter
; CHECK: DW_AT_location (indexed (0x0) loclist = 0x{{.*}}:
-; CHECK: [0x0000, 0x0004): DW_OP_reg12 R12B)
+; CHECK: [0x0000, 0x0004): DW_OP_reg12 R12)
; CHECK: DW_AT_name ("y")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics-v5.c")
; CHECK: DW_AT_decl_line (5)
; CHECK: DW_AT_type (0x{{.*}} "long")
; CHECK: DW_TAG_formal_parameter
-; CHECK: DW_AT_location (DW_OP_reg14 R14B)
+; CHECK: DW_AT_location (DW_OP_reg14 R14)
; CHECK: DW_AT_name ("p")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics-v5.c")
; CHECK: DW_AT_decl_line (5)
diff --git a/llvm/test/DebugInfo/MSP430/dwarf-basics.ll b/llvm/test/DebugInfo/MSP430/dwarf-basics.ll
index 592e3a507b86c..7d81d9c28d6f2 100644
--- a/llvm/test/DebugInfo/MSP430/dwarf-basics.ll
+++ b/llvm/test/DebugInfo/MSP430/dwarf-basics.ll
@@ -35,7 +35,7 @@
; CHECK: DW_TAG_subprogram
; CHECK: DW_AT_low_pc (0x{{.*}})
; CHECK: DW_AT_high_pc (0x{{.*}})
-; CHECK: DW_AT_frame_base (DW_OP_reg1 SPB)
+; CHECK: DW_AT_frame_base (DW_OP_reg1 SP)
; CHECK: DW_AT_name ("f")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics.c")
; CHECK: DW_AT_decl_line (5)
@@ -45,14 +45,14 @@
; CHECK: DW_TAG_formal_parameter
; CHECK: DW_AT_location (0x{{.*}}:
-; CHECK: [0x0000, 0x0004): DW_OP_reg12 R12B)
+; CHECK: [0x0000, 0x0004): DW_OP_reg12 R12)
; CHECK: DW_AT_name ("y")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics.c")
; CHECK: DW_AT_decl_line (5)
; CHECK: DW_AT_type (0x{{.*}} "long int")
; CHECK: DW_TAG_formal_parameter
-; CHECK: DW_AT_location (DW_OP_reg14 R14B)
+; CHECK: DW_AT_location (DW_OP_reg14 R14)
; CHECK: DW_AT_name ("p")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics.c")
; CHECK: DW_AT_decl_line (5)
diff --git a/llvm/test/DebugInfo/MSP430/fp-vla-callee-saved.ll b/llvm/test/DebugInfo/MSP430/fp-vla-callee-saved.ll
new file mode 100644
index 0000000000000..fc4d3aa9d7a67
--- /dev/null
+++ b/llvm/test/DebugInfo/MSP430/fp-vla-callee-saved.ll
@@ -0,0 +1,60 @@
+; RUN: llc -O0 -frame-pointer=all < %s | FileCheck %s
+
+; Check that CFI instructions are generated properly when
+; a frame pointer, variable length array and callee-saved
+; registers are all present at the same time
+
+target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
+target triple = "msp430-unknown-unknown-elf"
+
+ at g = global float 0.0
+ at N = external global i16, align 2
+
+define void @foo() {
+; CHECK-LABEL: foo:
+; CHECK: push r4
+; CHECK-NEXT: .cfi_def_cfa_offset 4
+; CHECK-NEXT: .cfi_offset r4, -4
+; CHECK-NEXT: mov r1, r4
+; CHECK-NEXT: .cfi_def_cfa_register r4
+; CHECK: push r6
+; CHECK-NEXT: push r7
+; CHECK-NEXT: push r8
+; CHECK-NEXT: push r9
+; CHECK-NEXT: push r10
+; CHECK: .cfi_offset r6, -6
+; CHECK: .cfi_offset r7, -8
+; CHECK: .cfi_offset r8, -10
+; CHECK: .cfi_offset r9, -12
+; CHECK: .cfi_offset r10, -14
+
+ %n = load i16, ptr @N, align 2
+ %vla = alloca i8, i16 %n, align 1
+ %t1 = load volatile float, float* @g
+ %t2 = load volatile float, float* @g
+ %t3 = load volatile float, float* @g
+ %t4 = load volatile float, float* @g
+ %t5 = load volatile float, float* @g
+ store volatile float %t1, float* @g
+ store volatile float %t2, float* @g
+ store volatile float %t3, float* @g
+ store volatile float %t4, float* @g
+ store volatile float %t5, float* @g
+
+; CHECK: mov r4, r1
+; CHECK-NEXT: sub #10, r1
+; CHECK: pop r10
+; CHECK-NEXT: pop r9
+; CHECK-NEXT: pop r8
+; CHECK-NEXT: pop r7
+; CHECK-NEXT: pop r6
+; CHECK: pop r4
+; CHECK: .cfi_def_cfa r1, 2
+; CHECK: .cfi_restore r6
+; CHECK: .cfi_restore r7
+; CHECK: .cfi_restore r8
+; CHECK: .cfi_restore r9
+; CHECK: .cfi_restore r10
+
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_function_name.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_function_name.ll.expected
index bb066c2ce4137..b8967743b06fd 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_function_name.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_function_name.ll.expected
@@ -5,7 +5,8 @@
define hidden i32 @"_Z54bar$ompvariant$bar"() {
; CHECK-LABEL: _Z54bar$ompvariant$bar:
-; CHECK: ; %bb.0: ; %entry
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
; CHECK-NEXT: mov #2, r12
; CHECK-NEXT: clr r13
; CHECK-NEXT: ret
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.generated.expected
index 4625b0c73b3b3..36519299c1ffb 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.generated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.generated.expected
@@ -65,9 +65,13 @@ define dso_local i32 @main() #0 {
attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-LABEL: check_boundaries:
-; CHECK: ; %bb.0:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: push r4
+; CHECK-NEXT: .cfi_def_cfa_offset 4
+; CHECK-NEXT: .cfi_offset r4, -4
; CHECK-NEXT: mov r1, r4
+; CHECK-NEXT: .cfi_def_cfa_register r4
; CHECK-NEXT: sub #20, r1
; CHECK-NEXT: clr -6(r4)
; CHECK-NEXT: clr -8(r4)
@@ -112,12 +116,17 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-NEXT: clr r13
; CHECK-NEXT: add #20, r1
; CHECK-NEXT: pop r4
+; CHECK-NEXT: .cfi_def_cfa r1, 2
; CHECK-NEXT: ret
;
; CHECK-LABEL: main:
-; CHECK: ; %bb.0:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: push r4
+; CHECK-NEXT: .cfi_def_cfa_offset 4
+; CHECK-NEXT: .cfi_offset r4, -4
; CHECK-NEXT: mov r1, r4
+; CHECK-NEXT: .cfi_def_cfa_register r4
; CHECK-NEXT: sub #20, r1
; CHECK-NEXT: clr &x+2
; CHECK-NEXT: mov #1, &x
@@ -145,4 +154,5 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-NEXT: clr r13
; CHECK-NEXT: add #20, r1
; CHECK-NEXT: pop r4
+; CHECK-NEXT: .cfi_def_cfa r1, 2
; CHECK-NEXT: ret
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.nogenerated.expected
index 2b511b1a09022..ffe417b9d618b 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.nogenerated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/msp430_generated_funcs.ll.nogenerated.expected
@@ -6,9 +6,13 @@
define dso_local i32 @check_boundaries() #0 {
; CHECK-LABEL: check_boundaries:
-; CHECK: ; %bb.0:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: push r4
+; CHECK-NEXT: .cfi_def_cfa_offset 4
+; CHECK-NEXT: .cfi_offset r4, -4
; CHECK-NEXT: mov r1, r4
+; CHECK-NEXT: .cfi_def_cfa_register r4
; CHECK-NEXT: sub #20, r1
; CHECK-NEXT: clr -6(r4)
; CHECK-NEXT: clr -8(r4)
@@ -53,6 +57,7 @@ define dso_local i32 @check_boundaries() #0 {
; CHECK-NEXT: clr r13
; CHECK-NEXT: add #20, r1
; CHECK-NEXT: pop r4
+; CHECK-NEXT: .cfi_def_cfa r1, 2
; CHECK-NEXT: ret
%1 = alloca i32, align 4
%2 = alloca i32, align 4
@@ -92,9 +97,13 @@ define dso_local i32 @check_boundaries() #0 {
define dso_local i32 @main() #0 {
; CHECK-LABEL: main:
-; CHECK: ; %bb.0:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: push r4
+; CHECK-NEXT: .cfi_def_cfa_offset 4
+; CHECK-NEXT: .cfi_offset r4, -4
; CHECK-NEXT: mov r1, r4
+; CHECK-NEXT: .cfi_def_cfa_register r4
; CHECK-NEXT: sub #20, r1
; CHECK-NEXT: clr &x+2
; CHECK-NEXT: mov #1, &x
@@ -122,6 +131,7 @@ define dso_local i32 @main() #0 {
; CHECK-NEXT: clr r13
; CHECK-NEXT: add #20, r1
; CHECK-NEXT: pop r4
+; CHECK-NEXT: .cfi_def_cfa r1, 2
; CHECK-NEXT: ret
%1 = alloca i32, align 4
%2 = alloca i32, align 4
More information about the llvm-commits
mailing list