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