LLVM 22.0.0git
MipsSEISelLowering.cpp
Go to the documentation of this file.
1//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===//
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 MipsTargetLowering specialized for mips32/64.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsSEISelLowering.h"
14#include "MipsMachineFunction.h"
15#include "MipsRegisterInfo.h"
16#include "MipsSubtarget.h"
17#include "llvm/ADT/APInt.h"
18#include "llvm/ADT/STLExtras.h"
35#include "llvm/IR/DebugLoc.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/IntrinsicsMips.h"
40#include "llvm/Support/Debug.h"
44#include <algorithm>
45#include <cassert>
46#include <cstddef>
47#include <cstdint>
48#include <iterator>
49#include <utility>
50
51using namespace llvm;
52
53#define DEBUG_TYPE "mips-isel"
54
55static cl::opt<bool>
56UseMipsTailCalls("mips-tail-calls", cl::Hidden,
57 cl::desc("MIPS: permit tail calls."), cl::init(false));
58
59static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
60 cl::desc("Expand double precision loads and "
61 "stores to their single precision "
62 "counterparts"));
63
64// Widen the v2 vectors to the register width, i.e. v2i16 -> v8i16,
65// v2i32 -> v4i32, etc, to ensure the correct rail size is used, i.e.
66// INST.h for v16, INST.w for v32, INST.d for v64.
69 if (this->Subtarget.hasMSA()) {
70 switch (VT.SimpleTy) {
71 // Leave v2i1 vectors to be promoted to larger ones.
72 // Other i1 types will be promoted by default.
73 case MVT::v2i1:
74 return TypePromoteInteger;
75 break;
76 // 16-bit vector types (v2 and longer)
77 case MVT::v2i8:
78 // 32-bit vector types (v2 and longer)
79 case MVT::v2i16:
80 case MVT::v4i8:
81 // 64-bit vector types (v2 and longer)
82 case MVT::v2i32:
83 case MVT::v4i16:
84 case MVT::v8i8:
85 return TypeWidenVector;
86 break;
87 // Only word (.w) and doubleword (.d) are available for floating point
88 // vectors. That means floating point vectors should be either v2f64
89 // or v4f32.
90 // Here we only explicitly widen the f32 types - f16 will be promoted
91 // by default.
92 case MVT::v2f32:
93 case MVT::v3f32:
94 return TypeWidenVector;
95 // v2i64 is already 128-bit wide.
96 default:
97 break;
98 }
99 }
101}
102
104 const MipsSubtarget &STI)
105 : MipsTargetLowering(TM, STI) {
106 // Set up the register classes
107 addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
108
109 if (Subtarget.isGP64bit())
110 addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
111
112 if (Subtarget.hasDSP() || Subtarget.hasMSA()) {
113 // Expand all truncating stores and extending loads.
116 setTruncStoreAction(VT0, VT1, Expand);
120 }
121 }
122 }
123
124 if (Subtarget.hasDSP()) {
125 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
126
127 for (const auto &VecTy : VecTys) {
128 addRegisterClass(VecTy, &Mips::DSPRRegClass);
129
130 // Expand all builtin opcodes.
131 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
133
136 setOperationAction(ISD::LOAD, VecTy, Legal);
137 setOperationAction(ISD::STORE, VecTy, Legal);
138 setOperationAction(ISD::BITCAST, VecTy, Legal);
139 }
140
143
144 if (Subtarget.hasMips32r2()) {
147 }
148 }
149
150 if (Subtarget.hasDSPR2())
151 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
152
153 if (Subtarget.hasMSA()) {
154 addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass);
155 addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass);
156 addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass);
157 addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass);
158 addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass);
159 addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
160 addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
161
162 // f16 is a storage-only type, always promote it to f32.
163 addRegisterClass(MVT::f16, &Mips::MSA128HRegClass);
165 setOperationAction(ISD::BR_CC, MVT::f16, Promote);
174 setOperationAction(ISD::FNEG, MVT::f16, Promote);
175 setOperationAction(ISD::FABS, MVT::f16, Promote);
176 setOperationAction(ISD::FCEIL, MVT::f16, Promote);
178 setOperationAction(ISD::FCOS, MVT::f16, Promote);
179 setOperationAction(ISD::FP_EXTEND, MVT::f16, Promote);
180 setOperationAction(ISD::FFLOOR, MVT::f16, Promote);
181 setOperationAction(ISD::FNEARBYINT, MVT::f16, Promote);
182 setOperationAction(ISD::FPOW, MVT::f16, Promote);
183 setOperationAction(ISD::FPOWI, MVT::f16, Promote);
184 setOperationAction(ISD::FRINT, MVT::f16, Promote);
185 setOperationAction(ISD::FSIN, MVT::f16, Promote);
186 setOperationAction(ISD::FSINCOS, MVT::f16, Promote);
187 setOperationAction(ISD::FSQRT, MVT::f16, Promote);
188 setOperationAction(ISD::FEXP, MVT::f16, Promote);
189 setOperationAction(ISD::FEXP2, MVT::f16, Promote);
190 setOperationAction(ISD::FLOG, MVT::f16, Promote);
191 setOperationAction(ISD::FLOG2, MVT::f16, Promote);
192 setOperationAction(ISD::FLOG10, MVT::f16, Promote);
193 setOperationAction(ISD::FROUND, MVT::f16, Promote);
194 setOperationAction(ISD::FTRUNC, MVT::f16, Promote);
195 setOperationAction(ISD::FMINNUM, MVT::f16, Promote);
196 setOperationAction(ISD::FMAXNUM, MVT::f16, Promote);
197 setOperationAction(ISD::FMINIMUM, MVT::f16, Promote);
198 setOperationAction(ISD::FMAXIMUM, MVT::f16, Promote);
199
201 }
202
203 if (!Subtarget.useSoftFloat()) {
204 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
205
206 // When dealing with single precision only, use libcalls
207 if (!Subtarget.isSingleFloat()) {
208 if (Subtarget.isFP64bit())
209 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
210 else
211 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
212 }
213
216 setOperationAction(Op, MVT::f32, Legal);
217 setOperationAction(Op, MVT::f64, Legal);
218 }
219 }
220
221 // Targets with 64bits integer registers, but no 64bit floating point register
222 // do not support conversion between them
223 if (Subtarget.isGP64bit() && Subtarget.isSingleFloat() &&
224 !Subtarget.useSoftFloat()) {
229 }
230
235
236 if (Subtarget.hasCnMips())
238 else if (Subtarget.isGP64bit())
240
241 if (Subtarget.isGP64bit()) {
248 }
249
252
255 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
256 if (Subtarget.hasMips32r6()) {
257 setOperationAction(ISD::LOAD, MVT::i32, Legal);
258 setOperationAction(ISD::STORE, MVT::i32, Legal);
259 } else {
260 setOperationAction(ISD::LOAD, MVT::i32, Custom);
261 setOperationAction(ISD::STORE, MVT::i32, Custom);
262 }
263
265
269
270 if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() &&
271 !Subtarget.hasMips64()) {
272 setOperationAction(ISD::BITCAST, MVT::i64, Custom);
273 }
274
275 if (NoDPLoadStore) {
276 setOperationAction(ISD::LOAD, MVT::f64, Custom);
277 setOperationAction(ISD::STORE, MVT::f64, Custom);
278 }
279
280 if (Subtarget.hasMips32r6()) {
281 // MIPS32r6 replaces the accumulator-based multiplies with a three register
282 // instruction
288
289 // MIPS32r6 replaces the accumulator-based division/remainder with separate
290 // three register division and remainder instructions.
297
298 // MIPS32r6 replaces conditional moves with an equivalent that removes the
299 // need for three GPR read ports.
303
307
308 assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6");
312
313 setOperationAction(ISD::BRCOND, MVT::Other, Legal);
314
315 // Floating point > and >= are supported via < and <=
320
325 }
326
327 if (Subtarget.hasMips64r6()) {
328 // MIPS64r6 replaces the accumulator-based multiplies with a three register
329 // instruction
335
336 // MIPS32r6 replaces the accumulator-based division/remainder with separate
337 // three register division and remainder instructions.
344
345 // MIPS64r6 replaces conditional moves with an equivalent that removes the
346 // need for three GPR read ports.
350 }
351
352 computeRegisterProperties(Subtarget.getRegisterInfo());
353}
354
355const MipsTargetLowering *
357 const MipsSubtarget &STI) {
358 return new MipsSETargetLowering(TM, STI);
359}
360
363 if (VT == MVT::Untyped)
364 return Subtarget.hasDSP() ? &Mips::ACC64DSPRegClass : &Mips::ACC64RegClass;
365
367}
368
369// Enable MSA support for the given integer type and Register class.
372 addRegisterClass(Ty, RC);
373
374 // Expand all builtin opcodes.
375 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
377
378 setOperationAction(ISD::BITCAST, Ty, Legal);
379 setOperationAction(ISD::LOAD, Ty, Legal);
380 setOperationAction(ISD::STORE, Ty, Legal);
385
407
408 if (Ty == MVT::v4i32 || Ty == MVT::v2i64) {
413 }
414
421}
422
423// Enable MSA support for the given floating-point type and Register class.
461
462SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
465
466 EVT ResTy = Op->getValueType(0);
467 SDLoc DL(Op);
468
469 // Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the
470 // floating point register are undefined. Not really an issue as sel.d, which
471 // is produced from an FSELECT node, only looks at bit 0.
472 SDValue Tmp = DAG.getNode(MipsISD::MTC1_D64, DL, MVT::f64, Op->getOperand(0));
473 return DAG.getNode(MipsISD::FSELECT, DL, ResTy, Tmp, Op->getOperand(1),
474 Op->getOperand(2));
475}
476
478 EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {
480
481 if (Subtarget.systemSupportsUnalignedAccess()) {
482 // MIPS32r6/MIPS64r6 is required to support unaligned access. It's
483 // implementation defined whether this is handled by hardware, software, or
484 // a hybrid of the two but it's expected that most implementations will
485 // handle the majority of cases in hardware.
486 if (Fast)
487 *Fast = 1;
488 return true;
489 } else if (Subtarget.hasMips32r6()) {
490 return false;
491 }
492
493 switch (SVT) {
494 case MVT::i64:
495 case MVT::i32:
496 if (Fast)
497 *Fast = 1;
498 return true;
499 default:
500 return false;
501 }
502}
503
505 SelectionDAG &DAG) const {
506 switch(Op.getOpcode()) {
507 case ISD::LOAD: return lowerLOAD(Op, DAG);
508 case ISD::STORE: return lowerSTORE(Op, DAG);
509 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
510 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
511 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
512 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
513 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
514 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
515 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
516 DAG);
517 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
518 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
519 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
520 case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
521 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
522 case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
523 case ISD::SELECT: return lowerSELECT(Op, DAG);
524 case ISD::BITCAST: return lowerBITCAST(Op, DAG);
525 }
526
528}
529
530// Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT
531//
532// Performs the following transformations:
533// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its
534// sign/zero-extension is completely overwritten by the new one performed by
535// the ISD::AND.
536// - Removes redundant zero extensions performed by an ISD::AND.
539 const MipsSubtarget &Subtarget) {
540 if (!Subtarget.hasMSA())
541 return SDValue();
542
543 SDValue Op0 = N->getOperand(0);
544 SDValue Op1 = N->getOperand(1);
545 unsigned Op0Opcode = Op0->getOpcode();
546
547 // (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d)
548 // where $d + 1 == 2^n and n == 32
549 // or $d + 1 == 2^n and n <= 32 and ZExt
550 // -> (MipsVExtractZExt $a, $b, $c)
551 if (Op0Opcode == MipsISD::VEXTRACT_SEXT_ELT ||
552 Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT) {
554
555 if (!Mask)
556 return SDValue();
557
558 int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2();
559
560 if (Log2IfPositive <= 0)
561 return SDValue(); // Mask+1 is not a power of 2
562
563 SDValue Op0Op2 = Op0->getOperand(2);
564 EVT ExtendTy = cast<VTSDNode>(Op0Op2)->getVT();
565 unsigned ExtendTySize = ExtendTy.getSizeInBits();
566 unsigned Log2 = Log2IfPositive;
567
568 if ((Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT && Log2 >= ExtendTySize) ||
569 Log2 == ExtendTySize) {
570 SDValue Ops[] = { Op0->getOperand(0), Op0->getOperand(1), Op0Op2 };
572 Op0->getVTList(),
573 ArrayRef(Ops, Op0->getNumOperands()));
574 }
575 }
576
577 return SDValue();
578}
579
580// Determine if the specified node is a constant vector splat.
581//
582// Returns true and sets Imm if:
583// * N is a ISD::BUILD_VECTOR representing a constant splat
584//
585// This function is quite similar to MipsSEDAGToDAGISel::selectVSplat. The
586// differences are that it assumes the MSA has already been checked and the
587// arbitrary requirement for a maximum of 32-bit integers isn't applied (and
588// must not be in order for binsri.d to be selectable).
589static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian) {
591
592 if (!Node)
593 return false;
594
595 APInt SplatValue, SplatUndef;
596 unsigned SplatBitSize;
597 bool HasAnyUndefs;
598
599 if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
600 8, !IsLittleEndian))
601 return false;
602
603 Imm = SplatValue;
604
605 return true;
606}
607
608// Test whether the given node is an all-ones build_vector.
610 // Look through bitcasts. Endianness doesn't matter because we are looking
611 // for an all-ones value.
612 if (N->getOpcode() == ISD::BITCAST)
613 N = N->getOperand(0);
614
616
617 if (!BVN)
618 return false;
619
620 APInt SplatValue, SplatUndef;
621 unsigned SplatBitSize;
622 bool HasAnyUndefs;
623
624 // Endianness doesn't matter in this context because we are looking for
625 // an all-ones value.
626 if (BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs))
627 return SplatValue.isAllOnes();
628
629 return false;
630}
631
632// Test whether N is the bitwise inverse of OfNode.
633static bool isBitwiseInverse(SDValue N, SDValue OfNode) {
634 if (N->getOpcode() != ISD::XOR)
635 return false;
636
637 if (isVectorAllOnes(N->getOperand(0)))
638 return N->getOperand(1) == OfNode;
639
640 if (isVectorAllOnes(N->getOperand(1)))
641 return N->getOperand(0) == OfNode;
642
643 return false;
644}
645
646// Perform combines where ISD::OR is the root node.
647//
648// Performs the following transformations:
649// - (or (and $a, $mask), (and $b, $inv_mask)) => (vselect $mask, $a, $b)
650// where $inv_mask is the bitwise inverse of $mask and the 'or' has a 128-bit
651// vector type.
654 const MipsSubtarget &Subtarget) {
655 if (!Subtarget.hasMSA())
656 return SDValue();
657
658 EVT Ty = N->getValueType(0);
659
660 if (!Ty.is128BitVector())
661 return SDValue();
662
663 SDValue Op0 = N->getOperand(0);
664 SDValue Op1 = N->getOperand(1);
665
666 if (Op0->getOpcode() == ISD::AND && Op1->getOpcode() == ISD::AND) {
667 SDValue Op0Op0 = Op0->getOperand(0);
668 SDValue Op0Op1 = Op0->getOperand(1);
669 SDValue Op1Op0 = Op1->getOperand(0);
670 SDValue Op1Op1 = Op1->getOperand(1);
671 bool IsLittleEndian = !Subtarget.isLittle();
672
673 SDValue IfSet, IfClr, Cond;
674 bool IsConstantMask = false;
675 APInt Mask, InvMask;
676
677 // If Op0Op0 is an appropriate mask, try to find it's inverse in either
678 // Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, while
679 // looking.
680 // IfClr will be set if we find a valid match.
681 if (isVSplat(Op0Op0, Mask, IsLittleEndian)) {
682 Cond = Op0Op0;
683 IfSet = Op0Op1;
684
685 if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
686 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
687 IfClr = Op1Op1;
688 else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
689 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
690 IfClr = Op1Op0;
691
692 IsConstantMask = true;
693 }
694
695 // If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the same
696 // thing again using this mask.
697 // IfClr will be set if we find a valid match.
698 if (!IfClr.getNode() && isVSplat(Op0Op1, Mask, IsLittleEndian)) {
699 Cond = Op0Op1;
700 IfSet = Op0Op0;
701
702 if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
703 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
704 IfClr = Op1Op1;
705 else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
706 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
707 IfClr = Op1Op0;
708
709 IsConstantMask = true;
710 }
711
712 // If IfClr is not yet set, try looking for a non-constant match.
713 // IfClr will be set if we find a valid match amongst the eight
714 // possibilities.
715 if (!IfClr.getNode()) {
716 if (isBitwiseInverse(Op0Op0, Op1Op0)) {
717 Cond = Op1Op0;
718 IfSet = Op1Op1;
719 IfClr = Op0Op1;
720 } else if (isBitwiseInverse(Op0Op1, Op1Op0)) {
721 Cond = Op1Op0;
722 IfSet = Op1Op1;
723 IfClr = Op0Op0;
724 } else if (isBitwiseInverse(Op0Op0, Op1Op1)) {
725 Cond = Op1Op1;
726 IfSet = Op1Op0;
727 IfClr = Op0Op1;
728 } else if (isBitwiseInverse(Op0Op1, Op1Op1)) {
729 Cond = Op1Op1;
730 IfSet = Op1Op0;
731 IfClr = Op0Op0;
732 } else if (isBitwiseInverse(Op1Op0, Op0Op0)) {
733 Cond = Op0Op0;
734 IfSet = Op0Op1;
735 IfClr = Op1Op1;
736 } else if (isBitwiseInverse(Op1Op1, Op0Op0)) {
737 Cond = Op0Op0;
738 IfSet = Op0Op1;
739 IfClr = Op1Op0;
740 } else if (isBitwiseInverse(Op1Op0, Op0Op1)) {
741 Cond = Op0Op1;
742 IfSet = Op0Op0;
743 IfClr = Op1Op1;
744 } else if (isBitwiseInverse(Op1Op1, Op0Op1)) {
745 Cond = Op0Op1;
746 IfSet = Op0Op0;
747 IfClr = Op1Op0;
748 }
749 }
750
751 // At this point, IfClr will be set if we have a valid match.
752 if (!IfClr.getNode())
753 return SDValue();
754
755 assert(Cond.getNode() && IfSet.getNode());
756
757 // Fold degenerate cases.
758 if (IsConstantMask) {
759 if (Mask.isAllOnes())
760 return IfSet;
761 else if (Mask == 0)
762 return IfClr;
763 }
764
765 // Transform the DAG into an equivalent VSELECT.
766 return DAG.getNode(ISD::VSELECT, SDLoc(N), Ty, Cond, IfSet, IfClr);
767 }
768
769 return SDValue();
770}
771
773 SelectionDAG &DAG,
774 const MipsSubtarget &Subtarget) {
775 // Estimate the number of operations the below transform will turn a
776 // constant multiply into. The number is approximately equal to the minimal
777 // number of powers of two that constant can be broken down to by adding
778 // or subtracting them.
779 //
780 // If we have taken more than 12[1] / 8[2] steps to attempt the
781 // optimization for a native sized value, it is more than likely that this
782 // optimization will make things worse.
783 //
784 // [1] MIPS64 requires 6 instructions at most to materialize any constant,
785 // multiplication requires at least 4 cycles, but another cycle (or two)
786 // to retrieve the result from the HI/LO registers.
787 //
788 // [2] For MIPS32, more than 8 steps is expensive as the constant could be
789 // materialized in 2 instructions, multiplication requires at least 4
790 // cycles, but another cycle (or two) to retrieve the result from the
791 // HI/LO registers.
792 //
793 // TODO:
794 // - MaxSteps needs to consider the `VT` of the constant for the current
795 // target.
796 // - Consider to perform this optimization after type legalization.
797 // That allows to remove a workaround for types not supported natively.
798 // - Take in account `-Os, -Oz` flags because this optimization
799 // increases code size.
800 unsigned MaxSteps = Subtarget.isABI_O32() ? 8 : 12;
801
802 SmallVector<APInt, 16> WorkStack(1, C);
803 unsigned Steps = 0;
804 unsigned BitWidth = C.getBitWidth();
805
806 while (!WorkStack.empty()) {
807 APInt Val = WorkStack.pop_back_val();
808
809 if (Val == 0 || Val == 1)
810 continue;
811
812 if (Steps >= MaxSteps)
813 return false;
814
815 if (Val.isPowerOf2()) {
816 ++Steps;
817 continue;
818 }
819
820 APInt Floor = APInt(BitWidth, 1) << Val.logBase2();
821 APInt Ceil = Val.isNegative() ? APInt(BitWidth, 0)
822 : APInt(BitWidth, 1) << C.ceilLogBase2();
823 if ((Val - Floor).ule(Ceil - Val)) {
824 WorkStack.push_back(Floor);
825 WorkStack.push_back(Val - Floor);
826 } else {
827 WorkStack.push_back(Ceil);
828 WorkStack.push_back(Ceil - Val);
829 }
830
831 ++Steps;
832 }
833
834 // If the value being multiplied is not supported natively, we have to pay
835 // an additional legalization cost, conservatively assume an increase in the
836 // cost of 3 instructions per step. This values for this heuristic were
837 // determined experimentally.
838 unsigned RegisterSize = DAG.getTargetLoweringInfo()
839 .getRegisterType(*DAG.getContext(), VT)
840 .getSizeInBits();
841 Steps *= (VT.getSizeInBits() != RegisterSize) * 3;
842 if (Steps > 27)
843 return false;
844
845 return true;
846}
847
849 EVT ShiftTy, SelectionDAG &DAG) {
850 // Return 0.
851 if (C == 0)
852 return DAG.getConstant(0, DL, VT);
853
854 // Return x.
855 if (C == 1)
856 return X;
857
858 // If c is power of 2, return (shl x, log2(c)).
859 if (C.isPowerOf2())
860 return DAG.getNode(ISD::SHL, DL, VT, X,
861 DAG.getConstant(C.logBase2(), DL, ShiftTy));
862
863 unsigned BitWidth = C.getBitWidth();
864 APInt Floor = APInt(BitWidth, 1) << C.logBase2();
865 APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) :
866 APInt(BitWidth, 1) << C.ceilLogBase2();
867
868 // If |c - floor_c| <= |c - ceil_c|,
869 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
870 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
871 if ((C - Floor).ule(Ceil - C)) {
872 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
873 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
874 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
875 }
876
877 // If |c - floor_c| > |c - ceil_c|,
878 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
879 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
880 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
881 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
882}
883
886 const MipsSETargetLowering *TL,
887 const MipsSubtarget &Subtarget) {
888 EVT VT = N->getValueType(0);
889
890 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
892 C->getAPIntValue(), VT, DAG, Subtarget))
893 return genConstMult(N->getOperand(0), C->getAPIntValue(), SDLoc(N), VT,
895 DAG);
896
897 return SDValue(N, 0);
898}
899
901 SelectionDAG &DAG,
902 const MipsSubtarget &Subtarget) {
903 // See if this is a vector splat immediate node.
904 APInt SplatValue, SplatUndef;
905 unsigned SplatBitSize;
906 bool HasAnyUndefs;
907 unsigned EltSize = Ty.getScalarSizeInBits();
908 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
909
910 if (!Subtarget.hasDSP())
911 return SDValue();
912
913 if (!BV ||
914 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
915 EltSize, !Subtarget.isLittle()) ||
916 (SplatBitSize != EltSize) ||
917 (SplatValue.getZExtValue() >= EltSize))
918 return SDValue();
919
920 SDLoc DL(N);
921 return DAG.getNode(Opc, DL, Ty, N->getOperand(0),
922 DAG.getConstant(SplatValue.getZExtValue(), DL, MVT::i32));
923}
924
927 const MipsSubtarget &Subtarget) {
928 EVT Ty = N->getValueType(0);
929
930 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
931 return SDValue();
932
933 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
934}
935
936// Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold
937// constant splats into MipsISD::SHRA_DSP for DSPr2.
938//
939// Performs the following transformations:
940// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its
941// sign/zero-extension is completely overwritten by the new one performed by
942// the ISD::SRA and ISD::SHL nodes.
943// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL
944// sequence.
945//
946// See performDSPShiftCombine for more information about the transformation
947// used for DSPr2.
950 const MipsSubtarget &Subtarget) {
951 EVT Ty = N->getValueType(0);
952
953 if (Subtarget.hasMSA()) {
954 SDValue Op0 = N->getOperand(0);
955 SDValue Op1 = N->getOperand(1);
956
957 // (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d)
958 // where $d + sizeof($c) == 32
959 // or $d + sizeof($c) <= 32 and SExt
960 // -> (MipsVExtractSExt $a, $b, $c)
961 if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(1)) {
962 SDValue Op0Op0 = Op0->getOperand(0);
964
965 if (!ShAmount)
966 return SDValue();
967
968 if (Op0Op0->getOpcode() != MipsISD::VEXTRACT_SEXT_ELT &&
970 return SDValue();
971
972 EVT ExtendTy = cast<VTSDNode>(Op0Op0->getOperand(2))->getVT();
973 unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits();
974
975 if (TotalBits == 32 ||
977 TotalBits <= 32)) {
978 SDValue Ops[] = { Op0Op0->getOperand(0), Op0Op0->getOperand(1),
979 Op0Op0->getOperand(2) };
980 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, SDLoc(Op0Op0),
981 Op0Op0->getVTList(),
982 ArrayRef(Ops, Op0Op0->getNumOperands()));
983 }
984 }
985 }
986
987 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget.hasDSPR2()))
988 return SDValue();
989
990 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
991}
992
993
996 const MipsSubtarget &Subtarget) {
997 EVT Ty = N->getValueType(0);
998
999 if (((Ty != MVT::v2i16) || !Subtarget.hasDSPR2()) && (Ty != MVT::v4i8))
1000 return SDValue();
1001
1002 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
1003}
1004
1006 bool IsV216 = (Ty == MVT::v2i16);
1007
1008 switch (CC) {
1009 case ISD::SETEQ:
1010 case ISD::SETNE: return true;
1011 case ISD::SETLT:
1012 case ISD::SETLE:
1013 case ISD::SETGT:
1014 case ISD::SETGE: return IsV216;
1015 case ISD::SETULT:
1016 case ISD::SETULE:
1017 case ISD::SETUGT:
1018 case ISD::SETUGE: return !IsV216;
1019 default: return false;
1020 }
1021}
1022
1024 EVT Ty = N->getValueType(0);
1025
1026 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
1027 return SDValue();
1028
1029 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
1030 return SDValue();
1031
1032 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
1033 N->getOperand(1), N->getOperand(2));
1034}
1035
1037 EVT Ty = N->getValueType(0);
1038
1039 if (Ty == MVT::v2i16 || Ty == MVT::v4i8) {
1040 SDValue SetCC = N->getOperand(0);
1041
1042 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
1043 return SDValue();
1044
1045 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
1046 SetCC.getOperand(0), SetCC.getOperand(1),
1047 N->getOperand(1), N->getOperand(2), SetCC.getOperand(2));
1048 }
1049
1050 return SDValue();
1051}
1052
1054 const MipsSubtarget &Subtarget) {
1055 EVT Ty = N->getValueType(0);
1056
1057 if (Subtarget.hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
1058 // Try the following combines:
1059 // (xor (or $a, $b), (build_vector allones))
1060 // (xor (or $a, $b), (bitcast (build_vector allones)))
1061 SDValue Op0 = N->getOperand(0);
1062 SDValue Op1 = N->getOperand(1);
1063 SDValue NotOp;
1064
1066 NotOp = Op1;
1067 else if (ISD::isBuildVectorAllOnes(Op1.getNode()))
1068 NotOp = Op0;
1069 else
1070 return SDValue();
1071
1072 if (NotOp->getOpcode() == ISD::OR)
1073 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0),
1074 NotOp->getOperand(1));
1075 }
1076
1077 return SDValue();
1078}
1079
1080SDValue
1082 SelectionDAG &DAG = DCI.DAG;
1083 SDValue Val;
1084
1085 switch (N->getOpcode()) {
1086 case ISD::AND:
1087 Val = performANDCombine(N, DAG, DCI, Subtarget);
1088 break;
1089 case ISD::OR:
1090 Val = performORCombine(N, DAG, DCI, Subtarget);
1091 break;
1092 case ISD::MUL:
1093 return performMULCombine(N, DAG, DCI, this, Subtarget);
1094 case ISD::SHL:
1095 Val = performSHLCombine(N, DAG, DCI, Subtarget);
1096 break;
1097 case ISD::SRA:
1098 return performSRACombine(N, DAG, DCI, Subtarget);
1099 case ISD::SRL:
1100 return performSRLCombine(N, DAG, DCI, Subtarget);
1101 case ISD::VSELECT:
1102 return performVSELECTCombine(N, DAG);
1103 case ISD::XOR:
1104 Val = performXORCombine(N, DAG, Subtarget);
1105 break;
1106 case ISD::SETCC:
1107 Val = performSETCCCombine(N, DAG);
1108 break;
1109 }
1110
1111 if (Val.getNode()) {
1112 LLVM_DEBUG(dbgs() << "\nMipsSE DAG Combine:\n";
1113 N->printrWithDepth(dbgs(), &DAG); dbgs() << "\n=> \n";
1114 Val.getNode()->printrWithDepth(dbgs(), &DAG); dbgs() << "\n");
1115 return Val;
1116 }
1117
1119}
1120
1123 MachineBasicBlock *BB) const {
1124 switch (MI.getOpcode()) {
1125 default:
1127 case Mips::BPOSGE32_PSEUDO:
1128 return emitBPOSGE32(MI, BB);
1129 case Mips::SNZ_B_PSEUDO:
1130 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
1131 case Mips::SNZ_H_PSEUDO:
1132 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
1133 case Mips::SNZ_W_PSEUDO:
1134 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
1135 case Mips::SNZ_D_PSEUDO:
1136 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
1137 case Mips::SNZ_V_PSEUDO:
1138 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
1139 case Mips::SZ_B_PSEUDO:
1140 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
1141 case Mips::SZ_H_PSEUDO:
1142 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
1143 case Mips::SZ_W_PSEUDO:
1144 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
1145 case Mips::SZ_D_PSEUDO:
1146 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
1147 case Mips::SZ_V_PSEUDO:
1148 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
1149 case Mips::COPY_FW_PSEUDO:
1150 return emitCOPY_FW(MI, BB);
1151 case Mips::COPY_FD_PSEUDO:
1152 return emitCOPY_FD(MI, BB);
1153 case Mips::INSERT_FW_PSEUDO:
1154 return emitINSERT_FW(MI, BB);
1155 case Mips::INSERT_FD_PSEUDO:
1156 return emitINSERT_FD(MI, BB);
1157 case Mips::INSERT_B_VIDX_PSEUDO:
1158 case Mips::INSERT_B_VIDX64_PSEUDO:
1159 return emitINSERT_DF_VIDX(MI, BB, 1, false);
1160 case Mips::INSERT_H_VIDX_PSEUDO:
1161 case Mips::INSERT_H_VIDX64_PSEUDO:
1162 return emitINSERT_DF_VIDX(MI, BB, 2, false);
1163 case Mips::INSERT_W_VIDX_PSEUDO:
1164 case Mips::INSERT_W_VIDX64_PSEUDO:
1165 return emitINSERT_DF_VIDX(MI, BB, 4, false);
1166 case Mips::INSERT_D_VIDX_PSEUDO:
1167 case Mips::INSERT_D_VIDX64_PSEUDO:
1168 return emitINSERT_DF_VIDX(MI, BB, 8, false);
1169 case Mips::INSERT_FW_VIDX_PSEUDO:
1170 case Mips::INSERT_FW_VIDX64_PSEUDO:
1171 return emitINSERT_DF_VIDX(MI, BB, 4, true);
1172 case Mips::INSERT_FD_VIDX_PSEUDO:
1173 case Mips::INSERT_FD_VIDX64_PSEUDO:
1174 return emitINSERT_DF_VIDX(MI, BB, 8, true);
1175 case Mips::FILL_FW_PSEUDO:
1176 return emitFILL_FW(MI, BB);
1177 case Mips::FILL_FD_PSEUDO:
1178 return emitFILL_FD(MI, BB);
1179 case Mips::FEXP2_W_1_PSEUDO:
1180 return emitFEXP2_W_1(MI, BB);
1181 case Mips::FEXP2_D_1_PSEUDO:
1182 return emitFEXP2_D_1(MI, BB);
1183 case Mips::ST_F16:
1184 return emitST_F16_PSEUDO(MI, BB);
1185 case Mips::LD_F16:
1186 return emitLD_F16_PSEUDO(MI, BB);
1187 case Mips::MSA_FP_EXTEND_W_PSEUDO:
1188 return emitFPEXTEND_PSEUDO(MI, BB, false);
1189 case Mips::MSA_FP_ROUND_W_PSEUDO:
1190 return emitFPROUND_PSEUDO(MI, BB, false);
1191 case Mips::MSA_FP_EXTEND_D_PSEUDO:
1192 return emitFPEXTEND_PSEUDO(MI, BB, true);
1193 case Mips::MSA_FP_ROUND_D_PSEUDO:
1194 return emitFPROUND_PSEUDO(MI, BB, true);
1195 }
1196}
1197
1198bool MipsSETargetLowering::isEligibleForTailCallOptimization(
1199 const CCState &CCInfo, unsigned NextStackOffset,
1200 const MipsFunctionInfo &FI) const {
1201 if (!UseMipsTailCalls)
1202 return false;
1203
1204 // Exception has to be cleared with eret.
1205 if (FI.isISR())
1206 return false;
1207
1208 // Return false if either the callee or caller has a byval argument.
1209 if (CCInfo.getInRegsParamsCount() > 0 || FI.hasByvalArg())
1210 return false;
1211
1212 // Return true if the callee's argument area is no larger than the
1213 // caller's.
1214 return NextStackOffset <= FI.getIncomingArgSize();
1215}
1216
1217void MipsSETargetLowering::
1218getOpndList(SmallVectorImpl<SDValue> &Ops,
1219 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
1220 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
1221 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
1222 SDValue Chain) const {
1223 Ops.push_back(Callee);
1224 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
1225 InternalLinkage, IsCallReloc, CLI, Callee,
1226 Chain);
1227}
1228
1229SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
1230 LoadSDNode &Nd = *cast<LoadSDNode>(Op);
1231
1232 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
1233 return MipsTargetLowering::lowerLOAD(Op, DAG);
1234
1235 // Replace a double precision load with two i32 loads and a buildpair64.
1236 SDLoc DL(Op);
1237 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
1238 EVT PtrVT = Ptr.getValueType();
1239
1240 // i32 load from lower address.
1241 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, MachinePointerInfo(),
1242 Nd.getAlign(), Nd.getMemOperand()->getFlags());
1243
1244 // i32 load from higher address.
1245 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, DL, PtrVT));
1246 SDValue Hi = DAG.getLoad(
1247 MVT::i32, DL, Lo.getValue(1), Ptr, MachinePointerInfo(),
1249
1250 if (!Subtarget.isLittle())
1251 std::swap(Lo, Hi);
1252
1253 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
1254 SDValue Ops[2] = {BP, Hi.getValue(1)};
1255 return DAG.getMergeValues(Ops, DL);
1256}
1257
1258SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
1259 StoreSDNode &Nd = *cast<StoreSDNode>(Op);
1260
1261 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
1263
1264 // Replace a double precision store with two extractelement64s and i32 stores.
1265 SDLoc DL(Op);
1266 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
1267 EVT PtrVT = Ptr.getValueType();
1269 Val, DAG.getConstant(0, DL, MVT::i32));
1271 Val, DAG.getConstant(1, DL, MVT::i32));
1272
1273 if (!Subtarget.isLittle())
1274 std::swap(Lo, Hi);
1275
1276 // i32 store to lower address.
1277 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(), Nd.getAlign(),
1278 Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
1279
1280 // i32 store to higher address.
1281 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, DL, PtrVT));
1282 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
1283 commonAlignment(Nd.getAlign(), 4),
1284 Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
1285}
1286
1287SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op,
1288 SelectionDAG &DAG) const {
1289 SDLoc DL(Op);
1290 MVT Src = Op.getOperand(0).getValueType().getSimpleVT();
1291 MVT Dest = Op.getValueType().getSimpleVT();
1292
1293 // Bitcast i64 to double.
1294 if (Src == MVT::i64 && Dest == MVT::f64) {
1295 SDValue Lo, Hi;
1296 std::tie(Lo, Hi) =
1297 DAG.SplitScalar(Op.getOperand(0), DL, MVT::i32, MVT::i32);
1298 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
1299 }
1300
1301 // Bitcast double to i64.
1302 if (Src == MVT::f64 && Dest == MVT::i64) {
1303 // Skip lower bitcast when operand0 has converted float results to integer
1304 // which was done by function SoftenFloatResult.
1305 if (getTypeAction(*DAG.getContext(), Op.getOperand(0).getValueType()) ==
1307 return SDValue();
1308 SDValue Lo =
1309 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
1310 DAG.getConstant(0, DL, MVT::i32));
1311 SDValue Hi =
1312 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
1313 DAG.getConstant(1, DL, MVT::i32));
1314 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
1315 }
1316
1317 // Skip other cases of bitcast and use default lowering.
1318 return SDValue();
1319}
1320
1321SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
1322 bool HasLo, bool HasHi,
1323 SelectionDAG &DAG) const {
1324 // MIPS32r6/MIPS64r6 removed accumulator based multiplies.
1325 assert(!Subtarget.hasMips32r6());
1326
1327 EVT Ty = Op.getOperand(0).getValueType();
1328 SDLoc DL(Op);
1329 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
1330 Op.getOperand(0), Op.getOperand(1));
1331 SDValue Lo, Hi;
1332
1333 if (HasLo)
1334 Lo = DAG.getNode(MipsISD::MFLO, DL, Ty, Mult);
1335 if (HasHi)
1336 Hi = DAG.getNode(MipsISD::MFHI, DL, Ty, Mult);
1337
1338 if (!HasLo || !HasHi)
1339 return HasLo ? Lo : Hi;
1340
1341 SDValue Vals[] = { Lo, Hi };
1342 return DAG.getMergeValues(Vals, DL);
1343}
1344
1346 SDValue InLo, InHi;
1347 std::tie(InLo, InHi) = DAG.SplitScalar(In, DL, MVT::i32, MVT::i32);
1348 return DAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, InLo, InHi);
1349}
1350
1352 SDValue Lo = DAG.getNode(MipsISD::MFLO, DL, MVT::i32, Op);
1353 SDValue Hi = DAG.getNode(MipsISD::MFHI, DL, MVT::i32, Op);
1354 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
1355}
1356
1357// This function expands mips intrinsic nodes which have 64-bit input operands
1358// or output values.
1359//
1360// out64 = intrinsic-node in64
1361// =>
1362// lo = copy (extract-element (in64, 0))
1363// hi = copy (extract-element (in64, 1))
1364// mips-specific-node
1365// v0 = copy lo
1366// v1 = copy hi
1367// out64 = merge-values (v0, v1)
1368//
1370 SDLoc DL(Op);
1371 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
1373 unsigned OpNo = 0;
1374
1375 // See if Op has a chain input.
1376 if (HasChainIn)
1377 Ops.push_back(Op->getOperand(OpNo++));
1378
1379 // The next operand is the intrinsic opcode.
1380 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
1381
1382 // See if the next operand has type i64.
1383 SDValue Opnd = Op->getOperand(++OpNo), In64;
1384
1385 if (Opnd.getValueType() == MVT::i64)
1386 In64 = initAccumulator(Opnd, DL, DAG);
1387 else
1388 Ops.push_back(Opnd);
1389
1390 // Push the remaining operands.
1391 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
1392 Ops.push_back(Op->getOperand(OpNo));
1393
1394 // Add In64 to the end of the list.
1395 if (In64.getNode())
1396 Ops.push_back(In64);
1397
1398 // Scan output.
1399 SmallVector<EVT, 2> ResTys;
1400
1401 for (EVT Ty : Op->values())
1402 ResTys.push_back((Ty == MVT::i64) ? MVT::Untyped : Ty);
1403
1404 // Create node.
1405 SDValue Val = DAG.getNode(Opc, DL, ResTys, Ops);
1406 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
1407
1408 if (!HasChainIn)
1409 return Out;
1410
1411 assert(Val->getValueType(1) == MVT::Other);
1412 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
1413 return DAG.getMergeValues(Vals, DL);
1414}
1415
1416// Lower an MSA copy intrinsic into the specified SelectionDAG node
1418 SDLoc DL(Op);
1419 SDValue Vec = Op->getOperand(1);
1420 SDValue Idx = Op->getOperand(2);
1421 EVT ResTy = Op->getValueType(0);
1422 EVT EltTy = Vec->getValueType(0).getVectorElementType();
1423
1424 SDValue Result = DAG.getNode(Opc, DL, ResTy, Vec, Idx,
1425 DAG.getValueType(EltTy));
1426
1427 return Result;
1428}
1429
1430static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) {
1431 EVT ResVecTy = Op->getValueType(0);
1432 EVT ViaVecTy = ResVecTy;
1433 bool BigEndian = !DAG.getSubtarget().getTargetTriple().isLittleEndian();
1434 SDLoc DL(Op);
1435
1436 // When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and
1437 // LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating
1438 // lanes.
1439 SDValue LaneA = Op->getOperand(OpNr);
1440 SDValue LaneB;
1441
1442 if (ResVecTy == MVT::v2i64) {
1443 // In case of the index being passed as an immediate value, set the upper
1444 // lane to 0 so that the splati.d instruction can be matched.
1445 if (isa<ConstantSDNode>(LaneA))
1446 LaneB = DAG.getConstant(0, DL, MVT::i32);
1447 // Having the index passed in a register, set the upper lane to the same
1448 // value as the lower - this results in the BUILD_VECTOR node not being
1449 // expanded through stack. This way we are able to pattern match the set of
1450 // nodes created here to splat.d.
1451 else
1452 LaneB = LaneA;
1453 ViaVecTy = MVT::v4i32;
1454 if(BigEndian)
1455 std::swap(LaneA, LaneB);
1456 } else
1457 LaneB = LaneA;
1458
1459 SDValue Ops[16] = { LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB,
1460 LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB };
1461
1462 SDValue Result = DAG.getBuildVector(
1463 ViaVecTy, DL, ArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1464
1465 if (ViaVecTy != ResVecTy) {
1466 SDValue One = DAG.getConstant(1, DL, ViaVecTy);
1467 Result = DAG.getNode(ISD::BITCAST, DL, ResVecTy,
1468 DAG.getNode(ISD::AND, DL, ViaVecTy, Result, One));
1469 }
1470
1471 return Result;
1472}
1473
1474static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG,
1475 bool IsSigned = false) {
1476 auto *CImm = cast<ConstantSDNode>(Op->getOperand(ImmOp));
1477 return DAG.getConstant(
1478 APInt(Op->getValueType(0).getScalarType().getSizeInBits(),
1479 IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
1480 SDLoc(Op), Op->getValueType(0));
1481}
1482
1483static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue,
1484 bool BigEndian, SelectionDAG &DAG) {
1485 EVT ViaVecTy = VecTy;
1486 SDValue SplatValueA = SplatValue;
1487 SDValue SplatValueB = SplatValue;
1488 SDLoc DL(SplatValue);
1489
1490 if (VecTy == MVT::v2i64) {
1491 // v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's.
1492 ViaVecTy = MVT::v4i32;
1493
1494 SplatValueA = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValue);
1495 SplatValueB = DAG.getNode(ISD::SRL, DL, MVT::i64, SplatValue,
1496 DAG.getConstant(32, DL, MVT::i32));
1497 SplatValueB = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValueB);
1498 }
1499
1500 // We currently hold the parts in little endian order. Swap them if
1501 // necessary.
1502 if (BigEndian)
1503 std::swap(SplatValueA, SplatValueB);
1504
1505 SDValue Ops[16] = { SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1506 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1507 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1508 SplatValueA, SplatValueB, SplatValueA, SplatValueB };
1509
1510 SDValue Result = DAG.getBuildVector(
1511 ViaVecTy, DL, ArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1512
1513 if (VecTy != ViaVecTy)
1514 Result = DAG.getNode(ISD::BITCAST, DL, VecTy, Result);
1515
1516 return Result;
1517}
1518
1520 unsigned Opc, SDValue Imm,
1521 bool BigEndian) {
1522 EVT VecTy = Op->getValueType(0);
1523 SDValue Exp2Imm;
1524 SDLoc DL(Op);
1525
1526 // The DAG Combiner can't constant fold bitcasted vectors yet so we must do it
1527 // here for now.
1528 if (VecTy == MVT::v2i64) {
1529 if (ConstantSDNode *CImm = dyn_cast<ConstantSDNode>(Imm)) {
1530 APInt BitImm = APInt(64, 1) << CImm->getAPIntValue();
1531
1532 SDValue BitImmHiOp = DAG.getConstant(BitImm.lshr(32).trunc(32), DL,
1533 MVT::i32);
1534 SDValue BitImmLoOp = DAG.getConstant(BitImm.trunc(32), DL, MVT::i32);
1535
1536 if (BigEndian)
1537 std::swap(BitImmLoOp, BitImmHiOp);
1538
1539 Exp2Imm = DAG.getNode(
1540 ISD::BITCAST, DL, MVT::v2i64,
1541 DAG.getBuildVector(MVT::v4i32, DL,
1542 {BitImmLoOp, BitImmHiOp, BitImmLoOp, BitImmHiOp}));
1543 }
1544 }
1545
1546 if (!Exp2Imm.getNode()) {
1547 // We couldnt constant fold, do a vector shift instead
1548
1549 // Extend i32 to i64 if necessary. Sign or zero extend doesn't matter since
1550 // only values 0-63 are valid.
1551 if (VecTy == MVT::v2i64)
1552 Imm = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Imm);
1553
1554 Exp2Imm = getBuildVectorSplat(VecTy, Imm, BigEndian, DAG);
1555
1556 Exp2Imm = DAG.getNode(ISD::SHL, DL, VecTy, DAG.getConstant(1, DL, VecTy),
1557 Exp2Imm);
1558 }
1559
1560 return DAG.getNode(Opc, DL, VecTy, Op->getOperand(1), Exp2Imm);
1561}
1562
1564 SDLoc DL(Op);
1565 EVT ResTy = Op->getValueType(0);
1566 SDValue Vec = Op->getOperand(2);
1567 bool BigEndian = !DAG.getSubtarget().getTargetTriple().isLittleEndian();
1568 MVT ResEltTy = ResTy == MVT::v2i64 ? MVT::i64 : MVT::i32;
1569 SDValue ConstValue = DAG.getConstant(Vec.getScalarValueSizeInBits() - 1,
1570 DL, ResEltTy);
1571 SDValue SplatVec = getBuildVectorSplat(ResTy, ConstValue, BigEndian, DAG);
1572
1573 return DAG.getNode(ISD::AND, DL, ResTy, Vec, SplatVec);
1574}
1575
1577 EVT ResTy = Op->getValueType(0);
1578 SDLoc DL(Op);
1579 SDValue One = DAG.getConstant(1, DL, ResTy);
1580 SDValue Bit = DAG.getNode(ISD::SHL, DL, ResTy, One, truncateVecElts(Op, DAG));
1581
1582 return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1),
1583 DAG.getNOT(DL, Bit, ResTy));
1584}
1585
1587 SDLoc DL(Op);
1588 EVT ResTy = Op->getValueType(0);
1589 APInt BitImm = APInt(ResTy.getScalarSizeInBits(), 1)
1590 << Op->getConstantOperandAPInt(2);
1591 SDValue BitMask = DAG.getConstant(~BitImm, DL, ResTy);
1592
1593 return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1), BitMask);
1594}
1595
1596SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
1597 SelectionDAG &DAG) const {
1598 SDLoc DL(Op);
1599 unsigned Intrinsic = Op->getConstantOperandVal(0);
1600 switch (Intrinsic) {
1601 default:
1602 return SDValue();
1603 case Intrinsic::mips_shilo:
1604 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
1605 case Intrinsic::mips_dpau_h_qbl:
1606 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
1607 case Intrinsic::mips_dpau_h_qbr:
1608 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
1609 case Intrinsic::mips_dpsu_h_qbl:
1610 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
1611 case Intrinsic::mips_dpsu_h_qbr:
1612 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
1613 case Intrinsic::mips_dpa_w_ph:
1614 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
1615 case Intrinsic::mips_dps_w_ph:
1616 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
1617 case Intrinsic::mips_dpax_w_ph:
1618 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
1619 case Intrinsic::mips_dpsx_w_ph:
1620 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
1621 case Intrinsic::mips_mulsa_w_ph:
1622 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
1623 case Intrinsic::mips_mult:
1624 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
1625 case Intrinsic::mips_multu:
1626 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
1627 case Intrinsic::mips_madd:
1628 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
1629 case Intrinsic::mips_maddu:
1630 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
1631 case Intrinsic::mips_msub:
1632 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
1633 case Intrinsic::mips_msubu:
1634 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
1635 case Intrinsic::mips_addv_b:
1636 case Intrinsic::mips_addv_h:
1637 case Intrinsic::mips_addv_w:
1638 case Intrinsic::mips_addv_d:
1639 return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1),
1640 Op->getOperand(2));
1641 case Intrinsic::mips_addvi_b:
1642 case Intrinsic::mips_addvi_h:
1643 case Intrinsic::mips_addvi_w:
1644 case Intrinsic::mips_addvi_d:
1645 return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1),
1646 lowerMSASplatImm(Op, 2, DAG));
1647 case Intrinsic::mips_and_v:
1648 return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1),
1649 Op->getOperand(2));
1650 case Intrinsic::mips_andi_b:
1651 return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1),
1652 lowerMSASplatImm(Op, 2, DAG));
1653 case Intrinsic::mips_bclr_b:
1654 case Intrinsic::mips_bclr_h:
1655 case Intrinsic::mips_bclr_w:
1656 case Intrinsic::mips_bclr_d:
1657 return lowerMSABitClear(Op, DAG);
1658 case Intrinsic::mips_bclri_b:
1659 case Intrinsic::mips_bclri_h:
1660 case Intrinsic::mips_bclri_w:
1661 case Intrinsic::mips_bclri_d:
1662 return lowerMSABitClearImm(Op, DAG);
1663 case Intrinsic::mips_binsli_b:
1664 case Intrinsic::mips_binsli_h:
1665 case Intrinsic::mips_binsli_w:
1666 case Intrinsic::mips_binsli_d: {
1667 // binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear)
1668 EVT VecTy = Op->getValueType(0);
1669 EVT EltTy = VecTy.getVectorElementType();
1670 if (Op->getConstantOperandVal(3) >= EltTy.getSizeInBits())
1671 report_fatal_error("Immediate out of range");
1673 Op->getConstantOperandVal(3) + 1);
1674 return DAG.getNode(ISD::VSELECT, DL, VecTy,
1675 DAG.getConstant(Mask, DL, VecTy, true),
1676 Op->getOperand(2), Op->getOperand(1));
1677 }
1678 case Intrinsic::mips_binsri_b:
1679 case Intrinsic::mips_binsri_h:
1680 case Intrinsic::mips_binsri_w:
1681 case Intrinsic::mips_binsri_d: {
1682 // binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear)
1683 EVT VecTy = Op->getValueType(0);
1684 EVT EltTy = VecTy.getVectorElementType();
1685 if (Op->getConstantOperandVal(3) >= EltTy.getSizeInBits())
1686 report_fatal_error("Immediate out of range");
1687 APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(),
1688 Op->getConstantOperandVal(3) + 1);
1689 return DAG.getNode(ISD::VSELECT, DL, VecTy,
1690 DAG.getConstant(Mask, DL, VecTy, true),
1691 Op->getOperand(2), Op->getOperand(1));
1692 }
1693 case Intrinsic::mips_bmnz_v:
1694 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
1695 Op->getOperand(2), Op->getOperand(1));
1696 case Intrinsic::mips_bmnzi_b:
1697 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1698 lowerMSASplatImm(Op, 3, DAG), Op->getOperand(2),
1699 Op->getOperand(1));
1700 case Intrinsic::mips_bmz_v:
1701 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
1702 Op->getOperand(1), Op->getOperand(2));
1703 case Intrinsic::mips_bmzi_b:
1704 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1705 lowerMSASplatImm(Op, 3, DAG), Op->getOperand(1),
1706 Op->getOperand(2));
1707 case Intrinsic::mips_bneg_b:
1708 case Intrinsic::mips_bneg_h:
1709 case Intrinsic::mips_bneg_w:
1710 case Intrinsic::mips_bneg_d: {
1711 EVT VecTy = Op->getValueType(0);
1712 SDValue One = DAG.getConstant(1, DL, VecTy);
1713
1714 return DAG.getNode(ISD::XOR, DL, VecTy, Op->getOperand(1),
1715 DAG.getNode(ISD::SHL, DL, VecTy, One,
1716 truncateVecElts(Op, DAG)));
1717 }
1718 case Intrinsic::mips_bnegi_b:
1719 case Intrinsic::mips_bnegi_h:
1720 case Intrinsic::mips_bnegi_w:
1721 case Intrinsic::mips_bnegi_d:
1722 return lowerMSABinaryBitImmIntr(Op, DAG, ISD::XOR, Op->getOperand(2),
1723 !Subtarget.isLittle());
1724 case Intrinsic::mips_bnz_b:
1725 case Intrinsic::mips_bnz_h:
1726 case Intrinsic::mips_bnz_w:
1727 case Intrinsic::mips_bnz_d:
1728 return DAG.getNode(MipsISD::VALL_NONZERO, DL, Op->getValueType(0),
1729 Op->getOperand(1));
1730 case Intrinsic::mips_bnz_v:
1731 return DAG.getNode(MipsISD::VANY_NONZERO, DL, Op->getValueType(0),
1732 Op->getOperand(1));
1733 case Intrinsic::mips_bsel_v:
1734 // bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1735 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1736 Op->getOperand(1), Op->getOperand(3),
1737 Op->getOperand(2));
1738 case Intrinsic::mips_bseli_b:
1739 // bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1740 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1741 Op->getOperand(1), lowerMSASplatImm(Op, 3, DAG),
1742 Op->getOperand(2));
1743 case Intrinsic::mips_bset_b:
1744 case Intrinsic::mips_bset_h:
1745 case Intrinsic::mips_bset_w:
1746 case Intrinsic::mips_bset_d: {
1747 EVT VecTy = Op->getValueType(0);
1748 SDValue One = DAG.getConstant(1, DL, VecTy);
1749
1750 return DAG.getNode(ISD::OR, DL, VecTy, Op->getOperand(1),
1751 DAG.getNode(ISD::SHL, DL, VecTy, One,
1752 truncateVecElts(Op, DAG)));
1753 }
1754 case Intrinsic::mips_bseti_b:
1755 case Intrinsic::mips_bseti_h:
1756 case Intrinsic::mips_bseti_w:
1757 case Intrinsic::mips_bseti_d:
1758 return lowerMSABinaryBitImmIntr(Op, DAG, ISD::OR, Op->getOperand(2),
1759 !Subtarget.isLittle());
1760 case Intrinsic::mips_bz_b:
1761 case Intrinsic::mips_bz_h:
1762 case Intrinsic::mips_bz_w:
1763 case Intrinsic::mips_bz_d:
1764 return DAG.getNode(MipsISD::VALL_ZERO, DL, Op->getValueType(0),
1765 Op->getOperand(1));
1766 case Intrinsic::mips_bz_v:
1767 return DAG.getNode(MipsISD::VANY_ZERO, DL, Op->getValueType(0),
1768 Op->getOperand(1));
1769 case Intrinsic::mips_ceq_b:
1770 case Intrinsic::mips_ceq_h:
1771 case Intrinsic::mips_ceq_w:
1772 case Intrinsic::mips_ceq_d:
1773 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1774 Op->getOperand(2), ISD::SETEQ);
1775 case Intrinsic::mips_ceqi_b:
1776 case Intrinsic::mips_ceqi_h:
1777 case Intrinsic::mips_ceqi_w:
1778 case Intrinsic::mips_ceqi_d:
1779 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1780 lowerMSASplatImm(Op, 2, DAG, true), ISD::SETEQ);
1781 case Intrinsic::mips_cle_s_b:
1782 case Intrinsic::mips_cle_s_h:
1783 case Intrinsic::mips_cle_s_w:
1784 case Intrinsic::mips_cle_s_d:
1785 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1786 Op->getOperand(2), ISD::SETLE);
1787 case Intrinsic::mips_clei_s_b:
1788 case Intrinsic::mips_clei_s_h:
1789 case Intrinsic::mips_clei_s_w:
1790 case Intrinsic::mips_clei_s_d:
1791 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1792 lowerMSASplatImm(Op, 2, DAG, true), ISD::SETLE);
1793 case Intrinsic::mips_cle_u_b:
1794 case Intrinsic::mips_cle_u_h:
1795 case Intrinsic::mips_cle_u_w:
1796 case Intrinsic::mips_cle_u_d:
1797 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1798 Op->getOperand(2), ISD::SETULE);
1799 case Intrinsic::mips_clei_u_b:
1800 case Intrinsic::mips_clei_u_h:
1801 case Intrinsic::mips_clei_u_w:
1802 case Intrinsic::mips_clei_u_d:
1803 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1804 lowerMSASplatImm(Op, 2, DAG), ISD::SETULE);
1805 case Intrinsic::mips_clt_s_b:
1806 case Intrinsic::mips_clt_s_h:
1807 case Intrinsic::mips_clt_s_w:
1808 case Intrinsic::mips_clt_s_d:
1809 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1810 Op->getOperand(2), ISD::SETLT);
1811 case Intrinsic::mips_clti_s_b:
1812 case Intrinsic::mips_clti_s_h:
1813 case Intrinsic::mips_clti_s_w:
1814 case Intrinsic::mips_clti_s_d:
1815 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1816 lowerMSASplatImm(Op, 2, DAG, true), ISD::SETLT);
1817 case Intrinsic::mips_clt_u_b:
1818 case Intrinsic::mips_clt_u_h:
1819 case Intrinsic::mips_clt_u_w:
1820 case Intrinsic::mips_clt_u_d:
1821 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1822 Op->getOperand(2), ISD::SETULT);
1823 case Intrinsic::mips_clti_u_b:
1824 case Intrinsic::mips_clti_u_h:
1825 case Intrinsic::mips_clti_u_w:
1826 case Intrinsic::mips_clti_u_d:
1827 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1828 lowerMSASplatImm(Op, 2, DAG), ISD::SETULT);
1829 case Intrinsic::mips_copy_s_b:
1830 case Intrinsic::mips_copy_s_h:
1831 case Intrinsic::mips_copy_s_w:
1833 case Intrinsic::mips_copy_s_d:
1834 if (Subtarget.hasMips64())
1835 // Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64.
1837 else {
1838 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
1839 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
1840 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
1841 Op->getValueType(0), Op->getOperand(1),
1842 Op->getOperand(2));
1843 }
1844 case Intrinsic::mips_copy_u_b:
1845 case Intrinsic::mips_copy_u_h:
1846 case Intrinsic::mips_copy_u_w:
1848 case Intrinsic::mips_copy_u_d:
1849 if (Subtarget.hasMips64())
1850 // Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64.
1852 else {
1853 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
1854 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
1855 // Note: When i64 is illegal, this results in copy_s.w instructions
1856 // instead of copy_u.w instructions. This makes no difference to the
1857 // behaviour since i64 is only illegal when the register file is 32-bit.
1858 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
1859 Op->getValueType(0), Op->getOperand(1),
1860 Op->getOperand(2));
1861 }
1862 case Intrinsic::mips_div_s_b:
1863 case Intrinsic::mips_div_s_h:
1864 case Intrinsic::mips_div_s_w:
1865 case Intrinsic::mips_div_s_d:
1866 return DAG.getNode(ISD::SDIV, DL, Op->getValueType(0), Op->getOperand(1),
1867 Op->getOperand(2));
1868 case Intrinsic::mips_div_u_b:
1869 case Intrinsic::mips_div_u_h:
1870 case Intrinsic::mips_div_u_w:
1871 case Intrinsic::mips_div_u_d:
1872 return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1),
1873 Op->getOperand(2));
1874 case Intrinsic::mips_fadd_w:
1875 case Intrinsic::mips_fadd_d:
1876 // TODO: If intrinsics have fast-math-flags, propagate them.
1877 return DAG.getNode(ISD::FADD, DL, Op->getValueType(0), Op->getOperand(1),
1878 Op->getOperand(2));
1879 // Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away
1880 case Intrinsic::mips_fceq_w:
1881 case Intrinsic::mips_fceq_d:
1882 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1883 Op->getOperand(2), ISD::SETOEQ);
1884 case Intrinsic::mips_fcle_w:
1885 case Intrinsic::mips_fcle_d:
1886 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1887 Op->getOperand(2), ISD::SETOLE);
1888 case Intrinsic::mips_fclt_w:
1889 case Intrinsic::mips_fclt_d:
1890 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1891 Op->getOperand(2), ISD::SETOLT);
1892 case Intrinsic::mips_fcne_w:
1893 case Intrinsic::mips_fcne_d:
1894 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1895 Op->getOperand(2), ISD::SETONE);
1896 case Intrinsic::mips_fcor_w:
1897 case Intrinsic::mips_fcor_d:
1898 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1899 Op->getOperand(2), ISD::SETO);
1900 case Intrinsic::mips_fcueq_w:
1901 case Intrinsic::mips_fcueq_d:
1902 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1903 Op->getOperand(2), ISD::SETUEQ);
1904 case Intrinsic::mips_fcule_w:
1905 case Intrinsic::mips_fcule_d:
1906 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1907 Op->getOperand(2), ISD::SETULE);
1908 case Intrinsic::mips_fcult_w:
1909 case Intrinsic::mips_fcult_d:
1910 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1911 Op->getOperand(2), ISD::SETULT);
1912 case Intrinsic::mips_fcun_w:
1913 case Intrinsic::mips_fcun_d:
1914 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1915 Op->getOperand(2), ISD::SETUO);
1916 case Intrinsic::mips_fcune_w:
1917 case Intrinsic::mips_fcune_d:
1918 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1919 Op->getOperand(2), ISD::SETUNE);
1920 case Intrinsic::mips_fdiv_w:
1921 case Intrinsic::mips_fdiv_d:
1922 // TODO: If intrinsics have fast-math-flags, propagate them.
1923 return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1),
1924 Op->getOperand(2));
1925 case Intrinsic::mips_ffint_u_w:
1926 case Intrinsic::mips_ffint_u_d:
1927 return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0),
1928 Op->getOperand(1));
1929 case Intrinsic::mips_ffint_s_w:
1930 case Intrinsic::mips_ffint_s_d:
1931 return DAG.getNode(ISD::SINT_TO_FP, DL, Op->getValueType(0),
1932 Op->getOperand(1));
1933 case Intrinsic::mips_fill_b:
1934 case Intrinsic::mips_fill_h:
1935 case Intrinsic::mips_fill_w:
1936 case Intrinsic::mips_fill_d: {
1937 EVT ResTy = Op->getValueType(0);
1939 Op->getOperand(1));
1940
1941 // If ResTy is v2i64 then the type legalizer will break this node down into
1942 // an equivalent v4i32.
1943 return DAG.getBuildVector(ResTy, DL, Ops);
1944 }
1945 case Intrinsic::mips_fexp2_w:
1946 case Intrinsic::mips_fexp2_d: {
1947 // TODO: If intrinsics have fast-math-flags, propagate them.
1948 EVT ResTy = Op->getValueType(0);
1949 return DAG.getNode(
1950 ISD::FMUL, SDLoc(Op), ResTy, Op->getOperand(1),
1951 DAG.getNode(ISD::FEXP2, SDLoc(Op), ResTy, Op->getOperand(2)));
1952 }
1953 case Intrinsic::mips_flog2_w:
1954 case Intrinsic::mips_flog2_d:
1955 return DAG.getNode(ISD::FLOG2, DL, Op->getValueType(0), Op->getOperand(1));
1956 case Intrinsic::mips_fmadd_w:
1957 case Intrinsic::mips_fmadd_d:
1958 return DAG.getNode(ISD::FMA, SDLoc(Op), Op->getValueType(0),
1959 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
1960 case Intrinsic::mips_fmul_w:
1961 case Intrinsic::mips_fmul_d:
1962 // TODO: If intrinsics have fast-math-flags, propagate them.
1963 return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1),
1964 Op->getOperand(2));
1965 case Intrinsic::mips_fmsub_w:
1966 case Intrinsic::mips_fmsub_d: {
1967 // TODO: If intrinsics have fast-math-flags, propagate them.
1968 return DAG.getNode(MipsISD::FMS, SDLoc(Op), Op->getValueType(0),
1969 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
1970 }
1971 case Intrinsic::mips_frint_w:
1972 case Intrinsic::mips_frint_d:
1973 return DAG.getNode(ISD::FRINT, DL, Op->getValueType(0), Op->getOperand(1));
1974 case Intrinsic::mips_fsqrt_w:
1975 case Intrinsic::mips_fsqrt_d:
1976 return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1));
1977 case Intrinsic::mips_fsub_w:
1978 case Intrinsic::mips_fsub_d:
1979 // TODO: If intrinsics have fast-math-flags, propagate them.
1980 return DAG.getNode(ISD::FSUB, DL, Op->getValueType(0), Op->getOperand(1),
1981 Op->getOperand(2));
1982 case Intrinsic::mips_ftrunc_u_w:
1983 case Intrinsic::mips_ftrunc_u_d:
1984 return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0),
1985 Op->getOperand(1));
1986 case Intrinsic::mips_ftrunc_s_w:
1987 case Intrinsic::mips_ftrunc_s_d:
1988 return DAG.getNode(ISD::FP_TO_SINT, DL, Op->getValueType(0),
1989 Op->getOperand(1));
1990 case Intrinsic::mips_ilvev_b:
1991 case Intrinsic::mips_ilvev_h:
1992 case Intrinsic::mips_ilvev_w:
1993 case Intrinsic::mips_ilvev_d:
1994 return DAG.getNode(MipsISD::ILVEV, DL, Op->getValueType(0),
1995 Op->getOperand(1), Op->getOperand(2));
1996 case Intrinsic::mips_ilvl_b:
1997 case Intrinsic::mips_ilvl_h:
1998 case Intrinsic::mips_ilvl_w:
1999 case Intrinsic::mips_ilvl_d:
2000 return DAG.getNode(MipsISD::ILVL, DL, Op->getValueType(0),
2001 Op->getOperand(1), Op->getOperand(2));
2002 case Intrinsic::mips_ilvod_b:
2003 case Intrinsic::mips_ilvod_h:
2004 case Intrinsic::mips_ilvod_w:
2005 case Intrinsic::mips_ilvod_d:
2006 return DAG.getNode(MipsISD::ILVOD, DL, Op->getValueType(0),
2007 Op->getOperand(1), Op->getOperand(2));
2008 case Intrinsic::mips_ilvr_b:
2009 case Intrinsic::mips_ilvr_h:
2010 case Intrinsic::mips_ilvr_w:
2011 case Intrinsic::mips_ilvr_d:
2012 return DAG.getNode(MipsISD::ILVR, DL, Op->getValueType(0),
2013 Op->getOperand(1), Op->getOperand(2));
2014 case Intrinsic::mips_insert_b:
2015 case Intrinsic::mips_insert_h:
2016 case Intrinsic::mips_insert_w:
2017 case Intrinsic::mips_insert_d:
2018 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), Op->getValueType(0),
2019 Op->getOperand(1), Op->getOperand(3), Op->getOperand(2));
2020 case Intrinsic::mips_insve_b:
2021 case Intrinsic::mips_insve_h:
2022 case Intrinsic::mips_insve_w:
2023 case Intrinsic::mips_insve_d: {
2024 // Report an error for out of range values.
2025 int64_t Max;
2026 switch (Intrinsic) {
2027 case Intrinsic::mips_insve_b: Max = 15; break;
2028 case Intrinsic::mips_insve_h: Max = 7; break;
2029 case Intrinsic::mips_insve_w: Max = 3; break;
2030 case Intrinsic::mips_insve_d: Max = 1; break;
2031 default: llvm_unreachable("Unmatched intrinsic");
2032 }
2033 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2034 if (Value < 0 || Value > Max)
2035 report_fatal_error("Immediate out of range");
2036 return DAG.getNode(MipsISD::INSVE, DL, Op->getValueType(0),
2037 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3),
2038 DAG.getConstant(0, DL, MVT::i32));
2039 }
2040 case Intrinsic::mips_ldi_b:
2041 case Intrinsic::mips_ldi_h:
2042 case Intrinsic::mips_ldi_w:
2043 case Intrinsic::mips_ldi_d:
2044 return lowerMSASplatImm(Op, 1, DAG, true);
2045 case Intrinsic::mips_lsa:
2046 case Intrinsic::mips_dlsa: {
2047 EVT ResTy = Op->getValueType(0);
2048 return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1),
2049 DAG.getNode(ISD::SHL, SDLoc(Op), ResTy,
2050 Op->getOperand(2), Op->getOperand(3)));
2051 }
2052 case Intrinsic::mips_maddv_b:
2053 case Intrinsic::mips_maddv_h:
2054 case Intrinsic::mips_maddv_w:
2055 case Intrinsic::mips_maddv_d: {
2056 EVT ResTy = Op->getValueType(0);
2057 return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1),
2058 DAG.getNode(ISD::MUL, SDLoc(Op), ResTy,
2059 Op->getOperand(2), Op->getOperand(3)));
2060 }
2061 case Intrinsic::mips_max_s_b:
2062 case Intrinsic::mips_max_s_h:
2063 case Intrinsic::mips_max_s_w:
2064 case Intrinsic::mips_max_s_d:
2065 return DAG.getNode(ISD::SMAX, DL, Op->getValueType(0),
2066 Op->getOperand(1), Op->getOperand(2));
2067 case Intrinsic::mips_max_u_b:
2068 case Intrinsic::mips_max_u_h:
2069 case Intrinsic::mips_max_u_w:
2070 case Intrinsic::mips_max_u_d:
2071 return DAG.getNode(ISD::UMAX, DL, Op->getValueType(0),
2072 Op->getOperand(1), Op->getOperand(2));
2073 case Intrinsic::mips_maxi_s_b:
2074 case Intrinsic::mips_maxi_s_h:
2075 case Intrinsic::mips_maxi_s_w:
2076 case Intrinsic::mips_maxi_s_d:
2077 return DAG.getNode(ISD::SMAX, DL, Op->getValueType(0),
2078 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG, true));
2079 case Intrinsic::mips_maxi_u_b:
2080 case Intrinsic::mips_maxi_u_h:
2081 case Intrinsic::mips_maxi_u_w:
2082 case Intrinsic::mips_maxi_u_d:
2083 return DAG.getNode(ISD::UMAX, DL, Op->getValueType(0),
2084 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2085 case Intrinsic::mips_min_s_b:
2086 case Intrinsic::mips_min_s_h:
2087 case Intrinsic::mips_min_s_w:
2088 case Intrinsic::mips_min_s_d:
2089 return DAG.getNode(ISD::SMIN, DL, Op->getValueType(0),
2090 Op->getOperand(1), Op->getOperand(2));
2091 case Intrinsic::mips_min_u_b:
2092 case Intrinsic::mips_min_u_h:
2093 case Intrinsic::mips_min_u_w:
2094 case Intrinsic::mips_min_u_d:
2095 return DAG.getNode(ISD::UMIN, DL, Op->getValueType(0),
2096 Op->getOperand(1), Op->getOperand(2));
2097 case Intrinsic::mips_mini_s_b:
2098 case Intrinsic::mips_mini_s_h:
2099 case Intrinsic::mips_mini_s_w:
2100 case Intrinsic::mips_mini_s_d:
2101 return DAG.getNode(ISD::SMIN, DL, Op->getValueType(0),
2102 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG, true));
2103 case Intrinsic::mips_mini_u_b:
2104 case Intrinsic::mips_mini_u_h:
2105 case Intrinsic::mips_mini_u_w:
2106 case Intrinsic::mips_mini_u_d:
2107 return DAG.getNode(ISD::UMIN, DL, Op->getValueType(0),
2108 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2109 case Intrinsic::mips_mod_s_b:
2110 case Intrinsic::mips_mod_s_h:
2111 case Intrinsic::mips_mod_s_w:
2112 case Intrinsic::mips_mod_s_d:
2113 return DAG.getNode(ISD::SREM, DL, Op->getValueType(0), Op->getOperand(1),
2114 Op->getOperand(2));
2115 case Intrinsic::mips_mod_u_b:
2116 case Intrinsic::mips_mod_u_h:
2117 case Intrinsic::mips_mod_u_w:
2118 case Intrinsic::mips_mod_u_d:
2119 return DAG.getNode(ISD::UREM, DL, Op->getValueType(0), Op->getOperand(1),
2120 Op->getOperand(2));
2121 case Intrinsic::mips_mulv_b:
2122 case Intrinsic::mips_mulv_h:
2123 case Intrinsic::mips_mulv_w:
2124 case Intrinsic::mips_mulv_d:
2125 return DAG.getNode(ISD::MUL, DL, Op->getValueType(0), Op->getOperand(1),
2126 Op->getOperand(2));
2127 case Intrinsic::mips_msubv_b:
2128 case Intrinsic::mips_msubv_h:
2129 case Intrinsic::mips_msubv_w:
2130 case Intrinsic::mips_msubv_d: {
2131 EVT ResTy = Op->getValueType(0);
2132 return DAG.getNode(ISD::SUB, SDLoc(Op), ResTy, Op->getOperand(1),
2133 DAG.getNode(ISD::MUL, SDLoc(Op), ResTy,
2134 Op->getOperand(2), Op->getOperand(3)));
2135 }
2136 case Intrinsic::mips_nlzc_b:
2137 case Intrinsic::mips_nlzc_h:
2138 case Intrinsic::mips_nlzc_w:
2139 case Intrinsic::mips_nlzc_d:
2140 return DAG.getNode(ISD::CTLZ, DL, Op->getValueType(0), Op->getOperand(1));
2141 case Intrinsic::mips_nor_v: {
2142 SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2143 Op->getOperand(1), Op->getOperand(2));
2144 return DAG.getNOT(DL, Res, Res->getValueType(0));
2145 }
2146 case Intrinsic::mips_nori_b: {
2147 SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2148 Op->getOperand(1),
2149 lowerMSASplatImm(Op, 2, DAG));
2150 return DAG.getNOT(DL, Res, Res->getValueType(0));
2151 }
2152 case Intrinsic::mips_or_v:
2153 return DAG.getNode(ISD::OR, DL, Op->getValueType(0), Op->getOperand(1),
2154 Op->getOperand(2));
2155 case Intrinsic::mips_ori_b:
2156 return DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2157 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2158 case Intrinsic::mips_pckev_b:
2159 case Intrinsic::mips_pckev_h:
2160 case Intrinsic::mips_pckev_w:
2161 case Intrinsic::mips_pckev_d:
2162 return DAG.getNode(MipsISD::PCKEV, DL, Op->getValueType(0),
2163 Op->getOperand(1), Op->getOperand(2));
2164 case Intrinsic::mips_pckod_b:
2165 case Intrinsic::mips_pckod_h:
2166 case Intrinsic::mips_pckod_w:
2167 case Intrinsic::mips_pckod_d:
2168 return DAG.getNode(MipsISD::PCKOD, DL, Op->getValueType(0),
2169 Op->getOperand(1), Op->getOperand(2));
2170 case Intrinsic::mips_pcnt_b:
2171 case Intrinsic::mips_pcnt_h:
2172 case Intrinsic::mips_pcnt_w:
2173 case Intrinsic::mips_pcnt_d:
2174 return DAG.getNode(ISD::CTPOP, DL, Op->getValueType(0), Op->getOperand(1));
2175 case Intrinsic::mips_sat_s_b:
2176 case Intrinsic::mips_sat_s_h:
2177 case Intrinsic::mips_sat_s_w:
2178 case Intrinsic::mips_sat_s_d:
2179 case Intrinsic::mips_sat_u_b:
2180 case Intrinsic::mips_sat_u_h:
2181 case Intrinsic::mips_sat_u_w:
2182 case Intrinsic::mips_sat_u_d: {
2183 // Report an error for out of range values.
2184 int64_t Max;
2185 switch (Intrinsic) {
2186 case Intrinsic::mips_sat_s_b:
2187 case Intrinsic::mips_sat_u_b: Max = 7; break;
2188 case Intrinsic::mips_sat_s_h:
2189 case Intrinsic::mips_sat_u_h: Max = 15; break;
2190 case Intrinsic::mips_sat_s_w:
2191 case Intrinsic::mips_sat_u_w: Max = 31; break;
2192 case Intrinsic::mips_sat_s_d:
2193 case Intrinsic::mips_sat_u_d: Max = 63; break;
2194 default: llvm_unreachable("Unmatched intrinsic");
2195 }
2196 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2197 if (Value < 0 || Value > Max)
2198 report_fatal_error("Immediate out of range");
2199 return SDValue();
2200 }
2201 case Intrinsic::mips_shf_b:
2202 case Intrinsic::mips_shf_h:
2203 case Intrinsic::mips_shf_w: {
2204 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2205 if (Value < 0 || Value > 255)
2206 report_fatal_error("Immediate out of range");
2207 return DAG.getNode(MipsISD::SHF, DL, Op->getValueType(0),
2208 Op->getOperand(2), Op->getOperand(1));
2209 }
2210 case Intrinsic::mips_sldi_b:
2211 case Intrinsic::mips_sldi_h:
2212 case Intrinsic::mips_sldi_w:
2213 case Intrinsic::mips_sldi_d: {
2214 // Report an error for out of range values.
2215 int64_t Max;
2216 switch (Intrinsic) {
2217 case Intrinsic::mips_sldi_b: Max = 15; break;
2218 case Intrinsic::mips_sldi_h: Max = 7; break;
2219 case Intrinsic::mips_sldi_w: Max = 3; break;
2220 case Intrinsic::mips_sldi_d: Max = 1; break;
2221 default: llvm_unreachable("Unmatched intrinsic");
2222 }
2223 int64_t Value = cast<ConstantSDNode>(Op->getOperand(3))->getSExtValue();
2224 if (Value < 0 || Value > Max)
2225 report_fatal_error("Immediate out of range");
2226 return SDValue();
2227 }
2228 case Intrinsic::mips_sll_b:
2229 case Intrinsic::mips_sll_h:
2230 case Intrinsic::mips_sll_w:
2231 case Intrinsic::mips_sll_d:
2232 return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), Op->getOperand(1),
2233 truncateVecElts(Op, DAG));
2234 case Intrinsic::mips_slli_b:
2235 case Intrinsic::mips_slli_h:
2236 case Intrinsic::mips_slli_w:
2237 case Intrinsic::mips_slli_d:
2238 return DAG.getNode(ISD::SHL, DL, Op->getValueType(0),
2239 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2240 case Intrinsic::mips_splat_b:
2241 case Intrinsic::mips_splat_h:
2242 case Intrinsic::mips_splat_w:
2243 case Intrinsic::mips_splat_d:
2244 // We can't lower via VECTOR_SHUFFLE because it requires constant shuffle
2245 // masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because
2246 // EXTRACT_VECTOR_ELT can't extract i64's on MIPS32.
2247 // Instead we lower to MipsISD::VSHF and match from there.
2248 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2249 lowerMSASplatZExt(Op, 2, DAG), Op->getOperand(1),
2250 Op->getOperand(1));
2251 case Intrinsic::mips_splati_b:
2252 case Intrinsic::mips_splati_h:
2253 case Intrinsic::mips_splati_w:
2254 case Intrinsic::mips_splati_d:
2255 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2256 lowerMSASplatImm(Op, 2, DAG), Op->getOperand(1),
2257 Op->getOperand(1));
2258 case Intrinsic::mips_sra_b:
2259 case Intrinsic::mips_sra_h:
2260 case Intrinsic::mips_sra_w:
2261 case Intrinsic::mips_sra_d:
2262 return DAG.getNode(ISD::SRA, DL, Op->getValueType(0), Op->getOperand(1),
2263 truncateVecElts(Op, DAG));
2264 case Intrinsic::mips_srai_b:
2265 case Intrinsic::mips_srai_h:
2266 case Intrinsic::mips_srai_w:
2267 case Intrinsic::mips_srai_d:
2268 return DAG.getNode(ISD::SRA, DL, Op->getValueType(0),
2269 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2270 case Intrinsic::mips_srari_b:
2271 case Intrinsic::mips_srari_h:
2272 case Intrinsic::mips_srari_w:
2273 case Intrinsic::mips_srari_d: {
2274 // Report an error for out of range values.
2275 int64_t Max;
2276 switch (Intrinsic) {
2277 case Intrinsic::mips_srari_b: Max = 7; break;
2278 case Intrinsic::mips_srari_h: Max = 15; break;
2279 case Intrinsic::mips_srari_w: Max = 31; break;
2280 case Intrinsic::mips_srari_d: Max = 63; break;
2281 default: llvm_unreachable("Unmatched intrinsic");
2282 }
2283 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2284 if (Value < 0 || Value > Max)
2285 report_fatal_error("Immediate out of range");
2286 return SDValue();
2287 }
2288 case Intrinsic::mips_srl_b:
2289 case Intrinsic::mips_srl_h:
2290 case Intrinsic::mips_srl_w:
2291 case Intrinsic::mips_srl_d:
2292 return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), Op->getOperand(1),
2293 truncateVecElts(Op, DAG));
2294 case Intrinsic::mips_srli_b:
2295 case Intrinsic::mips_srli_h:
2296 case Intrinsic::mips_srli_w:
2297 case Intrinsic::mips_srli_d:
2298 return DAG.getNode(ISD::SRL, DL, Op->getValueType(0),
2299 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2300 case Intrinsic::mips_srlri_b:
2301 case Intrinsic::mips_srlri_h:
2302 case Intrinsic::mips_srlri_w:
2303 case Intrinsic::mips_srlri_d: {
2304 // Report an error for out of range values.
2305 int64_t Max;
2306 switch (Intrinsic) {
2307 case Intrinsic::mips_srlri_b: Max = 7; break;
2308 case Intrinsic::mips_srlri_h: Max = 15; break;
2309 case Intrinsic::mips_srlri_w: Max = 31; break;
2310 case Intrinsic::mips_srlri_d: Max = 63; break;
2311 default: llvm_unreachable("Unmatched intrinsic");
2312 }
2313 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2314 if (Value < 0 || Value > Max)
2315 report_fatal_error("Immediate out of range");
2316 return SDValue();
2317 }
2318 case Intrinsic::mips_subv_b:
2319 case Intrinsic::mips_subv_h:
2320 case Intrinsic::mips_subv_w:
2321 case Intrinsic::mips_subv_d:
2322 return DAG.getNode(ISD::SUB, DL, Op->getValueType(0), Op->getOperand(1),
2323 Op->getOperand(2));
2324 case Intrinsic::mips_subvi_b:
2325 case Intrinsic::mips_subvi_h:
2326 case Intrinsic::mips_subvi_w:
2327 case Intrinsic::mips_subvi_d:
2328 return DAG.getNode(ISD::SUB, DL, Op->getValueType(0),
2329 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2330 case Intrinsic::mips_vshf_b:
2331 case Intrinsic::mips_vshf_h:
2332 case Intrinsic::mips_vshf_w:
2333 case Intrinsic::mips_vshf_d:
2334 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2335 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
2336 case Intrinsic::mips_xor_v:
2337 return DAG.getNode(ISD::XOR, DL, Op->getValueType(0), Op->getOperand(1),
2338 Op->getOperand(2));
2339 case Intrinsic::mips_xori_b:
2340 return DAG.getNode(ISD::XOR, DL, Op->getValueType(0),
2341 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2342 case Intrinsic::thread_pointer: {
2343 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2344 return DAG.getNode(MipsISD::ThreadPointer, DL, PtrVT);
2345 }
2346 }
2347}
2348
2349static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr,
2350 const MipsSubtarget &Subtarget) {
2351 SDLoc DL(Op);
2352 SDValue ChainIn = Op->getOperand(0);
2353 SDValue Address = Op->getOperand(2);
2354 SDValue Offset = Op->getOperand(3);
2355 EVT ResTy = Op->getValueType(0);
2356 EVT PtrTy = Address->getValueType(0);
2357
2358 // For N64 addresses have the underlying type MVT::i64. This intrinsic
2359 // however takes an i32 signed constant offset. The actual type of the
2360 // intrinsic is a scaled signed i10.
2361 if (Subtarget.isABI_N64())
2362 Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset);
2363
2364 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
2365 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(),
2366 Align(16));
2367}
2368
2369SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
2370 SelectionDAG &DAG) const {
2371 unsigned Intr = Op->getConstantOperandVal(1);
2372 switch (Intr) {
2373 default:
2374 return SDValue();
2375 case Intrinsic::mips_extp:
2376 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
2377 case Intrinsic::mips_extpdp:
2378 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
2379 case Intrinsic::mips_extr_w:
2380 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
2381 case Intrinsic::mips_extr_r_w:
2382 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
2383 case Intrinsic::mips_extr_rs_w:
2384 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
2385 case Intrinsic::mips_extr_s_h:
2386 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
2387 case Intrinsic::mips_mthlip:
2388 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
2389 case Intrinsic::mips_mulsaq_s_w_ph:
2391 case Intrinsic::mips_maq_s_w_phl:
2392 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
2393 case Intrinsic::mips_maq_s_w_phr:
2394 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
2395 case Intrinsic::mips_maq_sa_w_phl:
2397 case Intrinsic::mips_maq_sa_w_phr:
2399 case Intrinsic::mips_dpaq_s_w_ph:
2400 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
2401 case Intrinsic::mips_dpsq_s_w_ph:
2402 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
2403 case Intrinsic::mips_dpaq_sa_l_w:
2404 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
2405 case Intrinsic::mips_dpsq_sa_l_w:
2406 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
2407 case Intrinsic::mips_dpaqx_s_w_ph:
2409 case Intrinsic::mips_dpaqx_sa_w_ph:
2411 case Intrinsic::mips_dpsqx_s_w_ph:
2413 case Intrinsic::mips_dpsqx_sa_w_ph:
2415 case Intrinsic::mips_ld_b:
2416 case Intrinsic::mips_ld_h:
2417 case Intrinsic::mips_ld_w:
2418 case Intrinsic::mips_ld_d:
2419 return lowerMSALoadIntr(Op, DAG, Intr, Subtarget);
2420 }
2421}
2422
2424 const MipsSubtarget &Subtarget) {
2425 SDLoc DL(Op);
2426 SDValue ChainIn = Op->getOperand(0);
2427 SDValue Value = Op->getOperand(2);
2428 SDValue Address = Op->getOperand(3);
2429 SDValue Offset = Op->getOperand(4);
2430 EVT PtrTy = Address->getValueType(0);
2431
2432 // For N64 addresses have the underlying type MVT::i64. This intrinsic
2433 // however takes an i32 signed constant offset. The actual type of the
2434 // intrinsic is a scaled signed i10.
2435 if (Subtarget.isABI_N64())
2436 Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset);
2437
2438 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
2439
2440 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(),
2441 Align(16));
2442}
2443
2444SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
2445 SelectionDAG &DAG) const {
2446 unsigned Intr = Op->getConstantOperandVal(1);
2447 switch (Intr) {
2448 default:
2449 return SDValue();
2450 case Intrinsic::mips_st_b:
2451 case Intrinsic::mips_st_h:
2452 case Intrinsic::mips_st_w:
2453 case Intrinsic::mips_st_d:
2454 return lowerMSAStoreIntr(Op, DAG, Intr, Subtarget);
2455 }
2456}
2457
2458// Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT.
2459//
2460// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We
2461// choose to sign-extend but we could have equally chosen zero-extend. The
2462// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT
2463// result into this node later (possibly changing it to a zero-extend in the
2464// process).
2465SDValue MipsSETargetLowering::
2466lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const {
2467 SDLoc DL(Op);
2468 EVT ResTy = Op->getValueType(0);
2469 SDValue Op0 = Op->getOperand(0);
2470 EVT VecTy = Op0->getValueType(0);
2471
2472 if (!VecTy.is128BitVector())
2473 return SDValue();
2474
2475 if (ResTy.isInteger()) {
2476 SDValue Op1 = Op->getOperand(1);
2477 EVT EltTy = VecTy.getVectorElementType();
2478 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1,
2479 DAG.getValueType(EltTy));
2480 }
2481
2482 return Op;
2483}
2484
2485static bool isConstantOrUndef(const SDValue Op) {
2486 if (Op->isUndef())
2487 return true;
2489 return true;
2491 return true;
2492 return false;
2493}
2494
2496 for (unsigned i = 0; i < Op->getNumOperands(); ++i)
2497 if (isConstantOrUndef(Op->getOperand(i)))
2498 return true;
2499 return false;
2500}
2501
2502// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
2503// backend.
2504//
2505// Lowers according to the following rules:
2506// - Constant splats are legal as-is as long as the SplatBitSize is a power of
2507// 2 less than or equal to 64 and the value fits into a signed 10-bit
2508// immediate
2509// - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize
2510// is a power of 2 less than or equal to 64 and the value does not fit into a
2511// signed 10-bit immediate
2512// - Non-constant splats are legal as-is.
2513// - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT.
2514// - All others are illegal and must be expanded.
2515SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
2516 SelectionDAG &DAG) const {
2517 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
2518 EVT ResTy = Op->getValueType(0);
2519 SDLoc DL(Op);
2520 APInt SplatValue, SplatUndef;
2521 unsigned SplatBitSize;
2522 bool HasAnyUndefs;
2523
2524 if (!Subtarget.hasMSA() || !ResTy.is128BitVector())
2525 return SDValue();
2526
2527 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2528 HasAnyUndefs, 8,
2529 !Subtarget.isLittle()) && SplatBitSize <= 64) {
2530 // We can only cope with 8, 16, 32, or 64-bit elements
2531 if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
2532 SplatBitSize != 64)
2533 return SDValue();
2534
2535 // If the value isn't an integer type we will have to bitcast
2536 // from an integer type first. Also, if there are any undefs, we must
2537 // lower them to defined values first.
2538 if (ResTy.isInteger() && !HasAnyUndefs)
2539 return Op;
2540
2541 EVT ViaVecTy;
2542
2543 switch (SplatBitSize) {
2544 default:
2545 return SDValue();
2546 case 8:
2547 ViaVecTy = MVT::v16i8;
2548 break;
2549 case 16:
2550 ViaVecTy = MVT::v8i16;
2551 break;
2552 case 32:
2553 ViaVecTy = MVT::v4i32;
2554 break;
2555 case 64:
2556 // There's no fill.d to fall back on for 64-bit values
2557 return SDValue();
2558 }
2559
2560 // SelectionDAG::getConstant will promote SplatValue appropriately.
2561 SDValue Result = DAG.getConstant(SplatValue, DL, ViaVecTy);
2562
2563 // Bitcast to the type we originally wanted
2564 if (ViaVecTy != ResTy)
2565 Result = DAG.getNode(ISD::BITCAST, SDLoc(Node), ResTy, Result);
2566
2567 return Result;
2568 } else if (DAG.isSplatValue(Op, /* AllowUndefs */ false))
2569 return Op;
2570 else if (!isConstantOrUndefBUILD_VECTOR(Node)) {
2571 // Use INSERT_VECTOR_ELT operations rather than expand to stores.
2572 // The resulting code is the same length as the expansion, but it doesn't
2573 // use memory operations
2574 EVT ResTy = Node->getValueType(0);
2575
2576 assert(ResTy.isVector());
2577
2578 unsigned NumElts = ResTy.getVectorNumElements();
2579 SDValue Vector = DAG.getUNDEF(ResTy);
2580 for (unsigned i = 0; i < NumElts; ++i) {
2582 Node->getOperand(i),
2583 DAG.getConstant(i, DL, MVT::i32));
2584 }
2585 return Vector;
2586 }
2587
2588 return SDValue();
2589}
2590
2591// Lower VECTOR_SHUFFLE into SHF (if possible).
2592//
2593// SHF splits the vector into blocks of four elements, then shuffles these
2594// elements according to a <4 x i2> constant (encoded as an integer immediate).
2595//
2596// It is therefore possible to lower into SHF when the mask takes the form:
2597// <a, b, c, d, a+4, b+4, c+4, d+4, a+8, b+8, c+8, d+8, ...>
2598// When undef's appear they are treated as if they were whatever value is
2599// necessary in order to fit the above forms.
2600//
2601// For example:
2602// %2 = shufflevector <8 x i16> %0, <8 x i16> undef,
2603// <8 x i32> <i32 3, i32 2, i32 1, i32 0,
2604// i32 7, i32 6, i32 5, i32 4>
2605// is lowered to:
2606// (SHF_H $w0, $w1, 27)
2607// where the 27 comes from:
2608// 3 + (2 << 2) + (1 << 4) + (0 << 6)
2610 SmallVector<int, 16> Indices,
2611 SelectionDAG &DAG) {
2612 int SHFIndices[4] = { -1, -1, -1, -1 };
2613
2614 if (Indices.size() < 4)
2615 return SDValue();
2616
2617 for (unsigned i = 0; i < 4; ++i) {
2618 for (unsigned j = i; j < Indices.size(); j += 4) {
2619 int Idx = Indices[j];
2620
2621 // Convert from vector index to 4-element subvector index
2622 // If an index refers to an element outside of the subvector then give up
2623 if (Idx != -1) {
2624 Idx -= 4 * (j / 4);
2625 if (Idx < 0 || Idx >= 4)
2626 return SDValue();
2627 }
2628
2629 // If the mask has an undef, replace it with the current index.
2630 // Note that it might still be undef if the current index is also undef
2631 if (SHFIndices[i] == -1)
2632 SHFIndices[i] = Idx;
2633
2634 // Check that non-undef values are the same as in the mask. If they
2635 // aren't then give up
2636 if (!(Idx == -1 || Idx == SHFIndices[i]))
2637 return SDValue();
2638 }
2639 }
2640
2641 // Calculate the immediate. Replace any remaining undefs with zero
2642 APInt Imm(32, 0);
2643 for (int i = 3; i >= 0; --i) {
2644 int Idx = SHFIndices[i];
2645
2646 if (Idx == -1)
2647 Idx = 0;
2648
2649 Imm <<= 2;
2650 Imm |= Idx & 0x3;
2651 }
2652
2653 SDLoc DL(Op);
2654 return DAG.getNode(MipsISD::SHF, DL, ResTy,
2655 DAG.getTargetConstant(Imm, DL, MVT::i32),
2656 Op->getOperand(0));
2657}
2658
2659/// Determine whether a range fits a regular pattern of values.
2660/// This function accounts for the possibility of jumping over the End iterator.
2661template <typename ValType>
2662static bool
2664 unsigned CheckStride,
2666 ValType ExpectedIndex, unsigned ExpectedIndexStride) {
2667 auto &I = Begin;
2668
2669 while (I != End) {
2670 if (*I != -1 && *I != ExpectedIndex)
2671 return false;
2672 ExpectedIndex += ExpectedIndexStride;
2673
2674 // Incrementing past End is undefined behaviour so we must increment one
2675 // step at a time and check for End at each step.
2676 for (unsigned n = 0; n < CheckStride && I != End; ++n, ++I)
2677 ; // Empty loop body.
2678 }
2679 return true;
2680}
2681
2682// Determine whether VECTOR_SHUFFLE is a SPLATI.
2683//
2684// It is a SPLATI when the mask is:
2685// <x, x, x, ...>
2686// where x is any valid index.
2687//
2688// When undef's appear in the mask they are treated as if they were whatever
2689// value is necessary in order to fit the above form.
2691 SmallVector<int, 16> Indices,
2692 SelectionDAG &DAG) {
2693 assert((Indices.size() % 2) == 0);
2694
2695 int SplatIndex = -1;
2696 for (const auto &V : Indices) {
2697 if (V != -1) {
2698 SplatIndex = V;
2699 break;
2700 }
2701 }
2702
2703 return fitsRegularPattern<int>(Indices.begin(), 1, Indices.end(), SplatIndex,
2704 0);
2705}
2706
2707// Lower VECTOR_SHUFFLE into ILVEV (if possible).
2708//
2709// ILVEV interleaves the even elements from each vector.
2710//
2711// It is possible to lower into ILVEV when the mask consists of two of the
2712// following forms interleaved:
2713// <0, 2, 4, ...>
2714// <n, n+2, n+4, ...>
2715// where n is the number of elements in the vector.
2716// For example:
2717// <0, 0, 2, 2, 4, 4, ...>
2718// <0, n, 2, n+2, 4, n+4, ...>
2719//
2720// When undef's appear in the mask they are treated as if they were whatever
2721// value is necessary in order to fit the above forms.
2723 SmallVector<int, 16> Indices,
2724 SelectionDAG &DAG) {
2725 assert((Indices.size() % 2) == 0);
2726
2727 SDValue Wt;
2728 SDValue Ws;
2729 const auto &Begin = Indices.begin();
2730 const auto &End = Indices.end();
2731
2732 // Check even elements are taken from the even elements of one half or the
2733 // other and pick an operand accordingly.
2734 if (fitsRegularPattern<int>(Begin, 2, End, 0, 2))
2735 Wt = Op->getOperand(0);
2736 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size(), 2))
2737 Wt = Op->getOperand(1);
2738 else
2739 return SDValue();
2740
2741 // Check odd elements are taken from the even elements of one half or the
2742 // other and pick an operand accordingly.
2743 if (fitsRegularPattern<int>(Begin + 1, 2, End, 0, 2))
2744 Ws = Op->getOperand(0);
2745 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size(), 2))
2746 Ws = Op->getOperand(1);
2747 else
2748 return SDValue();
2749
2750 return DAG.getNode(MipsISD::ILVEV, SDLoc(Op), ResTy, Ws, Wt);
2751}
2752
2753// Lower VECTOR_SHUFFLE into ILVOD (if possible).
2754//
2755// ILVOD interleaves the odd elements from each vector.
2756//
2757// It is possible to lower into ILVOD when the mask consists of two of the
2758// following forms interleaved:
2759// <1, 3, 5, ...>
2760// <n+1, n+3, n+5, ...>
2761// where n is the number of elements in the vector.
2762// For example:
2763// <1, 1, 3, 3, 5, 5, ...>
2764// <1, n+1, 3, n+3, 5, n+5, ...>
2765//
2766// When undef's appear in the mask they are treated as if they were whatever
2767// value is necessary in order to fit the above forms.
2769 SmallVector<int, 16> Indices,
2770 SelectionDAG &DAG) {
2771 assert((Indices.size() % 2) == 0);
2772
2773 SDValue Wt;
2774 SDValue Ws;
2775 const auto &Begin = Indices.begin();
2776 const auto &End = Indices.end();
2777
2778 // Check even elements are taken from the odd elements of one half or the
2779 // other and pick an operand accordingly.
2780 if (fitsRegularPattern<int>(Begin, 2, End, 1, 2))
2781 Wt = Op->getOperand(0);
2782 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size() + 1, 2))
2783 Wt = Op->getOperand(1);
2784 else
2785 return SDValue();
2786
2787 // Check odd elements are taken from the odd elements of one half or the
2788 // other and pick an operand accordingly.
2789 if (fitsRegularPattern<int>(Begin + 1, 2, End, 1, 2))
2790 Ws = Op->getOperand(0);
2791 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size() + 1, 2))
2792 Ws = Op->getOperand(1);
2793 else
2794 return SDValue();
2795
2796 return DAG.getNode(MipsISD::ILVOD, SDLoc(Op), ResTy, Ws, Wt);
2797}
2798
2799// Lower VECTOR_SHUFFLE into ILVR (if possible).
2800//
2801// ILVR interleaves consecutive elements from the right (lowest-indexed) half of
2802// each vector.
2803//
2804// It is possible to lower into ILVR when the mask consists of two of the
2805// following forms interleaved:
2806// <0, 1, 2, ...>
2807// <n, n+1, n+2, ...>
2808// where n is the number of elements in the vector.
2809// For example:
2810// <0, 0, 1, 1, 2, 2, ...>
2811// <0, n, 1, n+1, 2, n+2, ...>
2812//
2813// When undef's appear in the mask they are treated as if they were whatever
2814// value is necessary in order to fit the above forms.
2816 SmallVector<int, 16> Indices,
2817 SelectionDAG &DAG) {
2818 assert((Indices.size() % 2) == 0);
2819
2820 SDValue Wt;
2821 SDValue Ws;
2822 const auto &Begin = Indices.begin();
2823 const auto &End = Indices.end();
2824
2825 // Check even elements are taken from the right (lowest-indexed) elements of
2826 // one half or the other and pick an operand accordingly.
2827 if (fitsRegularPattern<int>(Begin, 2, End, 0, 1))
2828 Wt = Op->getOperand(0);
2829 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size(), 1))
2830 Wt = Op->getOperand(1);
2831 else
2832 return SDValue();
2833
2834 // Check odd elements are taken from the right (lowest-indexed) elements of
2835 // one half or the other and pick an operand accordingly.
2836 if (fitsRegularPattern<int>(Begin + 1, 2, End, 0, 1))
2837 Ws = Op->getOperand(0);
2838 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size(), 1))
2839 Ws = Op->getOperand(1);
2840 else
2841 return SDValue();
2842
2843 return DAG.getNode(MipsISD::ILVR, SDLoc(Op), ResTy, Ws, Wt);
2844}
2845
2846// Lower VECTOR_SHUFFLE into ILVL (if possible).
2847//
2848// ILVL interleaves consecutive elements from the left (highest-indexed) half
2849// of each vector.
2850//
2851// It is possible to lower into ILVL when the mask consists of two of the
2852// following forms interleaved:
2853// <x, x+1, x+2, ...>
2854// <n+x, n+x+1, n+x+2, ...>
2855// where n is the number of elements in the vector and x is half n.
2856// For example:
2857// <x, x, x+1, x+1, x+2, x+2, ...>
2858// <x, n+x, x+1, n+x+1, x+2, n+x+2, ...>
2859//
2860// When undef's appear in the mask they are treated as if they were whatever
2861// value is necessary in order to fit the above forms.
2863 SmallVector<int, 16> Indices,
2864 SelectionDAG &DAG) {
2865 assert((Indices.size() % 2) == 0);
2866
2867 unsigned HalfSize = Indices.size() / 2;
2868 SDValue Wt;
2869 SDValue Ws;
2870 const auto &Begin = Indices.begin();
2871 const auto &End = Indices.end();
2872
2873 // Check even elements are taken from the left (highest-indexed) elements of
2874 // one half or the other and pick an operand accordingly.
2875 if (fitsRegularPattern<int>(Begin, 2, End, HalfSize, 1))
2876 Wt = Op->getOperand(0);
2877 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size() + HalfSize, 1))
2878 Wt = Op->getOperand(1);
2879 else
2880 return SDValue();
2881
2882 // Check odd elements are taken from the left (highest-indexed) elements of
2883 // one half or the other and pick an operand accordingly.
2884 if (fitsRegularPattern<int>(Begin + 1, 2, End, HalfSize, 1))
2885 Ws = Op->getOperand(0);
2886 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size() + HalfSize,
2887 1))
2888 Ws = Op->getOperand(1);
2889 else
2890 return SDValue();
2891
2892 return DAG.getNode(MipsISD::ILVL, SDLoc(Op), ResTy, Ws, Wt);
2893}
2894
2895// Lower VECTOR_SHUFFLE into PCKEV (if possible).
2896//
2897// PCKEV copies the even elements of each vector into the result vector.
2898//
2899// It is possible to lower into PCKEV when the mask consists of two of the
2900// following forms concatenated:
2901// <0, 2, 4, ...>
2902// <n, n+2, n+4, ...>
2903// where n is the number of elements in the vector.
2904// For example:
2905// <0, 2, 4, ..., 0, 2, 4, ...>
2906// <0, 2, 4, ..., n, n+2, n+4, ...>
2907//
2908// When undef's appear in the mask they are treated as if they were whatever
2909// value is necessary in order to fit the above forms.
2911 SmallVector<int, 16> Indices,
2912 SelectionDAG &DAG) {
2913 assert((Indices.size() % 2) == 0);
2914
2915 SDValue Wt;
2916 SDValue Ws;
2917 const auto &Begin = Indices.begin();
2918 const auto &Mid = Indices.begin() + Indices.size() / 2;
2919 const auto &End = Indices.end();
2920
2921 if (fitsRegularPattern<int>(Begin, 1, Mid, 0, 2))
2922 Wt = Op->getOperand(0);
2923 else if (fitsRegularPattern<int>(Begin, 1, Mid, Indices.size(), 2))
2924 Wt = Op->getOperand(1);
2925 else
2926 return SDValue();
2927
2928 if (fitsRegularPattern<int>(Mid, 1, End, 0, 2))
2929 Ws = Op->getOperand(0);
2930 else if (fitsRegularPattern<int>(Mid, 1, End, Indices.size(), 2))
2931 Ws = Op->getOperand(1);
2932 else
2933 return SDValue();
2934
2935 return DAG.getNode(MipsISD::PCKEV, SDLoc(Op), ResTy, Ws, Wt);
2936}
2937
2938// Lower VECTOR_SHUFFLE into PCKOD (if possible).
2939//
2940// PCKOD copies the odd elements of each vector into the result vector.
2941//
2942// It is possible to lower into PCKOD when the mask consists of two of the
2943// following forms concatenated:
2944// <1, 3, 5, ...>
2945// <n+1, n+3, n+5, ...>
2946// where n is the number of elements in the vector.
2947// For example:
2948// <1, 3, 5, ..., 1, 3, 5, ...>
2949// <1, 3, 5, ..., n+1, n+3, n+5, ...>
2950//
2951// When undef's appear in the mask they are treated as if they were whatever
2952// value is necessary in order to fit the above forms.
2954 SmallVector<int, 16> Indices,
2955 SelectionDAG &DAG) {
2956 assert((Indices.size() % 2) == 0);
2957
2958 SDValue Wt;
2959 SDValue Ws;
2960 const auto &Begin = Indices.begin();
2961 const auto &Mid = Indices.begin() + Indices.size() / 2;
2962 const auto &End = Indices.end();
2963
2964 if (fitsRegularPattern<int>(Begin, 1, Mid, 1, 2))
2965 Wt = Op->getOperand(0);
2966 else if (fitsRegularPattern<int>(Begin, 1, Mid, Indices.size() + 1, 2))
2967 Wt = Op->getOperand(1);
2968 else
2969 return SDValue();
2970
2971 if (fitsRegularPattern<int>(Mid, 1, End, 1, 2))
2972 Ws = Op->getOperand(0);
2973 else if (fitsRegularPattern<int>(Mid, 1, End, Indices.size() + 1, 2))
2974 Ws = Op->getOperand(1);
2975 else
2976 return SDValue();
2977
2978 return DAG.getNode(MipsISD::PCKOD, SDLoc(Op), ResTy, Ws, Wt);
2979}
2980
2981// Lower VECTOR_SHUFFLE into VSHF.
2982//
2983// This mostly consists of converting the shuffle indices in Indices into a
2984// BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is
2985// also code to eliminate unused operands of the VECTOR_SHUFFLE. For example,
2986// if the type is v8i16 and all the indices are less than 8 then the second
2987// operand is unused and can be replaced with anything. We choose to replace it
2988// with the used operand since this reduces the number of instructions overall.
2989//
2990// NOTE: SPLATI shuffle masks may contain UNDEFs, since isSPLATI() treats
2991// UNDEFs as same as SPLATI index.
2992// For other instances we use the last valid index if UNDEF is
2993// encountered.
2995 const SmallVector<int, 16> &Indices,
2996 const bool isSPLATI,
2997 SelectionDAG &DAG) {
2999 SDValue Op0;
3000 SDValue Op1;
3001 EVT MaskVecTy = ResTy.changeVectorElementTypeToInteger();
3002 EVT MaskEltTy = MaskVecTy.getVectorElementType();
3003 bool Using1stVec = false;
3004 bool Using2ndVec = false;
3005 SDLoc DL(Op);
3006 int ResTyNumElts = ResTy.getVectorNumElements();
3007
3008 assert(Indices[0] >= 0 &&
3009 "shuffle mask starts with an UNDEF, which is not expected");
3010
3011 for (int i = 0; i < ResTyNumElts; ++i) {
3012 // Idx == -1 means UNDEF
3013 int Idx = Indices[i];
3014
3015 if (0 <= Idx && Idx < ResTyNumElts)
3016 Using1stVec = true;
3017 if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2)
3018 Using2ndVec = true;
3019 }
3020 int LastValidIndex = 0;
3021 for (size_t i = 0; i < Indices.size(); i++) {
3022 int Idx = Indices[i];
3023 if (Idx < 0) {
3024 // Continue using splati index or use the last valid index.
3025 Idx = isSPLATI ? Indices[0] : LastValidIndex;
3026 } else {
3027 LastValidIndex = Idx;
3028 }
3029 Ops.push_back(DAG.getTargetConstant(Idx, DL, MaskEltTy));
3030 }
3031
3032 SDValue MaskVec = DAG.getBuildVector(MaskVecTy, DL, Ops);
3033
3034 if (Using1stVec && Using2ndVec) {
3035 Op0 = Op->getOperand(0);
3036 Op1 = Op->getOperand(1);
3037 } else if (Using1stVec)
3038 Op0 = Op1 = Op->getOperand(0);
3039 else if (Using2ndVec)
3040 Op0 = Op1 = Op->getOperand(1);
3041 else
3042 llvm_unreachable("shuffle vector mask references neither vector operand?");
3043
3044 // VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion.
3045 // <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11>
3046 // VSHF concatenates the vectors in a bitwise fashion:
3047 // <0b00, 0b01> + <0b10, 0b11> ->
3048 // 0b0100 + 0b1110 -> 0b01001110
3049 // <0b10, 0b11, 0b00, 0b01>
3050 // We must therefore swap the operands to get the correct result.
3051 return DAG.getNode(MipsISD::VSHF, DL, ResTy, MaskVec, Op1, Op0);
3052}
3053
3054// Lower VECTOR_SHUFFLE into one of a number of instructions depending on the
3055// indices in the shuffle.
3056SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
3057 SelectionDAG &DAG) const {
3058 ShuffleVectorSDNode *Node = cast<ShuffleVectorSDNode>(Op);
3059 EVT ResTy = Op->getValueType(0);
3060
3061 if (!ResTy.is128BitVector())
3062 return SDValue();
3063
3064 int ResTyNumElts = ResTy.getVectorNumElements();
3065 SmallVector<int, 16> Indices;
3066
3067 for (int i = 0; i < ResTyNumElts; ++i)
3068 Indices.push_back(Node->getMaskElt(i));
3069
3070 // splati.[bhwd] is preferable to the others but is matched from
3071 // MipsISD::VSHF.
3072 if (isVECTOR_SHUFFLE_SPLATI(Op, ResTy, Indices, DAG))
3073 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, true, DAG);
3075 if ((Result = lowerVECTOR_SHUFFLE_ILVEV(Op, ResTy, Indices, DAG)))
3076 return Result;
3077 if ((Result = lowerVECTOR_SHUFFLE_ILVOD(Op, ResTy, Indices, DAG)))
3078 return Result;
3079 if ((Result = lowerVECTOR_SHUFFLE_ILVL(Op, ResTy, Indices, DAG)))
3080 return Result;
3081 if ((Result = lowerVECTOR_SHUFFLE_ILVR(Op, ResTy, Indices, DAG)))
3082 return Result;
3083 if ((Result = lowerVECTOR_SHUFFLE_PCKEV(Op, ResTy, Indices, DAG)))
3084 return Result;
3085 if ((Result = lowerVECTOR_SHUFFLE_PCKOD(Op, ResTy, Indices, DAG)))
3086 return Result;
3087 if ((Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG)))
3088 return Result;
3089 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, false, DAG);
3090}
3091
3093MipsSETargetLowering::emitBPOSGE32(MachineInstr &MI,
3094 MachineBasicBlock *BB) const {
3095 // $bb:
3096 // bposge32_pseudo $vr0
3097 // =>
3098 // $bb:
3099 // bposge32 $tbb
3100 // $fbb:
3101 // li $vr2, 0
3102 // b $sink
3103 // $tbb:
3104 // li $vr1, 1
3105 // $sink:
3106 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
3107
3108 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3109 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3110 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
3111 DebugLoc DL = MI.getDebugLoc();
3112 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3114 MachineFunction *F = BB->getParent();
3115 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
3116 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
3117 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
3118 F->insert(It, FBB);
3119 F->insert(It, TBB);
3120 F->insert(It, Sink);
3121
3122 // Transfer the remainder of BB and its successor edges to Sink.
3123 Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
3124 BB->end());
3125 Sink->transferSuccessorsAndUpdatePHIs(BB);
3126
3127 // Add successors.
3128 BB->addSuccessor(FBB);
3129 BB->addSuccessor(TBB);
3130 FBB->addSuccessor(Sink);
3131 TBB->addSuccessor(Sink);
3132
3133 // Insert the real bposge32 instruction to $BB.
3134 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
3135 // Insert the real bposge32c instruction to $BB.
3136 BuildMI(BB, DL, TII->get(Mips::BPOSGE32C_MMR3)).addMBB(TBB);
3137
3138 // Fill $FBB.
3139 Register VR2 = RegInfo.createVirtualRegister(RC);
3140 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
3141 .addReg(Mips::ZERO).addImm(0);
3142 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
3143
3144 // Fill $TBB.
3145 Register VR1 = RegInfo.createVirtualRegister(RC);
3146 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
3147 .addReg(Mips::ZERO).addImm(1);
3148
3149 // Insert phi function to $Sink.
3150 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
3151 MI.getOperand(0).getReg())
3152 .addReg(VR2)
3153 .addMBB(FBB)
3154 .addReg(VR1)
3155 .addMBB(TBB);
3156
3157 MI.eraseFromParent(); // The pseudo instruction is gone now.
3158 return Sink;
3159}
3160
3161MachineBasicBlock *MipsSETargetLowering::emitMSACBranchPseudo(
3162 MachineInstr &MI, MachineBasicBlock *BB, unsigned BranchOp) const {
3163 // $bb:
3164 // vany_nonzero $rd, $ws
3165 // =>
3166 // $bb:
3167 // bnz.b $ws, $tbb
3168 // b $fbb
3169 // $fbb:
3170 // li $rd1, 0
3171 // b $sink
3172 // $tbb:
3173 // li $rd2, 1
3174 // $sink:
3175 // $rd = phi($rd1, $fbb, $rd2, $tbb)
3176
3177 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3178 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3179 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
3180 DebugLoc DL = MI.getDebugLoc();
3181 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3183 MachineFunction *F = BB->getParent();
3184 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
3185 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
3186 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
3187 F->insert(It, FBB);
3188 F->insert(It, TBB);
3189 F->insert(It, Sink);
3190
3191 // Transfer the remainder of BB and its successor edges to Sink.
3192 Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
3193 BB->end());
3194 Sink->transferSuccessorsAndUpdatePHIs(BB);
3195
3196 // Add successors.
3197 BB->addSuccessor(FBB);
3198 BB->addSuccessor(TBB);
3199 FBB->addSuccessor(Sink);
3200 TBB->addSuccessor(Sink);
3201
3202 // Insert the real bnz.b instruction to $BB.
3203 BuildMI(BB, DL, TII->get(BranchOp))
3204 .addReg(MI.getOperand(1).getReg())
3205 .addMBB(TBB);
3206
3207 // Fill $FBB.
3208 Register RD1 = RegInfo.createVirtualRegister(RC);
3209 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
3210 .addReg(Mips::ZERO).addImm(0);
3211 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
3212
3213 // Fill $TBB.
3214 Register RD2 = RegInfo.createVirtualRegister(RC);
3215 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
3216 .addReg(Mips::ZERO).addImm(1);
3217
3218 // Insert phi function to $Sink.
3219 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
3220 MI.getOperand(0).getReg())
3221 .addReg(RD1)
3222 .addMBB(FBB)
3223 .addReg(RD2)
3224 .addMBB(TBB);
3225
3226 MI.eraseFromParent(); // The pseudo instruction is gone now.
3227 return Sink;
3228}
3229
3230// Emit the COPY_FW pseudo instruction.
3231//
3232// copy_fw_pseudo $fd, $ws, n
3233// =>
3234// copy_u_w $rt, $ws, $n
3235// mtc1 $rt, $fd
3236//
3237// When n is zero, the equivalent operation can be performed with (potentially)
3238// zero instructions due to register overlaps. This optimization is never valid
3239// for lane 1 because it would require FR=0 mode which isn't supported by MSA.
3241MipsSETargetLowering::emitCOPY_FW(MachineInstr &MI,
3242 MachineBasicBlock *BB) const {
3243 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3244 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3245 DebugLoc DL = MI.getDebugLoc();
3246 Register Fd = MI.getOperand(0).getReg();
3247 Register Ws = MI.getOperand(1).getReg();
3248 unsigned Lane = MI.getOperand(2).getImm();
3249
3250 if (Lane == 0) {
3251 unsigned Wt = Ws;
3252 if (!Subtarget.useOddSPReg()) {
3253 // We must copy to an even-numbered MSA register so that the
3254 // single-precision sub-register is also guaranteed to be even-numbered.
3255 Wt = RegInfo.createVirtualRegister(&Mips::MSA128WEvensRegClass);
3256
3257 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Wt).addReg(Ws);
3258 }
3259
3260 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_lo);
3261 } else {
3262 Register Wt = RegInfo.createVirtualRegister(
3263 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3264 : &Mips::MSA128WEvensRegClass);
3265
3266 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wt).addReg(Ws).addImm(Lane);
3267 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_lo);
3268 }
3269
3270 MI.eraseFromParent(); // The pseudo instruction is gone now.
3271 return BB;
3272}
3273
3274// Emit the COPY_FD pseudo instruction.
3275//
3276// copy_fd_pseudo $fd, $ws, n
3277// =>
3278// splati.d $wt, $ws, $n
3279// copy $fd, $wt:sub_64
3280//
3281// When n is zero, the equivalent operation can be performed with (potentially)
3282// zero instructions due to register overlaps. This optimization is always
3283// valid because FR=1 mode which is the only supported mode in MSA.
3285MipsSETargetLowering::emitCOPY_FD(MachineInstr &MI,
3286 MachineBasicBlock *BB) const {
3287 assert(Subtarget.isFP64bit());
3288
3289 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3290 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3291 Register Fd = MI.getOperand(0).getReg();
3292 Register Ws = MI.getOperand(1).getReg();
3293 unsigned Lane = MI.getOperand(2).getImm() * 2;
3294 DebugLoc DL = MI.getDebugLoc();
3295
3296 if (Lane == 0)
3297 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_64);
3298 else {
3299 Register Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3300
3301 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wt).addReg(Ws).addImm(1);
3302 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_64);
3303 }
3304
3305 MI.eraseFromParent(); // The pseudo instruction is gone now.
3306 return BB;
3307}
3308
3309// Emit the INSERT_FW pseudo instruction.
3310//
3311// insert_fw_pseudo $wd, $wd_in, $n, $fs
3312// =>
3313// subreg_to_reg $wt:sub_lo, $fs
3314// insve_w $wd[$n], $wd_in, $wt[0]
3316MipsSETargetLowering::emitINSERT_FW(MachineInstr &MI,
3317 MachineBasicBlock *BB) const {
3318 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3319 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3320 DebugLoc DL = MI.getDebugLoc();
3321 Register Wd = MI.getOperand(0).getReg();
3322 Register Wd_in = MI.getOperand(1).getReg();
3323 unsigned Lane = MI.getOperand(2).getImm();
3324 Register Fs = MI.getOperand(3).getReg();
3325 Register Wt = RegInfo.createVirtualRegister(
3326 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3327 : &Mips::MSA128WEvensRegClass);
3328
3329 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3330 .addImm(0)
3331 .addReg(Fs)
3332 .addImm(Mips::sub_lo);
3333 BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_W), Wd)
3334 .addReg(Wd_in)
3335 .addImm(Lane)
3336 .addReg(Wt)
3337 .addImm(0);
3338
3339 MI.eraseFromParent(); // The pseudo instruction is gone now.
3340 return BB;
3341}
3342
3343// Emit the INSERT_FD pseudo instruction.
3344//
3345// insert_fd_pseudo $wd, $fs, n
3346// =>
3347// subreg_to_reg $wt:sub_64, $fs
3348// insve_d $wd[$n], $wd_in, $wt[0]
3350MipsSETargetLowering::emitINSERT_FD(MachineInstr &MI,
3351 MachineBasicBlock *BB) const {
3352 assert(Subtarget.isFP64bit());
3353
3354 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3355 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3356 DebugLoc DL = MI.getDebugLoc();
3357 Register Wd = MI.getOperand(0).getReg();
3358 Register Wd_in = MI.getOperand(1).getReg();
3359 unsigned Lane = MI.getOperand(2).getImm();
3360 Register Fs = MI.getOperand(3).getReg();
3361 Register Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3362
3363 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3364 .addImm(0)
3365 .addReg(Fs)
3366 .addImm(Mips::sub_64);
3367 BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_D), Wd)
3368 .addReg(Wd_in)
3369 .addImm(Lane)
3370 .addReg(Wt)
3371 .addImm(0);
3372
3373 MI.eraseFromParent(); // The pseudo instruction is gone now.
3374 return BB;
3375}
3376
3377// Emit the INSERT_([BHWD]|F[WD])_VIDX pseudo instruction.
3378//
3379// For integer:
3380// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $rs)
3381// =>
3382// (SLL $lanetmp1, $lane, <log2size)
3383// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3384// (INSERT_[BHWD], $wdtmp2, $wdtmp1, 0, $rs)
3385// (NEG $lanetmp2, $lanetmp1)
3386// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2)
3387//
3388// For floating point:
3389// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $fs)
3390// =>
3391// (SUBREG_TO_REG $wt, $fs, <subreg>)
3392// (SLL $lanetmp1, $lane, <log2size)
3393// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3394// (INSVE_[WD], $wdtmp2, 0, $wdtmp1, 0)
3395// (NEG $lanetmp2, $lanetmp1)
3396// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2)
3397MachineBasicBlock *MipsSETargetLowering::emitINSERT_DF_VIDX(
3398 MachineInstr &MI, MachineBasicBlock *BB, unsigned EltSizeInBytes,
3399 bool IsFP) const {
3400 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3401 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3402 DebugLoc DL = MI.getDebugLoc();
3403 Register Wd = MI.getOperand(0).getReg();
3404 Register SrcVecReg = MI.getOperand(1).getReg();
3405 Register LaneReg = MI.getOperand(2).getReg();
3406 Register SrcValReg = MI.getOperand(3).getReg();
3407
3408 const TargetRegisterClass *VecRC = nullptr;
3409 // FIXME: This should be true for N32 too.
3410 const TargetRegisterClass *GPRRC =
3411 Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3412 unsigned SubRegIdx = Subtarget.isABI_N64() ? Mips::sub_32 : 0;
3413 unsigned ShiftOp = Subtarget.isABI_N64() ? Mips::DSLL : Mips::SLL;
3414 unsigned EltLog2Size;
3415 unsigned InsertOp = 0;
3416 unsigned InsveOp = 0;
3417 switch (EltSizeInBytes) {
3418 default:
3419 llvm_unreachable("Unexpected size");
3420 case 1:
3421 EltLog2Size = 0;
3422 InsertOp = Mips::INSERT_B;
3423 InsveOp = Mips::INSVE_B;
3424 VecRC = &Mips::MSA128BRegClass;
3425 break;
3426 case 2:
3427 EltLog2Size = 1;
3428 InsertOp = Mips::INSERT_H;
3429 InsveOp = Mips::INSVE_H;
3430 VecRC = &Mips::MSA128HRegClass;
3431 break;
3432 case 4:
3433 EltLog2Size = 2;
3434 InsertOp = Mips::INSERT_W;
3435 InsveOp = Mips::INSVE_W;
3436 VecRC = &Mips::MSA128WRegClass;
3437 break;
3438 case 8:
3439 EltLog2Size = 3;
3440 InsertOp = Mips::INSERT_D;
3441 InsveOp = Mips::INSVE_D;
3442 VecRC = &Mips::MSA128DRegClass;
3443 break;
3444 }
3445
3446 if (IsFP) {
3447 Register Wt = RegInfo.createVirtualRegister(VecRC);
3448 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3449 .addImm(0)
3450 .addReg(SrcValReg)
3451 .addImm(EltSizeInBytes == 8 ? Mips::sub_64 : Mips::sub_lo);
3452 SrcValReg = Wt;
3453 }
3454
3455 // Convert the lane index into a byte index
3456 if (EltSizeInBytes != 1) {
3457 Register LaneTmp1 = RegInfo.createVirtualRegister(GPRRC);
3458 BuildMI(*BB, MI, DL, TII->get(ShiftOp), LaneTmp1)
3459 .addReg(LaneReg)
3460 .addImm(EltLog2Size);
3461 LaneReg = LaneTmp1;
3462 }
3463
3464 // Rotate bytes around so that the desired lane is element zero
3465 Register WdTmp1 = RegInfo.createVirtualRegister(VecRC);
3466 BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), WdTmp1)
3467 .addReg(SrcVecReg)
3468 .addReg(SrcVecReg)
3469 .addReg(LaneReg, 0, SubRegIdx);
3470
3471 Register WdTmp2 = RegInfo.createVirtualRegister(VecRC);
3472 if (IsFP) {
3473 // Use insve.df to insert to element zero
3474 BuildMI(*BB, MI, DL, TII->get(InsveOp), WdTmp2)
3475 .addReg(WdTmp1)
3476 .addImm(0)
3477 .addReg(SrcValReg)
3478 .addImm(0);
3479 } else {
3480 // Use insert.df to insert to element zero
3481 BuildMI(*BB, MI, DL, TII->get(InsertOp), WdTmp2)
3482 .addReg(WdTmp1)
3483 .addReg(SrcValReg)
3484 .addImm(0);
3485 }
3486
3487 // Rotate elements the rest of the way for a full rotation.
3488 // sld.df inteprets $rt modulo the number of columns so we only need to negate
3489 // the lane index to do this.
3490 Register LaneTmp2 = RegInfo.createVirtualRegister(GPRRC);
3491 BuildMI(*BB, MI, DL, TII->get(Subtarget.isABI_N64() ? Mips::DSUB : Mips::SUB),
3492 LaneTmp2)
3493 .addReg(Subtarget.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO)
3494 .addReg(LaneReg);
3495 BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), Wd)
3496 .addReg(WdTmp2)
3497 .addReg(WdTmp2)
3498 .addReg(LaneTmp2, 0, SubRegIdx);
3499
3500 MI.eraseFromParent(); // The pseudo instruction is gone now.
3501 return BB;
3502}
3503
3504// Emit the FILL_FW pseudo instruction.
3505//
3506// fill_fw_pseudo $wd, $fs
3507// =>
3508// implicit_def $wt1
3509// insert_subreg $wt2:subreg_lo, $wt1, $fs
3510// splati.w $wd, $wt2[0]
3512MipsSETargetLowering::emitFILL_FW(MachineInstr &MI,
3513 MachineBasicBlock *BB) const {
3514 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3515 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3516 DebugLoc DL = MI.getDebugLoc();
3517 Register Wd = MI.getOperand(0).getReg();
3518 Register Fs = MI.getOperand(1).getReg();
3519 Register Wt1 = RegInfo.createVirtualRegister(
3520 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3521 : &Mips::MSA128WEvensRegClass);
3522 Register Wt2 = RegInfo.createVirtualRegister(
3523 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3524 : &Mips::MSA128WEvensRegClass);
3525
3526 BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1);
3527 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2)
3528 .addReg(Wt1)
3529 .addReg(Fs)
3530 .addImm(Mips::sub_lo);
3531 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wd).addReg(Wt2).addImm(0);
3532
3533 MI.eraseFromParent(); // The pseudo instruction is gone now.
3534 return BB;
3535}
3536
3537// Emit the FILL_FD pseudo instruction.
3538//
3539// fill_fd_pseudo $wd, $fs
3540// =>
3541// implicit_def $wt1
3542// insert_subreg $wt2:subreg_64, $wt1, $fs
3543// splati.d $wd, $wt2[0]
3545MipsSETargetLowering::emitFILL_FD(MachineInstr &MI,
3546 MachineBasicBlock *BB) const {
3547 assert(Subtarget.isFP64bit());
3548
3549 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3550 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3551 DebugLoc DL = MI.getDebugLoc();
3552 Register Wd = MI.getOperand(0).getReg();
3553 Register Fs = MI.getOperand(1).getReg();
3554 Register Wt1 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3555 Register Wt2 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3556
3557 BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1);
3558 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2)
3559 .addReg(Wt1)
3560 .addReg(Fs)
3561 .addImm(Mips::sub_64);
3562 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wd).addReg(Wt2).addImm(0);
3563
3564 MI.eraseFromParent(); // The pseudo instruction is gone now.
3565 return BB;
3566}
3567
3568// Emit the ST_F16_PSEDUO instruction to store a f16 value from an MSA
3569// register.
3570//
3571// STF16 MSA128F16:$wd, mem_simm10:$addr
3572// =>
3573// copy_u.h $rtemp,$wd[0]
3574// sh $rtemp, $addr
3575//
3576// Safety: We can't use st.h & co as they would over write the memory after
3577// the destination. It would require half floats be allocated 16 bytes(!) of
3578// space.
3580MipsSETargetLowering::emitST_F16_PSEUDO(MachineInstr &MI,
3581 MachineBasicBlock *BB) const {
3582
3583 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3584 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3585 DebugLoc DL = MI.getDebugLoc();
3586 Register Ws = MI.getOperand(0).getReg();
3587 Register Rt = MI.getOperand(1).getReg();
3588 const MachineMemOperand &MMO = **MI.memoperands_begin();
3589 unsigned Imm = MMO.getOffset();
3590
3591 // Caution: A load via the GOT can expand to a GPR32 operand, a load via
3592 // spill and reload can expand as a GPR64 operand. Examine the
3593 // operand in detail and default to ABI.
3594 const TargetRegisterClass *RC =
3595 MI.getOperand(1).isReg() ? RegInfo.getRegClass(MI.getOperand(1).getReg())
3596 : (Subtarget.isABI_O32() ? &Mips::GPR32RegClass
3597 : &Mips::GPR64RegClass);
3598 const bool UsingMips32 = RC == &Mips::GPR32RegClass;
3599 Register Rs = RegInfo.createVirtualRegister(&Mips::GPR32RegClass);
3600
3601 BuildMI(*BB, MI, DL, TII->get(Mips::COPY_U_H), Rs).addReg(Ws).addImm(0);
3602 if(!UsingMips32) {
3603 Register Tmp = RegInfo.createVirtualRegister(&Mips::GPR64RegClass);
3604 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Tmp)
3605 .addImm(0)
3606 .addReg(Rs)
3607 .addImm(Mips::sub_32);
3608 Rs = Tmp;
3609 }
3610 BuildMI(*BB, MI, DL, TII->get(UsingMips32 ? Mips::SH : Mips::SH64))
3611 .addReg(Rs)
3612 .addReg(Rt)
3613 .addImm(Imm)
3615 &MMO, MMO.getOffset(), MMO.getSize()));
3616
3617 MI.eraseFromParent();
3618 return BB;
3619}
3620
3621// Emit the LD_F16_PSEDUO instruction to load a f16 value into an MSA register.
3622//
3623// LD_F16 MSA128F16:$wd, mem_simm10:$addr
3624// =>
3625// lh $rtemp, $addr
3626// fill.h $wd, $rtemp
3627//
3628// Safety: We can't use ld.h & co as they over-read from the source.
3629// Additionally, if the address is not modulo 16, 2 cases can occur:
3630// a) Segmentation fault as the load instruction reads from a memory page
3631// memory it's not supposed to.
3632// b) The load crosses an implementation specific boundary, requiring OS
3633// intervention.
3635MipsSETargetLowering::emitLD_F16_PSEUDO(MachineInstr &MI,
3636 MachineBasicBlock *BB) const {
3637
3638 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3639 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3640 DebugLoc DL = MI.getDebugLoc();
3641 Register Wd = MI.getOperand(0).getReg();
3642
3643 // Caution: A load via the GOT can expand to a GPR32 operand, a load via
3644 // spill and reload can expand as a GPR64 operand. Examine the
3645 // operand in detail and default to ABI.
3646 const TargetRegisterClass *RC =
3647 MI.getOperand(1).isReg() ? RegInfo.getRegClass(MI.getOperand(1).getReg())
3648 : (Subtarget.isABI_O32() ? &Mips::GPR32RegClass
3649 : &Mips::GPR64RegClass);
3650
3651 const bool UsingMips32 = RC == &Mips::GPR32RegClass;
3652 Register Rt = RegInfo.createVirtualRegister(RC);
3653
3654 MachineInstrBuilder MIB =
3655 BuildMI(*BB, MI, DL, TII->get(UsingMips32 ? Mips::LH : Mips::LH64), Rt);
3656 for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
3657 MIB.add(MO);
3658
3659 if(!UsingMips32) {
3660 Register Tmp = RegInfo.createVirtualRegister(&Mips::GPR32RegClass);
3661 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Tmp).addReg(Rt, 0, Mips::sub_32);
3662 Rt = Tmp;
3663 }
3664
3665 BuildMI(*BB, MI, DL, TII->get(Mips::FILL_H), Wd).addReg(Rt);
3666
3667 MI.eraseFromParent();
3668 return BB;
3669}
3670
3671// Emit the FPROUND_PSEUDO instruction.
3672//
3673// Round an FGR64Opnd, FGR32Opnd to an f16.
3674//
3675// Safety: Cycle the operand through the GPRs so the result always ends up
3676// the correct MSA register.
3677//
3678// FIXME: This copying is strictly unnecessary. If we could tie FGR32Opnd:$Fs
3679// / FGR64Opnd:$Fs and MSA128F16:$Wd to the same physical register
3680// (which they can be, as the MSA registers are defined to alias the
3681// FPU's 64 bit and 32 bit registers) the result can be accessed using
3682// the correct register class. That requires operands be tie-able across
3683// register classes which have a sub/super register class relationship.
3684//
3685// For FPG32Opnd:
3686//
3687// FPROUND MSA128F16:$wd, FGR32Opnd:$fs
3688// =>
3689// mfc1 $rtemp, $fs
3690// fill.w $rtemp, $wtemp
3691// fexdo.w $wd, $wtemp, $wtemp
3692//
3693// For FPG64Opnd on mips32r2+:
3694//
3695// FPROUND MSA128F16:$wd, FGR64Opnd:$fs
3696// =>
3697// mfc1 $rtemp, $fs
3698// fill.w $rtemp, $wtemp
3699// mfhc1 $rtemp2, $fs
3700// insert.w $wtemp[1], $rtemp2
3701// insert.w $wtemp[3], $rtemp2
3702// fexdo.w $wtemp2, $wtemp, $wtemp
3703// fexdo.h $wd, $temp2, $temp2
3704//
3705// For FGR64Opnd on mips64r2+:
3706//
3707// FPROUND MSA128F16:$wd, FGR64Opnd:$fs
3708// =>
3709// dmfc1 $rtemp, $fs
3710// fill.d $rtemp, $wtemp
3711// fexdo.w $wtemp2, $wtemp, $wtemp
3712// fexdo.h $wd, $wtemp2, $wtemp2
3713//
3714// Safety note: As $wtemp is UNDEF, we may provoke a spurious exception if the
3715// undef bits are "just right" and the exception enable bits are
3716// set. By using fill.w to replicate $fs into all elements over
3717// insert.w for one element, we avoid that potiential case. If
3718// fexdo.[hw] causes an exception in, the exception is valid and it
3719// occurs for all elements.
3721MipsSETargetLowering::emitFPROUND_PSEUDO(MachineInstr &MI,
3723 bool IsFGR64) const {
3724
3725 // Strictly speaking, we need MIPS32R5 to support MSA. We'll be generous
3726 // here. It's technically doable to support MIPS32 here, but the ISA forbids
3727 // it.
3728 assert(Subtarget.hasMSA() && Subtarget.hasMips32r2());
3729
3730 bool IsFGR64onMips64 = Subtarget.hasMips64() && IsFGR64;
3731 bool IsFGR64onMips32 = !Subtarget.hasMips64() && IsFGR64;
3732
3733 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3734 DebugLoc DL = MI.getDebugLoc();
3735 Register Wd = MI.getOperand(0).getReg();
3736 Register Fs = MI.getOperand(1).getReg();
3737
3738 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3739 Register Wtemp = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3740 const TargetRegisterClass *GPRRC =
3741 IsFGR64onMips64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3742 unsigned MFC1Opc = IsFGR64onMips64
3743 ? Mips::DMFC1
3744 : (IsFGR64onMips32 ? Mips::MFC1_D64 : Mips::MFC1);
3745 unsigned FILLOpc = IsFGR64onMips64 ? Mips::FILL_D : Mips::FILL_W;
3746
3747 // Perform the register class copy as mentioned above.
3748 Register Rtemp = RegInfo.createVirtualRegister(GPRRC);
3749 BuildMI(*BB, MI, DL, TII->get(MFC1Opc), Rtemp).addReg(Fs);
3750 BuildMI(*BB, MI, DL, TII->get(FILLOpc), Wtemp).addReg(Rtemp);
3751 unsigned WPHI = Wtemp;
3752
3753 if (IsFGR64onMips32) {
3754 Register Rtemp2 = RegInfo.createVirtualRegister(GPRRC);
3755 BuildMI(*BB, MI, DL, TII->get(Mips::MFHC1_D64), Rtemp2).addReg(Fs);
3756 Register Wtemp2 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3757 Register Wtemp3 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3758 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_W), Wtemp2)
3759 .addReg(Wtemp)
3760 .addReg(Rtemp2)
3761 .addImm(1);
3762 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_W), Wtemp3)
3763 .addReg(Wtemp2)
3764 .addReg(Rtemp2)
3765 .addImm(3);
3766 WPHI = Wtemp3;
3767 }
3768
3769 if (IsFGR64) {
3770 Register Wtemp2 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3771 BuildMI(*BB, MI, DL, TII->get(Mips::FEXDO_W), Wtemp2)
3772 .addReg(WPHI)
3773 .addReg(WPHI);
3774 WPHI = Wtemp2;
3775 }
3776
3777 BuildMI(*BB, MI, DL, TII->get(Mips::FEXDO_H), Wd).addReg(WPHI).addReg(WPHI);
3778
3779 MI.eraseFromParent();
3780 return BB;
3781}
3782
3783// Emit the FPEXTEND_PSEUDO instruction.
3784//
3785// Expand an f16 to either a FGR32Opnd or FGR64Opnd.
3786//
3787// Safety: Cycle the result through the GPRs so the result always ends up
3788// the correct floating point register.
3789//
3790// FIXME: This copying is strictly unnecessary. If we could tie FGR32Opnd:$Fd
3791// / FGR64Opnd:$Fd and MSA128F16:$Ws to the same physical register
3792// (which they can be, as the MSA registers are defined to alias the
3793// FPU's 64 bit and 32 bit registers) the result can be accessed using
3794// the correct register class. That requires operands be tie-able across
3795// register classes which have a sub/super register class relationship. I
3796// haven't checked.
3797//
3798// For FGR32Opnd:
3799//
3800// FPEXTEND FGR32Opnd:$fd, MSA128F16:$ws
3801// =>
3802// fexupr.w $wtemp, $ws
3803// copy_s.w $rtemp, $ws[0]
3804// mtc1 $rtemp, $fd
3805//
3806// For FGR64Opnd on Mips64:
3807//
3808// FPEXTEND FGR64Opnd:$fd, MSA128F16:$ws
3809// =>
3810// fexupr.w $wtemp, $ws
3811// fexupr.d $wtemp2, $wtemp
3812// copy_s.d $rtemp, $wtemp2s[0]
3813// dmtc1 $rtemp, $fd
3814//
3815// For FGR64Opnd on Mips32:
3816//
3817// FPEXTEND FGR64Opnd:$fd, MSA128F16:$ws
3818// =>
3819// fexupr.w $wtemp, $ws
3820// fexupr.d $wtemp2, $wtemp
3821// copy_s.w $rtemp, $wtemp2[0]
3822// mtc1 $rtemp, $ftemp
3823// copy_s.w $rtemp2, $wtemp2[1]
3824// $fd = mthc1 $rtemp2, $ftemp
3826MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
3828 bool IsFGR64) const {
3829
3830 // Strictly speaking, we need MIPS32R5 to support MSA. We'll be generous
3831 // here. It's technically doable to support MIPS32 here, but the ISA forbids
3832 // it.
3833 assert(Subtarget.hasMSA() && Subtarget.hasMips32r2());
3834
3835 bool IsFGR64onMips64 = Subtarget.hasMips64() && IsFGR64;
3836 bool IsFGR64onMips32 = !Subtarget.hasMips64() && IsFGR64;
3837
3838 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3839 DebugLoc DL = MI.getDebugLoc();
3840 Register Fd = MI.getOperand(0).getReg();
3841 Register Ws = MI.getOperand(1).getReg();
3842
3843 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3844 const TargetRegisterClass *GPRRC =
3845 IsFGR64onMips64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3846 unsigned MTC1Opc = IsFGR64onMips64
3847 ? Mips::DMTC1
3848 : (IsFGR64onMips32 ? Mips::MTC1_D64 : Mips::MTC1);
3849 Register COPYOpc = IsFGR64onMips64 ? Mips::COPY_S_D : Mips::COPY_S_W;
3850
3851 Register Wtemp = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3852 Register WPHI = Wtemp;
3853
3854 BuildMI(*BB, MI, DL, TII->get(Mips::FEXUPR_W), Wtemp).addReg(Ws);
3855 if (IsFGR64) {
3856 WPHI = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3857 BuildMI(*BB, MI, DL, TII->get(Mips::FEXUPR_D), WPHI).addReg(Wtemp);
3858 }
3859
3860 // Perform the safety regclass copy mentioned above.
3861 Register Rtemp = RegInfo.createVirtualRegister(GPRRC);
3862 Register FPRPHI = IsFGR64onMips32
3863 ? RegInfo.createVirtualRegister(&Mips::FGR64RegClass)
3864 : Fd;
3865 BuildMI(*BB, MI, DL, TII->get(COPYOpc), Rtemp).addReg(WPHI).addImm(0);
3866 BuildMI(*BB, MI, DL, TII->get(MTC1Opc), FPRPHI).addReg(Rtemp);
3867
3868 if (IsFGR64onMips32) {
3869 Register Rtemp2 = RegInfo.createVirtualRegister(GPRRC);
3870 BuildMI(*BB, MI, DL, TII->get(Mips::COPY_S_W), Rtemp2)
3871 .addReg(WPHI)
3872 .addImm(1);
3873 BuildMI(*BB, MI, DL, TII->get(Mips::MTHC1_D64), Fd)
3874 .addReg(FPRPHI)
3875 .addReg(Rtemp2);
3876 }
3877
3878 MI.eraseFromParent();
3879 return BB;
3880}
3881
3882// Emit the FEXP2_W_1 pseudo instructions.
3883//
3884// fexp2_w_1_pseudo $wd, $wt
3885// =>
3886// ldi.w $ws, 1
3887// fexp2.w $wd, $ws, $wt
3889MipsSETargetLowering::emitFEXP2_W_1(MachineInstr &MI,
3890 MachineBasicBlock *BB) const {
3891 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3892 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3893 const TargetRegisterClass *RC = &Mips::MSA128WRegClass;
3894 Register Ws1 = RegInfo.createVirtualRegister(RC);
3895 Register Ws2 = RegInfo.createVirtualRegister(RC);
3896 DebugLoc DL = MI.getDebugLoc();
3897
3898 // Splat 1.0 into a vector
3899 BuildMI(*BB, MI, DL, TII->get(Mips::LDI_W), Ws1).addImm(1);
3900 BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_W), Ws2).addReg(Ws1);
3901
3902 // Emit 1.0 * fexp2(Wt)
3903 BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_W), MI.getOperand(0).getReg())
3904 .addReg(Ws2)
3905 .addReg(MI.getOperand(1).getReg());
3906
3907 MI.eraseFromParent(); // The pseudo instruction is gone now.
3908 return BB;
3909}
3910
3911// Emit the FEXP2_D_1 pseudo instructions.
3912//
3913// fexp2_d_1_pseudo $wd, $wt
3914// =>
3915// ldi.d $ws, 1
3916// fexp2.d $wd, $ws, $wt
3918MipsSETargetLowering::emitFEXP2_D_1(MachineInstr &MI,
3919 MachineBasicBlock *BB) const {
3920 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3921 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3922 const TargetRegisterClass *RC = &Mips::MSA128DRegClass;
3923 Register Ws1 = RegInfo.createVirtualRegister(RC);
3924 Register Ws2 = RegInfo.createVirtualRegister(RC);
3925 DebugLoc DL = MI.getDebugLoc();
3926
3927 // Splat 1.0 into a vector
3928 BuildMI(*BB, MI, DL, TII->get(Mips::LDI_D), Ws1).addImm(1);
3929 BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_D), Ws2).addReg(Ws1);
3930
3931 // Emit 1.0 * fexp2(Wt)
3932 BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_D), MI.getOperand(0).getReg())
3933 .addReg(Ws2)
3934 .addReg(MI.getOperand(1).getReg());
3935
3936 MI.eraseFromParent(); // The pseudo instruction is gone now.
3937 return BB;
3938}
static SDValue performSHLCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
If the operand is a bitwise AND with a constant RHS, and the shift has a constant RHS and is the only...
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget, const AArch64TargetLowering &TLI)
return SDValue()
static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue performSETCCCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool fitsRegularPattern(typename SmallVectorImpl< ValType >::const_iterator Begin, unsigned CheckStride, typename SmallVectorImpl< ValType >::const_iterator End, ValType ExpectedIndex, unsigned ExpectedIndexStride)
Determine whether a range fits a regular pattern of values.
static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
static SDValue truncateVecElts(SDNode *Node, SelectionDAG &DAG)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Promote Memory to Register
Definition Mem2Reg.cpp:110
static SDValue lowerMSABinaryBitImmIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc, SDValue Imm, bool BigEndian)
static SDValue lowerMSABitClearImm(SDValue Op, SelectionDAG &DAG)
static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, const TargetLowering::DAGCombinerInfo &DCI, const MipsSETargetLowering *TL, const MipsSubtarget &Subtarget)
static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc)
static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc)
static cl::opt< bool > NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), cl::desc("Expand double precision loads and " "stores to their single precision " "counterparts"))
static SDValue lowerVECTOR_SHUFFLE_ILVR(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue, bool BigEndian, SelectionDAG &DAG)
static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG)
static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian)
static SDValue initAccumulator(SDValue In, const SDLoc &DL, SelectionDAG &DAG)
static bool isBitwiseInverse(SDValue N, SDValue OfNode)
static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, const MipsSubtarget &Subtarget)
static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
static bool isVectorAllOnes(SDValue N)
static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC)
static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG)
static SDValue lowerMSABitClear(SDValue Op, SelectionDAG &DAG)
static SDValue lowerVECTOR_SHUFFLE_PCKEV(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT, EVT ShiftTy, SelectionDAG &DAG)
static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG, bool IsSigned=false)
static SDValue lowerVECTOR_SHUFFLE_ILVOD(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isConstantOrUndef(const SDValue Op)
static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy, const SmallVector< int, 16 > &Indices, const bool isSPLATI, SelectionDAG &DAG)
static SDValue lowerVECTOR_SHUFFLE_SHF(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue extractLOHI(SDValue Op, const SDLoc &DL, SelectionDAG &DAG)
static bool shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerVECTOR_SHUFFLE_ILVEV(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isVECTOR_SHUFFLE_SPLATI(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op)
static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, const MipsSubtarget &Subtarget)
static cl::opt< bool > UseMipsTailCalls("mips-tail-calls", cl::Hidden, cl::desc("MIPS: permit tail calls."), cl::init(false))
static SDValue lowerVECTOR_SHUFFLE_ILVL(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1541
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:936
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:372
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1489
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:330
unsigned logBase2() const
Definition APInt.h:1762
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:441
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:307
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:297
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:852
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
unsigned getInRegsParamsCount() const
uint64_t getZExtValue() const
const SDValue & getBasePtr() const
const Triple & getTargetTriple() const
Machine Value Type.
SimpleValueType SimpleTy
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
Flags getFlags() const
Return the raw flags of the source value,.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Align getAlign() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
unsigned getIncomingArgSize() const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
void addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC)
Enable MSA support for the given floating-point type and Register class.
void addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC)
Enable MSA support for the given integer type and Register class.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
const TargetRegisterClass * getRepRegClassFor(MVT VT) const override
Return the 'representative' register class for the specified value type.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Determine if the target supports unaligned memory accesses.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
MipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
bool hasMips32r6() const
bool isLittle() const
bool hasDSPR2() const
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
Return the type to use for a scalar shift opcode, given the shifted amount type.
MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
This function fills Ops, which is the list of operands that will later be used when a function call n...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
const MipsSubtarget & Subtarget
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getNumOperands() const
Return the number of values used by this operation.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
LLVM_ABI void printrWithDepth(raw_ostream &O, const SelectionDAG *G=nullptr, unsigned depth=100) const
Print a SelectionDAG node and children up to depth "depth." The given SelectionDAG allows target-spec...
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
uint64_t getScalarValueSizeInBits() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const TargetSubtargetInfo & getSubtarget() const
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVMContext * getContext() const
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::const_iterator const_iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const SDValue & getBasePtr() const
const SDValue & getValue() const
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
Definition Triple.cpp:2082
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:807
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:270
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:289
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:259
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:511
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition ISDOpcodes.h:215
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:868
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:410
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:275
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:249
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:431
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:832
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:784
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:228
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:701
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:762
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:642
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:569
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:838
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:799
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:724
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:793
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:914
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
Definition ISDOpcodes.h:174
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:736
@ 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
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:420
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:558
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:844
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:527
@ 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:549
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
initializer< Ty > init(const Ty &Val)
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:532
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
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
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
const MipsTargetLowering * createMipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:197
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:869
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:94
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:373
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:385
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
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:168
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:328
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:336
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:152
This class contains a discriminated union of information about pointers in memory operands,...