llvm.org GIT mirror llvm / 3daccd8
Implement frame unwinding information emission for Thumb1. Not finished yet because there is no way given the constpool index to examine the actual entry: the reason is clones inserted by constant island pass, which are not tracked at all! The only connection is done during asmprinting time via magic label names which is really gross and needs to be eventually fixed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127104 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 9 years ago
8 changed file(s) with 82 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
821821 unsigned Opc = MI->getOpcode();
822822 unsigned SrcReg, DstReg;
823823
824 // Special case: tPUSH does not have src/dst regs.
825 if (Opc == ARM::tPUSH) {
824 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
825 // Two special cases:
826 // 1) tPUSH does not have src/dst regs.
827 // 2) for Thumb1 code we sometimes materialize the constant via constpool
828 // load. Yes, this is pretty fragile, but for now I don't see better
829 // way... :(
826830 SrcReg = DstReg = ARM::SP;
827831 } else {
828 SrcReg = MI->getOperand(1).getReg();
832 SrcReg = MI->getOperand(1).getReg();
829833 DstReg = MI->getOperand(0).getReg();
830834 }
831835
874878 assert(0 && "Unsupported opcode for unwinding information");
875879 case ARM::MOVr:
876880 case ARM::tMOVgpr2gpr:
881 case ARM::tMOVgpr2tgpr:
877882 Offset = 0;
878883 break;
879884 case ARM::ADDri:
889894 case ARM::tADDspi:
890895 case ARM::tADDrSPi:
891896 Offset = -MI->getOperand(2).getImm()*4;
897 break;
898 case ARM::tLDRpci:
899 assert(0 && "Not implemented yet!");
892900 break;
893901 }
894902
805805 DebugLoc dl,
806806 unsigned DestReg, unsigned SubIdx, int Val,
807807 ARMCC::CondCodes Pred,
808 unsigned PredReg) const {
808 unsigned PredReg, unsigned MIFlags) const {
809809 MachineFunction &MF = *MBB.getParent();
810810 MachineConstantPool *ConstantPool = MF.getConstantPool();
811811 const Constant *C =
815815 BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
816816 .addReg(DestReg, getDefRegState(true), SubIdx)
817817 .addConstantPoolIndex(Idx)
818 .addImm(0).addImm(Pred).addReg(PredReg);
818 .addImm(0).addImm(Pred).addReg(PredReg)
819 .setMIFlags(MIFlags);
819820 }
820821
821822 bool ARMBaseRegisterInfo::
175175 unsigned DestReg, unsigned SubIdx,
176176 int Val,
177177 ARMCC::CondCodes Pred = ARMCC::AL,
178 unsigned PredReg = 0) const;
178 unsigned PredReg = 0,
179 unsigned MIFlags = MachineInstr::NoFlags)const;
179180
180181 /// Code Generation virtual methods...
181182 virtual bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
3333 return !MF.getFrameInfo()->hasVarSizedObjects();
3434 }
3535
36 static void emitSPUpdate(MachineBasicBlock &MBB,
37 MachineBasicBlock::iterator &MBBI,
38 const TargetInstrInfo &TII, DebugLoc dl,
39 const Thumb1RegisterInfo &MRI,
40 int NumBytes) {
36 static void
37 emitSPUpdate(MachineBasicBlock &MBB,
38 MachineBasicBlock::iterator &MBBI,
39 const TargetInstrInfo &TII, DebugLoc dl,
40 const Thumb1RegisterInfo &MRI,
41 int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) {
4142 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
42 MRI);
43 MRI, MIFlags);
4344 }
4445
4546 void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
6970 int FramePtrSpillFI = 0;
7071
7172 if (VARegSaveSize)
72 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -VARegSaveSize);
73 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -VARegSaveSize,
74 MachineInstr::FrameSetup);
7375
7476 if (!AFI->hasStackFrame()) {
7577 if (NumBytes != 0)
76 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes);
78 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
79 MachineInstr::FrameSetup);
7780 return;
7881 }
7982
130133 // Adjust FP so it point to the stack slot that contains the previous FP.
131134 if (hasFP(MF)) {
132135 BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
133 .addFrameIndex(FramePtrSpillFI).addImm(0);
136 .addFrameIndex(FramePtrSpillFI).addImm(0)
137 .setMIFlags(MachineInstr::FrameSetup);
134138 if (NumBytes > 7)
135139 // If offset is > 7 then sp cannot be adjusted in a single instruction,
136140 // try restoring from fp instead.
139143
140144 if (NumBytes)
141145 // Insert it after all the callee-save spills.
142 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes);
146 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
147 MachineInstr::FrameSetup);
143148
144149 if (STI.isTargetELF() && hasFP(MF))
145150 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
155160 // to reference locals.
156161 if (RegInfo->hasBasePointer(MF))
157162 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), BasePtr).addReg(ARM::SP);
158
163
159164 // If the frame has variable sized objects then the epilogue must restore
160165 // the sp from fp. We can assume there's an FP here since hasFP already
161166 // checks for hasVarSizedObjects.
306311
307312 MIB.addReg(Reg, getKillRegState(isKill));
308313 }
314 MIB.setMIFlags(MachineInstr::FrameSetup);
309315 return true;
310316 }
311317
4949
5050 /// emitLoadConstPool - Emits a load from constpool to materialize the
5151 /// specified immediate.
52 void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
53 MachineBasicBlock::iterator &MBBI,
54 DebugLoc dl,
55 unsigned DestReg, unsigned SubIdx,
56 int Val,
57 ARMCC::CondCodes Pred,
58 unsigned PredReg) const {
52 void
53 Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
54 MachineBasicBlock::iterator &MBBI,
55 DebugLoc dl,
56 unsigned DestReg, unsigned SubIdx,
57 int Val,
58 ARMCC::CondCodes Pred, unsigned PredReg,
59 unsigned MIFlags) const {
5960 MachineFunction &MF = *MBB.getParent();
6061 MachineConstantPool *ConstantPool = MF.getConstantPool();
6162 const Constant *C = ConstantInt::get(
6465
6566 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
6667 .addReg(DestReg, getDefRegState(true), SubIdx)
67 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
68 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
69 .setMIFlags(MIFlags)
6870 }
6971
7072
7577 static
7678 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
7779 MachineBasicBlock::iterator &MBBI,
80 DebugLoc dl,
7881 unsigned DestReg, unsigned BaseReg,
7982 int NumBytes, bool CanChangeCC,
8083 const TargetInstrInfo &TII,
8184 const ARMBaseRegisterInfo& MRI,
82 DebugLoc dl) {
85 unsigned MIFlags = MachineInstr::NoFlags) {
8386 MachineFunction &MF = *MBB.getParent();
8487 bool isHigh = !isARMLowRegister(DestReg) ||
8588 (BaseReg != 0 && !isARMLowRegister(BaseReg));
100103
101104 if (NumBytes <= 255 && NumBytes >= 0)
102105 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
103 .addImm(NumBytes);
106 .addImm(NumBytes).setMIFlags(MIFlags);
104107 else if (NumBytes < 0 && NumBytes >= -255) {
105108 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
106 .addImm(NumBytes);
109 .addImm(NumBytes).setMIFlags(MIFlags);
107110 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
108 .addReg(LdReg, RegState::Kill);
111 .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
109112 } else
110 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes);
113 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
114 ARMCC::AL, 0, MIFlags);
111115
112116 // Emit add / sub.
113117 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
153157 DebugLoc dl,
154158 unsigned DestReg, unsigned BaseReg,
155159 int NumBytes, const TargetInstrInfo &TII,
156 const ARMBaseRegisterInfo& MRI, unsigned) {
160 const ARMBaseRegisterInfo& MRI,
161 unsigned MIFlags) {
157162 bool isSub = NumBytes < 0;
158163 unsigned Bytes = (unsigned)NumBytes;
159164 if (isSub) Bytes = -NumBytes;
210215 if (NumMIs > Threshold) {
211216 // This will expand into too many instructions. Load the immediate from a
212217 // constpool entry.
213 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
214 MRI, dl);
218 emitThumbRegPlusImmInReg(MBB, MBBI, dl,
219 DestReg, BaseReg, NumBytes, true,
220 TII, MRI, MIFlags);
215221 return;
216222 }
217223
223229 Bytes -= ThisVal;
224230 const TargetInstrDesc &TID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
225231 const MachineInstrBuilder MIB =
226 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg));
232 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg).setMIFlags(MIFlags));
227233 AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
228234 } else {
229235 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
230 .addReg(BaseReg, RegState::Kill);
236 .addReg(BaseReg, RegState::Kill)
237 .setMIFlags(MIFlags);
231238 }
232239 BaseReg = DestReg;
233240 }
242249 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
243250 if (NeedCC)
244251 MIB = AddDefaultT1CC(MIB);
245 MIB .addReg(DestReg).addImm(ThisVal);
252 MIB.addReg(DestReg).addImm(ThisVal);
246253 if (NeedPred)
247254 MIB = AddDefaultPred(MIB);
255 MIB.setMIFlags(MIFlags);
248256 }
249257 else {
250258 bool isKill = BaseReg != ARM::SP;
254262 MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
255263 if (NeedPred)
256264 MIB = AddDefaultPred(MIB);
265 MIB.setMIFlags(MIFlags);
266
257267 BaseReg = DestReg;
258
259268 if (Opc == ARM::tADDrSPi) {
260269 // r4 = add sp, imm
261270 // r4 = add r4, imm
273282 const TargetInstrDesc &TID = TII.get(ExtraOpc);
274283 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
275284 .addReg(DestReg, RegState::Kill)
276 .addImm(((unsigned)NumBytes) & 3));
285 .addImm(((unsigned)NumBytes) & 3)
286 .setMIFlags(MIFlags));
277287 }
278288 }
279289
644654 bool UseRR = false;
645655 if (Opcode == ARM::tRestore) {
646656 if (FrameReg == ARM::SP)
647 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
648 Offset, false, TII, *this, dl);
657 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
658 Offset, false, TII, *this);
649659 else {
650660 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
651661 UseRR = true;
667677
668678 if (Opcode == ARM::tSpill) {
669679 if (FrameReg == ARM::SP)
670 emitThumbRegPlusImmInReg(MBB, II, VReg, FrameReg,
671 Offset, false, TII, *this, dl);
680 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
681 Offset, false, TII, *this);
672682 else {
673683 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
674684 UseRR = true;
3434 DebugLoc dl,
3535 unsigned DestReg, unsigned SubIdx, int Val,
3636 ARMCC::CondCodes Pred = ARMCC::AL,
37 unsigned PredReg = 0) const;
37 unsigned PredReg = 0,
38 unsigned MIFlags = MachineInstr::NoFlags) const;
3839
3940 /// Code Generation virtual methods...
4041 void eliminateCallFramePseudoInstr(MachineFunction &MF,
4141
4242 /// emitLoadConstPool - Emits a load from constpool to materialize the
4343 /// specified immediate.
44 void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
45 MachineBasicBlock::iterator &MBBI,
46 DebugLoc dl,
47 unsigned DestReg, unsigned SubIdx,
48 int Val,
49 ARMCC::CondCodes Pred,
50 unsigned PredReg) const {
44 void
45 Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
46 MachineBasicBlock::iterator &MBBI,
47 DebugLoc dl,
48 unsigned DestReg, unsigned SubIdx,
49 int Val,
50 ARMCC::CondCodes Pred, unsigned PredReg,
51 unsigned MIFlags) const {
5152 MachineFunction &MF = *MBB.getParent();
5253 MachineConstantPool *ConstantPool = MF.getConstantPool();
5354 const Constant *C = ConstantInt::get(
5657
5758 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
5859 .addReg(DestReg, getDefRegState(true), SubIdx)
59 .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0);
60 .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0)
61 .setMIFlags(MIFlags);
6062 }
3434 DebugLoc dl,
3535 unsigned DestReg, unsigned SubIdx, int Val,
3636 ARMCC::CondCodes Pred = ARMCC::AL,
37 unsigned PredReg = 0) const;
37 unsigned PredReg = 0,
38 unsigned MIFlags = MachineInstr::NoFlags) const;
3839 };
3940 }
4041