From 9a9c6b8e7587d0459393024e793e299c96bde0d2 Mon Sep 17 00:00:00 2001 From: Ilia Kuklin Date: Wed, 5 Apr 2023 15:49:53 -0700 Subject: [PATCH] [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 --- .../MSP430/MCTargetDesc/MSP430InstPrinter.cpp | 4 + .../Target/MSP430/MCTargetDesc/MSP430InstPrinter.h | 2 + .../Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp | 8 +- .../Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h | 2 +- .../MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp | 24 ++- llvm/lib/Target/MSP430/MSP430FrameLowering.cpp | 183 ++++++++++++++++++--- llvm/lib/Target/MSP430/MSP430FrameLowering.h | 22 ++- llvm/lib/Target/MSP430/MSP430InstrInfo.h | 2 +- llvm/lib/Target/MSP430/MSP430RegisterInfo.h | 2 +- llvm/lib/Target/MSP430/MSP430RegisterInfo.td | 64 +++---- llvm/lib/Target/MSP430/MSP430Subtarget.cpp | 3 +- llvm/lib/Target/MSP430/MSP430Subtarget.h | 7 +- llvm/test/CodeGen/MSP430/asm-clobbers.ll | 46 +++++- llvm/test/CodeGen/MSP430/callee-saved.ll | 38 +++-- llvm/test/CodeGen/MSP430/interrupt.ll | 24 +-- llvm/test/CodeGen/MSP430/jumptable.ll | 2 +- llvm/test/DebugInfo/MSP430/dwarf-basics-v5.ll | 6 +- llvm/test/DebugInfo/MSP430/dwarf-basics.ll | 6 +- llvm/test/DebugInfo/MSP430/fp-vla-callee-saved.ll | 60 +++++++ .../Inputs/msp430_function_name.ll.expected | 3 +- .../msp430_generated_funcs.ll.generated.expected | 14 +- .../msp430_generated_funcs.ll.nogenerated.expected | 14 +- 22 files changed, 427 insertions(+), 109 deletions(-) create mode 100644 llvm/test/DebugInfo/MSP430/fp-vla-callee-saved.ll diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.cpp index 420893f..3726c60 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 60849d6..40605b9 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 de07b47..d04bb40 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 c4ff4a9..93979df 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 13a880d..df182a5 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 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 6a8dc35..176387d 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 &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(); 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 f6995ed..5227d3e 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 @@ public: 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 94cf9f8..b8d015a 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrInfo.h +++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.h @@ -33,7 +33,7 @@ public: /// 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 78b02cf..51e07f4 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 61cc72d..153df28 100644 --- a/llvm/lib/Target/MSP430/MSP430RegisterInfo.td +++ b/llvm/lib/Target/MSP430/MSP430RegisterInfo.td @@ -32,42 +32,42 @@ class MSP430RegWithSubregs num, string n, list 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 0604d47..2d208cd 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 079af2c..d99545a 100644 --- a/llvm/lib/Target/MSP430/MSP430Subtarget.h +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h @@ -38,10 +38,10 @@ private: 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 @@ public: 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 bd6f88c..3e41119 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 76db4dc..4f32329 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 dac3e14..47e72dd 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 6121f7e..3e50123 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 98922f1..2e61566 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 592e3a5..7d81d9c 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 0000000..fc4d3aa --- /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" + +@g = global float 0.0 +@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 bb066c2..b896774 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 4625b0c..3651929 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 2b511b1..ffe417b 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 -- 2.7.4