diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index a24eab4..99e861e 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2115,10 +2115,18 @@ unsigned ARMFastISel::ARMSelectCallOp(const GlobalValue *GV) { // iOS needs the r9 versions of the opcodes. bool isiOS = Subtarget->isTargetIOS(); - if (isThumb2) { - return isiOS ? ARM::tBLr9 : ARM::tBL; - } else { - return isiOS ? ARM::BLr9 : ARM::BL; + if (EnableARMLongCalls) { + if (isThumb2) { + return isiOS ? ARM::tBLXr_r9 : ARM::tBLXr; + } else { + return isiOS ? ARM::BLXr9 : ARM::BLX; + } + } else { + if (isThumb2) { + return isiOS ? ARM::tBLr9 : ARM::tBL; + } else { + return isiOS ? ARM::BLr9 : ARM::BL; + } } } @@ -2244,8 +2252,16 @@ 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; + // Handle the long call. + unsigned CalleeReg = 0; + if (EnableARMLongCalls) { + if (IntrMemName != NULL) { + return false; + } + // Create a constant pool entry for the callee address + EVT CalleeVT = TLI.getValueType(GV->getType()); + CalleeReg = ARMMaterializeGV(GV, CalleeVT); + } // Set up the argument vectors. SmallVector<Value*, 8> Args; @@ -2308,24 +2324,31 @@ bool ARMFastISel::SelectCall(const Instruction *I, MachineInstrBuilder MIB; unsigned CallOpc = ARMSelectCallOp(GV); // Explicitly adding the predicate here. - if(isThumb2) { - // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc))); - if (!IntrMemName) - MIB.addGlobalAddress(GV, 0, 0); - else - MIB.addExternalSymbol(IntrMemName, 0); - } else { - if (!IntrMemName) + if (EnableARMLongCalls) { // Explicitly adding the predicate here. MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)) - .addGlobalAddress(GV, 0, 0)); - else + .addReg(CalleeReg, RegState::Kill, 0)); + } else { + if(isThumb2) { + // Explicitly adding the predicate here. MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc)) - .addExternalSymbol(IntrMemName, 0)); + TII.get(CallOpc))); + if (!IntrMemName) + MIB.addGlobalAddress(GV, 0, 0); + else + MIB.addExternalSymbol(IntrMemName, 0); + } else { + if (!IntrMemName) + // Explicitly adding the predicate here. + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc)) + .addGlobalAddress(GV, 0, 0)); + else + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc)) + .addExternalSymbol(IntrMemName, 0)); + } } // Add implicit physical register uses to the call. |