1 //===- MipsInstructionSelector.cpp ------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the targeting of the InstructionSelector class for
12 /// \todo This should be generated by TableGen.
13 //===----------------------------------------------------------------------===//
15 #include "MipsRegisterBankInfo.h"
16 #include "MipsTargetMachine.h"
17 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
19 #define DEBUG_TYPE "mips-isel"
25 #define GET_GLOBALISEL_PREDICATE_BITSET
26 #include "MipsGenGlobalISel.inc"
27 #undef GET_GLOBALISEL_PREDICATE_BITSET
29 class MipsInstructionSelector : public InstructionSelector {
31 MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI,
32 const MipsRegisterBankInfo &RBI);
34 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
35 static const char *getName() { return DEBUG_TYPE; }
38 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
40 const MipsTargetMachine &TM;
41 const MipsSubtarget &STI;
42 const MipsInstrInfo &TII;
43 const MipsRegisterInfo &TRI;
44 const MipsRegisterBankInfo &RBI;
46 #define GET_GLOBALISEL_PREDICATES_DECL
47 #include "MipsGenGlobalISel.inc"
48 #undef GET_GLOBALISEL_PREDICATES_DECL
50 #define GET_GLOBALISEL_TEMPORARIES_DECL
51 #include "MipsGenGlobalISel.inc"
52 #undef GET_GLOBALISEL_TEMPORARIES_DECL
55 } // end anonymous namespace
57 #define GET_GLOBALISEL_IMPL
58 #include "MipsGenGlobalISel.inc"
59 #undef GET_GLOBALISEL_IMPL
61 MipsInstructionSelector::MipsInstructionSelector(
62 const MipsTargetMachine &TM, const MipsSubtarget &STI,
63 const MipsRegisterBankInfo &RBI)
64 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
65 TRI(*STI.getRegisterInfo()), RBI(RBI),
67 #define GET_GLOBALISEL_PREDICATES_INIT
68 #include "MipsGenGlobalISel.inc"
69 #undef GET_GLOBALISEL_PREDICATES_INIT
70 #define GET_GLOBALISEL_TEMPORARIES_INIT
71 #include "MipsGenGlobalISel.inc"
72 #undef GET_GLOBALISEL_TEMPORARIES_INIT
76 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
77 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
78 const RegisterBankInfo &RBI) {
79 unsigned DstReg = I.getOperand(0).getReg();
80 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
83 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
85 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
86 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
93 bool MipsInstructionSelector::select(MachineInstr &I,
94 CodeGenCoverage &CoverageInfo) const {
96 MachineBasicBlock &MBB = *I.getParent();
97 MachineFunction &MF = *MBB.getParent();
98 MachineRegisterInfo &MRI = MF.getRegInfo();
100 if (!isPreISelGenericOpcode(I.getOpcode())) {
102 return selectCopy(I, TII, MRI, TRI, RBI);
107 if (selectImpl(I, CoverageInfo)) {
111 MachineInstr *MI = nullptr;
112 using namespace TargetOpcode;
114 switch (I.getOpcode()) {
116 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
117 .add(I.getOperand(0))
118 .add(I.getOperand(1))
119 .add(I.getOperand(2));
122 case G_FRAME_INDEX: {
123 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
124 .add(I.getOperand(0))
125 .add(I.getOperand(1))
131 const unsigned DestReg = I.getOperand(0).getReg();
132 const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
133 const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
135 if (DestRegBank != Mips::GPRBRegBankID || OpSize != 32)
138 const unsigned NewOpc = I.getOpcode() == G_STORE ? Mips::SW : Mips::LW;
140 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
141 .add(I.getOperand(0))
142 .add(I.getOperand(1))
144 .addMemOperand(*I.memoperands_begin());
148 int Imm = I.getOperand(1).getCImm()->getValue().getLimitedValue();
149 unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
150 MachineInstr *LUi, *ORi;
152 LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
156 ORi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ORi))
157 .addDef(I.getOperand(0).getReg())
159 .addImm(Imm & 0xFFFF);
161 if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
163 if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
169 case G_GLOBAL_VALUE: {
170 if (MF.getTarget().isPositionIndependent())
173 const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
174 unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
175 MachineInstr *LUi, *ADDiu;
177 LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
179 .addGlobalAddress(GVal);
180 LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI);
182 ADDiu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
183 .addDef(I.getOperand(0).getReg())
185 .addGlobalAddress(GVal);
186 ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
188 if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
190 if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
202 return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
206 InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM,
207 MipsSubtarget &Subtarget,
208 MipsRegisterBankInfo &RBI) {
209 return new MipsInstructionSelector(TM, Subtarget, RBI);
211 } // end namespace llvm