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"
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
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 = RegIdx->getAsZExtVal();
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 InGlue = Node->getOperand(2);
208 unsigned Opc = InGlue.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, InGlue};
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
234 SDValue CstOne = CurDAG->getTargetConstant(1, DL, MVT::i32);
235
236 SDValue OuFlag = CurDAG->getTargetConstant(20, DL, MVT::i32);
237
238 SDNode *DSPCtrlField = CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32,
239 MVT::Glue, CstOne, InGlue);
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
673 Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), EltTy);
674 return true;
675 }
676 }
677
678 return false;
679}
680
681// Select constant vector splats whose value only has a consecutive sequence
682// of right-most bits set (e.g. 0b00...0011...11).
683//
684// In addition to the requirements of selectVSplat(), this function returns
685// true and sets Imm if:
686// * The splat value is the same width as the elements of the vector
687// * The splat value is a consecutive sequence of right-most bits.
688//
689// This function looks through ISD::BITCAST nodes.
690// TODO: This might not be appropriate for big-endian MSA since BITCAST is
691// sometimes a shuffle in big-endian mode.
692bool MipsSEDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
693 APInt ImmValue;
694 EVT EltTy = N->getValueType(0).getVectorElementType();
695
696 if (N->getOpcode() == ISD::BITCAST)
697 N = N->getOperand(0);
698
699 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
700 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
701 // Extract the run of set bits starting with bit zero, and test that the
702 // result is the same as the original value
703 if (ImmValue == (ImmValue & ~(ImmValue + 1))) {
704 Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), EltTy);
705 return true;
706 }
707 }
708
709 return false;
710}
711
712bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N,
713 SDValue &Imm) const {
714 APInt ImmValue;
715 EVT EltTy = N->getValueType(0).getVectorElementType();
716
717 if (N->getOpcode() == ISD::BITCAST)
718 N = N->getOperand(0);
719
720 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
721 ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
722 int32_t Log2 = (~ImmValue).exactLogBase2();
723
724 if (Log2 != -1) {
725 Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);
726 return true;
727 }
728 }
729
730 return false;
731}
732
733bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
734 unsigned Opcode = Node->getOpcode();
735 SDLoc DL(Node);
736
737 ///
738 // Instruction Selection not handled by the auto-generated
739 // tablegen selection should be handled here.
740 ///
741 switch(Opcode) {
742 default: break;
743
746 MVT VT = Subtarget->isGP64bit() ? MVT::i64 : MVT::i32;
747 SDValue cond = Node->getOperand(0);
748 SDValue Hi1 = Node->getOperand(1);
749 SDValue Lo1 = Node->getOperand(2);
750 SDValue Hi2 = Node->getOperand(3);
751 SDValue Lo2 = Node->getOperand(4);
752
753 SDValue ops[] = {cond, Hi1, Lo1, Hi2, Lo2};
754 EVT NodeTys[] = {VT, VT};
756 ? Mips::PseudoD_SELECT_I64
757 : Mips::PseudoD_SELECT_I,
758 DL, NodeTys, ops));
759 return true;
760 }
761
762 case ISD::ADDE: {
763 selectAddE(Node, DL);
764 return true;
765 }
766
767 case ISD::ConstantFP: {
768 auto *CN = cast<ConstantFPSDNode>(Node);
769 if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
770 if (Subtarget->isGP64bit()) {
772 Mips::ZERO_64, MVT::i64);
774 CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero));
775 } else if (Subtarget->isFP64bit()) {
777 Mips::ZERO, MVT::i32);
778 ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64_64, DL,
779 MVT::f64, Zero, Zero));
780 } else {
782 Mips::ZERO, MVT::i32);
783 ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64, DL,
784 MVT::f64, Zero, Zero));
785 }
786 return true;
787 }
788 break;
789 }
790
791 case ISD::Constant: {
792 auto *CN = cast<ConstantSDNode>(Node);
793 int64_t Imm = CN->getSExtValue();
794 unsigned Size = CN->getValueSizeInBits(0);
795
796 if (isInt<32>(Imm))
797 break;
798
799 MipsAnalyzeImmediate AnalyzeImm;
800
802 AnalyzeImm.Analyze(Imm, Size, false);
803
805 SDLoc DL(CN);
806 SDNode *RegOpnd;
807 SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
808 DL, MVT::i64);
809
810 // The first instruction can be a LUi which is different from other
811 // instructions (ADDiu, ORI and SLL) in that it does not have a register
812 // operand.
813 if (Inst->Opc == Mips::LUi64)
814 RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
815 else
816 RegOpnd =
817 CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
818 CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
819 ImmOpnd);
820
821 // The remaining instructions in the sequence are handled here.
822 for (++Inst; Inst != Seq.end(); ++Inst) {
823 ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), DL,
824 MVT::i64);
825 RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
826 SDValue(RegOpnd, 0), ImmOpnd);
827 }
828
829 ReplaceNode(Node, RegOpnd);
830 return true;
831 }
832
834 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(1);
835 switch (IntrinsicOpcode) {
836 default:
837 break;
838
839 case Intrinsic::mips_cfcmsa: {
840 SDValue ChainIn = Node->getOperand(0);
841 SDValue RegIdx = Node->getOperand(2);
842 SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL,
843 getMSACtrlReg(RegIdx), MVT::i32);
844 ReplaceNode(Node, Reg.getNode());
845 return true;
846 }
847 case Intrinsic::mips_ldr_d:
848 case Intrinsic::mips_ldr_w: {
849 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D
850 : Mips::LDR_W;
851
852 SDLoc DL(Node);
853 assert(Node->getNumOperands() == 4 && "Unexpected number of operands.");
854 const SDValue &Chain = Node->getOperand(0);
855 const SDValue &Intrinsic = Node->getOperand(1);
856 const SDValue &Pointer = Node->getOperand(2);
857 const SDValue &Constant = Node->getOperand(3);
858
859 assert(Chain.getValueType() == MVT::Other);
860 (void)Intrinsic;
861 assert(Intrinsic.getOpcode() == ISD::TargetConstant &&
862 Constant.getOpcode() == ISD::Constant &&
863 "Invalid instruction operand.");
864
865 // Convert Constant to TargetConstant.
866 const ConstantInt *Val =
867 cast<ConstantSDNode>(Constant)->getConstantIntValue();
868 SDValue Imm =
869 CurDAG->getTargetConstant(*Val, DL, Constant.getValueType());
870
872
873 assert(Node->getNumValues() == 2);
874 assert(Node->getValueType(0).is128BitVector());
875 assert(Node->getValueType(1) == MVT::Other);
876 SmallVector<EVT, 2> ResTys{Node->getValueType(0), Node->getValueType(1)};
877
878 ReplaceNode(Node, CurDAG->getMachineNode(Op, DL, ResTys, Ops));
879
880 return true;
881 }
882 }
883 break;
884 }
885
887 switch (Node->getConstantOperandVal(0)) {
888 default:
889 break;
890
891 case Intrinsic::mips_move_v:
892 // Like an assignment but will always produce a move.v even if
893 // unnecessary.
894 ReplaceNode(Node, CurDAG->getMachineNode(Mips::MOVE_V, DL,
895 Node->getValueType(0),
896 Node->getOperand(1)));
897 return true;
898 }
899 break;
900 }
901
902 case ISD::INTRINSIC_VOID: {
903 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(1);
904 switch (IntrinsicOpcode) {
905 default:
906 break;
907
908 case Intrinsic::mips_ctcmsa: {
909 SDValue ChainIn = Node->getOperand(0);
910 SDValue RegIdx = Node->getOperand(2);
911 SDValue Value = Node->getOperand(3);
912 SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL,
913 getMSACtrlReg(RegIdx), Value);
914 ReplaceNode(Node, ChainOut.getNode());
915 return true;
916 }
917 case Intrinsic::mips_str_d:
918 case Intrinsic::mips_str_w: {
919 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D
920 : Mips::STR_W;
921
922 SDLoc DL(Node);
923 assert(Node->getNumOperands() == 5 && "Unexpected number of operands.");
924 const SDValue &Chain = Node->getOperand(0);
925 const SDValue &Intrinsic = Node->getOperand(1);
926 const SDValue &Vec = Node->getOperand(2);
927 const SDValue &Pointer = Node->getOperand(3);
928 const SDValue &Constant = Node->getOperand(4);
929
930 assert(Chain.getValueType() == MVT::Other);
931 (void)Intrinsic;
932 assert(Intrinsic.getOpcode() == ISD::TargetConstant &&
933 Constant.getOpcode() == ISD::Constant &&
934 "Invalid instruction operand.");
935
936 // Convert Constant to TargetConstant.
937 const ConstantInt *Val =
938 cast<ConstantSDNode>(Constant)->getConstantIntValue();
939 SDValue Imm =
940 CurDAG->getTargetConstant(*Val, DL, Constant.getValueType());
941
942 SmallVector<SDValue, 4> Ops{Vec, Pointer, Imm, Chain};
943
944 assert(Node->getNumValues() == 1);
945 assert(Node->getValueType(0) == MVT::Other);
946 SmallVector<EVT, 1> ResTys{Node->getValueType(0)};
947
948 ReplaceNode(Node, CurDAG->getMachineNode(Op, DL, ResTys, Ops));
949 return true;
950 }
951 }
952 break;
953 }
954
955 case MipsISD::FAbs: {
956 MVT ResTy = Node->getSimpleValueType(0);
957 assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&
958 "Unsupported float type!");
959 unsigned Opc = 0;
960 if (ResTy == MVT::f64)
961 Opc = (Subtarget->isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32);
962 else
963 Opc = Mips::FABS_S;
964
965 if (Subtarget->inMicroMipsMode()) {
966 switch (Opc) {
967 case Mips::FABS_D64:
968 Opc = Mips::FABS_D64_MM;
969 break;
970 case Mips::FABS_D32:
971 Opc = Mips::FABS_D32_MM;
972 break;
973 case Mips::FABS_S:
974 Opc = Mips::FABS_S_MM;
975 break;
976 default:
977 llvm_unreachable("Unknown opcode for MIPS floating point abs!");
978 }
979 }
980
982 CurDAG->getMachineNode(Opc, DL, ResTy, Node->getOperand(0)));
983
984 return true;
985 }
986
987 // Manually match MipsISD::Ins nodes to get the correct instruction. It has
988 // to be done in this fashion so that we respect the differences between
989 // dins and dinsm, as the difference is that the size operand has the range
990 // 0 < size <= 32 for dins while dinsm has the range 2 <= size <= 64 which
991 // means SelectionDAGISel would have to test all the operands at once to
992 // match the instruction.
993 case MipsISD::Ins: {
994
995 // Validating the node operands.
996 if (Node->getValueType(0) != MVT::i32 && Node->getValueType(0) != MVT::i64)
997 return false;
998
999 if (Node->getNumOperands() != 4)
1000 return false;
1001
1002 if (Node->getOperand(1)->getOpcode() != ISD::Constant ||
1003 Node->getOperand(2)->getOpcode() != ISD::Constant)
1004 return false;
1005
1006 MVT ResTy = Node->getSimpleValueType(0);
1007 uint64_t Pos = Node->getConstantOperandVal(1);
1008 uint64_t Size = Node->getConstantOperandVal(2);
1009
1010 // Size has to be >0 for 'ins', 'dins' and 'dinsu'.
1011 if (!Size)
1012 return false;
1013
1014 if (Pos + Size > 64)
1015 return false;
1016
1017 if (ResTy != MVT::i32 && ResTy != MVT::i64)
1018 return false;
1019
1020 unsigned Opcode = 0;
1021 if (ResTy == MVT::i32) {
1022 if (Pos + Size <= 32)
1023 Opcode = Mips::INS;
1024 } else {
1025 if (Pos + Size <= 32)
1026 Opcode = Mips::DINS;
1027 else if (Pos < 32 && 1 < Size)
1028 Opcode = Mips::DINSM;
1029 else
1030 Opcode = Mips::DINSU;
1031 }
1032
1033 if (Opcode) {
1034 SDValue Ops[4] = {
1035 Node->getOperand(0), CurDAG->getTargetConstant(Pos, DL, MVT::i32),
1036 CurDAG->getTargetConstant(Size, DL, MVT::i32), Node->getOperand(3)};
1037
1038 ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, ResTy, Ops));
1039 return true;
1040 }
1041
1042 return false;
1043 }
1044
1047 unsigned RdhwrOpc, DestReg;
1048
1049 if (PtrVT == MVT::i32) {
1050 RdhwrOpc = Mips::RDHWR;
1051 DestReg = Mips::V1;
1052 } else {
1053 RdhwrOpc = Mips::RDHWR64;
1054 DestReg = Mips::V1_64;
1055 }
1056
1057 SDNode *Rdhwr =
1058 CurDAG->getMachineNode(RdhwrOpc, DL, Node->getValueType(0), MVT::Glue,
1059 CurDAG->getRegister(Mips::HWR29, MVT::i32),
1060 CurDAG->getTargetConstant(0, DL, MVT::i32));
1061 SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, DestReg,
1062 SDValue(Rdhwr, 0), SDValue(Rdhwr, 1));
1063 SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT,
1064 Chain.getValue(1));
1065 ReplaceNode(Node, ResNode.getNode());
1066 return true;
1067 }
1068
1069 case ISD::BUILD_VECTOR: {
1070 // Select appropriate ldi.[bhwd] instructions for constant splats of
1071 // 128-bit when MSA is enabled. Fixup any register class mismatches that
1072 // occur as a result.
1073 //
1074 // This allows the compiler to use a wider range of immediates than would
1075 // otherwise be allowed. If, for example, v4i32 could only use ldi.h then
1076 // it would not be possible to load { 0x01010101, 0x01010101, 0x01010101,
1077 // 0x01010101 } without using a constant pool. This would be sub-optimal
1078 // when // 'ldi.b wd, 1' is capable of producing that bit-pattern in the
1079 // same set/ of registers. Similarly, ldi.h isn't capable of producing {
1080 // 0x00000000, 0x00000001, 0x00000000, 0x00000001 } but 'ldi.d wd, 1' can.
1081
1082 const MipsABIInfo &ABI =
1083 static_cast<const MipsTargetMachine &>(TM).getABI();
1084
1085 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Node);
1086 APInt SplatValue, SplatUndef;
1087 unsigned SplatBitSize;
1088 bool HasAnyUndefs;
1089 unsigned LdiOp;
1090 EVT ResVecTy = BVN->getValueType(0);
1091 EVT ViaVecTy;
1092
1093 if (!Subtarget->hasMSA() || !BVN->getValueType(0).is128BitVector())
1094 return false;
1095
1096 if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
1097 HasAnyUndefs, 8,
1098 !Subtarget->isLittle()))
1099 return false;
1100
1101 switch (SplatBitSize) {
1102 default:
1103 return false;
1104 case 8:
1105 LdiOp = Mips::LDI_B;
1106 ViaVecTy = MVT::v16i8;
1107 break;
1108 case 16:
1109 LdiOp = Mips::LDI_H;
1110 ViaVecTy = MVT::v8i16;
1111 break;
1112 case 32:
1113 LdiOp = Mips::LDI_W;
1114 ViaVecTy = MVT::v4i32;
1115 break;
1116 case 64:
1117 LdiOp = Mips::LDI_D;
1118 ViaVecTy = MVT::v2i64;
1119 break;
1120 }
1121
1122 SDNode *Res = nullptr;
1123
1124 // If we have a signed 10 bit integer, we can splat it directly.
1125 //
1126 // If we have something bigger we can synthesize the value into a GPR and
1127 // splat from there.
1128 if (SplatValue.isSignedIntN(10)) {
1129 SDValue Imm = CurDAG->getTargetConstant(SplatValue, DL,
1130 ViaVecTy.getVectorElementType());
1131
1132 Res = CurDAG->getMachineNode(LdiOp, DL, ViaVecTy, Imm);
1133 } else if (SplatValue.isSignedIntN(16) &&
1134 ((ABI.IsO32() && SplatBitSize < 64) ||
1135 (ABI.IsN32() || ABI.IsN64()))) {
1136 // Only handle signed 16 bit values when the element size is GPR width.
1137 // MIPS64 can handle all the cases but MIPS32 would need to handle
1138 // negative cases specifically here. Instead, handle those cases as
1139 // 64bit values.
1140
1141 bool Is32BitSplat = ABI.IsO32() || SplatBitSize < 64;
1142 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;
1143 const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64;
1144 SDValue ZeroVal = CurDAG->getRegister(
1145 Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT);
1146
1147 const unsigned FILLOp =
1148 SplatBitSize == 16
1149 ? Mips::FILL_H
1150 : (SplatBitSize == 32 ? Mips::FILL_W
1151 : (SplatBitSize == 64 ? Mips::FILL_D : 0));
1152
1153 assert(FILLOp != 0 && "Unknown FILL Op for splat synthesis!");
1154 assert((!ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&
1155 "Attempting to use fill.d on MIPS32!");
1156
1157 const unsigned Lo = SplatValue.getLoBits(16).getZExtValue();
1158 SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, SplatMVT);
1159
1160 Res = CurDAG->getMachineNode(ADDiuOp, DL, SplatMVT, ZeroVal, LoVal);
1161 Res = CurDAG->getMachineNode(FILLOp, DL, ViaVecTy, SDValue(Res, 0));
1162
1163 } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 32) {
1164 // Only handle the cases where the splat size agrees with the size
1165 // of the SplatValue here.
1166 const unsigned Lo = SplatValue.getLoBits(16).getZExtValue();
1167 const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue();
1168 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);
1169
1170 SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32);
1171 SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32);
1172
1173 if (Hi)
1174 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);
1175
1176 if (Lo)
1177 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1178 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
1179
1180 assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!");
1181 Res =
1182 CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0));
1183
1184 } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 64 &&
1185 (ABI.IsN32() || ABI.IsN64())) {
1186 // N32 and N64 can perform some tricks that O32 can't for signed 32 bit
1187 // integers due to having 64bit registers. lui will cause the necessary
1188 // zero/sign extension.
1189 const unsigned Lo = SplatValue.getLoBits(16).getZExtValue();
1190 const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue();
1191 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);
1192
1193 SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32);
1194 SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32);
1195
1196 if (Hi)
1197 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);
1198
1199 if (Lo)
1200 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1201 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
1202
1203 Res = CurDAG->getMachineNode(
1204 Mips::SUBREG_TO_REG, DL, MVT::i64,
1205 CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64),
1206 SDValue(Res, 0),
1207 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));
1208
1209 Res =
1210 CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0));
1211
1212 } else if (SplatValue.isSignedIntN(64)) {
1213 // If we have a 64 bit Splat value, we perform a similar sequence to the
1214 // above:
1215 //
1216 // MIPS32: MIPS64:
1217 // lui $res, %highest(val) lui $res, %highest(val)
1218 // ori $res, $res, %higher(val) ori $res, $res, %higher(val)
1219 // lui $res2, %hi(val) lui $res2, %hi(val)
1220 // ori $res2, %res2, %lo(val) ori $res2, %res2, %lo(val)
1221 // $res3 = fill $res2 dinsu $res, $res2, 0, 32
1222 // $res4 = insert.w $res3[1], $res fill.d $res
1223 // splat.d $res4, 0
1224 //
1225 // The ability to use dinsu is guaranteed as MSA requires MIPSR5.
1226 // This saves having to materialize the value by shifts and ors.
1227 //
1228 // FIXME: Implement the preferred sequence for MIPS64R6:
1229 //
1230 // MIPS64R6:
1231 // ori $res, $zero, %lo(val)
1232 // daui $res, $res, %hi(val)
1233 // dahi $res, $res, %higher(val)
1234 // dati $res, $res, %highest(cal)
1235 // fill.d $res
1236 //
1237
1238 const unsigned Lo = SplatValue.getLoBits(16).getZExtValue();
1239 const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue();
1240 const unsigned Higher = SplatValue.lshr(32).getLoBits(16).getZExtValue();
1241 const unsigned Highest = SplatValue.lshr(48).getLoBits(16).getZExtValue();
1242
1243 SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32);
1244 SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32);
1245 SDValue HigherVal = CurDAG->getTargetConstant(Higher, DL, MVT::i32);
1246 SDValue HighestVal = CurDAG->getTargetConstant(Highest, DL, MVT::i32);
1247 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);
1248
1249 // Independent of whether we're targeting MIPS64 or not, the basic
1250 // operations are the same. Also, directly use the $zero register if
1251 // the 16 bit chunk is zero.
1252 //
1253 // For optimization purposes we always synthesize the splat value as
1254 // an i32 value, then if we're targetting MIPS64, use SUBREG_TO_REG
1255 // just before combining the values with dinsu to produce an i64. This
1256 // enables SelectionDAG to aggressively share components of splat values
1257 // where possible.
1258 //
1259 // FIXME: This is the general constant synthesis problem. This code
1260 // should be factored out into a class shared between all the
1261 // classes that need it. Specifically, for a splat size of 64
1262 // bits that's a negative number we can do better than LUi/ORi
1263 // for the upper 32bits.
1264
1265 if (Hi)
1266 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);
1267
1268 if (Lo)
1269 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1270 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
1271
1272 SDNode *HiRes;
1273 if (Highest)
1274 HiRes = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HighestVal);
1275
1276 if (Higher)
1277 HiRes = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,
1278 Highest ? SDValue(HiRes, 0) : ZeroVal,
1279 HigherVal);
1280
1281
1282 if (ABI.IsO32()) {
1283 Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32,
1284 (Hi || Lo) ? SDValue(Res, 0) : ZeroVal);
1285
1286 Res = CurDAG->getMachineNode(
1287 Mips::INSERT_W, DL, MVT::v4i32, SDValue(Res, 0),
1288 (Highest || Higher) ? SDValue(HiRes, 0) : ZeroVal,
1289 CurDAG->getTargetConstant(1, DL, MVT::i32));
1290
1292 const TargetRegisterClass *RC =
1293 TLI->getRegClassFor(ViaVecTy.getSimpleVT());
1294
1295 Res = CurDAG->getMachineNode(
1296 Mips::COPY_TO_REGCLASS, DL, ViaVecTy, SDValue(Res, 0),
1297 CurDAG->getTargetConstant(RC->getID(), DL, MVT::i32));
1298
1299 Res = CurDAG->getMachineNode(
1300 Mips::SPLATI_D, DL, MVT::v2i64, SDValue(Res, 0),
1301 CurDAG->getTargetConstant(0, DL, MVT::i32));
1302 } else if (ABI.IsN64() || ABI.IsN32()) {
1303
1304 SDValue Zero64Val = CurDAG->getRegister(Mips::ZERO_64, MVT::i64);
1305 const bool HiResNonZero = Highest || Higher;
1306 const bool ResNonZero = Hi || Lo;
1307
1308 if (HiResNonZero)
1309 HiRes = CurDAG->getMachineNode(
1310 Mips::SUBREG_TO_REG, DL, MVT::i64,
1311 CurDAG->getTargetConstant(((Highest >> 15) & 0x1), DL, MVT::i64),
1312 SDValue(HiRes, 0),
1313 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));
1314
1315 if (ResNonZero)
1316 Res = CurDAG->getMachineNode(
1317 Mips::SUBREG_TO_REG, DL, MVT::i64,
1318 CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64),
1319 SDValue(Res, 0),
1320 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));
1321
1322 // We have 3 cases:
1323 // The HiRes is nonzero but Res is $zero => dsll32 HiRes, 0
1324 // The Res is nonzero but HiRes is $zero => dinsu Res, $zero, 32, 32
1325 // Both are non zero => dinsu Res, HiRes, 32, 32
1326 //
1327 // The obvious "missing" case is when both are zero, but that case is
1328 // handled by the ldi case.
1329 if (ResNonZero) {
1330 IntegerType *Int32Ty =
1332 const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32);
1333 SDValue Ops[4] = {HiResNonZero ? SDValue(HiRes, 0) : Zero64Val,
1334 CurDAG->getConstant(*Const32, DL, MVT::i32),
1335 CurDAG->getConstant(*Const32, DL, MVT::i32),
1336 SDValue(Res, 0)};
1337
1338 Res = CurDAG->getMachineNode(Mips::DINSU, DL, MVT::i64, Ops);
1339 } else if (HiResNonZero) {
1340 Res = CurDAG->getMachineNode(
1341 Mips::DSLL32, DL, MVT::i64, SDValue(HiRes, 0),
1342 CurDAG->getTargetConstant(0, DL, MVT::i32));
1343 } else
1345 "Zero splat value handled by non-zero 64bit splat synthesis!");
1346
1347 Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64,
1348 SDValue(Res, 0));
1349 } else
1350 llvm_unreachable("Unknown ABI in MipsISelDAGToDAG!");
1351
1352 } else
1353 return false;
1354
1355 if (ResVecTy != ViaVecTy) {
1356 // If LdiOp is writing to a different register class to ResVecTy, then
1357 // fix it up here. This COPY_TO_REGCLASS should never cause a move.v
1358 // since the source and destination register sets contain the same
1359 // registers.
1361 MVT ResVecTySimple = ResVecTy.getSimpleVT();
1362 const TargetRegisterClass *RC = TLI->getRegClassFor(ResVecTySimple);
1363 Res = CurDAG->getMachineNode(Mips::COPY_TO_REGCLASS, DL,
1364 ResVecTy, SDValue(Res, 0),
1366 MVT::i32));
1367 }
1368
1369 ReplaceNode(Node, Res);
1370 return true;
1371 }
1372
1373 }
1374
1375 return false;
1376}
1377
1378bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand(
1379 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
1380 std::vector<SDValue> &OutOps) {
1382
1383 switch(ConstraintID) {
1384 default:
1385 llvm_unreachable("Unexpected asm memory constraint");
1386 // All memory constraints can at least accept raw pointers.
1389 if (selectAddrRegImm16(Op, Base, Offset)) {
1390 OutOps.push_back(Base);
1391 OutOps.push_back(Offset);
1392 return false;
1393 }
1394 OutOps.push_back(Op);
1395 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
1396 return false;
1398 // The 'R' constraint is supposed to be much more complicated than this.
1399 // However, it's becoming less useful due to architectural changes and
1400 // ought to be replaced by other constraints such as 'ZC'.
1401 // For now, support 9-bit signed offsets which is supportable by all
1402 // subtargets for all instructions.
1403 if (selectAddrRegImm9(Op, Base, Offset)) {
1404 OutOps.push_back(Base);
1405 OutOps.push_back(Offset);
1406 return false;
1407 }
1408 OutOps.push_back(Op);
1409 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
1410 return false;
1412 // ZC matches whatever the pref, ll, and sc instructions can handle for the
1413 // given subtarget.
1414 if (Subtarget->inMicroMipsMode()) {
1415 // On microMIPS, they can handle 12-bit offsets.
1416 if (selectAddrRegImm12(Op, Base, Offset)) {
1417 OutOps.push_back(Base);
1418 OutOps.push_back(Offset);
1419 return false;
1420 }
1421 } else if (Subtarget->hasMips32r6()) {
1422 // On MIPS32r6/MIPS64r6, they can only handle 9-bit offsets.
1423 if (selectAddrRegImm9(Op, Base, Offset)) {
1424 OutOps.push_back(Base);
1425 OutOps.push_back(Offset);
1426 return false;
1427 }
1428 } else if (selectAddrRegImm16(Op, Base, Offset)) {
1429 // Prior to MIPS32r6/MIPS64r6, they can handle 16-bit offsets.
1430 OutOps.push_back(Base);
1431 OutOps.push_back(Offset);
1432 return false;
1433 }
1434 // In all cases, 0-bit offsets are acceptable.
1435 OutOps.push_back(Op);
1436 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
1437 return false;
1438 }
1439 return true;
1440}
1441
1443 CodeGenOptLevel OL)
1444 : MipsDAGToDAGISelLegacy(std::make_unique<MipsSEDAGToDAGISel>(TM, OL)) {}
1445
1447 CodeGenOptLevel OptLevel) {
1448 return new MipsSEDAGToDAGISelLegacy(TM, OptLevel);
1449}
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
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 ...
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:613
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1498
unsigned popcount() const
Count the number of bits set.
Definition: APInt.h:1627
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1446
int32_t exactLogBase2() const
Definition: APInt.h:1739
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
Definition: APInt.h:413
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
Definition: APInt.h:410
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.h:829
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:81
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:380
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:266
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
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:487
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:741
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:787
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:690
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:813
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:570
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:953
@ 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:529
@ 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:359
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:307
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition: ValueTypes.h:204
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:319