LLVM 22.0.0git
Mips16ISelDAGToDAG.cpp
Go to the documentation of this file.
1//===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16 ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Subclass of MipsDAGToDAGISel specialized for mips16.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Mips16ISelDAGToDAG.h"
15#include "Mips.h"
16#include "MipsMachineFunction.h"
17#include "MipsRegisterInfo.h"
24using namespace llvm;
25
26#define DEBUG_TYPE "mips-isel"
27
28bool Mips16DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
30 if (!Subtarget->inMips16Mode())
31 return false;
33}
34/// Select multiply instructions.
35std::pair<SDNode *, SDNode *>
36Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, const SDLoc &DL, EVT Ty,
37 bool HasLo, bool HasHi) {
38 SDNode *Lo = nullptr, *Hi = nullptr;
39 SDNode *Mul = CurDAG->getMachineNode(Opc, DL, MVT::Glue, N->getOperand(0),
40 N->getOperand(1));
41 SDValue InGlue = SDValue(Mul, 0);
42
43 if (HasLo) {
44 unsigned Opcode = Mips::Mflo16;
45 Lo = CurDAG->getMachineNode(Opcode, DL, Ty, MVT::Glue, InGlue);
46 InGlue = SDValue(Lo, 1);
47 }
48 if (HasHi) {
49 unsigned Opcode = Mips::Mfhi16;
50 Hi = CurDAG->getMachineNode(Opcode, DL, Ty, InGlue);
51 }
52 return std::make_pair(Lo, Hi);
53}
54
55void Mips16DAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
56 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
57
58 if (!MipsFI->globalBaseRegSet())
59 return;
60
61 MachineBasicBlock &MBB = MF.front();
63 MachineRegisterInfo &RegInfo = MF.getRegInfo();
64 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
66 Register V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg(MF);
67 const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass;
68
69 V0 = RegInfo.createVirtualRegister(RC);
70 V1 = RegInfo.createVirtualRegister(RC);
71 V2 = RegInfo.createVirtualRegister(RC);
72
73
74 BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0)
76 BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1)
78
79 BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);
80 BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)
81 .addReg(V1)
82 .addReg(V2);
83}
84
85void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
86 initGlobalBaseReg(MF);
87}
88
89bool Mips16DAGToDAGISel::selectAddr(bool SPAllowed, SDValue Addr, SDValue &Base,
90 SDValue &Offset) {
91 SDLoc DL(Addr);
92 EVT ValTy = Addr.getValueType();
93
94 // if Address is FI, get the TargetFrameIndex.
95 if (SPAllowed) {
96 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
97 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
98 Offset = CurDAG->getTargetConstant(0, DL, ValTy);
99 return true;
100 }
101 }
102 // on PIC code Load GA
103 if (Addr.getOpcode() == MipsISD::Wrapper) {
104 Base = Addr.getOperand(0);
105 Offset = Addr.getOperand(1);
106 return true;
107 }
108 if (!TM.isPositionIndependent()) {
109 if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
111 return false;
112 }
113 // Addresses of the form FI+const or FI|const
114 if (CurDAG->isBaseWithConstantOffset(Addr)) {
115 auto *CN = cast<ConstantSDNode>(Addr.getOperand(1));
116 if (isInt<16>(CN->getSExtValue())) {
117 // If the first operand is a FI, get the TargetFI Node
118 if (SPAllowed) {
119 if (FrameIndexSDNode *FIN =
121 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
122 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), DL, ValTy);
123 return true;
124 }
125 }
126
127 Base = Addr.getOperand(0);
128 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), DL, ValTy);
129 return true;
130 }
131 }
132 // Operand is a result from an ADD.
133 if (Addr.getOpcode() == ISD::ADD) {
134 // When loading from constant pools, load the lower address part in
135 // the instruction itself. Example, instead of:
136 // lui $2, %hi($CPI1_0)
137 // addiu $2, $2, %lo($CPI1_0)
138 // lwc1 $f0, 0($2)
139 // Generate:
140 // lui $2, %hi($CPI1_0)
141 // lwc1 $f0, %lo($CPI1_0)($2)
142 if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
143 Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
144 SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
146 isa<JumpTableSDNode>(Opnd0)) {
147 Base = Addr.getOperand(0);
148 Offset = Opnd0;
149 return true;
150 }
151 }
152 }
153 Base = Addr;
154 Offset = CurDAG->getTargetConstant(0, DL, ValTy);
155 return true;
156}
157
158bool Mips16DAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base,
159 SDValue &Offset) {
160 return selectAddr(false, Addr, Base, Offset);
161}
162
163bool Mips16DAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base,
164 SDValue &Offset) {
165 return selectAddr(true, Addr, Base, Offset);
166}
167
168/// Select instructions not customized! Used for
169/// expanded, promoted and normal instructions
170bool Mips16DAGToDAGISel::trySelect(SDNode *Node) {
171 unsigned Opcode = Node->getOpcode();
172 SDLoc DL(Node);
173
174 ///
175 // Instruction Selection not handled by the auto-generated
176 // tablegen selection should be handled here.
177 ///
178 EVT NodeTy = Node->getValueType(0);
179 unsigned MultOpc;
180
181 switch (Opcode) {
182 default:
183 break;
184
185 /// Mul with two results
186 case ISD::SMUL_LOHI:
187 case ISD::UMUL_LOHI: {
188 MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 : Mips::MultRxRy16);
189 std::pair<SDNode *, SDNode *> LoHi =
190 selectMULT(Node, MultOpc, DL, NodeTy, true, true);
191 if (!SDValue(Node, 0).use_empty())
192 ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
193
194 if (!SDValue(Node, 1).use_empty())
195 ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
196
197 CurDAG->RemoveDeadNode(Node);
198 return true;
199 }
200
201 case ISD::MULHS:
202 case ISD::MULHU: {
203 MultOpc = (Opcode == ISD::MULHU ? Mips::MultuRxRy16 : Mips::MultRxRy16);
204 auto LoHi = selectMULT(Node, MultOpc, DL, NodeTy, false, true);
205 ReplaceNode(Node, LoHi.second);
206 return true;
207 }
208 }
209
210 return false;
211}
212
216
return SDValue()
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define I(x, y, z)
Definition MD5.cpp:58
Promote Memory to Register
Definition Mem2Reg.cpp:110
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Mips16DAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL)
MipsDAGToDAGISelLegacy(std::unique_ptr< SelectionDAGISel > S)
bool runOnMachineFunction(MachineFunction &MF) override
const MipsSubtarget * Subtarget
Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...
Register getGlobalBaseReg(MachineFunction &MF)
bool inMips16Mode() const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
MachineRegisterInfo * RegInfo
const TargetInstrInfo * TII
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:270
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:259
@ TargetExternalSymbol
Definition ISDOpcodes.h:185
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition ISDOpcodes.h:180
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:695
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
@ Mul
Product of integers.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
FunctionPass * createMips16ISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
Extended Value Type.
Definition ValueTypes.h:35