diff options
author | Jim Grosbach <grosbach@apple.com> | 2009-04-07 20:34:09 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2009-04-07 20:34:09 +0000 |
commit | fde2110aa9c1aee6e739ed7641056b36c00dc92a (patch) | |
tree | 9c2ba6f862c2a4b0200c5b4bf7c2675e40a924b7 /llvm/lib/Target/ARM/ARMISelLowering.cpp | |
parent | 986991fd28ba579160538a3529d903e99131ac03 (diff) | |
download | bcm5719-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.cpp | 38 |
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, |