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