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
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) {
125 MachineInstrBuilder MIB(MF, &MI);
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
153 MachineRegisterInfo *MRI = &MF.getRegInfo();
154
155 for (auto &MBB: MF) {
156 for (auto &MI: MBB) {
157 switch (MI.getOpcode()) {
158 case Mips::RDDSP:
159 addDSPCtrlRegOperands(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:
173 if (Subtarget->isABI_FPXX() && !Subtarget->hasMTHC1())
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);
270 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);
271 return true;
272 }
273 return false;
274}
275
276/// Match frameindex+offset and frameindex|offset
277bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
278 SDValue Addr, SDValue &Base, SDValue &Offset, unsigned OffsetBits,
279 unsigned ShiftAmount = 0) const {
280 if (CurDAG->isBaseWithConstantOffset(Addr)) {
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 =
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 ||
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);
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)) {
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};
713 ReplaceNode(Node, CurDAG->getMachineNode(Subtarget->isGP64bit()
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()) {
729 SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL,
730 Mips::ZERO_64, MVT::i64);
731 ReplaceNode(Node,
732 CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero));
733 } else if (Subtarget->isFP64bit()) {
734 SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL,
735 Mips::ZERO, MVT::i32);
736 ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64_64, DL,
737 MVT::f64, Zero, Zero));
738 } else {
739 SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL,
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
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
939 ReplaceNode(Node,
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
1004 EVT PtrVT = getTargetLowering()->getPointerTy(CurDAG->getDataLayout());
1005 unsigned RdhwrOpc, DestReg;
1006
1007 if (PtrVT == MVT::i32) {
1008 RdhwrOpc = Mips::RDHWR;
1009 DestReg = Mips::V1;
1010 } else {
1011 RdhwrOpc = Mips::RDHWR64;
1012 DestReg = Mips::V1_64;
1013 }
1014
1015 SDNode *Rdhwr =
1016 CurDAG->getMachineNode(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
1249 const TargetLowering *TLI = getTargetLowering();
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 =
1289 IntegerType::get(MF->getFunction().getContext(), 32);
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.
1318 const TargetLowering *TLI = getTargetLowering();
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),
1323 CurDAG->getTargetConstant(RC->getID(), DL,
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
1403
unsigned const MachineRegisterInfo * MRI
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static uint64_t getConstant(const Value *IndexValue)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
mir Rename Register Operands
Register Reg
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()
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.
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
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:319
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
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)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_iterator< true, false, false, true, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
const InstSeq & Analyze(uint64_t Imm, unsigned Size, bool LastInstrIsADDiu)
Analyze - Get an instruction sequence to load immediate Imm.
SmallVector< Inst, 7 > InstSeq
MipsDAGToDAGISelLegacy(std::unique_ptr< SelectionDAGISel > S)
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...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL)
bool inMips16Mode() 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.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetLowering * TLI
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
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...
unsigned getID() const
Return the register class ID number.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ 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
@ 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.
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:296
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition Alignment.h:134
FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel)
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:257
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:583
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:197
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:373
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:316
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:328