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