#include "Thumb1RegisterInfo.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/LLVMContext.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
: ARMBaseRegisterInfo(tii, sti) {
}
-static inline
-const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
- return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
-}
-
-static inline
-const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
- return MIB.addReg(ARM::CPSR);
-}
-
/// emitLoadConstPool - Emits a load from constpool to materialize the
/// specified immediate.
void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
- unsigned DestReg, int Val,
+ unsigned DestReg, unsigned SubIdx,
+ int Val,
ARMCC::CondCodes Pred,
unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool();
- Constant *C = ConstantInt::get(Type::Int32Ty, Val);
+ Constant *C = ConstantInt::get(
+ Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
- BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp), DestReg)
- .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp))
+ .addReg(DestReg, getDefRegState(true), SubIdx)
+ .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
}
const TargetRegisterClass*
-Thumb1RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
+Thumb1RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, EVT VT) const {
if (isARMLowRegister(Reg))
return ARM::tGPRRegisterClass;
switch (Reg) {
if (DestReg == ARM::SP) {
assert(BaseReg == ARM::SP && "Unexpected!");
LdReg = ARM::R3;
- BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
.addReg(ARM::R3, RegState::Kill);
}
if (NumBytes <= 255 && NumBytes >= 0)
- AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
+ AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
.addImm(NumBytes);
else if (NumBytes < 0 && NumBytes >= -255) {
- AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
+ AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
.addImm(NumBytes);
- AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
+ AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
.addReg(LdReg, RegState::Kill);
} else
- MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, NumBytes);
+ MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes);
// Emit add / sub.
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
if (Opc != ARM::tADDhirr)
- MIB = AddDefaultCC(MIB);
+ MIB = AddDefaultT1CC(MIB);
if (DestReg == ARM::SP || isSub)
MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
else
AddDefaultPred(MIB);
if (DestReg == ARM::SP)
- BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R3)
.addReg(ARM::R12, RegState::Kill);
}
if (DestReg != BaseReg)
DstNotEqBase = true;
NumBits = 8;
- Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
- NeedPred = NeedCC = true;
+ if (DestReg == ARM::SP) {
+ Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
+ assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
+ NumBits = 7;
+ Scale = 4;
+ } else {
+ Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
+ NumBits = 8;
+ NeedPred = NeedCC = true;
+ }
isTwoAddr = true;
}
Bytes -= ThisVal;
const TargetInstrDesc &TID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
const MachineInstrBuilder MIB =
- AddDefaultCC(BuildMI(MBB, MBBI, dl, TID, DestReg));
+ AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg));
AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
} else {
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
if (isTwoAddr) {
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
if (NeedCC)
- MIB = AddDefaultCC(MIB);
+ MIB = AddDefaultT1CC(MIB);
MIB .addReg(DestReg).addImm(ThisVal);
if (NeedPred)
MIB = AddDefaultPred(MIB);
bool isKill = BaseReg != ARM::SP;
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
if (NeedCC)
- MIB = AddDefaultCC(MIB);
+ MIB = AddDefaultT1CC(MIB);
MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
if (NeedPred)
MIB = AddDefaultPred(MIB);
if (ExtraOpc) {
const TargetInstrDesc &TID = TII.get(ExtraOpc);
- AddDefaultPred(AddDefaultCC(BuildMI(MBB, MBBI, dl, TID, DestReg))
+ AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
.addReg(DestReg, RegState::Kill)
.addImm(((unsigned)NumBytes) & 3));
}
int Chunk = (1 << 8) - 1;
int ThisVal = (Imm > Chunk) ? Chunk : Imm;
Imm -= ThisVal;
- AddDefaultPred(AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8),
- DestReg))
+ AddDefaultPred(AddDefaultT1CC(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) {
const TargetInstrDesc &TID = TII.get(ARM::tRSB);
- AddDefaultPred(AddDefaultCC(BuildMI(MBB, MBBI, dl, TID, DestReg))
+ AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
.addReg(DestReg, RegState::Kill));
}
}
MI.RemoveOperand(Op);
}
+int Thumb1RegisterInfo::
+rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
+ unsigned FrameReg, int Offset,
+ unsigned MOVOpc, unsigned ADDriOpc, unsigned SUBriOpc) const
+{
+ // if/when eliminateFrameIndex() conforms with ARMBaseRegisterInfo
+ // version then can pull out Thumb1 specific parts here
+ return 0;
+}
+
void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS) const{
unsigned i = 0;
if (Offset == 0) {
// Turn it into a move.
- MI.setDesc(TII.get(ARM::tMOVhir2lor));
+ MI.setDesc(TII.get(ARM::tMOVgpr2tgpr));
MI.getOperand(i).ChangeToRegister(FrameReg, false);
MI.RemoveOperand(i+1);
return;
if (Opcode == ARM::tADDi3) {
removeOperands(MI, i);
MachineInstrBuilder MIB(&MI);
- AddDefaultPred(AddDefaultCC(MIB).addReg(FrameReg).addImm(Offset/Scale));
+ AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
+ .addImm(Offset / Scale));
} else {
MI.getOperand(i).ChangeToRegister(FrameReg, false);
MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
if (Opcode == ARM::tADDi3) {
removeOperands(MI, i);
MachineInstrBuilder MIB(&MI);
- AddDefaultPred(AddDefaultCC(MIB).addReg(FrameReg).addImm(Mask));
+ AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask));
} else {
MI.getOperand(i).ChangeToRegister(FrameReg, false);
MI.getOperand(i+1).ChangeToImmediate(Mask);
// 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);
+ if (Opcode == ARM::tADDi3) {
+ MachineInstrBuilder MIB(&MI);
+ AddDefaultPred(MIB);
+ }
}
return;
} else {
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl);
else {
- emitLoadConstPool(MBB, II, dl, TmpReg, Offset);
+ emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true;
}
} else {
unsigned TmpReg = ARM::R3;
bool UseRR = false;
if (ValReg == ARM::R3) {
- BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
+ BuildMI(MBB, II, dl, TII.get(ARM::tMOVtgpr2gpr), 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)
+ BuildMI(MBB, II, dl, TII.get(ARM::tMOVtgpr2gpr), 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, dl, TmpReg, Offset);
+ emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true;
}
} else
MachineBasicBlock::iterator NII = next(II);
if (ValReg == ARM::R3)
- BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
+ BuildMI(MBB, NII, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R2)
.addReg(ARM::R12, RegState::Kill);
if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
- BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
+ BuildMI(MBB, NII, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R3)
.addReg(ARM::R12, RegState::Kill);
} else
assert(false && "Unexpected opcode!");
emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
TII, *this, dl);
else
- BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
.addReg(FramePtr);
} else {
if (MBBI->getOpcode() == ARM::tBX_RET &&
if (VARegSaveSize) {
// 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);
+ AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))).addReg(ARM::R3);
emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);