diff options
author | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-05-31 08:27:06 +0000 |
---|---|---|
committer | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-05-31 08:27:06 +0000 |
commit | efcd3c000991ba9e98428810b7dffecbd8848f57 (patch) | |
tree | a3bbeb07ec54ef18e7e119030f553d776a63cf82 /llvm/lib/Target/Mips/MipsInstructionSelector.cpp | |
parent | d1d915b8da91e3e527706c838e2cb4b338336e7a (diff) | |
download | bcm5719-llvm-efcd3c000991ba9e98428810b7dffecbd8848f57.tar.gz bcm5719-llvm-efcd3c000991ba9e98428810b7dffecbd8848f57.zip |
[MIPS GlobalISel] Handle position independent code
Handle position independent code for MIPS32.
When callee is global address, lower call will emit callee
as G_GLOBAL_VALUE and add target flag if needed.
Support $gp in getRegBankFromRegClass().
Select G_GLOBAL_VALUE, specially handle case when
there are target flags attached by lowerCall.
Differential Revision: https://reviews.llvm.org/D62589
llvm-svn: 362210
Diffstat (limited to 'llvm/lib/Target/Mips/MipsInstructionSelector.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstructionSelector.cpp | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp index a03e7ef57b7..442244af609 100644 --- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp +++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp @@ -11,6 +11,7 @@ /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// +#include "MipsMachineFunction.h" #include "MipsRegisterBankInfo.h" #include "MipsTargetMachine.h" #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" @@ -356,29 +357,59 @@ bool MipsInstructionSelector::select(MachineInstr &I, return true; } case G_GLOBAL_VALUE: { - if (MF.getTarget().isPositionIndependent()) - return false; - const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal(); - unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); - MachineInstr *LUi, *ADDiu; + if (MF.getTarget().isPositionIndependent()) { + MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) + .addDef(I.getOperand(0).getReg()) + .addReg(MF.getInfo<MipsFunctionInfo>() + ->getGlobalBaseRegForGlobalISel()) + .addGlobalAddress(GVal); + // Global Values that don't have local linkage are handled differently + // when they are part of call sequence. MipsCallLowering::lowerCall + // creates G_GLOBAL_VALUE instruction as part of call sequence and adds + // MO_GOT_CALL flag when Callee doesn't have local linkage. + if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL) + LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL); + else + LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT); + LWGOT->addMemOperand( + MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF), + MachineMemOperand::MOLoad, 4, 4)); + if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI)) + return false; - LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) - .addDef(LUiReg) - .addGlobalAddress(GVal); - LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI); + if (GVal->hasLocalLinkage()) { + unsigned LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass); + LWGOT->getOperand(0).setReg(LWGOTDef); - ADDiu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) + MachineInstr *ADDiu = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) .addDef(I.getOperand(0).getReg()) - .addUse(LUiReg) + .addReg(LWGOTDef) .addGlobalAddress(GVal); - ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); - - if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI)) - return false; - if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) - return false; + ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); + if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) + return false; + } + } else { + unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); + + MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) + .addDef(LUiReg) + .addGlobalAddress(GVal); + LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI); + if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI)) + return false; + MachineInstr *ADDiu = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) + .addDef(I.getOperand(0).getReg()) + .addUse(LUiReg) + .addGlobalAddress(GVal); + ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); + if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) + return false; + } I.eraseFromParent(); return true; } |