diff options
author | Diana Picus <diana.picus@linaro.org> | 2018-12-05 10:35:28 +0000 |
---|---|---|
committer | Diana Picus <diana.picus@linaro.org> | 2018-12-05 10:35:28 +0000 |
commit | 8a1b4f57c9aa86603d900dbb595ca56c74d9c7b8 (patch) | |
tree | e6fd20ff42b3753d3416b3388be7c67227d540fc /llvm/lib/Target/ARM/ARMCallLowering.cpp | |
parent | 83ff22c2973738e301b6f547f73e4e807475d2a4 (diff) | |
download | bcm5719-llvm-8a1b4f57c9aa86603d900dbb595ca56c74d9c7b8.tar.gz bcm5719-llvm-8a1b4f57c9aa86603d900dbb595ca56c74d9c7b8.zip |
[ARM GlobalISel] Implement call lowering for Thumb2
The only things that are different from arm are:
* different opcodes for calls and returns
* Thumb calls take predicate operands
llvm-svn: 348347
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCallLowering.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallLowering.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp index deab039772c..8e80c32bcf8 100644 --- a/llvm/lib/Target/ARM/ARMCallLowering.cpp +++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp @@ -429,7 +429,7 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, auto &TLI = *getTLI<ARMTargetLowering>(); auto Subtarget = TLI.getSubtarget(); - if (Subtarget->isThumb()) + if (Subtarget->isThumb1Only()) return false; // Quick exit if there aren't any args @@ -500,6 +500,22 @@ struct CallReturnHandler : public IncomingValueHandler { MachineInstrBuilder MIB; }; +// FIXME: This should move to the ARMSubtarget when it supports all the opcodes. +unsigned getCallOpcode(const ARMSubtarget &STI, bool isDirect) { + if (isDirect) + return STI.isThumb() ? ARM::tBL : ARM::BL; + + if (STI.isThumb()) + return ARM::tBLXr; + + if (STI.hasV5TOps()) + return ARM::BLX; + + if (STI.hasV4TOps()) + return ARM::BX_CALL; + + return ARM::BMOVPCRX_CALL; +} } // end anonymous namespace bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, @@ -517,27 +533,34 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (STI.genLongCalls()) return false; + if (STI.isThumb1Only()) + return false; + auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN); // Create the call instruction so we can add the implicit uses of arg // registers, but don't insert it yet. bool isDirect = !Callee.isReg(); - auto CallOpcode = - isDirect ? ARM::BL - : STI.hasV5TOps() - ? ARM::BLX - : STI.hasV4TOps() ? ARM::BX_CALL : ARM::BMOVPCRX_CALL; - auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode) - .add(Callee) - .addRegMask(TRI->getCallPreservedMask(MF, CallConv)); - if (Callee.isReg()) { + auto CallOpcode = getCallOpcode(STI, isDirect); + auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode); + + bool isThumb = STI.isThumb(); + if (isThumb) + MIB.add(predOps(ARMCC::AL)); + + MIB.add(Callee); + if (!isDirect) { auto CalleeReg = Callee.getReg(); - if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg)) - MIB->getOperand(0).setReg(constrainOperandRegClass( + if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg)) { + unsigned CalleeIdx = isThumb ? 2 : 0; + MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass( MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(), - *MIB.getInstr(), MIB->getDesc(), Callee, 0)); + *MIB.getInstr(), MIB->getDesc(), Callee, CalleeIdx)); + } } + MIB.addRegMask(TRI->getCallPreservedMask(MF, CallConv)); + SmallVector<ArgInfo, 8> ArgInfos; for (auto Arg : OrigArgs) { if (!isSupportedType(DL, TLI, Arg.Ty)) |