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