diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-06-12 19:25:13 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-06-12 19:25:13 +0000 |
commit | 49d6fc02efc45932e4d889fa56bbbfeefafbdc85 (patch) | |
tree | f6a905f6d34d5e778a82dc8cff7fb11a93e73934 /lib/Target | |
parent | 16803097fbefa313fdadc3adede659bd0e52cec1 (diff) | |
download | external_llvm-49d6fc02efc45932e4d889fa56bbbfeefafbdc85.zip external_llvm-49d6fc02efc45932e4d889fa56bbbfeefafbdc85.tar.gz external_llvm-49d6fc02efc45932e4d889fa56bbbfeefafbdc85.tar.bz2 |
[arm-fast-isel] Add support for -arm-long-calls.
Patch by Jush Lu <jush.msn@gmail.com>.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158368 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 98 |
1 files changed, 57 insertions, 41 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index e5d5157..a9b482a 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -190,7 +190,7 @@ class ARMFastISel : public FastISel { unsigned ARMMaterializeGV(const GlobalValue *GV, EVT VT); unsigned ARMMoveToFPReg(EVT VT, unsigned SrcReg); unsigned ARMMoveToIntReg(EVT VT, unsigned SrcReg); - unsigned ARMSelectCallOp(const GlobalValue *GV); + unsigned ARMSelectCallOp(bool UseReg); // Call handling routines. private: @@ -202,6 +202,7 @@ class ARMFastISel : public FastISel { SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC, unsigned &NumBytes); + unsigned getLibcallReg(const Twine &Name); bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, const Instruction *I, CallingConv::ID CC, unsigned &NumBytes); @@ -2108,8 +2109,17 @@ bool ARMFastISel::SelectRet(const Instruction *I) { return true; } -unsigned ARMFastISel::ARMSelectCallOp(const GlobalValue *GV) { - return isThumb2 ? ARM::tBL : ARM::BL; +unsigned ARMFastISel::ARMSelectCallOp(bool UseReg) { + if (UseReg) + return isThumb2 ? ARM::tBLXr : ARM::BLX; + else + return isThumb2 ? ARM::tBL : ARM::BL; +} + +unsigned ARMFastISel::getLibcallReg(const Twine &Name) { + GlobalValue *GV = new GlobalVariable(Type::getInt32Ty(*Context), false, + GlobalValue::ExternalLinkage, 0, Name); + return ARMMaterializeGV(GV, TLI.getValueType(GV->getType())); } // A quick function that will emit a call for a named libcall in F with the @@ -2130,9 +2140,6 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { else if (!isTypeLegal(RetTy, RetVT)) return false; - // TODO: For now if we have long calls specified we don't handle the call. - if (EnableARMLongCalls) return false; - // Can't handle non-double multi-reg retvals. if (RetVT != MVT::isVoid && RetVT != MVT::i32) { SmallVector<CCValAssign, 16> RVLocs; @@ -2176,20 +2183,32 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes)) return false; + unsigned CalleeReg = 0; + if (EnableARMLongCalls) { + CalleeReg = getLibcallReg(TLI.getLibcallName(Call)); + if (CalleeReg == 0) return false; + } + // Issue the call. - MachineInstrBuilder MIB; - unsigned CallOpc = ARMSelectCallOp(NULL); - if (isThumb2) - // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc))) - .addExternalSymbol(TLI.getLibcallName(Call)); - else + unsigned CallOpc = ARMSelectCallOp(EnableARMLongCalls); + MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, + DL, TII.get(CallOpc)); + if (isThumb2) { // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc)) - .addExternalSymbol(TLI.getLibcallName(Call))); + AddDefaultPred(MIB); + if (EnableARMLongCalls) + MIB.addReg(CalleeReg); + else + MIB.addExternalSymbol(TLI.getLibcallName(Call)); + } else { + if (EnableARMLongCalls) + MIB.addReg(CalleeReg); + else + MIB.addExternalSymbol(TLI.getLibcallName(Call)); + // Explicitly adding the predicate here. + AddDefaultPred(MIB); + } // Add implicit physical register uses to the call. for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) MIB.addReg(RegArgs[i]); @@ -2237,9 +2256,6 @@ bool ARMFastISel::SelectCall(const Instruction *I, RetVT != MVT::i8 && RetVT != MVT::i1) return false; - // TODO: For now if we have long calls specified we don't handle the call. - if (EnableARMLongCalls) return false; - // Can't handle non-double multi-reg retvals. if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 && RetVT != MVT::i16 && RetVT != MVT::i32) { @@ -2306,43 +2322,43 @@ bool ARMFastISel::SelectCall(const Instruction *I, if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes)) return false; - // Issue the call. - MachineInstrBuilder MIB; + bool UseReg = false; const GlobalValue *GV = dyn_cast<GlobalValue>(Callee); - unsigned CallOpc = ARMSelectCallOp(GV); + if (!GV || EnableARMLongCalls) UseReg = true; + unsigned CalleeReg = 0; + if (UseReg) { + if (IntrMemName) + CalleeReg = getLibcallReg(IntrMemName); + else + CalleeReg = getRegForValue(Callee); - if (!GV){ - CallOpc = isThumb2 ? ARM::tBLXr : ARM::BLX; - CalleeReg = getRegForValue(Callee); if (CalleeReg == 0) return false; } - // Explicitly adding the predicate here. + // Issue the call. + unsigned CallOpc = ARMSelectCallOp(UseReg); + MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, + DL, TII.get(CallOpc)); if(isThumb2) { // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc))); - if (!GV) + AddDefaultPred(MIB); + if (UseReg) MIB.addReg(CalleeReg); else if (!IntrMemName) MIB.addGlobalAddress(GV, 0, 0); else MIB.addExternalSymbol(IntrMemName, 0); } else { - if (!GV) - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc)) - .addReg(CalleeReg)); + if (UseReg) + MIB.addReg(CalleeReg); else if (!IntrMemName) - // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc)) - .addGlobalAddress(GV, 0, 0)); + MIB.addGlobalAddress(GV, 0, 0); else - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc)) - .addExternalSymbol(IntrMemName, 0)); + MIB.addExternalSymbol(IntrMemName, 0); + + // Explicitly adding the predicate here. + AddDefaultPred(MIB); } // Add implicit physical register uses to the call. |