1//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===// 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 7//===----------------------------------------------------------------------===// 9// Subclass of MipsTargetLowering specialized for mips32/64. 11//===----------------------------------------------------------------------===// 36#include "llvm/IR/IntrinsicsMips.h" 52#define DEBUG_TYPE "mips-isel" 59cl::desc(
"Expand double precision loads and " 60"stores to their single precision " 63// Widen the v2 vectors to the register width, i.e. v2i16 -> v8i16, 64// v2i32 -> v4i32, etc, to ensure the correct rail size is used, i.e. 65// INST.h for v16, INST.w for v32, INST.d for v64. 70// Leave v2i1 vectors to be promoted to larger ones. 71// Other i1 types will be promoted by default. 75// 16-bit vector types (v2 and longer) 77// 32-bit vector types (v2 and longer) 80// 64-bit vector types (v2 and longer) 86// Only word (.w) and doubleword (.d) are available for floating point 87// vectors. That means floating point vectors should be either v2f64 89// Here we only explicitly widen the f32 types - f16 will be promoted 94// v2i64 is already 128-bit wide. 105// Set up the register classes 112// Expand all truncating stores and extending loads. 126for (
constauto &VecTy : VecTys) {
129// Expand all builtin opcodes. 161// f16 is a storage-only type, always promote it to f32. 205// When dealing with single precision only, use libcalls 264// MIPS32r6 replaces the accumulator-based multiplies with a three register 272// MIPS32r6 replaces the accumulator-based division/remainder with separate 273// three register division and remainder instructions. 281// MIPS32r6 replaces conditional moves with an equivalent that removes the 282// need for three GPR read ports. 298// Floating point > and >= are supported via < and <= 311// MIPS64r6 replaces the accumulator-based multiplies with a three register 319// MIPS32r6 replaces the accumulator-based division/remainder with separate 320// three register division and remainder instructions. 328// MIPS64r6 replaces conditional moves with an equivalent that removes the 329// need for three GPR read ports. 346if (VT == MVT::Untyped)
347returnSubtarget.
hasDSP() ? &Mips::ACC64DSPRegClass : &Mips::ACC64RegClass;
352// Enable MSA support for the given integer type and Register class. 357// Expand all builtin opcodes. 391if (Ty == MVT::v4i32 || Ty == MVT::v2i64) {
406// Enable MSA support for the given floating-point type and Register class. 411// Expand all builtin opcodes. 422if (Ty != MVT::v8f16) {
449EVT ResTy =
Op->getValueType(0);
452// Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the 453// floating point register are undefined. Not really an issue as sel.d, which 454// is produced from an FSELECT node, only looks at bit 0. 465// MIPS32r6/MIPS64r6 is required to support unaligned access. It's 466// implementation defined whether this is handled by hardware, software, or 467// a hybrid of the two but it's expected that most implementations will 468// handle the majority of cases in hardware. 489switch(
Op.getOpcode()) {
513// Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT 515// Performs the following transformations: 516// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its 517// sign/zero-extension is completely overwritten by the new one performed by 519// - Removes redundant zero extensions performed by an ISD::AND. 530// (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d) 531// where $d + 1 == 2^n and n == 32 532// or $d + 1 == 2^n and n <= 32 and ZExt 533// -> (MipsVExtractZExt $a, $b, $c) 541 int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2();
543if (Log2IfPositive <= 0)
544returnSDValue();
// Mask+1 is not a power of 2 547EVT ExtendTy = cast<VTSDNode>(Op0Op2)->getVT();
549unsignedLog2 = Log2IfPositive;
552Log2 == ExtendTySize) {
563// Determine if the specified node is a constant vector splat. 565// Returns true and sets Imm if: 566// * N is a ISD::BUILD_VECTOR representing a constant splat 568// This function is quite similar to MipsSEDAGToDAGISel::selectVSplat. The 569// differences are that it assumes the MSA has already been checked and the 570// arbitrary requirement for a maximum of 32-bit integers isn't applied (and 571// must not be in order for binsri.d to be selectable). 578APInt SplatValue, SplatUndef;
579unsigned SplatBitSize;
582if (!
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
591// Test whether the given node is an all-ones build_vector. 593// Look through bitcasts. Endianness doesn't matter because we are looking 594// for an all-ones value. 603APInt SplatValue, SplatUndef;
604unsigned SplatBitSize;
607// Endianness doesn't matter in this context because we are looking for 609if (BVN->
isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs))
615// Test whether N is the bitwise inverse of OfNode. 621returnN->getOperand(1) == OfNode;
624returnN->getOperand(0) == OfNode;
629// Perform combines where ISD::OR is the root node. 631// Performs the following transformations: 632// - (or (and $a, $mask), (and $b, $inv_mask)) => (vselect $mask, $a, $b) 633// where $inv_mask is the bitwise inverse of $mask and the 'or' has a 128-bit 641EVT Ty =
N->getValueType(0);
654bool IsLittleEndian = !Subtarget.
isLittle();
657bool IsConstantMask =
false;
660// If Op0Op0 is an appropriate mask, try to find it's inverse in either 661// Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, while 663// IfClr will be set if we find a valid match. 664if (
isVSplat(Op0Op0, Mask, IsLittleEndian)) {
668if (
isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
669 Mask.getBitWidth() == InvMask.
getBitWidth() && Mask == ~InvMask)
671elseif (
isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
672 Mask.getBitWidth() == InvMask.
getBitWidth() && Mask == ~InvMask)
675 IsConstantMask =
true;
678// If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the same 679// thing again using this mask. 680// IfClr will be set if we find a valid match. 685if (
isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
686 Mask.getBitWidth() == InvMask.
getBitWidth() && Mask == ~InvMask)
688elseif (
isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
689 Mask.getBitWidth() == InvMask.
getBitWidth() && Mask == ~InvMask)
692 IsConstantMask =
true;
695// If IfClr is not yet set, try looking for a non-constant match. 696// IfClr will be set if we find a valid match amongst the eight 734// At this point, IfClr will be set if we have a valid match. 740// Fold degenerate cases. 748// Transform the DAG into an equivalent VSELECT. 758// Estimate the number of operations the below transform will turn a 759// constant multiply into. The number is approximately equal to the minimal 760// number of powers of two that constant can be broken down to by adding 761// or subtracting them. 763// If we have taken more than 12[1] / 8[2] steps to attempt the 764// optimization for a native sized value, it is more than likely that this 765// optimization will make things worse. 767// [1] MIPS64 requires 6 instructions at most to materialize any constant, 768// multiplication requires at least 4 cycles, but another cycle (or two) 769// to retrieve the result from the HI/LO registers. 771// [2] For MIPS32, more than 8 steps is expensive as the constant could be 772// materialized in 2 instructions, multiplication requires at least 4 773// cycles, but another cycle (or two) to retrieve the result from the 777// - MaxSteps needs to consider the `VT` of the constant for the current 779// - Consider to perform this optimization after type legalization. 780// That allows to remove a workaround for types not supported natively. 781// - Take in account `-Os, -Oz` flags because this optimization 782// increases code size. 789while (!WorkStack.
empty()) {
792if (Val == 0 || Val == 1)
806if ((Val - Floor).ule(Ceil - Val)) {
817// If the value being multiplied is not supported natively, we have to pay 818// an additional legalization cost, conservatively assume an increase in the 819// cost of 3 instructions per step. This values for this heuristic were 820// determined experimentally. 841// If c is power of 2, return (shl x, log2(c)). 851// If |c - floor_c| <= |c - ceil_c|, 852// where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))), 853// return (add constMult(x, floor_c), constMult(x, c - floor_c)). 854if ((
C - Floor).ule(Ceil -
C)) {
860// If |c - floor_c| > |c - ceil_c|, 861// return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)). 871EVT VT =
N->getValueType(0);
875C->getAPIntValue(), VT, DAG, Subtarget))
886// See if this is a vector splat immediate node. 887APInt SplatValue, SplatUndef;
888unsigned SplatBitSize;
897 !BV->
isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
899 (SplatBitSize != EltSize) ||
904return DAG.
getNode(Opc,
DL, Ty,
N->getOperand(0),
911EVT Ty =
N->getValueType(0);
913if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
919// Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold 920// constant splats into MipsISD::SHRA_DSP for DSPr2. 922// Performs the following transformations: 923// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its 924// sign/zero-extension is completely overwritten by the new one performed by 925// the ISD::SRA and ISD::SHL nodes. 926// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL 929// See performDSPShiftCombine for more information about the transformation 934EVT Ty =
N->getValueType(0);
940// (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d) 941// where $d + sizeof($c) == 32 942// or $d + sizeof($c) <= 32 and SExt 943// -> (MipsVExtractSExt $a, $b, $c) 955EVT ExtendTy = cast<VTSDNode>(Op0Op0->
getOperand(2))->getVT();
958if (TotalBits == 32 ||
970if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget.
hasDSPR2()))
980EVT Ty =
N->getValueType(0);
982if (((Ty != MVT::v2i16) || !Subtarget.
hasDSPR2()) && (Ty != MVT::v4i8))
989bool IsV216 = (Ty == MVT::v2i16);
1007EVT Ty =
N->getValueType(0);
1009if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
1016N->getOperand(1),
N->getOperand(2));
1020EVT Ty =
N->getValueType(0);
1022if (Ty == MVT::v2i16 || Ty == MVT::v4i8) {
1030N->getOperand(1),
N->getOperand(2), SetCC.
getOperand(2));
1038EVT Ty =
N->getValueType(0);
1041// Try the following combines: 1042// (xor (or $a, $b), (build_vector allones)) 1043// (xor (or $a, $b), (bitcast (build_vector allones))) 1068switch (
N->getOpcode()) {
1096N->printrWithDepth(
dbgs(), &DAG);
dbgs() <<
"\n=> \n";
1107switch (
MI.getOpcode()) {
1110case Mips::BPOSGE32_PSEUDO:
1111return emitBPOSGE32(
MI, BB);
1112case Mips::SNZ_B_PSEUDO:
1113return emitMSACBranchPseudo(
MI, BB, Mips::BNZ_B);
1114case Mips::SNZ_H_PSEUDO:
1115return emitMSACBranchPseudo(
MI, BB, Mips::BNZ_H);
1116case Mips::SNZ_W_PSEUDO:
1117return emitMSACBranchPseudo(
MI, BB, Mips::BNZ_W);
1118case Mips::SNZ_D_PSEUDO:
1119return emitMSACBranchPseudo(
MI, BB, Mips::BNZ_D);
1120case Mips::SNZ_V_PSEUDO:
1121return emitMSACBranchPseudo(
MI, BB, Mips::BNZ_V);
1122case Mips::SZ_B_PSEUDO:
1123return emitMSACBranchPseudo(
MI, BB, Mips::BZ_B);
1124case Mips::SZ_H_PSEUDO:
1125return emitMSACBranchPseudo(
MI, BB, Mips::BZ_H);
1126case Mips::SZ_W_PSEUDO:
1127return emitMSACBranchPseudo(
MI, BB, Mips::BZ_W);
1128case Mips::SZ_D_PSEUDO:
1129return emitMSACBranchPseudo(
MI, BB, Mips::BZ_D);
1130case Mips::SZ_V_PSEUDO:
1131return emitMSACBranchPseudo(
MI, BB, Mips::BZ_V);
1132case Mips::COPY_FW_PSEUDO:
1133return emitCOPY_FW(
MI, BB);
1134case Mips::COPY_FD_PSEUDO:
1135return emitCOPY_FD(
MI, BB);
1136case Mips::INSERT_FW_PSEUDO:
1137return emitINSERT_FW(
MI, BB);
1138case Mips::INSERT_FD_PSEUDO:
1139return emitINSERT_FD(
MI, BB);
1140case Mips::INSERT_B_VIDX_PSEUDO:
1141case Mips::INSERT_B_VIDX64_PSEUDO:
1142return emitINSERT_DF_VIDX(
MI, BB, 1,
false);
1143case Mips::INSERT_H_VIDX_PSEUDO:
1144case Mips::INSERT_H_VIDX64_PSEUDO:
1145return emitINSERT_DF_VIDX(
MI, BB, 2,
false);
1146case Mips::INSERT_W_VIDX_PSEUDO:
1147case Mips::INSERT_W_VIDX64_PSEUDO:
1148return emitINSERT_DF_VIDX(
MI, BB, 4,
false);
1149case Mips::INSERT_D_VIDX_PSEUDO:
1150case Mips::INSERT_D_VIDX64_PSEUDO:
1151return emitINSERT_DF_VIDX(
MI, BB, 8,
false);
1152case Mips::INSERT_FW_VIDX_PSEUDO:
1153case Mips::INSERT_FW_VIDX64_PSEUDO:
1154return emitINSERT_DF_VIDX(
MI, BB, 4,
true);
1155case Mips::INSERT_FD_VIDX_PSEUDO:
1156case Mips::INSERT_FD_VIDX64_PSEUDO:
1157return emitINSERT_DF_VIDX(
MI, BB, 8,
true);
1158case Mips::FILL_FW_PSEUDO:
1159return emitFILL_FW(
MI, BB);
1160case Mips::FILL_FD_PSEUDO:
1161return emitFILL_FD(
MI, BB);
1162case Mips::FEXP2_W_1_PSEUDO:
1163return emitFEXP2_W_1(
MI, BB);
1164case Mips::FEXP2_D_1_PSEUDO:
1165return emitFEXP2_D_1(
MI, BB);
1167return emitST_F16_PSEUDO(
MI, BB);
1169return emitLD_F16_PSEUDO(
MI, BB);
1170case Mips::MSA_FP_EXTEND_W_PSEUDO:
1171return emitFPEXTEND_PSEUDO(
MI, BB,
false);
1172case Mips::MSA_FP_ROUND_W_PSEUDO:
1173return emitFPROUND_PSEUDO(
MI, BB,
false);
1174case Mips::MSA_FP_EXTEND_D_PSEUDO:
1175return emitFPEXTEND_PSEUDO(
MI, BB,
true);
1176case Mips::MSA_FP_ROUND_D_PSEUDO:
1177return emitFPROUND_PSEUDO(
MI, BB,
true);
1181bool MipsSETargetLowering::isEligibleForTailCallOptimization(
1182constCCState &CCInfo,
unsigned NextStackOffset,
1187// Exception has to be cleared with eret. 1191// Return false if either the callee or caller has a byval argument. 1195// Return true if the callee's argument area is no larger than the 1200void MipsSETargetLowering::
1202 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
1203bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
1204bool IsCallReloc, CallLoweringInfo &CLI,
SDValue Callee,
1208 InternalLinkage, IsCallReloc, CLI, Callee,
1218// Replace a double precision load with two i32 loads and a buildpair64. 1221EVT PtrVT =
Ptr.getValueType();
1223// i32 load from lower address. 1227// i32 load from higher address. 1247// Replace a double precision store with two extractelement64s and i32 stores. 1250EVT PtrVT =
Ptr.getValueType();
1259// i32 store to lower address. 1263// i32 store to higher address. 1273MVT Src =
Op.getOperand(0).getValueType().getSimpleVT();
1274MVT Dest =
Op.getValueType().getSimpleVT();
1276// Bitcast i64 to double. 1277if (Src == MVT::i64 && Dest == MVT::f64) {
1284// Bitcast double to i64. 1285if (Src == MVT::f64 && Dest == MVT::i64) {
1286// Skip lower bitcast when operand0 has converted float results to integer 1287// which was done by function SoftenFloatResult. 1300// Skip other cases of bitcast and use default lowering. 1305bool HasLo,
bool HasHi,
1307// MIPS32r6/MIPS64r6 removed accumulator based multiplies. 1310EVT Ty =
Op.getOperand(0).getValueType();
1313Op.getOperand(0),
Op.getOperand(1));
1321if (!HasLo || !HasHi)
1322return HasLo ?
Lo :
Hi;
1330 std::tie(InLo, InHi) = DAG.
SplitScalar(In,
DL, MVT::i32, MVT::i32);
1340// This function expands mips intrinsic nodes which have 64-bit input operands 1343// out64 = intrinsic-node in64 1345// lo = copy (extract-element (in64, 0)) 1346// hi = copy (extract-element (in64, 1)) 1347// mips-specific-node 1350// out64 = merge-values (v0, v1) 1354bool HasChainIn =
Op->getOperand(0).getValueType() == MVT::Other;
1358// See if Op has a chain input. 1362// The next operand is the intrinsic opcode. 1365// See if the next operand has type i64. 1366SDValue Opnd =
Op->getOperand(++OpNo), In64;
1373// Push the remaining operands. 1377// Add In64 to the end of the list. 1384for (
EVT Ty :
Op->values())
1385 ResTys.
push_back((Ty == MVT::i64) ? MVT::Untyped : Ty);
1399// Lower an MSA copy intrinsic into the specified SelectionDAG node 1404EVT ResTy =
Op->getValueType(0);
1414EVT ResVecTy =
Op->getValueType(0);
1415EVT ViaVecTy = ResVecTy;
1419// When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and 1420// LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating 1425if (ResVecTy == MVT::v2i64) {
1426// In case of the index being passed as an immediate value, set the upper 1427// lane to 0 so that the splati.d instruction can be matched. 1428if (isa<ConstantSDNode>(LaneA))
1430// Having the index passed in a register, set the upper lane to the same 1431// value as the lower - this results in the BUILD_VECTOR node not being 1432// expanded through stack. This way we are able to pattern match the set of 1433// nodes created here to splat.d. 1436 ViaVecTy = MVT::v4i32;
1442SDValue Ops[16] = { LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB,
1443 LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB };
1448if (ViaVecTy != ResVecTy) {
1458bool IsSigned =
false) {
1459auto *CImm = cast<ConstantSDNode>(
Op->getOperand(ImmOp));
1461APInt(
Op->getValueType(0).getScalarType().getSizeInBits(),
1462 IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
1468EVT ViaVecTy = VecTy;
1469SDValue SplatValueA = SplatValue;
1470SDValue SplatValueB = SplatValue;
1473if (VecTy == MVT::v2i64) {
1474// v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's. 1475 ViaVecTy = MVT::v4i32;
1483// We currently hold the parts in little endian order. Swap them if 1488SDValue Ops[16] = { SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1489 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1490 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1491 SplatValueA, SplatValueB, SplatValueA, SplatValueB };
1496if (VecTy != ViaVecTy)
1505EVT VecTy =
Op->getValueType(0);
1509// The DAG Combiner can't constant fold bitcasted vectors yet so we must do it 1511if (VecTy == MVT::v2i64) {
1513APInt BitImm =
APInt(64, 1) << CImm->getAPIntValue();
1525 {BitImmLoOp, BitImmHiOp, BitImmLoOp, BitImmHiOp}));
1530// We couldnt constant fold, do a vector shift instead 1532// Extend i32 to i64 if necessary. Sign or zero extend doesn't matter since 1533// only values 0-63 are valid. 1534if (VecTy == MVT::v2i64)
1543return DAG.
getNode(Opc,
DL, VecTy,
Op->getOperand(1), Exp2Imm);
1548EVT ResTy =
Op->getValueType(0);
1551MVT ResEltTy = ResTy == MVT::v2i64 ? MVT::i64 : MVT::i32;
1560EVT ResTy =
Op->getValueType(0);
1571EVT ResTy =
Op->getValueType(0);
1573 <<
Op->getConstantOperandAPInt(2);
1586case Intrinsic::mips_shilo:
1588case Intrinsic::mips_dpau_h_qbl:
1590case Intrinsic::mips_dpau_h_qbr:
1592case Intrinsic::mips_dpsu_h_qbl:
1594case Intrinsic::mips_dpsu_h_qbr:
1596case Intrinsic::mips_dpa_w_ph:
1598case Intrinsic::mips_dps_w_ph:
1600case Intrinsic::mips_dpax_w_ph:
1602case Intrinsic::mips_dpsx_w_ph:
1604case Intrinsic::mips_mulsa_w_ph:
1606case Intrinsic::mips_mult:
1608case Intrinsic::mips_multu:
1610case Intrinsic::mips_madd:
1612case Intrinsic::mips_maddu:
1614case Intrinsic::mips_msub:
1616case Intrinsic::mips_msubu:
1618case Intrinsic::mips_addv_b:
1619case Intrinsic::mips_addv_h:
1620case Intrinsic::mips_addv_w:
1621case Intrinsic::mips_addv_d:
1624case Intrinsic::mips_addvi_b:
1625case Intrinsic::mips_addvi_h:
1626case Intrinsic::mips_addvi_w:
1627case Intrinsic::mips_addvi_d:
1630case Intrinsic::mips_and_v:
1633case Intrinsic::mips_andi_b:
1636case Intrinsic::mips_bclr_b:
1637case Intrinsic::mips_bclr_h:
1638case Intrinsic::mips_bclr_w:
1639case Intrinsic::mips_bclr_d:
1641case Intrinsic::mips_bclri_b:
1642case Intrinsic::mips_bclri_h:
1643case Intrinsic::mips_bclri_w:
1644case Intrinsic::mips_bclri_d:
1646case Intrinsic::mips_binsli_b:
1647case Intrinsic::mips_binsli_h:
1648case Intrinsic::mips_binsli_w:
1649case Intrinsic::mips_binsli_d: {
1650// binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear) 1651EVT VecTy =
Op->getValueType(0);
1656Op->getConstantOperandVal(3) + 1);
1659Op->getOperand(2),
Op->getOperand(1));
1661case Intrinsic::mips_binsri_b:
1662case Intrinsic::mips_binsri_h:
1663case Intrinsic::mips_binsri_w:
1664case Intrinsic::mips_binsri_d: {
1665// binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear) 1666EVT VecTy =
Op->getValueType(0);
1671Op->getConstantOperandVal(3) + 1);
1674Op->getOperand(2),
Op->getOperand(1));
1676case Intrinsic::mips_bmnz_v:
1678Op->getOperand(2),
Op->getOperand(1));
1679case Intrinsic::mips_bmnzi_b:
1683case Intrinsic::mips_bmz_v:
1685Op->getOperand(1),
Op->getOperand(2));
1686case Intrinsic::mips_bmzi_b:
1690case Intrinsic::mips_bneg_b:
1691case Intrinsic::mips_bneg_h:
1692case Intrinsic::mips_bneg_w:
1693case Intrinsic::mips_bneg_d: {
1694EVT VecTy =
Op->getValueType(0);
1701case Intrinsic::mips_bnegi_b:
1702case Intrinsic::mips_bnegi_h:
1703case Intrinsic::mips_bnegi_w:
1704case Intrinsic::mips_bnegi_d:
1707case Intrinsic::mips_bnz_b:
1708case Intrinsic::mips_bnz_h:
1709case Intrinsic::mips_bnz_w:
1710case Intrinsic::mips_bnz_d:
1713case Intrinsic::mips_bnz_v:
1716case Intrinsic::mips_bsel_v:
1717// bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear) 1719Op->getOperand(1),
Op->getOperand(3),
1721case Intrinsic::mips_bseli_b:
1722// bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear) 1726case Intrinsic::mips_bset_b:
1727case Intrinsic::mips_bset_h:
1728case Intrinsic::mips_bset_w:
1729case Intrinsic::mips_bset_d: {
1730EVT VecTy =
Op->getValueType(0);
1737case Intrinsic::mips_bseti_b:
1738case Intrinsic::mips_bseti_h:
1739case Intrinsic::mips_bseti_w:
1740case Intrinsic::mips_bseti_d:
1743case Intrinsic::mips_bz_b:
1744case Intrinsic::mips_bz_h:
1745case Intrinsic::mips_bz_w:
1746case Intrinsic::mips_bz_d:
1749case Intrinsic::mips_bz_v:
1752case Intrinsic::mips_ceq_b:
1753case Intrinsic::mips_ceq_h:
1754case Intrinsic::mips_ceq_w:
1755case Intrinsic::mips_ceq_d:
1758case Intrinsic::mips_ceqi_b:
1759case Intrinsic::mips_ceqi_h:
1760case Intrinsic::mips_ceqi_w:
1761case Intrinsic::mips_ceqi_d:
1764case Intrinsic::mips_cle_s_b:
1765case Intrinsic::mips_cle_s_h:
1766case Intrinsic::mips_cle_s_w:
1767case Intrinsic::mips_cle_s_d:
1770case Intrinsic::mips_clei_s_b:
1771case Intrinsic::mips_clei_s_h:
1772case Intrinsic::mips_clei_s_w:
1773case Intrinsic::mips_clei_s_d:
1776case Intrinsic::mips_cle_u_b:
1777case Intrinsic::mips_cle_u_h:
1778case Intrinsic::mips_cle_u_w:
1779case Intrinsic::mips_cle_u_d:
1782case Intrinsic::mips_clei_u_b:
1783case Intrinsic::mips_clei_u_h:
1784case Intrinsic::mips_clei_u_w:
1785case Intrinsic::mips_clei_u_d:
1788case Intrinsic::mips_clt_s_b:
1789case Intrinsic::mips_clt_s_h:
1790case Intrinsic::mips_clt_s_w:
1791case Intrinsic::mips_clt_s_d:
1794case Intrinsic::mips_clti_s_b:
1795case Intrinsic::mips_clti_s_h:
1796case Intrinsic::mips_clti_s_w:
1797case Intrinsic::mips_clti_s_d:
1800case Intrinsic::mips_clt_u_b:
1801case Intrinsic::mips_clt_u_h:
1802case Intrinsic::mips_clt_u_w:
1803case Intrinsic::mips_clt_u_d:
1806case Intrinsic::mips_clti_u_b:
1807case Intrinsic::mips_clti_u_h:
1808case Intrinsic::mips_clti_u_w:
1809case Intrinsic::mips_clti_u_d:
1812case Intrinsic::mips_copy_s_b:
1813case Intrinsic::mips_copy_s_h:
1814case Intrinsic::mips_copy_s_w:
1816case Intrinsic::mips_copy_s_d:
1818// Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64. 1821// Lower into the generic EXTRACT_VECTOR_ELT node and let the type 1822// legalizer and EXTRACT_VECTOR_ELT lowering sort it out. 1824Op->getValueType(0),
Op->getOperand(1),
1827case Intrinsic::mips_copy_u_b:
1828case Intrinsic::mips_copy_u_h:
1829case Intrinsic::mips_copy_u_w:
1831case Intrinsic::mips_copy_u_d:
1833// Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64. 1836// Lower into the generic EXTRACT_VECTOR_ELT node and let the type 1837// legalizer and EXTRACT_VECTOR_ELT lowering sort it out. 1838// Note: When i64 is illegal, this results in copy_s.w instructions 1839// instead of copy_u.w instructions. This makes no difference to the 1840// behaviour since i64 is only illegal when the register file is 32-bit. 1842Op->getValueType(0),
Op->getOperand(1),
1845case Intrinsic::mips_div_s_b:
1846case Intrinsic::mips_div_s_h:
1847case Intrinsic::mips_div_s_w:
1848case Intrinsic::mips_div_s_d:
1851case Intrinsic::mips_div_u_b:
1852case Intrinsic::mips_div_u_h:
1853case Intrinsic::mips_div_u_w:
1854case Intrinsic::mips_div_u_d:
1857case Intrinsic::mips_fadd_w:
1858case Intrinsic::mips_fadd_d:
1859// TODO: If intrinsics have fast-math-flags, propagate them. 1862// Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away 1863case Intrinsic::mips_fceq_w:
1864case Intrinsic::mips_fceq_d:
1867case Intrinsic::mips_fcle_w:
1868case Intrinsic::mips_fcle_d:
1871case Intrinsic::mips_fclt_w:
1872case Intrinsic::mips_fclt_d:
1875case Intrinsic::mips_fcne_w:
1876case Intrinsic::mips_fcne_d:
1879case Intrinsic::mips_fcor_w:
1880case Intrinsic::mips_fcor_d:
1883case Intrinsic::mips_fcueq_w:
1884case Intrinsic::mips_fcueq_d:
1887case Intrinsic::mips_fcule_w:
1888case Intrinsic::mips_fcule_d:
1891case Intrinsic::mips_fcult_w:
1892case Intrinsic::mips_fcult_d:
1895case Intrinsic::mips_fcun_w:
1896case Intrinsic::mips_fcun_d:
1899case Intrinsic::mips_fcune_w:
1900case Intrinsic::mips_fcune_d:
1903case Intrinsic::mips_fdiv_w:
1904case Intrinsic::mips_fdiv_d:
1905// TODO: If intrinsics have fast-math-flags, propagate them. 1908case Intrinsic::mips_ffint_u_w:
1909case Intrinsic::mips_ffint_u_d:
1912case Intrinsic::mips_ffint_s_w:
1913case Intrinsic::mips_ffint_s_d:
1916case Intrinsic::mips_fill_b:
1917case Intrinsic::mips_fill_h:
1918case Intrinsic::mips_fill_w:
1919case Intrinsic::mips_fill_d: {
1920EVT ResTy =
Op->getValueType(0);
1924// If ResTy is v2i64 then the type legalizer will break this node down into 1925// an equivalent v4i32. 1928case Intrinsic::mips_fexp2_w:
1929case Intrinsic::mips_fexp2_d: {
1930// TODO: If intrinsics have fast-math-flags, propagate them. 1931EVT ResTy =
Op->getValueType(0);
1936case Intrinsic::mips_flog2_w:
1937case Intrinsic::mips_flog2_d:
1939case Intrinsic::mips_fmadd_w:
1940case Intrinsic::mips_fmadd_d:
1942Op->getOperand(1),
Op->getOperand(2),
Op->getOperand(3));
1943case Intrinsic::mips_fmul_w:
1944case Intrinsic::mips_fmul_d:
1945// TODO: If intrinsics have fast-math-flags, propagate them. 1948case Intrinsic::mips_fmsub_w:
1949case Intrinsic::mips_fmsub_d: {
1950// TODO: If intrinsics have fast-math-flags, propagate them. 1952Op->getOperand(1),
Op->getOperand(2),
Op->getOperand(3));
1954case Intrinsic::mips_frint_w:
1955case Intrinsic::mips_frint_d:
1957case Intrinsic::mips_fsqrt_w:
1958case Intrinsic::mips_fsqrt_d:
1960case Intrinsic::mips_fsub_w:
1961case Intrinsic::mips_fsub_d:
1962// TODO: If intrinsics have fast-math-flags, propagate them. 1965case Intrinsic::mips_ftrunc_u_w:
1966case Intrinsic::mips_ftrunc_u_d:
1969case Intrinsic::mips_ftrunc_s_w:
1970case Intrinsic::mips_ftrunc_s_d:
1973case Intrinsic::mips_ilvev_b:
1974case Intrinsic::mips_ilvev_h:
1975case Intrinsic::mips_ilvev_w:
1976case Intrinsic::mips_ilvev_d:
1978Op->getOperand(1),
Op->getOperand(2));
1979case Intrinsic::mips_ilvl_b:
1980case Intrinsic::mips_ilvl_h:
1981case Intrinsic::mips_ilvl_w:
1982case Intrinsic::mips_ilvl_d:
1984Op->getOperand(1),
Op->getOperand(2));
1985case Intrinsic::mips_ilvod_b:
1986case Intrinsic::mips_ilvod_h:
1987case Intrinsic::mips_ilvod_w:
1988case Intrinsic::mips_ilvod_d:
1990Op->getOperand(1),
Op->getOperand(2));
1991case Intrinsic::mips_ilvr_b:
1992case Intrinsic::mips_ilvr_h:
1993case Intrinsic::mips_ilvr_w:
1994case Intrinsic::mips_ilvr_d:
1996Op->getOperand(1),
Op->getOperand(2));
1997case Intrinsic::mips_insert_b:
1998case Intrinsic::mips_insert_h:
1999case Intrinsic::mips_insert_w:
2000case Intrinsic::mips_insert_d:
2002Op->getOperand(1),
Op->getOperand(3),
Op->getOperand(2));
2003case Intrinsic::mips_insve_b:
2004case Intrinsic::mips_insve_h:
2005case Intrinsic::mips_insve_w:
2006case Intrinsic::mips_insve_d: {
2007// Report an error for out of range values. 2010case Intrinsic::mips_insve_b:
Max = 15;
break;
2011case Intrinsic::mips_insve_h:
Max = 7;
break;
2012case Intrinsic::mips_insve_w:
Max = 3;
break;
2013case Intrinsic::mips_insve_d:
Max = 1;
break;
2016 int64_t
Value = cast<ConstantSDNode>(
Op->getOperand(2))->getSExtValue();
2017if (Value < 0 || Value > Max)
2020Op->getOperand(1),
Op->getOperand(2),
Op->getOperand(3),
2023case Intrinsic::mips_ldi_b:
2024case Intrinsic::mips_ldi_h:
2025case Intrinsic::mips_ldi_w:
2026case Intrinsic::mips_ldi_d:
2028case Intrinsic::mips_lsa:
2029case Intrinsic::mips_dlsa: {
2030EVT ResTy =
Op->getValueType(0);
2033Op->getOperand(2),
Op->getOperand(3)));
2035case Intrinsic::mips_maddv_b:
2036case Intrinsic::mips_maddv_h:
2037case Intrinsic::mips_maddv_w:
2038case Intrinsic::mips_maddv_d: {
2039EVT ResTy =
Op->getValueType(0);
2042Op->getOperand(2),
Op->getOperand(3)));
2044case Intrinsic::mips_max_s_b:
2045case Intrinsic::mips_max_s_h:
2046case Intrinsic::mips_max_s_w:
2047case Intrinsic::mips_max_s_d:
2049Op->getOperand(1),
Op->getOperand(2));
2050case Intrinsic::mips_max_u_b:
2051case Intrinsic::mips_max_u_h:
2052case Intrinsic::mips_max_u_w:
2053case Intrinsic::mips_max_u_d:
2055Op->getOperand(1),
Op->getOperand(2));
2056case Intrinsic::mips_maxi_s_b:
2057case Intrinsic::mips_maxi_s_h:
2058case Intrinsic::mips_maxi_s_w:
2059case Intrinsic::mips_maxi_s_d:
2062case Intrinsic::mips_maxi_u_b:
2063case Intrinsic::mips_maxi_u_h:
2064case Intrinsic::mips_maxi_u_w:
2065case Intrinsic::mips_maxi_u_d:
2068case Intrinsic::mips_min_s_b:
2069case Intrinsic::mips_min_s_h:
2070case Intrinsic::mips_min_s_w:
2071case Intrinsic::mips_min_s_d:
2073Op->getOperand(1),
Op->getOperand(2));
2074case Intrinsic::mips_min_u_b:
2075case Intrinsic::mips_min_u_h:
2076case Intrinsic::mips_min_u_w:
2077case Intrinsic::mips_min_u_d:
2079Op->getOperand(1),
Op->getOperand(2));
2080case Intrinsic::mips_mini_s_b:
2081case Intrinsic::mips_mini_s_h:
2082case Intrinsic::mips_mini_s_w:
2083case Intrinsic::mips_mini_s_d:
2086case Intrinsic::mips_mini_u_b:
2087case Intrinsic::mips_mini_u_h:
2088case Intrinsic::mips_mini_u_w:
2089case Intrinsic::mips_mini_u_d:
2092case Intrinsic::mips_mod_s_b:
2093case Intrinsic::mips_mod_s_h:
2094case Intrinsic::mips_mod_s_w:
2095case Intrinsic::mips_mod_s_d:
2098case Intrinsic::mips_mod_u_b:
2099case Intrinsic::mips_mod_u_h:
2100case Intrinsic::mips_mod_u_w:
2101case Intrinsic::mips_mod_u_d:
2104case Intrinsic::mips_mulv_b:
2105case Intrinsic::mips_mulv_h:
2106case Intrinsic::mips_mulv_w:
2107case Intrinsic::mips_mulv_d:
2110case Intrinsic::mips_msubv_b:
2111case Intrinsic::mips_msubv_h:
2112case Intrinsic::mips_msubv_w:
2113case Intrinsic::mips_msubv_d: {
2114EVT ResTy =
Op->getValueType(0);
2117Op->getOperand(2),
Op->getOperand(3)));
2119case Intrinsic::mips_nlzc_b:
2120case Intrinsic::mips_nlzc_h:
2121case Intrinsic::mips_nlzc_w:
2122case Intrinsic::mips_nlzc_d:
2124case Intrinsic::mips_nor_v: {
2126Op->getOperand(1),
Op->getOperand(2));
2129case Intrinsic::mips_nori_b: {
2135case Intrinsic::mips_or_v:
2138case Intrinsic::mips_ori_b:
2141case Intrinsic::mips_pckev_b:
2142case Intrinsic::mips_pckev_h:
2143case Intrinsic::mips_pckev_w:
2144case Intrinsic::mips_pckev_d:
2146Op->getOperand(1),
Op->getOperand(2));
2147case Intrinsic::mips_pckod_b:
2148case Intrinsic::mips_pckod_h:
2149case Intrinsic::mips_pckod_w:
2150case Intrinsic::mips_pckod_d:
2152Op->getOperand(1),
Op->getOperand(2));
2153case Intrinsic::mips_pcnt_b:
2154case Intrinsic::mips_pcnt_h:
2155case Intrinsic::mips_pcnt_w:
2156case Intrinsic::mips_pcnt_d:
2158case Intrinsic::mips_sat_s_b:
2159case Intrinsic::mips_sat_s_h:
2160case Intrinsic::mips_sat_s_w:
2161case Intrinsic::mips_sat_s_d:
2162case Intrinsic::mips_sat_u_b:
2163case Intrinsic::mips_sat_u_h:
2164case Intrinsic::mips_sat_u_w:
2165case Intrinsic::mips_sat_u_d: {
2166// Report an error for out of range values. 2169case Intrinsic::mips_sat_s_b:
2170case Intrinsic::mips_sat_u_b:
Max = 7;
break;
2171case Intrinsic::mips_sat_s_h:
2172case Intrinsic::mips_sat_u_h:
Max = 15;
break;
2173case Intrinsic::mips_sat_s_w:
2174case Intrinsic::mips_sat_u_w:
Max = 31;
break;
2175case Intrinsic::mips_sat_s_d:
2176case Intrinsic::mips_sat_u_d:
Max = 63;
break;
2179 int64_t
Value = cast<ConstantSDNode>(
Op->getOperand(2))->getSExtValue();
2180if (Value < 0 || Value > Max)
2184case Intrinsic::mips_shf_b:
2185case Intrinsic::mips_shf_h:
2186case Intrinsic::mips_shf_w: {
2187 int64_t
Value = cast<ConstantSDNode>(
Op->getOperand(2))->getSExtValue();
2188if (Value < 0 || Value > 255)
2191Op->getOperand(2),
Op->getOperand(1));
2193case Intrinsic::mips_sldi_b:
2194case Intrinsic::mips_sldi_h:
2195case Intrinsic::mips_sldi_w:
2196case Intrinsic::mips_sldi_d: {
2197// Report an error for out of range values. 2200case Intrinsic::mips_sldi_b:
Max = 15;
break;
2201case Intrinsic::mips_sldi_h:
Max = 7;
break;
2202case Intrinsic::mips_sldi_w:
Max = 3;
break;
2203case Intrinsic::mips_sldi_d:
Max = 1;
break;
2206 int64_t
Value = cast<ConstantSDNode>(
Op->getOperand(3))->getSExtValue();
2207if (Value < 0 || Value > Max)
2211case Intrinsic::mips_sll_b:
2212case Intrinsic::mips_sll_h:
2213case Intrinsic::mips_sll_w:
2214case Intrinsic::mips_sll_d:
2217case Intrinsic::mips_slli_b:
2218case Intrinsic::mips_slli_h:
2219case Intrinsic::mips_slli_w:
2220case Intrinsic::mips_slli_d:
2223case Intrinsic::mips_splat_b:
2224case Intrinsic::mips_splat_h:
2225case Intrinsic::mips_splat_w:
2226case Intrinsic::mips_splat_d:
2227// We can't lower via VECTOR_SHUFFLE because it requires constant shuffle 2228// masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because 2229// EXTRACT_VECTOR_ELT can't extract i64's on MIPS32. 2230// Instead we lower to MipsISD::VSHF and match from there. 2234case Intrinsic::mips_splati_b:
2235case Intrinsic::mips_splati_h:
2236case Intrinsic::mips_splati_w:
2237case Intrinsic::mips_splati_d:
2241case Intrinsic::mips_sra_b:
2242case Intrinsic::mips_sra_h:
2243case Intrinsic::mips_sra_w:
2244case Intrinsic::mips_sra_d:
2247case Intrinsic::mips_srai_b:
2248case Intrinsic::mips_srai_h:
2249case Intrinsic::mips_srai_w:
2250case Intrinsic::mips_srai_d:
2253case Intrinsic::mips_srari_b:
2254case Intrinsic::mips_srari_h:
2255case Intrinsic::mips_srari_w:
2256case Intrinsic::mips_srari_d: {
2257// Report an error for out of range values. 2260case Intrinsic::mips_srari_b:
Max = 7;
break;
2261case Intrinsic::mips_srari_h:
Max = 15;
break;
2262case Intrinsic::mips_srari_w:
Max = 31;
break;
2263case Intrinsic::mips_srari_d:
Max = 63;
break;
2266 int64_t
Value = cast<ConstantSDNode>(
Op->getOperand(2))->getSExtValue();
2267if (Value < 0 || Value > Max)
2271case Intrinsic::mips_srl_b:
2272case Intrinsic::mips_srl_h:
2273case Intrinsic::mips_srl_w:
2274case Intrinsic::mips_srl_d:
2277case Intrinsic::mips_srli_b:
2278case Intrinsic::mips_srli_h:
2279case Intrinsic::mips_srli_w:
2280case Intrinsic::mips_srli_d:
2283case Intrinsic::mips_srlri_b:
2284case Intrinsic::mips_srlri_h:
2285case Intrinsic::mips_srlri_w:
2286case Intrinsic::mips_srlri_d: {
2287// Report an error for out of range values. 2290case Intrinsic::mips_srlri_b:
Max = 7;
break;
2291case Intrinsic::mips_srlri_h:
Max = 15;
break;
2292case Intrinsic::mips_srlri_w:
Max = 31;
break;
2293case Intrinsic::mips_srlri_d:
Max = 63;
break;
2296 int64_t
Value = cast<ConstantSDNode>(
Op->getOperand(2))->getSExtValue();
2297if (Value < 0 || Value > Max)
2301case Intrinsic::mips_subv_b:
2302case Intrinsic::mips_subv_h:
2303case Intrinsic::mips_subv_w:
2304case Intrinsic::mips_subv_d:
2307case Intrinsic::mips_subvi_b:
2308case Intrinsic::mips_subvi_h:
2309case Intrinsic::mips_subvi_w:
2310case Intrinsic::mips_subvi_d:
2313case Intrinsic::mips_vshf_b:
2314case Intrinsic::mips_vshf_h:
2315case Intrinsic::mips_vshf_w:
2316case Intrinsic::mips_vshf_d:
2318Op->getOperand(1),
Op->getOperand(2),
Op->getOperand(3));
2319case Intrinsic::mips_xor_v:
2322case Intrinsic::mips_xori_b:
2325case Intrinsic::thread_pointer: {
2338EVT ResTy =
Op->getValueType(0);
2341// For N64 addresses have the underlying type MVT::i64. This intrinsic 2342// however takes an i32 signed constant offset. The actual type of the 2343// intrinsic is a scaled signed i10. 2354unsignedIntr =
Op->getConstantOperandVal(1);
2358case Intrinsic::mips_extp:
2360case Intrinsic::mips_extpdp:
2362case Intrinsic::mips_extr_w:
2364case Intrinsic::mips_extr_r_w:
2366case Intrinsic::mips_extr_rs_w:
2368case Intrinsic::mips_extr_s_h:
2370case Intrinsic::mips_mthlip:
2372case Intrinsic::mips_mulsaq_s_w_ph:
2374case Intrinsic::mips_maq_s_w_phl:
2376case Intrinsic::mips_maq_s_w_phr:
2378case Intrinsic::mips_maq_sa_w_phl:
2380case Intrinsic::mips_maq_sa_w_phr:
2382case Intrinsic::mips_dpaq_s_w_ph:
2384case Intrinsic::mips_dpsq_s_w_ph:
2386case Intrinsic::mips_dpaq_sa_l_w:
2388case Intrinsic::mips_dpsq_sa_l_w:
2390case Intrinsic::mips_dpaqx_s_w_ph:
2392case Intrinsic::mips_dpaqx_sa_w_ph:
2394case Intrinsic::mips_dpsqx_s_w_ph:
2396case Intrinsic::mips_dpsqx_sa_w_ph:
2398case Intrinsic::mips_ld_b:
2399case Intrinsic::mips_ld_h:
2400case Intrinsic::mips_ld_w:
2401case Intrinsic::mips_ld_d:
2415// For N64 addresses have the underlying type MVT::i64. This intrinsic 2416// however takes an i32 signed constant offset. The actual type of the 2417// intrinsic is a scaled signed i10. 2429unsignedIntr =
Op->getConstantOperandVal(1);
2433case Intrinsic::mips_st_b:
2434case Intrinsic::mips_st_h:
2435case Intrinsic::mips_st_w:
2436case Intrinsic::mips_st_d:
2441// Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT. 2443// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We 2444// choose to sign-extend but we could have equally chosen zero-extend. The 2445// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT 2446// result into this node later (possibly changing it to a zero-extend in the 2451EVT ResTy =
Op->getValueType(0);
2471if (isa<ConstantSDNode>(
Op))
2473if (isa<ConstantFPSDNode>(
Op))
2485// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the 2488// Lowers according to the following rules: 2489// - Constant splats are legal as-is as long as the SplatBitSize is a power of 2490// 2 less than or equal to 64 and the value fits into a signed 10-bit 2492// - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize 2493// is a power of 2 less than or equal to 64 and the value does not fit into a 2494// signed 10-bit immediate 2495// - Non-constant splats are legal as-is. 2496// - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT. 2497// - All others are illegal and must be expanded. 2501EVT ResTy =
Op->getValueType(0);
2503APInt SplatValue, SplatUndef;
2504unsigned SplatBitSize;
2510if (
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2513// We can only cope with 8, 16, 32, or 64-bit elements 2514if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
2518// If the value isn't an integer type we will have to bitcast 2519// from an integer type first. Also, if there are any undefs, we must 2520// lower them to defined values first. 2526switch (SplatBitSize) {
2530 ViaVecTy = MVT::v16i8;
2533 ViaVecTy = MVT::v8i16;
2536 ViaVecTy = MVT::v4i32;
2539// There's no fill.d to fall back on for 64-bit values 2543// SelectionDAG::getConstant will promote SplatValue appropriately. 2546// Bitcast to the type we originally wanted 2547if (ViaVecTy != ResTy)
2554// Use INSERT_VECTOR_ELT operations rather than expand to stores. 2555// The resulting code is the same length as the expansion, but it doesn't 2556// use memory operations 2557EVT ResTy =
Node->getValueType(0);
2563for (
unsigned i = 0; i < NumElts; ++i) {
2574// Lower VECTOR_SHUFFLE into SHF (if possible). 2576// SHF splits the vector into blocks of four elements, then shuffles these 2577// elements according to a <4 x i2> constant (encoded as an integer immediate). 2579// It is therefore possible to lower into SHF when the mask takes the form: 2580// <a, b, c, d, a+4, b+4, c+4, d+4, a+8, b+8, c+8, d+8, ...> 2581// When undef's appear they are treated as if they were whatever value is 2582// necessary in order to fit the above forms. 2585// %2 = shufflevector <8 x i16> %0, <8 x i16> undef, 2586// <8 x i32> <i32 3, i32 2, i32 1, i32 0, 2587// i32 7, i32 6, i32 5, i32 4> 2589// (SHF_H $w0, $w1, 27) 2590// where the 27 comes from: 2591// 3 + (2 << 2) + (1 << 4) + (0 << 6) 2595int SHFIndices[4] = { -1, -1, -1, -1 };
2597if (Indices.
size() < 4)
2600for (
unsigned i = 0; i < 4; ++i) {
2601for (
unsigned j = i; j < Indices.
size(); j += 4) {
2604// Convert from vector index to 4-element subvector index 2605// If an index refers to an element outside of the subvector then give up 2608if (Idx < 0 || Idx >= 4)
2612// If the mask has an undef, replace it with the current index. 2613// Note that it might still be undef if the current index is also undef 2614if (SHFIndices[i] == -1)
2617// Check that non-undef values are the same as in the mask. If they 2618// aren't then give up 2619if (!(
Idx == -1 ||
Idx == SHFIndices[i]))
2624// Calculate the immediate. Replace any remaining undefs with zero 2626for (
int i = 3; i >= 0; --i) {
2627intIdx = SHFIndices[i];
2642/// Determine whether a range fits a regular pattern of values. 2643/// This function accounts for the possibility of jumping over the End iterator. 2644template <
typename ValType>
2647unsigned CheckStride,
2649 ValType ExpectedIndex,
unsigned ExpectedIndexStride) {
2653if (*
I != -1 && *
I != ExpectedIndex)
2655 ExpectedIndex += ExpectedIndexStride;
2657// Incrementing past End is undefined behaviour so we must increment one 2658// step at a time and check for End at each step. 2659for (
unsigned n = 0; n < CheckStride &&
I !=
End; ++n, ++
I)
2660 ;
// Empty loop body. 2665// Determine whether VECTOR_SHUFFLE is a SPLATI. 2667// It is a SPLATI when the mask is: 2669// where x is any valid index. 2671// When undef's appear in the mask they are treated as if they were whatever 2672// value is necessary in order to fit the above form. 2679for (
constauto &V : Indices) {
2686return fitsRegularPattern<int>(Indices.
begin(), 1, Indices.
end(), SplatIndex,
2690// Lower VECTOR_SHUFFLE into ILVEV (if possible). 2692// ILVEV interleaves the even elements from each vector. 2694// It is possible to lower into ILVEV when the mask consists of two of the 2695// following forms interleaved: 2697// <n, n+2, n+4, ...> 2698// where n is the number of elements in the vector. 2700// <0, 0, 2, 2, 4, 4, ...> 2701// <0, n, 2, n+2, 4, n+4, ...> 2703// When undef's appear in the mask they are treated as if they were whatever 2704// value is necessary in order to fit the above forms. 2712constauto &Begin = Indices.
begin();
2713constauto &
End = Indices.
end();
2715// Check even elements are taken from the even elements of one half or the 2716// other and pick an operand accordingly. 2717if (fitsRegularPattern<int>(Begin, 2,
End, 0, 2))
2718 Wt =
Op->getOperand(0);
2719elseif (fitsRegularPattern<int>(Begin, 2,
End, Indices.
size(), 2))
2720 Wt =
Op->getOperand(1);
2724// Check odd elements are taken from the even elements of one half or the 2725// other and pick an operand accordingly. 2726if (fitsRegularPattern<int>(Begin + 1, 2,
End, 0, 2))
2727 Ws =
Op->getOperand(0);
2728elseif (fitsRegularPattern<int>(Begin + 1, 2,
End, Indices.
size(), 2))
2729 Ws =
Op->getOperand(1);
2736// Lower VECTOR_SHUFFLE into ILVOD (if possible). 2738// ILVOD interleaves the odd elements from each vector. 2740// It is possible to lower into ILVOD when the mask consists of two of the 2741// following forms interleaved: 2743// <n+1, n+3, n+5, ...> 2744// where n is the number of elements in the vector. 2746// <1, 1, 3, 3, 5, 5, ...> 2747// <1, n+1, 3, n+3, 5, n+5, ...> 2749// When undef's appear in the mask they are treated as if they were whatever 2750// value is necessary in order to fit the above forms. 2758constauto &Begin = Indices.
begin();
2759constauto &
End = Indices.
end();
2761// Check even elements are taken from the odd elements of one half or the 2762// other and pick an operand accordingly. 2763if (fitsRegularPattern<int>(Begin, 2,
End, 1, 2))
2764 Wt =
Op->getOperand(0);
2765elseif (fitsRegularPattern<int>(Begin, 2,
End, Indices.
size() + 1, 2))
2766 Wt =
Op->getOperand(1);
2770// Check odd elements are taken from the odd elements of one half or the 2771// other and pick an operand accordingly. 2772if (fitsRegularPattern<int>(Begin + 1, 2,
End, 1, 2))
2773 Ws =
Op->getOperand(0);
2774elseif (fitsRegularPattern<int>(Begin + 1, 2,
End, Indices.
size() + 1, 2))
2775 Ws =
Op->getOperand(1);
2782// Lower VECTOR_SHUFFLE into ILVR (if possible). 2784// ILVR interleaves consecutive elements from the right (lowest-indexed) half of 2787// It is possible to lower into ILVR when the mask consists of two of the 2788// following forms interleaved: 2790// <n, n+1, n+2, ...> 2791// where n is the number of elements in the vector. 2793// <0, 0, 1, 1, 2, 2, ...> 2794// <0, n, 1, n+1, 2, n+2, ...> 2796// When undef's appear in the mask they are treated as if they were whatever 2797// value is necessary in order to fit the above forms. 2805constauto &Begin = Indices.
begin();
2806constauto &
End = Indices.
end();
2808// Check even elements are taken from the right (lowest-indexed) elements of 2809// one half or the other and pick an operand accordingly. 2810if (fitsRegularPattern<int>(Begin, 2,
End, 0, 1))
2811 Wt =
Op->getOperand(0);
2812elseif (fitsRegularPattern<int>(Begin, 2,
End, Indices.
size(), 1))
2813 Wt =
Op->getOperand(1);
2817// Check odd elements are taken from the right (lowest-indexed) elements of 2818// one half or the other and pick an operand accordingly. 2819if (fitsRegularPattern<int>(Begin + 1, 2,
End, 0, 1))
2820 Ws =
Op->getOperand(0);
2821elseif (fitsRegularPattern<int>(Begin + 1, 2,
End, Indices.
size(), 1))
2822 Ws =
Op->getOperand(1);
2829// Lower VECTOR_SHUFFLE into ILVL (if possible). 2831// ILVL interleaves consecutive elements from the left (highest-indexed) half 2834// It is possible to lower into ILVL when the mask consists of two of the 2835// following forms interleaved: 2836// <x, x+1, x+2, ...> 2837// <n+x, n+x+1, n+x+2, ...> 2838// where n is the number of elements in the vector and x is half n. 2840// <x, x, x+1, x+1, x+2, x+2, ...> 2841// <x, n+x, x+1, n+x+1, x+2, n+x+2, ...> 2843// When undef's appear in the mask they are treated as if they were whatever 2844// value is necessary in order to fit the above forms. 2850unsigned HalfSize = Indices.
size() / 2;
2853constauto &Begin = Indices.
begin();
2854constauto &
End = Indices.
end();
2856// Check even elements are taken from the left (highest-indexed) elements of 2857// one half or the other and pick an operand accordingly. 2858if (fitsRegularPattern<int>(Begin, 2,
End, HalfSize, 1))
2859 Wt =
Op->getOperand(0);
2860elseif (fitsRegularPattern<int>(Begin, 2,
End, Indices.
size() + HalfSize, 1))
2861 Wt =
Op->getOperand(1);
2865// Check odd elements are taken from the left (highest-indexed) elements of 2866// one half or the other and pick an operand accordingly. 2867if (fitsRegularPattern<int>(Begin + 1, 2,
End, HalfSize, 1))
2868 Ws =
Op->getOperand(0);
2869elseif (fitsRegularPattern<int>(Begin + 1, 2,
End, Indices.
size() + HalfSize,
2871 Ws =
Op->getOperand(1);
2878// Lower VECTOR_SHUFFLE into PCKEV (if possible). 2880// PCKEV copies the even elements of each vector into the result vector. 2882// It is possible to lower into PCKEV when the mask consists of two of the 2883// following forms concatenated: 2885// <n, n+2, n+4, ...> 2886// where n is the number of elements in the vector. 2888// <0, 2, 4, ..., 0, 2, 4, ...> 2889// <0, 2, 4, ..., n, n+2, n+4, ...> 2891// When undef's appear in the mask they are treated as if they were whatever 2892// value is necessary in order to fit the above forms. 2900constauto &Begin = Indices.
begin();
2901constauto &Mid = Indices.
begin() + Indices.
size() / 2;
2902constauto &
End = Indices.
end();
2904if (fitsRegularPattern<int>(Begin, 1, Mid, 0, 2))
2905 Wt =
Op->getOperand(0);
2906elseif (fitsRegularPattern<int>(Begin, 1, Mid, Indices.
size(), 2))
2907 Wt =
Op->getOperand(1);
2911if (fitsRegularPattern<int>(Mid, 1,
End, 0, 2))
2912 Ws =
Op->getOperand(0);
2913elseif (fitsRegularPattern<int>(Mid, 1,
End, Indices.
size(), 2))
2914 Ws =
Op->getOperand(1);
2921// Lower VECTOR_SHUFFLE into PCKOD (if possible). 2923// PCKOD copies the odd elements of each vector into the result vector. 2925// It is possible to lower into PCKOD when the mask consists of two of the 2926// following forms concatenated: 2928// <n+1, n+3, n+5, ...> 2929// where n is the number of elements in the vector. 2931// <1, 3, 5, ..., 1, 3, 5, ...> 2932// <1, 3, 5, ..., n+1, n+3, n+5, ...> 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. 2943constauto &Begin = Indices.
begin();
2944constauto &Mid = Indices.
begin() + Indices.
size() / 2;
2945constauto &
End = Indices.
end();
2947if (fitsRegularPattern<int>(Begin, 1, Mid, 1, 2))
2948 Wt =
Op->getOperand(0);
2949elseif (fitsRegularPattern<int>(Begin, 1, Mid, Indices.
size() + 1, 2))
2950 Wt =
Op->getOperand(1);
2954if (fitsRegularPattern<int>(Mid, 1,
End, 1, 2))
2955 Ws =
Op->getOperand(0);
2956elseif (fitsRegularPattern<int>(Mid, 1,
End, Indices.
size() + 1, 2))
2957 Ws =
Op->getOperand(1);
2964// Lower VECTOR_SHUFFLE into VSHF. 2966// This mostly consists of converting the shuffle indices in Indices into a 2967// BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is 2968// also code to eliminate unused operands of the VECTOR_SHUFFLE. For example, 2969// if the type is v8i16 and all the indices are less than 8 then the second 2970// operand is unused and can be replaced with anything. We choose to replace it 2971// with the used operand since this reduces the number of instructions overall. 2973// NOTE: SPLATI shuffle masks may contain UNDEFs, since isSPLATI() treats 2974// UNDEFs as same as SPLATI index. 2975// For other instances we use the last valid index if UNDEF is 2986bool Using1stVec =
false;
2987bool Using2ndVec =
false;
2992"shuffle mask starts with an UNDEF, which is not expected");
2994for (
int i = 0; i < ResTyNumElts; ++i) {
2995// Idx == -1 means UNDEF 2998if (0 <=
Idx &&
Idx < ResTyNumElts)
3000if (ResTyNumElts <=
Idx &&
Idx < ResTyNumElts * 2)
3003int LastValidIndex = 0;
3004for (
size_t i = 0; i < Indices.
size(); i++) {
3007// Continue using splati index or use the last valid index. 3008Idx = isSPLATI ? Indices[0] : LastValidIndex;
3010 LastValidIndex =
Idx;
3017if (Using1stVec && Using2ndVec) {
3018 Op0 =
Op->getOperand(0);
3019 Op1 =
Op->getOperand(1);
3020 }
elseif (Using1stVec)
3021 Op0 = Op1 =
Op->getOperand(0);
3023 Op0 = Op1 =
Op->getOperand(1);
3027// VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion. 3028// <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11> 3029// VSHF concatenates the vectors in a bitwise fashion: 3030// <0b00, 0b01> + <0b10, 0b11> -> 3031// 0b0100 + 0b1110 -> 0b01001110 3032// <0b10, 0b11, 0b00, 0b01> 3033// We must therefore swap the operands to get the correct result. 3037// Lower VECTOR_SHUFFLE into one of a number of instructions depending on the 3038// indices in the shuffle. 3042EVT ResTy =
Op->getValueType(0);
3050for (
int i = 0; i < ResTyNumElts; ++i)
3053// splati.[bhwd] is preferable to the others but is matched from 3079// bposge32_pseudo $vr0 3089// $vr0 = phi($vr2, $fbb, $vr1, $tbb) 3105// Transfer the remainder of BB and its successor edges to Sink. 3108Sink->transferSuccessorsAndUpdatePHIs(BB);
3116// Insert the real bposge32 instruction to $BB. 3118// Insert the real bposge32c instruction to $BB. 3132// Insert phi function to $Sink. 3134MI.getOperand(0).getReg())
3140MI.eraseFromParent();
// The pseudo instruction is gone now. 3147// vany_nonzero $rd, $ws 3158// $rd = phi($rd1, $fbb, $rd2, $tbb) 3174// Transfer the remainder of BB and its successor edges to Sink. 3177Sink->transferSuccessorsAndUpdatePHIs(BB);
3185// Insert the real bnz.b instruction to $BB. 3201// Insert phi function to $Sink. 3203MI.getOperand(0).getReg())
3209MI.eraseFromParent();
// The pseudo instruction is gone now. 3213// Emit the COPY_FW pseudo instruction. 3215// copy_fw_pseudo $fd, $ws, n 3217// copy_u_w $rt, $ws, $n 3220// When n is zero, the equivalent operation can be performed with (potentially) 3221// zero instructions due to register overlaps. This optimization is never valid 3222// for lane 1 because it would require FR=0 mode which isn't supported by MSA. 3231unsigned Lane =
MI.getOperand(2).getImm();
3236// We must copy to an even-numbered MSA register so that the 3237// single-precision sub-register is also guaranteed to be even-numbered. 3238 Wt =
RegInfo.createVirtualRegister(&Mips::MSA128WEvensRegClass);
3247 : &Mips::MSA128WEvensRegClass);
3253MI.eraseFromParent();
// The pseudo instruction is gone now. 3257// Emit the COPY_FD pseudo instruction. 3259// copy_fd_pseudo $fd, $ws, n 3261// splati.d $wt, $ws, $n 3262// copy $fd, $wt:sub_64 3264// When n is zero, the equivalent operation can be performed with (potentially) 3265// zero instructions due to register overlaps. This optimization is always 3266// valid because FR=1 mode which is the only supported mode in MSA. 3276unsigned Lane =
MI.getOperand(2).getImm() * 2;
3288MI.eraseFromParent();
// The pseudo instruction is gone now. 3292// Emit the INSERT_FW pseudo instruction. 3294// insert_fw_pseudo $wd, $wd_in, $n, $fs 3296// subreg_to_reg $wt:sub_lo, $fs 3297// insve_w $wd[$n], $wd_in, $wt[0] 3306unsigned Lane =
MI.getOperand(2).getImm();
3310 : &Mips::MSA128WEvensRegClass);
3322MI.eraseFromParent();
// The pseudo instruction is gone now. 3326// Emit the INSERT_FD pseudo instruction. 3328// insert_fd_pseudo $wd, $fs, n 3330// subreg_to_reg $wt:sub_64, $fs 3331// insve_d $wd[$n], $wd_in, $wt[0] 3342unsigned Lane =
MI.getOperand(2).getImm();
3356MI.eraseFromParent();
// The pseudo instruction is gone now. 3360// Emit the INSERT_([BHWD]|F[WD])_VIDX pseudo instruction. 3363// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $rs) 3365// (SLL $lanetmp1, $lane, <log2size) 3366// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1) 3367// (INSERT_[BHWD], $wdtmp2, $wdtmp1, 0, $rs) 3368// (NEG $lanetmp2, $lanetmp1) 3369// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2) 3371// For floating point: 3372// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $fs) 3374// (SUBREG_TO_REG $wt, $fs, <subreg>) 3375// (SLL $lanetmp1, $lane, <log2size) 3376// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1) 3377// (INSVE_[WD], $wdtmp2, 0, $wdtmp1, 0) 3378// (NEG $lanetmp2, $lanetmp1) 3379// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2) 3387Register SrcVecReg =
MI.getOperand(1).getReg();
3389Register SrcValReg =
MI.getOperand(3).getReg();
3392// FIXME: This should be true for N32 too. 3397unsigned EltLog2Size;
3398unsigned InsertOp = 0;
3399unsigned InsveOp = 0;
3400switch (EltSizeInBytes) {
3405 InsertOp = Mips::INSERT_B;
3406 InsveOp = Mips::INSVE_B;
3407 VecRC = &Mips::MSA128BRegClass;
3411 InsertOp = Mips::INSERT_H;
3412 InsveOp = Mips::INSVE_H;
3413 VecRC = &Mips::MSA128HRegClass;
3417 InsertOp = Mips::INSERT_W;
3418 InsveOp = Mips::INSVE_W;
3419 VecRC = &Mips::MSA128WRegClass;
3423 InsertOp = Mips::INSERT_D;
3424 InsveOp = Mips::INSVE_D;
3425 VecRC = &Mips::MSA128DRegClass;
3434 .
addImm(EltSizeInBytes == 8 ? Mips::sub_64 : Mips::sub_lo);
3438// Convert the lane index into a byte index 3439if (EltSizeInBytes != 1) {
3447// Rotate bytes around so that the desired lane is element zero 3452 .
addReg(LaneReg, 0, SubRegIdx);
3456// Use insve.df to insert to element zero 3463// Use insert.df to insert to element zero 3470// Rotate elements the rest of the way for a full rotation. 3471// sld.df inteprets $rt modulo the number of columns so we only need to negate 3472// the lane index to do this. 3481 .
addReg(LaneTmp2, 0, SubRegIdx);
3483MI.eraseFromParent();
// The pseudo instruction is gone now. 3487// Emit the FILL_FW pseudo instruction. 3489// fill_fw_pseudo $wd, $fs 3492// insert_subreg $wt2:subreg_lo, $wt1, $fs 3493// splati.w $wd, $wt2[0] 3504 : &Mips::MSA128WEvensRegClass);
3507 : &Mips::MSA128WEvensRegClass);
3516MI.eraseFromParent();
// The pseudo instruction is gone now. 3520// Emit the FILL_FD pseudo instruction. 3522// fill_fd_pseudo $wd, $fs 3525// insert_subreg $wt2:subreg_64, $wt1, $fs 3526// splati.d $wd, $wt2[0] 3547MI.eraseFromParent();
// The pseudo instruction is gone now. 3551// Emit the ST_F16_PSEDUO instruction to store a f16 value from an MSA 3554// STF16 MSA128F16:$wd, mem_simm10:$addr 3556// copy_u.h $rtemp,$wd[0] 3559// Safety: We can't use st.h & co as they would over write the memory after 3560// the destination. It would require half floats be allocated 16 bytes(!) of 3574// Caution: A load via the GOT can expand to a GPR32 operand, a load via 3575// spill and reload can expand as a GPR64 operand. Examine the 3576// operand in detail and default to ABI. 3578MI.getOperand(1).isReg() ?
RegInfo.getRegClass(
MI.getOperand(1).getReg())
3580 : &Mips::GPR64RegClass);
3581constbool UsingMips32 = RC == &Mips::GPR32RegClass;
3600MI.eraseFromParent();
3604// Emit the LD_F16_PSEDUO instruction to load a f16 value into an MSA register. 3606// LD_F16 MSA128F16:$wd, mem_simm10:$addr 3609// fill.h $wd, $rtemp 3611// Safety: We can't use ld.h & co as they over-read from the source. 3612// Additionally, if the address is not modulo 16, 2 cases can occur: 3613// a) Segmentation fault as the load instruction reads from a memory page 3614// memory it's not supposed to. 3615// b) The load crosses an implementation specific boundary, requiring OS 3626// Caution: A load via the GOT can expand to a GPR32 operand, a load via 3627// spill and reload can expand as a GPR64 operand. Examine the 3628// operand in detail and default to ABI. 3630MI.getOperand(1).isReg() ?
RegInfo.getRegClass(
MI.getOperand(1).getReg())
3632 : &Mips::GPR64RegClass);
3634constbool UsingMips32 = RC == &Mips::GPR32RegClass;
3638BuildMI(*BB,
MI,
DL,
TII->get(UsingMips32 ? Mips::LH : Mips::LH64), Rt);
3650MI.eraseFromParent();
3654// Emit the FPROUND_PSEUDO instruction. 3656// Round an FGR64Opnd, FGR32Opnd to an f16. 3658// Safety: Cycle the operand through the GPRs so the result always ends up 3659// the correct MSA register. 3661// FIXME: This copying is strictly unnecessary. If we could tie FGR32Opnd:$Fs 3662// / FGR64Opnd:$Fs and MSA128F16:$Wd to the same physical register 3663// (which they can be, as the MSA registers are defined to alias the 3664// FPU's 64 bit and 32 bit registers) the result can be accessed using 3665// the correct register class. That requires operands be tie-able across 3666// register classes which have a sub/super register class relationship. 3670// FPROUND MSA128F16:$wd, FGR32Opnd:$fs 3673// fill.w $rtemp, $wtemp 3674// fexdo.w $wd, $wtemp, $wtemp 3676// For FPG64Opnd on mips32r2+: 3678// FPROUND MSA128F16:$wd, FGR64Opnd:$fs 3681// fill.w $rtemp, $wtemp 3682// mfhc1 $rtemp2, $fs 3683// insert.w $wtemp[1], $rtemp2 3684// insert.w $wtemp[3], $rtemp2 3685// fexdo.w $wtemp2, $wtemp, $wtemp 3686// fexdo.h $wd, $temp2, $temp2 3688// For FGR64Opnd on mips64r2+: 3690// FPROUND MSA128F16:$wd, FGR64Opnd:$fs 3693// fill.d $rtemp, $wtemp 3694// fexdo.w $wtemp2, $wtemp, $wtemp 3695// fexdo.h $wd, $wtemp2, $wtemp2 3697// Safety note: As $wtemp is UNDEF, we may provoke a spurious exception if the 3698// undef bits are "just right" and the exception enable bits are 3699// set. By using fill.w to replicate $fs into all elements over 3700// insert.w for one element, we avoid that potiential case. If 3701// fexdo.[hw] causes an exception in, the exception is valid and it 3702// occurs for all elements. 3708// Strictly speaking, we need MIPS32R5 to support MSA. We'll be generous 3709// here. It's technically doable to support MIPS32 here, but the ISA forbids 3724 IsFGR64onMips64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3725unsigned MFC1Opc = IsFGR64onMips64
3727 : (IsFGR64onMips32 ? Mips::MFC1_D64 : Mips::MFC1);
3728unsigned FILLOpc = IsFGR64onMips64 ? Mips::FILL_D : Mips::FILL_W;
3730// Perform the register class copy as mentioned above. 3734unsigned WPHI = Wtemp;
3736if (IsFGR64onMips32) {
3739Register Wtemp2 =
RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3740Register Wtemp3 =
RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3753Register Wtemp2 =
RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
3762MI.eraseFromParent();
3766// Emit the FPEXTEND_PSEUDO instruction. 3768// Expand an f16 to either a FGR32Opnd or FGR64Opnd. 3770// Safety: Cycle the result through the GPRs so the result always ends up 3771// the correct floating point register. 3773// FIXME: This copying is strictly unnecessary. If we could tie FGR32Opnd:$Fd 3774// / FGR64Opnd:$Fd and MSA128F16:$Ws to the same physical register 3775// (which they can be, as the MSA registers are defined to alias the 3776// FPU's 64 bit and 32 bit registers) the result can be accessed using 3777// the correct register class. That requires operands be tie-able across 3778// register classes which have a sub/super register class relationship. I 3783// FPEXTEND FGR32Opnd:$fd, MSA128F16:$ws 3785// fexupr.w $wtemp, $ws 3786// copy_s.w $rtemp, $ws[0] 3789// For FGR64Opnd on Mips64: 3791// FPEXTEND FGR64Opnd:$fd, MSA128F16:$ws 3793// fexupr.w $wtemp, $ws 3794// fexupr.d $wtemp2, $wtemp 3795// copy_s.d $rtemp, $wtemp2s[0] 3798// For FGR64Opnd on Mips32: 3800// FPEXTEND FGR64Opnd:$fd, MSA128F16:$ws 3802// fexupr.w $wtemp, $ws 3803// fexupr.d $wtemp2, $wtemp 3804// copy_s.w $rtemp, $wtemp2[0] 3805// mtc1 $rtemp, $ftemp 3806// copy_s.w $rtemp2, $wtemp2[1] 3807// $fd = mthc1 $rtemp2, $ftemp 3813// Strictly speaking, we need MIPS32R5 to support MSA. We'll be generous 3814// here. It's technically doable to support MIPS32 here, but the ISA forbids 3828 IsFGR64onMips64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3829unsigned MTC1Opc = IsFGR64onMips64
3831 : (IsFGR64onMips32 ? Mips::MTC1_D64 : Mips::MTC1);
3832Register COPYOpc = IsFGR64onMips64 ? Mips::COPY_S_D : Mips::COPY_S_W;
3839 WPHI =
RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3843// Perform the safety regclass copy mentioned above. 3846 ?
RegInfo.createVirtualRegister(&Mips::FGR64RegClass)
3851if (IsFGR64onMips32) {
3861MI.eraseFromParent();
3865// Emit the FEXP2_W_1 pseudo instructions. 3867// fexp2_w_1_pseudo $wd, $wt 3870// fexp2.w $wd, $ws, $wt 3881// Splat 1.0 into a vector 3885// Emit 1.0 * fexp2(Wt) 3888 .
addReg(
MI.getOperand(1).getReg());
3890MI.eraseFromParent();
// The pseudo instruction is gone now. 3894// Emit the FEXP2_D_1 pseudo instructions. 3896// fexp2_d_1_pseudo $wd, $wt 3899// fexp2.d $wd, $ws, $wt 3910// Splat 1.0 into a vector 3914// Emit 1.0 * fexp2(Wt) 3917 .
addReg(
MI.getOperand(1).getReg());
3919MI.eraseFromParent();
// The pseudo instruction is gone now. static SDValue performSHLCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
If the operand is a bitwise AND with a constant RHS, and the shift has a constant RHS and is the only...
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget, const AArch64TargetLowering &TLI)
static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue performSETCCCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static bool fitsRegularPattern(typename SmallVectorImpl< ValType >::const_iterator Begin, unsigned CheckStride, typename SmallVectorImpl< ValType >::const_iterator End, ValType ExpectedIndex, unsigned ExpectedIndexStride)
Determine whether a range fits a regular pattern of values.
static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
static SDValue truncateVecElts(SDNode *Node, SelectionDAG &DAG)
static bool isConstantOrUndef(const SDValue Op)
static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op)
static SDValue lowerMSABinaryBitImmIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc, SDValue Imm, bool BigEndian)
static SDValue lowerMSABitClearImm(SDValue Op, SelectionDAG &DAG)
static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, const TargetLowering::DAGCombinerInfo &DCI, const MipsSETargetLowering *TL, const MipsSubtarget &Subtarget)
static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc)
static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc)
static cl::opt< bool > NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), cl::desc("Expand double precision loads and " "stores to their single precision " "counterparts"))
static SDValue lowerVECTOR_SHUFFLE_ILVR(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue, bool BigEndian, SelectionDAG &DAG)
static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG)
static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian)
static SDValue initAccumulator(SDValue In, const SDLoc &DL, SelectionDAG &DAG)
static bool isBitwiseInverse(SDValue N, SDValue OfNode)
static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, const MipsSubtarget &Subtarget)
static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
static bool isVectorAllOnes(SDValue N)
static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC)
static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG)
static SDValue lowerMSABitClear(SDValue Op, SelectionDAG &DAG)
static SDValue lowerVECTOR_SHUFFLE_PCKEV(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT, EVT ShiftTy, SelectionDAG &DAG)
static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG, bool IsSigned=false)
static SDValue lowerVECTOR_SHUFFLE_ILVOD(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static 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 SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, const MipsSubtarget &Subtarget)
static cl::opt< bool > UseMipsTailCalls("mips-tail-calls", cl::Hidden, cl::desc("MIPS: permit tail calls."), cl::init(false))
static SDValue lowerVECTOR_SHUFFLE_ILVL(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallVector class.
support::ulittle32_t & Wd
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
APInt trunc(unsigned width) const
Truncate to new width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
unsigned logBase2() const
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
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
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const Triple & getTargetTriple() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
Flags getFlags() const
Return the raw flags of the source value,.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
unsigned getIncomingArgSize() const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
void addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC)
Enable MSA support for the given floating-point type and Register class.
void addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC)
Enable MSA support for the given integer type and Register class.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
const TargetRegisterClass * getRepRegClassFor(MVT VT) const override
Return the 'representative' register class for the specified value type.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Determine if the target supports unaligned memory accesses.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
MipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
bool useSoftFloat() const
const MipsInstrInfo * getInstrInfo() const override
const MipsRegisterInfo * getRegisterInfo() const override
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
bool isSingleFloat() const
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
Return the type to use for a scalar shift opcode, given the shifted amount type.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
This function fills Ops, which is the list of operands that will later be used when a function call n...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
const MipsSubtarget & Subtarget
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
Wrapper class representing virtual and physical registers.
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
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
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
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
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.
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
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVMContext * getContext() const
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 SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::const_iterator const_iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
TargetInstrInfo - Interface to description of machine instruction set.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
bool isLittleEndian() const
Tests whether the target triple is little endian.
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ 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.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ 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.
@ 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.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BRCOND
BRCOND - Conditional branch.
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
const MipsTargetLowering * createMipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
unsigned Log2(Align A)
Returns the log2 of the alignment.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool isVector() const
Return true if this is a vector value type.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...