14 #define DEBUG_TYPE "arm-isel"
43 cl::desc(
"Disable isel of shifter-op"),
48 cl::desc(
"Check fp vmla / vmls hazard at isel time"),
76 virtual const char *getPassName()
const {
77 return "ARM Instruction Selection";
80 virtual void PreprocessISelDAG();
84 inline SDValue getI32Imm(
unsigned Imm) {
85 return CurDAG->getTargetConstant(Imm,
MVT::i32);
91 bool hasNoVMLxHazardUse(
SDNode *
N)
const;
92 bool isShifterOpProfitable(
const SDValue &Shift,
96 bool CheckProfitability =
true);
98 SDValue &B,
bool CheckProfitability =
true);
102 return SelectRegShifterOperand(N, A, B, C,
false);
107 return SelectImmShifterOperand(N, A, B,
false);
117 return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE;
122 return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP;
127 SelectAddrMode2Worker(N, Base, Offset, Opc);
136 Reg = CurDAG->getRegister(ARM::CPSR,
MVT::i32);
165 bool SelectThumbAddrModeImm5S(
SDValue N,
unsigned Scale,
SDValue &Base,
176 bool SelectT2ShifterOperandReg(
SDValue N,
187 inline bool is_so_imm(
unsigned Imm)
const {
191 inline bool is_so_imm_not(
unsigned Imm)
const {
195 inline bool is_t2_so_imm(
unsigned Imm)
const {
199 inline bool is_t2_so_imm_not(
unsigned Imm)
const {
204 #include "ARMGenDAGISel.inc"
216 SDNode *SelectVLD(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
217 const uint16_t *DOpcodes,
218 const uint16_t *QOpcodes0,
const uint16_t *QOpcodes1);
224 SDNode *SelectVST(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
225 const uint16_t *DOpcodes,
226 const uint16_t *QOpcodes0,
const uint16_t *QOpcodes1);
232 bool isUpdating,
unsigned NumVecs,
233 const uint16_t *DOpcodes,
const uint16_t *QOpcodes);
238 SDNode *SelectVLDDup(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
239 const uint16_t *Opcodes);
244 SDNode *SelectVTBL(
SDNode *N,
bool IsExt,
unsigned NumVecs,
unsigned Opc);
247 SDNode *SelectV6T2BitfieldExtractOp(
SDNode *N,
bool isSigned);
256 SDNode *SelectAtomic(
SDNode *N,
unsigned Op8,
unsigned Op16,
unsigned Op32,
unsigned Op64);
260 virtual bool SelectInlineAsmMemoryOperand(
const SDValue &Op,
262 std::vector<SDValue> &OutOps);
284 Imm = cast<ConstantSDNode>(
N)->getZExtValue();
309 int RangeMin,
int RangeMax,
310 int &ScaledConstant) {
311 assert(Scale > 0 &&
"Invalid scale!");
319 if ((ScaledConstant % Scale) != 0)
322 ScaledConstant /= Scale;
323 return ScaledConstant >= RangeMin && ScaledConstant < RangeMax;
326 void ARMDAGToDAGISel::PreprocessISelDAG() {
327 if (!Subtarget->hasV6T2Ops())
330 bool isThumb2 = Subtarget->isThumb();
332 E = CurDAG->allnodes_end();
I != E; ) {
349 unsigned And_imm = 0;
359 if (TZ != 1 && TZ != 2)
371 if (And_imm & (And_imm + 1))
376 unsigned Srl_imm = 0;
387 if (SelectT2ShifterOperandReg(N0, CPTmp0, CPTmp1))
390 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1) ||
391 SelectRegShifterOperand(N0, CPTmp0, CPTmp1, CPTmp2))
398 CurDAG->getConstant(Srl_imm+TZ,
MVT::i32));
400 Srl, CurDAG->getConstant(And_imm,
MVT::i32));
402 N1, CurDAG->getConstant(TZ,
MVT::i32));
403 CurDAG->UpdateNodeOperands(N, N0, N1);
410 bool ARMDAGToDAGISel::hasNoVMLxHazardUse(
SDNode *N)
const {
417 if (!Subtarget->isCortexA8() && !Subtarget->isCortexA9() &&
418 !Subtarget->isSwift())
456 bool ARMDAGToDAGISel::isShifterOpProfitable(
const SDValue &Shift,
459 if (!Subtarget->isLikeA9() && !Subtarget->isSwift())
465 (ShAmt == 2 || (Subtarget->isSwift() && ShAmt == 1));
468 bool ARMDAGToDAGISel::SelectImmShifterOperand(
SDValue N,
471 bool CheckProfitability) {
482 unsigned ShImmVal = 0;
484 if (!RHS)
return false;
491 bool ARMDAGToDAGISel::SelectRegShifterOperand(
SDValue N,
495 bool CheckProfitability) {
506 unsigned ShImmVal = 0;
508 if (RHS)
return false;
511 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal))
519 bool ARMDAGToDAGISel::SelectAddrModeImm12(
SDValue N,
526 !CurDAG->isBaseWithConstantOffset(N)) {
529 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
530 Base = CurDAG->getTargetFrameIndex(FI,
531 getTargetLowering()->getPointerTy());
532 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
537 !(Subtarget->useMovt() &&
542 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
551 if (RHSC >= 0 && RHSC < 0x1000) {
554 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
555 Base = CurDAG->getTargetFrameIndex(FI,
556 getTargetLowering()->getPointerTy());
558 OffImm = CurDAG->getTargetConstant(RHSC,
MVT::i32);
565 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
574 ((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.
hasOneUse())) {
586 unsigned ShAmt =
Log2_32(RHSC);
599 !CurDAG->isBaseWithConstantOffset(N))
606 -0x1000+1, 0x1000, RHSC))
624 ShAmt = Sh->getZExtValue();
625 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
638 !(Subtarget->isLikeA9() || Subtarget->isSwift() ||
646 ShAmt = Sh->getZExtValue();
647 if (isShifterOpProfitable(N.
getOperand(0), ShOpcVal, ShAmt)) {
673 (!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.
hasOneUse())) {
685 unsigned ShAmt =
Log2_32(RHSC);
698 !CurDAG->isBaseWithConstantOffset(N)) {
701 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
702 Base = CurDAG->getTargetFrameIndex(FI,
703 getTargetLowering()->getPointerTy());
705 !(Subtarget->useMovt() &&
709 Offset = CurDAG->getRegister(0,
MVT::i32);
720 -0x1000+1, 0x1000, RHSC)) {
723 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
724 Base = CurDAG->getTargetFrameIndex(FI,
725 getTargetLowering()->getPointerTy());
727 Offset = CurDAG->getRegister(0,
MVT::i32);
741 if ((Subtarget->isLikeA9() || Subtarget->isSwift()) && !N.
hasOneUse()) {
744 Offset = CurDAG->getRegister(0,
MVT::i32);
765 ShAmt = Sh->getZExtValue();
766 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
779 !(Subtarget->isLikeA9() || Subtarget->isSwift() ||
787 ShAmt = Sh->getZExtValue();
788 if (isShifterOpProfitable(N.
getOperand(0), ShOpcVal, ShAmt)) {
806 bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(
SDNode *Op,
SDValue N,
810 ? cast<LoadSDNode>(Op)->getAddressingMode()
811 : cast<StoreSDNode>(Op)->getAddressingMode();
825 ShAmt = Sh->getZExtValue();
826 if (isShifterOpProfitable(N, ShOpcVal, ShAmt))
842 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(
SDNode *Op,
SDValue N,
846 ? cast<LoadSDNode>(Op)->getAddressingMode()
847 : cast<StoreSDNode>(Op)->getAddressingMode();
853 Offset = CurDAG->getRegister(0,
MVT::i32);
854 Opc = CurDAG->getTargetConstant(Val,
MVT::i32);
862 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(
SDNode *Op,
SDValue N,
866 ? cast<LoadSDNode>(Op)->getAddressingMode()
867 : cast<StoreSDNode>(Op)->getAddressingMode();
872 Offset = CurDAG->getRegister(0,
MVT::i32);
882 bool ARMDAGToDAGISel::SelectAddrOffsetNone(
SDValue N,
SDValue &Base) {
887 bool ARMDAGToDAGISel::SelectAddrMode3(
SDValue N,
898 if (!CurDAG->isBaseWithConstantOffset(N)) {
901 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
902 Base = CurDAG->getTargetFrameIndex(FI,
903 getTargetLowering()->getPointerTy());
905 Offset = CurDAG->getRegister(0,
MVT::i32);
913 -256 + 1, 256, RHSC)) {
916 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
917 Base = CurDAG->getTargetFrameIndex(FI,
918 getTargetLowering()->getPointerTy());
920 Offset = CurDAG->getRegister(0,
MVT::i32);
937 bool ARMDAGToDAGISel::SelectAddrMode3Offset(
SDNode *Op,
SDValue N,
941 ? cast<LoadSDNode>(Op)->getAddressingMode()
942 : cast<StoreSDNode>(Op)->getAddressingMode();
947 Offset = CurDAG->getRegister(0,
MVT::i32);
957 bool ARMDAGToDAGISel::SelectAddrMode5(
SDValue N,
959 if (!CurDAG->isBaseWithConstantOffset(N)) {
962 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
963 Base = CurDAG->getTargetFrameIndex(FI,
964 getTargetLowering()->getPointerTy());
966 !(Subtarget->useMovt() &&
978 -256 + 1, 256, RHSC)) {
981 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
982 Base = CurDAG->getTargetFrameIndex(FI,
983 getTargetLowering()->getPointerTy());
1006 unsigned Alignment = 0;
1007 if (
LSBaseSDNode *LSN = dyn_cast<LSBaseSDNode>(Parent)) {
1010 unsigned LSNAlign = LSN->getAlignment();
1011 unsigned MemSize = LSN->getMemoryVT().getSizeInBits() / 8;
1012 if (LSNAlign >= MemSize && MemSize > 1)
1013 Alignment = MemSize;
1018 Alignment = cast<MemIntrinsicSDNode>(Parent)->getAlignment();
1021 Align = CurDAG->getTargetConstant(Alignment,
MVT::i32);
1025 bool ARMDAGToDAGISel::SelectAddrMode6Offset(
SDNode *Op,
SDValue N,
1034 Offset = CurDAG->getRegister(0,
MVT::i32);
1039 bool ARMDAGToDAGISel::SelectAddrModePC(
SDValue N,
1044 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
1057 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(
SDValue N,
1075 SDValue &Offset,
unsigned Scale) {
1078 if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm))
1086 if (!CurDAG->isBaseWithConstantOffset(N))
1092 if ((LHSR && LHSR->
getReg() == ARM::SP) ||
1093 (RHSR && RHSR->getReg() == ARM::SP))
1109 ARMDAGToDAGISel::SelectThumbAddrModeRI5S1(
SDValue N,
1112 return SelectThumbAddrModeRI(N, Base, Offset, 1);
1116 ARMDAGToDAGISel::SelectThumbAddrModeRI5S2(
SDValue N,
1119 return SelectThumbAddrModeRI(N, Base, Offset, 2);
1123 ARMDAGToDAGISel::SelectThumbAddrModeRI5S4(
SDValue N,
1126 return SelectThumbAddrModeRI(N, Base, Offset, 4);
1130 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(
SDValue N,
unsigned Scale,
1134 if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm))
1142 if (!CurDAG->isBaseWithConstantOffset(N)) {
1144 !(Subtarget->useMovt() &&
1151 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1157 if ((LHSR && LHSR->
getReg() == ARM::SP) ||
1158 (RHSR && RHSR->getReg() == ARM::SP)) {
1162 unsigned RHSC = RHS ? RHS->getZExtValue() : 0;
1165 if (LHSC != 0 || RHSC != 0)
return false;
1168 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1176 OffImm = CurDAG->getTargetConstant(RHSC,
MVT::i32);
1181 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1186 ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(
SDValue N,
SDValue &Base,
1188 return SelectThumbAddrModeImm5S(N, 4, Base, OffImm);
1192 ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(
SDValue N,
SDValue &Base,
1194 return SelectThumbAddrModeImm5S(N, 2, Base, OffImm);
1198 ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(
SDValue N,
SDValue &Base,
1200 return SelectThumbAddrModeImm5S(N, 1, Base, OffImm);
1203 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(
SDValue N,
1206 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1207 Base = CurDAG->getTargetFrameIndex(FI,
1208 getTargetLowering()->getPointerTy());
1209 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1213 if (!CurDAG->isBaseWithConstantOffset(N))
1218 (LHSR && LHSR->
getReg() == ARM::SP)) {
1224 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1225 Base = CurDAG->getTargetFrameIndex(FI,
1226 getTargetLowering()->getPointerTy());
1228 OffImm = CurDAG->getTargetConstant(RHSC,
MVT::i32);
1242 bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(
SDValue N,
SDValue &BaseReg,
1254 unsigned ShImmVal = 0;
1256 ShImmVal = RHS->getZExtValue() & 31;
1264 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(
SDValue N,
1270 !CurDAG->isBaseWithConstantOffset(N)) {
1273 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1274 Base = CurDAG->getTargetFrameIndex(FI,
1275 getTargetLowering()->getPointerTy());
1276 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1281 !(Subtarget->useMovt() &&
1288 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1293 if (SelectT2AddrModeImm8(N, Base, OffImm))
1297 int RHSC = (int)RHS->getZExtValue();
1301 if (RHSC >= 0 && RHSC < 0x1000) {
1304 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1305 Base = CurDAG->getTargetFrameIndex(FI,
1306 getTargetLowering()->getPointerTy());
1308 OffImm = CurDAG->getTargetConstant(RHSC,
MVT::i32);
1315 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1319 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(
SDValue N,
1323 !CurDAG->isBaseWithConstantOffset(N))
1327 int RHSC = (int)RHS->getSExtValue();
1331 if ((RHSC >= -255) && (RHSC < 0)) {
1334 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1335 Base = CurDAG->getTargetFrameIndex(FI,
1336 getTargetLowering()->getPointerTy());
1338 OffImm = CurDAG->getTargetConstant(RHSC,
MVT::i32);
1346 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(
SDNode *Op,
SDValue N,
1350 ? cast<LoadSDNode>(Op)->getAddressingMode()
1351 : cast<StoreSDNode>(Op)->getAddressingMode();
1355 ? CurDAG->getTargetConstant(RHSC,
MVT::i32)
1356 : CurDAG->getTargetConstant(-RHSC,
MVT::i32);
1363 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(
SDValue N,
1372 int RHSC = (int)RHS->getZExtValue();
1373 if (RHSC >= 0 && RHSC < 0x1000)
1375 else if (RHSC < 0 && RHSC >= -255)
1396 ShAmt = Sh->getZExtValue();
1397 if (ShAmt < 4 && isShifterOpProfitable(OffReg, ShOpcVal, ShAmt))
1408 ShImm = CurDAG->getTargetConstant(ShAmt,
MVT::i32);
1413 bool ARMDAGToDAGISel::SelectT2AddrModeExclusive(
SDValue N,
SDValue &Base,
1418 OffImm = CurDAG->getTargetConstant(0,
MVT::i32);
1428 if (RHSC > 1020 || RHSC % 4 != 0)
1433 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1434 Base = CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy());
1437 OffImm = CurDAG->getTargetConstant(RHSC / 4,
MVT::i32);
1448 SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(
SDNode *N) {
1457 unsigned Opcode = 0;
1459 if (LoadedVT ==
MVT::i32 && isPre &&
1460 SelectAddrMode2OffsetImmPre(N, LD->
getOffset(), Offset, AMOpc)) {
1461 Opcode = ARM::LDR_PRE_IMM;
1463 }
else if (LoadedVT ==
MVT::i32 && !isPre &&
1464 SelectAddrMode2OffsetImm(N, LD->
getOffset(), Offset, AMOpc)) {
1465 Opcode = ARM::LDR_POST_IMM;
1468 SelectAddrMode2OffsetReg(N, LD->
getOffset(), Offset, AMOpc)) {
1469 Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG;
1473 SelectAddrMode3Offset(N, LD->
getOffset(), Offset, AMOpc)) {
1476 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
1477 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
1480 if (SelectAddrMode3Offset(N, LD->
getOffset(), Offset, AMOpc)) {
1482 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
1486 SelectAddrMode2OffsetImmPre(N, LD->
getOffset(), Offset, AMOpc)) {
1488 Opcode = ARM::LDRB_PRE_IMM;
1489 }
else if (!isPre &&
1490 SelectAddrMode2OffsetImm(N, LD->
getOffset(), Offset, AMOpc)) {
1492 Opcode = ARM::LDRB_POST_IMM;
1493 }
else if (SelectAddrMode2OffsetReg(N, LD->
getOffset(), Offset, AMOpc)) {
1495 Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG;
1501 if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) {
1505 CurDAG->getRegister(0,
MVT::i32), Chain };
1512 CurDAG->getRegister(0,
MVT::i32), Chain };
1521 SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(
SDNode *N) {
1531 unsigned Opcode = 0;
1533 if (SelectT2AddrModeImm8Offset(N, LD->
getOffset(), Offset)) {
1536 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST;
1540 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST;
1542 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST;
1547 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST;
1549 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST;
1561 CurDAG->getRegister(0,
MVT::i32), Chain };
1573 CurDAG->getTargetConstant(ARM::GPRPairRegClassID,
MVT::i32);
1576 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1584 CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID,
MVT::i32);
1587 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1594 SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID,
MVT::i32);
1597 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1604 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID,
MVT::i32);
1607 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
1616 CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID,
MVT::i32);
1621 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1622 V2, SubReg2, V3, SubReg3 };
1630 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID,
MVT::i32);
1635 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1636 V2, SubReg2, V3, SubReg3 };
1644 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID,
MVT::i32);
1649 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
1650 V2, SubReg2, V3, SubReg3 };
1657 SDValue ARMDAGToDAGISel::GetVLDSTAlign(
SDValue Align,
unsigned NumVecs,
1658 bool is64BitVector) {
1659 unsigned NumRegs = NumVecs;
1660 if (!is64BitVector && NumVecs < 3)
1663 unsigned Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
1664 if (Alignment >= 32 && NumRegs == 4)
1666 else if (Alignment >= 16 && (NumRegs == 2 || NumRegs == 4))
1668 else if (Alignment >= 8)
1673 return CurDAG->getTargetConstant(Alignment,
MVT::i32);
1681 case ARM::VLD1d8wb_fixed:
return ARM::VLD1d8wb_register;
1682 case ARM::VLD1d16wb_fixed:
return ARM::VLD1d16wb_register;
1683 case ARM::VLD1d32wb_fixed:
return ARM::VLD1d32wb_register;
1684 case ARM::VLD1d64wb_fixed:
return ARM::VLD1d64wb_register;
1685 case ARM::VLD1q8wb_fixed:
return ARM::VLD1q8wb_register;
1686 case ARM::VLD1q16wb_fixed:
return ARM::VLD1q16wb_register;
1687 case ARM::VLD1q32wb_fixed:
return ARM::VLD1q32wb_register;
1688 case ARM::VLD1q64wb_fixed:
return ARM::VLD1q64wb_register;
1690 case ARM::VST1d8wb_fixed:
return ARM::VST1d8wb_register;
1691 case ARM::VST1d16wb_fixed:
return ARM::VST1d16wb_register;
1692 case ARM::VST1d32wb_fixed:
return ARM::VST1d32wb_register;
1693 case ARM::VST1d64wb_fixed:
return ARM::VST1d64wb_register;
1694 case ARM::VST1q8wb_fixed:
return ARM::VST1q8wb_register;
1695 case ARM::VST1q16wb_fixed:
return ARM::VST1q16wb_register;
1696 case ARM::VST1q32wb_fixed:
return ARM::VST1q32wb_register;
1697 case ARM::VST1q64wb_fixed:
return ARM::VST1q64wb_register;
1698 case ARM::VST1d64TPseudoWB_fixed:
return ARM::VST1d64TPseudoWB_register;
1699 case ARM::VST1d64QPseudoWB_fixed:
return ARM::VST1d64QPseudoWB_register;
1701 case ARM::VLD2d8wb_fixed:
return ARM::VLD2d8wb_register;
1702 case ARM::VLD2d16wb_fixed:
return ARM::VLD2d16wb_register;
1703 case ARM::VLD2d32wb_fixed:
return ARM::VLD2d32wb_register;
1704 case ARM::VLD2q8PseudoWB_fixed:
return ARM::VLD2q8PseudoWB_register;
1705 case ARM::VLD2q16PseudoWB_fixed:
return ARM::VLD2q16PseudoWB_register;
1706 case ARM::VLD2q32PseudoWB_fixed:
return ARM::VLD2q32PseudoWB_register;
1708 case ARM::VST2d8wb_fixed:
return ARM::VST2d8wb_register;
1709 case ARM::VST2d16wb_fixed:
return ARM::VST2d16wb_register;
1710 case ARM::VST2d32wb_fixed:
return ARM::VST2d32wb_register;
1711 case ARM::VST2q8PseudoWB_fixed:
return ARM::VST2q8PseudoWB_register;
1712 case ARM::VST2q16PseudoWB_fixed:
return ARM::VST2q16PseudoWB_register;
1713 case ARM::VST2q32PseudoWB_fixed:
return ARM::VST2q32PseudoWB_register;
1715 case ARM::VLD2DUPd8wb_fixed:
return ARM::VLD2DUPd8wb_register;
1716 case ARM::VLD2DUPd16wb_fixed:
return ARM::VLD2DUPd16wb_register;
1717 case ARM::VLD2DUPd32wb_fixed:
return ARM::VLD2DUPd32wb_register;
1722 SDNode *ARMDAGToDAGISel::SelectVLD(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
1723 const uint16_t *DOpcodes,
1724 const uint16_t *QOpcodes0,
1725 const uint16_t *QOpcodes1) {
1726 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VLD NumVecs out-of-range");
1730 unsigned AddrOpIdx = isUpdating ? 1 : 2;
1737 Align = GetVLDSTAlign(Align, NumVecs, is64BitVector);
1739 unsigned OpcodeIndex;
1754 assert(NumVecs == 1 &&
"v2i64 type only supported for VLD1");
1762 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
1767 std::vector<EVT> ResTys;
1768 ResTys.push_back(ResTy);
1779 if (is64BitVector || NumVecs <= 2) {
1780 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] :
1781 QOpcodes0[OpcodeIndex]);
1788 if ((NumVecs == 1 || NumVecs == 2) && !isa<ConstantSDNode>(Inc.
getNode()))
1792 if ((NumVecs != 1 && NumVecs != 2 && Opc != ARM::VLD1q64wb_fixed) ||
1793 !isa<ConstantSDNode>(Inc.
getNode()))
1799 VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1810 const SDValue OpsA[] = { MemAddr,
Align, Reg0, ImplDef, Pred, Reg0, Chain };
1811 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
1820 assert(isa<ConstantSDNode>(Inc.
getNode()) &&
1821 "only constant post-increment update allowed for VLD3/4");
1829 VLd = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, Ops);
1834 MemOp[0] = cast<MemIntrinsicSDNode>(
N)->getMemOperand();
1835 cast<MachineSDNode>(VLd)->setMemRefs(MemOp, MemOp + 1);
1842 assert(ARM::dsub_7 == ARM::dsub_0+7 &&
1843 ARM::qsub_3 == ARM::qsub_0+3 &&
"Unexpected subreg numbering");
1844 unsigned Sub0 = (is64BitVector ? ARM::dsub_0 : ARM::qsub_0);
1845 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
1847 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
1854 SDNode *ARMDAGToDAGISel::SelectVST(
SDNode *N,
bool isUpdating,
unsigned NumVecs,
1855 const uint16_t *DOpcodes,
1856 const uint16_t *QOpcodes0,
1857 const uint16_t *QOpcodes1) {
1858 assert(NumVecs >= 1 && NumVecs <= 4 &&
"VST NumVecs out-of-range");
1862 unsigned AddrOpIdx = isUpdating ? 1 : 2;
1863 unsigned Vec0Idx = 3;
1868 MemOp[0] = cast<MemIntrinsicSDNode>(
N)->getMemOperand();
1873 Align = GetVLDSTAlign(Align, NumVecs, is64BitVector);
1875 unsigned OpcodeIndex;
1890 assert(NumVecs == 1 &&
"v2i64 type only supported for VST1");
1894 std::vector<EVT> ResTys;
1904 if (is64BitVector || NumVecs <= 2) {
1908 }
else if (is64BitVector) {
1930 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] :
1931 QOpcodes0[OpcodeIndex]);
1938 if (NumVecs <= 2 && !isa<ConstantSDNode>(Inc.
getNode()))
1942 if ((NumVecs > 2 && Opc != ARM::VST1q64wb_fixed) ||
1943 !isa<ConstantSDNode>(Inc.
getNode()))
1950 SDNode *VSt = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1953 cast<MachineSDNode>(VSt)->setMemRefs(MemOp, MemOp + 1);
1972 const SDValue OpsA[] = { MemAddr,
Align, Reg0, RegSeq, Pred, Reg0, Chain };
1973 SDNode *VStA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
1976 cast<MachineSDNode>(VStA)->setMemRefs(MemOp, MemOp + 1);
1984 assert(isa<ConstantSDNode>(Inc.
getNode()) &&
1985 "only constant post-increment update allowed for VST3/4");
1993 SDNode *VStB = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys,
1995 cast<MachineSDNode>(VStB)->setMemRefs(MemOp, MemOp + 1);
1999 SDNode *ARMDAGToDAGISel::SelectVLDSTLane(
SDNode *N,
bool IsLoad,
2000 bool isUpdating,
unsigned NumVecs,
2001 const uint16_t *DOpcodes,
2002 const uint16_t *QOpcodes) {
2003 assert(NumVecs >=2 && NumVecs <= 4 &&
"VLDSTLane NumVecs out-of-range");
2007 unsigned AddrOpIdx = isUpdating ? 1 : 2;
2008 unsigned Vec0Idx = 3;
2013 MemOp[0] = cast<MemIntrinsicSDNode>(
N)->getMemOperand();
2017 cast<ConstantSDNode>(N->
getOperand(Vec0Idx + NumVecs))->getZExtValue();
2021 unsigned Alignment = 0;
2023 Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
2025 if (Alignment > NumBytes)
2026 Alignment = NumBytes;
2027 if (Alignment < 8 && Alignment < NumBytes)
2030 Alignment = (Alignment & -Alignment);
2034 Align = CurDAG->getTargetConstant(Alignment,
MVT::i32);
2036 unsigned OpcodeIndex;
2050 std::vector<EVT> ResTys;
2052 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
2097 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] :
2098 QOpcodes[OpcodeIndex]);
2099 SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2100 cast<MachineSDNode>(VLdLn)->setMemRefs(MemOp, MemOp + 1);
2106 assert(ARM::dsub_7 == ARM::dsub_0+7 &&
2107 ARM::qsub_3 == ARM::qsub_0+3 &&
"Unexpected subreg numbering");
2108 unsigned Sub0 = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
2109 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
2111 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
2118 SDNode *ARMDAGToDAGISel::SelectVLDDup(
SDNode *N,
bool isUpdating,
2120 const uint16_t *Opcodes) {
2121 assert(NumVecs >=2 && NumVecs <= 4 &&
"VLDDup NumVecs out-of-range");
2129 MemOp[0] = cast<MemIntrinsicSDNode>(
N)->getMemOperand();
2134 unsigned Alignment = 0;
2136 Alignment = cast<ConstantSDNode>(
Align)->getZExtValue();
2138 if (Alignment > NumBytes)
2139 Alignment = NumBytes;
2140 if (Alignment < 8 && Alignment < NumBytes)
2143 Alignment = (Alignment & -Alignment);
2147 Align = CurDAG->getTargetConstant(Alignment,
MVT::i32);
2149 unsigned OpcodeIndex;
2161 unsigned Opc = Opcodes[OpcodeIndex];
2169 if (!isa<ConstantSDNode>(Inc.
getNode()))
2172 else if (NumVecs > 2)
2179 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
2180 std::vector<EVT> ResTys;
2185 SDNode *VLdDup = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2186 cast<MachineSDNode>(VLdDup)->setMemRefs(MemOp, MemOp + 1);
2187 SuperReg =
SDValue(VLdDup, 0);
2190 assert(ARM::dsub_7 == ARM::dsub_0+7 &&
"Unexpected subreg numbering");
2191 unsigned SubIdx = ARM::dsub_0;
2192 for (
unsigned Vec = 0; Vec < NumVecs; ++Vec)
2194 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, SuperReg));
2201 SDNode *ARMDAGToDAGISel::SelectVTBL(
SDNode *N,
bool IsExt,
unsigned NumVecs,
2203 assert(NumVecs >= 2 && NumVecs <= 4 &&
"VTBL NumVecs out-of-range");
2206 unsigned FirstTblReg = IsExt ? 2 : 1;
2231 return CurDAG->getMachineNode(Opc, dl, VT, Ops);
2234 SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(
SDNode *N,
2236 if (!Subtarget->hasV6T2Ops())
2239 unsigned Opc = isSigned
2240 ? (Subtarget->isThumb() ? ARM::t2SBFX :
ARM::SBFX)
2241 : (Subtarget->isThumb() ? ARM::t2UBFX :
ARM::UBFX);
2244 unsigned And_imm = 0;
2249 if (And_imm & (And_imm + 1))
2252 unsigned Srl_imm = 0;
2255 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2259 unsigned LSB = Srl_imm;
2265 if (Subtarget->isThumb()) {
2266 Opc = isSigned ? ARM::t2ASRri : ARM::t2LSRri;
2268 CurDAG->getTargetConstant(LSB,
MVT::i32),
2269 getAL(CurDAG), Reg0, Reg0 };
2270 return CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops, 5);
2279 getAL(CurDAG), Reg0, Reg0 };
2280 return CurDAG->SelectNodeTo(N, ARM::MOVsi,
MVT::i32, Ops, 5);
2284 CurDAG->getTargetConstant(LSB,
MVT::i32),
2285 CurDAG->getTargetConstant(Width,
MVT::i32),
2286 getAL(CurDAG), Reg0 };
2287 return CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops, 5);
2294 unsigned Shl_imm = 0;
2296 assert(Shl_imm > 0 && Shl_imm < 32 &&
"bad amount in shift node!");
2297 unsigned Srl_imm = 0;
2299 assert(Srl_imm > 0 && Srl_imm < 32 &&
"bad amount in shift node!");
2301 unsigned Width = 32 - Srl_imm - 1;
2302 int LSB = Srl_imm - Shl_imm;
2307 CurDAG->getTargetConstant(LSB,
MVT::i32),
2308 CurDAG->getTargetConstant(Width,
MVT::i32),
2309 getAL(CurDAG), Reg0 };
2310 return CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops, 5);
2331 if (Subtarget->isThumb1Only())
2345 if (ADDSrc1 == XORSrc1 && ADDSrc0 == SRASrc0 &&
2346 XType.isInteger() && SRAConstant != NULL &&
2348 unsigned Opcode = Subtarget->isThumb2() ? ARM::t2ABS : ARM::ABS;
2349 return CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0);
2355 SDNode *ARMDAGToDAGISel::SelectConcatVector(
SDNode *N) {
2364 SDNode *ARMDAGToDAGISel::SelectAtomic(
SDNode *Node,
unsigned Op8,
2365 unsigned Op16,
unsigned Op32,
2393 return CurDAG->SelectNodeTo(Node, Op, VTs, &Ops[0], Ops.
size());
2407 SDNode *ResNode = SelectInlineAsm(N);
2414 SDNode *ResNode = SelectABSOp(N);
2421 unsigned Val = cast<ConstantSDNode>(
N)->getZExtValue();
2423 if (Subtarget->hasThumb2())
2428 if (Subtarget->isThumb()) {
2429 UseCP = (Val > 255 &&
2442 getTargetLowering()->getPointerTy());
2445 if (Subtarget->isThumb1Only()) {
2448 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() };
2454 CurDAG->getTargetConstant(0,
MVT::i32),
2457 CurDAG->getEntryNode()
2471 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
2472 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
2473 getTargetLowering()->getPointerTy());
2474 if (Subtarget->isThumb1Only()) {
2477 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi,
MVT::i32, Ops, 4);
2479 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ?
2480 ARM::t2ADDri : ARM::ADDri);
2483 CurDAG->getRegister(0,
MVT::i32) };
2484 return CurDAG->SelectNodeTo(N, Opc,
MVT::i32, Ops, 5);
2488 if (
SDNode *
I = SelectV6T2BitfieldExtractOp(N,
false))
2492 if (
SDNode *
I = SelectV6T2BitfieldExtractOp(N,
true))
2496 if (Subtarget->isThumb1Only())
2499 unsigned RHSV =
C->getZExtValue();
2502 unsigned ShImm =
Log2_32(RHSV-1);
2509 if (Subtarget->isThumb()) {
2510 SDValue Ops[] = { V, V, ShImmOp,
getAL(CurDAG), Reg0, Reg0 };
2511 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs,
MVT::i32, Ops, 6);
2513 SDValue Ops[] = { V, V, Reg0, ShImmOp,
getAL(CurDAG), Reg0, Reg0 };
2514 return CurDAG->SelectNodeTo(N, ARM::ADDrsi,
MVT::i32, Ops, 7);
2518 unsigned ShImm =
Log2_32(RHSV+1);
2525 if (Subtarget->isThumb()) {
2526 SDValue Ops[] = { V, V, ShImmOp,
getAL(CurDAG), Reg0, Reg0 };
2527 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs,
MVT::i32, Ops, 6);
2529 SDValue Ops[] = { V, V, Reg0, ShImmOp,
getAL(CurDAG), Reg0, Reg0 };
2530 return CurDAG->SelectNodeTo(N, ARM::RSBrsi,
MVT::i32, Ops, 7);
2537 if (
SDNode *
I = SelectV6T2BitfieldExtractOp(N,
false))
2548 unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2())
2550 : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0);
2564 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) &&
2565 (N1CVal & 0xffffU) == 0xffffU &&
2566 (N2CVal & 0xffffU) == 0x0U) {
2567 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16,
2571 return CurDAG->getMachineNode(Opc, dl, VT, Ops);
2581 if (Subtarget->isThumb1Only())
2583 if (Subtarget->isThumb()) {
2590 CurDAG->getRegister(0,
MVT::i32) };
2591 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
2592 ARM::UMULL : ARM::UMULLv5,
2597 if (Subtarget->isThumb1Only())
2599 if (Subtarget->isThumb()) {
2606 CurDAG->getRegister(0,
MVT::i32) };
2607 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
2608 ARM::SMULL : ARM::SMULLv5,
2613 if (Subtarget->isThumb()) {
2622 CurDAG->getRegister(0,
MVT::i32) };
2623 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
2629 if (Subtarget->isThumb()) {
2638 CurDAG->getRegister(0,
MVT::i32) };
2639 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
2646 if (Subtarget->isThumb() && Subtarget->hasThumb2())
2647 ResNode = SelectT2IndexedLoad(N);
2649 ResNode = SelectARMIndexedLoad(N);
2668 unsigned Opc = Subtarget->isThumb() ?
2669 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc;
2679 SDValue Tmp2 = CurDAG->getTargetConstant(((
unsigned)
2680 cast<ConstantSDNode>(N2)->getZExtValue()),
2682 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag };
2688 ReplaceUses(
SDValue(N, 1), InFlag);
2698 default:
return NULL;
2699 case MVT::v8i8: Opc = ARM::VZIPd8;
break;
2712 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops);
2718 default:
return NULL;
2719 case MVT::v8i8: Opc = ARM::VUZPd8;
break;
2732 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops);
2738 default:
return NULL;
2739 case MVT::v8i8: Opc = ARM::VTRNd8;
break;
2751 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops);
2758 assert(NumElts == 2 &&
"unexpected type for BUILD_VECTOR");
2761 assert(EltVT ==
MVT::f32 &&
"unexpected type for BUILD_VECTOR");
2764 assert(NumElts == 4 &&
"unexpected type for BUILD_VECTOR");
2770 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16,
2772 return SelectVLDDup(N,
false, 2, Opcodes);
2776 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo,
2777 ARM::VLD3DUPd16Pseudo,
2778 ARM::VLD3DUPd32Pseudo };
2779 return SelectVLDDup(N,
false, 3, Opcodes);
2783 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo,
2784 ARM::VLD4DUPd16Pseudo,
2785 ARM::VLD4DUPd32Pseudo };
2786 return SelectVLDDup(N,
false, 4, Opcodes);
2790 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8wb_fixed,
2791 ARM::VLD2DUPd16wb_fixed,
2792 ARM::VLD2DUPd32wb_fixed };
2793 return SelectVLDDup(N,
true, 2, Opcodes);
2797 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo_UPD,
2798 ARM::VLD3DUPd16Pseudo_UPD,
2799 ARM::VLD3DUPd32Pseudo_UPD };
2800 return SelectVLDDup(N,
true, 3, Opcodes);
2804 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo_UPD,
2805 ARM::VLD4DUPd16Pseudo_UPD,
2806 ARM::VLD4DUPd32Pseudo_UPD };
2807 return SelectVLDDup(N,
true, 4, Opcodes);
2811 static const uint16_t DOpcodes[] = { ARM::VLD1d8wb_fixed,
2812 ARM::VLD1d16wb_fixed,
2813 ARM::VLD1d32wb_fixed,
2814 ARM::VLD1d64wb_fixed };
2815 static const uint16_t QOpcodes[] = { ARM::VLD1q8wb_fixed,
2816 ARM::VLD1q16wb_fixed,
2817 ARM::VLD1q32wb_fixed,
2818 ARM::VLD1q64wb_fixed };
2819 return SelectVLD(N,
true, 1, DOpcodes, QOpcodes, 0);
2823 static const uint16_t DOpcodes[] = { ARM::VLD2d8wb_fixed,
2824 ARM::VLD2d16wb_fixed,
2825 ARM::VLD2d32wb_fixed,
2826 ARM::VLD1q64wb_fixed};
2827 static const uint16_t QOpcodes[] = { ARM::VLD2q8PseudoWB_fixed,
2828 ARM::VLD2q16PseudoWB_fixed,
2829 ARM::VLD2q32PseudoWB_fixed };
2830 return SelectVLD(N,
true, 2, DOpcodes, QOpcodes, 0);
2834 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD,
2835 ARM::VLD3d16Pseudo_UPD,
2836 ARM::VLD3d32Pseudo_UPD,
2837 ARM::VLD1q64wb_fixed};
2838 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
2839 ARM::VLD3q16Pseudo_UPD,
2840 ARM::VLD3q32Pseudo_UPD };
2841 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo_UPD,
2842 ARM::VLD3q16oddPseudo_UPD,
2843 ARM::VLD3q32oddPseudo_UPD };
2844 return SelectVLD(N,
true, 3, DOpcodes, QOpcodes0, QOpcodes1);
2848 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD,
2849 ARM::VLD4d16Pseudo_UPD,
2850 ARM::VLD4d32Pseudo_UPD,
2851 ARM::VLD1q64wb_fixed};
2852 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
2853 ARM::VLD4q16Pseudo_UPD,
2854 ARM::VLD4q32Pseudo_UPD };
2855 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo_UPD,
2856 ARM::VLD4q16oddPseudo_UPD,
2857 ARM::VLD4q32oddPseudo_UPD };
2858 return SelectVLD(N,
true, 4, DOpcodes, QOpcodes0, QOpcodes1);
2862 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo_UPD,
2863 ARM::VLD2LNd16Pseudo_UPD,
2864 ARM::VLD2LNd32Pseudo_UPD };
2865 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo_UPD,
2866 ARM::VLD2LNq32Pseudo_UPD };
2867 return SelectVLDSTLane(N,
true,
true, 2, DOpcodes, QOpcodes);
2871 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo_UPD,
2872 ARM::VLD3LNd16Pseudo_UPD,
2873 ARM::VLD3LNd32Pseudo_UPD };
2874 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo_UPD,
2875 ARM::VLD3LNq32Pseudo_UPD };
2876 return SelectVLDSTLane(N,
true,
true, 3, DOpcodes, QOpcodes);
2880 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo_UPD,
2881 ARM::VLD4LNd16Pseudo_UPD,
2882 ARM::VLD4LNd32Pseudo_UPD };
2883 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo_UPD,
2884 ARM::VLD4LNq32Pseudo_UPD };
2885 return SelectVLDSTLane(N,
true,
true, 4, DOpcodes, QOpcodes);
2889 static const uint16_t DOpcodes[] = { ARM::VST1d8wb_fixed,
2890 ARM::VST1d16wb_fixed,
2891 ARM::VST1d32wb_fixed,
2892 ARM::VST1d64wb_fixed };
2893 static const uint16_t QOpcodes[] = { ARM::VST1q8wb_fixed,
2894 ARM::VST1q16wb_fixed,
2895 ARM::VST1q32wb_fixed,
2896 ARM::VST1q64wb_fixed };
2897 return SelectVST(N,
true, 1, DOpcodes, QOpcodes, 0);
2901 static const uint16_t DOpcodes[] = { ARM::VST2d8wb_fixed,
2902 ARM::VST2d16wb_fixed,
2903 ARM::VST2d32wb_fixed,
2904 ARM::VST1q64wb_fixed};
2905 static const uint16_t QOpcodes[] = { ARM::VST2q8PseudoWB_fixed,
2906 ARM::VST2q16PseudoWB_fixed,
2907 ARM::VST2q32PseudoWB_fixed };
2908 return SelectVST(N,
true, 2, DOpcodes, QOpcodes, 0);
2912 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo_UPD,
2913 ARM::VST3d16Pseudo_UPD,
2914 ARM::VST3d32Pseudo_UPD,
2915 ARM::VST1d64TPseudoWB_fixed};
2916 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
2917 ARM::VST3q16Pseudo_UPD,
2918 ARM::VST3q32Pseudo_UPD };
2919 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD,
2920 ARM::VST3q16oddPseudo_UPD,
2921 ARM::VST3q32oddPseudo_UPD };
2922 return SelectVST(N,
true, 3, DOpcodes, QOpcodes0, QOpcodes1);
2926 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo_UPD,
2927 ARM::VST4d16Pseudo_UPD,
2928 ARM::VST4d32Pseudo_UPD,
2929 ARM::VST1d64QPseudoWB_fixed};
2930 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
2931 ARM::VST4q16Pseudo_UPD,
2932 ARM::VST4q32Pseudo_UPD };
2933 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD,
2934 ARM::VST4q16oddPseudo_UPD,
2935 ARM::VST4q32oddPseudo_UPD };
2936 return SelectVST(N,
true, 4, DOpcodes, QOpcodes0, QOpcodes1);
2940 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo_UPD,
2941 ARM::VST2LNd16Pseudo_UPD,
2942 ARM::VST2LNd32Pseudo_UPD };
2943 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo_UPD,
2944 ARM::VST2LNq32Pseudo_UPD };
2945 return SelectVLDSTLane(N,
false,
true, 2, DOpcodes, QOpcodes);
2949 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo_UPD,
2950 ARM::VST3LNd16Pseudo_UPD,
2951 ARM::VST3LNd32Pseudo_UPD };
2952 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo_UPD,
2953 ARM::VST3LNq32Pseudo_UPD };
2954 return SelectVLDSTLane(N,
false,
true, 3, DOpcodes, QOpcodes);
2958 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo_UPD,
2959 ARM::VST4LNd16Pseudo_UPD,
2960 ARM::VST4LNd32Pseudo_UPD };
2961 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo_UPD,
2962 ARM::VST4LNq32Pseudo_UPD };
2963 return SelectVLDSTLane(N,
false,
true, 4, DOpcodes, QOpcodes);
2968 unsigned IntNo = cast<ConstantSDNode>(N->
getOperand(1))->getZExtValue();
2978 bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2();
2979 unsigned NewOpc = isThumb ? ARM::t2LDREXD :ARM::LDREXD;
2982 std::vector<EVT> ResTys;
2996 SDNode *Ld = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
2999 MemOp[0] = cast<MemIntrinsicSDNode>(
N)->getMemOperand();
3000 cast<MachineSDNode>(Ld)->setMemRefs(MemOp, MemOp + 1);
3004 if (!SDValue(N, 0).use_empty()) {
3007 Result = SDValue(Ld, 0);
3009 SDValue SubRegIdx = CurDAG->getTargetConstant(ARM::gsub_0,
MVT::i32);
3011 dl,
MVT::i32, SDValue(Ld, 0), SubRegIdx);
3012 Result = SDValue(ResNode,0);
3014 ReplaceUses(SDValue(N, 0), Result);
3016 if (!SDValue(N, 1).use_empty()) {
3019 Result = SDValue(Ld, 1);
3021 SDValue SubRegIdx = CurDAG->getTargetConstant(ARM::gsub_1,
MVT::i32);
3023 dl,
MVT::i32, SDValue(Ld, 0), SubRegIdx);
3024 Result = SDValue(ResNode,0);
3026 ReplaceUses(SDValue(N, 1), Result);
3028 ReplaceUses(SDValue(N, 2), OutChain);
3043 bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2();
3057 unsigned NewOpc = isThumb ? ARM::t2STREXD : ARM::STREXD;
3059 SDNode *St = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
3062 MemOp[0] = cast<MemIntrinsicSDNode>(
N)->getMemOperand();
3063 cast<MachineSDNode>(St)->setMemRefs(MemOp, MemOp + 1);
3069 static const uint16_t DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16,
3070 ARM::VLD1d32, ARM::VLD1d64 };
3071 static const uint16_t QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16,
3072 ARM::VLD1q32, ARM::VLD1q64};
3073 return SelectVLD(N,
false, 1, DOpcodes, QOpcodes, 0);
3077 static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16,
3078 ARM::VLD2d32, ARM::VLD1q64 };
3079 static const uint16_t QOpcodes[] = { ARM::VLD2q8Pseudo, ARM::VLD2q16Pseudo,
3080 ARM::VLD2q32Pseudo };
3081 return SelectVLD(N,
false, 2, DOpcodes, QOpcodes, 0);
3085 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo,
3088 ARM::VLD1d64TPseudo };
3089 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
3090 ARM::VLD3q16Pseudo_UPD,
3091 ARM::VLD3q32Pseudo_UPD };
3092 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo,
3093 ARM::VLD3q16oddPseudo,
3094 ARM::VLD3q32oddPseudo };
3095 return SelectVLD(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3099 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo,
3102 ARM::VLD1d64QPseudo };
3103 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
3104 ARM::VLD4q16Pseudo_UPD,
3105 ARM::VLD4q32Pseudo_UPD };
3106 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo,
3107 ARM::VLD4q16oddPseudo,
3108 ARM::VLD4q32oddPseudo };
3109 return SelectVLD(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3113 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo,
3114 ARM::VLD2LNd16Pseudo,
3115 ARM::VLD2LNd32Pseudo };
3116 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo,
3117 ARM::VLD2LNq32Pseudo };
3118 return SelectVLDSTLane(N,
true,
false, 2, DOpcodes, QOpcodes);
3122 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo,
3123 ARM::VLD3LNd16Pseudo,
3124 ARM::VLD3LNd32Pseudo };
3125 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo,
3126 ARM::VLD3LNq32Pseudo };
3127 return SelectVLDSTLane(N,
true,
false, 3, DOpcodes, QOpcodes);
3131 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo,
3132 ARM::VLD4LNd16Pseudo,
3133 ARM::VLD4LNd32Pseudo };
3134 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo,
3135 ARM::VLD4LNq32Pseudo };
3136 return SelectVLDSTLane(N,
true,
false, 4, DOpcodes, QOpcodes);
3140 static const uint16_t DOpcodes[] = { ARM::VST1d8, ARM::VST1d16,
3141 ARM::VST1d32, ARM::VST1d64 };
3142 static const uint16_t QOpcodes[] = { ARM::VST1q8, ARM::VST1q16,
3143 ARM::VST1q32, ARM::VST1q64 };
3144 return SelectVST(N,
false, 1, DOpcodes, QOpcodes, 0);
3148 static const uint16_t DOpcodes[] = { ARM::VST2d8, ARM::VST2d16,
3149 ARM::VST2d32, ARM::VST1q64 };
3150 static uint16_t QOpcodes[] = { ARM::VST2q8Pseudo, ARM::VST2q16Pseudo,
3151 ARM::VST2q32Pseudo };
3152 return SelectVST(N,
false, 2, DOpcodes, QOpcodes, 0);
3156 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo,
3159 ARM::VST1d64TPseudo };
3160 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
3161 ARM::VST3q16Pseudo_UPD,
3162 ARM::VST3q32Pseudo_UPD };
3163 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo,
3164 ARM::VST3q16oddPseudo,
3165 ARM::VST3q32oddPseudo };
3166 return SelectVST(N,
false, 3, DOpcodes, QOpcodes0, QOpcodes1);
3170 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo,
3173 ARM::VST1d64QPseudo };
3174 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
3175 ARM::VST4q16Pseudo_UPD,
3176 ARM::VST4q32Pseudo_UPD };
3177 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo,
3178 ARM::VST4q16oddPseudo,
3179 ARM::VST4q32oddPseudo };
3180 return SelectVST(N,
false, 4, DOpcodes, QOpcodes0, QOpcodes1);
3184 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo,
3185 ARM::VST2LNd16Pseudo,
3186 ARM::VST2LNd32Pseudo };
3187 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo,
3188 ARM::VST2LNq32Pseudo };
3189 return SelectVLDSTLane(N,
false,
false, 2, DOpcodes, QOpcodes);
3193 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo,
3194 ARM::VST3LNd16Pseudo,
3195 ARM::VST3LNd32Pseudo };
3196 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo,
3197 ARM::VST3LNq32Pseudo };
3198 return SelectVLDSTLane(N,
false,
false, 3, DOpcodes, QOpcodes);
3202 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo,
3203 ARM::VST4LNd16Pseudo,
3204 ARM::VST4LNd32Pseudo };
3205 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo,
3206 ARM::VST4LNq32Pseudo };
3207 return SelectVLDSTLane(N,
false,
false, 4, DOpcodes, QOpcodes);
3214 unsigned IntNo = cast<ConstantSDNode>(N->
getOperand(0))->getZExtValue();
3222 return SelectVTBL(N,
false, 3, ARM::VTBL3Pseudo);
3224 return SelectVTBL(N,
false, 4, ARM::VTBL4Pseudo);
3227 return SelectVTBL(N,
true, 2, ARM::VTBX2);
3229 return SelectVTBL(N,
true, 3, ARM::VTBX3Pseudo);
3231 return SelectVTBL(N,
true, 4, ARM::VTBX4Pseudo);
3245 return CurDAG->getMachineNode(
ARM::VTBL1, dl, VT, Ops);
3254 SDValue RegSeq = SDValue(createDRegPairNode(
MVT::v16i8, V0, V1), 0);
3261 return CurDAG->getMachineNode(
ARM::VTBL2, dl, VT, Ops);
3265 return SelectConcatVector(N);
3268 if (cast<AtomicSDNode>(N)->getMemoryVT() ==
MVT::i64)
3269 return SelectAtomic(N, 0, 0, 0, ARM::ATOMIC_LOAD_I64);
3274 if (cast<AtomicSDNode>(N)->getMemoryVT() ==
MVT::i64)
3275 return SelectAtomic(N, 0, 0, 0, ARM::ATOMIC_STORE_I64);
3280 return SelectAtomic(N,
3281 ARM::ATOMIC_LOAD_ADD_I8,
3282 ARM::ATOMIC_LOAD_ADD_I16,
3283 ARM::ATOMIC_LOAD_ADD_I32,
3284 ARM::ATOMIC_LOAD_ADD_I64);
3286 return SelectAtomic(N,
3287 ARM::ATOMIC_LOAD_SUB_I8,
3288 ARM::ATOMIC_LOAD_SUB_I16,
3289 ARM::ATOMIC_LOAD_SUB_I32,
3290 ARM::ATOMIC_LOAD_SUB_I64);
3292 return SelectAtomic(N,
3293 ARM::ATOMIC_LOAD_AND_I8,
3294 ARM::ATOMIC_LOAD_AND_I16,
3295 ARM::ATOMIC_LOAD_AND_I32,
3296 ARM::ATOMIC_LOAD_AND_I64);
3298 return SelectAtomic(N,
3299 ARM::ATOMIC_LOAD_OR_I8,
3300 ARM::ATOMIC_LOAD_OR_I16,
3301 ARM::ATOMIC_LOAD_OR_I32,
3302 ARM::ATOMIC_LOAD_OR_I64);
3304 return SelectAtomic(N,
3305 ARM::ATOMIC_LOAD_XOR_I8,
3306 ARM::ATOMIC_LOAD_XOR_I16,
3307 ARM::ATOMIC_LOAD_XOR_I32,
3308 ARM::ATOMIC_LOAD_XOR_I64);
3310 return SelectAtomic(N,
3311 ARM::ATOMIC_LOAD_NAND_I8,
3312 ARM::ATOMIC_LOAD_NAND_I16,
3313 ARM::ATOMIC_LOAD_NAND_I32,
3314 ARM::ATOMIC_LOAD_NAND_I64);
3316 return SelectAtomic(N,
3317 ARM::ATOMIC_LOAD_MIN_I8,
3318 ARM::ATOMIC_LOAD_MIN_I16,
3319 ARM::ATOMIC_LOAD_MIN_I32,
3320 ARM::ATOMIC_LOAD_MIN_I64);
3322 return SelectAtomic(N,
3323 ARM::ATOMIC_LOAD_MAX_I8,
3324 ARM::ATOMIC_LOAD_MAX_I16,
3325 ARM::ATOMIC_LOAD_MAX_I32,
3326 ARM::ATOMIC_LOAD_MAX_I64);
3328 return SelectAtomic(N,
3329 ARM::ATOMIC_LOAD_UMIN_I8,
3330 ARM::ATOMIC_LOAD_UMIN_I16,
3331 ARM::ATOMIC_LOAD_UMIN_I32,
3332 ARM::ATOMIC_LOAD_UMIN_I64);
3334 return SelectAtomic(N,
3335 ARM::ATOMIC_LOAD_UMAX_I8,
3336 ARM::ATOMIC_LOAD_UMAX_I16,
3337 ARM::ATOMIC_LOAD_UMAX_I32,
3338 ARM::ATOMIC_LOAD_UMAX_I64);
3340 return SelectAtomic(N,
3341 ARM::ATOMIC_SWAP_I8,
3342 ARM::ATOMIC_SWAP_I16,
3343 ARM::ATOMIC_SWAP_I32,
3344 ARM::ATOMIC_SWAP_I64);
3346 return SelectAtomic(N,
3347 ARM::ATOMIC_CMP_SWAP_I8,
3348 ARM::ATOMIC_CMP_SWAP_I16,
3349 ARM::ATOMIC_CMP_SWAP_I32,
3350 ARM::ATOMIC_CMP_SWAP_I64);
3353 return SelectCode(N);
3357 std::vector<SDValue> AsmNodeOperands;
3358 unsigned Flag,
Kind;
3359 bool Changed =
false;
3375 for(
unsigned i = 0, e = N->
getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) {
3377 AsmNodeOperands.push_back(op);
3379 if (i < InlineAsm::Op_FirstOperand)
3383 Flag =
C->getZExtValue();
3393 if (Kind == InlineAsm::Kind_Imm) {
3395 AsmNodeOperands.push_back(op);
3403 unsigned DefIdx = 0;
3404 bool IsTiedToChangedOp =
false;
3408 IsTiedToChangedOp = OpChanged[DefIdx];
3410 if (Kind != InlineAsm::Kind_RegUse && Kind != InlineAsm::Kind_RegDef
3411 && Kind != InlineAsm::Kind_RegDefEarlyClobber)
3416 if ((!IsTiedToChangedOp && (!HasRC || RC != ARM::GPRRegClassID))
3420 assert((i+2 < NumOps) &&
"Invalid number of operands in inline asm");
3423 unsigned Reg0 = cast<RegisterSDNode>(V0)->
getReg();
3424 unsigned Reg1 = cast<RegisterSDNode>(V1)->
getReg();
3428 if (Kind == InlineAsm::Kind_RegDef ||
3429 Kind == InlineAsm::Kind_RegDefEarlyClobber) {
3435 SDValue Chain = SDValue(N,0);
3438 SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR,
MVT::Untyped,
3442 SDValue Sub0 = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl,
MVT::i32,
3444 SDValue Sub1 = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl,
MVT::i32,
3446 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
3448 SDValue
T1 = CurDAG->getCopyToReg(Sub1, dl, Reg1, Sub1, T0.
getValue(1));
3453 CurDAG->UpdateNodeOperands(GU, &Ops[0], Ops.
size());
3459 SDValue Chain = AsmNodeOperands[InlineAsm::Op_InputChain];
3462 SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0,
MVT::i32,
3464 SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1,
MVT::i32,
3466 SDValue Pair = SDValue(createGPRPairNode(
MVT::Untyped, T0, T1), 0);
3472 Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.
getValue(1));
3474 AsmNodeOperands[InlineAsm::Op_InputChain] = Chain;
3481 OpChanged[OpChanged.
size() -1 ] =
true;
3483 if (IsTiedToChangedOp)
3488 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
3491 AsmNodeOperands.push_back(PairedReg);
3498 AsmNodeOperands.push_back(Glue);
3504 AsmNodeOperands.size());
3510 bool ARMDAGToDAGISel::
3511 SelectInlineAsmMemoryOperand(
const SDValue &Op,
char ConstraintCode,
3512 std::vector<SDValue> &OutOps) {
3513 assert(ConstraintCode ==
'm' &&
"unexpected asm memory constraint");
3517 OutOps.push_back(Op);
3526 return new ARMDAGToDAGISel(TM, OptLevel);
void push_back(const T &Elt)
SDValue getValue(unsigned R) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
static unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool mayStore() const
Return true if this instruction could possibly modify memory. Instructions with this flag set are not...
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
SDNode * getGluedNode() const
static unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
unsigned getOpcode() const
unsigned getNumOperands() const
const SDValue & getOperand(unsigned Num) const
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...
void setNodeId(int Id)
setNodeId - Set unique node id.
const SDValue & getBasePtr() const
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
unsigned getResNo() const
get the index which selects a specific result in the SDNode
static cl::opt< bool > CheckVMLxHazard("check-vmlx-hazard", cl::Hidden, cl::desc("Check fp vmla / vmls hazard at isel time"), cl::init(true))
static SDValue getAL(SelectionDAG *CurDAG)
getAL - Returns a ARMCC::AL immediate node.
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
EVT getValueType(unsigned ResNo) const
static ShiftOpc getShiftOpcForNode(unsigned Opcode)
EVT getVectorElementType() const
bool isFpMLxInstruction(unsigned Opcode) const
unsigned getNumValues() const
enable_if_c< std::numeric_limits< T >::is_integer &&!std::numeric_limits< T >::is_signed, std::size_t >::type 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...
Simple integer binary arithmetic operators.
static int getT2SOImmVal(unsigned Arg)
AtomicOrdering getOrdering() const
EVT getMemoryVT() const
getMemoryVT - Return the type of the in-memory value.
static bool isThumbImmShiftedVal(unsigned V)
SDNode * getNode() const
get the SDNode which holds the desired result
initializer< Ty > init(const Ty &Val)
static unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
const SDValue & getOperand(unsigned i) const
static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc)
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
static cl::opt< bool > DisableShifterOp("disable-shifter-op", cl::Hidden, cl::desc("Disable isel of shifter-op"), cl::init(false))
static unsigned getNumOperandRegisters(unsigned Flag)
unsigned getOpcode() const
static unsigned getKind(unsigned Flags)
use_iterator use_begin() const
ISD::MemIndexedMode getAddressingMode() const
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements)
unsigned getOpcode() const
Return the opcode number for this descriptor.
const SDValue & getOffset() const
unsigned CountTrailingOnes_32(uint32_t Value)
SDNode * getGluedUser() const
const SDValue & getChain() const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
static bool isSOImmTwoPartVal(unsigned V)
unsigned Log2_32(uint32_t Value)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
ISD::LoadExtType getExtensionType() const
op_iterator op_begin() const
static unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
static int getSOImmVal(unsigned Arg)
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
Bitwise operators - logical and, logical or, logical xor.
static IntegerType * getInt32Ty(LLVMContext &C)
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
op_iterator op_end() const
FunctionPass * createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOpt::Level OptLevel)
bool is128BitVector() const
is128BitVector - Return true if this is a 128-bit vector type.
bool isPowerOf2_32(uint32_t Value)
const MCRegisterInfo & MRI
SDValue getTargetConstant(uint64_t Val, EVT VT)
bool is64BitVector() const
is64BitVector - Return true if this is a 64-bit vector type.
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
bool isMachineOpcode() const
unsigned getMachineOpcode() const
uint64_t getZExtValue() const
unsigned getVectorNumElements() const