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