1fac93e28SPetar Jovanovic //===- MipsInstructionSelector.cpp ------------------------------*- C++ -*-===//
2fac93e28SPetar Jovanovic //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fac93e28SPetar Jovanovic //
7fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===//
8fac93e28SPetar Jovanovic /// \file
9fac93e28SPetar Jovanovic /// This file implements the targeting of the InstructionSelector class for
10fac93e28SPetar Jovanovic /// Mips.
11fac93e28SPetar Jovanovic /// \todo This should be generated by TableGen.
12fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===//
13fac93e28SPetar Jovanovic
1422e99c43SPetar Avramovic #include "MCTargetDesc/MipsInstPrinter.h"
15efcd3c00SPetar Avramovic #include "MipsMachineFunction.h"
16fac93e28SPetar Jovanovic #include "MipsRegisterBankInfo.h"
17fac93e28SPetar Jovanovic #include "MipsTargetMachine.h"
18366857a2SPetar Jovanovic #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
19ce4dd0aeSPetar Jovanovic #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
20caef9306SPetar Avramovic #include "llvm/CodeGen/MachineJumpTableInfo.h"
215d986953SReid Kleckner #include "llvm/IR/IntrinsicsMips.h"
22fac93e28SPetar Jovanovic
23366857a2SPetar Jovanovic #define DEBUG_TYPE "mips-isel"
24366857a2SPetar Jovanovic
25fac93e28SPetar Jovanovic using namespace llvm;
26fac93e28SPetar Jovanovic
27fac93e28SPetar Jovanovic namespace {
28fac93e28SPetar Jovanovic
29366857a2SPetar Jovanovic #define GET_GLOBALISEL_PREDICATE_BITSET
30366857a2SPetar Jovanovic #include "MipsGenGlobalISel.inc"
31366857a2SPetar Jovanovic #undef GET_GLOBALISEL_PREDICATE_BITSET
32366857a2SPetar Jovanovic
33fac93e28SPetar Jovanovic class MipsInstructionSelector : public InstructionSelector {
34fac93e28SPetar Jovanovic public:
35fac93e28SPetar Jovanovic MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI,
36fac93e28SPetar Jovanovic const MipsRegisterBankInfo &RBI);
37fac93e28SPetar Jovanovic
38e14c91b7SAmara Emerson bool select(MachineInstr &I) override;
getName()39366857a2SPetar Jovanovic static const char *getName() { return DEBUG_TYPE; }
40fac93e28SPetar Jovanovic
41fac93e28SPetar Jovanovic private:
42366857a2SPetar Jovanovic bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
43d32a6f08SPetar Avramovic bool isRegInGprb(Register Reg, MachineRegisterInfo &MRI) const;
44d32a6f08SPetar Avramovic bool isRegInFprb(Register Reg, MachineRegisterInfo &MRI) const;
45faeaedf8SMatt Arsenault bool materialize32BitImm(Register DestReg, APInt Imm,
463e0da146SPetar Avramovic MachineIRBuilder &B) const;
47a034a64fSPetar Avramovic bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
487d0778eaSPetar Avramovic const TargetRegisterClass *
49d32a6f08SPetar Avramovic getRegClassForTypeOnBank(Register Reg, MachineRegisterInfo &MRI) const;
50599591f3SPetar Avramovic unsigned selectLoadStoreOpCode(MachineInstr &I,
51599591f3SPetar Avramovic MachineRegisterInfo &MRI) const;
525171d152SPetar Avramovic bool buildUnalignedStore(MachineInstr &I, unsigned Opc,
535171d152SPetar Avramovic MachineOperand &BaseAddr, unsigned Offset,
545171d152SPetar Avramovic MachineMemOperand *MMO) const;
555171d152SPetar Avramovic bool buildUnalignedLoad(MachineInstr &I, unsigned Opc, Register Dest,
565171d152SPetar Avramovic MachineOperand &BaseAddr, unsigned Offset,
575171d152SPetar Avramovic Register TiedDest, MachineMemOperand *MMO) const;
58366857a2SPetar Jovanovic
59366857a2SPetar Jovanovic const MipsTargetMachine &TM;
60366857a2SPetar Jovanovic const MipsSubtarget &STI;
61fac93e28SPetar Jovanovic const MipsInstrInfo &TII;
62fac93e28SPetar Jovanovic const MipsRegisterInfo &TRI;
63366857a2SPetar Jovanovic const MipsRegisterBankInfo &RBI;
64366857a2SPetar Jovanovic
65366857a2SPetar Jovanovic #define GET_GLOBALISEL_PREDICATES_DECL
66366857a2SPetar Jovanovic #include "MipsGenGlobalISel.inc"
67366857a2SPetar Jovanovic #undef GET_GLOBALISEL_PREDICATES_DECL
68366857a2SPetar Jovanovic
69366857a2SPetar Jovanovic #define GET_GLOBALISEL_TEMPORARIES_DECL
70366857a2SPetar Jovanovic #include "MipsGenGlobalISel.inc"
71366857a2SPetar Jovanovic #undef GET_GLOBALISEL_TEMPORARIES_DECL
72fac93e28SPetar Jovanovic };
73fac93e28SPetar Jovanovic
74fac93e28SPetar Jovanovic } // end anonymous namespace
75fac93e28SPetar Jovanovic
76366857a2SPetar Jovanovic #define GET_GLOBALISEL_IMPL
77366857a2SPetar Jovanovic #include "MipsGenGlobalISel.inc"
78366857a2SPetar Jovanovic #undef GET_GLOBALISEL_IMPL
79366857a2SPetar Jovanovic
MipsInstructionSelector(const MipsTargetMachine & TM,const MipsSubtarget & STI,const MipsRegisterBankInfo & RBI)80fac93e28SPetar Jovanovic MipsInstructionSelector::MipsInstructionSelector(
81fac93e28SPetar Jovanovic const MipsTargetMachine &TM, const MipsSubtarget &STI,
82fac93e28SPetar Jovanovic const MipsRegisterBankInfo &RBI)
83*f3a344d2SKazu Hirata : TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()),
84*f3a344d2SKazu Hirata RBI(RBI),
85366857a2SPetar Jovanovic
86366857a2SPetar Jovanovic #define GET_GLOBALISEL_PREDICATES_INIT
87366857a2SPetar Jovanovic #include "MipsGenGlobalISel.inc"
88366857a2SPetar Jovanovic #undef GET_GLOBALISEL_PREDICATES_INIT
89366857a2SPetar Jovanovic #define GET_GLOBALISEL_TEMPORARIES_INIT
90366857a2SPetar Jovanovic #include "MipsGenGlobalISel.inc"
91366857a2SPetar Jovanovic #undef GET_GLOBALISEL_TEMPORARIES_INIT
92366857a2SPetar Jovanovic {
93366857a2SPetar Jovanovic }
94366857a2SPetar Jovanovic
isRegInGprb(Register Reg,MachineRegisterInfo & MRI) const95d32a6f08SPetar Avramovic bool MipsInstructionSelector::isRegInGprb(Register Reg,
96d32a6f08SPetar Avramovic MachineRegisterInfo &MRI) const {
97d32a6f08SPetar Avramovic return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::GPRBRegBankID;
98d32a6f08SPetar Avramovic }
99d32a6f08SPetar Avramovic
isRegInFprb(Register Reg,MachineRegisterInfo & MRI) const100d32a6f08SPetar Avramovic bool MipsInstructionSelector::isRegInFprb(Register Reg,
101d32a6f08SPetar Avramovic MachineRegisterInfo &MRI) const {
102d32a6f08SPetar Avramovic return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::FPRBRegBankID;
103d32a6f08SPetar Avramovic }
104d32a6f08SPetar Avramovic
selectCopy(MachineInstr & I,MachineRegisterInfo & MRI) const105a034a64fSPetar Avramovic bool MipsInstructionSelector::selectCopy(MachineInstr &I,
106a034a64fSPetar Avramovic MachineRegisterInfo &MRI) const {
107faeaedf8SMatt Arsenault Register DstReg = I.getOperand(0).getReg();
1082bea69bfSDaniel Sanders if (Register::isPhysicalRegister(DstReg))
109366857a2SPetar Jovanovic return true;
110366857a2SPetar Jovanovic
111d32a6f08SPetar Avramovic const TargetRegisterClass *RC = getRegClassForTypeOnBank(DstReg, MRI);
112366857a2SPetar Jovanovic if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
113d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
114366857a2SPetar Jovanovic << " operand\n");
115366857a2SPetar Jovanovic return false;
116366857a2SPetar Jovanovic }
117366857a2SPetar Jovanovic return true;
118366857a2SPetar Jovanovic }
119fac93e28SPetar Jovanovic
getRegClassForTypeOnBank(Register Reg,MachineRegisterInfo & MRI) const1207d0778eaSPetar Avramovic const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
121d32a6f08SPetar Avramovic Register Reg, MachineRegisterInfo &MRI) const {
122d32a6f08SPetar Avramovic const LLT Ty = MRI.getType(Reg);
123d32a6f08SPetar Avramovic const unsigned TySize = Ty.getSizeInBits();
124d32a6f08SPetar Avramovic
125d32a6f08SPetar Avramovic if (isRegInGprb(Reg, MRI)) {
126d32a6f08SPetar Avramovic assert((Ty.isScalar() || Ty.isPointer()) && TySize == 32 &&
127d32a6f08SPetar Avramovic "Register class not available for LLT, register bank combination");
1287d0778eaSPetar Avramovic return &Mips::GPR32RegClass;
129d32a6f08SPetar Avramovic }
1307d0778eaSPetar Avramovic
131d32a6f08SPetar Avramovic if (isRegInFprb(Reg, MRI)) {
132d32a6f08SPetar Avramovic if (Ty.isScalar()) {
133d32a6f08SPetar Avramovic assert((TySize == 32 || TySize == 64) &&
134d32a6f08SPetar Avramovic "Register class not available for LLT, register bank combination");
135d32a6f08SPetar Avramovic if (TySize == 32)
136d32a6f08SPetar Avramovic return &Mips::FGR32RegClass;
137d32a6f08SPetar Avramovic return STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
138d32a6f08SPetar Avramovic }
139d32a6f08SPetar Avramovic }
1407d0778eaSPetar Avramovic
141d32a6f08SPetar Avramovic llvm_unreachable("Unsupported register bank.");
1427d0778eaSPetar Avramovic }
1437d0778eaSPetar Avramovic
materialize32BitImm(Register DestReg,APInt Imm,MachineIRBuilder & B) const144faeaedf8SMatt Arsenault bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
1453e0da146SPetar Avramovic MachineIRBuilder &B) const {
1463e0da146SPetar Avramovic assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
1473e0da146SPetar Avramovic // Ori zero extends immediate. Used for values with zeros in high 16 bits.
148a9bceb2bSJay Foad if (Imm.getHiBits(16).isZero()) {
1490bd82a96SSimon Atanasyan MachineInstr *Inst =
1500bd82a96SSimon Atanasyan B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
1513e0da146SPetar Avramovic .addImm(Imm.getLoBits(16).getLimitedValue());
1523e0da146SPetar Avramovic return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
1533e0da146SPetar Avramovic }
1543e0da146SPetar Avramovic // Lui places immediate in high 16 bits and sets low 16 bits to zero.
155a9bceb2bSJay Foad if (Imm.getLoBits(16).isZero()) {
1563e0da146SPetar Avramovic MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {})
1573e0da146SPetar Avramovic .addImm(Imm.getHiBits(16).getLimitedValue());
1583e0da146SPetar Avramovic return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
1593e0da146SPetar Avramovic }
1603e0da146SPetar Avramovic // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
1613e0da146SPetar Avramovic if (Imm.isSignedIntN(16)) {
1620bd82a96SSimon Atanasyan MachineInstr *Inst =
1630bd82a96SSimon Atanasyan B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
1643e0da146SPetar Avramovic .addImm(Imm.getLoBits(16).getLimitedValue());
1653e0da146SPetar Avramovic return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
1663e0da146SPetar Avramovic }
1673e0da146SPetar Avramovic // Values that cannot be materialized with single immediate instruction.
168faeaedf8SMatt Arsenault Register LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
1693e0da146SPetar Avramovic MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {})
1703e0da146SPetar Avramovic .addImm(Imm.getHiBits(16).getLimitedValue());
1713e0da146SPetar Avramovic MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
1723e0da146SPetar Avramovic .addImm(Imm.getLoBits(16).getLimitedValue());
1733e0da146SPetar Avramovic if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
1743e0da146SPetar Avramovic return false;
1753e0da146SPetar Avramovic if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
1763e0da146SPetar Avramovic return false;
1773e0da146SPetar Avramovic return true;
1783e0da146SPetar Avramovic }
1793e0da146SPetar Avramovic
180d32a6f08SPetar Avramovic /// When I.getOpcode() is returned, we failed to select MIPS instruction opcode.
181599591f3SPetar Avramovic unsigned
selectLoadStoreOpCode(MachineInstr & I,MachineRegisterInfo & MRI) const182599591f3SPetar Avramovic MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
183599591f3SPetar Avramovic MachineRegisterInfo &MRI) const {
184d32a6f08SPetar Avramovic const Register ValueReg = I.getOperand(0).getReg();
185d32a6f08SPetar Avramovic const LLT Ty = MRI.getType(ValueReg);
186d32a6f08SPetar Avramovic const unsigned TySize = Ty.getSizeInBits();
187599591f3SPetar Avramovic const unsigned MemSizeInBytes = (*I.memoperands_begin())->getSize();
188599591f3SPetar Avramovic unsigned Opc = I.getOpcode();
189599591f3SPetar Avramovic const bool isStore = Opc == TargetOpcode::G_STORE;
190d32a6f08SPetar Avramovic
191d32a6f08SPetar Avramovic if (isRegInGprb(ValueReg, MRI)) {
192d32a6f08SPetar Avramovic assert(((Ty.isScalar() && TySize == 32) ||
193d32a6f08SPetar Avramovic (Ty.isPointer() && TySize == 32 && MemSizeInBytes == 4)) &&
194d32a6f08SPetar Avramovic "Unsupported register bank, LLT, MemSizeInBytes combination");
19545ee0d6dSFangrui Song (void)TySize;
1967b31491aSPetar Avramovic if (isStore)
19779df8596SPetar Avramovic switch (MemSizeInBytes) {
19879df8596SPetar Avramovic case 4:
19979df8596SPetar Avramovic return Mips::SW;
200c98b26d3SPetar Avramovic case 2:
201c98b26d3SPetar Avramovic return Mips::SH;
202c98b26d3SPetar Avramovic case 1:
203c98b26d3SPetar Avramovic return Mips::SB;
20479df8596SPetar Avramovic default:
20579df8596SPetar Avramovic return Opc;
20679df8596SPetar Avramovic }
20779df8596SPetar Avramovic else
208c98b26d3SPetar Avramovic // Unspecified extending load is selected into zeroExtending load.
20979df8596SPetar Avramovic switch (MemSizeInBytes) {
21079df8596SPetar Avramovic case 4:
21179df8596SPetar Avramovic return Mips::LW;
21279df8596SPetar Avramovic case 2:
21379df8596SPetar Avramovic return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
21479df8596SPetar Avramovic case 1:
21579df8596SPetar Avramovic return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
21679df8596SPetar Avramovic default:
21779df8596SPetar Avramovic return Opc;
21879df8596SPetar Avramovic }
21979df8596SPetar Avramovic }
22079df8596SPetar Avramovic
221d32a6f08SPetar Avramovic if (isRegInFprb(ValueReg, MRI)) {
222d32a6f08SPetar Avramovic if (Ty.isScalar()) {
223d32a6f08SPetar Avramovic assert(((TySize == 32 && MemSizeInBytes == 4) ||
224d32a6f08SPetar Avramovic (TySize == 64 && MemSizeInBytes == 8)) &&
225d32a6f08SPetar Avramovic "Unsupported register bank, LLT, MemSizeInBytes combination");
226d32a6f08SPetar Avramovic
227d32a6f08SPetar Avramovic if (MemSizeInBytes == 4)
2287b31491aSPetar Avramovic return isStore ? Mips::SWC1 : Mips::LWC1;
229d32a6f08SPetar Avramovic
230599591f3SPetar Avramovic if (STI.isFP64bit())
2317b31491aSPetar Avramovic return isStore ? Mips::SDC164 : Mips::LDC164;
2327b31491aSPetar Avramovic return isStore ? Mips::SDC1 : Mips::LDC1;
233599591f3SPetar Avramovic }
234d32a6f08SPetar Avramovic
235d32a6f08SPetar Avramovic if (Ty.isVector()) {
236d32a6f08SPetar Avramovic assert(STI.hasMSA() && "Vector instructions require target with MSA.");
237d32a6f08SPetar Avramovic assert((TySize == 128 && MemSizeInBytes == 16) &&
238d32a6f08SPetar Avramovic "Unsupported register bank, LLT, MemSizeInBytes combination");
239d32a6f08SPetar Avramovic switch (Ty.getElementType().getSizeInBits()) {
240d32a6f08SPetar Avramovic case 8:
241d32a6f08SPetar Avramovic return isStore ? Mips::ST_B : Mips::LD_B;
242d32a6f08SPetar Avramovic case 16:
243d32a6f08SPetar Avramovic return isStore ? Mips::ST_H : Mips::LD_H;
244d32a6f08SPetar Avramovic case 32:
245d32a6f08SPetar Avramovic return isStore ? Mips::ST_W : Mips::LD_W;
246d32a6f08SPetar Avramovic case 64:
247d32a6f08SPetar Avramovic return isStore ? Mips::ST_D : Mips::LD_D;
2487b31491aSPetar Avramovic default:
2497b31491aSPetar Avramovic return Opc;
2507b31491aSPetar Avramovic }
2517b31491aSPetar Avramovic }
252d32a6f08SPetar Avramovic }
253d32a6f08SPetar Avramovic
2547b31491aSPetar Avramovic return Opc;
2557b31491aSPetar Avramovic }
2567b31491aSPetar Avramovic
buildUnalignedStore(MachineInstr & I,unsigned Opc,MachineOperand & BaseAddr,unsigned Offset,MachineMemOperand * MMO) const2575171d152SPetar Avramovic bool MipsInstructionSelector::buildUnalignedStore(
2585171d152SPetar Avramovic MachineInstr &I, unsigned Opc, MachineOperand &BaseAddr, unsigned Offset,
2595171d152SPetar Avramovic MachineMemOperand *MMO) const {
2605171d152SPetar Avramovic MachineInstr *NewInst =
2615171d152SPetar Avramovic BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
2625171d152SPetar Avramovic .add(I.getOperand(0))
2635171d152SPetar Avramovic .add(BaseAddr)
2645171d152SPetar Avramovic .addImm(Offset)
2655171d152SPetar Avramovic .addMemOperand(MMO);
2665171d152SPetar Avramovic if (!constrainSelectedInstRegOperands(*NewInst, TII, TRI, RBI))
2675171d152SPetar Avramovic return false;
2685171d152SPetar Avramovic return true;
2695171d152SPetar Avramovic }
2705171d152SPetar Avramovic
buildUnalignedLoad(MachineInstr & I,unsigned Opc,Register Dest,MachineOperand & BaseAddr,unsigned Offset,Register TiedDest,MachineMemOperand * MMO) const2715171d152SPetar Avramovic bool MipsInstructionSelector::buildUnalignedLoad(
2725171d152SPetar Avramovic MachineInstr &I, unsigned Opc, Register Dest, MachineOperand &BaseAddr,
2735171d152SPetar Avramovic unsigned Offset, Register TiedDest, MachineMemOperand *MMO) const {
2745171d152SPetar Avramovic MachineInstr *NewInst =
2755171d152SPetar Avramovic BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
2765171d152SPetar Avramovic .addDef(Dest)
2775171d152SPetar Avramovic .add(BaseAddr)
2785171d152SPetar Avramovic .addImm(Offset)
2795171d152SPetar Avramovic .addUse(TiedDest)
2805171d152SPetar Avramovic .addMemOperand(*I.memoperands_begin());
2815171d152SPetar Avramovic if (!constrainSelectedInstRegOperands(*NewInst, TII, TRI, RBI))
2825171d152SPetar Avramovic return false;
2835171d152SPetar Avramovic return true;
2845171d152SPetar Avramovic }
2855171d152SPetar Avramovic
select(MachineInstr & I)286e14c91b7SAmara Emerson bool MipsInstructionSelector::select(MachineInstr &I) {
287fac93e28SPetar Jovanovic
288366857a2SPetar Jovanovic MachineBasicBlock &MBB = *I.getParent();
289366857a2SPetar Jovanovic MachineFunction &MF = *MBB.getParent();
290366857a2SPetar Jovanovic MachineRegisterInfo &MRI = MF.getRegInfo();
291366857a2SPetar Jovanovic
292fac93e28SPetar Jovanovic if (!isPreISelGenericOpcode(I.getOpcode())) {
293366857a2SPetar Jovanovic if (I.isCopy())
294a034a64fSPetar Avramovic return selectCopy(I, MRI);
295366857a2SPetar Jovanovic
296fac93e28SPetar Jovanovic return true;
297fac93e28SPetar Jovanovic }
298fac93e28SPetar Jovanovic
299d1815dacSPetar Avramovic if (I.getOpcode() == Mips::G_MUL &&
300d32a6f08SPetar Avramovic isRegInGprb(I.getOperand(0).getReg(), MRI)) {
3013d3120dcSPetar Avramovic MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
3023d3120dcSPetar Avramovic .add(I.getOperand(0))
3033d3120dcSPetar Avramovic .add(I.getOperand(1))
3043d3120dcSPetar Avramovic .add(I.getOperand(2));
3053d3120dcSPetar Avramovic if (!constrainSelectedInstRegOperands(*Mul, TII, TRI, RBI))
3063d3120dcSPetar Avramovic return false;
3073d3120dcSPetar Avramovic Mul->getOperand(3).setIsDead(true);
3083d3120dcSPetar Avramovic Mul->getOperand(4).setIsDead(true);
3093d3120dcSPetar Avramovic
3103d3120dcSPetar Avramovic I.eraseFromParent();
311366857a2SPetar Jovanovic return true;
312366857a2SPetar Jovanovic }
313021e4c82SPetar Jovanovic
314e14c91b7SAmara Emerson if (selectImpl(I, *CoverageInfo))
3153d3120dcSPetar Avramovic return true;
3163d3120dcSPetar Avramovic
317021e4c82SPetar Jovanovic MachineInstr *MI = nullptr;
318021e4c82SPetar Jovanovic using namespace TargetOpcode;
319021e4c82SPetar Jovanovic
320021e4c82SPetar Jovanovic switch (I.getOpcode()) {
321a48285a1SPetar Avramovic case G_UMULH: {
322faeaedf8SMatt Arsenault Register PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
323a48285a1SPetar Avramovic MachineInstr *PseudoMULTu, *PseudoMove;
324a48285a1SPetar Avramovic
325a48285a1SPetar Avramovic PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu))
326a48285a1SPetar Avramovic .addDef(PseudoMULTuReg)
327a48285a1SPetar Avramovic .add(I.getOperand(1))
328a48285a1SPetar Avramovic .add(I.getOperand(2));
329a48285a1SPetar Avramovic if (!constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI))
330a48285a1SPetar Avramovic return false;
331a48285a1SPetar Avramovic
332a48285a1SPetar Avramovic PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI))
333a48285a1SPetar Avramovic .addDef(I.getOperand(0).getReg())
334a48285a1SPetar Avramovic .addUse(PseudoMULTuReg);
335a48285a1SPetar Avramovic if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
336a48285a1SPetar Avramovic return false;
337a48285a1SPetar Avramovic
338a48285a1SPetar Avramovic I.eraseFromParent();
339a48285a1SPetar Avramovic return true;
340a48285a1SPetar Avramovic }
341e74c5b96SDaniel Sanders case G_PTR_ADD: {
342021e4c82SPetar Jovanovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
343021e4c82SPetar Jovanovic .add(I.getOperand(0))
344021e4c82SPetar Jovanovic .add(I.getOperand(1))
345021e4c82SPetar Jovanovic .add(I.getOperand(2));
346021e4c82SPetar Jovanovic break;
347021e4c82SPetar Jovanovic }
348b1fc6f61SPetar Avramovic case G_INTTOPTR:
349b1fc6f61SPetar Avramovic case G_PTRTOINT: {
350b1fc6f61SPetar Avramovic I.setDesc(TII.get(COPY));
351b1fc6f61SPetar Avramovic return selectCopy(I, MRI);
352b1fc6f61SPetar Avramovic }
353021e4c82SPetar Jovanovic case G_FRAME_INDEX: {
354021e4c82SPetar Jovanovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
355021e4c82SPetar Jovanovic .add(I.getOperand(0))
356021e4c82SPetar Jovanovic .add(I.getOperand(1))
357021e4c82SPetar Jovanovic .addImm(0);
358021e4c82SPetar Jovanovic break;
359021e4c82SPetar Jovanovic }
3605d9b8eedSPetar Avramovic case G_BRCOND: {
3615d9b8eedSPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::BNE))
3625d9b8eedSPetar Avramovic .add(I.getOperand(0))
3635d9b8eedSPetar Avramovic .addUse(Mips::ZERO)
3645d9b8eedSPetar Avramovic .add(I.getOperand(1));
3655d9b8eedSPetar Avramovic break;
3665d9b8eedSPetar Avramovic }
367caef9306SPetar Avramovic case G_BRJT: {
368caef9306SPetar Avramovic unsigned EntrySize =
369caef9306SPetar Avramovic MF.getJumpTableInfo()->getEntrySize(MF.getDataLayout());
370caef9306SPetar Avramovic assert(isPowerOf2_32(EntrySize) &&
371caef9306SPetar Avramovic "Non-power-of-two jump-table entry size not supported.");
372caef9306SPetar Avramovic
373caef9306SPetar Avramovic Register JTIndex = MRI.createVirtualRegister(&Mips::GPR32RegClass);
374caef9306SPetar Avramovic MachineInstr *SLL = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SLL))
375caef9306SPetar Avramovic .addDef(JTIndex)
376caef9306SPetar Avramovic .addUse(I.getOperand(2).getReg())
377caef9306SPetar Avramovic .addImm(Log2_32(EntrySize));
378caef9306SPetar Avramovic if (!constrainSelectedInstRegOperands(*SLL, TII, TRI, RBI))
379caef9306SPetar Avramovic return false;
380caef9306SPetar Avramovic
381caef9306SPetar Avramovic Register DestAddress = MRI.createVirtualRegister(&Mips::GPR32RegClass);
382caef9306SPetar Avramovic MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
383caef9306SPetar Avramovic .addDef(DestAddress)
384caef9306SPetar Avramovic .addUse(I.getOperand(0).getReg())
385caef9306SPetar Avramovic .addUse(JTIndex);
386caef9306SPetar Avramovic if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI))
387caef9306SPetar Avramovic return false;
388caef9306SPetar Avramovic
389caef9306SPetar Avramovic Register Dest = MRI.createVirtualRegister(&Mips::GPR32RegClass);
390caef9306SPetar Avramovic MachineInstr *LW =
391caef9306SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
392caef9306SPetar Avramovic .addDef(Dest)
393caef9306SPetar Avramovic .addUse(DestAddress)
394caef9306SPetar Avramovic .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_LO)
395caef9306SPetar Avramovic .addMemOperand(MF.getMachineMemOperand(
396c9d5c195SGuillaume Chatelet MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4)));
397caef9306SPetar Avramovic if (!constrainSelectedInstRegOperands(*LW, TII, TRI, RBI))
398caef9306SPetar Avramovic return false;
399caef9306SPetar Avramovic
400caef9306SPetar Avramovic if (MF.getTarget().isPositionIndependent()) {
401caef9306SPetar Avramovic Register DestTmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
402caef9306SPetar Avramovic LW->getOperand(0).setReg(DestTmp);
403caef9306SPetar Avramovic MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
404caef9306SPetar Avramovic .addDef(Dest)
405caef9306SPetar Avramovic .addUse(DestTmp)
406caef9306SPetar Avramovic .addUse(MF.getInfo<MipsFunctionInfo>()
407669bb311SMatt Arsenault ->getGlobalBaseRegForGlobalISel(MF));
408caef9306SPetar Avramovic if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI))
409caef9306SPetar Avramovic return false;
410caef9306SPetar Avramovic }
411caef9306SPetar Avramovic
412caef9306SPetar Avramovic MachineInstr *Branch =
413caef9306SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch))
414caef9306SPetar Avramovic .addUse(Dest);
415caef9306SPetar Avramovic if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
416caef9306SPetar Avramovic return false;
417caef9306SPetar Avramovic
418caef9306SPetar Avramovic I.eraseFromParent();
419caef9306SPetar Avramovic return true;
420caef9306SPetar Avramovic }
421ff6ac1ebSPetar Avramovic case G_BRINDIRECT: {
422ff6ac1ebSPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch))
423ff6ac1ebSPetar Avramovic .add(I.getOperand(0));
424ff6ac1ebSPetar Avramovic break;
425ff6ac1ebSPetar Avramovic }
42614c7ecfeSPetar Avramovic case G_PHI: {
427faeaedf8SMatt Arsenault const Register DestReg = I.getOperand(0).getReg();
42814c7ecfeSPetar Avramovic
4297d0778eaSPetar Avramovic const TargetRegisterClass *DefRC = nullptr;
4302bea69bfSDaniel Sanders if (Register::isPhysicalRegister(DestReg))
4317d0778eaSPetar Avramovic DefRC = TRI.getRegClass(DestReg);
4327d0778eaSPetar Avramovic else
433d32a6f08SPetar Avramovic DefRC = getRegClassForTypeOnBank(DestReg, MRI);
43414c7ecfeSPetar Avramovic
43514c7ecfeSPetar Avramovic I.setDesc(TII.get(TargetOpcode::PHI));
43614c7ecfeSPetar Avramovic return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
43714c7ecfeSPetar Avramovic }
438021e4c82SPetar Jovanovic case G_STORE:
43979df8596SPetar Avramovic case G_LOAD:
44079df8596SPetar Avramovic case G_ZEXTLOAD:
44179df8596SPetar Avramovic case G_SEXTLOAD: {
4425171d152SPetar Avramovic auto MMO = *I.memoperands_begin();
4438a40cedfSPetar Avramovic MachineOperand BaseAddr = I.getOperand(1);
4448a40cedfSPetar Avramovic int64_t SignedOffset = 0;
445e74c5b96SDaniel Sanders // Try to fold load/store + G_PTR_ADD + G_CONSTANT
4468a40cedfSPetar Avramovic // %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate
447e74c5b96SDaniel Sanders // %Addr:(p0) = G_PTR_ADD %BaseAddr, %SignedOffset
4488a40cedfSPetar Avramovic // %LoadResult/%StoreSrc = load/store %Addr(p0)
4498a40cedfSPetar Avramovic // into:
4508a40cedfSPetar Avramovic // %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate
4518a40cedfSPetar Avramovic
4528a40cedfSPetar Avramovic MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg());
453e74c5b96SDaniel Sanders if (Addr->getOpcode() == G_PTR_ADD) {
4548a40cedfSPetar Avramovic MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg());
4558a40cedfSPetar Avramovic if (Offset->getOpcode() == G_CONSTANT) {
4568a40cedfSPetar Avramovic APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue();
4578a40cedfSPetar Avramovic if (OffsetValue.isSignedIntN(16)) {
4588a40cedfSPetar Avramovic BaseAddr = Addr->getOperand(1);
4598a40cedfSPetar Avramovic SignedOffset = OffsetValue.getSExtValue();
4608a40cedfSPetar Avramovic }
4618a40cedfSPetar Avramovic }
4628a40cedfSPetar Avramovic }
4638a40cedfSPetar Avramovic
4645171d152SPetar Avramovic // Unaligned memory access
46574eac903SGuillaume Chatelet if (MMO->getAlign() < MMO->getSize() &&
4665171d152SPetar Avramovic !STI.systemSupportsUnalignedAccess()) {
4675171d152SPetar Avramovic if (MMO->getSize() != 4 || !isRegInGprb(I.getOperand(0).getReg(), MRI))
4685171d152SPetar Avramovic return false;
4695171d152SPetar Avramovic
4705171d152SPetar Avramovic if (I.getOpcode() == G_STORE) {
4715171d152SPetar Avramovic if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, SignedOffset + 3, MMO))
4725171d152SPetar Avramovic return false;
4735171d152SPetar Avramovic if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, SignedOffset, MMO))
4745171d152SPetar Avramovic return false;
4755171d152SPetar Avramovic I.eraseFromParent();
4765171d152SPetar Avramovic return true;
4775171d152SPetar Avramovic }
4785171d152SPetar Avramovic
4795171d152SPetar Avramovic if (I.getOpcode() == G_LOAD) {
4805171d152SPetar Avramovic Register ImplDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4815171d152SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
4825171d152SPetar Avramovic .addDef(ImplDef);
4835171d152SPetar Avramovic Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
4845171d152SPetar Avramovic if (!buildUnalignedLoad(I, Mips::LWL, Tmp, BaseAddr, SignedOffset + 3,
4855171d152SPetar Avramovic ImplDef, MMO))
4865171d152SPetar Avramovic return false;
4875171d152SPetar Avramovic if (!buildUnalignedLoad(I, Mips::LWR, I.getOperand(0).getReg(),
4885171d152SPetar Avramovic BaseAddr, SignedOffset, Tmp, MMO))
4895171d152SPetar Avramovic return false;
4905171d152SPetar Avramovic I.eraseFromParent();
4915171d152SPetar Avramovic return true;
4925171d152SPetar Avramovic }
4935171d152SPetar Avramovic
4945171d152SPetar Avramovic return false;
4955171d152SPetar Avramovic }
4965171d152SPetar Avramovic
4975171d152SPetar Avramovic const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
4985171d152SPetar Avramovic if (NewOpc == I.getOpcode())
4995171d152SPetar Avramovic return false;
5005171d152SPetar Avramovic
501021e4c82SPetar Jovanovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
502021e4c82SPetar Jovanovic .add(I.getOperand(0))
5038a40cedfSPetar Avramovic .add(BaseAddr)
5048a40cedfSPetar Avramovic .addImm(SignedOffset)
5055171d152SPetar Avramovic .addMemOperand(MMO);
506021e4c82SPetar Jovanovic break;
507021e4c82SPetar Jovanovic }
5080a5e4eb7SPetar Avramovic case G_UDIV:
5090a5e4eb7SPetar Avramovic case G_UREM:
5100a5e4eb7SPetar Avramovic case G_SDIV:
5110a5e4eb7SPetar Avramovic case G_SREM: {
512faeaedf8SMatt Arsenault Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
5130a5e4eb7SPetar Avramovic bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV;
5140a5e4eb7SPetar Avramovic bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV;
5150a5e4eb7SPetar Avramovic
5160a5e4eb7SPetar Avramovic MachineInstr *PseudoDIV, *PseudoMove;
5170a5e4eb7SPetar Avramovic PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
5180a5e4eb7SPetar Avramovic TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV))
5190a5e4eb7SPetar Avramovic .addDef(HILOReg)
5200a5e4eb7SPetar Avramovic .add(I.getOperand(1))
5210a5e4eb7SPetar Avramovic .add(I.getOperand(2));
5220a5e4eb7SPetar Avramovic if (!constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI))
5230a5e4eb7SPetar Avramovic return false;
5240a5e4eb7SPetar Avramovic
5250a5e4eb7SPetar Avramovic PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
5260a5e4eb7SPetar Avramovic TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI))
5270a5e4eb7SPetar Avramovic .addDef(I.getOperand(0).getReg())
5280a5e4eb7SPetar Avramovic .addUse(HILOReg);
5290a5e4eb7SPetar Avramovic if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
5300a5e4eb7SPetar Avramovic return false;
5310a5e4eb7SPetar Avramovic
5320a5e4eb7SPetar Avramovic I.eraseFromParent();
5330a5e4eb7SPetar Avramovic return true;
5340a5e4eb7SPetar Avramovic }
53509dff333SPetar Avramovic case G_SELECT: {
53609dff333SPetar Avramovic // Handle operands with pointer type.
53709dff333SPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
53809dff333SPetar Avramovic .add(I.getOperand(0))
53909dff333SPetar Avramovic .add(I.getOperand(2))
54009dff333SPetar Avramovic .add(I.getOperand(1))
54109dff333SPetar Avramovic .add(I.getOperand(3));
54209dff333SPetar Avramovic break;
54309dff333SPetar Avramovic }
54492c80529SPetar Avramovic case G_UNMERGE_VALUES: {
54592c80529SPetar Avramovic if (I.getNumOperands() != 3)
54692c80529SPetar Avramovic return false;
54792c80529SPetar Avramovic Register Src = I.getOperand(2).getReg();
54892c80529SPetar Avramovic Register Lo = I.getOperand(0).getReg();
54992c80529SPetar Avramovic Register Hi = I.getOperand(1).getReg();
55092c80529SPetar Avramovic if (!isRegInFprb(Src, MRI) ||
55192c80529SPetar Avramovic !(isRegInGprb(Lo, MRI) && isRegInGprb(Hi, MRI)))
55292c80529SPetar Avramovic return false;
55392c80529SPetar Avramovic
55492c80529SPetar Avramovic unsigned Opcode =
55592c80529SPetar Avramovic STI.isFP64bit() ? Mips::ExtractElementF64_64 : Mips::ExtractElementF64;
55692c80529SPetar Avramovic
55792c80529SPetar Avramovic MachineInstr *ExtractLo = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
55892c80529SPetar Avramovic .addDef(Lo)
55992c80529SPetar Avramovic .addUse(Src)
56092c80529SPetar Avramovic .addImm(0);
56192c80529SPetar Avramovic if (!constrainSelectedInstRegOperands(*ExtractLo, TII, TRI, RBI))
56292c80529SPetar Avramovic return false;
56392c80529SPetar Avramovic
56492c80529SPetar Avramovic MachineInstr *ExtractHi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
56592c80529SPetar Avramovic .addDef(Hi)
56692c80529SPetar Avramovic .addUse(Src)
56792c80529SPetar Avramovic .addImm(1);
56892c80529SPetar Avramovic if (!constrainSelectedInstRegOperands(*ExtractHi, TII, TRI, RBI))
56992c80529SPetar Avramovic return false;
57092c80529SPetar Avramovic
57192c80529SPetar Avramovic I.eraseFromParent();
57292c80529SPetar Avramovic return true;
57392c80529SPetar Avramovic }
57475e43a60SPetar Avramovic case G_IMPLICIT_DEF: {
575d32a6f08SPetar Avramovic Register Dst = I.getOperand(0).getReg();
57675e43a60SPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
577d32a6f08SPetar Avramovic .addDef(Dst);
57875e43a60SPetar Avramovic
57975e43a60SPetar Avramovic // Set class based on register bank, there can be fpr and gpr implicit def.
580d32a6f08SPetar Avramovic MRI.setRegClass(Dst, getRegClassForTypeOnBank(Dst, MRI));
58175e43a60SPetar Avramovic break;
58275e43a60SPetar Avramovic }
583021e4c82SPetar Jovanovic case G_CONSTANT: {
5843e0da146SPetar Avramovic MachineIRBuilder B(I);
5853e0da146SPetar Avramovic if (!materialize32BitImm(I.getOperand(0).getReg(),
5863e0da146SPetar Avramovic I.getOperand(1).getCImm()->getValue(), B))
587021e4c82SPetar Jovanovic return false;
588021e4c82SPetar Jovanovic
589021e4c82SPetar Jovanovic I.eraseFromParent();
590021e4c82SPetar Jovanovic return true;
591021e4c82SPetar Jovanovic }
5921af05df3SPetar Avramovic case G_FCONSTANT: {
5931af05df3SPetar Avramovic const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
5941af05df3SPetar Avramovic APInt APImm = FPimm.bitcastToAPInt();
5951af05df3SPetar Avramovic unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
5961af05df3SPetar Avramovic
5971af05df3SPetar Avramovic if (Size == 32) {
598faeaedf8SMatt Arsenault Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
5991af05df3SPetar Avramovic MachineIRBuilder B(I);
6001af05df3SPetar Avramovic if (!materialize32BitImm(GPRReg, APImm, B))
6011af05df3SPetar Avramovic return false;
6021af05df3SPetar Avramovic
6031af05df3SPetar Avramovic MachineInstrBuilder MTC1 =
6041af05df3SPetar Avramovic B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
6051af05df3SPetar Avramovic if (!MTC1.constrainAllUses(TII, TRI, RBI))
6061af05df3SPetar Avramovic return false;
6071af05df3SPetar Avramovic }
6081af05df3SPetar Avramovic if (Size == 64) {
609faeaedf8SMatt Arsenault Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
610faeaedf8SMatt Arsenault Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
6111af05df3SPetar Avramovic MachineIRBuilder B(I);
6121af05df3SPetar Avramovic if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
6131af05df3SPetar Avramovic return false;
6141af05df3SPetar Avramovic if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
6151af05df3SPetar Avramovic return false;
6161af05df3SPetar Avramovic
6171af05df3SPetar Avramovic MachineInstrBuilder PairF64 = B.buildInstr(
6181af05df3SPetar Avramovic STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64,
6191af05df3SPetar Avramovic {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
6201af05df3SPetar Avramovic if (!PairF64.constrainAllUses(TII, TRI, RBI))
6211af05df3SPetar Avramovic return false;
6221af05df3SPetar Avramovic }
6231af05df3SPetar Avramovic
6241af05df3SPetar Avramovic I.eraseFromParent();
6251af05df3SPetar Avramovic return true;
6261af05df3SPetar Avramovic }
6270a1fd355SPetar Avramovic case G_FABS: {
6280a1fd355SPetar Avramovic unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
6290a1fd355SPetar Avramovic unsigned FABSOpcode =
6300a1fd355SPetar Avramovic Size == 32 ? Mips::FABS_S
6310a1fd355SPetar Avramovic : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32;
6320a1fd355SPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
6330a1fd355SPetar Avramovic .add(I.getOperand(0))
6340a1fd355SPetar Avramovic .add(I.getOperand(1));
6350a1fd355SPetar Avramovic break;
6360a1fd355SPetar Avramovic }
6374b4dae1cSPetar Avramovic case G_FPTOSI: {
6384b4dae1cSPetar Avramovic unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits();
6394b4dae1cSPetar Avramovic unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
640ddd056c9SFangrui Song (void)ToSize;
6414b4dae1cSPetar Avramovic assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI");
6424b4dae1cSPetar Avramovic assert((FromSize == 32 || FromSize == 64) &&
6434b4dae1cSPetar Avramovic "Unsupported floating point size for G_FPTOSI");
6444b4dae1cSPetar Avramovic
6454b4dae1cSPetar Avramovic unsigned Opcode;
6464b4dae1cSPetar Avramovic if (FromSize == 32)
6474b4dae1cSPetar Avramovic Opcode = Mips::TRUNC_W_S;
6484b4dae1cSPetar Avramovic else
6494b4dae1cSPetar Avramovic Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32;
6500c476111SDaniel Sanders Register ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass);
6514b4dae1cSPetar Avramovic MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
6524b4dae1cSPetar Avramovic .addDef(ResultInFPR)
6534b4dae1cSPetar Avramovic .addUse(I.getOperand(1).getReg());
6544b4dae1cSPetar Avramovic if (!constrainSelectedInstRegOperands(*Trunc, TII, TRI, RBI))
6554b4dae1cSPetar Avramovic return false;
6564b4dae1cSPetar Avramovic
6574b4dae1cSPetar Avramovic MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1))
6584b4dae1cSPetar Avramovic .addDef(I.getOperand(0).getReg())
6594b4dae1cSPetar Avramovic .addUse(ResultInFPR);
6604b4dae1cSPetar Avramovic if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
6614b4dae1cSPetar Avramovic return false;
6624b4dae1cSPetar Avramovic
6634b4dae1cSPetar Avramovic I.eraseFromParent();
6644b4dae1cSPetar Avramovic return true;
6654b4dae1cSPetar Avramovic }
66664c10ba8SPetar Jovanovic case G_GLOBAL_VALUE: {
667efcd3c00SPetar Avramovic const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
668efcd3c00SPetar Avramovic if (MF.getTarget().isPositionIndependent()) {
669efcd3c00SPetar Avramovic MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
670efcd3c00SPetar Avramovic .addDef(I.getOperand(0).getReg())
671efcd3c00SPetar Avramovic .addReg(MF.getInfo<MipsFunctionInfo>()
672669bb311SMatt Arsenault ->getGlobalBaseRegForGlobalISel(MF))
673efcd3c00SPetar Avramovic .addGlobalAddress(GVal);
674efcd3c00SPetar Avramovic // Global Values that don't have local linkage are handled differently
675efcd3c00SPetar Avramovic // when they are part of call sequence. MipsCallLowering::lowerCall
676efcd3c00SPetar Avramovic // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
677efcd3c00SPetar Avramovic // MO_GOT_CALL flag when Callee doesn't have local linkage.
678efcd3c00SPetar Avramovic if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
679efcd3c00SPetar Avramovic LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL);
680efcd3c00SPetar Avramovic else
681efcd3c00SPetar Avramovic LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT);
682efcd3c00SPetar Avramovic LWGOT->addMemOperand(
683efcd3c00SPetar Avramovic MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF),
684c9d5c195SGuillaume Chatelet MachineMemOperand::MOLoad, 4, Align(4)));
685efcd3c00SPetar Avramovic if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI))
68664c10ba8SPetar Jovanovic return false;
68764c10ba8SPetar Jovanovic
688efcd3c00SPetar Avramovic if (GVal->hasLocalLinkage()) {
689faeaedf8SMatt Arsenault Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
690efcd3c00SPetar Avramovic LWGOT->getOperand(0).setReg(LWGOTDef);
69164c10ba8SPetar Jovanovic
692efcd3c00SPetar Avramovic MachineInstr *ADDiu =
693efcd3c00SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
694efcd3c00SPetar Avramovic .addDef(I.getOperand(0).getReg())
695efcd3c00SPetar Avramovic .addReg(LWGOTDef)
696efcd3c00SPetar Avramovic .addGlobalAddress(GVal);
697efcd3c00SPetar Avramovic ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
698efcd3c00SPetar Avramovic if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
699efcd3c00SPetar Avramovic return false;
700efcd3c00SPetar Avramovic }
701efcd3c00SPetar Avramovic } else {
702faeaedf8SMatt Arsenault Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
703efcd3c00SPetar Avramovic
704efcd3c00SPetar Avramovic MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
70564c10ba8SPetar Jovanovic .addDef(LUiReg)
70664c10ba8SPetar Jovanovic .addGlobalAddress(GVal);
70764c10ba8SPetar Jovanovic LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI);
708efcd3c00SPetar Avramovic if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
709efcd3c00SPetar Avramovic return false;
71064c10ba8SPetar Jovanovic
711efcd3c00SPetar Avramovic MachineInstr *ADDiu =
712efcd3c00SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
71364c10ba8SPetar Jovanovic .addDef(I.getOperand(0).getReg())
71464c10ba8SPetar Jovanovic .addUse(LUiReg)
71564c10ba8SPetar Jovanovic .addGlobalAddress(GVal);
71664c10ba8SPetar Jovanovic ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
71764c10ba8SPetar Jovanovic if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
71864c10ba8SPetar Jovanovic return false;
719efcd3c00SPetar Avramovic }
72064c10ba8SPetar Jovanovic I.eraseFromParent();
72164c10ba8SPetar Jovanovic return true;
72264c10ba8SPetar Jovanovic }
723caef9306SPetar Avramovic case G_JUMP_TABLE: {
724caef9306SPetar Avramovic if (MF.getTarget().isPositionIndependent()) {
725caef9306SPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
726caef9306SPetar Avramovic .addDef(I.getOperand(0).getReg())
727caef9306SPetar Avramovic .addReg(MF.getInfo<MipsFunctionInfo>()
728669bb311SMatt Arsenault ->getGlobalBaseRegForGlobalISel(MF))
729caef9306SPetar Avramovic .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT)
730c9d5c195SGuillaume Chatelet .addMemOperand(MF.getMachineMemOperand(
731c9d5c195SGuillaume Chatelet MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad, 4,
732c9d5c195SGuillaume Chatelet Align(4)));
733caef9306SPetar Avramovic } else {
734caef9306SPetar Avramovic MI =
735caef9306SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
736caef9306SPetar Avramovic .addDef(I.getOperand(0).getReg())
737caef9306SPetar Avramovic .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI);
738caef9306SPetar Avramovic }
739caef9306SPetar Avramovic break;
740caef9306SPetar Avramovic }
741ce4dd0aeSPetar Jovanovic case G_ICMP: {
742ce4dd0aeSPetar Jovanovic struct Instr {
743faeaedf8SMatt Arsenault unsigned Opcode;
744faeaedf8SMatt Arsenault Register Def, LHS, RHS;
745faeaedf8SMatt Arsenault Instr(unsigned Opcode, Register Def, Register LHS, Register RHS)
746ce4dd0aeSPetar Jovanovic : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
747021e4c82SPetar Jovanovic
748ce4dd0aeSPetar Jovanovic bool hasImm() const {
749ce4dd0aeSPetar Jovanovic if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
750ce4dd0aeSPetar Jovanovic return true;
751ce4dd0aeSPetar Jovanovic return false;
752ce4dd0aeSPetar Jovanovic }
753ce4dd0aeSPetar Jovanovic };
754ce4dd0aeSPetar Jovanovic
755ce4dd0aeSPetar Jovanovic SmallVector<struct Instr, 2> Instructions;
756faeaedf8SMatt Arsenault Register ICMPReg = I.getOperand(0).getReg();
757faeaedf8SMatt Arsenault Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
758faeaedf8SMatt Arsenault Register LHS = I.getOperand(2).getReg();
759faeaedf8SMatt Arsenault Register RHS = I.getOperand(3).getReg();
760ce4dd0aeSPetar Jovanovic CmpInst::Predicate Cond =
761ce4dd0aeSPetar Jovanovic static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
762ce4dd0aeSPetar Jovanovic
763ce4dd0aeSPetar Jovanovic switch (Cond) {
764ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
765ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
766ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
767ce4dd0aeSPetar Jovanovic break;
768ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
769ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
770ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
771ce4dd0aeSPetar Jovanovic break;
772ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_UGT: // LHS > RHS -> RHS < LHS
773ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
774ce4dd0aeSPetar Jovanovic break;
775ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
776ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
777ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
778ce4dd0aeSPetar Jovanovic break;
779ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_ULT: // LHS < RHS -> LHS < RHS
780ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
781ce4dd0aeSPetar Jovanovic break;
782ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
783ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
784ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
785ce4dd0aeSPetar Jovanovic break;
786ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_SGT: // LHS > RHS -> RHS < LHS
787ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
788ce4dd0aeSPetar Jovanovic break;
789ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
790ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
791ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
792ce4dd0aeSPetar Jovanovic break;
793ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_SLT: // LHS < RHS -> LHS < RHS
794ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
795ce4dd0aeSPetar Jovanovic break;
796ce4dd0aeSPetar Jovanovic case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
797ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
798ce4dd0aeSPetar Jovanovic Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
799ce4dd0aeSPetar Jovanovic break;
800ce4dd0aeSPetar Jovanovic default:
801ce4dd0aeSPetar Jovanovic return false;
802ce4dd0aeSPetar Jovanovic }
803ce4dd0aeSPetar Jovanovic
804ce4dd0aeSPetar Jovanovic MachineIRBuilder B(I);
805ce4dd0aeSPetar Jovanovic for (const struct Instr &Instruction : Instructions) {
806cef44a23SAditya Nandakumar MachineInstrBuilder MIB = B.buildInstr(
807cef44a23SAditya Nandakumar Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
808ce4dd0aeSPetar Jovanovic
809ce4dd0aeSPetar Jovanovic if (Instruction.hasImm())
810ce4dd0aeSPetar Jovanovic MIB.addImm(Instruction.RHS);
811ce4dd0aeSPetar Jovanovic else
812ce4dd0aeSPetar Jovanovic MIB.addUse(Instruction.RHS);
813ce4dd0aeSPetar Jovanovic
814ce4dd0aeSPetar Jovanovic if (!MIB.constrainAllUses(TII, TRI, RBI))
815ce4dd0aeSPetar Jovanovic return false;
816ce4dd0aeSPetar Jovanovic }
817ce4dd0aeSPetar Jovanovic
818ce4dd0aeSPetar Jovanovic I.eraseFromParent();
819ce4dd0aeSPetar Jovanovic return true;
820ce4dd0aeSPetar Jovanovic }
82122e99c43SPetar Avramovic case G_FCMP: {
82222e99c43SPetar Avramovic unsigned MipsFCMPCondCode;
82322e99c43SPetar Avramovic bool isLogicallyNegated;
82422e99c43SPetar Avramovic switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
82522e99c43SPetar Avramovic I.getOperand(1).getPredicate())) {
82622e99c43SPetar Avramovic case CmpInst::FCMP_UNO: // Unordered
82722e99c43SPetar Avramovic case CmpInst::FCMP_ORD: // Ordered (OR)
82822e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_UN;
82922e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
83022e99c43SPetar Avramovic break;
83122e99c43SPetar Avramovic case CmpInst::FCMP_OEQ: // Equal
83222e99c43SPetar Avramovic case CmpInst::FCMP_UNE: // Not Equal (NEQ)
83322e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_OEQ;
83422e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
83522e99c43SPetar Avramovic break;
83622e99c43SPetar Avramovic case CmpInst::FCMP_UEQ: // Unordered or Equal
83722e99c43SPetar Avramovic case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
83822e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_UEQ;
83922e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
84022e99c43SPetar Avramovic break;
84122e99c43SPetar Avramovic case CmpInst::FCMP_OLT: // Ordered or Less Than
84222e99c43SPetar Avramovic case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
84322e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_OLT;
84422e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
84522e99c43SPetar Avramovic break;
84622e99c43SPetar Avramovic case CmpInst::FCMP_ULT: // Unordered or Less Than
84722e99c43SPetar Avramovic case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
84822e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_ULT;
84922e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
85022e99c43SPetar Avramovic break;
85122e99c43SPetar Avramovic case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
85222e99c43SPetar Avramovic case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
85322e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_OLE;
85422e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
85522e99c43SPetar Avramovic break;
85622e99c43SPetar Avramovic case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
85722e99c43SPetar Avramovic case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
85822e99c43SPetar Avramovic MipsFCMPCondCode = Mips::FCOND_ULE;
85922e99c43SPetar Avramovic isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
86022e99c43SPetar Avramovic break;
86122e99c43SPetar Avramovic default:
86222e99c43SPetar Avramovic return false;
86322e99c43SPetar Avramovic }
86422e99c43SPetar Avramovic
86522e99c43SPetar Avramovic // Default compare result in gpr register will be `true`.
86622e99c43SPetar Avramovic // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
86722e99c43SPetar Avramovic // using MOVF_I. When orignal predicate (Cond) is logically negated
86822e99c43SPetar Avramovic // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
86922e99c43SPetar Avramovic unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
87022e99c43SPetar Avramovic
8710c476111SDaniel Sanders Register TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
87222e99c43SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
87322e99c43SPetar Avramovic .addDef(TrueInReg)
87422e99c43SPetar Avramovic .addUse(Mips::ZERO)
87522e99c43SPetar Avramovic .addImm(1);
87622e99c43SPetar Avramovic
87722e99c43SPetar Avramovic unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
87822e99c43SPetar Avramovic unsigned FCMPOpcode =
87922e99c43SPetar Avramovic Size == 32 ? Mips::FCMP_S32
88022e99c43SPetar Avramovic : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
88122e99c43SPetar Avramovic MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
88222e99c43SPetar Avramovic .addUse(I.getOperand(2).getReg())
88322e99c43SPetar Avramovic .addUse(I.getOperand(3).getReg())
88422e99c43SPetar Avramovic .addImm(MipsFCMPCondCode);
88522e99c43SPetar Avramovic if (!constrainSelectedInstRegOperands(*FCMP, TII, TRI, RBI))
88622e99c43SPetar Avramovic return false;
88722e99c43SPetar Avramovic
88822e99c43SPetar Avramovic MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
88922e99c43SPetar Avramovic .addDef(I.getOperand(0).getReg())
89022e99c43SPetar Avramovic .addUse(Mips::ZERO)
89122e99c43SPetar Avramovic .addUse(Mips::FCC0)
89222e99c43SPetar Avramovic .addUse(TrueInReg);
89322e99c43SPetar Avramovic if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
89422e99c43SPetar Avramovic return false;
89522e99c43SPetar Avramovic
89622e99c43SPetar Avramovic I.eraseFromParent();
89722e99c43SPetar Avramovic return true;
89822e99c43SPetar Avramovic }
899a4bfc8dfSPetar Avramovic case G_FENCE: {
900a4bfc8dfSPetar Avramovic MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
901a4bfc8dfSPetar Avramovic break;
902a4bfc8dfSPetar Avramovic }
903c063b0b0SPetar Avramovic case G_VASTART: {
904c063b0b0SPetar Avramovic MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
905c063b0b0SPetar Avramovic int FI = FuncInfo->getVarArgsFrameIndex();
906c063b0b0SPetar Avramovic
907c063b0b0SPetar Avramovic Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
908c063b0b0SPetar Avramovic MachineInstr *LEA_ADDiu =
909c063b0b0SPetar Avramovic BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
910c063b0b0SPetar Avramovic .addDef(LeaReg)
911c063b0b0SPetar Avramovic .addFrameIndex(FI)
912c063b0b0SPetar Avramovic .addImm(0);
913c063b0b0SPetar Avramovic if (!constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI))
914c063b0b0SPetar Avramovic return false;
915c063b0b0SPetar Avramovic
916c063b0b0SPetar Avramovic MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
917c063b0b0SPetar Avramovic .addUse(LeaReg)
918c063b0b0SPetar Avramovic .addUse(I.getOperand(0).getReg())
919c063b0b0SPetar Avramovic .addImm(0);
920c063b0b0SPetar Avramovic if (!constrainSelectedInstRegOperands(*Store, TII, TRI, RBI))
921c063b0b0SPetar Avramovic return false;
922c063b0b0SPetar Avramovic
923c063b0b0SPetar Avramovic I.eraseFromParent();
924c063b0b0SPetar Avramovic return true;
925c063b0b0SPetar Avramovic }
926021e4c82SPetar Jovanovic default:
927021e4c82SPetar Jovanovic return false;
928021e4c82SPetar Jovanovic }
929021e4c82SPetar Jovanovic
930021e4c82SPetar Jovanovic I.eraseFromParent();
931021e4c82SPetar Jovanovic return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
932fac93e28SPetar Jovanovic }
933fac93e28SPetar Jovanovic
934fac93e28SPetar Jovanovic namespace llvm {
createMipsInstructionSelector(const MipsTargetMachine & TM,MipsSubtarget & Subtarget,MipsRegisterBankInfo & RBI)935fac93e28SPetar Jovanovic InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM,
936fac93e28SPetar Jovanovic MipsSubtarget &Subtarget,
937fac93e28SPetar Jovanovic MipsRegisterBankInfo &RBI) {
938fac93e28SPetar Jovanovic return new MipsInstructionSelector(TM, Subtarget, RBI);
939fac93e28SPetar Jovanovic }
940fac93e28SPetar Jovanovic } // end namespace llvm
941