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