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