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