Deleted Added
full compact
34,36d33
< #include "llvm/ADT/STLExtras.h"
< #include "llvm/Support/CommandLine.h"
< #include <algorithm>
39,43c36
< static cl::opt<bool> ThumbRegScavenging("enable-thumb-reg-scavenging",
< cl::Hidden,
< cl::desc("Enable register scavenging on Thumb"));
<
< unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
---
> unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
84,85c77,78
< unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum,
< bool &isSPVFP) {
---
> unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
> bool &isSPVFP) {
111,116c104,109
< case S4: case S5: case S6: case S7:
< case S8: case S9: case S10: case S11:
< case S12: case S13: case S14: case S15:
< case S16: case S17: case S18: case S19:
< case S20: case S21: case S22: case S23:
< case S24: case S25: case S26: case S27:
---
> case S4: case S5: case S6: case S7:
> case S8: case S9: case S10: case S11:
> case S12: case S13: case S14: case S15:
> case S16: case S17: case S18: case S19:
> case S20: case S21: case S22: case S23:
> case S24: case S25: case S26: case S27:
158,159c151,152
< ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
< const ARMSubtarget &sti)
---
> ARMBaseRegisterInfo::ARMBaseRegisterInfo(const TargetInstrInfo &tii,
> const ARMSubtarget &sti)
164a158,162
> ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
> const ARMSubtarget &sti)
> : ARMBaseRegisterInfo(tii, sti) {
> }
>
178a177
> const TargetInstrInfo *TII, DebugLoc dl,
180,183c179,180
< unsigned Pred, unsigned PredReg,
< const TargetInstrInfo *TII,
< bool isThumb,
< DebugLoc dl) const {
---
> ARMCC::CondCodes Pred,
> unsigned PredReg) const {
188,195d184
< if (isThumb)
< BuildMI(MBB, MBBI, dl,
< TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx);
< else
< BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg)
< .addConstantPoolIndex(Idx)
< .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
< }
197,207c186,188
< /// isLowRegister - Returns true if the register is low register r0-r7.
< ///
< bool ARMRegisterInfo::isLowRegister(unsigned Reg) const {
< using namespace ARM;
< switch (Reg) {
< case R0: case R1: case R2: case R3:
< case R4: case R5: case R6: case R7:
< return true;
< default:
< return false;
< }
---
> BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg)
> .addConstantPoolIndex(Idx)
> .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
210,225d190
< const TargetRegisterClass*
< ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
< if (STI.isThumb()) {
< if (isLowRegister(Reg))
< return ARM::tGPRRegisterClass;
< switch (Reg) {
< default:
< break;
< case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
< case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC:
< return ARM::GPRRegisterClass;
< }
< }
< return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
< }
<
227c192
< ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
---
> ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
251c216
< ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
---
> ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
300c265
< BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
---
> BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
314c279
< ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
---
> ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
332c297
< const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const {
---
> const TargetRegisterClass *ARMBaseRegisterInfo::getPointerRegClass() const {
339,341c304,306
< ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
< unsigned HintType, unsigned HintReg,
< const MachineFunction &MF) const {
---
> ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
> unsigned HintType, unsigned HintReg,
> const MachineFunction &MF) const {
482,483c447,448
< ARMRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
< const MachineFunction &MF) const {
---
> ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
> const MachineFunction &MF) const {
498,499c463,464
< ARMRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
< MachineFunction &MF) const {
---
> ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
> MachineFunction &MF) const {
519,520c484
< const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
< return ThumbRegScavenging || !AFI->isThumbFunction();
---
> return true;
527c491
< bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const {
---
> bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
542d505
< ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
547,553c510,512
< if (AFI->isThumbFunction()) {
< if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
< return false;
< } else {
< if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
< return false;
< }
---
> if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
> return false;
>
573c532
<
---
>
576c535
<
---
>
580c539
<
---
>
589,610c548,554
< /// calcNumMI - Returns the number of instructions required to materialize
< /// the specific add / sub r, c instruction.
< static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
< unsigned NumBits, unsigned Scale) {
< unsigned NumMIs = 0;
< unsigned Chunk = ((1 << NumBits) - 1) * Scale;
<
< if (Opc == ARM::tADDrSPi) {
< unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
< Bytes -= ThisVal;
< NumMIs++;
< NumBits = 8;
< Scale = 1; // Followed by a number of tADDi8.
< Chunk = ((1 << NumBits) - 1) * Scale;
< }
<
< NumMIs += Bytes / Chunk;
< if ((Bytes % Chunk) != 0)
< NumMIs++;
< if (ExtraOpc)
< NumMIs++;
< return NumMIs;
---
> static void
> emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
> const TargetInstrInfo &TII, DebugLoc dl,
> int NumBytes,
> ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
> emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
> Pred, PredReg, TII, dl);
613,788d556
< /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
< /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
< /// in a register using mov / mvn sequences or load the immediate from a
< /// constpool entry.
< static
< void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
< MachineBasicBlock::iterator &MBBI,
< unsigned DestReg, unsigned BaseReg,
< int NumBytes, bool CanChangeCC,
< const TargetInstrInfo &TII,
< const ARMRegisterInfo& MRI,
< DebugLoc dl) {
< bool isHigh = !MRI.isLowRegister(DestReg) ||
< (BaseReg != 0 && !MRI.isLowRegister(BaseReg));
< bool isSub = false;
< // Subtract doesn't have high register version. Load the negative value
< // if either base or dest register is a high register. Also, if do not
< // issue sub as part of the sequence if condition register is to be
< // preserved.
< if (NumBytes < 0 && !isHigh && CanChangeCC) {
< isSub = true;
< NumBytes = -NumBytes;
< }
< unsigned LdReg = DestReg;
< if (DestReg == ARM::SP) {
< assert(BaseReg == ARM::SP && "Unexpected!");
< LdReg = ARM::R3;
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
< .addReg(ARM::R3, RegState::Kill);
< }
<
< if (NumBytes <= 255 && NumBytes >= 0)
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
< else if (NumBytes < 0 && NumBytes >= -255) {
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
< .addReg(LdReg, RegState::Kill);
< } else
< MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII,
< true, dl);
<
< // Emit add / sub.
< int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
< const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
< TII.get(Opc), DestReg);
< if (DestReg == ARM::SP || isSub)
< MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
< else
< MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
< if (DestReg == ARM::SP)
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
< .addReg(ARM::R12, RegState::Kill);
< }
<
< /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
< /// a destreg = basereg + immediate in Thumb code.
< static
< void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
< MachineBasicBlock::iterator &MBBI,
< unsigned DestReg, unsigned BaseReg,
< int NumBytes, const TargetInstrInfo &TII,
< const ARMRegisterInfo& MRI,
< DebugLoc dl) {
< bool isSub = NumBytes < 0;
< unsigned Bytes = (unsigned)NumBytes;
< if (isSub) Bytes = -NumBytes;
< bool isMul4 = (Bytes & 3) == 0;
< bool isTwoAddr = false;
< bool DstNotEqBase = false;
< unsigned NumBits = 1;
< unsigned Scale = 1;
< int Opc = 0;
< int ExtraOpc = 0;
<
< if (DestReg == BaseReg && BaseReg == ARM::SP) {
< assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
< NumBits = 7;
< Scale = 4;
< Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
< isTwoAddr = true;
< } else if (!isSub && BaseReg == ARM::SP) {
< // r1 = add sp, 403
< // =>
< // r1 = add sp, 100 * 4
< // r1 = add r1, 3
< if (!isMul4) {
< Bytes &= ~3;
< ExtraOpc = ARM::tADDi3;
< }
< NumBits = 8;
< Scale = 4;
< Opc = ARM::tADDrSPi;
< } else {
< // sp = sub sp, c
< // r1 = sub sp, c
< // r8 = sub sp, c
< if (DestReg != BaseReg)
< DstNotEqBase = true;
< NumBits = 8;
< Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
< isTwoAddr = true;
< }
<
< unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
< unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
< if (NumMIs > Threshold) {
< // This will expand into too many instructions. Load the immediate from a
< // constpool entry.
< emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
< MRI, dl);
< return;
< }
<
< if (DstNotEqBase) {
< if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) {
< // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
< unsigned Chunk = (1 << 3) - 1;
< unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
< Bytes -= ThisVal;
< BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
< .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
< } else {
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
< .addReg(BaseReg, RegState::Kill);
< }
< BaseReg = DestReg;
< }
<
< unsigned Chunk = ((1 << NumBits) - 1) * Scale;
< while (Bytes) {
< unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
< Bytes -= ThisVal;
< ThisVal /= Scale;
< // Build the new tADD / tSUB.
< if (isTwoAddr)
< BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
< .addReg(DestReg).addImm(ThisVal);
< else {
< bool isKill = BaseReg != ARM::SP;
< BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
< .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
< BaseReg = DestReg;
<
< if (Opc == ARM::tADDrSPi) {
< // r4 = add sp, imm
< // r4 = add r4, imm
< // ...
< NumBits = 8;
< Scale = 1;
< Chunk = ((1 << NumBits) - 1) * Scale;
< Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
< isTwoAddr = true;
< }
< }
< }
<
< if (ExtraOpc)
< BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
< .addReg(DestReg, RegState::Kill)
< .addImm(((unsigned)NumBytes) & 3);
< }
<
< static
< void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
< int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
< bool isThumb, const TargetInstrInfo &TII,
< const ARMRegisterInfo& MRI,
< DebugLoc dl) {
< if (isThumb)
< emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
< MRI, dl);
< else
< emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
< Pred, PredReg, TII, dl);
< }
<
800d567
< ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
809,811c576
< bool isThumb = AFI->isThumbFunction();
< ARMCC::CondCodes Pred = isThumb
< ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm();
---
> ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm();
814,815c579,580
< unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg();
< emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this, dl);
---
> unsigned PredReg = Old->getOperand(2).getReg();
> emitSPUpdate(MBB, I, TII, dl, -Amount, Pred, PredReg);
818c583
< unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg();
---
> unsigned PredReg = Old->getOperand(3).getReg();
820c585
< emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this, dl);
---
> emitSPUpdate(MBB, I, TII, dl, Amount, Pred, PredReg);
827,848d591
< /// emitThumbConstant - Emit a series of instructions to materialize a
< /// constant.
< static void emitThumbConstant(MachineBasicBlock &MBB,
< MachineBasicBlock::iterator &MBBI,
< unsigned DestReg, int Imm,
< const TargetInstrInfo &TII,
< const ARMRegisterInfo& MRI,
< DebugLoc dl) {
< bool isSub = Imm < 0;
< if (isSub) Imm = -Imm;
<
< int Chunk = (1 << 8) - 1;
< int ThisVal = (Imm > Chunk) ? Chunk : Imm;
< Imm -= ThisVal;
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
< if (Imm > 0)
< emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
< if (isSub)
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
< .addReg(DestReg, RegState::Kill);
< }
<
871d613
< bool isThumb = AFI->isThumbFunction();
878c620
<
---
>
881c623
< int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
---
> int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
929c671
<
---
>
935c677
<
---
>
938c680
<
---
>
941c683
< assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
---
> assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
943,1008d684
< } else if (Opcode == ARM::tADDrSPi) {
< Offset += MI.getOperand(i+1).getImm();
<
< // Can't use tADDrSPi if it's based off the frame pointer.
< unsigned NumBits = 0;
< unsigned Scale = 1;
< if (FrameReg != ARM::SP) {
< Opcode = ARM::tADDi3;
< MI.setDesc(TII.get(ARM::tADDi3));
< NumBits = 3;
< } else {
< NumBits = 8;
< Scale = 4;
< assert((Offset & 3) == 0 &&
< "Thumb add/sub sp, #imm immediate must be multiple of 4!");
< }
<
< if (Offset == 0) {
< // Turn it into a move.
< MI.setDesc(TII.get(ARM::tMOVhir2lor));
< MI.getOperand(i).ChangeToRegister(FrameReg, false);
< MI.RemoveOperand(i+1);
< return;
< }
<
< // Common case: small offset, fits into instruction.
< unsigned Mask = (1 << NumBits) - 1;
< if (((Offset / Scale) & ~Mask) == 0) {
< // Replace the FrameIndex with sp / fp
< MI.getOperand(i).ChangeToRegister(FrameReg, false);
< MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
< return;
< }
<
< unsigned DestReg = MI.getOperand(0).getReg();
< unsigned Bytes = (Offset > 0) ? Offset : -Offset;
< unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
< // MI would expand into a large number of instructions. Don't try to
< // simplify the immediate.
< if (NumMIs > 2) {
< emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
< *this, dl);
< MBB.erase(II);
< return;
< }
<
< if (Offset > 0) {
< // Translate r0 = add sp, imm to
< // r0 = add sp, 255*4
< // r0 = add r0, (imm - 255*4)
< MI.getOperand(i).ChangeToRegister(FrameReg, false);
< MI.getOperand(i+1).ChangeToImmediate(Mask);
< Offset = (Offset - Mask * Scale);
< MachineBasicBlock::iterator NII = next(II);
< emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
< *this, dl);
< } else {
< // Translate r0 = add sp, -imm to
< // r0 = -imm (this is then translated into a series of instructons)
< // r0 = add r0, sp
< emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
< MI.setDesc(TII.get(ARM::tADDhirr));
< MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
< MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
< }
< return;
1040,1046d715
< case ARMII::AddrModeTs: {
< ImmIdx = i+1;
< InstrOffs = MI.getOperand(ImmIdx).getImm();
< NumBits = (FrameReg == ARM::SP) ? 8 : 5;
< Scale = 4;
< break;
< }
1055c724
< if (Offset < 0 && !isThumb) {
---
> if (Offset < 0) {
1073,1091c742,747
< bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
< if (AddrMode == ARMII::AddrModeTs) {
< // Thumb tLDRspi, tSTRspi. These will change to instructions that use
< // a different base register.
< NumBits = 5;
< Mask = (1 << NumBits) - 1;
< }
< // If this is a thumb spill / restore, we will be using a constpool load to
< // materialize the offset.
< if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore)
< ImmOp.ChangeToImmediate(0);
< else {
< // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
< ImmedOffset = ImmedOffset & Mask;
< if (isSub)
< ImmedOffset |= 1 << NumBits;
< ImmOp.ChangeToImmediate(ImmedOffset);
< Offset &= ~(Mask*Scale);
< }
---
> // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
> ImmedOffset = ImmedOffset & Mask;
> if (isSub)
> ImmedOffset |= 1 << NumBits;
> ImmOp.ChangeToImmediate(ImmedOffset);
> Offset &= ~(Mask*Scale);
1093c749
<
---
>
1099,1187c755,769
< if (isThumb) {
< if (Desc.mayLoad()) {
< // Use the destination register to materialize sp + offset.
< unsigned TmpReg = MI.getOperand(0).getReg();
< bool UseRR = false;
< if (Opcode == ARM::tRestore) {
< if (FrameReg == ARM::SP)
< emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
< Offset, false, TII, *this, dl);
< else {
< emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII,
< true, dl);
< UseRR = true;
< }
< } else
< emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
< *this, dl);
< MI.setDesc(TII.get(ARM::tLDR));
< MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
< if (UseRR)
< // Use [reg, reg] addrmode.
< MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
< else // tLDR has an extra register operand.
< MI.addOperand(MachineOperand::CreateReg(0, false));
< } else if (Desc.mayStore()) {
< // FIXME! This is horrific!!! We need register scavenging.
< // Our temporary workaround has marked r3 unavailable. Of course, r3 is
< // also a ABI register so it's possible that is is the register that is
< // being storing here. If that's the case, we do the following:
< // r12 = r2
< // Use r2 to materialize sp + offset
< // str r3, r2
< // r2 = r12
< unsigned ValReg = MI.getOperand(0).getReg();
< unsigned TmpReg = ARM::R3;
< bool UseRR = false;
< if (ValReg == ARM::R3) {
< BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
< .addReg(ARM::R2, RegState::Kill);
< TmpReg = ARM::R2;
< }
< if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
< BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
< .addReg(ARM::R3, RegState::Kill);
< if (Opcode == ARM::tSpill) {
< if (FrameReg == ARM::SP)
< emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
< Offset, false, TII, *this, dl);
< else {
< emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII,
< true, dl);
< UseRR = true;
< }
< } else
< emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
< *this, dl);
< MI.setDesc(TII.get(ARM::tSTR));
< MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
< if (UseRR) // Use [reg, reg] addrmode.
< MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
< else // tSTR has an extra register operand.
< MI.addOperand(MachineOperand::CreateReg(0, false));
<
< MachineBasicBlock::iterator NII = next(II);
< if (ValReg == ARM::R3)
< BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
< .addReg(ARM::R12, RegState::Kill);
< if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
< BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
< .addReg(ARM::R12, RegState::Kill);
< } else
< assert(false && "Unexpected opcode!");
< } else {
< // Insert a set of r12 with the full address: r12 = sp + offset
< // If the offset we have is too large to fit into the instruction, we need
< // to form it with a series of ADDri's. Do this by taking 8-bit chunks
< // out of 'Offset'.
< unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
< if (ScratchReg == 0)
< // No register is "free". Scavenge a register.
< ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
< int PIdx = MI.findFirstPredOperandIdx();
< ARMCC::CondCodes Pred = (PIdx == -1)
< ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
< unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
< emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
< isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
< MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
< }
---
> // Insert a set of r12 with the full address: r12 = sp + offset
> // If the offset we have is too large to fit into the instruction, we need
> // to form it with a series of ADDri's. Do this by taking 8-bit chunks
> // out of 'Offset'.
> unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
> if (ScratchReg == 0)
> // No register is "free". Scavenge a register.
> ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
> int PIdx = MI.findFirstPredOperandIdx();
> ARMCC::CondCodes Pred = (PIdx == -1)
> ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
> unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
> emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
> isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
> MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1209,1210c791,792
< ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
< RegScavenger *RS) const {
---
> ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
> RegScavenger *RS) const {
1269c851
< } else {
---
> } else {
1335c917,918
< if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) {
---
> if (!AFI->isThumbFunction() ||
> isARMLowRegister(Reg) || Reg == ARM::LR) {
1354c937
< // to materialize a stack offset. If so, either spill one additiona
---
> // to materialize a stack offset. If so, either spill one additional
1463d1045
< bool isThumb = AFI->isThumbFunction();
1470,1484d1051
< if (isThumb) {
< // Check if R3 is live in. It might have to be used as a scratch register.
< for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(),
< E = MF.getRegInfo().livein_end(); I != E; ++I) {
< if (I->first == ARM::R3) {
< AFI->setR3IsLiveIn(true);
< break;
< }
< }
<
< // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
< NumBytes = (NumBytes + 3) & ~3;
< MFI->setStackSize(NumBytes);
< }
<
1491,1492c1058
< emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII,
< *this, dl);
---
> emitSPUpdate(MBB, MBBI, TII, dl, -VARegSaveSize);
1496c1062
< emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
---
> emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
1534,1542c1100,1102
< if (!isThumb) {
< // Build the new SUBri to adjust SP for integer callee-save spill area 1.
< emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this, dl);
< movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
< } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
< ++MBBI;
< if (MBBI != MBB.end())
< dl = MBBI->getDebugLoc();
< }
---
> // Build the new SUBri to adjust SP for integer callee-save spill area 1.
> emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size);
> movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
1548,1549c1108
< BuildMI(MBB, MBBI, dl, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),
< FramePtr)
---
> BuildMI(MBB, MBBI, dl, TII.get(ARM::ADDri), FramePtr)
1551c1110
< if (!isThumb) AddDefaultCC(AddDefaultPred(MIB));
---
> AddDefaultCC(AddDefaultPred(MIB));
1554,1556c1113,1114
< if (!isThumb) {
< // Build the new SUBri to adjust SP for integer callee-save spill area 2.
< emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this, dl);
---
> // Build the new SUBri to adjust SP for integer callee-save spill area 2.
> emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size);
1558,1561c1116,1118
< // Build the new SUBri to adjust SP for FP callee-save spill area.
< movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
< emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this, dl);
< }
---
> // Build the new SUBri to adjust SP for FP callee-save spill area.
> movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
> emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize);
1571c1128
<
---
>
1575,1577c1132,1133
< if (!isThumb)
< movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
< emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
---
> movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
> emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
1580c1136
< if(STI.isTargetELF() && hasFP(MF)) {
---
> if (STI.isTargetELF() && hasFP(MF)) {
1599,1600c1155
< MI->getOpcode() == ARM::LDR ||
< MI->getOpcode() == ARM::tRestore) &&
---
> MI->getOpcode() == ARM::LDR) &&
1608,1610c1163
< assert((MBBI->getOpcode() == ARM::BX_RET ||
< MBBI->getOpcode() == ARM::tBX_RET ||
< MBBI->getOpcode() == ARM::tPOP_RET) &&
---
> assert(MBBI->getOpcode() == ARM::BX_RET &&
1615d1167
< bool isThumb = AFI->isThumbFunction();
1621c1173
< emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
---
> emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
1637,1641c1189,1199
< if (isThumb) {
< if (hasFP(MF)) {
< NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
< // Reset SP based on frame pointer only if the stack frame extends beyond
< // frame pointer stack slot or target is ELF and the function has FP.
---
>
> // Darwin ABI requires FP to point to the stack slot that contains the
> // previous FP.
> if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
> NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
> // Reset SP based on frame pointer only if the stack frame extends beyond
> // frame pointer stack slot or target is ELF and the function has FP.
> if (AFI->getGPRCalleeSavedArea2Size() ||
> AFI->getDPRCalleeSavedAreaSize() ||
> AFI->getDPRCalleeSavedAreaOffset()||
> hasFP(MF)) {
1643,1644c1201,1203
< emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
< TII, *this, dl);
---
> BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
> .addImm(NumBytes)
> .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1646,1657c1205,1206
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
< .addReg(FramePtr);
< } else {
< if (MBBI->getOpcode() == ARM::tBX_RET &&
< &MBB.front() != MBBI &&
< prior(MBBI)->getOpcode() == ARM::tPOP) {
< MachineBasicBlock::iterator PMBBI = prior(MBBI);
< emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII,
< *this, dl);
< } else
< emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII,
< *this, dl);
---
> BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
> .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1659,1680c1208,1210
< } else {
< // Darwin ABI requires FP to point to the stack slot that contains the
< // previous FP.
< if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
< NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
< // Reset SP based on frame pointer only if the stack frame extends beyond
< // frame pointer stack slot or target is ELF and the function has FP.
< if (AFI->getGPRCalleeSavedArea2Size() ||
< AFI->getDPRCalleeSavedAreaSize() ||
< AFI->getDPRCalleeSavedAreaOffset()||
< hasFP(MF)) {
< if (NumBytes)
< BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
< .addImm(NumBytes)
< .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
< else
< BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
< .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
< }
< } else if (NumBytes) {
< emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this, dl);
< }
---
> } else if (NumBytes) {
> emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
> }
1682,1685c1212,1214
< // Move SP to start of integer callee save spill area 2.
< movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
< emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0,
< false, TII, *this, dl);
---
> // Move SP to start of integer callee save spill area 2.
> movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
> emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize());
1687,1690c1216,1218
< // Move SP to start of integer callee save spill area 1.
< movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
< emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0,
< false, TII, *this, dl);
---
> // Move SP to start of integer callee save spill area 1.
> movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
> emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size());
1692,1696c1220,1222
< // Move SP to SP upon entry to the function.
< movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
< emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0,
< false, TII, *this, dl);
< }
---
> // Move SP to SP upon entry to the function.
> movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
> emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size());
1699,1703c1225,1226
< if (VARegSaveSize) {
< if (isThumb)
< // Epilogue for vararg functions: pop LR to R3 and branch off it.
< // FIXME: Verify this is still ok when R3 is no longer being reserved.
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
---
> if (VARegSaveSize)
> emitSPUpdate(MBB, MBBI, TII, dl, VARegSaveSize);
1705,1712d1227
< emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII,
< *this, dl);
<
< if (isThumb) {
< BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
< MBB.erase(MBBI);
< }
< }
1715c1230
< unsigned ARMRegisterInfo::getRARegister() const {
---
> unsigned ARMBaseRegisterInfo::getRARegister() const {
1719c1234
< unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
---
> unsigned ARMBaseRegisterInfo::getFrameRegister(MachineFunction &MF) const {
1725c1240
< unsigned ARMRegisterInfo::getEHExceptionRegister() const {
---
> unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
1730c1245
< unsigned ARMRegisterInfo::getEHHandlerRegister() const {
---
> unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
1735c1250
< int ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
---
> int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
1739,1740c1254,1255
< unsigned ARMRegisterInfo::getRegisterPairEven(unsigned Reg,
< const MachineFunction &MF) const {
---
> unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
> const MachineFunction &MF) const {
1813c1328
< unsigned ARMRegisterInfo::getRegisterPairOdd(unsigned Reg,
---
> unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,