summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2009-04-07 20:34:09 +0000
committerJim Grosbach <grosbach@apple.com>2009-04-07 20:34:09 +0000
commitfde2110aa9c1aee6e739ed7641056b36c00dc92a (patch)
tree9c2ba6f862c2a4b0200c5b4bf7c2675e40a924b7 /llvm/lib/Target/ARM/ARMISelLowering.cpp
parent986991fd28ba579160538a3529d903e99131ac03 (diff)
downloadbcm5719-llvm-fde2110aa9c1aee6e739ed7641056b36c00dc92a.tar.gz
bcm5719-llvm-fde2110aa9c1aee6e739ed7641056b36c00dc92a.zip
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. llvm-svn: 68545
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp38
1 files changed, 31 insertions, 7 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 676f7d2159b..79a75863487 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -117,7 +117,10 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
}
}
- addRegisterClass(MVT::i32, ARM::GPRRegisterClass);
+ if (Subtarget->isThumb())
+ addRegisterClass(MVT::i32, ARM::tGPRRegisterClass);
+ else
+ addRegisterClass(MVT::i32, ARM::GPRRegisterClass);
if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) {
addRegisterClass(MVT::f32, ARM::SPRRegisterClass);
addRegisterClass(MVT::f64, ARM::DPRRegisterClass);
@@ -937,6 +940,7 @@ static SDValue LowerFORMAL_ARGUMENT(SDValue Op, SelectionDAG &DAG,
MVT ObjectVT = Op.getValue(ArgNo).getValueType();
SDValue Root = Op.getOperand(0);
MachineRegisterInfo &RegInfo = MF.getRegInfo();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
static const unsigned GPRArgRegs[] = {
ARM::R0, ARM::R1, ARM::R2, ARM::R3
@@ -955,17 +959,28 @@ static SDValue LowerFORMAL_ARGUMENT(SDValue Op, SelectionDAG &DAG,
SDValue ArgValue;
if (ObjGPRs == 1) {
- unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass);
+ unsigned VReg;
+ if (AFI->isThumbFunction())
+ VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass);
+ else
+ VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass);
RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg);
ArgValue = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
if (ObjectVT == MVT::f32)
ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, ArgValue);
} else if (ObjGPRs == 2) {
- unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass);
+ unsigned VReg;
+ if (AFI->isThumbFunction())
+ VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass);
+ else
+ VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass);
RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg);
ArgValue = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
- VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass);
+ if (AFI->isThumbFunction())
+ VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass);
+ else
+ VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass);
RegInfo.addLiveIn(GPRArgRegs[NumGPRs+1], VReg);
SDValue ArgValue2 = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
@@ -1029,7 +1044,11 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
SmallVector<SDValue, 4> MemOps;
for (; NumGPRs < 4; ++NumGPRs) {
- unsigned VReg = RegInfo.createVirtualRegister(&ARM::GPRRegClass);
+ unsigned VReg;
+ if (AFI->isThumbFunction())
+ VReg = RegInfo.createVirtualRegister(ARM::tGPRRegisterClass);
+ else
+ VReg = RegInfo.createVirtualRegister(ARM::GPRRegisterClass);
RegInfo.addLiveIn(GPRArgRegs[NumGPRs], VReg);
SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
@@ -1965,8 +1984,10 @@ ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
// GCC RS6000 Constraint Letters
switch (Constraint[0]) {
case 'l':
- // FIXME: in thumb mode, 'l' is only low-regs.
- // FALL THROUGH.
+ if (Subtarget->isThumb())
+ return std::make_pair(0U, ARM::tGPRRegisterClass);
+ else
+ return std::make_pair(0U, ARM::GPRRegisterClass);
case 'r':
return std::make_pair(0U, ARM::GPRRegisterClass);
case 'w':
@@ -1989,6 +2010,9 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint,
switch (Constraint[0]) { // GCC ARM Constraint Letters
default: break;
case 'l':
+ return make_vector<unsigned>(ARM::R0, ARM::R1, ARM::R2, ARM::R3,
+ ARM::R4, ARM::R5, ARM::R6, ARM::R7,
+ 0);
case 'r':
return make_vector<unsigned>(ARM::R0, ARM::R1, ARM::R2, ARM::R3,
ARM::R4, ARM::R5, ARM::R6, ARM::R7,
OpenPOWER on IntegriCloud