40 #define DEBUG_TYPE "arm-isel" 44 cl::desc(
"Disable isel of shifter-op"),
69 StringRef getPassName()
const override {
return "ARM Instruction Selection"; }
71 void PreprocessISelDAG()
override;
75 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
76 return CurDAG->getTargetConstant(Imm, dl,
MVT::i32);
81 bool hasNoVMLxHazardUse(
SDNode *
N)
const;
82 bool isShifterOpProfitable(
const SDValue &Shift,
86 bool CheckProfitability =
true);
88 SDValue &
B,
bool CheckProfitability =
true);
92 return SelectRegShifterOperand(N, A, B, C,
false);
97 return SelectImmShifterOperand(N, A, B,
false);
108 Reg = CurDAG->getRegister(ARM::CPSR,
MVT::i32);
124 int Lwb,
int Upb,
bool FP16);
154 inline bool is_so_imm(
unsigned Imm)
const {
158 inline bool is_so_imm_not(
unsigned Imm)
const {
162 inline bool is_t2_so_imm(
unsigned Imm)
const {
166 inline bool is_t2_so_imm_not(
unsigned Imm)
const {
171 #include "ARMGenDAGISel.inc" 177 bool tryARMIndexedLoad(
SDNode *N);
178 bool tryT1IndexedLoad(
SDNode *N);
179 bool tryT2IndexedLoad(
SDNode *N);
185 void SelectVLD(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
186 const uint16_t *DOpcodes,
const uint16_t *QOpcodes0,
187 const uint16_t *QOpcodes1);
193 void SelectVST(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
194 const uint16_t *DOpcodes,
const uint16_t *QOpcodes0,
195 const uint16_t *QOpcodes1);
200 void SelectVLDSTLane(
SDNode *N,
bool IsLoad,
bool isUpdating,
201 unsigned NumVecs,
const uint16_t *DOpcodes,
202 const uint16_t *QOpcodes);
207 void SelectVLDDup(
SDNode *N,
bool IsIntrinsic,
bool isUpdating,
208 unsigned NumVecs,
const uint16_t *DOpcodes,
209 const uint16_t *QOpcodes0 =
nullptr,
210 const uint16_t *QOpcodes1 =
nullptr);
213 bool tryV6T2BitfieldExtractOp(
SDNode *N,
bool isSigned);
218 bool tryReadRegister(
SDNode *N);
219 bool tryWriteRegister(
SDNode *N);
221 bool tryInlineAsm(
SDNode *N);
223 void SelectCMPZ(
SDNode *N,
bool &SwitchEQNEToPLMI);
225 void SelectCMP_SWAP(
SDNode *N);
229 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
230 std::vector<SDValue> &OutOps)
override;
249 unsigned ConstantMaterializationCost(
unsigned Val)
const;
256 bool canExtractShiftFromMul(
const SDValue &N,
unsigned MaxShift,
257 unsigned &PowerOfTwo,
SDValue &NewMulConst)
const;
269 Imm = cast<ConstantSDNode>(
N)->getZExtValue();
294 int RangeMin,
int RangeMax,
295 int &ScaledConstant) {
296 assert(Scale > 0 &&
"Invalid scale!");
304 if ((ScaledConstant % Scale) != 0)
307 ScaledConstant /= Scale;
308 return ScaledConstant >= RangeMin && ScaledConstant < RangeMax;
311 void ARMDAGToDAGISel::PreprocessISelDAG() {
315 bool isThumb2 = Subtarget->
isThumb();
317 E = CurDAG->allnodes_end();
I !=
E; ) {
334 unsigned And_imm = 0;
344 if (TZ != 1 && TZ != 2)
356 if (And_imm & (And_imm + 1))
361 unsigned Srl_imm = 0;
372 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1))
375 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1) ||
376 SelectRegShifterOperand(N0, CPTmp0, CPTmp1, CPTmp2))
383 CurDAG->getConstant(Srl_imm + TZ,
SDLoc(Srl),
390 CurDAG->UpdateNodeOperands(N, N0, N1);
397 bool ARMDAGToDAGISel::hasNoVMLxHazardUse(
SDNode *
N)
const {
412 CurDAG->getSubtarget().getInstrInfo());
439 bool ARMDAGToDAGISel::isShifterOpProfitable(
const SDValue &Shift,
448 (ShAmt == 2 || (Subtarget->
isSwift() && ShAmt == 1));
451 unsigned ARMDAGToDAGISel::ConstantMaterializationCost(
unsigned Val)
const {
453 if (Val <= 255)
return 1;
457 if (Val <= 510)
return 2;
458 if (~Val <= 255)
return 2;
463 if (Subtarget->
hasV6T2Ops() && Val <= 0xffff)
return 1;
466 if (Subtarget->
useMovt(*MF))
return 2;
470 bool ARMDAGToDAGISel::canExtractShiftFromMul(
const SDValue &N,
472 unsigned &PowerOfTwo,
482 if (!MulConst)
return false;
485 if (!MulConst->
hasOneUse())
return false;
487 if (MulConstVal == 0)
return false;
490 PowerOfTwo = MaxShift;
491 while ((MulConstVal % (1 << PowerOfTwo)) != 0) {
493 if (PowerOfTwo == 0)
return false;
497 unsigned NewMulConstVal = MulConstVal / (1 << PowerOfTwo);
498 NewMulConst = CurDAG->getConstant(NewMulConstVal,
SDLoc(N),
MVT::i32);
499 unsigned OldCost = ConstantMaterializationCost(MulConstVal);
500 unsigned NewCost = ConstantMaterializationCost(NewMulConstVal);
501 return NewCost < OldCost;
504 void ARMDAGToDAGISel::replaceDAGValue(
const SDValue &N,
SDValue M) {
509 bool ARMDAGToDAGISel::SelectImmShifterOperand(
SDValue N,
512 bool CheckProfitability) {
519 unsigned PowerOfTwo = 0;
521 if (canExtractShiftFromMul(N, 31, PowerOfTwo, NewMulConst)) {
524 replaceDAGValue(N.
getOperand(1), NewMulConst);
526 Opc = CurDAG->getTargetConstant(
539 unsigned ShImmVal = 0;
541 if (!RHS)
return false;
548 bool ARMDAGToDAGISel::SelectRegShifterOperand(
SDValue N,
552 bool CheckProfitability) {
563 unsigned ShImmVal = 0;
565 if (RHS)
return false;
568 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal))
580 return CurDAG->haveNoCommonBitsSet(N, Parent->
getOperand(1));
584 bool ARMDAGToDAGISel::SelectAddrModeImm12(
SDValue N,
591 !CurDAG->isBaseWithConstantOffset(N)) {
594 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
595 Base = CurDAG->getTargetFrameIndex(
596 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
613 int RHSC = (int)RHS->getSExtValue();
617 if (RHSC > -0x1000 && RHSC < 0x1000) {
620 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
621 Base = CurDAG->getTargetFrameIndex(
622 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
624 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
643 int RHSC = (int)RHS->getZExtValue();
652 unsigned ShAmt =
Log2_32(RHSC);
665 !CurDAG->isBaseWithConstantOffset(N))
672 -0x1000+1, 0x1000, RHSC))
690 ShAmt = Sh->getZExtValue();
691 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
712 ShAmt = Sh->getZExtValue();
713 if (isShifterOpProfitable(N.
getOperand(0), ShOpcVal, ShAmt)) {
729 unsigned PowerOfTwo = 0;
731 if (canExtractShiftFromMul(Offset, 31, PowerOfTwo, NewMulConst)) {
733 replaceDAGValue(Offset.
getOperand(1), NewMulConst);
749 ? cast<LoadSDNode>(Op)->getAddressingMode()
750 : cast<StoreSDNode>(
Op)->getAddressingMode();
764 ShAmt = Sh->getZExtValue();
765 if (isShifterOpProfitable(N, ShOpcVal, ShAmt))
781 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(
SDNode *Op,
SDValue N,
785 ? cast<LoadSDNode>(Op)->getAddressingMode()
786 : cast<StoreSDNode>(
Op)->getAddressingMode();
792 Offset = CurDAG->getRegister(0,
MVT::i32);
801 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(
SDNode *Op,
SDValue N,
805 ? cast<LoadSDNode>(Op)->getAddressingMode()
806 : cast<StoreSDNode>(
Op)->getAddressingMode();
811 Offset = CurDAG->getRegister(0,
MVT::i32);
821 bool ARMDAGToDAGISel::SelectAddrOffsetNone(
SDValue N,
SDValue &Base) {
826 bool ARMDAGToDAGISel::SelectAddrMode3(
SDValue N,
838 if (!CurDAG->isBaseWithConstantOffset(N)) {
841 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
842 Base = CurDAG->getTargetFrameIndex(
843 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
845 Offset = CurDAG->getRegister(0,
MVT::i32);
854 -256 + 1, 256, RHSC)) {
857 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
858 Base = CurDAG->getTargetFrameIndex(
859 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
861 Offset = CurDAG->getRegister(0,
MVT::i32);
880 bool ARMDAGToDAGISel::SelectAddrMode3Offset(
SDNode *Op,
SDValue N,
884 ? cast<LoadSDNode>(Op)->getAddressingMode()
885 : cast<StoreSDNode>(
Op)->getAddressingMode();
890 Offset = CurDAG->getRegister(0,
MVT::i32);
903 int Lwb,
int Upb,
bool FP16) {
904 if (!CurDAG->isBaseWithConstantOffset(N)) {
907 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
908 Base = CurDAG->getTargetFrameIndex(
909 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
923 const int Scale = FP16 ? 2 : 4;
928 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
929 Base = CurDAG->getTargetFrameIndex(
930 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
961 bool ARMDAGToDAGISel::SelectAddrMode5(
SDValue N,
965 return IsAddressingMode5(N, Base, Offset, Lwb, Upb,
false);
968 bool ARMDAGToDAGISel::SelectAddrMode5FP16(
SDValue N,
972 return IsAddressingMode5(N, Base, Offset, Lwb, Upb,
true);
979 unsigned Alignment = 0;
981 MemSDNode *MemN = cast<MemSDNode>(Parent);
983 if (isa<LSBaseSDNode>(MemN) ||
991 if (MMOAlign >= MemSize && MemSize > 1)
1000 Align = CurDAG->getTargetConstant(Alignment,
SDLoc(N),
MVT::i32);
1004 bool ARMDAGToDAGISel::SelectAddrMode6Offset(
SDNode *Op,
SDValue N,
1013 Offset = CurDAG->getRegister(0,
MVT::i32);
1018 bool ARMDAGToDAGISel::SelectAddrModePC(
SDValue N,
1023 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
1036 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(
SDValue N,
1053 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(
SDValue N,
unsigned Scale,
1055 if (!CurDAG->isBaseWithConstantOffset(N)) {
1076 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1085 ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(
SDValue N,
SDValue &Base,
1087 return SelectThumbAddrModeImm5S(N, 4, Base, OffImm);
1091 ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(
SDValue N,
SDValue &Base,
1093 return SelectThumbAddrModeImm5S(N, 2, Base, OffImm);
1097 ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(
SDValue N,
SDValue &Base,
1099 return SelectThumbAddrModeImm5S(N, 1, Base, OffImm);
1102 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(
SDValue N,
1105 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1111 Base = CurDAG->getTargetFrameIndex(
1112 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1117 if (!CurDAG->isBaseWithConstantOffset(N))
1122 (LHSR && LHSR->
getReg() == ARM::SP)) {
1128 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1134 Base = CurDAG->getTargetFrameIndex(
1135 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1137 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1151 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(
SDValue N,
1157 !CurDAG->isBaseWithConstantOffset(N)) {
1160 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1161 Base = CurDAG->getTargetFrameIndex(
1162 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1181 if (SelectT2AddrModeImm8(N, Base, OffImm))
1185 int RHSC = (int)RHS->getZExtValue();
1189 if (RHSC >= 0 && RHSC < 0x1000) {
1192 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1193 Base = CurDAG->getTargetFrameIndex(
1194 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1196 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1207 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(
SDValue N,
1211 !CurDAG->isBaseWithConstantOffset(N))
1215 int RHSC = (int)RHS->getSExtValue();
1219 if ((RHSC >= -255) && (RHSC < 0)) {
1222 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1223 Base = CurDAG->getTargetFrameIndex(
1224 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1226 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1234 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(
SDNode *Op,
SDValue N,
1238 ? cast<LoadSDNode>(Op)->getAddressingMode()
1239 : cast<StoreSDNode>(
Op)->getAddressingMode();
1251 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(
SDValue N,
1260 int RHSC = (int)RHS->getZExtValue();
1261 if (RHSC >= 0 && RHSC < 0x1000)
1263 else if (RHSC < 0 && RHSC >= -255)
1284 ShAmt = Sh->getZExtValue();
1285 if (ShAmt < 4 && isShifterOpProfitable(OffReg, ShOpcVal, ShAmt))
1296 unsigned PowerOfTwo = 0;
1298 if (canExtractShiftFromMul(OffReg, 3, PowerOfTwo, NewMulConst)) {
1300 replaceDAGValue(OffReg.
getOperand(1), NewMulConst);
1306 ShImm = CurDAG->getTargetConstant(ShAmt,
SDLoc(N),
MVT::i32);
1311 bool ARMDAGToDAGISel::SelectT2AddrModeExclusive(
SDValue N,
SDValue &Base,
1326 if (RHSC > 1020 || RHSC % 4 != 0)
1331 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1332 Base = CurDAG->getTargetFrameIndex(
1333 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1336 OffImm = CurDAG->getTargetConstant(RHSC/4,
SDLoc(N),
MVT::i32);
1347 void ARMDAGToDAGISel::transferMemOperands(
SDNode *N,
SDNode *Result) {
1349 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Result), {MemOp});
1352 bool ARMDAGToDAGISel::tryARMIndexedLoad(
SDNode *N) {
1361 unsigned Opcode = 0;
1363 if (LoadedVT ==
MVT::i32 && isPre &&
1365 Opcode = ARM::LDR_PRE_IMM;
1367 }
else if (LoadedVT ==
MVT::i32 && !isPre &&
1369 Opcode = ARM::LDR_POST_IMM;
1373 Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG;
1380 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
1381 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
1386 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
1392 Opcode = ARM::LDRB_PRE_IMM;
1393 }
else if (!isPre &&
1396 Opcode = ARM::LDRB_POST_IMM;
1397 }
else if (SelectAddrMode2OffsetReg(N, LD->
getOffset(),
Offset, AMOpc)) {
1399 Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG;
1405 if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) {
1409 CurDAG->getRegister(0,
MVT::i32), Chain };
1412 transferMemOperands(N, New);
1413 ReplaceNode(N, New);
1419 CurDAG->getRegister(0,
MVT::i32), Chain };
1422 transferMemOperands(N, New);
1423 ReplaceNode(N, New);
1431 bool ARMDAGToDAGISel::tryT1IndexedLoad(
SDNode *N) {
1436 LoadedVT.getSimpleVT().SimpleTy !=
MVT::i32)
1440 if (!COffs || COffs->getZExtValue() != 4)
1450 CurDAG->getRegister(0,
MVT::i32), Chain };
1453 transferMemOperands(N, New);
1454 ReplaceNode(N, New);
1458 bool ARMDAGToDAGISel::tryT2IndexedLoad(
SDNode *N) {
1468 unsigned Opcode = 0;
1473 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST;
1477 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST;
1479 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST;
1484 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST;
1486 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST;
1498 CurDAG->getRegister(0,
MVT::i32), Chain };
1501 transferMemOperands(N, New);
1502 ReplaceNode(N, New);
1513 CurDAG->getTargetConstant(ARM::GPRPairRegClassID, dl,
MVT::i32);
1514 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::gsub_0, dl,
MVT::i32);
1515 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::gsub_1, dl,
MVT::i32);
1516 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1517 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1524 CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, dl,
MVT::i32);
1525 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl,
MVT::i32);
1526 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl,
MVT::i32);
1527 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1528 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1534 SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, dl,
1536 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl,
MVT::i32);
1537 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl,
MVT::i32);
1538 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1539 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1545 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl,
1547 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl,
MVT::i32);
1548 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl,
MVT::i32);
1549 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1550 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1558 CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, dl,
MVT::i32);
1559 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl,
MVT::i32);
1560 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl,
MVT::i32);
1561 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, dl,
MVT::i32);
1562 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, dl,
MVT::i32);
1563 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1564 V2, SubReg2, V3, SubReg3 };
1565 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1572 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl,
1574 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl,
MVT::i32);
1575 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl,
MVT::i32);
1576 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, dl,
MVT::i32);
1577 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, dl,
MVT::i32);
1578 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1579 V2, SubReg2, V3, SubReg3 };
1580 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1587 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, dl,
1589 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl,
MVT::i32);
1590 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl,
MVT::i32);
1591 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, dl,
MVT::i32);
1592 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, dl,
MVT::i32);
1593 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1594 V2, SubReg2, V3, SubReg3 };
1595 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1602 unsigned NumVecs,
bool is64BitVector) {
1603 unsigned NumRegs = NumVecs;
1604 if (!is64BitVector && NumVecs < 3)
1607 unsigned Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
1608 if (Alignment >= 32 && NumRegs == 4)
1610 else if (Alignment >= 16 && (NumRegs == 2 || NumRegs == 4))
1612 else if (Alignment >= 8)
1617 return CurDAG->getTargetConstant(Alignment, dl,
MVT::i32);
1623 default:
return false;
1624 case ARM::VLD1d8wb_fixed :
return true;
1625 case ARM::VLD1d16wb_fixed :
return true;
1626 case ARM::VLD1d64Qwb_fixed :
return true;
1627 case ARM::VLD1d32wb_fixed :
return true;
1628 case ARM::VLD1d64wb_fixed :
return true;
1629 case ARM::VLD1d64TPseudoWB_fixed :
return true;
1630 case ARM::VLD1d64QPseudoWB_fixed :
return true;
1631 case ARM::VLD1q8wb_fixed :
return true;
1632 case ARM::VLD1q16wb_fixed :
return true;
1633 case ARM::VLD1q32wb_fixed :
return true;
1634 case ARM::VLD1q64wb_fixed :
return true;
1635 case ARM::VLD1DUPd8wb_fixed :
return true;
1636 case ARM::VLD1DUPd16wb_fixed :
return true;
1637 case ARM::VLD1DUPd32wb_fixed :
return true;
1638 case ARM::VLD1DUPq8wb_fixed :
return true;
1639 case ARM::VLD1DUPq16wb_fixed :
return true;
1640 case ARM::VLD1DUPq32wb_fixed :
return true;
1641 case ARM::VLD2d8wb_fixed :
return true;
1642 case ARM::VLD2d16wb_fixed :
return true;
1643 case ARM::VLD2d32wb_fixed :
return true;
1644 case ARM::VLD2q8PseudoWB_fixed :
return true;
1645 case ARM::VLD2q16PseudoWB_fixed :
return true;
1646 case ARM::VLD2q32PseudoWB_fixed :
return true;
1647 case ARM::VLD2DUPd8wb_fixed :
return true;
1648 case ARM::VLD2DUPd16wb_fixed :
return true;
1649 case ARM::VLD2DUPd32wb_fixed :
return true;
1656 default:
return false;
1657 case ARM::VST1d8wb_fixed :
return true;
1658 case ARM::VST1d16wb_fixed :
return true;
1659 case ARM::VST1d32wb_fixed :
return true;
1660 case ARM::VST1d64wb_fixed :
return true;
1661 case ARM::VST1q8wb_fixed :
return true;
1662 case ARM::VST1q16wb_fixed :
return true;
1663 case ARM::VST1q32wb_fixed :
return true;
1664 case ARM::VST1q64wb_fixed :
return true;
1665 case ARM::VST1d64TPseudoWB_fixed :
return true;
1666 case ARM::VST1d64QPseudoWB_fixed :
return true;
1667 case ARM::VST2d8wb_fixed :
return true;
1668 case ARM::VST2d16wb_fixed :
return true;
1669 case ARM::VST2d32wb_fixed :
return true;
1670 case ARM::VST2q8PseudoWB_fixed :
return true;
1671 case ARM::VST2q16PseudoWB_fixed :
return true;
1672 case ARM::VST2q32PseudoWB_fixed :
return true;
1680 &&
"Incorrect fixed stride updating instruction.");
1683 case ARM::VLD1d8wb_fixed:
return ARM::VLD1d8wb_register;
1684 case ARM::VLD1d16wb_fixed:
return ARM::VLD1d16wb_register;
1685 case ARM::VLD1d32wb_fixed:
return ARM::VLD1d32wb_register;
1686 case ARM::VLD1d64wb_fixed:
return ARM::VLD1d64wb_register;
1687 case ARM::VLD1q8wb_fixed:
return ARM::VLD1q8wb_register;
1688 case ARM::VLD1q16wb_fixed:
return ARM::VLD1q16wb_register;
1689 case ARM::VLD1q32wb_fixed:
return ARM::VLD1q32wb_register;
1690 case ARM::VLD1q64wb_fixed:
return ARM::VLD1q64wb_register;
1691 case ARM::VLD1d64Twb_fixed:
return ARM::VLD1d64Twb_register;
1692 case ARM::VLD1d64Qwb_fixed:
return ARM::VLD1d64Qwb_register;
1693 case ARM::VLD1d64TPseudoWB_fixed:
return ARM::VLD1d64TPseudoWB_register;
1694 case ARM::VLD1d64QPseudoWB_fixed:
return ARM::VLD1d64QPseudoWB_register;
1695 case ARM::VLD1DUPd8wb_fixed :
return ARM::VLD1DUPd8wb_register;
1696 case ARM::VLD1DUPd16wb_fixed :
return ARM::VLD1DUPd16wb_register;
1697 case ARM::VLD1DUPd32wb_fixed :
return ARM::VLD1DUPd32wb_register;
1698 case ARM::VLD1DUPq8wb_fixed :
return ARM::VLD1DUPq8wb_register;
1699 case ARM::VLD1DUPq16wb_fixed :
return ARM::VLD1DUPq16wb_register;
1700 case ARM::VLD1DUPq32wb_fixed :
return ARM::VLD1DUPq32wb_register;
1702 case ARM::VST1d8wb_fixed:
return ARM::VST1d8wb_register;
1703 case ARM::VST1d16wb_fixed:
return ARM::VST1d16wb_register;
1704 case ARM::VST1d32wb_fixed:
return ARM::VST1d32wb_register;
1705 case ARM::VST1d64wb_fixed:
return ARM::VST1d64wb_register;
1706 case ARM::VST1q8wb_fixed:
return ARM::VST1q8wb_register;
1707 case ARM::VST1q16wb_fixed:
return ARM::VST1q16wb_register;
1708 case ARM::VST1q32wb_fixed:
return ARM::VST1q32wb_register;
1709 case ARM::VST1q64wb_fixed:
return ARM::VST1q64wb_register;
1710 case ARM::VST1d64TPseudoWB_fixed:
return ARM::VST1d64TPseudoWB_register;
1711 case ARM::VST1d64QPseudoWB_fixed:
return ARM::VST1d64QPseudoWB_register;
1713 case ARM::VLD2d8wb_fixed:
return ARM::VLD2d8wb_register;
1714 case ARM::VLD2d16wb_fixed:
return ARM::VLD2d16wb_register;
1715 case ARM::VLD2d32wb_fixed:
return ARM::VLD2d32wb_register;
1716 case ARM::VLD2q8PseudoWB_fixed:
return ARM::VLD2q8PseudoWB_register;
1717 case ARM::VLD2q16PseudoWB_fixed:
return ARM::VLD2q16PseudoWB_register;
1718 case ARM::VLD2q32PseudoWB_fixed:
return ARM::VLD2q32PseudoWB_register;
1720 case ARM::VST2d8wb_fixed:
return ARM::VST2d8wb_register;
1721 case ARM::VST2d16wb_fixed:
return ARM::VST2d16wb_register;
1722 case ARM::VST2d32wb_fixed:
return ARM::VST2d32wb_register;
1723 case ARM::VST2q8PseudoWB_fixed:
return ARM::VST2q8PseudoWB_register;
1724 case ARM::VST2q16PseudoWB_fixed:
return ARM::VST2q16PseudoWB_register;
1725 case ARM::VST2q32PseudoWB_fixed:
return ARM::VST2q32PseudoWB_register;
1727 case ARM::VLD2DUPd8wb_fixed:
return ARM::VLD2DUPd8wb_register;
1728 case ARM::VLD2DUPd16wb_fixed:
return ARM::VLD2DUPd16wb_register;
1729 case ARM::VLD2DUPd32wb_fixed:
return ARM::VLD2DUPd32wb_register;
1742 void ARMDAGToDAGISel::SelectVLD(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
1743 const uint16_t *DOpcodes,
1744 const uint16_t *QOpcodes0,
1745 const uint16_t *QOpcodes1) {
1746 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VLD NumVecs out-of-range");
1750 bool IsIntrinsic = !isUpdating;
1752 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
1759 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector);
1785 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
1790 std::vector<EVT> ResTys;
1791 ResTys.push_back(ResTy);
1802 if (is64BitVector || NumVecs <= 2) {
1803 unsigned Opc = (is64BitVector ? DOpcodes[
OpcodeIndex] :
1824 VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1834 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0);
1835 const SDValue OpsA[] = { MemAddr,
Align, Reg0, ImplDef, Pred, Reg0, Chain };
1836 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
1846 "only constant post-increment update allowed for VLD3/4");
1854 VLd = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, Ops);
1859 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLd), {MemOp});
1862 ReplaceNode(N, VLd);
1868 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7 &&
1869 ARM::qsub_3 == ARM::qsub_0 + 3,
1870 "Unexpected subreg numbering");
1871 unsigned Sub0 = (is64BitVector ? ARM::dsub_0 : ARM::qsub_0);
1872 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
1874 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
1878 CurDAG->RemoveDeadNode(N);
1881 void ARMDAGToDAGISel::SelectVST(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
1882 const uint16_t *DOpcodes,
1883 const uint16_t *QOpcodes0,
1884 const uint16_t *QOpcodes1) {
1885 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VST NumVecs out-of-range");
1889 bool IsIntrinsic = !isUpdating;
1891 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
1892 unsigned Vec0Idx = 3;
1901 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector);
1923 std::vector<EVT> ResTys;
1933 if (is64BitVector || NumVecs <= 2) {
1937 }
else if (is64BitVector) {
1948 ?
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
1959 unsigned Opc = (is64BitVector ? DOpcodes[
OpcodeIndex] :
1982 SDNode *VSt = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1985 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VSt), {MemOp});
1987 ReplaceNode(N, VSt);
1999 ?
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
2005 const SDValue OpsA[] = { MemAddr,
Align, Reg0, RegSeq, Pred, Reg0, Chain };
2006 SDNode *VStA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
2009 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VStA), {MemOp});
2018 "only constant post-increment update allowed for VST3/4");
2026 SDNode *VStB = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys,
2028 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VStB), {MemOp});
2029 ReplaceNode(N, VStB);
2032 void ARMDAGToDAGISel::SelectVLDSTLane(
SDNode *N,
bool IsLoad,
bool isUpdating,
2034 const uint16_t *DOpcodes,
2035 const uint16_t *QOpcodes) {
2036 assert(NumVecs >=2 && NumVecs <= 4 &&
"VLDSTLane NumVecs out-of-range");
2040 bool IsIntrinsic = !isUpdating;
2042 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
2043 unsigned Vec0Idx = 3;
2051 cast<ConstantSDNode>(N->
getOperand(Vec0Idx + NumVecs))->getZExtValue();
2055 unsigned Alignment = 0;
2057 Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
2059 if (Alignment > NumBytes)
2060 Alignment = NumBytes;
2061 if (Alignment < 8 && Alignment < NumBytes)
2064 Alignment = (Alignment & -Alignment);
2068 Align = CurDAG->getTargetConstant(Alignment, dl,
MVT::i32);
2084 std::vector<EVT> ResTys;
2086 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
2106 Ops.
push_back(IsImmUpdate ? Reg0 : Inc);
2120 ?
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
2133 unsigned Opc = (is64BitVector ? DOpcodes[
OpcodeIndex] :
2135 SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2136 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLdLn), {MemOp});
2138 ReplaceNode(N, VLdLn);
2144 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7 &&
2145 ARM::qsub_3 == ARM::qsub_0 + 3,
2146 "Unexpected subreg numbering");
2147 unsigned Sub0 = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
2148 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
2150 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
2154 CurDAG->RemoveDeadNode(N);
2157 void ARMDAGToDAGISel::SelectVLDDup(
SDNode *N,
bool IsIntrinsic,
2158 bool isUpdating,
unsigned NumVecs,
2159 const uint16_t *DOpcodes,
2160 const uint16_t *QOpcodes0,
2161 const uint16_t *QOpcodes1) {
2162 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VLDDup NumVecs out-of-range");
2166 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
2174 unsigned Alignment = 0;
2176 Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
2178 if (Alignment > NumBytes)
2179 Alignment = NumBytes;
2180 if (Alignment < 8 && Alignment < NumBytes)
2183 Alignment = (Alignment & -Alignment);
2187 Align = CurDAG->getTargetConstant(Alignment, dl,
MVT::i32);
2204 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
2209 std::vector<EVT> ResTys;
2210 ResTys.push_back(ResTy);
2219 if (is64BitVector || NumVecs == 1) {
2223 unsigned Opc = is64BitVector ? DOpcodes[
OpcodeIndex] :
2231 if (NumVecs <= 2 && !IsImmUpdate)
2236 else if (NumVecs > 2)
2242 VLdDup = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2243 }
else if (NumVecs == 2) {
2244 const SDValue OpsA[] = { MemAddr,
Align, Pred, Reg0, Chain };
2245 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex],
2249 const SDValue OpsB[] = { MemAddr,
Align, Pred, Reg0, Chain };
2250 VLdDup = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, OpsB);
2253 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0);
2254 const SDValue OpsA[] = { MemAddr,
Align, ImplDef, Pred, Reg0, Chain };
2255 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex],
2260 const SDValue OpsB[] = { MemAddr,
Align, SuperReg, Pred, Reg0, Chain };
2261 VLdDup = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, OpsB);
2266 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLdDup), {MemOp});
2273 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7,
"Unexpected subreg numbering");
2274 unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
2275 for (
unsigned Vec = 0; Vec != NumVecs; ++Vec) {
2277 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, SuperReg));
2283 CurDAG->RemoveDeadNode(N);
2286 bool ARMDAGToDAGISel::tryV6T2BitfieldExtractOp(
SDNode *N,
bool isSigned) {
2290 unsigned Opc = isSigned
2291 ? (Subtarget->
isThumb() ? ARM::t2SBFX : ARM::SBFX)
2292 : (Subtarget->
isThumb() ? ARM::t2UBFX : ARM::UBFX);
2296 unsigned And_imm = 0;
2301 if (And_imm & (And_imm + 1))
2304 unsigned Srl_imm = 0;
2307 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2312 And_imm &= -1U >> Srl_imm;
2316 unsigned LSB = Srl_imm;
2323 Opc = isSigned ? ARM::t2ASRri : ARM::t2LSRri;
2325 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2326 getAL(CurDAG, dl), Reg0, Reg0 };
2327 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2337 getAL(CurDAG, dl), Reg0, Reg0 };
2338 CurDAG->SelectNodeTo(N, ARM::MOVsi,
MVT::i32, Ops);
2342 assert(LSB + Width + 1 <= 32 &&
"Shouldn't create an invalid ubfx");
2344 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2345 CurDAG->getTargetConstant(Width, dl,
MVT::i32),
2346 getAL(CurDAG, dl), Reg0 };
2347 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2355 unsigned Shl_imm = 0;
2357 assert(Shl_imm > 0 && Shl_imm < 32 &&
"bad amount in shift node!");
2358 unsigned Srl_imm = 0;
2360 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2362 unsigned Width = 32 - Srl_imm - 1;
2363 int LSB = Srl_imm - Shl_imm;
2367 assert(LSB + Width + 1 <= 32 &&
"Shouldn't create an invalid ubfx");
2369 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2370 CurDAG->getTargetConstant(Width, dl,
MVT::i32),
2371 getAL(CurDAG, dl), Reg0 };
2372 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2380 unsigned Srl_imm = 0;
2384 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2387 unsigned Width = MSB - LSB;
2389 assert(Srl_imm + Width + 1 <= 32 &&
"Shouldn't create an invalid ubfx");
2391 CurDAG->getTargetConstant(Srl_imm, dl,
MVT::i32),
2392 CurDAG->getTargetConstant(Width, dl,
MVT::i32),
2393 getAL(CurDAG, dl), Reg0 };
2394 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2400 unsigned Width = cast<VTSDNode>(N->
getOperand(1))->getVT().getSizeInBits();
2406 if (LSB + Width > 32)
2410 assert(LSB + Width <= 32 &&
"Shouldn't create an invalid ubfx");
2412 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2413 CurDAG->getTargetConstant(Width - 1, dl,
MVT::i32),
2414 getAL(CurDAG, dl), Reg0 };
2415 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2432 bool ARMDAGToDAGISel::tryABSOp(
SDNode *N){
2449 unsigned Size = XType.getSizeInBits() - 1;
2451 if (ADDSrc1 == XORSrc1 && ADDSrc0 == SRASrc0 &&
2452 XType.isInteger() && SRAConstant !=
nullptr &&
2455 CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0);
2463 void ARMDAGToDAGISel::SelectCMP_SWAP(
SDNode *N) {
2465 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
2467 Opcode = ARM::CMP_SWAP_8;
2469 Opcode = ARM::CMP_SWAP_16;
2471 Opcode = ARM::CMP_SWAP_32;
2477 SDNode *CmpSwap = CurDAG->getMachineNode(
2482 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
2486 CurDAG->RemoveDeadNode(N);
2495 return std::make_pair(FirstOne, LastOne);
2498 void ARMDAGToDAGISel::SelectCMPZ(
SDNode *N,
bool &SwitchEQNEToPLMI) {
2500 SwitchEQNEToPLMI =
false;
2513 if (!isa<ConstantSDNode>(Zero) || !cast<ConstantSDNode>(Zero)->isNullValue() ||
2529 auto EmitShift = [&](
unsigned Opc,
SDValue Src,
unsigned Imm) ->
SDNode* {
2531 Opc = (Opc == ARM::tLSLri) ? ARM::t2LSLri : ARM::t2LSRri;
2534 CurDAG->getRegister(0,
MVT::i32) };
2535 return CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops);
2538 CurDAG->getTargetConstant(Imm, dl,
MVT::i32),
2540 return CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops);
2544 if (Range->second == 0) {
2546 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
2547 ReplaceNode(And.
getNode(), NewN);
2548 }
else if (Range->first == 31) {
2550 NewN = EmitShift(ARM::tLSRri, X, Range->second);
2551 ReplaceNode(And.
getNode(), NewN);
2552 }
else if (Range->first == Range->second) {
2555 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
2556 ReplaceNode(And.
getNode(), NewN);
2558 SwitchEQNEToPLMI =
true;
2562 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
2563 NewN = EmitShift(ARM::tLSRri,
SDValue(NewN, 0),
2564 Range->second + (31 - Range->first));
2565 ReplaceNode(And.
getNode(), NewN);
2581 if (tryWriteRegister(N))
2585 if (tryReadRegister(N))
2589 if (tryInlineAsm(N))
2599 unsigned Val = cast<ConstantSDNode>(
N)->getZExtValue();
2601 if (ConstantMaterializationCost(Val) > 2) {
2602 SDValue CPIdx = CurDAG->getTargetConstantPool(
2604 TLI->getPointerTy(CurDAG->getDataLayout()));
2612 CurDAG->getEntryNode()
2619 CurDAG->getTargetConstant(0, dl,
MVT::i32),
2622 CurDAG->getEntryNode()
2635 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {MemOp});
2637 ReplaceNode(N, ResNode);
2646 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
2647 SDValue TFI = CurDAG->getTargetFrameIndex(
2648 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
2655 CurDAG->SelectNodeTo(N, ARM::tADDframe,
MVT::i32, TFI,
2656 CurDAG->getTargetConstant(0, dl,
MVT::i32));
2660 ARM::t2ADDri : ARM::ADDri);
2663 CurDAG->getRegister(0,
MVT::i32) };
2664 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2669 if (tryV6T2BitfieldExtractOp(N,
false))
2674 if (tryV6T2BitfieldExtractOp(N,
true))
2681 unsigned RHSV =
C->getZExtValue();
2684 unsigned ShImm =
Log2_32(RHSV-1);
2692 SDValue Ops[] = { V, V, ShImmOp,
getAL(CurDAG, dl), Reg0, Reg0 };
2693 CurDAG->SelectNodeTo(N, ARM::t2ADDrs,
MVT::i32, Ops);
2696 SDValue Ops[] = { V, V, Reg0, ShImmOp,
getAL(CurDAG, dl), Reg0,
2698 CurDAG->SelectNodeTo(N, ARM::ADDrsi,
MVT::i32, Ops);
2703 unsigned ShImm =
Log2_32(RHSV+1);
2711 SDValue Ops[] = { V, V, ShImmOp,
getAL(CurDAG, dl), Reg0, Reg0 };
2712 CurDAG->SelectNodeTo(N, ARM::t2RSBrs,
MVT::i32, Ops);
2715 SDValue Ops[] = { V, V, Reg0, ShImmOp,
getAL(CurDAG, dl), Reg0,
2717 CurDAG->SelectNodeTo(N, ARM::RSBrsi,
MVT::i32, Ops);
2725 if (tryV6T2BitfieldExtractOp(N,
false))
2732 if (N1C && N1C->hasOneUse() && Subtarget->
isThumb()) {
2739 bool PreferImmediateEncoding =
2740 Subtarget->
hasThumb2() && (is_t2_so_imm(Imm) || is_t2_so_imm_not(Imm));
2741 if (!PreferImmediateEncoding &&
2742 ConstantMaterializationCost(Imm) >
2743 ConstantMaterializationCost(~Imm)) {
2747 CurDAG->getConstant(~N1C->getZExtValue(), dl,
MVT::i32);
2757 ReplaceNode(N, CurDAG->getMachineNode(ARM::tBIC, dl,
MVT::i32, Ops));
2764 CurDAG->getMachineNode(ARM::t2BICrr, dl,
MVT::i32, Ops));
2780 : (Subtarget->
hasV6T2Ops() ? ARM::MOVTi16 : 0);
2794 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) &&
2795 (N1CVal & 0xffffU) == 0xffffU &&
2796 (N2CVal & 0xffffU) == 0x0U) {
2797 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16,
2801 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
2813 CurDAG->getRegister(0,
MVT::i32) };
2829 CurDAG->getRegister(0,
MVT::i32) };
2830 ReplaceNode(N, CurDAG->getMachineNode(
2848 CurDAG->getRegister(0,
MVT::i32) };
2849 ReplaceNode(N, CurDAG->getMachineNode(
2867 "This pattern should not be generated for Thumb");
2873 if (!Zero || Zero->getZExtValue() != 0 ||
2879 unsigned Opc = Subtarget->
isThumb2() ? ARM::t2SMMLS : ARM::SMMLS;
2882 CurDAG->getRegister(0,
MVT::i32) };
2883 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops));
2888 if (tryT2IndexedLoad(N))
2890 }
else if (Subtarget->
isThumb()) {
2891 if (tryT1IndexedLoad(N))
2893 }
else if (tryARMIndexedLoad(N))
2911 unsigned Opc = Subtarget->
isThumb() ?
2912 ((Subtarget->
hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc;
2922 unsigned CC = (
unsigned) cast<ConstantSDNode>(N2)->getZExtValue();
2925 bool SwitchEQNEToPLMI;
2926 SelectCMPZ(InFlag.
getNode(), SwitchEQNEToPLMI);
2929 if (SwitchEQNEToPLMI) {
2943 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag };
2949 ReplaceUses(
SDValue(N, 1), InFlag);
2953 CurDAG->RemoveDeadNode(N);
2964 if (
C &&
C->getSExtValue() < 0 && Subtarget->
isThumb()) {
2965 int64_t Addend = -
C->getSExtValue();
2972 if (Addend < 1<<8) {
2976 CurDAG->getRegister(0,
MVT::i32) };
2977 Add = CurDAG->getMachineNode(ARM::t2ADDri, dl,
MVT::i32, Ops);
2979 unsigned Opc = (Addend < 1<<3) ? ARM::tADDi3 : ARM::tADDi8;
2981 CurDAG->getTargetConstant(Addend, dl,
MVT::i32),
2983 Add = CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops);
2999 bool SwitchEQNEToPLMI;
3000 SelectCMPZ(InFlag.
getNode(), SwitchEQNEToPLMI);
3002 if (SwitchEQNEToPLMI) {
3032 case MVT::v8i8: Opc = ARM::VZIPd8;
break;
3047 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops));
3055 case MVT::v8i8: Opc = ARM::VUZPd8;
break;
3070 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops));
3078 case MVT::v8i8: Opc = ARM::VTRNd8;
break;
3092 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops));
3100 assert(NumElts == 2 &&
"unexpected type for BUILD_VECTOR");
3111 assert(NumElts == 4 &&
"unexpected type for BUILD_VECTOR");
3119 static const uint16_t DOpcodes[] = { ARM::VLD1DUPd8, ARM::VLD1DUPd16,
3121 static const uint16_t QOpcodes[] = { ARM::VLD1DUPq8, ARM::VLD1DUPq16,
3123 SelectVLDDup(N,
false,
false, 1, DOpcodes, QOpcodes);
3128 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16,
3130 SelectVLDDup(N,
false,
false, 2, Opcodes);
3135 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo,
3136 ARM::VLD3DUPd16Pseudo,
3137 ARM::VLD3DUPd32Pseudo };
3138 SelectVLDDup(N,
false,
false, 3, Opcodes);
3143 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo,
3144 ARM::VLD4DUPd16Pseudo,
3145 ARM::VLD4DUPd32Pseudo };
3146 SelectVLDDup(N,
false,
false, 4, Opcodes);
3151 static const uint16_t DOpcodes[] = { ARM::VLD1DUPd8wb_fixed,
3152 ARM::VLD1DUPd16wb_fixed,
3153 ARM::VLD1DUPd32wb_fixed };
3154 static const uint16_t QOpcodes[] = { ARM::VLD1DUPq8wb_fixed,
3155 ARM::VLD1DUPq16wb_fixed,
3156 ARM::VLD1DUPq32wb_fixed };
3157 SelectVLDDup(N,
false,
true, 1, DOpcodes, QOpcodes);
3162 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8wb_fixed,
3163 ARM::VLD2DUPd16wb_fixed,
3164 ARM::VLD2DUPd32wb_fixed };
3165 SelectVLDDup(N,
false,
true, 2, Opcodes);
3170 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo_UPD,
3171 ARM::VLD3DUPd16Pseudo_UPD,
3172 ARM::VLD3DUPd32Pseudo_UPD };
3173 SelectVLDDup(N,
false,
true, 3, Opcodes);
3178 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo_UPD,
3179 ARM::VLD4DUPd16Pseudo_UPD,
3180 ARM::VLD4DUPd32Pseudo_UPD };
3181 SelectVLDDup(N,
false,
true, 4, Opcodes);
3186 static const uint16_t DOpcodes[] = { ARM::VLD1d8wb_fixed,
3187 ARM::VLD1d16wb_fixed,
3188 ARM::VLD1d32wb_fixed,
3189 ARM::VLD1d64wb_fixed };
3190 static const uint16_t QOpcodes[] = { ARM::VLD1q8wb_fixed,
3191 ARM::VLD1q16wb_fixed,
3192 ARM::VLD1q32wb_fixed,
3193 ARM::VLD1q64wb_fixed };
3194 SelectVLD(N,
true, 1, DOpcodes, QOpcodes,
nullptr);
3199 static const uint16_t DOpcodes[] = { ARM::VLD2d8wb_fixed,
3200 ARM::VLD2d16wb_fixed,
3201 ARM::VLD2d32wb_fixed,
3202 ARM::VLD1q64wb_fixed};
3203 static const uint16_t QOpcodes[] = { ARM::VLD2q8PseudoWB_fixed,
3204 ARM::VLD2q16PseudoWB_fixed,
3205 ARM::VLD2q32PseudoWB_fixed };
3206 SelectVLD(N,
true, 2, DOpcodes, QOpcodes,
nullptr);
3211 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD,
3212 ARM::VLD3d16Pseudo_UPD,
3213 ARM::VLD3d32Pseudo_UPD,
3214 ARM::VLD1d64TPseudoWB_fixed};
3215 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
3216 ARM::VLD3q16Pseudo_UPD,
3217 ARM::VLD3q32Pseudo_UPD };
3218 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo_UPD,
3219 ARM::VLD3q16oddPseudo_UPD,
3220 ARM::VLD3q32oddPseudo_UPD };
3221 SelectVLD(N,
true, 3, DOpcodes, QOpcodes0, QOpcodes1);
3226 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD,
3227 ARM::VLD4d16Pseudo_UPD,
3228 ARM::VLD4d32Pseudo_UPD,
3229 ARM::VLD1d64QPseudoWB_fixed};
3230 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
3231 ARM::VLD4q16Pseudo_UPD,
3232 ARM::VLD4q32Pseudo_UPD };
3233 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo_UPD,
3234 ARM::VLD4q16oddPseudo_UPD,
3235 ARM::VLD4q32oddPseudo_UPD };
3236 SelectVLD(N,
true, 4, DOpcodes, QOpcodes0, QOpcodes1);
3241 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo_UPD,
3242 ARM::VLD2LNd16Pseudo_UPD,
3243 ARM::VLD2LNd32Pseudo_UPD };
3244 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo_UPD,
3245 ARM::VLD2LNq32Pseudo_UPD };
3246 SelectVLDSTLane(N,
true,
true, 2, DOpcodes, QOpcodes);
3251 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo_UPD,
3252 ARM::VLD3LNd16Pseudo_UPD,
3253 ARM::VLD3LNd32Pseudo_UPD };
3254 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo_UPD,
3255 ARM::VLD3LNq32Pseudo_UPD };
3256 SelectVLDSTLane(N,
true,
true, 3, DOpcodes, QOpcodes);
3261 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo_UPD,
3262 ARM::VLD4LNd16Pseudo_UPD,
3263 ARM::VLD4LNd32Pseudo_UPD };
3264 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo_UPD,
3265 ARM::VLD4LNq32Pseudo_UPD };
3266 SelectVLDSTLane(N,
true,
true, 4, DOpcodes, QOpcodes);
3271 static const uint16_t DOpcodes[] = { ARM::VST1d8wb_fixed,
3272 ARM::VST1d16wb_fixed,
3273 ARM::VST1d32wb_fixed,
3274 ARM::VST1d64wb_fixed };
3275 static const uint16_t QOpcodes[] = { ARM::VST1q8wb_fixed,
3276 ARM::VST1q16wb_fixed,
3277 ARM::VST1q32wb_fixed,
3278 ARM::VST1q64wb_fixed };
3279 SelectVST(N,
true, 1, DOpcodes, QOpcodes,
nullptr);
3284 static const uint16_t DOpcodes[] = { ARM::VST2d8wb_fixed,
3285 ARM::VST2d16wb_fixed,
3286 ARM::VST2d32wb_fixed,
3287 ARM::VST1q64wb_fixed};
3288 static const uint16_t QOpcodes[] = { ARM::VST2q8PseudoWB_fixed,
3289 ARM::VST2q16PseudoWB_fixed,
3290 ARM::VST2q32PseudoWB_fixed };
3291 SelectVST(N,
true, 2, DOpcodes, QOpcodes,
nullptr);
3296 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo_UPD,
3297 ARM::VST3d16Pseudo_UPD,
3298 ARM::VST3d32Pseudo_UPD,
3299 ARM::VST1d64TPseudoWB_fixed};
3300 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
3301 ARM::VST3q16Pseudo_UPD,
3302 ARM::VST3q32Pseudo_UPD };
3303 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD,
3304 ARM::VST3q16oddPseudo_UPD,
3305 ARM::VST3q32oddPseudo_UPD };
3306 SelectVST(N,
true, 3, DOpcodes, QOpcodes0, QOpcodes1);
3311 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo_UPD,
3312 ARM::VST4d16Pseudo_UPD,
3313 ARM::VST4d32Pseudo_UPD,
3314 ARM::VST1d64QPseudoWB_fixed};
3315 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
3316 ARM::VST4q16Pseudo_UPD,
3317 ARM::VST4q32Pseudo_UPD };
3318 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD,
3319 ARM::VST4q16oddPseudo_UPD,
3320 ARM::VST4q32oddPseudo_UPD };
3321 SelectVST(N,
true, 4, DOpcodes, QOpcodes0, QOpcodes1);
3326 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo_UPD,
3327 ARM::VST2LNd16Pseudo_UPD,
3328 ARM::VST2LNd32Pseudo_UPD };
3329 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo_UPD,
3330 ARM::VST2LNq32Pseudo_UPD };
3331 SelectVLDSTLane(N,
false,
true, 2, DOpcodes, QOpcodes);
3336 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo_UPD,
3337 ARM::VST3LNd16Pseudo_UPD,
3338 ARM::VST3LNd32Pseudo_UPD };
3339 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo_UPD,
3340 ARM::VST3LNq32Pseudo_UPD };
3341 SelectVLDSTLane(N,
false,
true, 3, DOpcodes, QOpcodes);
3346 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo_UPD,
3347 ARM::VST4LNd16Pseudo_UPD,
3348 ARM::VST4LNd32Pseudo_UPD };
3349 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo_UPD,
3350 ARM::VST4LNq32Pseudo_UPD };
3351 SelectVLDSTLane(N,
false,
true, 4, DOpcodes, QOpcodes);
3357 unsigned IntNo = cast<ConstantSDNode>(N->
getOperand(1))->getZExtValue();
3381 if (Opc != ARM::MRRC2) {
3391 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, RetType, Ops));
3402 unsigned NewOpc = isThumb ? (IsAcquire ? ARM::t2LDAEXD : ARM::t2LDREXD)
3403 : (IsAcquire ? ARM::LDAEXD : ARM::LDREXD);
3406 std::vector<EVT> ResTys;
3416 CurDAG->getRegister(0,
MVT::i32), Chain};
3417 SDNode *Ld = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
3420 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
3424 if (!SDValue(N, 0).use_empty()) {
3427 Result = SDValue(Ld, 0);
3430 CurDAG->getTargetConstant(ARM::gsub_0, dl,
MVT::i32);
3431 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
3432 dl,
MVT::i32, SDValue(Ld, 0), SubRegIdx);
3433 Result = SDValue(ResNode,0);
3435 ReplaceUses(SDValue(N, 0), Result);
3437 if (!SDValue(N, 1).use_empty()) {
3440 Result = SDValue(Ld, 1);
3443 CurDAG->getTargetConstant(ARM::gsub_1, dl,
MVT::i32);
3444 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
3445 dl,
MVT::i32, SDValue(Ld, 0), SubRegIdx);
3446 Result = SDValue(ResNode,0);
3448 ReplaceUses(SDValue(N, 1), Result);
3450 ReplaceUses(SDValue(N, 2), OutChain);
3451 CurDAG->RemoveDeadNode(N);
3481 unsigned NewOpc = isThumb ? (IsRelease ? ARM::t2STLEXD : ARM::t2STREXD)
3482 : (IsRelease ? ARM::STLEXD : ARM::STREXD);
3484 SDNode *St = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
3487 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
3494 static const uint16_t DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16,
3495 ARM::VLD1d32, ARM::VLD1d64 };
3496 static const uint16_t QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16,
3497 ARM::VLD1q32, ARM::VLD1q64};
3498 SelectVLD(N,
false, 1, DOpcodes, QOpcodes,
nullptr);
3503 static const uint16_t DOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16,
3504 ARM::VLD1q32, ARM::VLD1q64 };
3505 static const uint16_t QOpcodes[] = { ARM::VLD1d8QPseudo,
3506 ARM::VLD1d16QPseudo,
3507 ARM::VLD1d32QPseudo,
3508 ARM::VLD1d64QPseudo };
3509 SelectVLD(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3514 static const uint16_t DOpcodes[] = { ARM::VLD1d8TPseudo,
3515 ARM::VLD1d16TPseudo,
3516 ARM::VLD1d32TPseudo,
3517 ARM::VLD1d64TPseudo };
3518 static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowTPseudo_UPD,
3519 ARM::VLD1q16LowTPseudo_UPD,
3520 ARM::VLD1q32LowTPseudo_UPD,
3521 ARM::VLD1q64LowTPseudo_UPD };
3522 static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighTPseudo,
3523 ARM::VLD1q16HighTPseudo,
3524 ARM::VLD1q32HighTPseudo,
3525 ARM::VLD1q64HighTPseudo };
3526 SelectVLD(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3531 static const uint16_t DOpcodes[] = { ARM::VLD1d8QPseudo,
3532 ARM::VLD1d16QPseudo,
3533 ARM::VLD1d32QPseudo,
3534 ARM::VLD1d64QPseudo };
3535 static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowQPseudo_UPD,
3536 ARM::VLD1q16LowQPseudo_UPD,
3537 ARM::VLD1q32LowQPseudo_UPD,
3538 ARM::VLD1q64LowQPseudo_UPD };
3539 static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighQPseudo,
3540 ARM::VLD1q16HighQPseudo,
3541 ARM::VLD1q32HighQPseudo,
3542 ARM::VLD1q64HighQPseudo };
3543 SelectVLD(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3548 static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16,
3549 ARM::VLD2d32, ARM::VLD1q64 };
3550 static const uint16_t QOpcodes[] = { ARM::VLD2q8Pseudo, ARM::VLD2q16Pseudo,
3551 ARM::VLD2q32Pseudo };
3552 SelectVLD(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3557 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo,
3560 ARM::VLD1d64TPseudo };
3561 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
3562 ARM::VLD3q16Pseudo_UPD,
3563 ARM::VLD3q32Pseudo_UPD };
3564 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo,
3565 ARM::VLD3q16oddPseudo,
3566 ARM::VLD3q32oddPseudo };
3567 SelectVLD(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3572 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo,
3575 ARM::VLD1d64QPseudo };
3576 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
3577 ARM::VLD4q16Pseudo_UPD,
3578 ARM::VLD4q32Pseudo_UPD };
3579 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo,
3580 ARM::VLD4q16oddPseudo,
3581 ARM::VLD4q32oddPseudo };
3582 SelectVLD(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3587 static const uint16_t DOpcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16,
3588 ARM::VLD2DUPd32, ARM::VLD1q64 };
3589 static const uint16_t QOpcodes0[] = { ARM::VLD2DUPq8EvenPseudo,
3590 ARM::VLD2DUPq16EvenPseudo,
3591 ARM::VLD2DUPq32EvenPseudo };
3592 static const uint16_t QOpcodes1[] = { ARM::VLD2DUPq8OddPseudo,
3593 ARM::VLD2DUPq16OddPseudo,
3594 ARM::VLD2DUPq32OddPseudo };
3595 SelectVLDDup(N,
true,
false, 2,
3596 DOpcodes, QOpcodes0, QOpcodes1);
3601 static const uint16_t DOpcodes[] = { ARM::VLD3DUPd8Pseudo,
3602 ARM::VLD3DUPd16Pseudo,
3603 ARM::VLD3DUPd32Pseudo,
3604 ARM::VLD1d64TPseudo };
3605 static const uint16_t QOpcodes0[] = { ARM::VLD3DUPq8EvenPseudo,
3606 ARM::VLD3DUPq16EvenPseudo,
3607 ARM::VLD3DUPq32EvenPseudo };
3608 static const uint16_t QOpcodes1[] = { ARM::VLD3DUPq8OddPseudo,
3609 ARM::VLD3DUPq16OddPseudo,
3610 ARM::VLD3DUPq32OddPseudo };
3611 SelectVLDDup(N,
true,
false, 3,
3612 DOpcodes, QOpcodes0, QOpcodes1);
3617 static const uint16_t DOpcodes[] = { ARM::VLD4DUPd8Pseudo,
3618 ARM::VLD4DUPd16Pseudo,
3619 ARM::VLD4DUPd32Pseudo,
3620 ARM::VLD1d64QPseudo };
3621 static const uint16_t QOpcodes0[] = { ARM::VLD4DUPq8EvenPseudo,
3622 ARM::VLD4DUPq16EvenPseudo,
3623 ARM::VLD4DUPq32EvenPseudo };
3624 static const uint16_t QOpcodes1[] = { ARM::VLD4DUPq8OddPseudo,
3625 ARM::VLD4DUPq16OddPseudo,
3626 ARM::VLD4DUPq32OddPseudo };
3627 SelectVLDDup(N,
true,
false, 4,
3628 DOpcodes, QOpcodes0, QOpcodes1);
3633 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo,
3634 ARM::VLD2LNd16Pseudo,
3635 ARM::VLD2LNd32Pseudo };
3636 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo,
3637 ARM::VLD2LNq32Pseudo };
3638 SelectVLDSTLane(N,
true,
false, 2, DOpcodes, QOpcodes);
3643 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo,
3644 ARM::VLD3LNd16Pseudo,
3645 ARM::VLD3LNd32Pseudo };
3646 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo,
3647 ARM::VLD3LNq32Pseudo };
3648 SelectVLDSTLane(N,
true,
false, 3, DOpcodes, QOpcodes);
3653 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo,
3654 ARM::VLD4LNd16Pseudo,
3655 ARM::VLD4LNd32Pseudo };
3656 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo,
3657 ARM::VLD4LNq32Pseudo };
3658 SelectVLDSTLane(N,
true,
false, 4, DOpcodes, QOpcodes);
3663 static const uint16_t DOpcodes[] = { ARM::VST1d8, ARM::VST1d16,
3664 ARM::VST1d32, ARM::VST1d64 };
3665 static const uint16_t QOpcodes[] = { ARM::VST1q8, ARM::VST1q16,
3666 ARM::VST1q32, ARM::VST1q64 };
3667 SelectVST(N,
false, 1, DOpcodes, QOpcodes,
nullptr);
3672 static const uint16_t DOpcodes[] = { ARM::VST1q8, ARM::VST1q16,
3673 ARM::VST1q32, ARM::VST1q64 };
3674 static const uint16_t QOpcodes[] = { ARM::VST1d8QPseudo,
3675 ARM::VST1d16QPseudo,
3676 ARM::VST1d32QPseudo,
3677 ARM::VST1d64QPseudo };
3678 SelectVST(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3683 static const uint16_t DOpcodes[] = { ARM::VST1d8TPseudo,
3684 ARM::VST1d16TPseudo,
3685 ARM::VST1d32TPseudo,
3686 ARM::VST1d64TPseudo };
3687 static const uint16_t QOpcodes0[] = { ARM::VST1q8LowTPseudo_UPD,
3688 ARM::VST1q16LowTPseudo_UPD,
3689 ARM::VST1q32LowTPseudo_UPD,
3690 ARM::VST1q64LowTPseudo_UPD };
3691 static const uint16_t QOpcodes1[] = { ARM::VST1q8HighTPseudo,
3692 ARM::VST1q16HighTPseudo,
3693 ARM::VST1q32HighTPseudo,
3694 ARM::VST1q64HighTPseudo };
3695 SelectVST(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3700 static const uint16_t DOpcodes[] = { ARM::VST1d8QPseudo,
3701 ARM::VST1d16QPseudo,
3702 ARM::VST1d32QPseudo,
3703 ARM::VST1d64QPseudo };
3704 static const uint16_t QOpcodes0[] = { ARM::VST1q8LowQPseudo_UPD,
3705 ARM::VST1q16LowQPseudo_UPD,
3706 ARM::VST1q32LowQPseudo_UPD,
3707 ARM::VST1q64LowQPseudo_UPD };
3708 static const uint16_t QOpcodes1[] = { ARM::VST1q8HighQPseudo,
3709 ARM::VST1q16HighQPseudo,
3710 ARM::VST1q32HighQPseudo,
3711 ARM::VST1q64HighQPseudo };
3712 SelectVST(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3717 static const uint16_t DOpcodes[] = { ARM::VST2d8, ARM::VST2d16,
3718 ARM::VST2d32, ARM::VST1q64 };
3719 static const uint16_t QOpcodes[] = { ARM::VST2q8Pseudo, ARM::VST2q16Pseudo,
3720 ARM::VST2q32Pseudo };
3721 SelectVST(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3726 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo,
3729 ARM::VST1d64TPseudo };
3730 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
3731 ARM::VST3q16Pseudo_UPD,
3732 ARM::VST3q32Pseudo_UPD };
3733 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo,
3734 ARM::VST3q16oddPseudo,
3735 ARM::VST3q32oddPseudo };
3736 SelectVST(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3741 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo,
3744 ARM::VST1d64QPseudo };
3745 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
3746 ARM::VST4q16Pseudo_UPD,
3747 ARM::VST4q32Pseudo_UPD };
3748 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo,
3749 ARM::VST4q16oddPseudo,
3750 ARM::VST4q32oddPseudo };
3751 SelectVST(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3756 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo,
3757 ARM::VST2LNd16Pseudo,
3758 ARM::VST2LNd32Pseudo };
3759 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo,
3760 ARM::VST2LNq32Pseudo };
3761 SelectVLDSTLane(N,
false,
false, 2, DOpcodes, QOpcodes);
3766 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo,
3767 ARM::VST3LNd16Pseudo,
3768 ARM::VST3LNd32Pseudo };
3769 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo,
3770 ARM::VST3LNq32Pseudo };
3771 SelectVLDSTLane(N,
false,
false, 3, DOpcodes, QOpcodes);
3776 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo,
3777 ARM::VST4LNd16Pseudo,
3778 ARM::VST4LNd32Pseudo };
3779 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo,
3780 ARM::VST4LNq32Pseudo };
3781 SelectVLDSTLane(N,
false,
false, 4, DOpcodes, QOpcodes);
3804 std::vector<SDValue> &Ops) {
3806 RegString.
split(Fields,
':');
3808 if (Fields.
size() > 1) {
3809 bool AllIntFields =
true;
3814 AllIntFields &= !
Field.trim(
"CPcp").getAsInteger(10, IntField);
3819 "Unexpected non-integer value in special register string.");
3829 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegString.
lower());
3832 return TheReg->Encoding;
3844 .
Case(
"nzcvqg", 0x3)
3852 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Reg);
3853 const FeatureBitset &FeatureBits = Subtarget->getFeatureBits();
3854 if (!TheReg || !TheReg->hasRequiredFeatures(FeatureBits))
3856 return (
int)(TheReg->Encoding & 0xFFF);
3865 if (Reg ==
"apsr") {
3875 if (Reg !=
"cpsr" && Reg !=
"spsr") {
3880 if (Flags.
empty() || Flags ==
"all")
3885 for (
char Flag : Flags) {
3905 if (!FlagVal || (Mask & FlagVal))
3920 bool ARMDAGToDAGISel::tryReadRegister(
SDNode *N){
3923 bool IsThumb2 = Subtarget->
isThumb2();
3926 std::vector<SDValue> Ops;
3936 if (Ops.size() == 5){
3937 Opcode = IsThumb2 ? ARM::t2MRC : ARM::MRC;
3940 assert(Ops.size() == 3 &&
3941 "Invalid number of fields in special register string.");
3942 Opcode = IsThumb2 ? ARM::t2MRRC : ARM::MRRC;
3946 Ops.push_back(
getAL(CurDAG, DL));
3947 Ops.push_back(CurDAG->getRegister(0,
MVT::i32));
3949 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL, ResTypes, Ops));
3953 std::string SpecialReg = RegString->getString().lower();
3956 if (BankedReg != -1) {
3957 Ops = { CurDAG->getTargetConstant(BankedReg, DL,
MVT::i32),
3961 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSbanked : ARM::MRSbanked,
3970 .Case(
"fpscr", ARM::VMRS)
3971 .
Case(
"fpexc", ARM::VMRS_FPEXC)
3972 .
Case(
"fpsid", ARM::VMRS_FPSID)
3973 .
Case(
"mvfr0", ARM::VMRS_MVFR0)
3974 .
Case(
"mvfr1", ARM::VMRS_MVFR1)
3975 .
Case(
"mvfr2", ARM::VMRS_MVFR2)
3976 .
Case(
"fpinst", ARM::VMRS_FPINST)
3977 .
Case(
"fpinst2", ARM::VMRS_FPINST2)
3984 if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->
hasFPARMv8())
3987 Ops = {
getAL(CurDAG, DL), CurDAG->getRegister(0,
MVT::i32),
3999 if (SYSmValue == -1)
4012 if (SpecialReg ==
"apsr" || SpecialReg ==
"cpsr") {
4013 Ops = {
getAL(CurDAG, DL), CurDAG->getRegister(0,
MVT::i32),
4015 ReplaceNode(N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRS_AR : ARM::MRS,
4020 if (SpecialReg ==
"spsr") {
4021 Ops = {
getAL(CurDAG, DL), CurDAG->getRegister(0,
MVT::i32),
4024 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSsys_AR : ARM::MRSsys, DL,
4035 bool ARMDAGToDAGISel::tryWriteRegister(
SDNode *N){
4038 bool IsThumb2 = Subtarget->
isThumb2();
4041 std::vector<SDValue> Ops;
4050 if (Ops.size() == 5) {
4051 Opcode = IsThumb2 ? ARM::t2MCR : ARM::MCR;
4054 assert(Ops.size() == 3 &&
4055 "Invalid number of fields in special register string.");
4056 Opcode = IsThumb2 ? ARM::t2MCRR : ARM::MCRR;
4058 Ops.insert(Ops.begin()+2, WriteValue, WriteValue+2);
4061 Ops.push_back(
getAL(CurDAG, DL));
4062 Ops.push_back(CurDAG->getRegister(0,
MVT::i32));
4065 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL,
MVT::Other, Ops));
4069 std::string SpecialReg = RegString->getString().lower();
4071 if (BankedReg != -1) {
4076 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSRbanked : ARM::MSRbanked,
4085 .Case(
"fpscr", ARM::VMSR)
4086 .
Case(
"fpexc", ARM::VMSR_FPEXC)
4087 .
Case(
"fpsid", ARM::VMSR_FPSID)
4088 .
Case(
"fpinst", ARM::VMSR_FPINST)
4089 .
Case(
"fpinst2", ARM::VMSR_FPINST2)
4097 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL,
MVT::Other, Ops));
4101 std::pair<StringRef, StringRef> Fields;
4103 std::string
Reg = Fields.first.str();
4110 if (SYSmValue == -1)
4116 ReplaceNode(N, CurDAG->getMachineNode(ARM::t2MSR_M, DL,
MVT::Other, Ops));
4128 ReplaceNode(N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSR_AR : ARM::MSR,
4136 bool ARMDAGToDAGISel::tryInlineAsm(
SDNode *N){
4137 std::vector<SDValue> AsmNodeOperands;
4139 bool Changed =
false;
4156 for(
unsigned i = 0, e = N->
getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) {
4158 AsmNodeOperands.push_back(op);
4164 Flag =
C->getZExtValue();
4176 AsmNodeOperands.push_back(op);
4184 unsigned DefIdx = 0;
4185 bool IsTiedToChangedOp =
false;
4189 IsTiedToChangedOp = OpChanged[DefIdx];
4198 AsmNodeOperands.push_back(op);
4208 if ((!IsTiedToChangedOp && (!HasRC || RC != ARM::GPRRegClassID))
4212 assert((i+2 < NumOps) &&
"Invalid number of operands in inline asm");
4215 unsigned Reg0 = cast<RegisterSDNode>(V0)->
getReg();
4216 unsigned Reg1 = cast<RegisterSDNode>(V1)->
getReg();
4234 SDValue Sub0 = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl,
MVT::i32,
4236 SDValue Sub1 = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl,
MVT::i32,
4238 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
4245 CurDAG->UpdateNodeOperands(GU, Ops);
4263 Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.
getValue(1));
4272 OpChanged[OpChanged.
size() -1 ] =
true;
4274 if (IsTiedToChangedOp)
4279 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
4282 AsmNodeOperands.push_back(PairedReg);
4289 AsmNodeOperands.push_back(Glue);
4296 ReplaceNode(N, New.
getNode());
4301 bool ARMDAGToDAGISel::
4302 SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
4303 std::vector<SDValue> &OutOps) {
4304 switch(ConstraintID) {
4324 OutOps.push_back(Op);
4335 return new ARMDAGToDAGISel(TM, OptLevel);
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
EVT getValueType() const
Return the ValueType of the referenced return value.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const SDValue & getOffset() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
This class represents lattice values for constants.
static int getARClassRegisterMask(StringRef Reg, StringRef Flags)
const SDValue & getBasePtr() const
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
Describe properties that are true of each instruction in the target description file.
SDVTList getVTList() const
static Optional< std::pair< unsigned, unsigned > > getContiguousRangeOfSetBits(const APInt &A)
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
const SDValue & getChain() const
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
unsigned getAlignment() const
static bool isVSTfixed(unsigned Opc)
LLVM_NODISCARD std::pair< StringRef, StringRef > rsplit(StringRef Separator) const
Split into two substrings around the last occurrence of a separator string.
bool isSOImmTwoPartVal(unsigned V)
isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVa...
const MDOperand & getOperand(unsigned I) const
unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
static bool isScaledConstantInRange(SDValue Node, int Scale, int RangeMin, int RangeMax, int &ScaledConstant)
Check whether a particular node is a constant value representable as (N * Scale) where (N in [RangeMi...
bool isThumb1Only() const
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
static bool isThumb(const MCSubtargetInfo &STI)
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
isUseOperandTiedToDef - Return true if the flag of the inline asm operand indicates it is an use oper...
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...
bool hasV8MBaselineOps() const
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
bool hasOneUse() const
Return true if there is exactly one use of this node.
bool isFpMLxInstruction(unsigned Opcode) const
isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS instruction.
A description of a memory reference used in the backend.
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
getFlagWordForRegClass - Augment an existing flag word returned by getFlagWord with the required regi...
const HexagonInstrInfo * TII
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.
Base class for LoadSDNode and StoreSDNode.
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth...
A Use represents the edge between a Value definition and its users.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
const MDNode * getMD() const
op_iterator op_end() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static ShiftOpc getShiftOpcForNode(unsigned Opcode)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
INLINEASM - Represents an inline asm block.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
unsigned getScalarSizeInBits() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
bool useMovt(const MachineFunction &MF) const
static bool isVLDfixed(unsigned Opc)
Simple integer binary arithmetic operators.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
op_iterator op_begin() const
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
A switch()-like statement whose cases are string literals.
initializer< Ty > init(const Ty &Val)
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
Container class for subtarget features.
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...
static int getBankedRegisterMask(StringRef RegString)
unsigned countPopulation() const
Count the number of bits set.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc)
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
bool isThumbImmShiftedVal(unsigned V)
isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit im...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< bool > DisableShifterOp("disable-shifter-op", cl::Hidden, cl::desc("Disable isel of shifter-op"), cl::init(false))
SDNode * getGluedUser() const
If this node has a glue value with a user, return the user (there is at most one).
const SDValue & getOperand(unsigned Num) const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
static unsigned getKind(unsigned Flags)
FunctionPass class - This class is used to implement most global optimizations.
int getT2SOImmValSplatVal(unsigned V)
getT2SOImmValSplat - Return the 12-bit encoded representation if the specified value can be obtained ...
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
self_iterator getIterator()
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
static SDValue getAL(SelectionDAG *CurDAG, const SDLoc &dl)
getAL - Returns a ARMCC::AL immediate node.
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.
Iterator for intrusive lists based on ilist_node.
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
static SDValue createGPRPairNode(SelectionDAG &DAG, SDValue V)
unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset)
getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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.
This is an abstract virtual class for memory operations.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
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.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT...
EVT getMemoryVT() const
Return the type of the in-memory value.
Class for arbitrary precision integers.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool mayStore() const
Return true if this instruction could possibly modify memory.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
int getNodeId() const
Return the unique node id.
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
const SDValue & getValue() const
Bitwise operators - logical and, logical or, logical xor.
static IntegerType * getInt32Ty(LLVMContext &C)
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
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 int getMClassRegisterMask(StringRef Reg, const ARMSubtarget *Subtarget)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getOpcode() const
SDValue getValue(unsigned R) const
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
FunctionPass * createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOpt::Level OptLevel)
createARMISelDag - This pass converts a legalized DAG into a ARM-specific DAG, ready for instruction ...
bool hasVMLxHazards() const
LLVM_NODISCARD std::string lower() const
This class is used to form a handle around another node that is persistent and is updated across invo...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
static void getIntOperandsFromRegisterString(StringRef RegString, SelectionDAG *CurDAG, const SDLoc &DL, std::vector< SDValue > &Ops)
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.
unsigned getOpcode() const
Return the opcode number for this descriptor.
static bool isPerfectIncrement(SDValue Inc, EVT VecTy, unsigned NumVecs)
Returns true if the given increment is a Constant known to be equal to the access size performed by a...
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.
static int getMClassFlagsMask(StringRef Flags)
unsigned countLeadingZeros() const
The APInt version of the countLeadingZeros functions in MathExtras.h.
const SDValue & getOperand(unsigned i) const
uint64_t getZExtValue() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
void setObjectAlignment(int ObjectIdx, unsigned Align)
setObjectAlignment - Change the alignment of the specified stack object.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
This file describes how to lower LLVM code to machine code.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
This class is used to represent ISD::LOAD nodes.