29 #define DEBUG_TYPE "aarch64-isel" 52 return "AArch64 Instruction Selection";
65 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
66 unsigned ConstraintID,
67 std::vector<SDValue> &OutOps)
override;
69 bool tryMLAV64LaneV128(
SDNode *
N);
70 bool tryMULLV64LaneV128(
unsigned IntNo,
SDNode *N);
75 return SelectShiftedRegister(N,
false, Reg, Shift);
78 return SelectShiftedRegister(N,
true, Reg, Shift);
81 return SelectAddrModeIndexed7S(N, 1, Base, OffImm);
84 return SelectAddrModeIndexed7S(N, 2, Base, OffImm);
87 return SelectAddrModeIndexed7S(N, 4, Base, OffImm);
90 return SelectAddrModeIndexed7S(N, 8, Base, OffImm);
93 return SelectAddrModeIndexed7S(N, 16, Base, OffImm);
96 return SelectAddrModeIndexed(N, 1, Base, OffImm);
99 return SelectAddrModeIndexed(N, 2, Base, OffImm);
102 return SelectAddrModeIndexed(N, 4, Base, OffImm);
105 return SelectAddrModeIndexed(N, 8, Base, OffImm);
108 return SelectAddrModeIndexed(N, 16, Base, OffImm);
111 return SelectAddrModeUnscaled(N, 1, Base, OffImm);
114 return SelectAddrModeUnscaled(N, 2, Base, OffImm);
117 return SelectAddrModeUnscaled(N, 4, Base, OffImm);
120 return SelectAddrModeUnscaled(N, 8, Base, OffImm);
123 return SelectAddrModeUnscaled(N, 16, Base, OffImm);
129 return SelectAddrModeWRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
135 return SelectAddrModeXRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
149 const unsigned SubRegs[]);
151 void SelectTable(
SDNode *N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
153 bool tryIndexedLoad(
SDNode *N);
155 void SelectLoad(
SDNode *N,
unsigned NumVecs,
unsigned Opc,
157 void SelectPostLoad(
SDNode *N,
unsigned NumVecs,
unsigned Opc,
159 void SelectLoadLane(
SDNode *N,
unsigned NumVecs,
unsigned Opc);
160 void SelectPostLoadLane(
SDNode *N,
unsigned NumVecs,
unsigned Opc);
162 void SelectStore(
SDNode *N,
unsigned NumVecs,
unsigned Opc);
163 void SelectPostStore(
SDNode *N,
unsigned NumVecs,
unsigned Opc);
164 void SelectStoreLane(
SDNode *N,
unsigned NumVecs,
unsigned Opc);
165 void SelectPostStoreLane(
SDNode *N,
unsigned NumVecs,
unsigned Opc);
167 bool tryBitfieldExtractOp(
SDNode *N);
168 bool tryBitfieldExtractOpFromSExt(
SDNode *N);
169 bool tryBitfieldInsertOp(
SDNode *N);
170 bool tryBitfieldInsertInZeroOp(
SDNode *N);
171 bool tryShiftAmountMod(
SDNode *N);
173 bool tryReadRegister(
SDNode *N);
174 bool tryWriteRegister(
SDNode *N);
177 #include "AArch64GenDAGISel.inc" 180 bool SelectShiftedRegister(
SDValue N,
bool AllowROR,
SDValue &Reg,
184 bool SelectAddrModeIndexed(
SDValue N,
unsigned Size,
SDValue &Base,
186 bool SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
SDValue &Base,
194 bool isWorthFolding(
SDValue V)
const;
195 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
198 template<
unsigned RegW
idth>
200 return SelectCVTFixedPosOperand(N, FixedPos, RegWidth);
203 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
205 bool SelectCMP_SWAP(
SDNode *N);
214 Imm =
C->getZExtValue();
235 bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
236 const SDValue &
Op,
unsigned ConstraintID, std::vector<SDValue> &OutOps) {
237 switch(ConstraintID) {
250 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
253 OutOps.push_back(NewOp);
269 if (!isa<ConstantSDNode>(N.
getNode()))
272 uint64_t Immed = cast<ConstantSDNode>(N.
getNode())->getZExtValue();
275 if (Immed >> 12 == 0) {
277 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
285 Val = CurDAG->getTargetConstant(Immed, dl,
MVT::i32);
286 Shift = CurDAG->getTargetConstant(ShVal, dl,
MVT::i32);
292 bool AArch64DAGToDAGISel::SelectNegArithImmed(
SDValue N,
SDValue &Val,
299 if (!isa<ConstantSDNode>(N.
getNode()))
303 uint64_t Immed = cast<ConstantSDNode>(N.
getNode())->getZExtValue();
314 Immed = ~Immed + 1ULL;
315 if (Immed & 0xFFFFFFFFFF000000ULL)
318 Immed &= 0xFFFFFFULL;
319 return SelectArithImmed(CurDAG->getConstant(Immed,
SDLoc(N),
MVT::i32), Val,
357 if (!isa<MemSDNode>(*UI))
359 if (!isa<MemSDNode>(*UII))
365 bool AArch64DAGToDAGISel::isWorthFolding(
SDValue V)
const {
393 bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
403 unsigned Val = RHS->getZExtValue() & (BitSize - 1);
407 Shift = CurDAG->getTargetConstant(ShVal,
SDLoc(N),
MVT::i32);
408 return isWorthFolding(N);
422 SrcVT = cast<VTSDNode>(N.
getOperand(1))->getVT();
426 if (!IsLoadStore && SrcVT ==
MVT::i8)
428 else if (!IsLoadStore && SrcVT ==
MVT::i16)
438 if (!IsLoadStore && SrcVT ==
MVT::i8)
440 else if (!IsLoadStore && SrcVT ==
MVT::i16)
484 LaneIdx = DLidx->
getSExtValue() + EVidx->getSExtValue();
493 SDValue &LaneOp,
int &LaneIdx) {
507 bool AArch64DAGToDAGISel::tryMLAV64LaneV128(
SDNode *N) {
527 SDValue Ops[] = { Op0, MLAOp1, MLAOp2, LaneIdxVal };
529 unsigned MLAOpc = ~0U;
535 MLAOpc = AArch64::MLAv4i16_indexed;
538 MLAOpc = AArch64::MLAv8i16_indexed;
541 MLAOpc = AArch64::MLAv2i32_indexed;
544 MLAOpc = AArch64::MLAv4i32_indexed;
548 ReplaceNode(N, CurDAG->getMachineNode(MLAOpc, dl, N->
getValueType(0), Ops));
552 bool AArch64DAGToDAGISel::tryMULLV64LaneV128(
unsigned IntNo,
SDNode *N) {
564 SDValue Ops[] = { SMULLOp0, SMULLOp1, LaneIdxVal };
566 unsigned SMULLOpc = ~0U;
573 SMULLOpc = AArch64::SMULLv4i16_indexed;
576 SMULLOpc = AArch64::SMULLv2i32_indexed;
584 SMULLOpc = AArch64::UMULLv4i16_indexed;
587 SMULLOpc = AArch64::UMULLv2i32_indexed;
593 ReplaceNode(N, CurDAG->getMachineNode(SMULLOpc, dl, N->
getValueType(0), Ops));
615 bool AArch64DAGToDAGISel::SelectArithExtendedRegister(
SDValue N,
SDValue &Reg,
617 unsigned ShiftVal = 0;
655 return isWorthFolding(N);
682 bool AArch64DAGToDAGISel::SelectAddrModeIndexed7S(
SDValue N,
unsigned Size,
686 const DataLayout &DL = CurDAG->getDataLayout();
689 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
690 Base = CurDAG->getTargetFrameIndex(FI, TLI->
getPointerTy(DL));
691 OffImm = CurDAG->getTargetConstant(0, dl,
MVT::i64);
698 if (CurDAG->isBaseWithConstantOffset(N)) {
700 int64_t RHSC = RHS->getSExtValue();
701 unsigned Scale =
Log2_32(Size);
702 if ((RHSC & (Size - 1)) == 0 && RHSC >= -(0x40 << Scale) &&
703 RHSC < (0x40 << Scale)) {
706 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
707 Base = CurDAG->getTargetFrameIndex(FI, TLI->
getPointerTy(DL));
709 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl,
MVT::i64);
720 OffImm = CurDAG->getTargetConstant(0, dl,
MVT::i64);
727 bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
730 const DataLayout &DL = CurDAG->getDataLayout();
733 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
734 Base = CurDAG->getTargetFrameIndex(FI, TLI->
getPointerTy(DL));
735 OffImm = CurDAG->getTargetConstant(0, dl,
MVT::i64);
751 if (Alignment == 0 && Ty->
isSized())
754 if (Alignment >= Size)
759 if (CurDAG->isBaseWithConstantOffset(N)) {
761 int64_t RHSC = (int64_t)RHS->getZExtValue();
762 unsigned Scale =
Log2_32(Size);
763 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
766 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
767 Base = CurDAG->getTargetFrameIndex(FI, TLI->
getPointerTy(DL));
769 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl,
MVT::i64);
777 if (SelectAddrModeUnscaled(N, Size, Base, OffImm))
785 OffImm = CurDAG->getTargetConstant(0, dl,
MVT::i64);
794 bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
797 if (!CurDAG->isBaseWithConstantOffset(N))
800 int64_t RHSC = RHS->getSExtValue();
802 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 &&
803 RHSC < (0x1000 <<
Log2_32(Size)))
805 if (RHSC >= -256 && RHSC < 256) {
808 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
810 Base = CurDAG->getTargetFrameIndex(
813 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i64);
826 TargetOpcode::INSERT_SUBREG, dl,
MVT::i64, ImpDef, N, SubReg);
832 bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
837 if (!CSD || (CSD->getZExtValue() & 0x7) != CSD->getZExtValue())
852 SignExtend = CurDAG->getTargetConstant(0, dl,
MVT::i32);
855 unsigned LegalShiftVal =
Log2_32(Size);
856 unsigned ShiftVal = CSD->getZExtValue();
858 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
861 return isWorthFolding(N);
864 bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
876 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
884 if (!isa<MemSDNode>(*UI))
889 bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
893 SelectExtendedSHL(RHS, Size,
true, Offset, SignExtend)) {
895 DoShift = CurDAG->getTargetConstant(
true, dl,
MVT::i32);
901 SelectExtendedSHL(LHS, Size,
true, Offset, SignExtend)) {
903 DoShift = CurDAG->getTargetConstant(
true, dl,
MVT::i32);
908 DoShift = CurDAG->getTargetConstant(
false, dl,
MVT::i32);
912 if (IsExtendedRegisterWorthFolding &&
919 if (isWorthFolding(LHS))
924 if (IsExtendedRegisterWorthFolding &&
931 if (isWorthFolding(RHS))
943 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
946 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
948 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
949 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
953 bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
968 if (!isa<MemSDNode>(*UI))
983 if (isa<ConstantSDNode>(RHS)) {
984 int64_t ImmOff = (int64_t)cast<ConstantSDNode>(RHS)->getZExtValue();
985 unsigned Scale =
Log2_32(Size);
989 if ((ImmOff % Size == 0 && ImmOff >= 0 && ImmOff < (0x1000 << Scale)) ||
995 CurDAG->getMachineNode(AArch64::MOVi64imm, DL,
MVT::i64, Ops);
1002 bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
1006 SelectExtendedSHL(RHS, Size,
false, Offset, SignExtend)) {
1008 DoShift = CurDAG->getTargetConstant(
true, DL,
MVT::i32);
1014 SelectExtendedSHL(LHS, Size,
false, Offset, SignExtend)) {
1016 DoShift = CurDAG->getTargetConstant(
true, DL,
MVT::i32);
1023 SignExtend = CurDAG->getTargetConstant(
false, DL,
MVT::i32);
1024 DoShift = CurDAG->getTargetConstant(
false, DL,
MVT::i32);
1030 static const unsigned RegClassIDs[] = {
1031 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1032 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1033 AArch64::dsub2, AArch64::dsub3};
1035 return createTuple(Regs, RegClassIDs, SubRegs);
1039 static const unsigned RegClassIDs[] = {
1040 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1041 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1042 AArch64::qsub2, AArch64::qsub3};
1044 return createTuple(Regs, RegClassIDs, SubRegs);
1048 const unsigned RegClassIDs[],
1049 const unsigned SubRegs[]) {
1052 if (Regs.
size() == 1)
1063 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2], DL,
MVT::i32));
1066 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1072 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
MVT::Untyped, Ops);
1076 void AArch64DAGToDAGISel::SelectTable(
SDNode *N,
unsigned NumVecs,
unsigned Opc,
1081 unsigned ExtOff = isExt;
1084 unsigned Vec0Off = ExtOff + 1;
1086 N->
op_begin() + Vec0Off + NumVecs);
1087 SDValue RegSeq = createQTuple(Regs);
1094 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
1097 bool AArch64DAGToDAGISel::tryIndexedLoad(
SDNode *N) {
1109 unsigned Opcode = 0;
1112 bool InsertTo64 =
false;
1114 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1117 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1119 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1121 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1130 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1132 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1134 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1143 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1145 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1147 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1154 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1156 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1158 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1160 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1170 SDNode *Res = CurDAG->getMachineNode(Opcode, dl,
MVT::i64, DstVT,
1177 SDValue(CurDAG->getMachineNode(
1178 AArch64::SUBREG_TO_REG, dl,
MVT::i64,
1179 CurDAG->getTargetConstant(0, dl,
MVT::i64), LoadedVal,
1184 ReplaceUses(
SDValue(N, 0), LoadedVal);
1187 CurDAG->RemoveDeadNode(N);
1191 void AArch64DAGToDAGISel::SelectLoad(
SDNode *N,
unsigned NumVecs,
unsigned Opc,
1192 unsigned SubRegIdx) {
1202 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1204 for (
unsigned i = 0; i < NumVecs; ++i)
1206 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1212 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
1214 CurDAG->RemoveDeadNode(N);
1217 void AArch64DAGToDAGISel::SelectPostLoad(
SDNode *N,
unsigned NumVecs,
1218 unsigned Opc,
unsigned SubRegIdx) {
1230 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1238 ReplaceUses(
SDValue(N, 0), SuperReg);
1240 for (
unsigned i = 0; i < NumVecs; ++i)
1242 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1246 CurDAG->RemoveDeadNode(N);
1249 void AArch64DAGToDAGISel::SelectStore(
SDNode *N,
unsigned NumVecs,
1257 SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs);
1264 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
1269 void AArch64DAGToDAGISel::SelectPostStore(
SDNode *N,
unsigned NumVecs,
1279 SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs);
1285 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1325 void AArch64DAGToDAGISel::SelectLoadLane(
SDNode *N,
unsigned NumVecs,
1338 SDValue RegSeq = createQTuple(Regs);
1343 cast<ConstantSDNode>(N->
getOperand(NumVecs + 2))->getZExtValue();
1345 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl,
MVT::i64),
1347 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1350 EVT WideVT = RegSeq.getOperand(1)->getValueType(0);
1351 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
1352 AArch64::qsub2, AArch64::qsub3 };
1353 for (
unsigned i = 0; i < NumVecs; ++i) {
1354 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
1357 ReplaceUses(
SDValue(N, i), NV);
1361 CurDAG->RemoveDeadNode(N);
1364 void AArch64DAGToDAGISel::SelectPostLoadLane(
SDNode *N,
unsigned NumVecs,
1377 SDValue RegSeq = createQTuple(Regs);
1383 cast<ConstantSDNode>(N->
getOperand(NumVecs + 1))->getZExtValue();
1386 CurDAG->getTargetConstant(LaneNo, dl,
1391 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1402 EVT WideVT = RegSeq.getOperand(1)->getValueType(0);
1403 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
1404 AArch64::qsub2, AArch64::qsub3 };
1405 for (
unsigned i = 0; i < NumVecs; ++i) {
1406 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
1410 ReplaceUses(
SDValue(N, i), NV);
1416 CurDAG->RemoveDeadNode(N);
1419 void AArch64DAGToDAGISel::SelectStoreLane(
SDNode *N,
unsigned NumVecs,
1432 SDValue RegSeq = createQTuple(Regs);
1435 cast<ConstantSDNode>(N->
getOperand(NumVecs + 2))->getZExtValue();
1437 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl,
MVT::i64),
1443 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
1448 void AArch64DAGToDAGISel::SelectPostStoreLane(
SDNode *N,
unsigned NumVecs,
1461 SDValue RegSeq = createQTuple(Regs);
1467 cast<ConstantSDNode>(N->
getOperand(NumVecs + 1))->getZExtValue();
1469 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl,
MVT::i64),
1473 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1477 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
1484 unsigned &LSB,
unsigned &MSB,
1485 unsigned NumberOfIgnoredLowBits,
1486 bool BiggerPattern) {
1488 "N must be a AND operation to call this function");
1496 "Type checking must have been done before calling this function");
1506 uint64_t AndImm = 0;
1514 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
1517 if (AndImm & (AndImm + 1))
1520 bool ClampMSB =
false;
1521 uint64_t SrlImm = 0;
1540 }
else if (BiggerPattern) {
1552 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.getSizeInBits())) {
1555 <<
": Found large shift immediate, this should not happen\n"));
1560 MSB = SrlImm + (VT ==
MVT::i32 ? countTrailingOnes<uint32_t>(AndImm)
1561 : countTrailingOnes<uint64_t>(AndImm)) -
1568 MSB = MSB > 31 ? 31 : MSB;
1570 Opc = VT ==
MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
1575 SDValue &Opd0,
unsigned &Immr,
1582 "Type checking must have been done before calling this function");
1588 BitWidth = VT.getSizeInBits();
1596 unsigned Width = cast<VTSDNode>(N->
getOperand(1))->getVT().getSizeInBits();
1597 if (ShiftImm + Width > BitWidth)
1600 Opc = (VT ==
MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
1603 Imms = ShiftImm + Width - 1;
1627 uint64_t AndMask = 0;
1633 uint64_t SrlImm = 0;
1639 if (BitWide &&
isMask_64(AndMask >> SrlImm)) {
1641 Opc = AArch64::UBFMWri;
1643 Opc = AArch64::UBFMXri;
1646 MSB = BitWide + SrlImm - 1;
1654 unsigned &Immr,
unsigned &Imms,
1655 bool BiggerPattern) {
1657 "N must be a SHR/SRA operation to call this function");
1665 "Type checking must have been done before calling this function");
1672 uint64_t ShlImm = 0;
1673 uint64_t TruncBits = 0;
1686 }
else if (BiggerPattern) {
1699 <<
": Found large shift immediate, this should not happen\n"));
1703 uint64_t SrlImm = 0;
1708 "bad amount in shift node!");
1709 int immr = SrlImm - ShlImm;
1720 bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(
SDNode *N) {
1736 unsigned Immr = ShiftImm;
1738 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
1739 CurDAG->getTargetConstant(Imms, dl, VT)};
1740 CurDAG->SelectNodeTo(N, AArch64::SBFMXri, VT, Ops);
1745 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
1746 unsigned NumberOfIgnoredLowBits = 0,
1747 bool BiggerPattern =
false) {
1758 NumberOfIgnoredLowBits, BiggerPattern);
1771 case AArch64::SBFMWri:
1772 case AArch64::UBFMWri:
1773 case AArch64::SBFMXri:
1774 case AArch64::UBFMXri:
1785 bool AArch64DAGToDAGISel::tryBitfieldExtractOp(
SDNode *N) {
1786 unsigned Opc, Immr, Imms;
1796 if ((Opc == AArch64::SBFMXri || Opc == AArch64::UBFMXri) && VT ==
MVT::i32) {
1797 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl,
MVT::i64),
1798 CurDAG->getTargetConstant(Imms, dl,
MVT::i64)};
1802 ReplaceNode(N, CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl,
1807 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
1808 CurDAG->getTargetConstant(Imms, dl, VT)};
1809 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
1818 unsigned NumberOfIgnoredHighBits,
EVT VT) {
1820 "i32 or i64 mask type expected!");
1821 unsigned BitWidth = VT.
getSizeInBits() - NumberOfIgnoredHighBits;
1823 APInt SignificantDstMask =
APInt(BitWidth, DstMask);
1824 APInt SignificantBitsToBeInserted = BitsToBeInserted.
zextOrTrunc(BitWidth);
1826 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
1827 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnesValue();
1852 UsefulBits &=
APInt(UsefulBits.getBitWidth(), Imm);
1857 uint64_t Imm, uint64_t MSB,
1860 APInt OpUsefulBits(UsefulBits);
1864 OpUsefulBits <<= MSB - Imm + 1;
1869 OpUsefulBits <<= Imm;
1871 OpUsefulBits <<= MSB + 1;
1874 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
1880 UsefulBits &= OpUsefulBits;
1895 uint64_t ShiftTypeAndValue =
1928 APInt OpUsefulBits(UsefulBits);
1939 uint64_t Width = MSB - Imm + 1;
1942 OpUsefulBits <<= Width;
1947 Mask = ResultUsefulBits & OpUsefulBits;
1953 Mask |= (ResultUsefulBits & ~OpUsefulBits);
1956 uint64_t Width = MSB + 1;
1959 OpUsefulBits <<= Width;
1961 OpUsefulBits <<= LSB;
1965 Mask = ResultUsefulBits & OpUsefulBits;
1966 Mask.lshrInPlace(LSB);
1970 Mask |= (ResultUsefulBits & ~OpUsefulBits);
1987 case AArch64::ANDSWri:
1988 case AArch64::ANDSXri:
1989 case AArch64::ANDWri:
1990 case AArch64::ANDXri:
1994 case AArch64::UBFMWri:
1995 case AArch64::UBFMXri:
1998 case AArch64::ORRWrs:
1999 case AArch64::ORRXrs:
2004 case AArch64::BFMWri:
2005 case AArch64::BFMXri:
2008 case AArch64::STRBBui:
2009 case AArch64::STURBBi:
2015 case AArch64::STRHHui:
2016 case AArch64::STURHHi:
2031 UsefulBits =
APInt(Bitwidth, 0);
2040 UsersUsefulBits |= UsefulBitsForUse;
2045 UsefulBits &= UsersUsefulBits;
2058 unsigned UBFMOpc = BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2061 if (ShlAmount > 0) {
2064 UBFMOpc, dl, VT, Op,
2069 assert(ShlAmount < 0 &&
"expected right shift");
2070 int ShrAmount = -ShlAmount;
2083 SDValue &Src,
int &ShiftAmount,
2088 assert(BitWidth == 32 || BitWidth == 64);
2094 uint64_t NonZeroBits = (~Known.
Zero).getZExtValue();
2125 if (ShlImm - ShiftAmount != 0 && !BiggerPattern)
2173 uint64_t NotKnownZero = (~Known.
Zero).getZExtValue();
2180 if ((OrImm & NotKnownZero) != 0) {
2191 unsigned ImmR = (BitWidth - LSB) % BitWidth;
2192 unsigned ImmS = Width - 1;
2198 bool IsBFI = LSB != 0;
2199 uint64_t BFIImm = OrImm >> LSB;
2203 unsigned OrChunks = 0, BFIChunks = 0;
2204 for (
unsigned Shift = 0; Shift < BitWidth; Shift += 16) {
2205 if (((OrImm >> Shift) & 0xFFFF) != 0)
2207 if (((BFIImm >> Shift) & 0xFFFF) != 0)
2210 if (BFIChunks > OrChunks)
2216 unsigned MOVIOpc = VT ==
MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
2224 unsigned Opc = (VT ==
MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
2263 for (
int I = 0;
I < 4; ++
I) {
2266 unsigned ImmR, ImmS;
2267 bool BiggerPattern =
I / 2;
2276 NumberOfIgnoredLowBits, BiggerPattern)) {
2279 if ((BFXOpc != AArch64::UBFMXri && VT ==
MVT::i64) ||
2280 (BFXOpc != AArch64::UBFMWri && VT ==
MVT::i32))
2285 Width = ImmS - ImmR + 1;
2296 Src, DstLSB, Width)) {
2297 ImmR = (BitWidth - DstLSB) % BitWidth;
2314 APInt BitsToBeInserted =
2317 if ((BitsToBeInserted & ~Known.
Zero) != 0)
2335 unsigned Opc = (VT ==
MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
2343 uint64_t Mask0Imm, Mask1Imm;
2349 APInt(BitWidth, Mask0Imm) == ~
APInt(BitWidth, Mask1Imm) &&
2368 unsigned ShiftOpc = (VT ==
MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
2374 unsigned ImmR = (BitWidth - LSB) % BitWidth;
2375 unsigned ImmS = Width - 1;
2381 unsigned Opc = (VT ==
MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
2389 bool AArch64DAGToDAGISel::tryBitfieldInsertOp(
SDNode *N) {
2398 CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->
getValueType(0));
2411 bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(
SDNode *N) {
2422 Op0, DstLSB, Width))
2428 unsigned ImmS = Width - 1;
2431 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR, DL, VT),
2432 CurDAG->getTargetConstant(ImmS, DL, VT)};
2433 unsigned Opc = (VT ==
MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
2434 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2440 bool AArch64DAGToDAGISel::tryShiftAmountMod(
SDNode *N) {
2446 Opc = (VT ==
MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
2449 Opc = (VT ==
MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
2452 Opc = (VT ==
MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
2455 Opc = (VT ==
MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
2494 (Add0Imm % Size == 0)) {
2499 NegOpc = AArch64::SUBWrr;
2500 ZeroReg = AArch64::WZR;
2503 NegOpc = AArch64::SUBXrr;
2504 ZeroReg = AArch64::XZR;
2507 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, ZeroReg, SubVT);
2509 CurDAG->getMachineNode(NegOpc, DL, SubVT, Zero, Add1);
2510 NewShiftAmt =
SDValue(Neg, 0);
2533 AArch64::SUBREG_TO_REG, DL, VT,
2534 CurDAG->getTargetConstant(0, DL,
MVT::i64), NewShiftAmt,
SubReg);
2535 NewShiftAmt =
SDValue(Ext, 0);
2539 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2544 AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
2545 unsigned RegWidth) {
2548 FVal = CN->getValueAPF();
2549 else if (
LoadSDNode *LN = dyn_cast<LoadSDNode>(N)) {
2552 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
2557 FVal = cast<ConstantFP>(CN->
getConstVal())->getValueAPF();
2576 if (!IsExact || !IntVal.
isPowerOf2())
return false;
2577 unsigned FBits = IntVal.
logBase2();
2581 if (FBits == 0 || FBits > RegWidth)
return false;
2583 FixedPos = CurDAG->getTargetConstant(FBits,
SDLoc(N),
MVT::i32);
2592 RegString.
split(Fields,
':');
2594 if (Fields.
size() == 1)
2598 &&
"Invalid number of fields in read register string");
2601 bool AllIntFields =
true;
2605 AllIntFields &= !
Field.getAsInteger(10, IntField);
2606 Ops.push_back(IntField);
2610 "Unexpected non-integer value in special register string.");
2614 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
2615 (Ops[3] << 3) | (Ops[4]);
2622 bool AArch64DAGToDAGISel::tryReadRegister(
SDNode *N) {
2629 ReplaceNode(N, CurDAG->getMachineNode(
2631 CurDAG->getTargetConstant(Reg, DL,
MVT::i32),
2639 if (TheReg && TheReg->Readable &&
2640 TheReg->haveFeatures(Subtarget->getFeatureBits()))
2646 ReplaceNode(N, CurDAG->getMachineNode(
2648 CurDAG->getTargetConstant(Reg, DL,
MVT::i32),
2660 bool AArch64DAGToDAGISel::tryWriteRegister(
SDNode *N) {
2668 N, CurDAG->getMachineNode(AArch64::MSR, DL,
MVT::Other,
2669 CurDAG->getTargetConstant(Reg, DL,
MVT::i32),
2679 auto PMapper = AArch64PState::lookupPStateByName(RegString->getString());
2682 &&
"Expected a constant integer expression.");
2683 unsigned Reg = PMapper->Encoding;
2684 uint64_t Immed = cast<ConstantSDNode>(N->
getOperand(2))->getZExtValue();
2686 if (Reg == AArch64PState::PAN || Reg == AArch64PState::UAO || Reg == AArch64PState::SSBS) {
2687 assert(Immed < 2 &&
"Bad imm");
2688 State = AArch64::MSRpstateImm1;
2690 assert(Immed < 16 &&
"Bad imm");
2691 State = AArch64::MSRpstateImm4;
2693 ReplaceNode(N, CurDAG->getMachineNode(
2695 CurDAG->getTargetConstant(Reg, DL,
MVT::i32),
2696 CurDAG->getTargetConstant(Immed, DL,
MVT::i16),
2705 if (TheReg && TheReg->Writeable &&
2706 TheReg->haveFeatures(Subtarget->getFeatureBits()))
2711 ReplaceNode(N, CurDAG->getMachineNode(
2713 CurDAG->getTargetConstant(Reg, DL,
MVT::i32),
2722 bool AArch64DAGToDAGISel::SelectCMP_SWAP(
SDNode *N) {
2724 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
2727 if (Subtarget->hasLSE())
return false;
2730 Opcode = AArch64::CMP_SWAP_8;
2732 Opcode = AArch64::CMP_SWAP_16;
2734 Opcode = AArch64::CMP_SWAP_32;
2736 Opcode = AArch64::CMP_SWAP_64;
2743 SDNode *CmpSwap = CurDAG->getMachineNode(
2748 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
2752 CurDAG->RemoveDeadNode(N);
2773 if (SelectCMP_SWAP(Node))
2778 if (tryReadRegister(Node))
2783 if (tryWriteRegister(Node))
2788 if (tryMLAV64LaneV128(Node))
2795 if (tryIndexedLoad(Node))
2804 if (tryBitfieldExtractOp(Node))
2806 if (tryBitfieldInsertInZeroOp(Node))
2811 if (tryShiftAmountMod(Node))
2816 if (tryBitfieldExtractOpFromSExt(Node))
2821 if (tryBitfieldInsertOp(Node))
2849 SubReg = AArch64::dsub;
2852 SubReg = AArch64::ssub;
2855 SubReg = AArch64::hsub;
2860 SDValue Extract = CurDAG->getTargetExtractSubreg(SubReg,
SDLoc(Node), VT,
2865 ReplaceNode(Node, Extract.
getNode());
2874 SDValue New = CurDAG->getCopyFromReg(
2875 CurDAG->getEntryNode(),
SDLoc(Node), AArch64::WZR,
MVT::i32);
2876 ReplaceNode(Node, New.
getNode());
2879 SDValue New = CurDAG->getCopyFromReg(
2880 CurDAG->getEntryNode(),
SDLoc(Node), AArch64::XZR,
MVT::i64);
2881 ReplaceNode(Node, New.
getNode());
2890 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
2893 SDValue TFI = CurDAG->getTargetFrameIndex(
2897 CurDAG->getTargetConstant(Shifter, DL,
MVT::i32) };
2898 CurDAG->SelectNodeTo(Node, AArch64::ADDXri,
MVT::i64, Ops);
2902 unsigned IntNo = cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue();
2919 cast<MemIntrinsicSDNode>(Node)->getMemOperand();
2920 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
2921 ReplaceNode(Node, Ld);
2935 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
2940 cast<MemIntrinsicSDNode>(Node)->getMemOperand();
2941 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
2943 ReplaceNode(Node, St);
2948 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
2951 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
2954 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
2957 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
2960 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
2963 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
2966 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
2969 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
2975 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
2978 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
2981 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
2984 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
2987 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
2990 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
2993 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
2996 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
3002 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
3005 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
3008 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
3011 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
3014 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
3017 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
3020 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
3023 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
3029 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
3032 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
3035 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
3038 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
3041 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
3044 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
3047 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
3050 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
3056 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
3059 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
3062 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
3065 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
3068 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
3071 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
3074 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
3077 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
3083 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
3086 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
3089 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
3092 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
3095 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
3098 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
3101 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
3104 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
3110 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
3113 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
3116 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
3119 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
3122 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
3125 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
3128 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
3131 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
3137 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
3140 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
3143 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
3146 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
3149 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
3152 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
3155 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
3158 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
3164 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
3167 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
3170 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
3173 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
3176 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
3179 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
3182 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
3185 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
3191 SelectLoadLane(Node, 2, AArch64::LD2i8);
3195 SelectLoadLane(Node, 2, AArch64::LD2i16);
3199 SelectLoadLane(Node, 2, AArch64::LD2i32);
3203 SelectLoadLane(Node, 2, AArch64::LD2i64);
3209 SelectLoadLane(Node, 3, AArch64::LD3i8);
3213 SelectLoadLane(Node, 3, AArch64::LD3i16);
3217 SelectLoadLane(Node, 3, AArch64::LD3i32);
3221 SelectLoadLane(Node, 3, AArch64::LD3i64);
3227 SelectLoadLane(Node, 4, AArch64::LD4i8);
3231 SelectLoadLane(Node, 4, AArch64::LD4i16);
3235 SelectLoadLane(Node, 4, AArch64::LD4i32);
3239 SelectLoadLane(Node, 4, AArch64::LD4i64);
3246 unsigned IntNo = cast<ConstantSDNode>(Node->
getOperand(0))->getZExtValue();
3251 SelectTable(Node, 2,
3252 VT ==
MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
3256 SelectTable(Node, 3, VT ==
MVT::v8i8 ? AArch64::TBLv8i8Three
3257 : AArch64::TBLv16i8Three,
3261 SelectTable(Node, 4, VT ==
MVT::v8i8 ? AArch64::TBLv8i8Four
3262 : AArch64::TBLv16i8Four,
3266 SelectTable(Node, 2,
3267 VT ==
MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
3271 SelectTable(Node, 3, VT ==
MVT::v8i8 ? AArch64::TBXv8i8Three
3272 : AArch64::TBXv16i8Three,
3276 SelectTable(Node, 4, VT ==
MVT::v8i8 ? AArch64::TBXv8i8Four
3277 : AArch64::TBXv16i8Four,
3282 if (tryMULLV64LaneV128(IntNo, Node))
3289 unsigned IntNo = cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue();
3297 SelectStore(Node, 2, AArch64::ST1Twov8b);
3300 SelectStore(Node, 2, AArch64::ST1Twov16b);
3303 SelectStore(Node, 2, AArch64::ST1Twov4h);
3306 SelectStore(Node, 2, AArch64::ST1Twov8h);
3309 SelectStore(Node, 2, AArch64::ST1Twov2s);
3312 SelectStore(Node, 2, AArch64::ST1Twov4s);
3315 SelectStore(Node, 2, AArch64::ST1Twov2d);
3318 SelectStore(Node, 2, AArch64::ST1Twov1d);
3325 SelectStore(Node, 3, AArch64::ST1Threev8b);
3328 SelectStore(Node, 3, AArch64::ST1Threev16b);
3331 SelectStore(Node, 3, AArch64::ST1Threev4h);
3334 SelectStore(Node, 3, AArch64::ST1Threev8h);
3337 SelectStore(Node, 3, AArch64::ST1Threev2s);
3340 SelectStore(Node, 3, AArch64::ST1Threev4s);
3343 SelectStore(Node, 3, AArch64::ST1Threev2d);
3346 SelectStore(Node, 3, AArch64::ST1Threev1d);
3353 SelectStore(Node, 4, AArch64::ST1Fourv8b);
3356 SelectStore(Node, 4, AArch64::ST1Fourv16b);
3359 SelectStore(Node, 4, AArch64::ST1Fourv4h);
3362 SelectStore(Node, 4, AArch64::ST1Fourv8h);
3365 SelectStore(Node, 4, AArch64::ST1Fourv2s);
3368 SelectStore(Node, 4, AArch64::ST1Fourv4s);
3371 SelectStore(Node, 4, AArch64::ST1Fourv2d);
3374 SelectStore(Node, 4, AArch64::ST1Fourv1d);
3381 SelectStore(Node, 2, AArch64::ST2Twov8b);
3384 SelectStore(Node, 2, AArch64::ST2Twov16b);
3387 SelectStore(Node, 2, AArch64::ST2Twov4h);
3390 SelectStore(Node, 2, AArch64::ST2Twov8h);
3393 SelectStore(Node, 2, AArch64::ST2Twov2s);
3396 SelectStore(Node, 2, AArch64::ST2Twov4s);
3399 SelectStore(Node, 2, AArch64::ST2Twov2d);
3402 SelectStore(Node, 2, AArch64::ST1Twov1d);
3409 SelectStore(Node, 3, AArch64::ST3Threev8b);
3412 SelectStore(Node, 3, AArch64::ST3Threev16b);
3415 SelectStore(Node, 3, AArch64::ST3Threev4h);
3418 SelectStore(Node, 3, AArch64::ST3Threev8h);
3421 SelectStore(Node, 3, AArch64::ST3Threev2s);
3424 SelectStore(Node, 3, AArch64::ST3Threev4s);
3427 SelectStore(Node, 3, AArch64::ST3Threev2d);
3430 SelectStore(Node, 3, AArch64::ST1Threev1d);
3437 SelectStore(Node, 4, AArch64::ST4Fourv8b);
3440 SelectStore(Node, 4, AArch64::ST4Fourv16b);
3443 SelectStore(Node, 4, AArch64::ST4Fourv4h);
3446 SelectStore(Node, 4, AArch64::ST4Fourv8h);
3449 SelectStore(Node, 4, AArch64::ST4Fourv2s);
3452 SelectStore(Node, 4, AArch64::ST4Fourv4s);
3455 SelectStore(Node, 4, AArch64::ST4Fourv2d);
3458 SelectStore(Node, 4, AArch64::ST1Fourv1d);
3465 SelectStoreLane(Node, 2, AArch64::ST2i8);
3469 SelectStoreLane(Node, 2, AArch64::ST2i16);
3473 SelectStoreLane(Node, 2, AArch64::ST2i32);
3477 SelectStoreLane(Node, 2, AArch64::ST2i64);
3484 SelectStoreLane(Node, 3, AArch64::ST3i8);
3488 SelectStoreLane(Node, 3, AArch64::ST3i16);
3492 SelectStoreLane(Node, 3, AArch64::ST3i32);
3496 SelectStoreLane(Node, 3, AArch64::ST3i64);
3503 SelectStoreLane(Node, 4, AArch64::ST4i8);
3507 SelectStoreLane(Node, 4, AArch64::ST4i16);
3511 SelectStoreLane(Node, 4, AArch64::ST4i32);
3515 SelectStoreLane(Node, 4, AArch64::ST4i64);
3525 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
3528 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
3531 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
3534 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
3537 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
3540 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
3543 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
3546 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
3553 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
3556 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
3559 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
3562 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
3565 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
3568 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
3571 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
3574 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
3581 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
3584 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
3587 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
3590 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
3593 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
3596 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
3599 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
3602 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
3609 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
3612 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
3615 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
3618 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
3621 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
3624 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
3627 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
3630 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
3637 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
3640 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
3643 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
3646 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
3649 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
3652 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
3655 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
3658 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
3665 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
3668 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
3671 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
3674 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
3677 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
3680 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
3683 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
3686 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
3693 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
3696 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
3699 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
3702 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
3705 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
3708 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
3711 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
3714 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
3721 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
3724 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
3727 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
3730 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
3733 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
3736 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
3739 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
3742 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
3749 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
3752 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
3755 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
3758 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
3761 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
3764 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
3767 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
3770 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
3777 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
3780 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
3783 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
3786 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
3789 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
3792 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
3795 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
3798 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
3805 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
3809 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
3813 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
3817 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
3824 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
3828 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
3832 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
3836 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
3843 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
3847 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
3851 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
3855 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
3862 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
3866 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
3870 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
3874 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
3882 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
3885 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
3888 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
3891 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
3894 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
3897 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
3900 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
3903 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
3911 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
3914 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
3917 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
3920 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
3923 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
3926 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
3929 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
3932 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
3940 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
3943 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
3946 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
3949 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
3952 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
3955 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
3958 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
3961 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
3969 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
3972 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
3975 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
3978 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
3981 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
3984 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
3987 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
3990 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
3998 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
4001 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
4004 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
4007 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
4010 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
4013 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
4016 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
4019 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
4027 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
4030 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
4033 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
4036 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
4039 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
4042 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
4045 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
4048 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
4056 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
4060 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
4064 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
4068 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
4076 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
4080 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
4084 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
4088 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
4096 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
4100 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
4104 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
4108 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
4123 return new AArch64DAGToDAGISel(TM, OptLevel);
void clearAllBits()
Set every bit to 0.
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
A parsed version of the target data layout string in and methods for querying it. ...
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &ShiftAmount, int &MaskWidth)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL...
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOffset() const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void flipAllBits()
Toggle every bit to its opposite value.
const GlobalValue * getGlobal() const
uint64_t getZExtValue() const
Get zero extended value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
DiagnosticInfoOptimizationBase::Argument NV
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
This class represents lattice values for constants.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
const SDValue & getBasePtr() const
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
const SDValue & getChain() const
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
unsigned const TargetRegisterInfo * TRI
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
const MDOperand & getOperand(unsigned I) const
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
unsigned getBitWidth() const
Get the bit width of this value.
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
unsigned getBitWidth() const
Return the number of bits in the APInt.
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
A description of a memory reference used in the backend.
static bool checkV64LaneV128(SDValue Op0, SDValue Op1, SDValue &StdOp, SDValue &LaneOp, int &LaneIdx)
static bool isPreferredADD(int64_t ImmOff)
Shift and rotation operations.
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
A Use represents the edge between a Value definition and its users.
SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
const MDNode * getMD() const
unsigned getScalarValueSizeInBits() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
unsigned getID() const
Return the register class ID number.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
int64_t getSExtValue() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Simple integer binary arithmetic operators.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
op_iterator op_begin() const
unsigned getAlignment() const
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
bool isStrongerThanMonotonic(AtomicOrdering ao)
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
static SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
int64_t getOffset() const
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
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...
unsigned countPopulation() const
Count the number of bits set.
The instances of the Type class are immutable: once they are created, they are never changed...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
size_t size() const
size - Get the array size.
const SDValue & getOperand(unsigned Num) const
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
FunctionPass class - This class is used to implement most global optimizations.
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32...
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getNumOperands() const
Return the number of values used by this operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
void dump() const
Dump this node, for debugging.
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
EVT getVectorElementType() const
Given a vector type, return the type of each element.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
An SDNode that represents everything that will be needed to construct a MachineInstr.
const Constant * getConstVal() const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
unsigned logBase2() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
EVT getMemoryVT() const
Return the type of the in-memory value.
Class for arbitrary precision integers.
iterator_range< use_iterator > uses()
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
const SysReg * lookupSysRegByName(StringRef)
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
uint32_t parseGenericRegister(StringRef Name)
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOpt::Level OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG...
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
bool is64BitVector() const
Return true if this is a 64-bit vector type.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
static bool checkHighLaneIndex(SDNode *DL, SDValue &LaneOp, int &LaneIdx)
Bitwise operators - logical and, logical or, logical xor.
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static int getIntOperandFromRegisterString(StringRef RegString)
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted, suitable for use in a BFI instruction.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Type * getValueType() const
unsigned getOpcode() const
OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere...
static bool isShiftedMask(uint64_t Mask, EVT VT)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void dumpr() const
Dump (recursively) this node and its use-def subgraph.
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
StringRef - Represent a constant reference to a string, i.e.
unsigned countLeadingZeros() const
The APInt version of the countLeadingZeros functions in MathExtras.h.
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
const SDValue & getOperand(unsigned i) const
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
uint64_t getZExtValue() const
SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
TRUNCATE - Completely drop the high bits.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
std::size_t countLeadingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the most significant bit to the first zero bit.
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
This class is used to represent ISD::LOAD nodes.