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