diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2017-01-29 16:46:22 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2017-01-29 16:46:22 +0000 |
commit | 5282eed06c94581375809d32f416ed16f84d310e (patch) | |
tree | 9d696467d350272506399be843371c810dd76d24 /llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | |
parent | 14a4b8185f33c1c2f765b6718649dcbdbda51335 (diff) | |
download | bcm5719-llvm-5282eed06c94581375809d32f416ed16f84d310e.tar.gz bcm5719-llvm-5282eed06c94581375809d32f416ed16f84d310e.zip |
ARM: support `-mlong-calls` with AEABI TLS on ELF
Support lowering AEABI TLS access (__aeabi_read_tp) with long calls.
This requires adjusting the call sequence to use an indirect call to get
full addressability.
Resolves PR31769!
llvm-svn: 293433
Diffstat (limited to 'llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 06226168e93..78a9144bd32 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -1231,15 +1231,36 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, } case ARM::tTPsoft: case ARM::TPsoft: { + const bool Thumb = Opcode == ARM::tTPsoft; + MachineInstrBuilder MIB; - if (Opcode == ARM::tTPsoft) - MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tBL)) - .add(predOps(ARMCC::AL)) - .addExternalSymbol("__aeabi_read_tp", 0); - else + if (STI->genLongCalls()) { + MachineFunction *MF = MBB.getParent(); + MachineConstantPool *MCP = MF->getConstantPool(); + unsigned PCLabelID = AFI->createPICLabelUId(); + MachineConstantPoolValue *CPV = + ARMConstantPoolSymbol::Create(MF->getFunction()->getContext(), + "__aeabi_read_tp", PCLabelID, 0); + unsigned Reg = MI.getOperand(0).getReg(); + MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), + TII->get(Thumb ? ARM::tLDRpci : ARM::LDRi12), Reg) + .addConstantPoolIndex(MCP->getConstantPoolIndex(CPV, 4)); + if (!Thumb) + MIB.addImm(0); + MIB.add(predOps(ARMCC::AL)); + MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get( ARM::BL)) - .addExternalSymbol("__aeabi_read_tp", 0); + TII->get(Thumb ? ARM::tBLXr : ARM::BLX)); + if (Thumb) + MIB.add(predOps(ARMCC::AL)); + MIB.addReg(Reg, RegState::Kill); + } else { + MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), + TII->get(Thumb ? ARM::tBL : ARM::BL)); + if (Thumb) + MIB.add(predOps(ARMCC::AL)); + MIB.addExternalSymbol("__aeabi_read_tp", 0); + } MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); TransferImpOps(MI, MIB, MIB); |