39 #define DEBUG_TYPE "arm-isel" 43 cl::desc(
"Disable isel of shifter-op"),
68 StringRef getPassName()
const override {
return "ARM Instruction Selection"; }
70 void PreprocessISelDAG()
override;
74 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
75 return CurDAG->getTargetConstant(Imm, dl,
MVT::i32);
80 bool hasNoVMLxHazardUse(
SDNode *
N)
const;
81 bool isShifterOpProfitable(
const SDValue &Shift,
85 bool CheckProfitability =
true);
87 SDValue &
B,
bool CheckProfitability =
true);
91 return SelectRegShifterOperand(N, A, B, C,
false);
96 return SelectImmShifterOperand(N, A, B,
false);
107 Reg = CurDAG->getRegister(ARM::CPSR,
MVT::i32);
123 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;
459 if (Val <= 510)
return 2;
460 if (~Val <= 255)
return 2;
465 if (Subtarget->
hasV6T2Ops() && Val <= 0xffff)
return 1;
468 if (Subtarget->
useMovt())
return 2;
472 bool ARMDAGToDAGISel::canExtractShiftFromMul(
const SDValue &N,
474 unsigned &PowerOfTwo,
484 if (!MulConst)
return false;
487 if (!MulConst->
hasOneUse())
return false;
489 if (MulConstVal == 0)
return false;
492 PowerOfTwo = MaxShift;
493 while ((MulConstVal % (1 << PowerOfTwo)) != 0) {
495 if (PowerOfTwo == 0)
return false;
499 unsigned NewMulConstVal = MulConstVal / (1 << PowerOfTwo);
500 NewMulConst = CurDAG->getConstant(NewMulConstVal,
SDLoc(N),
MVT::i32);
501 unsigned OldCost = ConstantMaterializationCost(MulConstVal);
502 unsigned NewCost = ConstantMaterializationCost(NewMulConstVal);
503 return NewCost < OldCost;
506 void ARMDAGToDAGISel::replaceDAGValue(
const SDValue &N,
SDValue M) {
511 bool ARMDAGToDAGISel::SelectImmShifterOperand(
SDValue N,
514 bool CheckProfitability) {
521 unsigned PowerOfTwo = 0;
523 if (canExtractShiftFromMul(N, 31, PowerOfTwo, NewMulConst)) {
526 replaceDAGValue(N.
getOperand(1), NewMulConst);
528 Opc = CurDAG->getTargetConstant(
541 unsigned ShImmVal = 0;
543 if (!RHS)
return false;
550 bool ARMDAGToDAGISel::SelectRegShifterOperand(
SDValue N,
554 bool CheckProfitability) {
565 unsigned ShImmVal = 0;
567 if (RHS)
return false;
570 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal))
582 return CurDAG->haveNoCommonBitsSet(N, Parent->
getOperand(1));
586 bool ARMDAGToDAGISel::SelectAddrModeImm12(
SDValue N,
593 !CurDAG->isBaseWithConstantOffset(N)) {
596 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
597 Base = CurDAG->getTargetFrameIndex(
598 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
615 int RHSC = (int)RHS->getSExtValue();
619 if (RHSC > -0x1000 && RHSC < 0x1000) {
622 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
623 Base = CurDAG->getTargetFrameIndex(
624 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
626 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
645 int RHSC = (int)RHS->getZExtValue();
654 unsigned ShAmt =
Log2_32(RHSC);
667 !CurDAG->isBaseWithConstantOffset(N))
674 -0x1000+1, 0x1000, RHSC))
692 ShAmt = Sh->getZExtValue();
693 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
714 ShAmt = Sh->getZExtValue();
715 if (isShifterOpProfitable(N.
getOperand(0), ShOpcVal, ShAmt)) {
731 unsigned PowerOfTwo = 0;
733 if (canExtractShiftFromMul(Offset, 31, PowerOfTwo, NewMulConst)) {
735 replaceDAGValue(Offset.
getOperand(1), NewMulConst);
751 ? cast<LoadSDNode>(Op)->getAddressingMode()
752 : cast<StoreSDNode>(
Op)->getAddressingMode();
766 ShAmt = Sh->getZExtValue();
767 if (isShifterOpProfitable(N, ShOpcVal, ShAmt))
783 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(
SDNode *Op,
SDValue N,
787 ? cast<LoadSDNode>(Op)->getAddressingMode()
788 : cast<StoreSDNode>(
Op)->getAddressingMode();
794 Offset = CurDAG->getRegister(0,
MVT::i32);
803 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(
SDNode *Op,
SDValue N,
807 ? cast<LoadSDNode>(Op)->getAddressingMode()
808 : cast<StoreSDNode>(
Op)->getAddressingMode();
813 Offset = CurDAG->getRegister(0,
MVT::i32);
823 bool ARMDAGToDAGISel::SelectAddrOffsetNone(
SDValue N,
SDValue &Base) {
828 bool ARMDAGToDAGISel::SelectAddrMode3(
SDValue N,
840 if (!CurDAG->isBaseWithConstantOffset(N)) {
843 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
844 Base = CurDAG->getTargetFrameIndex(
845 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
847 Offset = CurDAG->getRegister(0,
MVT::i32);
856 -256 + 1, 256, RHSC)) {
859 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
860 Base = CurDAG->getTargetFrameIndex(
861 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
863 Offset = CurDAG->getRegister(0,
MVT::i32);
882 bool ARMDAGToDAGISel::SelectAddrMode3Offset(
SDNode *Op,
SDValue N,
886 ? cast<LoadSDNode>(Op)->getAddressingMode()
887 : cast<StoreSDNode>(
Op)->getAddressingMode();
892 Offset = CurDAG->getRegister(0,
MVT::i32);
905 int Lwb,
int Upb,
bool FP16) {
906 if (!CurDAG->isBaseWithConstantOffset(N)) {
909 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
910 Base = CurDAG->getTargetFrameIndex(
911 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
925 const int Scale = FP16 ? 2 : 4;
930 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
931 Base = CurDAG->getTargetFrameIndex(
932 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
963 bool ARMDAGToDAGISel::SelectAddrMode5(
SDValue N,
967 return IsAddressingMode5(N, Base, Offset, Lwb, Upb,
false);
970 bool ARMDAGToDAGISel::SelectAddrMode5FP16(
SDValue N,
974 return IsAddressingMode5(N, Base, Offset, Lwb, Upb,
true);
981 unsigned Alignment = 0;
983 MemSDNode *MemN = cast<MemSDNode>(Parent);
985 if (isa<LSBaseSDNode>(MemN) ||
993 if (MMOAlign >= MemSize && MemSize > 1)
1002 Align = CurDAG->getTargetConstant(Alignment,
SDLoc(N),
MVT::i32);
1006 bool ARMDAGToDAGISel::SelectAddrMode6Offset(
SDNode *Op,
SDValue N,
1015 Offset = CurDAG->getRegister(0,
MVT::i32);
1020 bool ARMDAGToDAGISel::SelectAddrModePC(
SDValue N,
1025 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
1046 if (
auto C = dyn_cast<ConstantSDNode>(N.
getOperand(1)))
1047 return C->getSExtValue() < 0 &&
C->getSExtValue() >= -255;
1052 bool ARMDAGToDAGISel::SelectThumbAddrModeRRSext(
SDValue N,
SDValue &Base,
1068 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(
SDValue N,
SDValue &Base,
1072 return SelectThumbAddrModeRRSext(N, Base, Offset);
1076 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(
SDValue N,
unsigned Scale,
1084 if (!CurDAG->isBaseWithConstantOffset(N)) {
1105 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1114 ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(
SDValue N,
SDValue &Base,
1116 return SelectThumbAddrModeImm5S(N, 4, Base, OffImm);
1120 ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(
SDValue N,
SDValue &Base,
1122 return SelectThumbAddrModeImm5S(N, 2, Base, OffImm);
1126 ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(
SDValue N,
SDValue &Base,
1128 return SelectThumbAddrModeImm5S(N, 1, Base, OffImm);
1131 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(
SDValue N,
1134 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1140 Base = CurDAG->getTargetFrameIndex(
1141 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1146 if (!CurDAG->isBaseWithConstantOffset(N))
1151 (LHSR && LHSR->
getReg() == ARM::SP)) {
1157 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1163 Base = CurDAG->getTargetFrameIndex(
1164 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1166 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1180 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(
SDValue N,
1186 !CurDAG->isBaseWithConstantOffset(N)) {
1189 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1190 Base = CurDAG->getTargetFrameIndex(
1191 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1210 if (SelectT2AddrModeImm8(N, Base, OffImm))
1214 int RHSC = (int)RHS->getZExtValue();
1218 if (RHSC >= 0 && RHSC < 0x1000) {
1221 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1222 Base = CurDAG->getTargetFrameIndex(
1223 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1225 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1236 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(
SDValue N,
1240 !CurDAG->isBaseWithConstantOffset(N))
1244 int RHSC = (int)RHS->getSExtValue();
1248 if ((RHSC >= -255) && (RHSC < 0)) {
1251 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1252 Base = CurDAG->getTargetFrameIndex(
1253 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1255 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(N),
MVT::i32);
1263 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(
SDNode *Op,
SDValue N,
1267 ? cast<LoadSDNode>(Op)->getAddressingMode()
1268 : cast<StoreSDNode>(
Op)->getAddressingMode();
1280 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(
SDValue N,
1289 int RHSC = (int)RHS->getZExtValue();
1290 if (RHSC >= 0 && RHSC < 0x1000)
1292 else if (RHSC < 0 && RHSC >= -255)
1313 ShAmt = Sh->getZExtValue();
1314 if (ShAmt < 4 && isShifterOpProfitable(OffReg, ShOpcVal, ShAmt))
1325 unsigned PowerOfTwo = 0;
1327 if (canExtractShiftFromMul(OffReg, 3, PowerOfTwo, NewMulConst)) {
1329 replaceDAGValue(OffReg.
getOperand(1), NewMulConst);
1335 ShImm = CurDAG->getTargetConstant(ShAmt,
SDLoc(N),
MVT::i32);
1340 bool ARMDAGToDAGISel::SelectT2AddrModeExclusive(
SDValue N,
SDValue &Base,
1355 if (RHSC > 1020 || RHSC % 4 != 0)
1360 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1361 Base = CurDAG->getTargetFrameIndex(
1362 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1365 OffImm = CurDAG->getTargetConstant(RHSC/4,
SDLoc(N),
MVT::i32);
1376 void ARMDAGToDAGISel::transferMemOperands(
SDNode *N,
SDNode *Result) {
1378 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Result), {MemOp});
1381 bool ARMDAGToDAGISel::tryARMIndexedLoad(
SDNode *N) {
1390 unsigned Opcode = 0;
1392 if (LoadedVT ==
MVT::i32 && isPre &&
1394 Opcode = ARM::LDR_PRE_IMM;
1396 }
else if (LoadedVT ==
MVT::i32 && !isPre &&
1398 Opcode = ARM::LDR_POST_IMM;
1402 Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG;
1409 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
1410 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
1415 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
1421 Opcode = ARM::LDRB_PRE_IMM;
1422 }
else if (!isPre &&
1425 Opcode = ARM::LDRB_POST_IMM;
1426 }
else if (SelectAddrMode2OffsetReg(N, LD->
getOffset(),
Offset, AMOpc)) {
1428 Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG;
1434 if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) {
1438 CurDAG->getRegister(0,
MVT::i32), Chain };
1441 transferMemOperands(N, New);
1442 ReplaceNode(N, New);
1448 CurDAG->getRegister(0,
MVT::i32), Chain };
1451 transferMemOperands(N, New);
1452 ReplaceNode(N, New);
1460 bool ARMDAGToDAGISel::tryT1IndexedLoad(
SDNode *N) {
1465 LoadedVT.getSimpleVT().SimpleTy !=
MVT::i32)
1469 if (!COffs || COffs->getZExtValue() != 4)
1479 CurDAG->getRegister(0,
MVT::i32), Chain };
1482 transferMemOperands(N, New);
1483 ReplaceNode(N, New);
1487 bool ARMDAGToDAGISel::tryT2IndexedLoad(
SDNode *N) {
1497 unsigned Opcode = 0;
1502 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST;
1506 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST;
1508 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST;
1513 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST;
1515 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST;
1527 CurDAG->getRegister(0,
MVT::i32), Chain };
1530 transferMemOperands(N, New);
1531 ReplaceNode(N, New);
1542 CurDAG->getTargetConstant(ARM::GPRPairRegClassID, dl,
MVT::i32);
1543 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::gsub_0, dl,
MVT::i32);
1544 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::gsub_1, dl,
MVT::i32);
1545 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1546 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1553 CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, dl,
MVT::i32);
1554 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl,
MVT::i32);
1555 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl,
MVT::i32);
1556 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1557 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1563 SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, dl,
1565 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl,
MVT::i32);
1566 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl,
MVT::i32);
1567 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1568 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1574 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl,
1576 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl,
MVT::i32);
1577 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl,
MVT::i32);
1578 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1579 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1587 CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, dl,
MVT::i32);
1588 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl,
MVT::i32);
1589 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl,
MVT::i32);
1590 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, dl,
MVT::i32);
1591 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, dl,
MVT::i32);
1592 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1593 V2, SubReg2, V3, SubReg3 };
1594 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1601 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl,
1603 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl,
MVT::i32);
1604 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl,
MVT::i32);
1605 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, dl,
MVT::i32);
1606 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, dl,
MVT::i32);
1607 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1608 V2, SubReg2, V3, SubReg3 };
1609 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1616 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, dl,
1618 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl,
MVT::i32);
1619 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl,
MVT::i32);
1620 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, dl,
MVT::i32);
1621 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, dl,
MVT::i32);
1622 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1623 V2, SubReg2, V3, SubReg3 };
1624 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
1631 unsigned NumVecs,
bool is64BitVector) {
1632 unsigned NumRegs = NumVecs;
1633 if (!is64BitVector && NumVecs < 3)
1636 unsigned Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
1637 if (Alignment >= 32 && NumRegs == 4)
1639 else if (Alignment >= 16 && (NumRegs == 2 || NumRegs == 4))
1641 else if (Alignment >= 8)
1646 return CurDAG->getTargetConstant(Alignment, dl,
MVT::i32);
1652 default:
return false;
1653 case ARM::VLD1d8wb_fixed :
return true;
1654 case ARM::VLD1d16wb_fixed :
return true;
1655 case ARM::VLD1d64Qwb_fixed :
return true;
1656 case ARM::VLD1d32wb_fixed :
return true;
1657 case ARM::VLD1d64wb_fixed :
return true;
1658 case ARM::VLD1d64TPseudoWB_fixed :
return true;
1659 case ARM::VLD1d64QPseudoWB_fixed :
return true;
1660 case ARM::VLD1q8wb_fixed :
return true;
1661 case ARM::VLD1q16wb_fixed :
return true;
1662 case ARM::VLD1q32wb_fixed :
return true;
1663 case ARM::VLD1q64wb_fixed :
return true;
1664 case ARM::VLD1DUPd8wb_fixed :
return true;
1665 case ARM::VLD1DUPd16wb_fixed :
return true;
1666 case ARM::VLD1DUPd32wb_fixed :
return true;
1667 case ARM::VLD1DUPq8wb_fixed :
return true;
1668 case ARM::VLD1DUPq16wb_fixed :
return true;
1669 case ARM::VLD1DUPq32wb_fixed :
return true;
1670 case ARM::VLD2d8wb_fixed :
return true;
1671 case ARM::VLD2d16wb_fixed :
return true;
1672 case ARM::VLD2d32wb_fixed :
return true;
1673 case ARM::VLD2q8PseudoWB_fixed :
return true;
1674 case ARM::VLD2q16PseudoWB_fixed :
return true;
1675 case ARM::VLD2q32PseudoWB_fixed :
return true;
1676 case ARM::VLD2DUPd8wb_fixed :
return true;
1677 case ARM::VLD2DUPd16wb_fixed :
return true;
1678 case ARM::VLD2DUPd32wb_fixed :
return true;
1685 default:
return false;
1686 case ARM::VST1d8wb_fixed :
return true;
1687 case ARM::VST1d16wb_fixed :
return true;
1688 case ARM::VST1d32wb_fixed :
return true;
1689 case ARM::VST1d64wb_fixed :
return true;
1690 case ARM::VST1q8wb_fixed :
return true;
1691 case ARM::VST1q16wb_fixed :
return true;
1692 case ARM::VST1q32wb_fixed :
return true;
1693 case ARM::VST1q64wb_fixed :
return true;
1694 case ARM::VST1d64TPseudoWB_fixed :
return true;
1695 case ARM::VST1d64QPseudoWB_fixed :
return true;
1696 case ARM::VST2d8wb_fixed :
return true;
1697 case ARM::VST2d16wb_fixed :
return true;
1698 case ARM::VST2d32wb_fixed :
return true;
1699 case ARM::VST2q8PseudoWB_fixed :
return true;
1700 case ARM::VST2q16PseudoWB_fixed :
return true;
1701 case ARM::VST2q32PseudoWB_fixed :
return true;
1709 &&
"Incorrect fixed stride updating instruction.");
1712 case ARM::VLD1d8wb_fixed:
return ARM::VLD1d8wb_register;
1713 case ARM::VLD1d16wb_fixed:
return ARM::VLD1d16wb_register;
1714 case ARM::VLD1d32wb_fixed:
return ARM::VLD1d32wb_register;
1715 case ARM::VLD1d64wb_fixed:
return ARM::VLD1d64wb_register;
1716 case ARM::VLD1q8wb_fixed:
return ARM::VLD1q8wb_register;
1717 case ARM::VLD1q16wb_fixed:
return ARM::VLD1q16wb_register;
1718 case ARM::VLD1q32wb_fixed:
return ARM::VLD1q32wb_register;
1719 case ARM::VLD1q64wb_fixed:
return ARM::VLD1q64wb_register;
1720 case ARM::VLD1d64Twb_fixed:
return ARM::VLD1d64Twb_register;
1721 case ARM::VLD1d64Qwb_fixed:
return ARM::VLD1d64Qwb_register;
1722 case ARM::VLD1d64TPseudoWB_fixed:
return ARM::VLD1d64TPseudoWB_register;
1723 case ARM::VLD1d64QPseudoWB_fixed:
return ARM::VLD1d64QPseudoWB_register;
1724 case ARM::VLD1DUPd8wb_fixed :
return ARM::VLD1DUPd8wb_register;
1725 case ARM::VLD1DUPd16wb_fixed :
return ARM::VLD1DUPd16wb_register;
1726 case ARM::VLD1DUPd32wb_fixed :
return ARM::VLD1DUPd32wb_register;
1727 case ARM::VLD1DUPq8wb_fixed :
return ARM::VLD1DUPq8wb_register;
1728 case ARM::VLD1DUPq16wb_fixed :
return ARM::VLD1DUPq16wb_register;
1729 case ARM::VLD1DUPq32wb_fixed :
return ARM::VLD1DUPq32wb_register;
1731 case ARM::VST1d8wb_fixed:
return ARM::VST1d8wb_register;
1732 case ARM::VST1d16wb_fixed:
return ARM::VST1d16wb_register;
1733 case ARM::VST1d32wb_fixed:
return ARM::VST1d32wb_register;
1734 case ARM::VST1d64wb_fixed:
return ARM::VST1d64wb_register;
1735 case ARM::VST1q8wb_fixed:
return ARM::VST1q8wb_register;
1736 case ARM::VST1q16wb_fixed:
return ARM::VST1q16wb_register;
1737 case ARM::VST1q32wb_fixed:
return ARM::VST1q32wb_register;
1738 case ARM::VST1q64wb_fixed:
return ARM::VST1q64wb_register;
1739 case ARM::VST1d64TPseudoWB_fixed:
return ARM::VST1d64TPseudoWB_register;
1740 case ARM::VST1d64QPseudoWB_fixed:
return ARM::VST1d64QPseudoWB_register;
1742 case ARM::VLD2d8wb_fixed:
return ARM::VLD2d8wb_register;
1743 case ARM::VLD2d16wb_fixed:
return ARM::VLD2d16wb_register;
1744 case ARM::VLD2d32wb_fixed:
return ARM::VLD2d32wb_register;
1745 case ARM::VLD2q8PseudoWB_fixed:
return ARM::VLD2q8PseudoWB_register;
1746 case ARM::VLD2q16PseudoWB_fixed:
return ARM::VLD2q16PseudoWB_register;
1747 case ARM::VLD2q32PseudoWB_fixed:
return ARM::VLD2q32PseudoWB_register;
1749 case ARM::VST2d8wb_fixed:
return ARM::VST2d8wb_register;
1750 case ARM::VST2d16wb_fixed:
return ARM::VST2d16wb_register;
1751 case ARM::VST2d32wb_fixed:
return ARM::VST2d32wb_register;
1752 case ARM::VST2q8PseudoWB_fixed:
return ARM::VST2q8PseudoWB_register;
1753 case ARM::VST2q16PseudoWB_fixed:
return ARM::VST2q16PseudoWB_register;
1754 case ARM::VST2q32PseudoWB_fixed:
return ARM::VST2q32PseudoWB_register;
1756 case ARM::VLD2DUPd8wb_fixed:
return ARM::VLD2DUPd8wb_register;
1757 case ARM::VLD2DUPd16wb_fixed:
return ARM::VLD2DUPd16wb_register;
1758 case ARM::VLD2DUPd32wb_fixed:
return ARM::VLD2DUPd32wb_register;
1771 void ARMDAGToDAGISel::SelectVLD(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
1772 const uint16_t *DOpcodes,
1773 const uint16_t *QOpcodes0,
1774 const uint16_t *QOpcodes1) {
1775 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VLD NumVecs out-of-range");
1779 bool IsIntrinsic = !isUpdating;
1781 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
1788 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector);
1814 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
1819 std::vector<EVT> ResTys;
1820 ResTys.push_back(ResTy);
1831 if (is64BitVector || NumVecs <= 2) {
1832 unsigned Opc = (is64BitVector ? DOpcodes[
OpcodeIndex] :
1853 VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1863 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0);
1864 const SDValue OpsA[] = { MemAddr,
Align, Reg0, ImplDef, Pred, Reg0, Chain };
1865 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
1875 "only constant post-increment update allowed for VLD3/4");
1883 VLd = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, Ops);
1888 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLd), {MemOp});
1891 ReplaceNode(N, VLd);
1897 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7 &&
1898 ARM::qsub_3 == ARM::qsub_0 + 3,
1899 "Unexpected subreg numbering");
1900 unsigned Sub0 = (is64BitVector ? ARM::dsub_0 : ARM::qsub_0);
1901 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
1903 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
1907 CurDAG->RemoveDeadNode(N);
1910 void ARMDAGToDAGISel::SelectVST(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
1911 const uint16_t *DOpcodes,
1912 const uint16_t *QOpcodes0,
1913 const uint16_t *QOpcodes1) {
1914 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VST NumVecs out-of-range");
1918 bool IsIntrinsic = !isUpdating;
1920 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
1921 unsigned Vec0Idx = 3;
1930 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector);
1952 std::vector<EVT> ResTys;
1962 if (is64BitVector || NumVecs <= 2) {
1966 }
else if (is64BitVector) {
1977 ?
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
1988 unsigned Opc = (is64BitVector ? DOpcodes[
OpcodeIndex] :
2011 SDNode *VSt = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2014 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VSt), {MemOp});
2016 ReplaceNode(N, VSt);
2028 ?
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
2034 const SDValue OpsA[] = { MemAddr,
Align, Reg0, RegSeq, Pred, Reg0, Chain };
2035 SDNode *VStA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
2038 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VStA), {MemOp});
2047 "only constant post-increment update allowed for VST3/4");
2055 SDNode *VStB = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys,
2057 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VStB), {MemOp});
2058 ReplaceNode(N, VStB);
2061 void ARMDAGToDAGISel::SelectVLDSTLane(
SDNode *N,
bool IsLoad,
bool isUpdating,
2063 const uint16_t *DOpcodes,
2064 const uint16_t *QOpcodes) {
2065 assert(NumVecs >=2 && NumVecs <= 4 &&
"VLDSTLane NumVecs out-of-range");
2069 bool IsIntrinsic = !isUpdating;
2071 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
2072 unsigned Vec0Idx = 3;
2080 cast<ConstantSDNode>(N->
getOperand(Vec0Idx + NumVecs))->getZExtValue();
2084 unsigned Alignment = 0;
2086 Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
2088 if (Alignment > NumBytes)
2089 Alignment = NumBytes;
2090 if (Alignment < 8 && Alignment < NumBytes)
2093 Alignment = (Alignment & -Alignment);
2097 Align = CurDAG->getTargetConstant(Alignment, dl,
MVT::i32);
2113 std::vector<EVT> ResTys;
2115 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
2135 Ops.
push_back(IsImmUpdate ? Reg0 : Inc);
2149 ?
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
2162 unsigned Opc = (is64BitVector ? DOpcodes[
OpcodeIndex] :
2164 SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2165 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLdLn), {MemOp});
2167 ReplaceNode(N, VLdLn);
2173 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7 &&
2174 ARM::qsub_3 == ARM::qsub_0 + 3,
2175 "Unexpected subreg numbering");
2176 unsigned Sub0 = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
2177 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
2179 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
2183 CurDAG->RemoveDeadNode(N);
2186 void ARMDAGToDAGISel::SelectVLDDup(
SDNode *N,
bool IsIntrinsic,
2187 bool isUpdating,
unsigned NumVecs,
2188 const uint16_t *DOpcodes,
2189 const uint16_t *QOpcodes0,
2190 const uint16_t *QOpcodes1) {
2191 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VLDDup NumVecs out-of-range");
2195 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1;
2203 unsigned Alignment = 0;
2205 Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
2207 if (Alignment > NumBytes)
2208 Alignment = NumBytes;
2209 if (Alignment < 8 && Alignment < NumBytes)
2212 Alignment = (Alignment & -Alignment);
2216 Align = CurDAG->getTargetConstant(Alignment, dl,
MVT::i32);
2233 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
2238 std::vector<EVT> ResTys;
2239 ResTys.push_back(ResTy);
2248 if (is64BitVector || NumVecs == 1) {
2252 unsigned Opc = is64BitVector ? DOpcodes[
OpcodeIndex] :
2260 if (NumVecs <= 2 && !IsImmUpdate)
2265 else if (NumVecs > 2)
2271 VLdDup = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2272 }
else if (NumVecs == 2) {
2273 const SDValue OpsA[] = { MemAddr,
Align, Pred, Reg0, Chain };
2274 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex],
2278 const SDValue OpsB[] = { MemAddr,
Align, Pred, Reg0, Chain };
2279 VLdDup = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, OpsB);
2282 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0);
2283 const SDValue OpsA[] = { MemAddr,
Align, ImplDef, Pred, Reg0, Chain };
2284 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex],
2289 const SDValue OpsB[] = { MemAddr,
Align, SuperReg, Pred, Reg0, Chain };
2290 VLdDup = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, OpsB);
2295 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLdDup), {MemOp});
2302 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7,
"Unexpected subreg numbering");
2303 unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
2304 for (
unsigned Vec = 0; Vec != NumVecs; ++Vec) {
2306 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, SuperReg));
2312 CurDAG->RemoveDeadNode(N);
2315 bool ARMDAGToDAGISel::tryV6T2BitfieldExtractOp(
SDNode *N,
bool isSigned) {
2319 unsigned Opc = isSigned
2320 ? (Subtarget->
isThumb() ? ARM::t2SBFX : ARM::SBFX)
2321 : (Subtarget->
isThumb() ? ARM::t2UBFX : ARM::UBFX);
2325 unsigned And_imm = 0;
2330 if (And_imm & (And_imm + 1))
2333 unsigned Srl_imm = 0;
2336 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2341 And_imm &= -1U >> Srl_imm;
2345 unsigned LSB = Srl_imm;
2352 Opc = isSigned ? ARM::t2ASRri : ARM::t2LSRri;
2354 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2355 getAL(CurDAG, dl), Reg0, Reg0 };
2356 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2366 getAL(CurDAG, dl), Reg0, Reg0 };
2367 CurDAG->SelectNodeTo(N, ARM::MOVsi,
MVT::i32, Ops);
2371 assert(LSB + Width + 1 <= 32 &&
"Shouldn't create an invalid ubfx");
2373 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2374 CurDAG->getTargetConstant(Width, dl,
MVT::i32),
2375 getAL(CurDAG, dl), Reg0 };
2376 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2384 unsigned Shl_imm = 0;
2386 assert(Shl_imm > 0 && Shl_imm < 32 &&
"bad amount in shift node!");
2387 unsigned Srl_imm = 0;
2389 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2391 unsigned Width = 32 - Srl_imm - 1;
2392 int LSB = Srl_imm - Shl_imm;
2396 assert(LSB + Width + 1 <= 32 &&
"Shouldn't create an invalid ubfx");
2398 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2399 CurDAG->getTargetConstant(Width, dl,
MVT::i32),
2400 getAL(CurDAG, dl), Reg0 };
2401 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2409 unsigned Srl_imm = 0;
2413 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2416 unsigned Width = MSB - LSB;
2418 assert(Srl_imm + Width + 1 <= 32 &&
"Shouldn't create an invalid ubfx");
2420 CurDAG->getTargetConstant(Srl_imm, dl,
MVT::i32),
2421 CurDAG->getTargetConstant(Width, dl,
MVT::i32),
2422 getAL(CurDAG, dl), Reg0 };
2423 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2429 unsigned Width = cast<VTSDNode>(N->
getOperand(1))->getVT().getSizeInBits();
2435 if (LSB + Width > 32)
2439 assert(LSB + Width <= 32 &&
"Shouldn't create an invalid ubfx");
2441 CurDAG->getTargetConstant(LSB, dl,
MVT::i32),
2442 CurDAG->getTargetConstant(Width - 1, dl,
MVT::i32),
2443 getAL(CurDAG, dl), Reg0 };
2444 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2461 bool ARMDAGToDAGISel::tryABSOp(
SDNode *N){
2478 unsigned Size = XType.getSizeInBits() - 1;
2480 if (ADDSrc1 == XORSrc1 && ADDSrc0 == SRASrc0 &&
2481 XType.isInteger() && SRAConstant !=
nullptr &&
2484 CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0);
2492 void ARMDAGToDAGISel::SelectCMP_SWAP(
SDNode *N) {
2494 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
2496 Opcode = ARM::CMP_SWAP_8;
2498 Opcode = ARM::CMP_SWAP_16;
2500 Opcode = ARM::CMP_SWAP_32;
2506 SDNode *CmpSwap = CurDAG->getMachineNode(
2511 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
2515 CurDAG->RemoveDeadNode(N);
2524 return std::make_pair(FirstOne, LastOne);
2527 void ARMDAGToDAGISel::SelectCMPZ(
SDNode *N,
bool &SwitchEQNEToPLMI) {
2529 SwitchEQNEToPLMI =
false;
2542 if (!isa<ConstantSDNode>(Zero) || !cast<ConstantSDNode>(Zero)->isNullValue() ||
2558 auto EmitShift = [&](
unsigned Opc,
SDValue Src,
unsigned Imm) ->
SDNode* {
2560 Opc = (Opc == ARM::tLSLri) ? ARM::t2LSLri : ARM::t2LSRri;
2563 CurDAG->getRegister(0,
MVT::i32) };
2564 return CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops);
2567 CurDAG->getTargetConstant(Imm, dl,
MVT::i32),
2569 return CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops);
2573 if (Range->second == 0) {
2575 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
2576 ReplaceNode(And.
getNode(), NewN);
2577 }
else if (Range->first == 31) {
2579 NewN = EmitShift(ARM::tLSRri, X, Range->second);
2580 ReplaceNode(And.
getNode(), NewN);
2581 }
else if (Range->first == Range->second) {
2584 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
2585 ReplaceNode(And.
getNode(), NewN);
2587 SwitchEQNEToPLMI =
true;
2591 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
2592 NewN = EmitShift(ARM::tLSRri,
SDValue(NewN, 0),
2593 Range->second + (31 - Range->first));
2594 ReplaceNode(And.
getNode(), NewN);
2610 if (tryWriteRegister(N))
2614 if (tryReadRegister(N))
2619 if (tryInlineAsm(N))
2629 unsigned Val = cast<ConstantSDNode>(
N)->getZExtValue();
2631 if (ConstantMaterializationCost(Val) > 2) {
2632 SDValue CPIdx = CurDAG->getTargetConstantPool(
2634 TLI->getPointerTy(CurDAG->getDataLayout()));
2642 CurDAG->getEntryNode()
2649 CurDAG->getTargetConstant(0, dl,
MVT::i32),
2652 CurDAG->getEntryNode()
2665 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {MemOp});
2667 ReplaceNode(N, ResNode);
2676 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
2677 SDValue TFI = CurDAG->getTargetFrameIndex(
2678 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
2685 CurDAG->SelectNodeTo(N, ARM::tADDframe,
MVT::i32, TFI,
2686 CurDAG->getTargetConstant(0, dl,
MVT::i32));
2690 ARM::t2ADDri : ARM::ADDri);
2693 CurDAG->getRegister(0,
MVT::i32) };
2694 CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops);
2699 if (tryV6T2BitfieldExtractOp(N,
false))
2704 if (tryV6T2BitfieldExtractOp(N,
true))
2711 unsigned RHSV =
C->getZExtValue();
2714 unsigned ShImm =
Log2_32(RHSV-1);
2722 SDValue Ops[] = { V, V, ShImmOp,
getAL(CurDAG, dl), Reg0, Reg0 };
2723 CurDAG->SelectNodeTo(N, ARM::t2ADDrs,
MVT::i32, Ops);
2726 SDValue Ops[] = { V, V, Reg0, ShImmOp,
getAL(CurDAG, dl), Reg0,
2728 CurDAG->SelectNodeTo(N, ARM::ADDrsi,
MVT::i32, Ops);
2733 unsigned ShImm =
Log2_32(RHSV+1);
2741 SDValue Ops[] = { V, V, ShImmOp,
getAL(CurDAG, dl), Reg0, Reg0 };
2742 CurDAG->SelectNodeTo(N, ARM::t2RSBrs,
MVT::i32, Ops);
2745 SDValue Ops[] = { V, V, Reg0, ShImmOp,
getAL(CurDAG, dl), Reg0,
2747 CurDAG->SelectNodeTo(N, ARM::RSBrsi,
MVT::i32, Ops);
2755 if (tryV6T2BitfieldExtractOp(N,
false))
2762 if (N1C && N1C->hasOneUse() && Subtarget->
isThumb()) {
2769 bool PreferImmediateEncoding =
2770 Subtarget->
hasThumb2() && (is_t2_so_imm(Imm) || is_t2_so_imm_not(Imm));
2771 if (!PreferImmediateEncoding &&
2772 ConstantMaterializationCost(Imm) >
2773 ConstantMaterializationCost(~Imm)) {
2777 CurDAG->getConstant(~N1C->getZExtValue(), dl,
MVT::i32);
2787 ReplaceNode(N, CurDAG->getMachineNode(ARM::tBIC, dl,
MVT::i32, Ops));
2794 CurDAG->getMachineNode(ARM::t2BICrr, dl,
MVT::i32, Ops));
2810 : (Subtarget->
hasV6T2Ops() ? ARM::MOVTi16 : 0);
2824 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) &&
2825 (N1CVal & 0xffffU) == 0xffffU &&
2826 (N2CVal & 0xffffU) == 0x0U) {
2827 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16,
2831 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
2843 CurDAG->getRegister(0,
MVT::i32) };
2859 CurDAG->getRegister(0,
MVT::i32) };
2860 ReplaceNode(N, CurDAG->getMachineNode(
2878 CurDAG->getRegister(0,
MVT::i32) };
2879 ReplaceNode(N, CurDAG->getMachineNode(
2897 "This pattern should not be generated for Thumb");
2903 if (!Zero || Zero->getZExtValue() != 0 ||
2909 unsigned Opc = Subtarget->
isThumb2() ? ARM::t2SMMLS : ARM::SMMLS;
2912 CurDAG->getRegister(0,
MVT::i32) };
2913 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops));
2918 if (tryT2IndexedLoad(N))
2920 }
else if (Subtarget->
isThumb()) {
2921 if (tryT1IndexedLoad(N))
2923 }
else if (tryARMIndexedLoad(N))
2941 unsigned Opc = Subtarget->
isThumb() ?
2942 ((Subtarget->
hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc;
2952 unsigned CC = (
unsigned) cast<ConstantSDNode>(N2)->getZExtValue();
2955 bool SwitchEQNEToPLMI;
2956 SelectCMPZ(InFlag.
getNode(), SwitchEQNEToPLMI);
2959 if (SwitchEQNEToPLMI) {
2973 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag };
2979 ReplaceUses(
SDValue(N, 1), InFlag);
2983 CurDAG->RemoveDeadNode(N);
2994 if (
C &&
C->getSExtValue() < 0 && Subtarget->
isThumb()) {
2995 int64_t Addend = -
C->getSExtValue();
3002 if (Addend < 1<<8) {
3006 CurDAG->getRegister(0,
MVT::i32) };
3007 Add = CurDAG->getMachineNode(ARM::t2ADDri, dl,
MVT::i32, Ops);
3009 unsigned Opc = (Addend < 1<<3) ? ARM::tADDi3 : ARM::tADDi8;
3011 CurDAG->getTargetConstant(Addend, dl,
MVT::i32),
3013 Add = CurDAG->getMachineNode(Opc, dl,
MVT::i32, Ops);
3029 bool SwitchEQNEToPLMI;
3030 SelectCMPZ(InFlag.
getNode(), SwitchEQNEToPLMI);
3032 if (SwitchEQNEToPLMI) {
3062 case MVT::v8i8: Opc = ARM::VZIPd8;
break;
3077 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops));
3085 case MVT::v8i8: Opc = ARM::VUZPd8;
break;
3100 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops));
3108 case MVT::v8i8: Opc = ARM::VTRNd8;
break;
3122 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops));
3130 assert(NumElts == 2 &&
"unexpected type for BUILD_VECTOR");
3141 assert(NumElts == 4 &&
"unexpected type for BUILD_VECTOR");
3149 static const uint16_t DOpcodes[] = { ARM::VLD1DUPd8, ARM::VLD1DUPd16,
3151 static const uint16_t QOpcodes[] = { ARM::VLD1DUPq8, ARM::VLD1DUPq16,
3153 SelectVLDDup(N,
false,
false, 1, DOpcodes, QOpcodes);
3158 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16,
3160 SelectVLDDup(N,
false,
false, 2, Opcodes);
3165 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo,
3166 ARM::VLD3DUPd16Pseudo,
3167 ARM::VLD3DUPd32Pseudo };
3168 SelectVLDDup(N,
false,
false, 3, Opcodes);
3173 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo,
3174 ARM::VLD4DUPd16Pseudo,
3175 ARM::VLD4DUPd32Pseudo };
3176 SelectVLDDup(N,
false,
false, 4, Opcodes);
3181 static const uint16_t DOpcodes[] = { ARM::VLD1DUPd8wb_fixed,
3182 ARM::VLD1DUPd16wb_fixed,
3183 ARM::VLD1DUPd32wb_fixed };
3184 static const uint16_t QOpcodes[] = { ARM::VLD1DUPq8wb_fixed,
3185 ARM::VLD1DUPq16wb_fixed,
3186 ARM::VLD1DUPq32wb_fixed };
3187 SelectVLDDup(N,
false,
true, 1, DOpcodes, QOpcodes);
3192 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8wb_fixed,
3193 ARM::VLD2DUPd16wb_fixed,
3194 ARM::VLD2DUPd32wb_fixed };
3195 SelectVLDDup(N,
false,
true, 2, Opcodes);
3200 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo_UPD,
3201 ARM::VLD3DUPd16Pseudo_UPD,
3202 ARM::VLD3DUPd32Pseudo_UPD };
3203 SelectVLDDup(N,
false,
true, 3, Opcodes);
3208 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo_UPD,
3209 ARM::VLD4DUPd16Pseudo_UPD,
3210 ARM::VLD4DUPd32Pseudo_UPD };
3211 SelectVLDDup(N,
false,
true, 4, Opcodes);
3216 static const uint16_t DOpcodes[] = { ARM::VLD1d8wb_fixed,
3217 ARM::VLD1d16wb_fixed,
3218 ARM::VLD1d32wb_fixed,
3219 ARM::VLD1d64wb_fixed };
3220 static const uint16_t QOpcodes[] = { ARM::VLD1q8wb_fixed,
3221 ARM::VLD1q16wb_fixed,
3222 ARM::VLD1q32wb_fixed,
3223 ARM::VLD1q64wb_fixed };
3224 SelectVLD(N,
true, 1, DOpcodes, QOpcodes,
nullptr);
3229 static const uint16_t DOpcodes[] = { ARM::VLD2d8wb_fixed,
3230 ARM::VLD2d16wb_fixed,
3231 ARM::VLD2d32wb_fixed,
3232 ARM::VLD1q64wb_fixed};
3233 static const uint16_t QOpcodes[] = { ARM::VLD2q8PseudoWB_fixed,
3234 ARM::VLD2q16PseudoWB_fixed,
3235 ARM::VLD2q32PseudoWB_fixed };
3236 SelectVLD(N,
true, 2, DOpcodes, QOpcodes,
nullptr);
3241 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD,
3242 ARM::VLD3d16Pseudo_UPD,
3243 ARM::VLD3d32Pseudo_UPD,
3244 ARM::VLD1d64TPseudoWB_fixed};
3245 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
3246 ARM::VLD3q16Pseudo_UPD,
3247 ARM::VLD3q32Pseudo_UPD };
3248 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo_UPD,
3249 ARM::VLD3q16oddPseudo_UPD,
3250 ARM::VLD3q32oddPseudo_UPD };
3251 SelectVLD(N,
true, 3, DOpcodes, QOpcodes0, QOpcodes1);
3256 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD,
3257 ARM::VLD4d16Pseudo_UPD,
3258 ARM::VLD4d32Pseudo_UPD,
3259 ARM::VLD1d64QPseudoWB_fixed};
3260 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
3261 ARM::VLD4q16Pseudo_UPD,
3262 ARM::VLD4q32Pseudo_UPD };
3263 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo_UPD,
3264 ARM::VLD4q16oddPseudo_UPD,
3265 ARM::VLD4q32oddPseudo_UPD };
3266 SelectVLD(N,
true, 4, DOpcodes, QOpcodes0, QOpcodes1);
3271 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo_UPD,
3272 ARM::VLD2LNd16Pseudo_UPD,
3273 ARM::VLD2LNd32Pseudo_UPD };
3274 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo_UPD,
3275 ARM::VLD2LNq32Pseudo_UPD };
3276 SelectVLDSTLane(N,
true,
true, 2, DOpcodes, QOpcodes);
3281 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo_UPD,
3282 ARM::VLD3LNd16Pseudo_UPD,
3283 ARM::VLD3LNd32Pseudo_UPD };
3284 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo_UPD,
3285 ARM::VLD3LNq32Pseudo_UPD };
3286 SelectVLDSTLane(N,
true,
true, 3, DOpcodes, QOpcodes);
3291 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo_UPD,
3292 ARM::VLD4LNd16Pseudo_UPD,
3293 ARM::VLD4LNd32Pseudo_UPD };
3294 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo_UPD,
3295 ARM::VLD4LNq32Pseudo_UPD };
3296 SelectVLDSTLane(N,
true,
true, 4, DOpcodes, QOpcodes);
3301 static const uint16_t DOpcodes[] = { ARM::VST1d8wb_fixed,
3302 ARM::VST1d16wb_fixed,
3303 ARM::VST1d32wb_fixed,
3304 ARM::VST1d64wb_fixed };
3305 static const uint16_t QOpcodes[] = { ARM::VST1q8wb_fixed,
3306 ARM::VST1q16wb_fixed,
3307 ARM::VST1q32wb_fixed,
3308 ARM::VST1q64wb_fixed };
3309 SelectVST(N,
true, 1, DOpcodes, QOpcodes,
nullptr);
3314 static const uint16_t DOpcodes[] = { ARM::VST2d8wb_fixed,
3315 ARM::VST2d16wb_fixed,
3316 ARM::VST2d32wb_fixed,
3317 ARM::VST1q64wb_fixed};
3318 static const uint16_t QOpcodes[] = { ARM::VST2q8PseudoWB_fixed,
3319 ARM::VST2q16PseudoWB_fixed,
3320 ARM::VST2q32PseudoWB_fixed };
3321 SelectVST(N,
true, 2, DOpcodes, QOpcodes,
nullptr);
3326 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo_UPD,
3327 ARM::VST3d16Pseudo_UPD,
3328 ARM::VST3d32Pseudo_UPD,
3329 ARM::VST1d64TPseudoWB_fixed};
3330 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
3331 ARM::VST3q16Pseudo_UPD,
3332 ARM::VST3q32Pseudo_UPD };
3333 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD,
3334 ARM::VST3q16oddPseudo_UPD,
3335 ARM::VST3q32oddPseudo_UPD };
3336 SelectVST(N,
true, 3, DOpcodes, QOpcodes0, QOpcodes1);
3341 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo_UPD,
3342 ARM::VST4d16Pseudo_UPD,
3343 ARM::VST4d32Pseudo_UPD,
3344 ARM::VST1d64QPseudoWB_fixed};
3345 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
3346 ARM::VST4q16Pseudo_UPD,
3347 ARM::VST4q32Pseudo_UPD };
3348 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD,
3349 ARM::VST4q16oddPseudo_UPD,
3350 ARM::VST4q32oddPseudo_UPD };
3351 SelectVST(N,
true, 4, DOpcodes, QOpcodes0, QOpcodes1);
3356 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo_UPD,
3357 ARM::VST2LNd16Pseudo_UPD,
3358 ARM::VST2LNd32Pseudo_UPD };
3359 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo_UPD,
3360 ARM::VST2LNq32Pseudo_UPD };
3361 SelectVLDSTLane(N,
false,
true, 2, DOpcodes, QOpcodes);
3366 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo_UPD,
3367 ARM::VST3LNd16Pseudo_UPD,
3368 ARM::VST3LNd32Pseudo_UPD };
3369 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo_UPD,
3370 ARM::VST3LNq32Pseudo_UPD };
3371 SelectVLDSTLane(N,
false,
true, 3, DOpcodes, QOpcodes);
3376 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo_UPD,
3377 ARM::VST4LNd16Pseudo_UPD,
3378 ARM::VST4LNd32Pseudo_UPD };
3379 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo_UPD,
3380 ARM::VST4LNq32Pseudo_UPD };
3381 SelectVLDSTLane(N,
false,
true, 4, DOpcodes, QOpcodes);
3387 unsigned IntNo = cast<ConstantSDNode>(N->
getOperand(1))->getZExtValue();
3392 case Intrinsic::arm_mrrc:
3393 case Intrinsic::arm_mrrc2: {
3399 Opc = (IntNo == Intrinsic::arm_mrrc ? ARM::t2MRRC : ARM::t2MRRC2);
3401 Opc = (IntNo == Intrinsic::arm_mrrc ? ARM::MRRC : ARM::MRRC2);
3411 if (Opc != ARM::MRRC2) {
3421 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, RetType, Ops));
3424 case Intrinsic::arm_ldaexd:
3425 case Intrinsic::arm_ldrexd: {
3431 bool IsAcquire = IntNo == Intrinsic::arm_ldaexd;
3432 unsigned NewOpc = isThumb ? (IsAcquire ? ARM::t2LDAEXD : ARM::t2LDREXD)
3433 : (IsAcquire ? ARM::LDAEXD : ARM::LDREXD);
3436 std::vector<EVT> ResTys;
3446 CurDAG->getRegister(0,
MVT::i32), Chain};
3447 SDNode *Ld = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
3450 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
3454 if (!SDValue(N, 0).use_empty()) {
3457 Result = SDValue(Ld, 0);
3460 CurDAG->getTargetConstant(ARM::gsub_0, dl,
MVT::i32);
3461 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
3462 dl,
MVT::i32, SDValue(Ld, 0), SubRegIdx);
3463 Result = SDValue(ResNode,0);
3465 ReplaceUses(SDValue(N, 0), Result);
3467 if (!SDValue(N, 1).use_empty()) {
3470 Result = SDValue(Ld, 1);
3473 CurDAG->getTargetConstant(ARM::gsub_1, dl,
MVT::i32);
3474 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
3475 dl,
MVT::i32, SDValue(Ld, 0), SubRegIdx);
3476 Result = SDValue(ResNode,0);
3478 ReplaceUses(SDValue(N, 1), Result);
3480 ReplaceUses(SDValue(N, 2), OutChain);
3481 CurDAG->RemoveDeadNode(N);
3484 case Intrinsic::arm_stlexd:
3485 case Intrinsic::arm_strexd: {
3510 bool IsRelease = IntNo == Intrinsic::arm_stlexd;
3511 unsigned NewOpc = isThumb ? (IsRelease ? ARM::t2STLEXD : ARM::t2STREXD)
3512 : (IsRelease ? ARM::STLEXD : ARM::STREXD);
3514 SDNode *St = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
3517 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
3523 case Intrinsic::arm_neon_vld1: {
3524 static const uint16_t DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16,
3525 ARM::VLD1d32, ARM::VLD1d64 };
3526 static const uint16_t QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16,
3527 ARM::VLD1q32, ARM::VLD1q64};
3528 SelectVLD(N,
false, 1, DOpcodes, QOpcodes,
nullptr);
3532 case Intrinsic::arm_neon_vld1x2: {
3533 static const uint16_t DOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16,
3534 ARM::VLD1q32, ARM::VLD1q64 };
3535 static const uint16_t QOpcodes[] = { ARM::VLD1d8QPseudo,
3536 ARM::VLD1d16QPseudo,
3537 ARM::VLD1d32QPseudo,
3538 ARM::VLD1d64QPseudo };
3539 SelectVLD(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3543 case Intrinsic::arm_neon_vld1x3: {
3544 static const uint16_t DOpcodes[] = { ARM::VLD1d8TPseudo,
3545 ARM::VLD1d16TPseudo,
3546 ARM::VLD1d32TPseudo,
3547 ARM::VLD1d64TPseudo };
3548 static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowTPseudo_UPD,
3549 ARM::VLD1q16LowTPseudo_UPD,
3550 ARM::VLD1q32LowTPseudo_UPD,
3551 ARM::VLD1q64LowTPseudo_UPD };
3552 static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighTPseudo,
3553 ARM::VLD1q16HighTPseudo,
3554 ARM::VLD1q32HighTPseudo,
3555 ARM::VLD1q64HighTPseudo };
3556 SelectVLD(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3560 case Intrinsic::arm_neon_vld1x4: {
3561 static const uint16_t DOpcodes[] = { ARM::VLD1d8QPseudo,
3562 ARM::VLD1d16QPseudo,
3563 ARM::VLD1d32QPseudo,
3564 ARM::VLD1d64QPseudo };
3565 static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowQPseudo_UPD,
3566 ARM::VLD1q16LowQPseudo_UPD,
3567 ARM::VLD1q32LowQPseudo_UPD,
3568 ARM::VLD1q64LowQPseudo_UPD };
3569 static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighQPseudo,
3570 ARM::VLD1q16HighQPseudo,
3571 ARM::VLD1q32HighQPseudo,
3572 ARM::VLD1q64HighQPseudo };
3573 SelectVLD(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3577 case Intrinsic::arm_neon_vld2: {
3578 static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16,
3579 ARM::VLD2d32, ARM::VLD1q64 };
3580 static const uint16_t QOpcodes[] = { ARM::VLD2q8Pseudo, ARM::VLD2q16Pseudo,
3581 ARM::VLD2q32Pseudo };
3582 SelectVLD(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3586 case Intrinsic::arm_neon_vld3: {
3587 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo,
3590 ARM::VLD1d64TPseudo };
3591 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
3592 ARM::VLD3q16Pseudo_UPD,
3593 ARM::VLD3q32Pseudo_UPD };
3594 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo,
3595 ARM::VLD3q16oddPseudo,
3596 ARM::VLD3q32oddPseudo };
3597 SelectVLD(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3601 case Intrinsic::arm_neon_vld4: {
3602 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo,
3605 ARM::VLD1d64QPseudo };
3606 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
3607 ARM::VLD4q16Pseudo_UPD,
3608 ARM::VLD4q32Pseudo_UPD };
3609 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo,
3610 ARM::VLD4q16oddPseudo,
3611 ARM::VLD4q32oddPseudo };
3612 SelectVLD(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3616 case Intrinsic::arm_neon_vld2dup: {
3617 static const uint16_t DOpcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16,
3618 ARM::VLD2DUPd32, ARM::VLD1q64 };
3619 static const uint16_t QOpcodes0[] = { ARM::VLD2DUPq8EvenPseudo,
3620 ARM::VLD2DUPq16EvenPseudo,
3621 ARM::VLD2DUPq32EvenPseudo };
3622 static const uint16_t QOpcodes1[] = { ARM::VLD2DUPq8OddPseudo,
3623 ARM::VLD2DUPq16OddPseudo,
3624 ARM::VLD2DUPq32OddPseudo };
3625 SelectVLDDup(N,
true,
false, 2,
3626 DOpcodes, QOpcodes0, QOpcodes1);
3630 case Intrinsic::arm_neon_vld3dup: {
3631 static const uint16_t DOpcodes[] = { ARM::VLD3DUPd8Pseudo,
3632 ARM::VLD3DUPd16Pseudo,
3633 ARM::VLD3DUPd32Pseudo,
3634 ARM::VLD1d64TPseudo };
3635 static const uint16_t QOpcodes0[] = { ARM::VLD3DUPq8EvenPseudo,
3636 ARM::VLD3DUPq16EvenPseudo,
3637 ARM::VLD3DUPq32EvenPseudo };
3638 static const uint16_t QOpcodes1[] = { ARM::VLD3DUPq8OddPseudo,
3639 ARM::VLD3DUPq16OddPseudo,
3640 ARM::VLD3DUPq32OddPseudo };
3641 SelectVLDDup(N,
true,
false, 3,
3642 DOpcodes, QOpcodes0, QOpcodes1);
3646 case Intrinsic::arm_neon_vld4dup: {
3647 static const uint16_t DOpcodes[] = { ARM::VLD4DUPd8Pseudo,
3648 ARM::VLD4DUPd16Pseudo,
3649 ARM::VLD4DUPd32Pseudo,
3650 ARM::VLD1d64QPseudo };
3651 static const uint16_t QOpcodes0[] = { ARM::VLD4DUPq8EvenPseudo,
3652 ARM::VLD4DUPq16EvenPseudo,
3653 ARM::VLD4DUPq32EvenPseudo };
3654 static const uint16_t QOpcodes1[] = { ARM::VLD4DUPq8OddPseudo,
3655 ARM::VLD4DUPq16OddPseudo,
3656 ARM::VLD4DUPq32OddPseudo };
3657 SelectVLDDup(N,
true,
false, 4,
3658 DOpcodes, QOpcodes0, QOpcodes1);
3662 case Intrinsic::arm_neon_vld2lane: {
3663 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo,
3664 ARM::VLD2LNd16Pseudo,
3665 ARM::VLD2LNd32Pseudo };
3666 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo,
3667 ARM::VLD2LNq32Pseudo };
3668 SelectVLDSTLane(N,
true,
false, 2, DOpcodes, QOpcodes);
3672 case Intrinsic::arm_neon_vld3lane: {
3673 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo,
3674 ARM::VLD3LNd16Pseudo,
3675 ARM::VLD3LNd32Pseudo };
3676 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo,
3677 ARM::VLD3LNq32Pseudo };
3678 SelectVLDSTLane(N,
true,
false, 3, DOpcodes, QOpcodes);
3682 case Intrinsic::arm_neon_vld4lane: {
3683 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo,
3684 ARM::VLD4LNd16Pseudo,
3685 ARM::VLD4LNd32Pseudo };
3686 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo,
3687 ARM::VLD4LNq32Pseudo };
3688 SelectVLDSTLane(N,
true,
false, 4, DOpcodes, QOpcodes);
3692 case Intrinsic::arm_neon_vst1: {
3693 static const uint16_t DOpcodes[] = { ARM::VST1d8, ARM::VST1d16,
3694 ARM::VST1d32, ARM::VST1d64 };
3695 static const uint16_t QOpcodes[] = { ARM::VST1q8, ARM::VST1q16,
3696 ARM::VST1q32, ARM::VST1q64 };
3697 SelectVST(N,
false, 1, DOpcodes, QOpcodes,
nullptr);
3701 case Intrinsic::arm_neon_vst1x2: {
3702 static const uint16_t DOpcodes[] = { ARM::VST1q8, ARM::VST1q16,
3703 ARM::VST1q32, ARM::VST1q64 };
3704 static const uint16_t QOpcodes[] = { ARM::VST1d8QPseudo,
3705 ARM::VST1d16QPseudo,
3706 ARM::VST1d32QPseudo,
3707 ARM::VST1d64QPseudo };
3708 SelectVST(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3712 case Intrinsic::arm_neon_vst1x3: {
3713 static const uint16_t DOpcodes[] = { ARM::VST1d8TPseudo,
3714 ARM::VST1d16TPseudo,
3715 ARM::VST1d32TPseudo,
3716 ARM::VST1d64TPseudo };
3717 static const uint16_t QOpcodes0[] = { ARM::VST1q8LowTPseudo_UPD,
3718 ARM::VST1q16LowTPseudo_UPD,
3719 ARM::VST1q32LowTPseudo_UPD,
3720 ARM::VST1q64LowTPseudo_UPD };
3721 static const uint16_t QOpcodes1[] = { ARM::VST1q8HighTPseudo,
3722 ARM::VST1q16HighTPseudo,
3723 ARM::VST1q32HighTPseudo,
3724 ARM::VST1q64HighTPseudo };
3725 SelectVST(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3729 case Intrinsic::arm_neon_vst1x4: {
3730 static const uint16_t DOpcodes[] = { ARM::VST1d8QPseudo,
3731 ARM::VST1d16QPseudo,
3732 ARM::VST1d32QPseudo,
3733 ARM::VST1d64QPseudo };
3734 static const uint16_t QOpcodes0[] = { ARM::VST1q8LowQPseudo_UPD,
3735 ARM::VST1q16LowQPseudo_UPD,
3736 ARM::VST1q32LowQPseudo_UPD,
3737 ARM::VST1q64LowQPseudo_UPD };
3738 static const uint16_t QOpcodes1[] = { ARM::VST1q8HighQPseudo,
3739 ARM::VST1q16HighQPseudo,
3740 ARM::VST1q32HighQPseudo,
3741 ARM::VST1q64HighQPseudo };
3742 SelectVST(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3746 case Intrinsic::arm_neon_vst2: {
3747 static const uint16_t DOpcodes[] = { ARM::VST2d8, ARM::VST2d16,
3748 ARM::VST2d32, ARM::VST1q64 };
3749 static const uint16_t QOpcodes[] = { ARM::VST2q8Pseudo, ARM::VST2q16Pseudo,
3750 ARM::VST2q32Pseudo };
3751 SelectVST(N,
false, 2, DOpcodes, QOpcodes,
nullptr);
3755 case Intrinsic::arm_neon_vst3: {
3756 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo,
3759 ARM::VST1d64TPseudo };
3760 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
3761 ARM::VST3q16Pseudo_UPD,
3762 ARM::VST3q32Pseudo_UPD };
3763 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo,
3764 ARM::VST3q16oddPseudo,
3765 ARM::VST3q32oddPseudo };
3766 SelectVST(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3770 case Intrinsic::arm_neon_vst4: {
3771 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo,
3774 ARM::VST1d64QPseudo };
3775 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
3776 ARM::VST4q16Pseudo_UPD,
3777 ARM::VST4q32Pseudo_UPD };
3778 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo,
3779 ARM::VST4q16oddPseudo,
3780 ARM::VST4q32oddPseudo };
3781 SelectVST(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3785 case Intrinsic::arm_neon_vst2lane: {
3786 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo,
3787 ARM::VST2LNd16Pseudo,
3788 ARM::VST2LNd32Pseudo };
3789 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo,
3790 ARM::VST2LNq32Pseudo };
3791 SelectVLDSTLane(N,
false,
false, 2, DOpcodes, QOpcodes);
3795 case Intrinsic::arm_neon_vst3lane: {
3796 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo,
3797 ARM::VST3LNd16Pseudo,
3798 ARM::VST3LNd32Pseudo };
3799 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo,
3800 ARM::VST3LNq32Pseudo };
3801 SelectVLDSTLane(N,
false,
false, 3, DOpcodes, QOpcodes);
3805 case Intrinsic::arm_neon_vst4lane: {
3806 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo,
3807 ARM::VST4LNd16Pseudo,
3808 ARM::VST4LNd32Pseudo };
3809 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo,
3810 ARM::VST4LNq32Pseudo };
3811 SelectVLDSTLane(N,
false,
false, 4, DOpcodes, QOpcodes);
3834 std::vector<SDValue> &Ops) {
3836 RegString.
split(Fields,
':');
3838 if (Fields.
size() > 1) {
3839 bool AllIntFields =
true;
3844 AllIntFields &= !
Field.trim(
"CPcp").getAsInteger(10, IntField);
3849 "Unexpected non-integer value in special register string.");
3859 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegString.
lower());
3862 return TheReg->Encoding;
3874 .
Case(
"nzcvqg", 0x3)
3882 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Reg);
3883 const FeatureBitset &FeatureBits = Subtarget->getFeatureBits();
3884 if (!TheReg || !TheReg->hasRequiredFeatures(FeatureBits))
3886 return (
int)(TheReg->Encoding & 0xFFF);
3895 if (Reg ==
"apsr") {
3905 if (Reg !=
"cpsr" && Reg !=
"spsr") {
3910 if (Flags.
empty() || Flags ==
"all")
3915 for (
char Flag : Flags) {
3935 if (!FlagVal || (Mask & FlagVal))
3950 bool ARMDAGToDAGISel::tryReadRegister(
SDNode *N){
3953 bool IsThumb2 = Subtarget->
isThumb2();
3956 std::vector<SDValue> Ops;
3966 if (Ops.size() == 5){
3967 Opcode = IsThumb2 ? ARM::t2MRC : ARM::MRC;
3970 assert(Ops.size() == 3 &&
3971 "Invalid number of fields in special register string.");
3972 Opcode = IsThumb2 ? ARM::t2MRRC : ARM::MRRC;
3976 Ops.push_back(
getAL(CurDAG, DL));
3977 Ops.push_back(CurDAG->getRegister(0,
MVT::i32));
3979 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL, ResTypes, Ops));
3983 std::string SpecialReg = RegString->getString().lower();
3986 if (BankedReg != -1) {
3987 Ops = { CurDAG->getTargetConstant(BankedReg, DL,
MVT::i32),
3991 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSbanked : ARM::MRSbanked,
4000 .Case(
"fpscr", ARM::VMRS)
4001 .
Case(
"fpexc", ARM::VMRS_FPEXC)
4002 .
Case(
"fpsid", ARM::VMRS_FPSID)
4003 .
Case(
"mvfr0", ARM::VMRS_MVFR0)
4004 .
Case(
"mvfr1", ARM::VMRS_MVFR1)
4005 .
Case(
"mvfr2", ARM::VMRS_MVFR2)
4006 .
Case(
"fpinst", ARM::VMRS_FPINST)
4007 .
Case(
"fpinst2", ARM::VMRS_FPINST2)
4014 if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->
hasFPARMv8())
4017 Ops = {
getAL(CurDAG, DL), CurDAG->getRegister(0,
MVT::i32),
4029 if (SYSmValue == -1)
4042 if (SpecialReg ==
"apsr" || SpecialReg ==
"cpsr") {
4043 Ops = {
getAL(CurDAG, DL), CurDAG->getRegister(0,
MVT::i32),
4045 ReplaceNode(N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRS_AR : ARM::MRS,
4050 if (SpecialReg ==
"spsr") {
4051 Ops = {
getAL(CurDAG, DL), CurDAG->getRegister(0,
MVT::i32),
4054 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSsys_AR : ARM::MRSsys, DL,
4065 bool ARMDAGToDAGISel::tryWriteRegister(
SDNode *N){
4068 bool IsThumb2 = Subtarget->
isThumb2();
4071 std::vector<SDValue> Ops;
4080 if (Ops.size() == 5) {
4081 Opcode = IsThumb2 ? ARM::t2MCR : ARM::MCR;
4084 assert(Ops.size() == 3 &&
4085 "Invalid number of fields in special register string.");
4086 Opcode = IsThumb2 ? ARM::t2MCRR : ARM::MCRR;
4088 Ops.insert(Ops.begin()+2, WriteValue, WriteValue+2);
4091 Ops.push_back(
getAL(CurDAG, DL));
4092 Ops.push_back(CurDAG->getRegister(0,
MVT::i32));
4095 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL,
MVT::Other, Ops));
4099 std::string SpecialReg = RegString->getString().lower();
4101 if (BankedReg != -1) {
4106 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSRbanked : ARM::MSRbanked,
4115 .Case(
"fpscr", ARM::VMSR)
4116 .
Case(
"fpexc", ARM::VMSR_FPEXC)
4117 .
Case(
"fpsid", ARM::VMSR_FPSID)
4118 .
Case(
"fpinst", ARM::VMSR_FPINST)
4119 .
Case(
"fpinst2", ARM::VMSR_FPINST2)
4127 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL,
MVT::Other, Ops));
4131 std::pair<StringRef, StringRef> Fields;
4133 std::string
Reg = Fields.first.str();
4140 if (SYSmValue == -1)
4146 ReplaceNode(N, CurDAG->getMachineNode(ARM::t2MSR_M, DL,
MVT::Other, Ops));
4158 ReplaceNode(N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSR_AR : ARM::MSR,
4166 bool ARMDAGToDAGISel::tryInlineAsm(
SDNode *N){
4167 std::vector<SDValue> AsmNodeOperands;
4169 bool Changed =
false;
4186 for(
unsigned i = 0, e = N->
getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) {
4188 AsmNodeOperands.push_back(op);
4194 Flag =
C->getZExtValue();
4206 AsmNodeOperands.push_back(op);
4214 unsigned DefIdx = 0;
4215 bool IsTiedToChangedOp =
false;
4219 IsTiedToChangedOp = OpChanged[DefIdx];
4228 AsmNodeOperands.push_back(op);
4238 if ((!IsTiedToChangedOp && (!HasRC || RC != ARM::GPRRegClassID))
4242 assert((i+2 < NumOps) &&
"Invalid number of operands in inline asm");
4245 unsigned Reg0 = cast<RegisterSDNode>(V0)->
getReg();
4246 unsigned Reg1 = cast<RegisterSDNode>(V1)->
getReg();
4264 SDValue Sub0 = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl,
MVT::i32,
4266 SDValue Sub1 = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl,
MVT::i32,
4268 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
4275 CurDAG->UpdateNodeOperands(GU, Ops);
4293 Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.
getValue(1));
4302 OpChanged[OpChanged.
size() -1 ] =
true;
4304 if (IsTiedToChangedOp)
4309 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
4312 AsmNodeOperands.push_back(PairedReg);
4319 AsmNodeOperands.push_back(Glue);
4326 ReplaceNode(N, New.
getNode());
4331 bool ARMDAGToDAGISel::
4332 SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
4333 std::vector<SDValue> &OutOps) {
4334 switch(ConstraintID) {
4354 OutOps.push_back(Op);
4365 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...
StringSwitch & Case(StringLiteral S, T Value)
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
LLVM_NODISCARD R Default(T Value)
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)
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.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
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.
static bool isVLDfixed(unsigned Opc)
Simple integer binary arithmetic operators.
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.
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.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static bool shouldUseZeroOffsetLdSt(SDValue N)
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())
INLINEASM_BR - Terminator version of inline asm. Used by asm-goto.
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.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
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.