const MachineInstr *Orig) const {
DebugLoc dl = Orig->getDebugLoc();
if (Orig->getOpcode() == ARM::MOVi2pieces) {
- RI.emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImm(),
- Orig->getOperand(2).getImm(),
- Orig->getOperand(3).getReg(), this, dl);
+ RI.emitLoadConstPool(MBB, I, this, dl,
+ DestReg,
+ Orig->getOperand(1).getImm(),
+ (ARMCC::CondCodes)Orig->getOperand(2).getImm(),
+ Orig->getOperand(3).getReg());
return;
}
/// specified immediate.
void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
+ const TargetInstrInfo *TII, DebugLoc dl,
unsigned DestReg, int Val,
- unsigned Pred, unsigned PredReg,
- const TargetInstrInfo *TII,
- DebugLoc dl) const {
+ ARMCC::CondCodes Pred,
+ unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool();
Constant *C = ConstantInt::get(Type::Int32Ty, Val);
.addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
}
-/// isLowRegister - Returns true if the register is low register r0-r7.
-///
-bool ARMBaseRegisterInfo::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;
- }
-}
-
const unsigned*
ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
static const unsigned CalleeSavedRegs[] = {
}
}
-void ARMRegisterInfo::
+static void
emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
- int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
- const TargetInstrInfo &TII, DebugLoc dl) const {
+ 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);
}
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
// Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
unsigned PredReg = Old->getOperand(2).getReg();
- emitSPUpdate(MBB, I, -Amount, Pred, PredReg, TII, dl);
+ emitSPUpdate(MBB, I, TII, dl, -Amount, Pred, PredReg);
} else {
// Note: PredReg is operand 3 for ADJCALLSTACKUP.
unsigned PredReg = Old->getOperand(3).getReg();
assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
- emitSPUpdate(MBB, I, Amount, Pred, PredReg, TII, dl);
+ emitSPUpdate(MBB, I, TII, dl, Amount, Pred, PredReg);
}
}
}
for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
unsigned Reg = UnspilledCS1GPRs[i];
// Don't spiil high register if the function is thumb
- if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) {
+ if (!AFI->isThumbFunction() ||
+ isARMLowRegister(Reg) || Reg == ARM::LR) {
MF.getRegInfo().setPhysRegUsed(Reg);
AFI->setCSRegisterIsSpilled(Reg);
if (!isReservedReg(MF, Reg))
int FramePtrSpillFI = 0;
if (VARegSaveSize)
- emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, -VARegSaveSize);
if (!AFI->hasStackFrame()) {
if (NumBytes != 0)
- emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
return;
}
}
// Build the new SUBri to adjust SP for integer callee-save spill area 1.
- emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size);
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
// Darwin ABI requires FP to point to the stack slot that contains the
}
// Build the new SUBri to adjust SP for integer callee-save spill area 2.
- emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size);
// 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, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize);
// Determine starting offsets of spill areas.
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
if (NumBytes) {
// Insert it after all the callee-save spills.
movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
- emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
}
if (STI.isTargetELF() && hasFP(MF)) {
if (!AFI->hasStackFrame()) {
if (NumBytes != 0)
- emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
} else {
// Unwind MBBI to point to first LDR / FLDD.
const unsigned *CSRegs = getCalleeSavedRegs();
.addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
}
} else if (NumBytes) {
- emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
}
// 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,
- TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize());
// 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,
- TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size());
// Move SP to SP upon entry to the function.
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
- emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0,
- TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size());
}
if (VARegSaveSize)
- emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, VARegSaveSize);
}
};
}
+/// isARMLowRegister - Returns true if the register is low register r0-r7.
+///
+static inline bool isARMLowRegister(unsigned Reg) {
+ 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;
+ }
+}
+
struct ARMBaseRegisterInfo : public ARMGenRegisterInfo {
protected:
const TargetInstrInfo &TII;
/// specified immediate.
void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
+ const TargetInstrInfo *TII, DebugLoc dl,
unsigned DestReg, int Val,
- unsigned Pred, unsigned PredReg,
- const TargetInstrInfo *TII,
- DebugLoc dl) const;
+ ARMCC::CondCodes Pred = ARMCC::AL,
+ unsigned PredReg = 0) const;
/// Code Generation virtual methods...
bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
-
- void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
- int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
- const TargetInstrInfo &TII, DebugLoc dl) const;
};
} // end namespace llvm
case ARM::tMOVhir2hir: {
if (OpNum == 0) { // move -> store
unsigned SrcReg = MI->getOperand(1).getReg();
- if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
+ if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
// tSpill cannot take a high register operand.
return false;
} else { // move -> load
unsigned DstReg = MI->getOperand(0).getReg();
- if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
+ if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
// tRestore cannot target a high register operand.
return false;
}
if (OpNum == 0) { // move -> store
unsigned SrcReg = MI->getOperand(1).getReg();
bool isKill = MI->getOperand(1).isKill();
- if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
+ if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
// tSpill cannot take a high register operand.
break;
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
.addFrameIndex(FI).addImm(0);
} else { // move -> load
unsigned DstReg = MI->getOperand(0).getReg();
- if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
+ if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
// tRestore cannot target a high register operand.
break;
bool isDead = MI->getOperand(0).isDead();
void ThumbRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
unsigned DestReg, int Val,
- unsigned Pred, unsigned PredReg,
const TargetInstrInfo *TII,
DebugLoc dl) const {
MachineFunction &MF = *MBB.getParent();
const TargetRegisterClass*
ThumbRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
- if (isLowRegister(Reg))
+ if (isARMLowRegister(Reg))
return ARM::tGPRRegisterClass;
switch (Reg) {
default:
const TargetInstrInfo &TII,
const ThumbRegisterInfo& MRI,
DebugLoc dl) {
- bool isHigh = !MRI.isLowRegister(DestReg) ||
- (BaseReg != 0 && !MRI.isLowRegister(BaseReg));
+ bool isHigh = !isARMLowRegister(DestReg) ||
+ (BaseReg != 0 && !isARMLowRegister(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
BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
.addReg(LdReg, RegState::Kill);
} else
- MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII, dl);
+ MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, &TII, dl);
// Emit add / sub.
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
}
if (DstNotEqBase) {
- if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) {
+ if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
// If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
unsigned Chunk = (1 << 3) - 1;
unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
.addImm(((unsigned)NumBytes) & 3);
}
-void ThumbRegisterInfo::
-emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
- int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
- const TargetInstrInfo &TII, DebugLoc dl) const {
+static void emitSPUpdate(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &MBBI,
+ const TargetInstrInfo &TII, DebugLoc dl,
+ const ThumbRegisterInfo &MRI,
+ int NumBytes) {
emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
- *this, dl);
+ MRI, dl);
}
void ThumbRegisterInfo::
// Replace the pseudo instruction with a new instruction...
unsigned Opc = Old->getOpcode();
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
- // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
- emitSPUpdate(MBB, I, -Amount, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
} else {
- // Note: PredReg is operand 3 for ADJCALLSTACKUP.
assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
- emitSPUpdate(MBB, I, Amount, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, I, TII, dl, *this, Amount);
}
}
}
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl);
else {
- emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, dl);
+ emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
UseRR = true;
}
} else
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl);
else {
- emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, dl);
+ emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
UseRR = true;
}
} else
int FramePtrSpillFI = 0;
if (VARegSaveSize)
- emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, *this, -VARegSaveSize);
if (!AFI->hasStackFrame()) {
if (NumBytes != 0)
- emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
return;
}
NumBytes = DPRCSOffset;
if (NumBytes) {
// Insert it after all the callee-save spills.
- emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
}
if (STI.isTargetELF() && hasFP(MF)) {
if (!AFI->hasStackFrame()) {
if (NumBytes != 0)
- emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
} else {
// Unwind MBBI to point to first LDR / FLDD.
const unsigned *CSRegs = getCalleeSavedRegs();
&MBB.front() != MBBI &&
prior(MBBI)->getOpcode() == ARM::tPOP) {
MachineBasicBlock::iterator PMBBI = prior(MBBI);
- emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, PMBBI, TII, dl, *this, NumBytes);
} else
- emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
}
}
// FIXME: Verify this is still ok when R3 is no longer being reserved.
BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
- emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, TII, dl);
+ emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
MBB.erase(MBBI);
void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
unsigned DestReg, int Val,
- unsigned Pred, unsigned PredReg,
const TargetInstrInfo *TII,
DebugLoc dl) const;
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
-
- void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
- int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
- const TargetInstrInfo &TII, DebugLoc dl) const;
};
}