llvm.org GIT mirror llvm / 8bed6c9
In thumb mode, R3 is reserved, but it can be live in to the function. If that is the case, whenever we use it as a scratch register, save it to R12 first and then restore it after the use. This is a temporary and truly horrible workaround! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33999 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
2 changed file(s) with 32 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
3939 /// far jump.
4040 bool LRForceSpilled;
4141
42 /// R3IsLiveIn - True if R3 is live in to this function.
43 ///
44 bool R3IsLiveIn;
45
4246 /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
4347 /// spill stack offset.
4448 unsigned FramePtrSpillOffset;
7478 public:
7579 ARMFunctionInfo() :
7680 isThumb(false),
77 VarArgsRegSaveSize(0), HasStackFrame(false), LRForceSpilled(false),
81 VarArgsRegSaveSize(0), HasStackFrame(false),
82 LRForceSpilled(false), R3IsLiveIn(false),
7883 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
7984 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
8085
8186 ARMFunctionInfo(MachineFunction &MF) :
8287 isThumb(MF.getTarget().getSubtarget().isThumb()),
83 VarArgsRegSaveSize(0), HasStackFrame(false), LRForceSpilled(false),
88 VarArgsRegSaveSize(0), HasStackFrame(false),
89 LRForceSpilled(false), R3IsLiveIn(false),
8490 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
8591 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
8692
94100
95101 bool isLRForceSpilled() const { return LRForceSpilled; }
96102 void setLRIsForceSpilled(bool s) { LRForceSpilled = s; }
103
104 bool isR3IsLiveIn() const { return R3IsLiveIn; }
105 void setR3IsLiveIn(bool l) { R3IsLiveIn = l; }
97106
98107 unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
99108 void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
400400
401401 if (NumBytes <= 255 && NumBytes >= 0)
402402 BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
403 else
403 else if (NumBytes < 0 && NumBytes >= -255) {
404 BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
405 BuildMI(MBB, MBBI, TII.get(ARM::tNEG), LdReg).addReg(LdReg);
406 } else
404407 emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII);
405408
406409 // Emit add / sub.
810813 // being storing here. If that's the case, we do the following:
811814 // r12 = r2
812815 // Use r2 to materialize sp + offset
813 // str r12, r2
816 // str r3, r2
814817 // r2 = r12
815818 unsigned ValReg = MI.getOperand(0).getReg();
816819 unsigned TmpReg = ARM::R3;
819822 BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
820823 TmpReg = ARM::R2;
821824 }
825 if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn())
826 BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R3);
822827 if (Opcode == ARM::tSpill) {
823828 if (FrameReg == ARM::SP)
824829 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
834839 MI.addRegOperand(FrameReg, false); // Use [reg, reg] addrmode.
835840 else
836841 MI.addRegOperand(0, false); // tSTR has an extra register operand.
837 if (ValReg == ARM::R3) {
838 MachineBasicBlock::iterator NII = next(II);
842
843 MachineBasicBlock::iterator NII = next(II);
844 if (ValReg == ARM::R3)
839845 BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
840 }
846 if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn())
847 BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R3).addReg(ARM::R12);
841848 } else
842849 assert(false && "Unexpected opcode!");
843850 } else {
10311038 const std::vector &CSI = MFI->getCalleeSavedInfo();
10321039
10331040 if (isThumb) {
1041 // Check if R3 is live in. It might have to be used as a scratch register.
1042 for (MachineFunction::livein_iterator I=MF.livein_begin(),E=MF.livein_end();
1043 I != E; ++I) {
1044 if ((*I).first == ARM::R3) {
1045 AFI->setR3IsLiveIn(true);
1046 break;
1047 }
1048 }
1049
10341050 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
10351051 NumBytes = (NumBytes + 3) & ~3;
10361052 MFI->setStackSize(NumBytes);