summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-05-31 08:27:06 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-05-31 08:27:06 +0000
commitefcd3c000991ba9e98428810b7dffecbd8848f57 (patch)
treea3bbeb07ec54ef18e7e119030f553d776a63cf82 /llvm/lib/Target/Mips/MipsInstructionSelector.cpp
parentd1d915b8da91e3e527706c838e2cb4b338336e7a (diff)
downloadbcm5719-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.cpp65
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;
}
OpenPOWER on IntegriCloud