llvm.org GIT mirror llvm / a98cbc5
ARM refactoring. Step 2: split RegisterInfo git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74384 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 11 years ago
9 changed file(s) with 1096 addition(s) and 715 deletion(s). Raw diff Collapse all Expand all
3939 }
4040
4141 ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &STI)
42 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
43 RI(*this, STI) {
42 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)) {
4443 }
4544
4645 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
47 : ARMBaseInstrInfo(STI) {
46 : ARMBaseInstrInfo(STI), RI(*this, STI) {
4847 }
4948
5049 /// Return true if the instruction is a register to register move and
132131 return 0;
133132 }
134133
135 void ARMBaseInstrInfo::reMaterialize(MachineBasicBlock &MBB,
136 MachineBasicBlock::iterator I,
137 unsigned DestReg,
138 const MachineInstr *Orig) const {
134 void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB,
135 MachineBasicBlock::iterator I,
136 unsigned DestReg,
137 const MachineInstr *Orig) const {
139138 DebugLoc dl = Orig->getDebugLoc();
140139 if (Orig->getOpcode() == ARM::MOVi2pieces) {
141140 RI.emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImm(),
142141 Orig->getOperand(2).getImm(),
143 Orig->getOperand(3).getReg(), this, false, dl);
142 Orig->getOperand(3).getReg(), this, dl);
144143 return;
145144 }
146145
659658 return NewMI;
660659 }
661660
662 bool ARMBaseInstrInfo::
663 canFoldMemoryOperand(const MachineInstr *MI,
664 const SmallVectorImpl &Ops) const {
661 bool
662 ARMInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
663 const SmallVectorImpl &Ops) const {
665664 if (Ops.size() != 1) return false;
666665
667 unsigned OpNum = Ops[0];
668666 unsigned Opc = MI->getOpcode();
669667 switch (Opc) {
670668 default: break;
671669 case ARM::MOVr:
672670 // If it is updating CPSR, then it cannot be folded.
673671 return MI->getOperand(4).getReg() != ARM::CPSR;
674 case ARM::tMOVr:
675 case ARM::tMOVlor2hir:
676 case ARM::tMOVhir2lor:
677 case ARM::tMOVhir2hir: {
678 if (OpNum == 0) { // move -> store
679 unsigned SrcReg = MI->getOperand(1).getReg();
680 if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
681 // tSpill cannot take a high register operand.
682 return false;
683 } else { // move -> load
684 unsigned DstReg = MI->getOperand(0).getReg();
685 if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
686 // tRestore cannot target a high register operand.
687 return false;
688 }
689 return true;
690 }
691672 case ARM::FCPYS:
692673 case ARM::FCPYD:
693674 return true;
701682 }
702683
703684 bool
704 ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
685 ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
705686 if (MBB.empty()) return false;
706687
707688 switch (MBB.back().getOpcode()) {
146146 }
147147
148148 class ARMBaseInstrInfo : public TargetInstrInfoImpl {
149 const ARMRegisterInfo RI;
150149 protected:
151150 // Can be only subclassed.
152151 explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
153152 public:
154
155 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
156 /// such, whenever a client has an instance of instruction info, it should
157 /// always be able to get register info as well (through this method).
158 ///
159 virtual const ARMRegisterInfo &getRegisterInfo() const { return RI; }
160
161 void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
162 unsigned DestReg, const MachineInstr *Orig) const;
163
164153 virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
165154 MachineBasicBlock::iterator &MBBI,
166155 LiveVariables *LV) const;
175164 MachineBasicBlock *FBB,
176165 const SmallVectorImpl &Cond) const;
177166
178 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
179 const SmallVectorImpl &Ops) const;
180
181167 virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
182168 virtual
183169 bool ReverseBranchCondition(SmallVectorImpl &Cond) const;
208194 };
209195
210196 class ARMInstrInfo : public ARMBaseInstrInfo {
197 ARMRegisterInfo RI;
211198 public:
212199 explicit ARMInstrInfo(const ARMSubtarget &STI);
200
201 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
202 /// such, whenever a client has an instance of instruction info, it should
203 /// always be able to get register info as well (through this method).
204 ///
205 virtual const ARMRegisterInfo &getRegisterInfo() const { return RI; }
213206
214207 /// Return true if the instruction is a register to register move and return
215208 /// the source and dest operands and their sub-register indices by reference.
247240 const TargetRegisterClass *RC,
248241 SmallVectorImpl &NewMIs) const;
249242
243 void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
244 unsigned DestReg, const MachineInstr *Orig) const;
245
246 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
247 const SmallVectorImpl &Ops) const;
248
250249 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
251250 MachineInstr* MI,
252251 const SmallVectorImpl &Ops,
3030 #include "llvm/Target/TargetOptions.h"
3131 #include "llvm/ADT/BitVector.h"
3232 #include "llvm/ADT/SmallVector.h"
33 #include "llvm/ADT/STLExtras.h"
34 #include "llvm/Support/CommandLine.h"
35 #include
3633 using namespace llvm;
3734
38 static cl::opt ThumbRegScavenging("enable-thumb-reg-scavenging",
39 cl::Hidden,
40 cl::desc("Enable register scavenging on Thumb"));
41
42 unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
35 unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
4336 using namespace ARM;
4437 switch (RegEnum) {
4538 case R0: case S0: case D0: return 0;
8073 }
8174 }
8275
83 unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum,
84 bool &isSPVFP) {
76 unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
77 bool &isSPVFP) {
8578 isSPVFP = false;
8679
8780 using namespace ARM;
107100 case PC: case D15: return 15;
108101
109102 case S0: case S1: case S2: case S3:
110 case S4: case S5: case S6: case S7:
111 case S8: case S9: case S10: case S11:
112 case S12: case S13: case S14: case S15:
113 case S16: case S17: case S18: case S19:
114 case S20: case S21: case S22: case S23:
115 case S24: case S25: case S26: case S27:
103 case S4: case S5: case S6: case S7:
104 case S8: case S9: case S10: case S11:
105 case S12: case S13: case S14: case S15:
106 case S16: case S17: case S18: case S19:
107 case S20: case S21: case S22: case S23:
108 case S24: case S25: case S26: case S27:
116109 case S28: case S29: case S30: case S31: {
117110 isSPVFP = true;
118111 switch (RegEnum) {
154147 }
155148 }
156149
157 ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
158 const ARMSubtarget &sti)
150 ARMBaseRegisterInfo::ARMBaseRegisterInfo(const TargetInstrInfo &tii,
151 const ARMSubtarget &sti)
159152 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
160153 TII(tii), STI(sti),
161154 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) {
155 }
156
157 ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
158 const ARMSubtarget &sti)
159 : ARMBaseRegisterInfo(tii, sti) {
162160 }
163161
164162 static inline
178176 unsigned DestReg, int Val,
179177 unsigned Pred, unsigned PredReg,
180178 const TargetInstrInfo *TII,
181 bool isThumb,
182179 DebugLoc dl) const {
183180 MachineFunction &MF = *MBB.getParent();
184181 MachineConstantPool *ConstantPool = MF.getConstantPool();
185182 Constant *C = ConstantInt::get(Type::Int32Ty, Val);
186183 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
187 if (isThumb)
188 BuildMI(MBB, MBBI, dl,
189 TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx);
190 else
191 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg)
192 .addConstantPoolIndex(Idx)
193 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
184
185 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg)
186 .addConstantPoolIndex(Idx)
187 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
194188 }
195189
196190 /// isLowRegister - Returns true if the register is low register r0-r7.
197191 ///
198 bool ARMRegisterInfo::isLowRegister(unsigned Reg) const {
192 bool ARMBaseRegisterInfo::isLowRegister(unsigned Reg) const {
199193 using namespace ARM;
200194 switch (Reg) {
201195 case R0: case R1: case R2: case R3:
206200 }
207201 }
208202
209 const TargetRegisterClass*
210 ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
211 if (STI.isThumb()) {
212 if (isLowRegister(Reg))
213 return ARM::tGPRRegisterClass;
214 switch (Reg) {
215 default:
216 break;
217 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
218 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC:
219 return ARM::GPRRegisterClass;
220 }
221 }
222 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
223 }
224
225203 const unsigned*
226 ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
204 ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
227205 static const unsigned CalleeSavedRegs[] = {
228206 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
229207 ARM::R7, ARM::R6, ARM::R5, ARM::R4,
247225 }
248226
249227 const TargetRegisterClass* const *
250 ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
228 ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
251229 static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
252230 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
253231 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
296274 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
297275 }
298276
299 BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
277 BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
300278 // FIXME: avoid re-calculating this everytime.
301279 BitVector Reserved(getNumRegs());
302280 Reserved.set(ARM::SP);
310288 }
311289
312290 bool
313 ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
291 ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
314292 switch (Reg) {
315293 default: break;
316294 case ARM::SP:
328306 return false;
329307 }
330308
331 const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const {
309 const TargetRegisterClass *ARMBaseRegisterInfo::getPointerRegClass() const {
332310 return &ARM::GPRRegClass;
333311 }
334312
335313 /// getAllocationOrder - Returns the register allocation order for a specified
336314 /// register class in the form of a pair of TargetRegisterClass iterators.
337315 std::pair
338 ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
339 unsigned HintType, unsigned HintReg,
340 const MachineFunction &MF) const {
316 ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
317 unsigned HintType, unsigned HintReg,
318 const MachineFunction &MF) const {
341319 // Alternative register allocation orders when favoring even / odd registers
342320 // of register pairs.
343321
478456 /// ResolveRegAllocHint - Resolves the specified register allocation hint
479457 /// to a physical register. Returns the physical register if it is successful.
480458 unsigned
481 ARMRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
482 const MachineFunction &MF) const {
459 ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
460 const MachineFunction &MF) const {
483461 if (Reg == 0 || !isPhysicalRegister(Reg))
484462 return 0;
485463 if (Type == 0)
494472 }
495473
496474 void
497 ARMRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
498 MachineFunction &MF) const {
475 ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
476 MachineFunction &MF) const {
499477 MachineRegisterInfo *MRI = &MF.getRegInfo();
500478 std::pair Hint = MRI->getRegAllocationHint(Reg);
501479 if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
515493
516494 bool
517495 ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
518 const ARMFunctionInfo *AFI = MF.getInfo();
519 return ThumbRegScavenging || !AFI->isThumbFunction();
496 return true;
520497 }
521498
522499 /// hasFP - Return true if the specified function should have a dedicated frame
523500 /// pointer register. This is true if the function has variable sized allocas
524501 /// or if frame pointer elimination is disabled.
525502 ///
526 bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const {
503 bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
527504 const MachineFrameInfo *MFI = MF.getFrameInfo();
528505 return (NoFramePointerElim ||
529506 MFI->hasVarSizedObjects() ||
538515 bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
539516 const MachineFrameInfo *FFI = MF.getFrameInfo();
540517 unsigned CFSize = FFI->getMaxCallFrameSize();
541 ARMFunctionInfo *AFI = MF.getInfo();
542518 // It's not always a good idea to include the call frame as part of the
543519 // stack frame. ARM (especially Thumb) has small immediate offset to
544520 // address the stack frame. So a large call frame can cause poor codegen
545521 // and may even makes it impossible to scavenge a register.
546 if (AFI->isThumbFunction()) {
547 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
548 return false;
549 } else {
550 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
551 return false;
552 }
522 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
523 return false;
524
553525 return !MF.getFrameInfo()->hasVarSizedObjects();
554526 }
555527
569541 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
570542 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
571543 assert(ThisVal && "Didn't extract field correctly");
572
544
573545 // We will handle these bits from offset, clear them.
574546 NumBytes &= ~ThisVal;
575
547
576548 // Get the properly encoded SOImmVal field.
577549 int SOImmVal = ARM_AM::getSOImmVal(ThisVal);
578550 assert(SOImmVal != -1 && "Bit extraction didn't work?");
579
551
580552 // Build the new ADD / SUB.
581553 BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg)
582554 .addReg(BaseReg, RegState::Kill).addImm(SOImmVal)
585557 }
586558 }
587559
588 /// calcNumMI - Returns the number of instructions required to materialize
589 /// the specific add / sub r, c instruction.
590 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
591 unsigned NumBits, unsigned Scale) {
592 unsigned NumMIs = 0;
593 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
594
595 if (Opc == ARM::tADDrSPi) {
596 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
597 Bytes -= ThisVal;
598 NumMIs++;
599 NumBits = 8;
600 Scale = 1; // Followed by a number of tADDi8.
601 Chunk = ((1 << NumBits) - 1) * Scale;
602 }
603
604 NumMIs += Bytes / Chunk;
605 if ((Bytes % Chunk) != 0)
606 NumMIs++;
607 if (ExtraOpc)
608 NumMIs++;
609 return NumMIs;
610 }
611
612 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
613 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
614 /// in a register using mov / mvn sequences or load the immediate from a
615 /// constpool entry.
616 static
617 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
618 MachineBasicBlock::iterator &MBBI,
619 unsigned DestReg, unsigned BaseReg,
620 int NumBytes, bool CanChangeCC,
621 const TargetInstrInfo &TII,
622 const ARMRegisterInfo& MRI,
623 DebugLoc dl) {
624 bool isHigh = !MRI.isLowRegister(DestReg) ||
625 (BaseReg != 0 && !MRI.isLowRegister(BaseReg));
626 bool isSub = false;
627 // Subtract doesn't have high register version. Load the negative value
628 // if either base or dest register is a high register. Also, if do not
629 // issue sub as part of the sequence if condition register is to be
630 // preserved.
631 if (NumBytes < 0 && !isHigh && CanChangeCC) {
632 isSub = true;
633 NumBytes = -NumBytes;
634 }
635 unsigned LdReg = DestReg;
636 if (DestReg == ARM::SP) {
637 assert(BaseReg == ARM::SP && "Unexpected!");
638 LdReg = ARM::R3;
639 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
640 .addReg(ARM::R3, RegState::Kill);
641 }
642
643 if (NumBytes <= 255 && NumBytes >= 0)
644 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
645 else if (NumBytes < 0 && NumBytes >= -255) {
646 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
647 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
648 .addReg(LdReg, RegState::Kill);
649 } else
650 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII,
651 true, dl);
652
653 // Emit add / sub.
654 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
655 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
656 TII.get(Opc), DestReg);
657 if (DestReg == ARM::SP || isSub)
658 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
659 else
660 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
661 if (DestReg == ARM::SP)
662 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
663 .addReg(ARM::R12, RegState::Kill);
664 }
665
666 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
667 /// a destreg = basereg + immediate in Thumb code.
668 static
669 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
670 MachineBasicBlock::iterator &MBBI,
671 unsigned DestReg, unsigned BaseReg,
672 int NumBytes, const TargetInstrInfo &TII,
673 const ARMRegisterInfo& MRI,
674 DebugLoc dl) {
675 bool isSub = NumBytes < 0;
676 unsigned Bytes = (unsigned)NumBytes;
677 if (isSub) Bytes = -NumBytes;
678 bool isMul4 = (Bytes & 3) == 0;
679 bool isTwoAddr = false;
680 bool DstNotEqBase = false;
681 unsigned NumBits = 1;
682 unsigned Scale = 1;
683 int Opc = 0;
684 int ExtraOpc = 0;
685
686 if (DestReg == BaseReg && BaseReg == ARM::SP) {
687 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
688 NumBits = 7;
689 Scale = 4;
690 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
691 isTwoAddr = true;
692 } else if (!isSub && BaseReg == ARM::SP) {
693 // r1 = add sp, 403
694 // =>
695 // r1 = add sp, 100 * 4
696 // r1 = add r1, 3
697 if (!isMul4) {
698 Bytes &= ~3;
699 ExtraOpc = ARM::tADDi3;
700 }
701 NumBits = 8;
702 Scale = 4;
703 Opc = ARM::tADDrSPi;
704 } else {
705 // sp = sub sp, c
706 // r1 = sub sp, c
707 // r8 = sub sp, c
708 if (DestReg != BaseReg)
709 DstNotEqBase = true;
710 NumBits = 8;
711 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
712 isTwoAddr = true;
713 }
714
715 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
716 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
717 if (NumMIs > Threshold) {
718 // This will expand into too many instructions. Load the immediate from a
719 // constpool entry.
720 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
721 MRI, dl);
722 return;
723 }
724
725 if (DstNotEqBase) {
726 if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) {
727 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
728 unsigned Chunk = (1 << 3) - 1;
729 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
730 Bytes -= ThisVal;
731 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
732 .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
733 } else {
734 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
735 .addReg(BaseReg, RegState::Kill);
736 }
737 BaseReg = DestReg;
738 }
739
740 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
741 while (Bytes) {
742 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
743 Bytes -= ThisVal;
744 ThisVal /= Scale;
745 // Build the new tADD / tSUB.
746 if (isTwoAddr)
747 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
748 .addReg(DestReg).addImm(ThisVal);
749 else {
750 bool isKill = BaseReg != ARM::SP;
751 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
752 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
753 BaseReg = DestReg;
754
755 if (Opc == ARM::tADDrSPi) {
756 // r4 = add sp, imm
757 // r4 = add r4, imm
758 // ...
759 NumBits = 8;
760 Scale = 1;
761 Chunk = ((1 << NumBits) - 1) * Scale;
762 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
763 isTwoAddr = true;
764 }
765 }
766 }
767
768 if (ExtraOpc)
769 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
770 .addReg(DestReg, RegState::Kill)
771 .addImm(((unsigned)NumBytes) & 3);
772 }
773
774 static
775 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
776 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
777 bool isThumb, const TargetInstrInfo &TII,
778 const ARMRegisterInfo& MRI,
779 DebugLoc dl) {
780 if (isThumb)
781 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
782 MRI, dl);
783 else
784 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
785 Pred, PredReg, TII, dl);
560 void ARMRegisterInfo::
561 emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
562 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
563 const TargetInstrInfo &TII, DebugLoc dl) const {
564 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
565 Pred, PredReg, TII, dl);
786566 }
787567
788568 void ARMRegisterInfo::
796576 DebugLoc dl = Old->getDebugLoc();
797577 unsigned Amount = Old->getOperand(0).getImm();
798578 if (Amount != 0) {
799 ARMFunctionInfo *AFI = MF.getInfo();
800579 // We need to keep the stack aligned properly. To do this, we round the
801580 // amount of space needed for the outgoing arguments up to the next
802581 // alignment boundary.
805584
806585 // Replace the pseudo instruction with a new instruction...
807586 unsigned Opc = Old->getOpcode();
808 bool isThumb = AFI->isThumbFunction();
809 ARMCC::CondCodes Pred = isThumb
810 ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm();
587 ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm();
811588 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
812589 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
813 unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg();
814 emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this, dl);
590 unsigned PredReg = Old->getOperand(2).getReg();
591 emitSPUpdate(MBB, I, -Amount, Pred, PredReg, TII, dl);
815592 } else {
816593 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
817 unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg();
594 unsigned PredReg = Old->getOperand(3).getReg();
818595 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
819 emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this, dl);
596 emitSPUpdate(MBB, I, Amount, Pred, PredReg, TII, dl);
820597 }
821598 }
822599 }
823600 MBB.erase(I);
824 }
825
826 /// emitThumbConstant - Emit a series of instructions to materialize a
827 /// constant.
828 static void emitThumbConstant(MachineBasicBlock &MBB,
829 MachineBasicBlock::iterator &MBBI,
830 unsigned DestReg, int Imm,
831 const TargetInstrInfo &TII,
832 const ARMRegisterInfo& MRI,
833 DebugLoc dl) {
834 bool isSub = Imm < 0;
835 if (isSub) Imm = -Imm;
836
837 int Chunk = (1 << 8) - 1;
838 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
839 Imm -= ThisVal;
840 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
841 if (Imm > 0)
842 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
843 if (isSub)
844 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
845 .addReg(DestReg, RegState::Kill);
846601 }
847602
848603 /// findScratchRegister - Find a 'free' ARM register. If register scavenger
867622 MachineBasicBlock &MBB = *MI.getParent();
868623 MachineFunction &MF = *MBB.getParent();
869624 ARMFunctionInfo *AFI = MF.getInfo();
870 bool isThumb = AFI->isThumbFunction();
871625 DebugLoc dl = MI.getDebugLoc();
872626
873627 while (!MI.getOperand(i).isFI()) {
874628 ++i;
875629 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
876630 }
877
631
878632 unsigned FrameReg = ARM::SP;
879633 int FrameIndex = MI.getOperand(i).getIndex();
880 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
634 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
881635 MF.getFrameInfo()->getStackSize() + SPAdj;
882636
883637 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
925679 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset);
926680 return;
927681 }
928
682
929683 // Otherwise, we fallback to common code below to form the imm offset with
930684 // a sequence of ADDri instructions. First though, pull as much of the imm
931685 // into this ADDri as possible.
932686 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
933687 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
934
688
935689 // We will handle these bits from offset, clear them.
936690 Offset &= ~ThisImmVal;
937
691
938692 // Get the properly encoded SOImmVal field.
939693 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal);
940 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
694 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
941695 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal);
942 } else if (Opcode == ARM::tADDrSPi) {
943 Offset += MI.getOperand(i+1).getImm();
944
945 // Can't use tADDrSPi if it's based off the frame pointer.
946 unsigned NumBits = 0;
947 unsigned Scale = 1;
948 if (FrameReg != ARM::SP) {
949 Opcode = ARM::tADDi3;
950 MI.setDesc(TII.get(ARM::tADDi3));
951 NumBits = 3;
952 } else {
953 NumBits = 8;
954 Scale = 4;
955 assert((Offset & 3) == 0 &&
956 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
957 }
958
959 if (Offset == 0) {
960 // Turn it into a move.
961 MI.setDesc(TII.get(ARM::tMOVhir2lor));
962 MI.getOperand(i).ChangeToRegister(FrameReg, false);
963 MI.RemoveOperand(i+1);
964 return;
965 }
966
967 // Common case: small offset, fits into instruction.
968 unsigned Mask = (1 << NumBits) - 1;
969 if (((Offset / Scale) & ~Mask) == 0) {
970 // Replace the FrameIndex with sp / fp
971 MI.getOperand(i).ChangeToRegister(FrameReg, false);
972 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
973 return;
974 }
975
976 unsigned DestReg = MI.getOperand(0).getReg();
977 unsigned Bytes = (Offset > 0) ? Offset : -Offset;
978 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
979 // MI would expand into a large number of instructions. Don't try to
980 // simplify the immediate.
981 if (NumMIs > 2) {
982 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
983 *this, dl);
984 MBB.erase(II);
985 return;
986 }
987
988 if (Offset > 0) {
989 // Translate r0 = add sp, imm to
990 // r0 = add sp, 255*4
991 // r0 = add r0, (imm - 255*4)
992 MI.getOperand(i).ChangeToRegister(FrameReg, false);
993 MI.getOperand(i+1).ChangeToImmediate(Mask);
994 Offset = (Offset - Mask * Scale);
995 MachineBasicBlock::iterator NII = next(II);
996 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
997 *this, dl);
998 } else {
999 // Translate r0 = add sp, -imm to
1000 // r0 = -imm (this is then translated into a series of instructons)
1001 // r0 = add r0, sp
1002 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
1003 MI.setDesc(TII.get(ARM::tADDhirr));
1004 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
1005 MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
1006 }
1007 return;
1008696 } else {
1009697 unsigned ImmIdx = 0;
1010698 int InstrOffs = 0;
1036724 Scale = 4;
1037725 break;
1038726 }
1039 case ARMII::AddrModeTs: {
1040 ImmIdx = i+1;
1041 InstrOffs = MI.getOperand(ImmIdx).getImm();
1042 NumBits = (FrameReg == ARM::SP) ? 8 : 5;
1043 Scale = 4;
1044 break;
1045 }
1046727 default:
1047728 assert(0 && "Unsupported addressing mode!");
1048729 abort();
1051732
1052733 Offset += InstrOffs * Scale;
1053734 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1054 if (Offset < 0 && !isThumb) {
735 if (Offset < 0) {
1055736 Offset = -Offset;
1056737 isSub = true;
1057738 }
1069750 return;
1070751 }
1071752
1072 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
1073 if (AddrMode == ARMII::AddrModeTs) {
1074 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
1075 // a different base register.
1076 NumBits = 5;
1077 Mask = (1 << NumBits) - 1;
1078 }
1079 // If this is a thumb spill / restore, we will be using a constpool load to
1080 // materialize the offset.
1081 if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore)
1082 ImmOp.ChangeToImmediate(0);
1083 else {
1084 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1085 ImmedOffset = ImmedOffset & Mask;
1086 if (isSub)
1087 ImmedOffset |= 1 << NumBits;
1088 ImmOp.ChangeToImmediate(ImmedOffset);
1089 Offset &= ~(Mask*Scale);
1090 }
1091 }
1092
753 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
754 ImmedOffset = ImmedOffset & Mask;
755 if (isSub)
756 ImmedOffset |= 1 << NumBits;
757 ImmOp.ChangeToImmediate(ImmedOffset);
758 Offset &= ~(Mask*Scale);
759 }
760
1093761 // If we get here, the immediate doesn't fit into the instruction. We folded
1094762 // as much as possible above, handle the rest, providing a register that is
1095763 // SP+LargeImm.
1096764 assert(Offset && "This code isn't needed if offset already handled!");
1097765
1098 if (isThumb) {
1099 if (Desc.mayLoad()) {
1100 // Use the destination register to materialize sp + offset.
1101 unsigned TmpReg = MI.getOperand(0).getReg();
1102 bool UseRR = false;
1103 if (Opcode == ARM::tRestore) {
1104 if (FrameReg == ARM::SP)
1105 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
1106 Offset, false, TII, *this, dl);
1107 else {
1108 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII,
1109 true, dl);
1110 UseRR = true;
1111 }
1112 } else
1113 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
1114 *this, dl);
1115 MI.setDesc(TII.get(ARM::tLDR));
1116 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
1117 if (UseRR)
1118 // Use [reg, reg] addrmode.
1119 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
1120 else // tLDR has an extra register operand.
1121 MI.addOperand(MachineOperand::CreateReg(0, false));
1122 } else if (Desc.mayStore()) {
1123 // FIXME! This is horrific!!! We need register scavenging.
1124 // Our temporary workaround has marked r3 unavailable. Of course, r3 is
1125 // also a ABI register so it's possible that is is the register that is
1126 // being storing here. If that's the case, we do the following:
1127 // r12 = r2
1128 // Use r2 to materialize sp + offset
1129 // str r3, r2
1130 // r2 = r12
1131 unsigned ValReg = MI.getOperand(0).getReg();
1132 unsigned TmpReg = ARM::R3;
1133 bool UseRR = false;
1134 if (ValReg == ARM::R3) {
1135 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
1136 .addReg(ARM::R2, RegState::Kill);
1137 TmpReg = ARM::R2;
1138 }
1139 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
1140 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
1141 .addReg(ARM::R3, RegState::Kill);
1142 if (Opcode == ARM::tSpill) {
1143 if (FrameReg == ARM::SP)
1144 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
1145 Offset, false, TII, *this, dl);
1146 else {
1147 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII,
1148 true, dl);
1149 UseRR = true;
1150 }
1151 } else
1152 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
1153 *this, dl);
1154 MI.setDesc(TII.get(ARM::tSTR));
1155 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
1156 if (UseRR) // Use [reg, reg] addrmode.
1157 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
1158 else // tSTR has an extra register operand.
1159 MI.addOperand(MachineOperand::CreateReg(0, false));
1160
1161 MachineBasicBlock::iterator NII = next(II);
1162 if (ValReg == ARM::R3)
1163 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
1164 .addReg(ARM::R12, RegState::Kill);
1165 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
1166 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
1167 .addReg(ARM::R12, RegState::Kill);
1168 } else
1169 assert(false && "Unexpected opcode!");
1170 } else {
1171 // Insert a set of r12 with the full address: r12 = sp + offset
1172 // If the offset we have is too large to fit into the instruction, we need
1173 // to form it with a series of ADDri's. Do this by taking 8-bit chunks
1174 // out of 'Offset'.
1175 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
1176 if (ScratchReg == 0)
1177 // No register is "free". Scavenge a register.
1178 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
1179 int PIdx = MI.findFirstPredOperandIdx();
1180 ARMCC::CondCodes Pred = (PIdx == -1)
1181 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1182 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
1183 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
1184 isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
1185 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1186 }
766 // Insert a set of r12 with the full address: r12 = sp + offset
767 // If the offset we have is too large to fit into the instruction, we need
768 // to form it with a series of ADDri's. Do this by taking 8-bit chunks
769 // out of 'Offset'.
770 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
771 if (ScratchReg == 0)
772 // No register is "free". Scavenge a register.
773 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
774 int PIdx = MI.findFirstPredOperandIdx();
775 ARMCC::CondCodes Pred = (PIdx == -1)
776 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
777 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
778 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
779 isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
780 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1187781 }
1188782
1189783 static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
1205799 }
1206800
1207801 void
1208 ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
1209 RegScavenger *RS) const {
802 ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
803 RegScavenger *RS) const {
1210804 // This tells PEI to spill the FP as if it is any other callee-save register
1211805 // to take advantage the eliminateFrameIndex machinery. This also ensures it
1212806 // is spilled in the order specified by getCalleeSavedRegs() to make it easier
1265859 default:
1266860 break;
1267861 }
1268 } else {
862 } else {
1269863 if (!STI.isTargetDarwin()) {
1270864 UnspilledCS1GPRs.push_back(Reg);
1271865 continue;
14591053 MachineBasicBlock::iterator MBBI = MBB.begin();
14601054 MachineFrameInfo *MFI = MF.getFrameInfo();
14611055 ARMFunctionInfo *AFI = MF.getInfo();
1462 bool isThumb = AFI->isThumbFunction();
14631056 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
14641057 unsigned NumBytes = MFI->getStackSize();
14651058 const std::vector &CSI = MFI->getCalleeSavedInfo();
14661059 DebugLoc dl = (MBBI != MBB.end() ?
14671060 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
14681061
1469 if (isThumb) {
1470 // Check if R3 is live in. It might have to be used as a scratch register.
1471 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(),
1472 E = MF.getRegInfo().livein_end(); I != E; ++I) {
1473 if (I->first == ARM::R3) {
1474 AFI->setR3IsLiveIn(true);
1475 break;
1476 }
1477 }
1478
1479 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
1480 NumBytes = (NumBytes + 3) & ~3;
1481 MFI->setStackSize(NumBytes);
1482 }
1483
14841062 // Determine the sizes of each callee-save spill areas and record which frame
14851063 // belongs to which callee-save spill areas.
14861064 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
14871065 int FramePtrSpillFI = 0;
14881066
14891067 if (VARegSaveSize)
1490 emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII,
1491 *this, dl);
1068 emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, TII, dl);
14921069
14931070 if (!AFI->hasStackFrame()) {
14941071 if (NumBytes != 0)
1495 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
1072 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
14961073 return;
14971074 }
14981075
15301107 }
15311108 }
15321109
1533 if (!isThumb) {
1534 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
1535 emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this, dl);
1536 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
1537 } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
1538 ++MBBI;
1539 if (MBBI != MBB.end())
1540 dl = MBBI->getDebugLoc();
1541 }
1110 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
1111 emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, TII, dl);
1112 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
15421113
15431114 // Darwin ABI requires FP to point to the stack slot that contains the
15441115 // previous FP.
15451116 if (STI.isTargetDarwin() || hasFP(MF)) {
15461117 MachineInstrBuilder MIB =
1547 BuildMI(MBB, MBBI, dl, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),
1548 FramePtr)
1118 BuildMI(MBB, MBBI, dl, TII.get(ARM::ADDri), FramePtr)
15491119 .addFrameIndex(FramePtrSpillFI).addImm(0);
1550 if (!isThumb) AddDefaultCC(AddDefaultPred(MIB));
1551 }
1552
1553 if (!isThumb) {
1554 // Build the new SUBri to adjust SP for integer callee-save spill area 2.
1555 emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this, dl);
1556
1557 // Build the new SUBri to adjust SP for FP callee-save spill area.
1558 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
1559 emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this, dl);
1560 }
1120 AddDefaultCC(AddDefaultPred(MIB));
1121 }
1122
1123 // Build the new SUBri to adjust SP for integer callee-save spill area 2.
1124 emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, TII, dl);
1125
1126 // Build the new SUBri to adjust SP for FP callee-save spill area.
1127 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
1128 emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, TII, dl);
15611129
15621130 // Determine starting offsets of spill areas.
15631131 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
15671135 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
15681136 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
15691137 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
1570
1138
15711139 NumBytes = DPRCSOffset;
15721140 if (NumBytes) {
15731141 // Insert it after all the callee-save spills.
1574 if (!isThumb)
1575 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
1576 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
1577 }
1578
1579 if(STI.isTargetELF() && hasFP(MF)) {
1142 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
1143 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
1144 }
1145
1146 if (STI.isTargetELF() && hasFP(MF)) {
15801147 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
15811148 AFI->getFramePtrSpillOffset());
15821149 }
15951162
15961163 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
15971164 return ((MI->getOpcode() == ARM::FLDD ||
1598 MI->getOpcode() == ARM::LDR ||
1599 MI->getOpcode() == ARM::tRestore) &&
1165 MI->getOpcode() == ARM::LDR) &&
16001166 MI->getOperand(1).isFI() &&
16011167 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
16021168 }
16041170 void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
16051171 MachineBasicBlock &MBB) const {
16061172 MachineBasicBlock::iterator MBBI = prior(MBB.end());
1607 assert((MBBI->getOpcode() == ARM::BX_RET ||
1608 MBBI->getOpcode() == ARM::tBX_RET ||
1609 MBBI->getOpcode() == ARM::tPOP_RET) &&
1173 assert(MBBI->getOpcode() == ARM::BX_RET &&
16101174 "Can only insert epilog into returning blocks");
16111175 DebugLoc dl = MBBI->getDebugLoc();
16121176 MachineFrameInfo *MFI = MF.getFrameInfo();
16131177 ARMFunctionInfo *AFI = MF.getInfo();
1614 bool isThumb = AFI->isThumbFunction();
16151178 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
16161179 int NumBytes = (int)MFI->getStackSize();
16171180
16181181 if (!AFI->hasStackFrame()) {
16191182 if (NumBytes != 0)
1620 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
1183 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
16211184 } else {
16221185 // Unwind MBBI to point to first LDR / FLDD.
16231186 const unsigned *CSRegs = getCalleeSavedRegs();
16331196 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
16341197 AFI->getGPRCalleeSavedArea2Size() +
16351198 AFI->getDPRCalleeSavedAreaSize());
1636 if (isThumb) {
1637 if (hasFP(MF)) {
1638 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1639 // Reset SP based on frame pointer only if the stack frame extends beyond
1640 // frame pointer stack slot or target is ELF and the function has FP.
1199
1200 // Darwin ABI requires FP to point to the stack slot that contains the
1201 // previous FP.
1202 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
1203 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1204 // Reset SP based on frame pointer only if the stack frame extends beyond
1205 // frame pointer stack slot or target is ELF and the function has FP.
1206 if (AFI->getGPRCalleeSavedArea2Size() ||
1207 AFI->getDPRCalleeSavedAreaSize() ||
1208 AFI->getDPRCalleeSavedAreaOffset()||
1209 hasFP(MF)) {
16411210 if (NumBytes)
1642 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
1643 TII, *this, dl);
1211 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
1212 .addImm(NumBytes)
1213 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
16441214 else
1645 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
1646 .addReg(FramePtr);
1647 } else {
1648 if (MBBI->getOpcode() == ARM::tBX_RET &&
1649 &MBB.front() != MBBI &&
1650 prior(MBBI)->getOpcode() == ARM::tPOP) {
1651 MachineBasicBlock::iterator PMBBI = prior(MBBI);
1652 emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII,
1653 *this, dl);
1654 } else
1655 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII,
1656 *this, dl);
1215 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
1216 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
16571217 }
1658 } else {
1659 // Darwin ABI requires FP to point to the stack slot that contains the
1660 // previous FP.
1661 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
1662 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1663 // Reset SP based on frame pointer only if the stack frame extends beyond
1664 // frame pointer stack slot or target is ELF and the function has FP.
1665 if (AFI->getGPRCalleeSavedArea2Size() ||
1666 AFI->getDPRCalleeSavedAreaSize() ||
1667 AFI->getDPRCalleeSavedAreaOffset()||
1668 hasFP(MF)) {
1669 if (NumBytes)
1670 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
1671 .addImm(NumBytes)
1672 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1673 else
1674 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
1675 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1676 }
1677 } else if (NumBytes) {
1678 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this, dl);
1679 }
1680
1681 // Move SP to start of integer callee save spill area 2.
1682 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
1683 emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0,
1684 false, TII, *this, dl);
1685
1686 // Move SP to start of integer callee save spill area 1.
1687 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
1688 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0,
1689 false, TII, *this, dl);
1690
1691 // Move SP to SP upon entry to the function.
1692 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
1693 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0,
1694 false, TII, *this, dl);
1695 }
1696 }
1697
1698 if (VARegSaveSize) {
1699 if (isThumb)
1700 // Epilogue for vararg functions: pop LR to R3 and branch off it.
1701 // FIXME: Verify this is still ok when R3 is no longer being reserved.
1702 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
1703
1704 emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII,
1705 *this, dl);
1706
1707 if (isThumb) {
1708 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
1709 MBB.erase(MBBI);
1710 }
1711 }
1712 }
1713
1714 unsigned ARMRegisterInfo::getRARegister() const {
1218 } else if (NumBytes) {
1219 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
1220 }
1221
1222 // Move SP to start of integer callee save spill area 2.
1223 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
1224 emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0,
1225 TII, dl);
1226
1227 // Move SP to start of integer callee save spill area 1.
1228 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
1229 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0,
1230 TII, dl);
1231
1232 // Move SP to SP upon entry to the function.
1233 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
1234 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0,
1235 TII, dl);
1236 }
1237
1238 if (VARegSaveSize)
1239 emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, TII, dl);
1240
1241 }
1242
1243 unsigned ARMBaseRegisterInfo::getRARegister() const {
17151244 return ARM::LR;
17161245 }
17171246
1718 unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
1247 unsigned ARMBaseRegisterInfo::getFrameRegister(MachineFunction &MF) const {
17191248 if (STI.isTargetDarwin() || hasFP(MF))
17201249 return FramePtr;
17211250 return ARM::SP;
17221251 }
17231252
1724 unsigned ARMRegisterInfo::getEHExceptionRegister() const {
1253 unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
17251254 assert(0 && "What is the exception register");
17261255 return 0;
17271256 }
17281257
1729 unsigned ARMRegisterInfo::getEHHandlerRegister() const {
1258 unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
17301259 assert(0 && "What is the exception handler register");
17311260 return 0;
17321261 }
17331262
1734 int ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
1263 int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
17351264 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
17361265 }
17371266
1738 unsigned ARMRegisterInfo::getRegisterPairEven(unsigned Reg,
1739 const MachineFunction &MF) const {
1267 unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
1268 const MachineFunction &MF) const {
17401269 switch (Reg) {
17411270 default: break;
17421271 // Return 0 if either register of the pair is a special register.
18091338 return 0;
18101339 }
18111340
1812 unsigned ARMRegisterInfo::getRegisterPairOdd(unsigned Reg,
1341 unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
18131342 const MachineFunction &MF) const {
18141343 switch (Reg) {
18151344 default: break;
1313 #ifndef ARMREGISTERINFO_H
1414 #define ARMREGISTERINFO_H
1515
16 #include "ARM.h"
1617 #include "llvm/Target/TargetRegisterInfo.h"
1718 #include "ARMGenRegisterInfo.h.inc"
1819
2930 };
3031 }
3132
32 struct ARMRegisterInfo : public ARMGenRegisterInfo {
33 struct ARMBaseRegisterInfo : public ARMGenRegisterInfo {
34 protected:
3335 const TargetInstrInfo &TII;
3436 const ARMSubtarget &STI;
3537
38 /// FramePtr - ARM physical register used as frame ptr.
39 unsigned FramePtr;
3640 public:
37 ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
38
39 /// emitLoadConstPool - Emits a load from constpool to materialize the
40 /// specified immediate.
41 void emitLoadConstPool(MachineBasicBlock &MBB,
42 MachineBasicBlock::iterator &MBBI,
43 unsigned DestReg, int Val,
44 unsigned Pred, unsigned PredReg,
45 const TargetInstrInfo *TII, bool isThumb,
46 DebugLoc dl) const;
41 ARMBaseRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
4742
4843 /// getRegisterNumbering - Given the enum value for some register, e.g.
4944 /// ARM::LR, return the number that it corresponds to (e.g. 14).
5449 static unsigned getRegisterNumbering(unsigned RegEnum, bool &isSPVFP);
5550
5651 /// Code Generation virtual methods...
57 const TargetRegisterClass *
58 getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) const;
5952 const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
6053
6154 const TargetRegisterClass* const*
7871 void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
7972 MachineFunction &MF) const;
8073
74 bool hasFP(const MachineFunction &MF) const;
75
76 void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
77 RegScavenger *RS = NULL) const;
78
79 // Debug information queries.
80 unsigned getRARegister() const;
81 unsigned getFrameRegister(MachineFunction &MF) const;
82
83 // Exception handling queries.
84 unsigned getEHExceptionRegister() const;
85 unsigned getEHHandlerRegister() const;
86
87 int getDwarfRegNum(unsigned RegNum, bool isEH) const;
88
89 bool isLowRegister(unsigned Reg) const;
90
91 private:
92 unsigned getRegisterPairEven(unsigned Reg, const MachineFunction &MF) const;
93
94 unsigned getRegisterPairOdd(unsigned Reg, const MachineFunction &MF) const;
95 };
96
97 struct ARMRegisterInfo : public ARMBaseRegisterInfo {
98 public:
99 ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
100
101 /// emitLoadConstPool - Emits a load from constpool to materialize the
102 /// specified immediate.
103 void emitLoadConstPool(MachineBasicBlock &MBB,
104 MachineBasicBlock::iterator &MBBI,
105 unsigned DestReg, int Val,
106 unsigned Pred, unsigned PredReg,
107 const TargetInstrInfo *TII,
108 DebugLoc dl) const;
109
110 /// Code Generation virtual methods...
111 bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
112
81113 bool requiresRegisterScavenging(const MachineFunction &MF) const;
82
83 bool hasFP(const MachineFunction &MF) const;
84114
85115 bool hasReservedCallFrame(MachineFunction &MF) const;
86116
91121 void eliminateFrameIndex(MachineBasicBlock::iterator II,
92122 int SPAdj, RegScavenger *RS = NULL) const;
93123
94 void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
95 RegScavenger *RS = NULL) const;
96
97124 void emitPrologue(MachineFunction &MF) const;
98125 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
99126
100 // Debug information queries.
101 unsigned getRARegister() const;
102 unsigned getFrameRegister(MachineFunction &MF) const;
103
104 // Exception handling queries.
105 unsigned getEHExceptionRegister() const;
106 unsigned getEHHandlerRegister() const;
107
108 int getDwarfRegNum(unsigned RegNum, bool isEH) const;
109
110 bool isLowRegister(unsigned Reg) const;
111
112 private:
113 /// FramePtr - ARM physical register used as frame ptr.
114 unsigned FramePtr;
115
116 unsigned getRegisterPairEven(unsigned Reg, const MachineFunction &MF) const;
117
118 unsigned getRegisterPairOdd(unsigned Reg, const MachineFunction &MF) const;
119
127 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
128 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
129 const TargetInstrInfo &TII, DebugLoc dl) const;
120130 };
121131
122132 } // end namespace llvm
119119 public:
120120 ThumbTargetMachine(const Module &M, const std::string &FS);
121121
122 virtual const ARMRegisterInfo *getRegisterInfo() const {
122 virtual const ThumbRegisterInfo *getRegisterInfo() const {
123123 return &InstrInfo.getRegisterInfo();
124124 }
125125
2222 using namespace llvm;
2323
2424 ThumbInstrInfo::ThumbInstrInfo(const ARMSubtarget &STI)
25 : ARMBaseInstrInfo(STI) {
25 : ARMBaseInstrInfo(STI), RI(*this, STI) {
2626 }
2727
2828 bool ThumbInstrInfo::isMoveInstr(const MachineInstr &MI,
113113 return false;
114114 }
115115
116 bool ThumbInstrInfo::
117 canFoldMemoryOperand(const MachineInstr *MI,
118 const SmallVectorImpl &Ops) const {
119 if (Ops.size() != 1) return false;
120
121 unsigned OpNum = Ops[0];
122 unsigned Opc = MI->getOpcode();
123 switch (Opc) {
124 default: break;
125 case ARM::tMOVr:
126 case ARM::tMOVlor2hir:
127 case ARM::tMOVhir2lor:
128 case ARM::tMOVhir2hir: {
129 if (OpNum == 0) { // move -> store
130 unsigned SrcReg = MI->getOperand(1).getReg();
131 if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
132 // tSpill cannot take a high register operand.
133 return false;
134 } else { // move -> load
135 unsigned DstReg = MI->getOperand(0).getReg();
136 if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
137 // tRestore cannot target a high register operand.
138 return false;
139 }
140 return true;
141 }
142 }
143
144 return false;
145 }
146
116147 void ThumbInstrInfo::
117148 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
118149 unsigned SrcReg, bool isKill, int FI,
243274 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
244275 const SmallVectorImpl &Ops, int FI) const {
245276 if (Ops.size() != 1) return NULL;
246 const ARMRegisterInfo &RI = getRegisterInfo();
247277
248278 unsigned OpNum = Ops[0];
249279 unsigned Opc = MI->getOpcode();
1414 #define THUMBINSTRUCTIONINFO_H
1515
1616 #include "llvm/Target/TargetInstrInfo.h"
17 #include "ARMRegisterInfo.h"
1817 #include "ARM.h"
1918 #include "ARMInstrInfo.h"
19 #include "ThumbRegisterInfo.h"
2020
2121 namespace llvm {
2222 class ARMSubtarget;
2323
2424 class ThumbInstrInfo : public ARMBaseInstrInfo {
25 ThumbRegisterInfo RI;
2526 public:
2627 explicit ThumbInstrInfo(const ARMSubtarget &STI);
28
29 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
30 /// such, whenever a client has an instance of instruction info, it should
31 /// always be able to get register info as well (through this method).
32 ///
33 virtual const ThumbRegisterInfo &getRegisterInfo() const { return RI; }
2734
2835 /// Return true if the instruction is a register to register move and return
2936 /// the source and dest operands and their sub-register indices by reference.
6774 MachineBasicBlock::iterator MI,
6875 const std::vector &CSI) const;
6976
77 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
78 const SmallVectorImpl &Ops) const;
79
7080 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
7181 MachineInstr* MI,
7282 const SmallVectorImpl &Ops,
0 //===- ThumbRegisterInfo.cpp - Thumb Register Information -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the ARM implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARM.h"
14 #include "ARMAddressingModes.h"
15 #include "ARMMachineFunctionInfo.h"
16 #include "ARMSubtarget.h"
17 #include "ThumbInstrInfo.h"
18 #include "ThumbRegisterInfo.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineLocation.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/Target/TargetFrameInfo.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/ADT/BitVector.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/Support/CommandLine.h"
32 using namespace llvm;
33
34 static cl::opt
35 ThumbRegScavenging("enable-thumb-reg-scavenging",
36 cl::Hidden,
37 cl::desc("Enable register scavenging on Thumb"));
38
39 ThumbRegisterInfo::ThumbRegisterInfo(const TargetInstrInfo &tii,
40 const ARMSubtarget &sti)
41 : ARMBaseRegisterInfo(tii, sti) {
42 }
43
44 /// emitLoadConstPool - Emits a load from constpool to materialize the
45 /// specified immediate.
46 void ThumbRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
47 MachineBasicBlock::iterator &MBBI,
48 unsigned DestReg, int Val,
49 unsigned Pred, unsigned PredReg,
50 const TargetInstrInfo *TII,
51 DebugLoc dl) const {
52 MachineFunction &MF = *MBB.getParent();
53 MachineConstantPool *ConstantPool = MF.getConstantPool();
54 Constant *C = ConstantInt::get(Type::Int32Ty, Val);
55 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
56
57 BuildMI(MBB, MBBI, dl, TII->get(ARM::tLDRcp), DestReg)
58 .addConstantPoolIndex(Idx);
59 }
60
61 const TargetRegisterClass*
62 ThumbRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
63 if (isLowRegister(Reg))
64 return ARM::tGPRRegisterClass;
65 switch (Reg) {
66 default:
67 break;
68 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
69 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC:
70 return ARM::GPRRegisterClass;
71 }
72
73 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
74 }
75
76 bool
77 ThumbRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
78 return ThumbRegScavenging;
79 }
80
81 bool ThumbRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
82 const MachineFrameInfo *FFI = MF.getFrameInfo();
83 unsigned CFSize = FFI->getMaxCallFrameSize();
84 // It's not always a good idea to include the call frame as part of the
85 // stack frame. ARM (especially Thumb) has small immediate offset to
86 // address the stack frame. So a large call frame can cause poor codegen
87 // and may even makes it impossible to scavenge a register.
88 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
89 return false;
90
91 return !MF.getFrameInfo()->hasVarSizedObjects();
92 }
93
94 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
95 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
96 /// in a register using mov / mvn sequences or load the immediate from a
97 /// constpool entry.
98 static
99 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
100 MachineBasicBlock::iterator &MBBI,
101 unsigned DestReg, unsigned BaseReg,
102 int NumBytes, bool CanChangeCC,
103 const TargetInstrInfo &TII,
104 const ThumbRegisterInfo& MRI,
105 DebugLoc dl) {
106 bool isHigh = !MRI.isLowRegister(DestReg) ||
107 (BaseReg != 0 && !MRI.isLowRegister(BaseReg));
108 bool isSub = false;
109 // Subtract doesn't have high register version. Load the negative value
110 // if either base or dest register is a high register. Also, if do not
111 // issue sub as part of the sequence if condition register is to be
112 // preserved.
113 if (NumBytes < 0 && !isHigh && CanChangeCC) {
114 isSub = true;
115 NumBytes = -NumBytes;
116 }
117 unsigned LdReg = DestReg;
118 if (DestReg == ARM::SP) {
119 assert(BaseReg == ARM::SP && "Unexpected!");
120 LdReg = ARM::R3;
121 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
122 .addReg(ARM::R3, RegState::Kill);
123 }
124
125 if (NumBytes <= 255 && NumBytes >= 0)
126 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
127 else if (NumBytes < 0 && NumBytes >= -255) {
128 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
129 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
130 .addReg(LdReg, RegState::Kill);
131 } else
132 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII, dl);
133
134 // Emit add / sub.
135 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
136 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
137 TII.get(Opc), DestReg);
138 if (DestReg == ARM::SP || isSub)
139 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
140 else
141 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
142 if (DestReg == ARM::SP)
143 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
144 .addReg(ARM::R12, RegState::Kill);
145 }
146
147 /// calcNumMI - Returns the number of instructions required to materialize
148 /// the specific add / sub r, c instruction.
149 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
150 unsigned NumBits, unsigned Scale) {
151 unsigned NumMIs = 0;
152 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
153
154 if (Opc == ARM::tADDrSPi) {
155 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
156 Bytes -= ThisVal;
157 NumMIs++;
158 NumBits = 8;
159 Scale = 1; // Followed by a number of tADDi8.
160 Chunk = ((1 << NumBits) - 1) * Scale;
161 }
162
163 NumMIs += Bytes / Chunk;
164 if ((Bytes % Chunk) != 0)
165 NumMIs++;
166 if (ExtraOpc)
167 NumMIs++;
168 return NumMIs;
169 }
170
171 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
172 /// a destreg = basereg + immediate in Thumb code.
173 static
174 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
175 MachineBasicBlock::iterator &MBBI,
176 unsigned DestReg, unsigned BaseReg,
177 int NumBytes, const TargetInstrInfo &TII,
178 const ThumbRegisterInfo& MRI,
179 DebugLoc dl) {
180 bool isSub = NumBytes < 0;
181 unsigned Bytes = (unsigned)NumBytes;
182 if (isSub) Bytes = -NumBytes;
183 bool isMul4 = (Bytes & 3) == 0;
184 bool isTwoAddr = false;
185 bool DstNotEqBase = false;
186 unsigned NumBits = 1;
187 unsigned Scale = 1;
188 int Opc = 0;
189 int ExtraOpc = 0;
190
191 if (DestReg == BaseReg && BaseReg == ARM::SP) {
192 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
193 NumBits = 7;
194 Scale = 4;
195 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
196 isTwoAddr = true;
197 } else if (!isSub && BaseReg == ARM::SP) {
198 // r1 = add sp, 403
199 // =>
200 // r1 = add sp, 100 * 4
201 // r1 = add r1, 3
202 if (!isMul4) {
203 Bytes &= ~3;
204 ExtraOpc = ARM::tADDi3;
205 }
206 NumBits = 8;
207 Scale = 4;
208 Opc = ARM::tADDrSPi;
209 } else {
210 // sp = sub sp, c
211 // r1 = sub sp, c
212 // r8 = sub sp, c
213 if (DestReg != BaseReg)
214 DstNotEqBase = true;
215 NumBits = 8;
216 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
217 isTwoAddr = true;
218 }
219
220 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
221 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
222 if (NumMIs > Threshold) {
223 // This will expand into too many instructions. Load the immediate from a
224 // constpool entry.
225 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
226 MRI, dl);
227 return;
228 }
229
230 if (DstNotEqBase) {
231 if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) {
232 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
233 unsigned Chunk = (1 << 3) - 1;
234 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
235 Bytes -= ThisVal;
236 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
237 .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
238 } else {
239 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
240 .addReg(BaseReg, RegState::Kill);
241 }
242 BaseReg = DestReg;
243 }
244
245 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
246 while (Bytes) {
247 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
248 Bytes -= ThisVal;
249 ThisVal /= Scale;
250 // Build the new tADD / tSUB.
251 if (isTwoAddr)
252 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
253 .addReg(DestReg).addImm(ThisVal);
254 else {
255 bool isKill = BaseReg != ARM::SP;
256 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
257 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
258 BaseReg = DestReg;
259
260 if (Opc == ARM::tADDrSPi) {
261 // r4 = add sp, imm
262 // r4 = add r4, imm
263 // ...
264 NumBits = 8;
265 Scale = 1;
266 Chunk = ((1 << NumBits) - 1) * Scale;
267 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
268 isTwoAddr = true;
269 }
270 }
271 }
272
273 if (ExtraOpc)
274 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
275 .addReg(DestReg, RegState::Kill)
276 .addImm(((unsigned)NumBytes) & 3);
277 }
278
279 void ThumbRegisterInfo::
280 emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
281 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
282 const TargetInstrInfo &TII, DebugLoc dl) const {
283 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
284 *this, dl);
285 }
286
287 void ThumbRegisterInfo::
288 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
289 MachineBasicBlock::iterator I) const {
290 if (!hasReservedCallFrame(MF)) {
291 // If we have alloca, convert as follows:
292 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
293 // ADJCALLSTACKUP -> add, sp, sp, amount
294 MachineInstr *Old = I;
295 DebugLoc dl = Old->getDebugLoc();
296 unsigned Amount = Old->getOperand(0).getImm();
297 if (Amount != 0) {
298 // We need to keep the stack aligned properly. To do this, we round the
299 // amount of space needed for the outgoing arguments up to the next
300 // alignment boundary.
301 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
302 Amount = (Amount+Align-1)/Align*Align;
303
304 // Replace the pseudo instruction with a new instruction...
305 unsigned Opc = Old->getOpcode();
306 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
307 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
308 emitSPUpdate(MBB, I, -Amount, ARMCC::AL, 0, TII, dl);
309 } else {
310 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
311 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
312 emitSPUpdate(MBB, I, Amount, ARMCC::AL, 0, TII, dl);
313 }
314 }
315 }
316 MBB.erase(I);
317 }
318
319 /// emitThumbConstant - Emit a series of instructions to materialize a
320 /// constant.
321 static void emitThumbConstant(MachineBasicBlock &MBB,
322 MachineBasicBlock::iterator &MBBI,
323 unsigned DestReg, int Imm,
324 const TargetInstrInfo &TII,
325 const ThumbRegisterInfo& MRI,
326 DebugLoc dl) {
327 bool isSub = Imm < 0;
328 if (isSub) Imm = -Imm;
329
330 int Chunk = (1 << 8) - 1;
331 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
332 Imm -= ThisVal;
333 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
334 if (Imm > 0)
335 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
336 if (isSub)
337 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
338 .addReg(DestReg, RegState::Kill);
339 }
340
341 void ThumbRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
342 int SPAdj, RegScavenger *RS) const{
343 unsigned i = 0;
344 MachineInstr &MI = *II;
345 MachineBasicBlock &MBB = *MI.getParent();
346 MachineFunction &MF = *MBB.getParent();
347 ARMFunctionInfo *AFI = MF.getInfo();
348 DebugLoc dl = MI.getDebugLoc();
349
350 while (!MI.getOperand(i).isFI()) {
351 ++i;
352 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
353 }
354
355 unsigned FrameReg = ARM::SP;
356 int FrameIndex = MI.getOperand(i).getIndex();
357 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
358 MF.getFrameInfo()->getStackSize() + SPAdj;
359
360 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
361 Offset -= AFI->getGPRCalleeSavedArea1Offset();
362 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
363 Offset -= AFI->getGPRCalleeSavedArea2Offset();
364 else if (hasFP(MF)) {
365 assert(SPAdj == 0 && "Unexpected");
366 // There is alloca()'s in this function, must reference off the frame
367 // pointer instead.
368 FrameReg = getFrameRegister(MF);
369 Offset -= AFI->getFramePtrSpillOffset();
370 }
371
372 unsigned Opcode = MI.getOpcode();
373 const TargetInstrDesc &Desc = MI.getDesc();
374 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
375
376 if (Opcode == ARM::tADDrSPi) {
377 Offset += MI.getOperand(i+1).getImm();
378
379 // Can't use tADDrSPi if it's based off the frame pointer.
380 unsigned NumBits = 0;
381 unsigned Scale = 1;
382 if (FrameReg != ARM::SP) {
383 Opcode = ARM::tADDi3;
384 MI.setDesc(TII.get(ARM::tADDi3));
385 NumBits = 3;
386 } else {
387 NumBits = 8;
388 Scale = 4;
389 assert((Offset & 3) == 0 &&
390 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
391 }
392
393 if (Offset == 0) {
394 // Turn it into a move.
395 MI.setDesc(TII.get(ARM::tMOVhir2lor));
396 MI.getOperand(i).ChangeToRegister(FrameReg, false);
397 MI.RemoveOperand(i+1);
398 return;
399 }
400
401 // Common case: small offset, fits into instruction.
402 unsigned Mask = (1 << NumBits) - 1;
403 if (((Offset / Scale) & ~Mask) == 0) {
404 // Replace the FrameIndex with sp / fp
405 MI.getOperand(i).ChangeToRegister(FrameReg, false);
406 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
407 return;
408 }
409
410 unsigned DestReg = MI.getOperand(0).getReg();
411 unsigned Bytes = (Offset > 0) ? Offset : -Offset;
412 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
413 // MI would expand into a large number of instructions. Don't try to
414 // simplify the immediate.
415 if (NumMIs > 2) {
416 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
417 *this, dl);
418 MBB.erase(II);
419 return;
420 }
421
422 if (Offset > 0) {
423 // Translate r0 = add sp, imm to
424 // r0 = add sp, 255*4
425 // r0 = add r0, (imm - 255*4)
426 MI.getOperand(i).ChangeToRegister(FrameReg, false);
427 MI.getOperand(i+1).ChangeToImmediate(Mask);
428 Offset = (Offset - Mask * Scale);
429 MachineBasicBlock::iterator NII = next(II);
430 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
431 *this, dl);
432 } else {
433 // Translate r0 = add sp, -imm to
434 // r0 = -imm (this is then translated into a series of instructons)
435 // r0 = add r0, sp
436 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
437 MI.setDesc(TII.get(ARM::tADDhirr));
438 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
439 MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
440 }
441 return;
442 } else {
443 unsigned ImmIdx = 0;
444 int InstrOffs = 0;
445 unsigned NumBits = 0;
446 unsigned Scale = 1;
447 switch (AddrMode) {
448 case ARMII::AddrModeTs: {
449 ImmIdx = i+1;
450 InstrOffs = MI.getOperand(ImmIdx).getImm();
451 NumBits = (FrameReg == ARM::SP) ? 8 : 5;
452 Scale = 4;
453 break;
454 }
455 default:
456 assert(0 && "Unsupported addressing mode!");
457 abort();
458 break;
459 }
460
461 Offset += InstrOffs * Scale;
462 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
463
464 // Common case: small offset, fits into instruction.
465 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
466 int ImmedOffset = Offset / Scale;
467 unsigned Mask = (1 << NumBits) - 1;
468 if ((unsigned)Offset <= Mask * Scale) {
469 // Replace the FrameIndex with sp
470 MI.getOperand(i).ChangeToRegister(FrameReg, false);
471 ImmOp.ChangeToImmediate(ImmedOffset);
472 return;
473 }
474
475 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
476 if (AddrMode == ARMII::AddrModeTs) {
477 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
478 // a different base register.
479 NumBits = 5;
480 Mask = (1 << NumBits) - 1;
481 }
482 // If this is a thumb spill / restore, we will be using a constpool load to
483 // materialize the offset.
484 if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore)
485 ImmOp.ChangeToImmediate(0);
486 else {
487 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
488 ImmedOffset = ImmedOffset & Mask;
489 ImmOp.ChangeToImmediate(ImmedOffset);
490 Offset &= ~(Mask*Scale);
491 }
492 }
493
494 // If we get here, the immediate doesn't fit into the instruction. We folded
495 // as much as possible above, handle the rest, providing a register that is
496 // SP+LargeImm.
497 assert(Offset && "This code isn't needed if offset already handled!");
498
499 if (Desc.mayLoad()) {
500 // Use the destination register to materialize sp + offset.
501 unsigned TmpReg = MI.getOperand(0).getReg();
502 bool UseRR = false;
503 if (Opcode == ARM::tRestore) {
504 if (FrameReg == ARM::SP)
505 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
506 Offset, false, TII, *this, dl);
507 else {
508 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, dl);
509 UseRR = true;
510 }
511 } else
512 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
513 *this, dl);
514 MI.setDesc(TII.get(ARM::tLDR));
515 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
516 if (UseRR)
517 // Use [reg, reg] addrmode.
518 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
519 else // tLDR has an extra register operand.
520 MI.addOperand(MachineOperand::CreateReg(0, false));
521 } else if (Desc.mayStore()) {
522 // FIXME! This is horrific!!! We need register scavenging.
523 // Our temporary workaround has marked r3 unavailable. Of course, r3 is
524 // also a ABI register so it's possible that is is the register that is
525 // being storing here. If that's the case, we do the following:
526 // r12 = r2
527 // Use r2 to materialize sp + offset
528 // str r3, r2
529 // r2 = r12
530 unsigned ValReg = MI.getOperand(0).getReg();
531 unsigned TmpReg = ARM::R3;
532 bool UseRR = false;
533 if (ValReg == ARM::R3) {
534 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
535 .addReg(ARM::R2, RegState::Kill);
536 TmpReg = ARM::R2;
537 }
538 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
539 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
540 .addReg(ARM::R3, RegState::Kill);
541 if (Opcode == ARM::tSpill) {
542 if (FrameReg == ARM::SP)
543 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
544 Offset, false, TII, *this, dl);
545 else {
546 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, dl);
547 UseRR = true;
548 }
549 } else
550 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
551 *this, dl);
552 MI.setDesc(TII.get(ARM::tSTR));
553 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
554 if (UseRR) // Use [reg, reg] addrmode.
555 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
556 else // tSTR has an extra register operand.
557 MI.addOperand(MachineOperand::CreateReg(0, false));
558
559 MachineBasicBlock::iterator NII = next(II);
560 if (ValReg == ARM::R3)
561 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
562 .addReg(ARM::R12, RegState::Kill);
563 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
564 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
565 .addReg(ARM::R12, RegState::Kill);
566 } else
567 assert(false && "Unexpected opcode!");
568 }
569
570 void ThumbRegisterInfo::emitPrologue(MachineFunction &MF) const {
571 MachineBasicBlock &MBB = MF.front();
572 MachineBasicBlock::iterator MBBI = MBB.begin();
573 MachineFrameInfo *MFI = MF.getFrameInfo();
574 ARMFunctionInfo *AFI = MF.getInfo();
575 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
576 unsigned NumBytes = MFI->getStackSize();
577 const std::vector &CSI = MFI->getCalleeSavedInfo();
578 DebugLoc dl = (MBBI != MBB.end() ?
579 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
580
581 // Check if R3 is live in. It might have to be used as a scratch register.
582 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(),
583 E = MF.getRegInfo().livein_end(); I != E; ++I) {
584 if (I->first == ARM::R3) {
585 AFI->setR3IsLiveIn(true);
586 break;
587 }
588 }
589
590 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
591 NumBytes = (NumBytes + 3) & ~3;
592 MFI->setStackSize(NumBytes);
593
594 // Determine the sizes of each callee-save spill areas and record which frame
595 // belongs to which callee-save spill areas.
596 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
597 int FramePtrSpillFI = 0;
598
599 if (VARegSaveSize)
600 emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, TII, dl);
601
602 if (!AFI->hasStackFrame()) {
603 if (NumBytes != 0)
604 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
605 return;
606 }
607
608 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
609 unsigned Reg = CSI[i].getReg();
610 int FI = CSI[i].getFrameIdx();
611 switch (Reg) {
612 case ARM::R4:
613 case ARM::R5:
614 case ARM::R6:
615 case ARM::R7:
616 case ARM::LR:
617 if (Reg == FramePtr)
618 FramePtrSpillFI = FI;
619 AFI->addGPRCalleeSavedArea1Frame(FI);
620 GPRCS1Size += 4;
621 break;
622 case ARM::R8:
623 case ARM::R9:
624 case ARM::R10:
625 case ARM::R11:
626 if (Reg == FramePtr)
627 FramePtrSpillFI = FI;
628 if (STI.isTargetDarwin()) {
629 AFI->addGPRCalleeSavedArea2Frame(FI);
630 GPRCS2Size += 4;
631 } else {
632 AFI->addGPRCalleeSavedArea1Frame(FI);
633 GPRCS1Size += 4;
634 }
635 break;
636 default:
637 AFI->addDPRCalleeSavedAreaFrame(FI);
638 DPRCSSize += 8;
639 }
640 }
641
642 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
643 ++MBBI;
644 if (MBBI != MBB.end())
645 dl = MBBI->getDebugLoc();
646 }
647
648 // Darwin ABI requires FP to point to the stack slot that contains the
649 // previous FP.
650 if (STI.isTargetDarwin() || hasFP(MF)) {
651 MachineInstrBuilder MIB =
652 BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
653 .addFrameIndex(FramePtrSpillFI).addImm(0);
654 }
655
656 // Determine starting offsets of spill areas.
657 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
658 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
659 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
660 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
661 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
662 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
663 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
664
665 NumBytes = DPRCSOffset;
666 if (NumBytes) {
667 // Insert it after all the callee-save spills.
668 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
669 }
670
671 if (STI.isTargetELF() && hasFP(MF)) {
672 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
673 AFI->getFramePtrSpillOffset());
674 }
675
676 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
677 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
678 AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
679 }
680
681 static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
682 for (unsigned i = 0; CSRegs[i]; ++i)
683 if (Reg == CSRegs[i])
684 return true;
685 return false;
686 }
687
688 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
689 return (MI->getOpcode() == ARM::tRestore &&
690 MI->getOperand(1).isFI() &&
691 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
692 }
693
694 void ThumbRegisterInfo::emitEpilogue(MachineFunction &MF,
695 MachineBasicBlock &MBB) const {
696 MachineBasicBlock::iterator MBBI = prior(MBB.end());
697 assert((MBBI->getOpcode() == ARM::tBX_RET ||
698 MBBI->getOpcode() == ARM::tPOP_RET) &&
699 "Can only insert epilog into returning blocks");
700 DebugLoc dl = MBBI->getDebugLoc();
701 MachineFrameInfo *MFI = MF.getFrameInfo();
702 ARMFunctionInfo *AFI = MF.getInfo();
703 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
704 int NumBytes = (int)MFI->getStackSize();
705
706 if (!AFI->hasStackFrame()) {
707 if (NumBytes != 0)
708 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
709 } else {
710 // Unwind MBBI to point to first LDR / FLDD.
711 const unsigned *CSRegs = getCalleeSavedRegs();
712 if (MBBI != MBB.begin()) {
713 do
714 --MBBI;
715 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
716 if (!isCSRestore(MBBI, CSRegs))
717 ++MBBI;
718 }
719
720 // Move SP to start of FP callee save spill area.
721 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
722 AFI->getGPRCalleeSavedArea2Size() +
723 AFI->getDPRCalleeSavedAreaSize());
724
725 if (hasFP(MF)) {
726 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
727 // Reset SP based on frame pointer only if the stack frame extends beyond
728 // frame pointer stack slot or target is ELF and the function has FP.
729 if (NumBytes)
730 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
731 TII, *this, dl);
732 else
733 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
734 .addReg(FramePtr);
735 } else {
736 if (MBBI->getOpcode() == ARM::tBX_RET &&
737 &MBB.front() != MBBI &&
738 prior(MBBI)->getOpcode() == ARM::tPOP) {
739 MachineBasicBlock::iterator PMBBI = prior(MBBI);
740 emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, TII, dl);
741 } else
742 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
743 }
744 }
745
746 if (VARegSaveSize) {
747 // Epilogue for vararg functions: pop LR to R3 and branch off it.
748 // FIXME: Verify this is still ok when R3 is no longer being reserved.
749 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
750
751 emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, TII, dl);
752
753 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
754 MBB.erase(MBBI);
755 }
756 }
0 //===- ThumbRegisterInfo.h - Thumb Register Information Impl ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the ARM implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef THUMBREGISTERINFO_H
14 #define THUMBREGISTERINFO_H
15
16 #include "ARM.h"
17 #include "ARMRegisterInfo.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19
20 namespace llvm {
21 class ARMSubtarget;
22 class TargetInstrInfo;
23 class Type;
24
25 struct ThumbRegisterInfo : public ARMBaseRegisterInfo {
26 public:
27 ThumbRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
28
29 /// emitLoadConstPool - Emits a load from constpool to materialize the
30 /// specified immediate.
31 void emitLoadConstPool(MachineBasicBlock &MBB,
32 MachineBasicBlock::iterator &MBBI,
33 unsigned DestReg, int Val,
34 unsigned Pred, unsigned PredReg,
35 const TargetInstrInfo *TII,
36 DebugLoc dl) const;
37
38 /// Code Generation virtual methods...
39 const TargetRegisterClass *
40 getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) const;
41
42 bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
43
44 bool requiresRegisterScavenging(const MachineFunction &MF) const;
45
46 bool hasReservedCallFrame(MachineFunction &MF) const;
47
48 void eliminateCallFramePseudoInstr(MachineFunction &MF,
49 MachineBasicBlock &MBB,
50 MachineBasicBlock::iterator I) const;
51
52 void eliminateFrameIndex(MachineBasicBlock::iterator II,
53 int SPAdj, RegScavenger *RS = NULL) const;
54
55 void emitPrologue(MachineFunction &MF) const;
56 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
57
58 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
59 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
60 const TargetInstrInfo &TII, DebugLoc dl) const;
61 };
62 }
63
64 #endif // THUMBREGISTERINFO_H