llvm.org GIT mirror llvm / 8e59ea9
Spill / restore should avoid modifying the condition register. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33971 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
4 changed file(s) with 65 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
8282 return MI->getOperand(0).getReg();
8383 }
8484 break;
85 case ARM::tLDRspi:
85 case ARM::tRestore:
8686 if (MI->getOperand(1).isFrameIndex() &&
8787 MI->getOperand(2).isImmediate() &&
8888 MI->getOperand(2).getImmedValue() == 0) {
116116 return MI->getOperand(0).getReg();
117117 }
118118 break;
119 case ARM::tSTRspi:
119 case ARM::tSpill:
120120 if (MI->getOperand(1).isFrameIndex() &&
121121 MI->getOperand(2).isImmediate() &&
122122 MI->getOperand(2).getImmedValue() == 0) {
238238 "ldr $dst, $addr",
239239 [(set GPR:$dst, (load t_addrmode_sp:$addr))]>;
240240
241 // Special instruction for restore. It cannot clobber condition register
242 // when it's expanded by eliminateCallFramePseudoInstr().
243 def tRestore : TIs<(ops GPR:$dst, t_addrmode_sp:$addr),
244 "ldr $dst, $addr", []>;
245
241246 // Load tconstpool
242247 def tLDRpci : TIs<(ops GPR:$dst, i32imm:$addr),
243248 "ldr $dst, $addr",
260265 def tSTRspi : TIs<(ops GPR:$src, t_addrmode_sp:$addr),
261266 "str $src, $addr",
262267 [(store GPR:$src, t_addrmode_sp:$addr)]>;
268
269 // Special instruction for spill. It cannot clobber condition register
270 // when it's expanded by eliminateCallFramePseudoInstr().
271 def tSpill : TIs<(ops GPR:$src, t_addrmode_sp:$addr),
272 "str $src, $addr", []>;
263273 }
264274
265275 //===----------------------------------------------------------------------===//
129129 MachineFunction &MF = *MBB.getParent();
130130 ARMFunctionInfo *AFI = MF.getInfo();
131131 if (AFI->isThumbFunction())
132 BuildMI(MBB, I, TII.get(ARM::tSTRspi)).addReg(SrcReg)
132 BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg)
133133 .addFrameIndex(FI).addImm(0);
134134 else
135135 BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg)
152152 MachineFunction &MF = *MBB.getParent();
153153 ARMFunctionInfo *AFI = MF.getInfo();
154154 if (AFI->isThumbFunction())
155 BuildMI(MBB, I, TII.get(ARM::tLDRspi), DestReg)
155 BuildMI(MBB, I, TII.get(ARM::tRestore), DestReg)
156156 .addFrameIndex(FI).addImm(0);
157157 else
158158 BuildMI(MBB, I, TII.get(ARM::LDR), DestReg)
219219 if (OpNum == 0) { // move -> store
220220 unsigned SrcReg = MI->getOperand(1).getReg();
221221 if (!isLowRegister(SrcReg))
222 // tSTRspi cannot take a high register operand.
222 // tSpill cannot take a high register operand.
223223 break;
224 NewMI = BuildMI(TII.get(ARM::tSTRspi)).addReg(SrcReg).addFrameIndex(FI)
224 NewMI = BuildMI(TII.get(ARM::tSpill)).addReg(SrcReg).addFrameIndex(FI)
225225 .addImm(0);
226226 } else { // move -> load
227227 unsigned DstReg = MI->getOperand(0).getReg();
228228 if (!isLowRegister(DstReg))
229 // tLDRspi cannot target a high register operand.
229 // tRestore cannot target a high register operand.
230230 break;
231 NewMI = BuildMI(TII.get(ARM::tLDRspi), DstReg).addFrameIndex(FI)
231 NewMI = BuildMI(TII.get(ARM::tRestore), DstReg).addFrameIndex(FI)
232232 .addImm(0);
233233 }
234234 break;
411411 if (isSub) Bytes = -NumBytes;
412412 bool isMul4 = (Bytes & 3) == 0;
413413 bool isTwoAddr = false;
414 bool DstNeBase = false;
414 bool DstNotEqBase = false;
415415 unsigned NumBits = 1;
416416 unsigned Scale = 1;
417417 int Opc = 0;
440440 // r1 = sub sp, c
441441 // r8 = sub sp, c
442442 if (DestReg != BaseReg)
443 DstNeBase = true;
443 DstNotEqBase = true;
444444 NumBits = 8;
445445 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
446446 isTwoAddr = true;
447447 }
448448
449449 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
450 unsigned Threshold = (DestReg == ARM::SP) ? 4 : 3;
450 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
451451 if (NumMIs > Threshold) {
452452 // This will expand into too many instructions. Load the immediate from a
453453 // constpool entry.
455455 return;
456456 }
457457
458 if (DstNeBase) {
458 if (DstNotEqBase) {
459459 if (isLowRegister(DestReg) && isLowRegister(BaseReg)) {
460460 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
461461 unsigned Chunk = (1 << 3) - 1;
729729 isSub = true;
730730 }
731731
732 if (!isSub || !isThumb) {
733 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
734 int ImmedOffset = Offset / Scale;
735 unsigned Mask = (1 << NumBits) - 1;
736 if ((unsigned)Offset <= Mask * Scale) {
737 // Replace the FrameIndex with sp
738 MI.getOperand(i).ChangeToRegister(FrameReg, false);
739 if (isSub)
740 ImmedOffset |= 1 << NumBits;
741 ImmOp.ChangeToImmediate(ImmedOffset);
742 return;
743 }
744
732 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
733 int ImmedOffset = Offset / Scale;
734 unsigned Mask = (1 << NumBits) - 1;
735 if ((unsigned)Offset <= Mask * Scale) {
736 // Replace the FrameIndex with sp
737 MI.getOperand(i).ChangeToRegister(FrameReg, false);
738 if (isSub)
739 ImmedOffset |= 1 << NumBits;
740 ImmOp.ChangeToImmediate(ImmedOffset);
741 return;
742 }
743
744 if (!isThumb) {
745745 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
746 if (AddrMode == ARMII::AddrModeTs) {
747 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
748 // a different base register.
749 NumBits = 5;
750 Mask = (1 << NumBits) - 1;
751 }
752
753746 ImmedOffset = ImmedOffset & Mask;
754747 if (isSub)
755748 ImmedOffset |= 1 << NumBits;
767760 if (TII.isLoad(Opcode)) {
768761 // Use the destination register to materialize sp + offset.
769762 unsigned TmpReg = MI.getOperand(0).getReg();
770 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
771 isSub ? -Offset : Offset, TII);
763 if (Opcode == ARM::tRestore)
764 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
765 isSub ? -Offset : Offset, TII);
766 else
767 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
768 isSub ? -Offset : Offset, TII);
772769 MI.setInstrDescriptor(TII.get(ARM::tLDR));
773770 MI.getOperand(i).ChangeToRegister(TmpReg, false);
774771 MI.addRegOperand(0, false); // tLDR has an extra register operand.
787784 BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
788785 TmpReg = ARM::R2;
789786 }
790 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
791 isSub ? -Offset : Offset, TII);
787 if (Opcode == ARM::tSpill)
788 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
789 isSub ? -Offset : Offset, TII);
790 else
791 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
792 isSub ? -Offset : Offset, TII);
792793 MI.setInstrDescriptor(TII.get(ARM::tSTR));
793794 MI.getOperand(i).ChangeToRegister(TmpReg, false);
794795 MI.addRegOperand(0, false); // tSTR has an extra register operand.
10971098 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
10981099 return ((MI->getOpcode() == ARM::FLDD ||
10991100 MI->getOpcode() == ARM::LDR ||
1100 MI->getOpcode() == ARM::tLDRspi) &&
1101 MI->getOpcode() == ARM::tRestore) &&
11011102 MI->getOperand(1).isFrameIndex() &&
11021103 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
11031104 }
123123 .align 2
124124 L11:
125125 .long 642
126
127 //===---------------------------------------------------------------------===//
128
129 When spilling in thumb mode and the sp offset is too large to fit in the ldr /
130 str offset field, we load the offset from a constpool entry and add it to sp:
131
132 ldr r2, LCPI
133 add r2, sp
134 ldr r2, [r2]
135
136 These instructions preserve the condition code which is important if the spill
137 is between a cmp and a bcc instruction. However, we can use the (potentially)
138 cheaper sequnce if we know it's ok to clobber the condition register.
139
140 add r2, sp, #255 * 4
141 add r2, #132
142 ldr r2, [r2, #7 * 4]