diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstructionSelector.cpp | 73 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp | 6 |
3 files changed, 83 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp index 2cb2e9461ac..2ac8b0fd1da 100644 --- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp +++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp @@ -17,6 +17,7 @@ #include "MipsTargetMachine.h" #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #define DEBUG_TYPE "mips-isel" @@ -284,6 +285,60 @@ bool MipsInstructionSelector::select(MachineInstr &I, .add(I.getOperand(1)); break; } + case G_BRJT: { + unsigned EntrySize = + MF.getJumpTableInfo()->getEntrySize(MF.getDataLayout()); + assert(isPowerOf2_32(EntrySize) && + "Non-power-of-two jump-table entry size not supported."); + + Register JTIndex = MRI.createVirtualRegister(&Mips::GPR32RegClass); + MachineInstr *SLL = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SLL)) + .addDef(JTIndex) + .addUse(I.getOperand(2).getReg()) + .addImm(Log2_32(EntrySize)); + if (!constrainSelectedInstRegOperands(*SLL, TII, TRI, RBI)) + return false; + + Register DestAddress = MRI.createVirtualRegister(&Mips::GPR32RegClass); + MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu)) + .addDef(DestAddress) + .addUse(I.getOperand(0).getReg()) + .addUse(JTIndex); + if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI)) + return false; + + Register Dest = MRI.createVirtualRegister(&Mips::GPR32RegClass); + MachineInstr *LW = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) + .addDef(Dest) + .addUse(DestAddress) + .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_LO) + .addMemOperand(MF.getMachineMemOperand( + MachinePointerInfo(), MachineMemOperand::MOLoad, 4, 4)); + if (!constrainSelectedInstRegOperands(*LW, TII, TRI, RBI)) + return false; + + if (MF.getTarget().isPositionIndependent()) { + Register DestTmp = MRI.createVirtualRegister(&Mips::GPR32RegClass); + LW->getOperand(0).setReg(DestTmp); + MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu)) + .addDef(Dest) + .addUse(DestTmp) + .addUse(MF.getInfo<MipsFunctionInfo>() + ->getGlobalBaseRegForGlobalISel()); + if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI)) + return false; + } + + MachineInstr *Branch = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch)) + .addUse(Dest); + if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI)) + return false; + + I.eraseFromParent(); + return true; + } case G_PHI: { const Register DestReg = I.getOperand(0).getReg(); const unsigned OpSize = MRI.getType(DestReg).getSizeInBits(); @@ -522,6 +577,24 @@ bool MipsInstructionSelector::select(MachineInstr &I, I.eraseFromParent(); return true; } + case G_JUMP_TABLE: { + if (MF.getTarget().isPositionIndependent()) { + MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) + .addDef(I.getOperand(0).getReg()) + .addReg(MF.getInfo<MipsFunctionInfo>() + ->getGlobalBaseRegForGlobalISel()) + .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT) + .addMemOperand( + MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF), + MachineMemOperand::MOLoad, 4, 4)); + } else { + MI = + BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) + .addDef(I.getOperand(0).getReg()) + .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI); + } + break; + } case G_ICMP: { struct Instr { unsigned Opcode; diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp index a62a077eba3..ea7cc098df4 100644 --- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp +++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -63,6 +63,9 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { .legalFor({s32}) .minScalar(0, s32); + getActionDefinitionsBuilder(G_BRJT) + .legalFor({{p0, s32}}); + getActionDefinitionsBuilder(G_PHI) .legalFor({p0, s32, s64}) .minScalar(0, s32); @@ -98,7 +101,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { getActionDefinitionsBuilder(G_FRAME_INDEX) .legalFor({p0}); - getActionDefinitionsBuilder(G_GLOBAL_VALUE) + getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE}) .legalFor({p0}); // FP instructions diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp index fc514cd2b3b..e6f507e2b31 100644 --- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -576,10 +576,16 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case G_CONSTANT: case G_FRAME_INDEX: case G_GLOBAL_VALUE: + case G_JUMP_TABLE: case G_BRCOND: OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); break; + case G_BRJT: + OperandsMapping = + getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, + &Mips::ValueMappings[Mips::GPRIdx]}); + break; case G_ICMP: OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, |