1 //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines an instruction selector for the MIPS target.
11 //===----------------------------------------------------------------------===//
13 #include "MipsISelDAGToDAG.h"
14 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "Mips16ISelDAGToDAG.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsRegisterInfo.h"
19 #include "MipsSEISelDAGToDAG.h"
20 #include "llvm/CodeGen/MachineConstantPool.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/SelectionDAG.h"
26 #include "llvm/CodeGen/SelectionDAGNodes.h"
27 #include "llvm/CodeGen/StackProtector.h"
28 #include "llvm/IR/CFG.h"
29 #include "llvm/IR/GlobalValue.h"
30 #include "llvm/IR/Instructions.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/IR/Type.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/KnownBits.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/Target/TargetMachine.h"
40 #define DEBUG_TYPE "mips-isel"
41 #define PASS_NAME "MIPS DAG->DAG Pattern Instruction Selection"
43 //===----------------------------------------------------------------------===//
44 // Instruction Selector Implementation
45 //===----------------------------------------------------------------------===//
47 //===----------------------------------------------------------------------===//
48 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
49 // instructions for SelectionDAG operations.
50 //===----------------------------------------------------------------------===//
52 void MipsDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage
&AU
) const {
53 // There are multiple MipsDAGToDAGISel instances added to the pass pipeline.
54 // We need to preserve StackProtector for the next one.
55 AU
.addPreserved
<StackProtector
>();
56 SelectionDAGISelLegacy::getAnalysisUsage(AU
);
59 bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction
&MF
) {
60 Subtarget
= &MF
.getSubtarget
<MipsSubtarget
>();
61 bool Ret
= SelectionDAGISel::runOnMachineFunction(MF
);
63 processFunctionAfterISel(MF
);
68 /// getGlobalBaseReg - Output the instructions required to put the
69 /// GOT address into a register.
70 SDNode
*MipsDAGToDAGISel::getGlobalBaseReg() {
71 Register GlobalBaseReg
= MF
->getInfo
<MipsFunctionInfo
>()->getGlobalBaseReg(*MF
);
72 return CurDAG
->getRegister(GlobalBaseReg
, getTargetLowering()->getPointerTy(
73 CurDAG
->getDataLayout()))
77 /// ComplexPattern used on MipsInstrInfo
78 /// Used on Mips Load/Store instructions
79 bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr
, SDValue
&Base
,
80 SDValue
&Offset
) const {
81 llvm_unreachable("Unimplemented function.");
85 bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr
, SDValue
&Base
,
86 SDValue
&Offset
) const {
87 llvm_unreachable("Unimplemented function.");
91 bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr
, SDValue
&Base
,
92 SDValue
&Offset
) const {
93 llvm_unreachable("Unimplemented function.");
97 bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr
, SDValue
&Base
,
98 SDValue
&Offset
) const {
99 llvm_unreachable("Unimplemented function.");
103 bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr
, SDValue
&Base
,
104 SDValue
&Offset
) const {
105 llvm_unreachable("Unimplemented function.");
109 bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr
, SDValue
&Base
,
110 SDValue
&Offset
) const {
111 llvm_unreachable("Unimplemented function.");
115 bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr
, SDValue
&Base
,
116 SDValue
&Offset
) const {
117 llvm_unreachable("Unimplemented function.");
121 bool MipsDAGToDAGISel::selectIntAddrSImm10(SDValue Addr
, SDValue
&Base
,
122 SDValue
&Offset
) const {
123 llvm_unreachable("Unimplemented function.");
127 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr
, SDValue
&Base
,
128 SDValue
&Offset
) const {
129 llvm_unreachable("Unimplemented function.");
133 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr
, SDValue
&Base
,
134 SDValue
&Offset
) const {
135 llvm_unreachable("Unimplemented function.");
139 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr
, SDValue
&Base
,
140 SDValue
&Offset
) const {
141 llvm_unreachable("Unimplemented function.");
145 bool MipsDAGToDAGISel::selectAddr16(SDValue Addr
, SDValue
&Base
,
147 llvm_unreachable("Unimplemented function.");
151 bool MipsDAGToDAGISel::selectAddr16SP(SDValue Addr
, SDValue
&Base
,
153 llvm_unreachable("Unimplemented function.");
157 bool MipsDAGToDAGISel::selectVSplat(SDNode
*N
, APInt
&Imm
,
158 unsigned MinSizeInBits
) const {
159 llvm_unreachable("Unimplemented function.");
163 bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N
, SDValue
&Imm
) const {
164 llvm_unreachable("Unimplemented function.");
168 bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N
, SDValue
&Imm
) const {
169 llvm_unreachable("Unimplemented function.");
173 bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N
, SDValue
&Imm
) const {
174 llvm_unreachable("Unimplemented function.");
178 bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N
, SDValue
&Imm
) const {
179 llvm_unreachable("Unimplemented function.");
183 bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N
, SDValue
&Imm
) const {
184 llvm_unreachable("Unimplemented function.");
188 bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N
, SDValue
&Imm
) const {
189 llvm_unreachable("Unimplemented function.");
193 bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N
, SDValue
&Imm
) const {
194 llvm_unreachable("Unimplemented function.");
198 bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N
, SDValue
&Imm
) const {
199 llvm_unreachable("Unimplemented function.");
203 bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N
, SDValue
&Imm
) const {
204 llvm_unreachable("Unimplemented function.");
208 bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N
, SDValue
&Imm
) const {
209 llvm_unreachable("Unimplemented function.");
213 bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N
, SDValue
&Imm
) const {
214 llvm_unreachable("Unimplemented function.");
218 bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N
, SDValue
&Imm
) const {
219 llvm_unreachable("Unimplemented function.");
223 /// Convert vector addition with vector subtraction if that allows to encode
224 /// constant as an immediate and thus avoid extra 'ldi' instruction.
225 /// add X, <-1, -1...> --> sub X, <1, 1...>
226 bool MipsDAGToDAGISel::selectVecAddAsVecSubIfProfitable(SDNode
*Node
) {
227 assert(Node
->getOpcode() == ISD::ADD
&& "Should only get 'add' here.");
229 EVT VT
= Node
->getValueType(0);
230 assert(VT
.isVector() && "Should only be called for vectors.");
232 SDValue X
= Node
->getOperand(0);
233 SDValue C
= Node
->getOperand(1);
235 auto *BVN
= dyn_cast
<BuildVectorSDNode
>(C
);
239 APInt SplatValue
, SplatUndef
;
240 unsigned SplatBitSize
;
243 if (!BVN
->isConstantSplat(SplatValue
, SplatUndef
, SplatBitSize
, HasAnyUndefs
,
244 8, !Subtarget
->isLittle()))
247 auto IsInlineConstant
= [](const APInt
&Imm
) { return Imm
.isIntN(5); };
249 if (IsInlineConstant(SplatValue
))
250 return false; // Can already be encoded as an immediate.
252 APInt NegSplatValue
= 0 - SplatValue
;
253 if (!IsInlineConstant(NegSplatValue
))
254 return false; // Even if we negate it it won't help.
258 SDValue NegC
= CurDAG
->FoldConstantArithmetic(
259 ISD::SUB
, DL
, VT
, {CurDAG
->getConstant(0, DL
, VT
), C
});
260 assert(NegC
&& "Constant-folding failed!");
261 SDValue NewNode
= CurDAG
->getNode(ISD::SUB
, DL
, VT
, X
, NegC
);
263 ReplaceNode(Node
, NewNode
.getNode());
264 SelectCode(NewNode
.getNode());
268 /// Select instructions not customized! Used for
269 /// expanded, promoted and normal instructions
270 void MipsDAGToDAGISel::Select(SDNode
*Node
) {
271 unsigned Opcode
= Node
->getOpcode();
273 // If we have a custom node, we already have selected!
274 if (Node
->isMachineOpcode()) {
275 LLVM_DEBUG(errs() << "== "; Node
->dump(CurDAG
); errs() << "\n");
280 // See if subclasses can handle this node.
288 if (Node
->getSimpleValueType(0).isVector() &&
289 selectVecAddAsVecSubIfProfitable(Node
))
293 // Get target GOT address.
294 case ISD::GLOBAL_OFFSET_TABLE
:
295 ReplaceNode(Node
, getGlobalBaseReg());
301 assert((Subtarget
->systemSupportsUnalignedAccess() ||
302 cast
<MemSDNode
>(Node
)->getAlign() >=
303 cast
<MemSDNode
>(Node
)->getMemoryVT().getStoreSize()) &&
304 "Unexpected unaligned loads/stores.");
309 // Select the default instruction
313 bool MipsDAGToDAGISel::SelectInlineAsmMemoryOperand(
314 const SDValue
&Op
, InlineAsm::ConstraintCode ConstraintID
,
315 std::vector
<SDValue
> &OutOps
) {
316 // All memory constraints can at least accept raw pointers.
317 switch(ConstraintID
) {
319 llvm_unreachable("Unexpected asm memory constraint");
320 case InlineAsm::ConstraintCode::m
:
321 case InlineAsm::ConstraintCode::R
:
322 case InlineAsm::ConstraintCode::ZC
:
323 OutOps
.push_back(Op
);
329 bool MipsDAGToDAGISel::isUnneededShiftMask(SDNode
*N
,
330 unsigned ShAmtBits
) const {
331 assert(N
->getOpcode() == ISD::AND
&& "Unexpected opcode");
333 const APInt
&RHS
= N
->getConstantOperandAPInt(1);
334 if (RHS
.countr_one() >= ShAmtBits
) {
338 << " Need optimize 'and & shl/srl/sra' and operand value bits is "
339 << RHS
.countr_one() << "\n");
343 KnownBits Known
= CurDAG
->computeKnownBits(N
->getOperand(0));
344 return (Known
.Zero
| RHS
).countr_one() >= ShAmtBits
;
347 char MipsDAGToDAGISelLegacy::ID
= 0;
349 MipsDAGToDAGISelLegacy::MipsDAGToDAGISelLegacy(
350 std::unique_ptr
<SelectionDAGISel
> S
)
351 : SelectionDAGISelLegacy(ID
, std::move(S
)) {}
353 INITIALIZE_PASS(MipsDAGToDAGISelLegacy
, DEBUG_TYPE
, PASS_NAME
, false, false)