PR2985 / <rdar://problem/6584986>

When compiling in Thumb mode, only the low (R0-R7) registers are available
for most instructions. Breaking the low registers into a new register class
handles this. Uses of R12, SP, etc, are handled explicitly where needed
with copies inserted to move results into low registers where the rest of
the code generator can deal with them.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68545 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach
2009-04-07 20:34:09 +00:00
parent f23e809be0
commit 30eae3c022
8 changed files with 319 additions and 195 deletions
+62 -27
View File
@@ -64,6 +64,9 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
return true;
case ARM::MOVr:
case ARM::tMOVr:
case ARM::tMOVhir2lor:
case ARM::tMOVlor2hir:
case ARM::tMOVhir2hir:
assert(MI.getDesc().getNumOperands() >= 2 &&
MI.getOperand(0).isReg() &&
MI.getOperand(1).isReg() &&
@@ -483,23 +486,43 @@ bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
DebugLoc DL = DebugLoc::getUnknownLoc();
if (I != MBB.end()) DL = I->getDebugLoc();
if (!AFI->isThumbFunction()) {
if (DestRC == ARM::GPRRegisterClass) {
AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
.addReg(SrcReg)));
return true;
}
} else {
if (DestRC == ARM::GPRRegisterClass) {
if (SrcRC == ARM::GPRRegisterClass) {
BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg(SrcReg);
return true;
} else if (SrcRC == ARM::tGPRRegisterClass) {
BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg(SrcReg);
return true;
}
} else if (DestRC == ARM::tGPRRegisterClass) {
if (SrcRC == ARM::GPRRegisterClass) {
BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg(SrcReg);
return true;
} else if (SrcRC == ARM::tGPRRegisterClass) {
BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
return true;
}
}
}
if (DestRC != SrcRC) {
// Not yet supported!
return false;
}
DebugLoc DL = DebugLoc::getUnknownLoc();
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC == ARM::GPRRegisterClass) {
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (AFI->isThumbFunction())
BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
else
AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
.addReg(SrcReg)));
} else if (DestRC == ARM::SPRRegisterClass)
if (DestRC == ARM::SPRRegisterClass)
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
.addReg(SrcReg));
else if (DestRC == ARM::DPRRegisterClass)
@@ -521,14 +544,17 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
if (RC == ARM::GPRRegisterClass) {
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (AFI->isThumbFunction())
BuildMI(MBB, I, DL, get(ARM::tSpill))
.addReg(SrcReg, false, false, isKill)
.addFrameIndex(FI).addImm(0);
else
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
.addReg(SrcReg, false, false, isKill)
.addFrameIndex(FI).addReg(0).addImm(0));
assert (!AFI->isThumbFunction());
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
.addReg(SrcReg, false, false, isKill)
.addFrameIndex(FI).addReg(0).addImm(0));
} else if (RC == ARM::tGPRRegisterClass) {
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert (AFI->isThumbFunction());
BuildMI(MBB, I, DL, get(ARM::tSpill))
.addReg(SrcReg, false, false, isKill)
.addFrameIndex(FI).addImm(0);
} else if (RC == ARM::DPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
.addReg(SrcReg, false, false, isKill)
@@ -586,12 +612,15 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
if (RC == ARM::GPRRegisterClass) {
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (AFI->isThumbFunction())
BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
.addFrameIndex(FI).addImm(0);
else
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
.addFrameIndex(FI).addReg(0).addImm(0));
assert (!AFI->isThumbFunction());
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
.addFrameIndex(FI).addReg(0).addImm(0));
} else if (RC == ARM::tGPRRegisterClass) {
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert (AFI->isThumbFunction());
BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
.addFrameIndex(FI).addImm(0);
} else if (RC == ARM::DPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
.addFrameIndex(FI).addImm(0));
@@ -715,7 +744,10 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
}
break;
}
case ARM::tMOVr: {
case ARM::tMOVr:
case ARM::tMOVlor2hir:
case ARM::tMOVhir2lor:
case ARM::tMOVhir2hir: {
if (OpNum == 0) { // move -> store
unsigned SrcReg = MI->getOperand(1).getReg();
bool isKill = MI->getOperand(1).isKill();
@@ -788,7 +820,10 @@ canFoldMemoryOperand(const MachineInstr *MI,
case ARM::MOVr:
// If it is updating CPSR, then it cannot be folded.
return MI->getOperand(4).getReg() != ARM::CPSR;
case ARM::tMOVr: {
case ARM::tMOVr:
case ARM::tMOVlor2hir:
case ARM::tMOVhir2lor:
case ARM::tMOVhir2hir: {
if (OpNum == 0) { // move -> store
unsigned SrcReg = MI->getOperand(1).getReg();
if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))