1//===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE ----===//
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 mips32/64.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsSEISelDAGToDAG.h"
14#include "Mips.h"
15#include "MipsAnalyzeImmediate.h"
16#include "MipsMachineFunction.h"
17#include "MipsRegisterInfo.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/CodeGen/SelectionDAGNodes.h"
23#include "llvm/IR/Dominators.h"
24#include "llvm/IR/GlobalValue.h"
25#include "llvm/IR/Instructions.h"
26#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/IntrinsicsMips.h"
28#include "llvm/IR/Type.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Target/TargetMachine.h"
31using namespace llvm;
32
33#define DEBUG_TYPE "mips-isel"
34
35bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
36 Subtarget = &MF.getSubtarget<MipsSubtarget>();
37 if (Subtarget->inMips16Mode())
38 return false;
39 return MipsDAGToDAGISel::runOnMachineFunction(MF);
40}
41
42void MipsSEDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
43 SelectionDAGISelLegacy::getAnalysisUsage(AU);
44}
45
46void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI,
47 MachineFunction &MF) {
48 MachineInstrBuilder MIB(MF, &MI);
49 unsigned Mask = MI.getOperand(i: 1).getImm();
50 RegState Flag =
51 IsDef ? RegState::ImplicitDefine : RegState::Implicit | RegState::Undef;
52
53 if (Mask & 1)
54 MIB.addReg(RegNo: Mips::DSPPos, Flags: Flag);
55
56 if (Mask & 2)
57 MIB.addReg(RegNo: Mips::DSPSCount, Flags: Flag);
58
59 if (Mask & 4)
60 MIB.addReg(RegNo: Mips::DSPCarry, Flags: Flag);
61
62 if (Mask & 8)
63 MIB.addReg(RegNo: Mips::DSPOutFlag, Flags: Flag);
64
65 if (Mask & 16)
66 MIB.addReg(RegNo: Mips::DSPCCond, Flags: Flag);
67
68 if (Mask & 32)
69 MIB.addReg(RegNo: Mips::DSPEFI, Flags: Flag);
70}
71
72MCRegister MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const {
73 uint64_t RegNum = RegIdx->getAsZExtVal();
74 return Mips::MSACtrlRegClass.getRegister(i: RegNum);
75}
76
77bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI,
78 const MachineInstr& MI) {
79 unsigned DstReg = 0, ZeroReg = 0;
80
81 // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0".
82 if ((MI.getOpcode() == Mips::ADDiu) &&
83 (MI.getOperand(i: 1).getReg() == Mips::R0) && (MI.getOperand(i: 2).isImm()) &&
84 (MI.getOperand(i: 2).getImm() == 0)) {
85 DstReg = MI.getOperand(i: 0).getReg();
86 ZeroReg = Mips::R0;
87 } else if ((MI.getOpcode() == Mips::DADDiu) &&
88 (MI.getOperand(i: 1).getReg() == Mips::R0_64) &&
89 (MI.getOperand(i: 2).isImm()) && (MI.getOperand(i: 2).getImm() == 0)) {
90 DstReg = MI.getOperand(i: 0).getReg();
91 ZeroReg = Mips::R0_64;
92 }
93
94 if (!DstReg)
95 return false;
96
97 // Replace uses with ZeroReg.
98 for (MachineRegisterInfo::use_iterator U = MRI->use_begin(RegNo: DstReg),
99 E = MRI->use_end(); U != E;) {
100 MachineOperand &MO = *U;
101 unsigned OpNo = U.getOperandNo();
102 MachineInstr *MI = MO.getParent();
103 ++U;
104
105 // Do not replace if it is a phi's operand or is tied to def operand.
106 if (MI->isPHI() || MI->isRegTiedToDefOperand(UseOpIdx: OpNo) || MI->isPseudo())
107 continue;
108
109 // Also, we have to check that the register class of the operand
110 // contains the zero register.
111 if (!MRI->getRegClass(Reg: MO.getReg())->contains(Reg: ZeroReg))
112 continue;
113
114 MO.setReg(ZeroReg);
115 }
116
117 return true;
118}
119
120void MipsSEDAGToDAGISel::emitMCountABI(MachineInstr &MI, MachineBasicBlock &MBB,
121 MachineFunction &MF) {
122 MachineInstrBuilder MIB(MF, &MI);
123 if (!Subtarget->isABI_O32()) { // N32, N64
124 // Save current return address.
125 BuildMI(BB&: MBB, I: &MI, MIMD: MI.getDebugLoc(), MCID: TII->get(Opcode: Mips::OR64))
126 .addDef(RegNo: Mips::R1_64)
127 .addUse(RegNo: Mips::RA_64, Flags: RegState::Undef)
128 .addUse(RegNo: Mips::R0_64);
129 // Stops instruction above from being removed later on.
130 MIB.addUse(RegNo: Mips::R1_64, Flags: RegState::Implicit);
131 } else { // O32
132 // Save current return address.
133 BuildMI(BB&: MBB, I: &MI, MIMD: MI.getDebugLoc(), MCID: TII->get(Opcode: Mips::OR))
134 .addDef(RegNo: Mips::R1)
135 .addUse(RegNo: Mips::RA, Flags: RegState::Undef)
136 .addUse(RegNo: Mips::R0);
137 // _mcount pops 2 words from stack.
138 BuildMI(BB&: MBB, I: &MI, MIMD: MI.getDebugLoc(), MCID: TII->get(Opcode: Mips::ADDiu))
139 .addDef(RegNo: Mips::SP)
140 .addUse(RegNo: Mips::SP)
141 .addImm(Val: -8);
142 // Stops first instruction above from being removed later on.
143 MIB.addUse(RegNo: Mips::R1, Flags: RegState::Implicit);
144 }
145}
146
147void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
148 MF.getInfo<MipsFunctionInfo>()->initGlobalBaseReg(MF);
149
150 MachineRegisterInfo *MRI = &MF.getRegInfo();
151
152 for (auto &MBB: MF) {
153 for (auto &MI: MBB) {
154 switch (MI.getOpcode()) {
155 case Mips::RDDSP:
156 addDSPCtrlRegOperands(IsDef: false, MI, MF);
157 break;
158 case Mips::WRDSP:
159 addDSPCtrlRegOperands(IsDef: true, MI, MF);
160 break;
161 case Mips::BuildPairF64_64:
162 case Mips::ExtractElementF64_64:
163 if (!Subtarget->useOddSPReg() || !Subtarget->hasMTHC1()) {
164 MI.addOperand(Op: MachineOperand::CreateReg(Reg: Mips::SP, isDef: false, isImp: true));
165 break;
166 }
167 [[fallthrough]];
168 case Mips::BuildPairF64:
169 case Mips::ExtractElementF64:
170 if (Subtarget->isABI_FPXX() && !Subtarget->hasMTHC1())
171 MI.addOperand(Op: MachineOperand::CreateReg(Reg: Mips::SP, isDef: false, isImp: true));
172 break;
173 case Mips::JAL:
174 case Mips::JAL_MM:
175 if (MI.getOperand(i: 0).isGlobal() &&
176 MI.getOperand(i: 0).getGlobal()->hasExternalLinkage() &&
177 MI.getOperand(i: 0).getGlobal()->getName() == "_mcount")
178 emitMCountABI(MI, MBB, MF);
179 break;
180 case Mips::JALRPseudo:
181 case Mips::JALR64Pseudo:
182 case Mips::JALR16_MM:
183 if (MI.getOperand(i: 2).isMCSymbol() &&
184 MI.getOperand(i: 2).getMCSymbol()->getName() == "_mcount")
185 emitMCountABI(MI, MBB, MF);
186 break;
187 case Mips::JALR:
188 if (MI.getOperand(i: 3).isMCSymbol() &&
189 MI.getOperand(i: 3).getMCSymbol()->getName() == "_mcount")
190 emitMCountABI(MI, MBB, MF);
191 break;
192 default:
193 replaceUsesWithZeroReg(MRI, MI);
194 }
195 }
196 }
197}
198
199void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const {
200 SDValue InGlue = Node->getOperand(Num: 2);
201 unsigned Opc = InGlue.getOpcode();
202 SDValue LHS = Node->getOperand(Num: 0), RHS = Node->getOperand(Num: 1);
203 EVT VT = LHS.getValueType();
204
205 // In the base case, we can rely on the carry bit from the addsc
206 // instruction.
207 if (Opc == ISD::ADDC) {
208 SDValue Ops[3] = {LHS, RHS, InGlue};
209 CurDAG->SelectNodeTo(N: Node, MachineOpc: Mips::ADDWC, VT1: VT, VT2: MVT::Glue, Ops);
210 return;
211 }
212
213 assert(Opc == ISD::ADDE && "ISD::ADDE not in a chain of ADDE nodes!");
214
215 // The more complex case is when there is a chain of ISD::ADDE nodes like:
216 // (adde (adde (adde (addc a b) c) d) e).
217 //
218 // The addwc instruction does not write to the carry bit, instead it writes
219 // to bit 20 of the dsp control register. To match this series of nodes, each
220 // intermediate adde node must be expanded to write the carry bit before the
221 // addition.
222
223 // Start by reading the overflow field for addsc and moving the value to the
224 // carry field. The usage of 1 here with MipsISD::RDDSP / Mips::WRDSP
225 // corresponds to reading/writing the entire control register to/from a GPR.
226
227 SDValue CstOne = CurDAG->getTargetConstant(Val: 1, DL, VT: MVT::i32);
228
229 SDValue OuFlag = CurDAG->getTargetConstant(Val: 20, DL, VT: MVT::i32);
230
231 SDNode *DSPCtrlField = CurDAG->getMachineNode(Opcode: Mips::RDDSP, dl: DL, VT1: MVT::i32,
232 VT2: MVT::Glue, Op1: CstOne, Op2: InGlue);
233
234 SDNode *Carry = CurDAG->getMachineNode(
235 Opcode: Mips::EXT, dl: DL, VT: MVT::i32, Op1: SDValue(DSPCtrlField, 0), Op2: OuFlag, Op3: CstOne);
236
237 SDValue Ops[4] = {SDValue(DSPCtrlField, 0),
238 CurDAG->getTargetConstant(Val: 6, DL, VT: MVT::i32), CstOne,
239 SDValue(Carry, 0)};
240 SDNode *DSPCFWithCarry = CurDAG->getMachineNode(Opcode: Mips::INS, dl: DL, VT: MVT::i32, Ops);
241
242 // My reading of the MIPS DSP 3.01 specification isn't as clear as I
243 // would like about whether bit 20 always gets overwritten by addwc.
244 // Hence take an extremely conservative view and presume it's sticky. We
245 // therefore need to clear it.
246
247 SDValue Zero = CurDAG->getRegister(Reg: Mips::R0, VT: MVT::i32);
248
249 SDValue InsOps[4] = {Zero, OuFlag, CstOne, SDValue(DSPCFWithCarry, 0)};
250 SDNode *DSPCtrlFinal =
251 CurDAG->getMachineNode(Opcode: Mips::INS, dl: DL, VT: MVT::i32, Ops: InsOps);
252
253 SDNode *WrDSP = CurDAG->getMachineNode(Opcode: Mips::WRDSP, dl: DL, VT: MVT::Glue,
254 Op1: SDValue(DSPCtrlFinal, 0), Op2: CstOne);
255
256 SDValue Operands[3] = {LHS, RHS, SDValue(WrDSP, 0)};
257 CurDAG->SelectNodeTo(N: Node, MachineOpc: Mips::ADDWC, VT1: VT, VT2: MVT::Glue, Ops: Operands);
258}
259
260/// Match frameindex
261bool MipsSEDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base,
262 SDValue &Offset) const {
263 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Val&: Addr)) {
264 EVT ValTy = Addr.getValueType();
265
266 Base = CurDAG->getTargetFrameIndex(FI: FIN->getIndex(), VT: ValTy);
267 Offset = CurDAG->getTargetConstant(Val: 0, DL: SDLoc(Addr), VT: ValTy);
268 return true;
269 }
270 return false;
271}
272
273/// Match frameindex+offset and frameindex|offset
274bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
275 SDValue Addr, SDValue &Base, SDValue &Offset, unsigned OffsetBits,
276 unsigned ShiftAmount = 0) const {
277 if (CurDAG->isBaseWithConstantOffset(Op: Addr)) {
278 auto *CN = cast<ConstantSDNode>(Val: Addr.getOperand(i: 1));
279 if (isIntN(N: OffsetBits + ShiftAmount, x: CN->getSExtValue())) {
280 EVT ValTy = Addr.getValueType();
281
282 // If the first operand is a FI, get the TargetFI Node
283 if (FrameIndexSDNode *FIN =
284 dyn_cast<FrameIndexSDNode>(Val: Addr.getOperand(i: 0)))
285 Base = CurDAG->getTargetFrameIndex(FI: FIN->getIndex(), VT: ValTy);
286 else {
287 Base = Addr.getOperand(i: 0);
288 // If base is a FI, additional offset calculation is done in
289 // eliminateFrameIndex, otherwise we need to check the alignment
290 const Align Alignment = Align::fromLog2(Log2Value: ShiftAmount);
291 if (!isAligned(Lhs: Alignment, SizeInBytes: CN->getZExtValue()))
292 return false;
293 }
294
295 Offset = CurDAG->getTargetConstant(Val: CN->getZExtValue(), DL: SDLoc(Addr),
296 VT: ValTy);
297 if (Base.getOpcode() == ISD::ADD &&
298 (Subtarget->hasMips1() && !Subtarget->hasMips2())) {
299 // Instead of:
300 // lui $2, %hi($CPI1_0)
301 // addiu $2, $2, %lo($CPI1_0)
302 // lwc1 $f0, 4($2)
303 // Generate:
304 // lui $2, %hi($CPI1_0)
305 // lwc1 $f0, %lo($CPI1_0+4)($2)
306 if (Base.getOperand(i: 1).getOpcode() == MipsISD::Lo ||
307 Base.getOperand(i: 1).getOpcode() == MipsISD::GPRel) {
308 SDValue Opnd0 = Base.getOperand(i: 1).getOperand(i: 0);
309 if (isa<ConstantPoolSDNode>(Val: Opnd0) || isa<JumpTableSDNode>(Val: Opnd0))
310 Base = Base.getOperand(i: 0);
311 else if (GlobalAddressSDNode *GA =
312 dyn_cast<GlobalAddressSDNode>(Val&: Opnd0)) {
313 Base = Base.getOperand(i: 0);
314 const GlobalValue *GV = GA->getGlobal();
315 int64_t GAOffset = GA->getOffset();
316 Offset = CurDAG->getTargetGlobalAddress(
317 GV, DL: SDLoc(Addr), VT: MVT::i32, offset: GAOffset + CN->getZExtValue(),
318 TargetFlags: MipsII::MO_ABS_LO);
319 return true;
320 }
321 }
322 }
323 return true;
324 }
325 }
326 return false;
327}
328
329/// ComplexPattern used on MipsInstrInfo
330/// Used on Mips Load/Store instructions
331bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
332 SDValue &Offset) const {
333 // if Address is FI, get the TargetFrameIndex.
334 if (selectAddrFrameIndex(Addr, Base, Offset))
335 return true;
336
337 // on PIC code Load GA
338 if (Addr.getOpcode() == MipsISD::Wrapper) {
339 Base = Addr.getOperand(i: 0);
340 Offset = Addr.getOperand(i: 1);
341 return true;
342 }
343
344 if (!TM.isPositionIndependent()) {
345 if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
346 Addr.getOpcode() == ISD::TargetGlobalAddress))
347 return false;
348 }
349
350 // Addresses of the form FI+const or FI|const
351 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 16))
352 return true;
353
354 // Operand is a result from an ADD.
355 if (Addr.getOpcode() == ISD::ADD) {
356 // When loading from constant pools, load the lower address part in
357 // the instruction itself. Example, instead of:
358 // lui $2, %hi($CPI1_0)
359 // addiu $2, $2, %lo($CPI1_0)
360 // lwc1 $f0, 0($2)
361 // Generate:
362 // lui $2, %hi($CPI1_0)
363 // lwc1 $f0, %lo($CPI1_0)($2)
364 if (Addr.getOperand(i: 1).getOpcode() == MipsISD::Lo ||
365 Addr.getOperand(i: 1).getOpcode() == MipsISD::GPRel) {
366 SDValue Opnd0 = Addr.getOperand(i: 1).getOperand(i: 0);
367 if (isa<ConstantPoolSDNode>(Val: Opnd0) || isa<GlobalAddressSDNode>(Val: Opnd0) ||
368 isa<JumpTableSDNode>(Val: Opnd0)) {
369 Base = Addr.getOperand(i: 0);
370 Offset = Opnd0;
371 return true;
372 }
373 }
374 }
375
376 return false;
377}
378
379/// ComplexPattern used on MipsInstrInfo
380/// Used on Mips Load/Store instructions
381bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
382 SDValue &Offset) const {
383 Base = Addr;
384 Offset = CurDAG->getTargetConstant(Val: 0, DL: SDLoc(Addr), VT: Addr.getValueType());
385 return true;
386}
387
388bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
389 SDValue &Offset) const {
390 return selectAddrRegImm(Addr, Base, Offset) ||
391 selectAddrDefault(Addr, Base, Offset);
392}
393
394bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base,
395 SDValue &Offset) const {
396 if (selectAddrFrameIndex(Addr, Base, Offset))
397 return true;
398
399 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 9))
400 return true;
401
402 return false;
403}
404
405/// Used on microMIPS LWC2, LDC2, SWC2 and SDC2 instructions (11-bit offset)
406bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base,
407 SDValue &Offset) const {
408 if (selectAddrFrameIndex(Addr, Base, Offset))
409 return true;
410
411 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 11))
412 return true;
413
414 return false;
415}
416
417/// Used on microMIPS Load/Store unaligned instructions (12-bit offset)
418bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base,
419 SDValue &Offset) const {
420 if (selectAddrFrameIndex(Addr, Base, Offset))
421 return true;
422
423 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 12))
424 return true;
425
426 return false;
427}
428
429bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base,
430 SDValue &Offset) const {
431 if (selectAddrFrameIndex(Addr, Base, Offset))
432 return true;
433
434 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 16))
435 return true;
436
437 return false;
438}
439
440bool MipsSEDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base,
441 SDValue &Offset) const {
442 return selectAddrRegImm11(Addr, Base, Offset) ||
443 selectAddrDefault(Addr, Base, Offset);
444}
445
446bool MipsSEDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base,
447 SDValue &Offset) const {
448 return selectAddrRegImm12(Addr, Base, Offset) ||
449 selectAddrDefault(Addr, Base, Offset);
450}
451
452bool MipsSEDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base,
453 SDValue &Offset) const {
454 return selectAddrRegImm16(Addr, Base, Offset) ||
455 selectAddrDefault(Addr, Base, Offset);
456}
457
458bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
459 SDValue &Offset) const {
460 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 7)) {
461 if (isa<FrameIndexSDNode>(Val: Base))
462 return false;
463
464 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val&: Offset)) {
465 unsigned CnstOff = CN->getZExtValue();
466 return (CnstOff == (CnstOff & 0x3c));
467 }
468
469 return false;
470 }
471
472 // For all other cases where "lw" would be selected, don't select "lw16"
473 // because it would result in additional instructions to prepare operands.
474 if (selectAddrRegImm(Addr, Base, Offset))
475 return false;
476
477 return selectAddrDefault(Addr, Base, Offset);
478}
479
480bool MipsSEDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base,
481 SDValue &Offset) const {
482
483 if (selectAddrFrameIndex(Addr, Base, Offset))
484 return true;
485
486 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 10))
487 return true;
488
489 return selectAddrDefault(Addr, Base, Offset);
490}
491
492bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,
493 SDValue &Offset) const {
494 if (selectAddrFrameIndex(Addr, Base, Offset))
495 return true;
496
497 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 10, ShiftAmount: 1))
498 return true;
499
500 return selectAddrDefault(Addr, Base, Offset);
501}
502
503bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,
504 SDValue &Offset) const {
505 if (selectAddrFrameIndex(Addr, Base, Offset))
506 return true;
507
508 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 10, ShiftAmount: 2))
509 return true;
510
511 return selectAddrDefault(Addr, Base, Offset);
512}
513
514bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,
515 SDValue &Offset) const {
516 if (selectAddrFrameIndex(Addr, Base, Offset))
517 return true;
518
519 if (selectAddrFrameIndexOffset(Addr, Base, Offset, OffsetBits: 10, ShiftAmount: 3))
520 return true;
521
522 return selectAddrDefault(Addr, Base, Offset);
523}
524
525// Select constant vector splats.
526//
527// Returns true and sets Imm if:
528// * MSA is enabled
529// * N is a ISD::BUILD_VECTOR representing a constant splat
530bool MipsSEDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
531 unsigned MinSizeInBits) const {
532 if (!Subtarget->hasMSA())
533 return false;
534
535 BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(Val: N);
536
537 if (!Node)
538 return false;
539
540 APInt SplatValue, SplatUndef;
541 unsigned SplatBitSize;
542 bool HasAnyUndefs;
543
544 if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
545 MinSplatBits: MinSizeInBits, isBigEndian: !Subtarget->isLittle()))
546 return false;
547
548 Imm = SplatValue;
549
550 return true;
551}
552
553// Select constant vector splats.
554//
555// In addition to the requirements of selectVSplat(), this function returns
556// true and sets Imm if:
557// * The splat value is the same width as the elements of the vector
558// * The splat value fits in an integer with the specified signed-ness and
559// width.
560//
561// This function looks through ISD::BITCAST nodes.
562// TODO: This might not be appropriate for big-endian MSA since BITCAST is
563// sometimes a shuffle in big-endian mode.
564//
565// It's worth noting that this function is not used as part of the selection
566// of ldi.[bhwd] since it does not permit using the wrong-typed ldi.[bhwd]
567// instruction to achieve the desired bit pattern. ldi.[bhwd] is selected in
568// MipsSEDAGToDAGISel::selectNode.
569bool MipsSEDAGToDAGISel::
570selectVSplatCommon(SDValue N, SDValue &Imm, bool Signed,
571 unsigned ImmBitSize) const {
572 APInt ImmValue;
573 EVT EltTy = N->getValueType(ResNo: 0).getVectorElementType();
574
575 if (N->getOpcode() == ISD::BITCAST)
576 N = N->getOperand(Num: 0);
577
578 if (selectVSplat(N: N.getNode(), Imm&: ImmValue, MinSizeInBits: EltTy.getSizeInBits()) &&
579 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
580
581 if (( Signed && ImmValue.isSignedIntN(N: ImmBitSize)) ||
582 (!Signed && ImmValue.isIntN(N: ImmBitSize))) {
583 Imm = CurDAG->getTargetConstant(Val: ImmValue, DL: SDLoc(N), VT: EltTy);
584 return true;
585 }
586 }
587
588 return false;
589}
590
591// Select constant vector splats whose value is a power of 2.
592//
593// In addition to the requirements of selectVSplat(), this function returns
594// true and sets Imm if:
595// * The splat value is the same width as the elements of the vector
596// * The splat value is a power of two.
597//
598// This function looks through ISD::BITCAST nodes.
599// TODO: This might not be appropriate for big-endian MSA since BITCAST is
600// sometimes a shuffle in big-endian mode.
601bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
602 APInt ImmValue;
603 EVT EltTy = N->getValueType(ResNo: 0).getVectorElementType();
604
605 if (N->getOpcode() == ISD::BITCAST)
606 N = N->getOperand(Num: 0);
607
608 if (selectVSplat(N: N.getNode(), Imm&: ImmValue, MinSizeInBits: EltTy.getSizeInBits()) &&
609 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
610 int32_t Log2 = ImmValue.exactLogBase2();
611
612 if (Log2 != -1) {
613 Imm = CurDAG->getTargetConstant(Val: Log2, DL: SDLoc(N), VT: EltTy);
614 return true;
615 }
616 }
617
618 return false;
619}
620
621// Select constant vector splats whose value only has a consecutive sequence
622// of left-most bits set (e.g. 0b11...1100...00).
623//
624// In addition to the requirements of selectVSplat(), this function returns
625// true and sets Imm if:
626// * The splat value is the same width as the elements of the vector
627// * The splat value is a consecutive sequence of left-most bits.
628//
629// This function looks through ISD::BITCAST nodes.
630// TODO: This might not be appropriate for big-endian MSA since BITCAST is
631// sometimes a shuffle in big-endian mode.
632bool MipsSEDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
633 APInt ImmValue;
634 EVT EltTy = N->getValueType(ResNo: 0).getVectorElementType();
635
636 if (N->getOpcode() == ISD::BITCAST)
637 N = N->getOperand(Num: 0);
638
639 if (selectVSplat(N: N.getNode(), Imm&: ImmValue, MinSizeInBits: EltTy.getSizeInBits()) &&
640 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
641 // Check if we have a leading one, then check if the whole value is a
642 // shifted mask.
643 if (ImmValue.isNegative() && ImmValue.isShiftedMask()) {
644 Imm = CurDAG->getTargetConstant(Val: ImmValue.popcount() - 1, DL: SDLoc(N), VT: EltTy);
645 return true;
646 }
647 }
648
649 return false;
650}
651
652// Select constant vector splats whose value only has a consecutive sequence
653// of right-most bits set (e.g. 0b00...0011...11).
654//
655// In addition to the requirements of selectVSplat(), this function returns
656// true and sets Imm if:
657// * The splat value is the same width as the elements of the vector
658// * The splat value is a consecutive sequence of right-most bits.
659//
660// This function looks through ISD::BITCAST nodes.
661// TODO: This might not be appropriate for big-endian MSA since BITCAST is
662// sometimes a shuffle in big-endian mode.
663bool MipsSEDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
664 APInt ImmValue;
665 EVT EltTy = N->getValueType(ResNo: 0).getVectorElementType();
666
667 if (N->getOpcode() == ISD::BITCAST)
668 N = N->getOperand(Num: 0);
669
670 if (selectVSplat(N: N.getNode(), Imm&: ImmValue, MinSizeInBits: EltTy.getSizeInBits()) &&
671 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
672 if (ImmValue.isMask()) {
673 Imm = CurDAG->getTargetConstant(Val: ImmValue.popcount() - 1, DL: SDLoc(N), VT: EltTy);
674 return true;
675 }
676 }
677
678 return false;
679}
680
681bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N,
682 SDValue &Imm) const {
683 APInt ImmValue;
684 EVT EltTy = N->getValueType(ResNo: 0).getVectorElementType();
685
686 if (N->getOpcode() == ISD::BITCAST)
687 N = N->getOperand(Num: 0);
688
689 if (selectVSplat(N: N.getNode(), Imm&: ImmValue, MinSizeInBits: EltTy.getSizeInBits()) &&
690 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
691 int32_t Log2 = (~ImmValue).exactLogBase2();
692
693 if (Log2 != -1) {
694 Imm = CurDAG->getTargetConstant(Val: Log2, DL: SDLoc(N), VT: EltTy);
695 return true;
696 }
697 }
698
699 return false;
700}
701
702// Select const vector splat of 1.
703bool MipsSEDAGToDAGISel::selectVSplatImmEq1(SDValue N) const {
704 APInt ImmValue;
705 EVT EltTy = N->getValueType(ResNo: 0).getVectorElementType();
706
707 if (N->getOpcode() == ISD::BITCAST)
708 N = N->getOperand(Num: 0);
709
710 return selectVSplat(N: N.getNode(), Imm&: ImmValue, MinSizeInBits: EltTy.getSizeInBits()) &&
711 ImmValue.getBitWidth() == EltTy.getSizeInBits() && ImmValue == 1;
712}
713
714bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
715 unsigned Opcode = Node->getOpcode();
716 SDLoc DL(Node);
717
718 ///
719 // Instruction Selection not handled by the auto-generated
720 // tablegen selection should be handled here.
721 ///
722 switch(Opcode) {
723 default: break;
724
725 case MipsISD::DOUBLE_SELECT_I:
726 case MipsISD::DOUBLE_SELECT_I64: {
727 MVT VT = Subtarget->isGP64bit() ? MVT::i64 : MVT::i32;
728 SDValue cond = Node->getOperand(Num: 0);
729 SDValue Hi1 = Node->getOperand(Num: 1);
730 SDValue Lo1 = Node->getOperand(Num: 2);
731 SDValue Hi2 = Node->getOperand(Num: 3);
732 SDValue Lo2 = Node->getOperand(Num: 4);
733
734 SDValue ops[] = {cond, Hi1, Lo1, Hi2, Lo2};
735 EVT NodeTys[] = {VT, VT};
736 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode: Subtarget->isGP64bit()
737 ? Mips::PseudoD_SELECT_I64
738 : Mips::PseudoD_SELECT_I,
739 dl: DL, ResultTys: NodeTys, Ops: ops));
740 return true;
741 }
742
743 case ISD::ADDE: {
744 selectAddE(Node, DL);
745 return true;
746 }
747
748 case ISD::ConstantFP: {
749 auto *CN = cast<ConstantFPSDNode>(Val: Node);
750 if (Node->getValueType(ResNo: 0) == MVT::f64 && CN->isPosZero()) {
751 if (Subtarget->isGP64bit()) {
752 SDValue Zero = CurDAG->getCopyFromReg(Chain: CurDAG->getEntryNode(), dl: DL,
753 Reg: Mips::R0_64, VT: MVT::i64);
754 ReplaceNode(F: Node,
755 T: CurDAG->getMachineNode(Opcode: Mips::DMTC1, dl: DL, VT: MVT::f64, Op1: Zero));
756 } else if (Subtarget->isFP64bit()) {
757 SDValue Zero = CurDAG->getCopyFromReg(Chain: CurDAG->getEntryNode(), dl: DL,
758 Reg: Mips::R0, VT: MVT::i32);
759 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode: Mips::BuildPairF64_64, dl: DL,
760 VT: MVT::f64, Op1: Zero, Op2: Zero));
761 } else {
762 SDValue Zero = CurDAG->getCopyFromReg(Chain: CurDAG->getEntryNode(), dl: DL,
763 Reg: Mips::R0, VT: MVT::i32);
764 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode: Mips::BuildPairF64, dl: DL,
765 VT: MVT::f64, Op1: Zero, Op2: Zero));
766 }
767 return true;
768 }
769 break;
770 }
771
772 case ISD::Constant: {
773 auto *CN = cast<ConstantSDNode>(Val: Node);
774 int64_t Imm = CN->getSExtValue();
775 unsigned Size = CN->getValueSizeInBits(ResNo: 0);
776
777 if (isInt<32>(x: Imm))
778 break;
779
780 MipsAnalyzeImmediate AnalyzeImm;
781
782 const MipsAnalyzeImmediate::InstSeq &Seq =
783 AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu: false);
784
785 MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
786 SDLoc DL(CN);
787 SDNode *RegOpnd;
788 SDValue ImmOpnd = CurDAG->getTargetConstant(Val: SignExtend64<16>(x: Inst->ImmOpnd),
789 DL, VT: MVT::i64);
790
791 // The first instruction can be a LUi which is different from other
792 // instructions (ADDiu, ORI and SLL) in that it does not have a register
793 // operand.
794 if (Inst->Opc == Mips::LUi64)
795 RegOpnd = CurDAG->getMachineNode(Opcode: Inst->Opc, dl: DL, VT: MVT::i64, Op1: ImmOpnd);
796 else
797 RegOpnd = CurDAG->getMachineNode(
798 Opcode: Inst->Opc, dl: DL, VT: MVT::i64, Op1: CurDAG->getRegister(Reg: Mips::R0_64, VT: MVT::i64),
799 Op2: ImmOpnd);
800
801 // The remaining instructions in the sequence are handled here.
802 for (++Inst; Inst != Seq.end(); ++Inst) {
803 ImmOpnd = CurDAG->getTargetConstant(Val: SignExtend64<16>(x: Inst->ImmOpnd), DL,
804 VT: MVT::i64);
805 RegOpnd = CurDAG->getMachineNode(Opcode: Inst->Opc, dl: DL, VT: MVT::i64,
806 Op1: SDValue(RegOpnd, 0), Op2: ImmOpnd);
807 }
808
809 ReplaceNode(F: Node, T: RegOpnd);
810 return true;
811 }
812
813 case ISD::INTRINSIC_W_CHAIN: {
814 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(Num: 1);
815 switch (IntrinsicOpcode) {
816 default:
817 break;
818
819 case Intrinsic::mips_cfcmsa: {
820 SDValue ChainIn = Node->getOperand(Num: 0);
821 SDValue RegIdx = Node->getOperand(Num: 2);
822 SDValue Reg = CurDAG->getCopyFromReg(Chain: ChainIn, dl: DL,
823 Reg: getMSACtrlReg(RegIdx), VT: MVT::i32);
824 ReplaceNode(F: Node, T: Reg.getNode());
825 return true;
826 }
827 case Intrinsic::mips_ldr_d:
828 case Intrinsic::mips_ldr_w: {
829 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D
830 : Mips::LDR_W;
831
832 SDLoc DL(Node);
833 assert(Node->getNumOperands() == 4 && "Unexpected number of operands.");
834 const SDValue &Chain = Node->getOperand(Num: 0);
835 const SDValue &Intrinsic = Node->getOperand(Num: 1);
836 const SDValue &Pointer = Node->getOperand(Num: 2);
837 const SDValue &Constant = Node->getOperand(Num: 3);
838
839 assert(Chain.getValueType() == MVT::Other);
840 (void)Intrinsic;
841 assert(Intrinsic.getOpcode() == ISD::TargetConstant &&
842 Constant.getOpcode() == ISD::Constant &&
843 "Invalid instruction operand.");
844
845 // Convert Constant to TargetConstant.
846 const ConstantInt *Val =
847 cast<ConstantSDNode>(Val: Constant)->getConstantIntValue();
848 SDValue Imm =
849 CurDAG->getTargetConstant(Val: *Val, DL, VT: Constant.getValueType());
850
851 SmallVector<SDValue, 3> Ops{Pointer, Imm, Chain};
852
853 assert(Node->getNumValues() == 2);
854 assert(Node->getValueType(0).is128BitVector());
855 assert(Node->getValueType(1) == MVT::Other);
856 SmallVector<EVT, 2> ResTys{Node->getValueType(ResNo: 0), Node->getValueType(ResNo: 1)};
857
858 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode: Op, dl: DL, ResultTys: ResTys, Ops));
859
860 return true;
861 }
862 }
863 break;
864 }
865
866 case ISD::INTRINSIC_WO_CHAIN: {
867 switch (Node->getConstantOperandVal(Num: 0)) {
868 default:
869 break;
870
871 case Intrinsic::mips_move_v:
872 // Like an assignment but will always produce a move.v even if
873 // unnecessary.
874 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode: Mips::MOVE_V, dl: DL,
875 VT: Node->getValueType(ResNo: 0),
876 Op1: Node->getOperand(Num: 1)));
877 return true;
878 }
879 break;
880 }
881
882 case ISD::INTRINSIC_VOID: {
883 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(Num: 1);
884 switch (IntrinsicOpcode) {
885 default:
886 break;
887
888 case Intrinsic::mips_ctcmsa: {
889 SDValue ChainIn = Node->getOperand(Num: 0);
890 SDValue RegIdx = Node->getOperand(Num: 2);
891 SDValue Value = Node->getOperand(Num: 3);
892 SDValue ChainOut = CurDAG->getCopyToReg(Chain: ChainIn, dl: DL,
893 Reg: getMSACtrlReg(RegIdx), N: Value);
894 ReplaceNode(F: Node, T: ChainOut.getNode());
895 return true;
896 }
897 case Intrinsic::mips_str_d:
898 case Intrinsic::mips_str_w: {
899 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D
900 : Mips::STR_W;
901
902 SDLoc DL(Node);
903 assert(Node->getNumOperands() == 5 && "Unexpected number of operands.");
904 const SDValue &Chain = Node->getOperand(Num: 0);
905 const SDValue &Intrinsic = Node->getOperand(Num: 1);
906 const SDValue &Vec = Node->getOperand(Num: 2);
907 const SDValue &Pointer = Node->getOperand(Num: 3);
908 const SDValue &Constant = Node->getOperand(Num: 4);
909
910 assert(Chain.getValueType() == MVT::Other);
911 (void)Intrinsic;
912 assert(Intrinsic.getOpcode() == ISD::TargetConstant &&
913 Constant.getOpcode() == ISD::Constant &&
914 "Invalid instruction operand.");
915
916 // Convert Constant to TargetConstant.
917 const ConstantInt *Val =
918 cast<ConstantSDNode>(Val: Constant)->getConstantIntValue();
919 SDValue Imm =
920 CurDAG->getTargetConstant(Val: *Val, DL, VT: Constant.getValueType());
921
922 SmallVector<SDValue, 4> Ops{Vec, Pointer, Imm, Chain};
923
924 assert(Node->getNumValues() == 1);
925 assert(Node->getValueType(0) == MVT::Other);
926 SmallVector<EVT, 1> ResTys{Node->getValueType(ResNo: 0)};
927
928 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode: Op, dl: DL, ResultTys: ResTys, Ops));
929 return true;
930 }
931 }
932 break;
933 }
934
935 case MipsISD::FAbs: {
936 MVT ResTy = Node->getSimpleValueType(ResNo: 0);
937 assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&
938 "Unsupported float type!");
939 unsigned Opc = 0;
940 if (ResTy == MVT::f64)
941 Opc = (Subtarget->isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32);
942 else
943 Opc = Mips::FABS_S;
944
945 if (Subtarget->inMicroMipsMode()) {
946 switch (Opc) {
947 case Mips::FABS_D64:
948 Opc = Mips::FABS_D64_MM;
949 break;
950 case Mips::FABS_D32:
951 Opc = Mips::FABS_D32_MM;
952 break;
953 case Mips::FABS_S:
954 Opc = Mips::FABS_S_MM;
955 break;
956 default:
957 llvm_unreachable("Unknown opcode for MIPS floating point abs!");
958 }
959 }
960
961 ReplaceNode(F: Node,
962 T: CurDAG->getMachineNode(Opcode: Opc, dl: DL, VT: ResTy, Op1: Node->getOperand(Num: 0)));
963
964 return true;
965 }
966
967 // Manually match MipsISD::Ins nodes to get the correct instruction. It has
968 // to be done in this fashion so that we respect the differences between
969 // dins and dinsm, as the difference is that the size operand has the range
970 // 0 < size <= 32 for dins while dinsm has the range 2 <= size <= 64 which
971 // means SelectionDAGISel would have to test all the operands at once to
972 // match the instruction.
973 case MipsISD::Ins: {
974
975 // Validating the node operands.
976 if (Node->getValueType(ResNo: 0) != MVT::i32 && Node->getValueType(ResNo: 0) != MVT::i64)
977 return false;
978
979 if (Node->getNumOperands() != 4)
980 return false;
981
982 if (Node->getOperand(Num: 1)->getOpcode() != ISD::Constant ||
983 Node->getOperand(Num: 2)->getOpcode() != ISD::Constant)
984 return false;
985
986 MVT ResTy = Node->getSimpleValueType(ResNo: 0);
987 uint64_t Pos = Node->getConstantOperandVal(Num: 1);
988 uint64_t Size = Node->getConstantOperandVal(Num: 2);
989
990 // Size has to be >0 for 'ins', 'dins' and 'dinsu'.
991 if (!Size)
992 return false;
993
994 if (Pos + Size > 64)
995 return false;
996
997 if (ResTy != MVT::i32 && ResTy != MVT::i64)
998 return false;
999
1000 unsigned Opcode = 0;
1001 if (ResTy == MVT::i32) {
1002 if (Pos + Size <= 32)
1003 Opcode = Mips::INS;
1004 } else {
1005 if (Pos + Size <= 32)
1006 Opcode = Mips::DINS;
1007 else if (Pos < 32 && 1 < Size)
1008 Opcode = Mips::DINSM;
1009 else
1010 Opcode = Mips::DINSU;
1011 }
1012
1013 if (Opcode) {
1014 SDValue Ops[4] = {
1015 Node->getOperand(Num: 0), CurDAG->getTargetConstant(Val: Pos, DL, VT: MVT::i32),
1016 CurDAG->getTargetConstant(Val: Size, DL, VT: MVT::i32), Node->getOperand(Num: 3)};
1017
1018 ReplaceNode(F: Node, T: CurDAG->getMachineNode(Opcode, dl: DL, VT: ResTy, Ops));
1019 return true;
1020 }
1021
1022 return false;
1023 }
1024
1025 case MipsISD::ThreadPointer: {
1026 EVT PtrVT = getTargetLowering()->getPointerTy(DL: CurDAG->getDataLayout());
1027 unsigned RdhwrOpc, DestReg;
1028
1029 if (PtrVT == MVT::i32) {
1030 RdhwrOpc = Mips::RDHWR;
1031 DestReg = Mips::R3;
1032 } else {
1033 RdhwrOpc = Mips::RDHWR64;
1034 DestReg = Mips::R3_64;
1035 }
1036
1037 SDNode *Rdhwr =
1038 CurDAG->getMachineNode(Opcode: RdhwrOpc, dl: DL, VT1: Node->getValueType(ResNo: 0), VT2: MVT::Glue,
1039 Op1: CurDAG->getRegister(Reg: Mips::HWR29, VT: MVT::i32),
1040 Op2: CurDAG->getTargetConstant(Val: 0, DL, VT: MVT::i32));
1041 SDValue Chain = CurDAG->getCopyToReg(Chain: CurDAG->getEntryNode(), dl: DL, Reg: DestReg,
1042 N: SDValue(Rdhwr, 0), Glue: SDValue(Rdhwr, 1));
1043 SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl: DL, Reg: DestReg, VT: PtrVT,
1044 Glue: Chain.getValue(R: 1));
1045 ReplaceNode(F: Node, T: ResNode.getNode());
1046 return true;
1047 }
1048
1049 case ISD::BUILD_VECTOR: {
1050 // Select appropriate ldi.[bhwd] instructions for constant splats of
1051 // 128-bit when MSA is enabled. Fixup any register class mismatches that
1052 // occur as a result.
1053 //
1054 // This allows the compiler to use a wider range of immediates than would
1055 // otherwise be allowed. If, for example, v4i32 could only use ldi.h then
1056 // it would not be possible to load { 0x01010101, 0x01010101, 0x01010101,
1057 // 0x01010101 } without using a constant pool. This would be sub-optimal
1058 // when // 'ldi.b wd, 1' is capable of producing that bit-pattern in the
1059 // same set/ of registers. Similarly, ldi.h isn't capable of producing {
1060 // 0x00000000, 0x00000001, 0x00000000, 0x00000001 } but 'ldi.d wd, 1' can.
1061
1062 const MipsABIInfo &ABI = Subtarget->getABI();
1063
1064 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Val: Node);
1065 APInt SplatValue, SplatUndef;
1066 unsigned SplatBitSize;
1067 bool HasAnyUndefs;
1068 unsigned LdiOp;
1069 EVT ResVecTy = BVN->getValueType(ResNo: 0);
1070 EVT ViaVecTy;
1071
1072 if (!Subtarget->hasMSA() || !BVN->getValueType(ResNo: 0).is128BitVector())
1073 return false;
1074
1075 if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
1076 HasAnyUndefs, MinSplatBits: 8,
1077 isBigEndian: !Subtarget->isLittle()))
1078 return false;
1079
1080 switch (SplatBitSize) {
1081 default:
1082 return false;
1083 case 8:
1084 LdiOp = Mips::LDI_B;
1085 ViaVecTy = MVT::v16i8;
1086 break;
1087 case 16:
1088 LdiOp = Mips::LDI_H;
1089 ViaVecTy = MVT::v8i16;
1090 break;
1091 case 32:
1092 LdiOp = Mips::LDI_W;
1093 ViaVecTy = MVT::v4i32;
1094 break;
1095 case 64:
1096 LdiOp = Mips::LDI_D;
1097 ViaVecTy = MVT::v2i64;
1098 break;
1099 }
1100
1101 SDNode *Res = nullptr;
1102
1103 // If we have a signed 10 bit integer, we can splat it directly.
1104 //
1105 // If we have something bigger we can synthesize the value into a GPR and
1106 // splat from there.
1107 if (SplatValue.isSignedIntN(N: 10)) {
1108 SDValue Imm = CurDAG->getTargetConstant(Val: SplatValue, DL,
1109 VT: ViaVecTy.getVectorElementType());
1110
1111 Res = CurDAG->getMachineNode(Opcode: LdiOp, dl: DL, VT: ViaVecTy, Op1: Imm);
1112 } else if (SplatValue.isSignedIntN(N: 16) &&
1113 ((ABI.IsO32() && SplatBitSize < 64) ||
1114 (ABI.IsN32() || ABI.IsN64()))) {
1115 // Only handle signed 16 bit values when the element size is GPR width.
1116 // MIPS64 can handle all the cases but MIPS32 would need to handle
1117 // negative cases specifically here. Instead, handle those cases as
1118 // 64bit values.
1119
1120 bool Is32BitSplat = ABI.IsO32() || SplatBitSize < 64;
1121 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;
1122 const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64;
1123 SDValue ZeroVal =
1124 CurDAG->getRegister(Reg: Is32BitSplat ? Mips::R0 : Mips::R0_64, VT: SplatMVT);
1125
1126 const unsigned FILLOp =
1127 SplatBitSize == 16
1128 ? Mips::FILL_H
1129 : (SplatBitSize == 32 ? Mips::FILL_W
1130 : (SplatBitSize == 64 ? Mips::FILL_D : 0));
1131
1132 assert(FILLOp != 0 && "Unknown FILL Op for splat synthesis!");
1133 assert((!ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&
1134 "Attempting to use fill.d on MIPS32!");
1135
1136 const unsigned Lo = SplatValue.getLoBits(numBits: 16).getZExtValue();
1137 SDValue LoVal = CurDAG->getTargetConstant(Val: Lo, DL, VT: SplatMVT);
1138
1139 Res = CurDAG->getMachineNode(Opcode: ADDiuOp, dl: DL, VT: SplatMVT, Op1: ZeroVal, Op2: LoVal);
1140 Res = CurDAG->getMachineNode(Opcode: FILLOp, dl: DL, VT: ViaVecTy, Op1: SDValue(Res, 0));
1141
1142 } else if (SplatValue.isSignedIntN(N: 32) && SplatBitSize == 32) {
1143 // Only handle the cases where the splat size agrees with the size
1144 // of the SplatValue here.
1145 const unsigned Lo = SplatValue.getLoBits(numBits: 16).getZExtValue();
1146 const unsigned Hi = SplatValue.lshr(shiftAmt: 16).getLoBits(numBits: 16).getZExtValue();
1147 SDValue ZeroVal = CurDAG->getRegister(Reg: Mips::R0, VT: MVT::i32);
1148
1149 SDValue LoVal = CurDAG->getTargetConstant(Val: Lo, DL, VT: MVT::i32);
1150 SDValue HiVal = CurDAG->getTargetConstant(Val: Hi, DL, VT: MVT::i32);
1151
1152 if (Hi)
1153 Res = CurDAG->getMachineNode(Opcode: Mips::LUi, dl: DL, VT: MVT::i32, Op1: HiVal);
1154
1155 if (Lo)
1156 Res = CurDAG->getMachineNode(Opcode: Mips::ORi, dl: DL, VT: MVT::i32,
1157 Op1: Hi ? SDValue(Res, 0) : ZeroVal, Op2: LoVal);
1158
1159 assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!");
1160 Res =
1161 CurDAG->getMachineNode(Opcode: Mips::FILL_W, dl: DL, VT: MVT::v4i32, Op1: SDValue(Res, 0));
1162
1163 } else if (SplatValue.isSignedIntN(N: 32) && SplatBitSize == 64 &&
1164 (ABI.IsN32() || ABI.IsN64())) {
1165 // N32 and N64 can perform some tricks that O32 can't for signed 32 bit
1166 // integers due to having 64bit registers. lui will cause the necessary
1167 // zero/sign extension.
1168 const unsigned Lo = SplatValue.getLoBits(numBits: 16).getZExtValue();
1169 const unsigned Hi = SplatValue.lshr(shiftAmt: 16).getLoBits(numBits: 16).getZExtValue();
1170 SDValue ZeroVal = CurDAG->getRegister(Reg: Mips::R0, VT: MVT::i32);
1171
1172 SDValue LoVal = CurDAG->getTargetConstant(Val: Lo, DL, VT: MVT::i32);
1173 SDValue HiVal = CurDAG->getTargetConstant(Val: Hi, DL, VT: MVT::i32);
1174
1175 if (Hi)
1176 Res = CurDAG->getMachineNode(Opcode: Mips::LUi, dl: DL, VT: MVT::i32, Op1: HiVal);
1177
1178 if (Lo)
1179 Res = CurDAG->getMachineNode(Opcode: Mips::ORi, dl: DL, VT: MVT::i32,
1180 Op1: Hi ? SDValue(Res, 0) : ZeroVal, Op2: LoVal);
1181
1182 Res = CurDAG->getMachineNode(
1183 Opcode: Mips::SUBREG_TO_REG, dl: DL, VT: MVT::i64, Op1: SDValue(Res, 0),
1184 Op2: CurDAG->getTargetConstant(Val: Mips::sub_32, DL, VT: MVT::i64));
1185
1186 Res =
1187 CurDAG->getMachineNode(Opcode: Mips::FILL_D, dl: DL, VT: MVT::v2i64, Op1: SDValue(Res, 0));
1188
1189 } else if (SplatValue.isSignedIntN(N: 64)) {
1190 // If we have a 64 bit Splat value, we perform a similar sequence to the
1191 // above:
1192 //
1193 // MIPS32: MIPS64:
1194 // lui $res, %highest(val) lui $res, %highest(val)
1195 // ori $res, $res, %higher(val) ori $res, $res, %higher(val)
1196 // lui $res2, %hi(val) lui $res2, %hi(val)
1197 // ori $res2, %res2, %lo(val) ori $res2, %res2, %lo(val)
1198 // $res3 = fill $res2 dinsu $res, $res2, 0, 32
1199 // $res4 = insert.w $res3[1], $res fill.d $res
1200 // splat.d $res4, 0
1201 //
1202 // The ability to use dinsu is guaranteed as MSA requires MIPSR5.
1203 // This saves having to materialize the value by shifts and ors.
1204 //
1205 // FIXME: Implement the preferred sequence for MIPS64R6:
1206 //
1207 // MIPS64R6:
1208 // ori $res, $zero, %lo(val)
1209 // daui $res, $res, %hi(val)
1210 // dahi $res, $res, %higher(val)
1211 // dati $res, $res, %highest(cal)
1212 // fill.d $res
1213 //
1214
1215 const unsigned Lo = SplatValue.getLoBits(numBits: 16).getZExtValue();
1216 const unsigned Hi = SplatValue.lshr(shiftAmt: 16).getLoBits(numBits: 16).getZExtValue();
1217 const unsigned Higher = SplatValue.lshr(shiftAmt: 32).getLoBits(numBits: 16).getZExtValue();
1218 const unsigned Highest = SplatValue.lshr(shiftAmt: 48).getLoBits(numBits: 16).getZExtValue();
1219
1220 SDValue LoVal = CurDAG->getTargetConstant(Val: Lo, DL, VT: MVT::i32);
1221 SDValue HiVal = CurDAG->getTargetConstant(Val: Hi, DL, VT: MVT::i32);
1222 SDValue HigherVal = CurDAG->getTargetConstant(Val: Higher, DL, VT: MVT::i32);
1223 SDValue HighestVal = CurDAG->getTargetConstant(Val: Highest, DL, VT: MVT::i32);
1224 SDValue ZeroVal = CurDAG->getRegister(Reg: Mips::R0, VT: MVT::i32);
1225
1226 // Independent of whether we're targeting MIPS64 or not, the basic
1227 // operations are the same. Also, directly use the $zero register if
1228 // the 16 bit chunk is zero.
1229 //
1230 // For optimization purposes we always synthesize the splat value as
1231 // an i32 value, then if we're targetting MIPS64, use SUBREG_TO_REG
1232 // just before combining the values with dinsu to produce an i64. This
1233 // enables SelectionDAG to aggressively share components of splat values
1234 // where possible.
1235 //
1236 // FIXME: This is the general constant synthesis problem. This code
1237 // should be factored out into a class shared between all the
1238 // classes that need it. Specifically, for a splat size of 64
1239 // bits that's a negative number we can do better than LUi/ORi
1240 // for the upper 32bits.
1241
1242 if (Hi)
1243 Res = CurDAG->getMachineNode(Opcode: Mips::LUi, dl: DL, VT: MVT::i32, Op1: HiVal);
1244
1245 if (Lo)
1246 Res = CurDAG->getMachineNode(Opcode: Mips::ORi, dl: DL, VT: MVT::i32,
1247 Op1: Hi ? SDValue(Res, 0) : ZeroVal, Op2: LoVal);
1248
1249 SDNode *HiRes;
1250 if (Highest)
1251 HiRes = CurDAG->getMachineNode(Opcode: Mips::LUi, dl: DL, VT: MVT::i32, Op1: HighestVal);
1252
1253 if (Higher)
1254 HiRes = CurDAG->getMachineNode(Opcode: Mips::ORi, dl: DL, VT: MVT::i32,
1255 Op1: Highest ? SDValue(HiRes, 0) : ZeroVal,
1256 Op2: HigherVal);
1257
1258
1259 if (ABI.IsO32()) {
1260 Res = CurDAG->getMachineNode(Opcode: Mips::FILL_W, dl: DL, VT: MVT::v4i32,
1261 Op1: (Hi || Lo) ? SDValue(Res, 0) : ZeroVal);
1262
1263 Res = CurDAG->getMachineNode(
1264 Opcode: Mips::INSERT_W, dl: DL, VT: MVT::v4i32, Op1: SDValue(Res, 0),
1265 Op2: (Highest || Higher) ? SDValue(HiRes, 0) : ZeroVal,
1266 Op3: CurDAG->getTargetConstant(Val: 1, DL, VT: MVT::i32));
1267
1268 const TargetLowering *TLI = getTargetLowering();
1269 const TargetRegisterClass *RC =
1270 TLI->getRegClassFor(VT: ViaVecTy.getSimpleVT());
1271
1272 Res = CurDAG->getMachineNode(
1273 Opcode: Mips::COPY_TO_REGCLASS, dl: DL, VT: ViaVecTy, Op1: SDValue(Res, 0),
1274 Op2: CurDAG->getTargetConstant(Val: RC->getID(), DL, VT: MVT::i32));
1275
1276 Res = CurDAG->getMachineNode(
1277 Opcode: Mips::SPLATI_D, dl: DL, VT: MVT::v2i64, Op1: SDValue(Res, 0),
1278 Op2: CurDAG->getTargetConstant(Val: 0, DL, VT: MVT::i32));
1279 } else if (ABI.IsN64() || ABI.IsN32()) {
1280
1281 SDValue Zero64Val = CurDAG->getRegister(Reg: Mips::R0_64, VT: MVT::i64);
1282 const bool HiResNonZero = Highest || Higher;
1283 const bool ResNonZero = Hi || Lo;
1284
1285 if (HiResNonZero)
1286 HiRes = CurDAG->getMachineNode(
1287 Opcode: Mips::SUBREG_TO_REG, dl: DL, VT: MVT::i64, Op1: SDValue(HiRes, 0),
1288 Op2: CurDAG->getTargetConstant(Val: Mips::sub_32, DL, VT: MVT::i64));
1289
1290 if (ResNonZero)
1291 Res = CurDAG->getMachineNode(
1292 Opcode: Mips::SUBREG_TO_REG, dl: DL, VT: MVT::i64, Op1: SDValue(Res, 0),
1293 Op2: CurDAG->getTargetConstant(Val: Mips::sub_32, DL, VT: MVT::i64));
1294
1295 // We have 3 cases:
1296 // The HiRes is nonzero but Res is $zero => dsll32 HiRes, 0
1297 // The Res is nonzero but HiRes is $zero => dinsu Res, $zero, 32, 32
1298 // Both are non zero => dinsu Res, HiRes, 32, 32
1299 //
1300 // The obvious "missing" case is when both are zero, but that case is
1301 // handled by the ldi case.
1302 if (ResNonZero) {
1303 IntegerType *Int32Ty =
1304 IntegerType::get(C&: MF->getFunction().getContext(), NumBits: 32);
1305 const ConstantInt *Const32 = ConstantInt::get(Ty: Int32Ty, V: 32);
1306 SDValue Ops[4] = {HiResNonZero ? SDValue(HiRes, 0) : Zero64Val,
1307 CurDAG->getConstant(Val: *Const32, DL, VT: MVT::i32),
1308 CurDAG->getConstant(Val: *Const32, DL, VT: MVT::i32),
1309 SDValue(Res, 0)};
1310
1311 Res = CurDAG->getMachineNode(Opcode: Mips::DINSU, dl: DL, VT: MVT::i64, Ops);
1312 } else if (HiResNonZero) {
1313 Res = CurDAG->getMachineNode(
1314 Opcode: Mips::DSLL32, dl: DL, VT: MVT::i64, Op1: SDValue(HiRes, 0),
1315 Op2: CurDAG->getTargetConstant(Val: 0, DL, VT: MVT::i32));
1316 } else
1317 llvm_unreachable(
1318 "Zero splat value handled by non-zero 64bit splat synthesis!");
1319
1320 Res = CurDAG->getMachineNode(Opcode: Mips::FILL_D, dl: DL, VT: MVT::v2i64,
1321 Op1: SDValue(Res, 0));
1322 } else
1323 llvm_unreachable("Unknown ABI in MipsISelDAGToDAG!");
1324
1325 } else
1326 return false;
1327
1328 if (ResVecTy != ViaVecTy) {
1329 // If LdiOp is writing to a different register class to ResVecTy, then
1330 // fix it up here. This COPY_TO_REGCLASS should never cause a move.v
1331 // since the source and destination register sets contain the same
1332 // registers.
1333 const TargetLowering *TLI = getTargetLowering();
1334 MVT ResVecTySimple = ResVecTy.getSimpleVT();
1335 const TargetRegisterClass *RC = TLI->getRegClassFor(VT: ResVecTySimple);
1336 Res = CurDAG->getMachineNode(Opcode: Mips::COPY_TO_REGCLASS, dl: DL,
1337 VT: ResVecTy, Op1: SDValue(Res, 0),
1338 Op2: CurDAG->getTargetConstant(Val: RC->getID(), DL,
1339 VT: MVT::i32));
1340 }
1341
1342 ReplaceNode(F: Node, T: Res);
1343 return true;
1344 }
1345
1346 }
1347
1348 return false;
1349}
1350
1351bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand(
1352 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
1353 std::vector<SDValue> &OutOps) {
1354 SDValue Base, Offset;
1355
1356 switch(ConstraintID) {
1357 default:
1358 llvm_unreachable("Unexpected asm memory constraint");
1359 // All memory constraints can at least accept raw pointers.
1360 case InlineAsm::ConstraintCode::m:
1361 case InlineAsm::ConstraintCode::o:
1362 if (selectAddrRegImm16(Addr: Op, Base, Offset)) {
1363 OutOps.push_back(x: Base);
1364 OutOps.push_back(x: Offset);
1365 return false;
1366 }
1367 OutOps.push_back(x: Op);
1368 OutOps.push_back(x: CurDAG->getTargetConstant(Val: 0, DL: SDLoc(Op), VT: MVT::i32));
1369 return false;
1370 case InlineAsm::ConstraintCode::R:
1371 // The 'R' constraint is supposed to be much more complicated than this.
1372 // However, it's becoming less useful due to architectural changes and
1373 // ought to be replaced by other constraints such as 'ZC'.
1374 // For now, support 9-bit signed offsets which is supportable by all
1375 // subtargets for all instructions.
1376 if (selectAddrRegImm9(Addr: Op, Base, Offset)) {
1377 OutOps.push_back(x: Base);
1378 OutOps.push_back(x: Offset);
1379 return false;
1380 }
1381 OutOps.push_back(x: Op);
1382 OutOps.push_back(x: CurDAG->getTargetConstant(Val: 0, DL: SDLoc(Op), VT: MVT::i32));
1383 return false;
1384 case InlineAsm::ConstraintCode::ZC:
1385 // ZC matches whatever the pref, ll, and sc instructions can handle for the
1386 // given subtarget.
1387 if (Subtarget->inMicroMipsMode()) {
1388 // On microMIPS, they can handle 12-bit offsets.
1389 if (selectAddrRegImm12(Addr: Op, Base, Offset)) {
1390 OutOps.push_back(x: Base);
1391 OutOps.push_back(x: Offset);
1392 return false;
1393 }
1394 } else if (Subtarget->hasMips32r6()) {
1395 // On MIPS32r6/MIPS64r6, they can only handle 9-bit offsets.
1396 if (selectAddrRegImm9(Addr: Op, Base, Offset)) {
1397 OutOps.push_back(x: Base);
1398 OutOps.push_back(x: Offset);
1399 return false;
1400 }
1401 } else if (selectAddrRegImm16(Addr: Op, Base, Offset)) {
1402 // Prior to MIPS32r6/MIPS64r6, they can handle 16-bit offsets.
1403 OutOps.push_back(x: Base);
1404 OutOps.push_back(x: Offset);
1405 return false;
1406 }
1407 // In all cases, 0-bit offsets are acceptable.
1408 OutOps.push_back(x: Op);
1409 OutOps.push_back(x: CurDAG->getTargetConstant(Val: 0, DL: SDLoc(Op), VT: MVT::i32));
1410 return false;
1411 }
1412 return true;
1413}
1414
1415MipsSEDAGToDAGISelLegacy::MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM,
1416 CodeGenOptLevel OL)
1417 : MipsDAGToDAGISelLegacy(std::make_unique<MipsSEDAGToDAGISel>(args&: TM, args&: OL)) {}
1418
1419FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM,
1420 CodeGenOptLevel OptLevel) {
1421 return new MipsSEDAGToDAGISelLegacy(TM, OptLevel);
1422}
1423