74#define DEBUG_TYPE "arm-instrinfo"
76#define GET_INSTRINFO_CTOR_DTOR
77#include "ARMGenInstrInfo.inc"
81 cl::desc(
"Enable ARM 2-addr to 3-addr conv"));
95 { ARM::VMLAS, ARM::VMULS, ARM::VADDS,
false,
false },
96 { ARM::VMLSS, ARM::VMULS, ARM::VSUBS,
false,
false },
97 { ARM::VMLAD, ARM::VMULD, ARM::VADDD,
false,
false },
98 { ARM::VMLSD, ARM::VMULD, ARM::VSUBD,
false,
false },
99 { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS,
true,
false },
100 { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS,
true,
false },
101 { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD,
true,
false },
102 { ARM::VNMLSD, ARM::VMULD, ARM::VSUBD,
true,
false },
105 { ARM::VMLAfd, ARM::VMULfd, ARM::VADDfd,
false,
false },
106 { ARM::VMLSfd, ARM::VMULfd, ARM::VSUBfd,
false,
false },
107 { ARM::VMLAfq, ARM::VMULfq, ARM::VADDfq,
false,
false },
108 { ARM::VMLSfq, ARM::VMULfq, ARM::VSUBfq,
false,
false },
109 { ARM::VMLAslfd, ARM::VMULslfd, ARM::VADDfd,
false,
true },
110 { ARM::VMLSslfd, ARM::VMULslfd, ARM::VSUBfd,
false,
true },
111 { ARM::VMLAslfq, ARM::VMULslfq, ARM::VADDfq,
false,
true },
112 { ARM::VMLSslfq, ARM::VMULslfq, ARM::VSUBfq,
false,
true },
118 for (
unsigned i = 0, e = std::size(
ARM_MLxTable); i != e; ++i) {
131 if (usePreRAHazardRecognizer()) {
133 static_cast<const ARMSubtarget *
>(STI)->getInstrItineraryData();
153 std::make_unique<ARMBankConflictHazardRecognizer>(DAG, 0x4,
true));
190 default:
return nullptr;
216 unsigned OffImm =
MI.getOperand(NumOps - 2).getImm();
229 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
234 }
else if (Amt != 0) {
238 get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
247 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
260 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
267 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
276 std::vector<MachineInstr*> NewMIs;
280 BuildMI(MF,
MI.getDebugLoc(),
get(MemOpc),
MI.getOperand(0).getReg())
291 NewMIs.push_back(MemMI);
292 NewMIs.push_back(UpdateMI);
296 BuildMI(MF,
MI.getDebugLoc(),
get(MemOpc),
MI.getOperand(0).getReg())
309 NewMIs.push_back(UpdateMI);
310 NewMIs.push_back(MemMI);
316 if (MO.isReg() && MO.getReg().isVirtual()) {
321 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
325 if (MO.isUse() && MO.isKill()) {
326 for (
unsigned j = 0; j < 2; ++j) {
332 if (VI.removeKill(
MI))
333 VI.Kills.push_back(NewMI);
359 bool AllowModify)
const {
374 bool CantAnalyze =
false;
378 while (
I->isDebugInstr() || !
I->isTerminator() ||
380 I->getOpcode() == ARM::t2DoLoopStartTP){
392 TBB =
I->getOperand(0).getMBB();
398 assert(!FBB &&
"FBB should have been null.");
400 TBB =
I->getOperand(0).getMBB();
401 Cond.push_back(
I->getOperand(1));
402 Cond.push_back(
I->getOperand(2));
403 }
else if (
I->isReturn()) {
406 }
else if (
I->getOpcode() == ARM::t2LoopEnd &&
413 TBB =
I->getOperand(1).getMBB();
415 Cond.push_back(
I->getOperand(0));
472 int *BytesRemoved)
const {
473 assert(!BytesRemoved &&
"code size not handled");
484 I->eraseFromParent();
494 I->eraseFromParent();
503 int *BytesAdded)
const {
504 assert(!BytesAdded &&
"code size not handled");
513 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
515 "ARM branch conditions have two or three components!");
525 }
else if (
Cond.size() == 2) {
536 if (
Cond.size() == 2)
541 else if (
Cond.size() == 3)
552 if (
Cond.size() == 2) {
564 while (++
I !=
E &&
I->isInsideBundle()) {
565 int PIdx =
I->findFirstPredOperandIdx();
566 if (PIdx != -1 &&
I->getOperand(PIdx).getImm() !=
ARMCC::AL)
572 int PIdx =
MI.findFirstPredOperandIdx();
573 return PIdx != -1 &&
MI.getOperand(PIdx).getImm() !=
ARMCC::AL;
581 std::string GenericComment =
583 if (!GenericComment.empty())
584 return GenericComment;
588 return std::string();
592 int FirstPredOp =
MI.findFirstPredOperandIdx();
593 if (FirstPredOp != (
int) OpIdx)
594 return std::string();
596 std::string
CC =
"CC::";
603 unsigned Opc =
MI.getOpcode();
612 int PIdx =
MI.findFirstPredOperandIdx();
615 PMO.
setImm(Pred[0].getImm());
616 MI.getOperand(PIdx+1).setReg(Pred[1].
getReg());
623 "CPSR def isn't expected operand");
624 assert((
MI.getOperand(1).isDead() ||
625 MI.getOperand(1).getReg() != ARM::CPSR) &&
626 "if conversion tried to stop defining used CPSR");
627 MI.getOperand(1).setReg(ARM::NoRegister);
637 if (Pred1.
size() > 2 || Pred2.
size() > 2)
662 std::vector<MachineOperand> &Pred,
663 bool SkipDead)
const {
666 bool ClobbersCPSR = MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR);
667 bool IsCPSR = MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR;
668 if (ClobbersCPSR || IsCPSR) {
686 for (
const auto &MO :
MI.operands())
687 if (MO.isReg() && MO.getReg() == ARM::CPSR && MO.isDef() && !MO.isDead())
693 switch (
MI->getOpcode()) {
694 default:
return true;
725 if (!
MI.isPredicable())
763 if (!MO.isReg() || MO.isUndef() || MO.isUse())
765 if (MO.getReg() != ARM::CPSR)
785 switch (
MI.getOpcode()) {
793 case TargetOpcode::BUNDLE:
794 return getInstBundleLength(
MI);
795 case ARM::CONSTPOOL_ENTRY:
796 case ARM::JUMPTABLE_INSTS:
797 case ARM::JUMPTABLE_ADDRS:
798 case ARM::JUMPTABLE_TBB:
799 case ARM::JUMPTABLE_TBH:
802 return MI.getOperand(2).getImm();
804 return MI.getOperand(1).getImm();
806 case ARM::INLINEASM_BR: {
808 unsigned Size = getInlineAsmLength(
MI.getOperand(0).getSymbolName(), *MAI);
816unsigned ARMBaseInstrInfo::getInstBundleLength(
const MachineInstr &
MI)
const {
820 while (++
I !=
E &&
I->isInsideBundle()) {
821 assert(!
I->isBundle() &&
"No nested bundle!");
829 unsigned DestReg,
bool KillSrc,
831 unsigned Opc = Subtarget.isThumb()
832 ? (Subtarget.
isMClass() ? ARM::t2MRS_M : ARM::t2MRS_AR)
849 unsigned SrcReg,
bool KillSrc,
851 unsigned Opc = Subtarget.isThumb()
852 ? (Subtarget.
isMClass() ? ARM::t2MSR_M : ARM::t2MSR_AR)
886 unsigned Cond,
unsigned Inactive) {
895 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
896 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
898 if (GPRDest && GPRSrc) {
906 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
907 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
910 if (SPRDest && SPRSrc)
912 else if (GPRDest && SPRSrc)
914 else if (SPRDest && GPRSrc)
916 else if (ARM::DPRRegClass.
contains(DestReg, SrcReg) && Subtarget.hasFP64())
918 else if (ARM::QPRRegClass.
contains(DestReg, SrcReg))
919 Opc = Subtarget.hasNEON() ? ARM::VORRq : ARM::MQPRCopy;
924 if (Opc == ARM::VORRq || Opc == ARM::MVE_VORR)
926 if (Opc == ARM::MVE_VORR)
928 else if (Opc != ARM::MQPRCopy)
934 unsigned BeginIdx = 0;
935 unsigned SubRegs = 0;
939 if (ARM::QQPRRegClass.
contains(DestReg, SrcReg)) {
940 Opc = Subtarget.hasNEON() ? ARM::VORRq : ARM::MVE_VORR;
941 BeginIdx = ARM::qsub_0;
943 }
else if (ARM::QQQQPRRegClass.
contains(DestReg, SrcReg)) {
944 Opc = Subtarget.hasNEON() ? ARM::VORRq : ARM::MVE_VORR;
945 BeginIdx = ARM::qsub_0;
948 }
else if (ARM::DPairRegClass.
contains(DestReg, SrcReg)) {
950 BeginIdx = ARM::dsub_0;
952 }
else if (ARM::DTripleRegClass.
contains(DestReg, SrcReg)) {
954 BeginIdx = ARM::dsub_0;
956 }
else if (ARM::DQuadRegClass.
contains(DestReg, SrcReg)) {
958 BeginIdx = ARM::dsub_0;
960 }
else if (ARM::GPRPairRegClass.
contains(DestReg, SrcReg)) {
961 Opc = Subtarget.
isThumb2() ? ARM::tMOVr : ARM::MOVr;
962 BeginIdx = ARM::gsub_0;
964 }
else if (ARM::DPairSpcRegClass.
contains(DestReg, SrcReg)) {
966 BeginIdx = ARM::dsub_0;
969 }
else if (ARM::DTripleSpcRegClass.
contains(DestReg, SrcReg)) {
971 BeginIdx = ARM::dsub_0;
974 }
else if (ARM::DQuadSpcRegClass.
contains(DestReg, SrcReg)) {
976 BeginIdx = ARM::dsub_0;
979 }
else if (ARM::DPRRegClass.
contains(DestReg, SrcReg) &&
980 !Subtarget.hasFP64()) {
982 BeginIdx = ARM::ssub_0;
984 }
else if (SrcReg == ARM::CPSR) {
987 }
else if (DestReg == ARM::CPSR) {
990 }
else if (DestReg == ARM::VPR) {
996 }
else if (SrcReg == ARM::VPR) {
1002 }
else if (DestReg == ARM::FPSCR_NZCV) {
1004 BuildMI(
MBB,
I,
I->getDebugLoc(),
get(ARM::VMSR_FPSCR_NZCVQC), DestReg)
1008 }
else if (SrcReg == ARM::FPSCR_NZCV) {
1010 BuildMI(
MBB,
I,
I->getDebugLoc(),
get(ARM::VMRS_FPSCR_NZCVQC), DestReg)
1016 assert(Opc &&
"Impossible reg-to-reg copy");
1022 if (
TRI->regsOverlap(SrcReg,
TRI->getSubReg(DestReg, BeginIdx))) {
1023 BeginIdx = BeginIdx + ((SubRegs - 1) * Spacing);
1029 for (
unsigned i = 0; i != SubRegs; ++i) {
1030 Register Dst =
TRI->getSubReg(DestReg, BeginIdx + i * Spacing);
1031 Register Src =
TRI->getSubReg(SrcReg, BeginIdx + i * Spacing);
1032 assert(Dst && Src &&
"Bad sub-register");
1034 assert(!DstRegs.
count(Src) &&
"destructive vector copy");
1039 if (Opc == ARM::VORRq || Opc == ARM::MVE_VORR) {
1043 if (Opc == ARM::MVE_VORR)
1048 if (Opc == ARM::MOVr)
1057std::optional<DestSourcePair>
1066 if (!
MI.isMoveReg() ||
1067 (
MI.getOpcode() == ARM::VORRq &&
1068 MI.getOperand(1).getReg() !=
MI.getOperand(2).getReg()))
1069 return std::nullopt;
1073std::optional<ParamLoadedValue>
1077 Register DstReg = DstSrcPair->Destination->getReg();
1098 return std::nullopt;
1105 unsigned SubIdx,
unsigned State,
1108 return MIB.
addReg(Reg, State);
1111 return MIB.
addReg(
TRI->getSubReg(Reg, SubIdx), State);
1112 return MIB.
addReg(Reg, State, SubIdx);
1117 Register SrcReg,
bool isKill,
int FI,
1129 switch (
TRI->getSpillSize(*RC)) {
1131 if (ARM::HPRRegClass.hasSubClassEq(RC)) {
1142 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1149 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1156 }
else if (ARM::VCCRRegClass.hasSubClassEq(RC)) {
1167 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1174 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1175 if (Subtarget.hasV5TEOps()) {
1195 if (ARM::DPairRegClass.hasSubClassEq(RC) && Subtarget.hasNEON()) {
1211 }
else if (ARM::QPRRegClass.hasSubClassEq(RC) &&
1212 Subtarget.hasMVEIntegerOps()) {
1217 .addMemOperand(MMO);
1223 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1226 Subtarget.hasNEON()) {
1240 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0,
TRI);
1247 if (ARM::QQPRRegClass.hasSubClassEq(RC) ||
1248 ARM::MQQPRRegClass.hasSubClassEq(RC) ||
1249 ARM::DQuadRegClass.hasSubClassEq(RC)) {
1251 Subtarget.hasNEON()) {
1260 }
else if (Subtarget.hasMVEIntegerOps()) {
1272 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0,
TRI);
1273 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0,
TRI);
1280 if (ARM::MQQQQPRRegClass.hasSubClassEq(RC) &&
1281 Subtarget.hasMVEIntegerOps()) {
1286 }
else if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1292 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0,
TRI);
1293 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0,
TRI);
1294 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_3, 0,
TRI);
1295 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_4, 0,
TRI);
1296 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_5, 0,
TRI);
1297 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_6, 0,
TRI);
1308 int &FrameIndex)
const {
1309 switch (
MI.getOpcode()) {
1313 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isReg() &&
1314 MI.getOperand(3).isImm() &&
MI.getOperand(2).getReg() == 0 &&
1315 MI.getOperand(3).getImm() == 0) {
1316 FrameIndex =
MI.getOperand(1).getIndex();
1317 return MI.getOperand(0).getReg();
1325 case ARM::VSTR_P0_off:
1326 case ARM::MVE_VSTRWU32:
1327 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
1328 MI.getOperand(2).getImm() == 0) {
1329 FrameIndex =
MI.getOperand(1).getIndex();
1330 return MI.getOperand(0).getReg();
1334 case ARM::VST1d64TPseudo:
1335 case ARM::VST1d64QPseudo:
1336 if (
MI.getOperand(0).isFI() &&
MI.getOperand(2).getSubReg() == 0) {
1337 FrameIndex =
MI.getOperand(0).getIndex();
1338 return MI.getOperand(2).getReg();
1342 if (
MI.getOperand(1).isFI() &&
MI.getOperand(0).getSubReg() == 0) {
1343 FrameIndex =
MI.getOperand(1).getIndex();
1344 return MI.getOperand(0).getReg();
1347 case ARM::MQQPRStore:
1348 case ARM::MQQQQPRStore:
1349 if (
MI.getOperand(1).isFI()) {
1350 FrameIndex =
MI.getOperand(1).getIndex();
1351 return MI.getOperand(0).getReg();
1360 int &FrameIndex)
const {
1362 if (
MI.mayStore() && hasStoreToStackSlot(
MI, Accesses) &&
1363 Accesses.
size() == 1) {
1365 cast<FixedStackPseudoSourceValue>(Accesses.
front()->getPseudoValue())
1387 switch (
TRI->getSpillSize(*RC)) {
1389 if (ARM::HPRRegClass.hasSubClassEq(RC)) {
1399 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1405 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1411 }
else if (ARM::VCCRRegClass.hasSubClassEq(RC)) {
1421 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1427 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1430 if (Subtarget.hasV5TEOps()) {
1453 if (ARM::DPairRegClass.hasSubClassEq(RC) && Subtarget.hasNEON()) {
1466 }
else if (ARM::QPRRegClass.hasSubClassEq(RC) &&
1467 Subtarget.hasMVEIntegerOps()) {
1469 MIB.addFrameIndex(FI)
1471 .addMemOperand(MMO);
1477 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1479 Subtarget.hasNEON()) {
1500 if (ARM::QQPRRegClass.hasSubClassEq(RC) ||
1501 ARM::MQQPRRegClass.hasSubClassEq(RC) ||
1502 ARM::DQuadRegClass.hasSubClassEq(RC)) {
1504 Subtarget.hasNEON()) {
1510 }
else if (Subtarget.hasMVEIntegerOps()) {
1530 if (ARM::MQQQQPRRegClass.hasSubClassEq(RC) &&
1531 Subtarget.hasMVEIntegerOps()) {
1535 }
else if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1559 int &FrameIndex)
const {
1560 switch (
MI.getOpcode()) {
1564 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isReg() &&
1565 MI.getOperand(3).isImm() &&
MI.getOperand(2).getReg() == 0 &&
1566 MI.getOperand(3).getImm() == 0) {
1567 FrameIndex =
MI.getOperand(1).getIndex();
1568 return MI.getOperand(0).getReg();
1576 case ARM::VLDR_P0_off:
1577 case ARM::MVE_VLDRWU32:
1578 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
1579 MI.getOperand(2).getImm() == 0) {
1580 FrameIndex =
MI.getOperand(1).getIndex();
1581 return MI.getOperand(0).getReg();
1585 case ARM::VLD1d8TPseudo:
1586 case ARM::VLD1d16TPseudo:
1587 case ARM::VLD1d32TPseudo:
1588 case ARM::VLD1d64TPseudo:
1589 case ARM::VLD1d8QPseudo:
1590 case ARM::VLD1d16QPseudo:
1591 case ARM::VLD1d32QPseudo:
1592 case ARM::VLD1d64QPseudo:
1593 if (
MI.getOperand(1).isFI() &&
MI.getOperand(0).getSubReg() == 0) {
1594 FrameIndex =
MI.getOperand(1).getIndex();
1595 return MI.getOperand(0).getReg();
1599 if (
MI.getOperand(1).isFI() &&
MI.getOperand(0).getSubReg() == 0) {
1600 FrameIndex =
MI.getOperand(1).getIndex();
1601 return MI.getOperand(0).getReg();
1604 case ARM::MQQPRLoad:
1605 case ARM::MQQQQPRLoad:
1606 if (
MI.getOperand(1).isFI()) {
1607 FrameIndex =
MI.getOperand(1).getIndex();
1608 return MI.getOperand(0).getReg();
1617 int &FrameIndex)
const {
1619 if (
MI.mayLoad() && hasLoadFromStackSlot(
MI, Accesses) &&
1620 Accesses.
size() == 1) {
1622 cast<FixedStackPseudoSourceValue>(Accesses.
front()->getPseudoValue())
1633 bool isThumb2 = Subtarget.
isThumb2();
1640 if (isThumb1 || !
MI->getOperand(1).isDead()) {
1642 LDM =
BuildMI(*BB,
MI, dl,
TII->get(isThumb2 ? ARM::t2LDMIA_UPD
1643 : isThumb1 ? ARM::tLDMIA_UPD
1647 LDM =
BuildMI(*BB,
MI, dl,
TII->get(isThumb2 ? ARM::t2LDMIA : ARM::LDMIA));
1650 if (isThumb1 || !
MI->getOperand(0).isDead()) {
1652 STM =
BuildMI(*BB,
MI, dl,
TII->get(isThumb2 ? ARM::t2STMIA_UPD
1653 : isThumb1 ? ARM::tSTMIA_UPD
1657 STM =
BuildMI(*BB,
MI, dl,
TII->get(isThumb2 ? ARM::t2STMIA : ARM::STMIA));
1672 [&
TRI](
const unsigned &Reg1,
const unsigned &Reg2) ->
bool {
1673 return TRI.getEncodingValue(Reg1) <
1674 TRI.getEncodingValue(Reg2);
1677 for (
const auto &Reg : ScratchRegs) {
1686 if (
MI.getOpcode() == TargetOpcode::LOAD_STACK_GUARD) {
1687 expandLoadStackGuard(
MI);
1688 MI.getParent()->erase(
MI);
1692 if (
MI.getOpcode() == ARM::MEMCPY) {
1701 if (!
MI.isCopy() || Subtarget.dontWidenVMOVS() || !Subtarget.hasFP64())
1706 Register DstRegS =
MI.getOperand(0).getReg();
1707 Register SrcRegS =
MI.getOperand(1).getReg();
1708 if (!ARM::SPRRegClass.
contains(DstRegS, SrcRegS))
1712 unsigned DstRegD =
TRI->getMatchingSuperReg(DstRegS, ARM::ssub_0,
1714 unsigned SrcRegD =
TRI->getMatchingSuperReg(SrcRegS, ARM::ssub_0,
1716 if (!DstRegD || !SrcRegD)
1722 if (!
MI.definesRegister(DstRegD,
TRI) ||
MI.readsRegister(DstRegD,
TRI))
1726 if (
MI.getOperand(0).isDead())
1735 int ImpDefIdx =
MI.findRegisterDefOperandIdx(DstRegD);
1736 if (ImpDefIdx != -1)
1737 MI.removeOperand(ImpDefIdx);
1740 MI.setDesc(
get(ARM::VMOVD));
1741 MI.getOperand(0).setReg(DstRegD);
1742 MI.getOperand(1).setReg(SrcRegD);
1749 MI.getOperand(1).setIsUndef();
1754 if (
MI.getOperand(1).isKill()) {
1755 MI.getOperand(1).setIsKill(
false);
1756 MI.addRegisterKilled(SrcRegS,
TRI,
true);
1770 assert(MCPE.isMachineConstantPoolEntry() &&
1771 "Expecting a machine constantpool entry!");
1785 cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
ARMCP::CPValue,
1790 cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(), PCLabelId, 4);
1793 Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
1801 cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
1821 case ARM::tLDRpci_pic:
1822 case ARM::t2LDRpci_pic: {
1842 switch (
I->getOpcode()) {
1843 case ARM::tLDRpci_pic:
1844 case ARM::t2LDRpci_pic: {
1846 unsigned CPI =
I->getOperand(1).getIndex();
1848 I->getOperand(1).setIndex(CPI);
1849 I->getOperand(2).setImm(PCLabelId);
1853 if (!
I->isBundledWithSucc())
1864 if (Opcode == ARM::t2LDRpci || Opcode == ARM::t2LDRpci_pic ||
1865 Opcode == ARM::tLDRpci || Opcode == ARM::tLDRpci_pic ||
1866 Opcode == ARM::LDRLIT_ga_pcrel || Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1867 Opcode == ARM::tLDRLIT_ga_pcrel || Opcode == ARM::t2LDRLIT_ga_pcrel ||
1868 Opcode == ARM::MOV_ga_pcrel || Opcode == ARM::MOV_ga_pcrel_ldr ||
1869 Opcode == ARM::t2MOV_ga_pcrel) {
1880 if (Opcode == ARM::LDRLIT_ga_pcrel || Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1881 Opcode == ARM::tLDRLIT_ga_pcrel || Opcode == ARM::t2LDRLIT_ga_pcrel ||
1882 Opcode == ARM::MOV_ga_pcrel || Opcode == ARM::MOV_ga_pcrel_ldr ||
1883 Opcode == ARM::t2MOV_ga_pcrel)
1895 if (isARMCP0 && isARMCP1) {
1901 }
else if (!isARMCP0 && !isARMCP1) {
1905 }
else if (Opcode == ARM::PICLDR) {
1913 if (Addr0 != Addr1) {
1949 int64_t &Offset2)
const {
1970 case ARM::t2LDRSHi8:
1972 case ARM::t2LDRBi12:
1973 case ARM::t2LDRSHi12:
1990 case ARM::t2LDRSHi8:
1992 case ARM::t2LDRBi12:
1993 case ARM::t2LDRSHi12:
2007 if (isa<ConstantSDNode>(Load1->
getOperand(1)) &&
2009 Offset1 = cast<ConstantSDNode>(Load1->
getOperand(1))->getSExtValue();
2010 Offset2 = cast<ConstantSDNode>(Load2->
getOperand(1))->getSExtValue();
2029 int64_t Offset1, int64_t Offset2,
2030 unsigned NumLoads)
const {
2034 assert(Offset2 > Offset1);
2036 if ((Offset2 - Offset1) / 8 > 64)
2067 if (
MI.isDebugInstr())
2071 if (
MI.isTerminator() ||
MI.isPosition())
2075 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2089 while (++
I !=
MBB->
end() &&
I->isDebugInstr())
2091 if (
I !=
MBB->
end() &&
I->getOpcode() == ARM::t2IT)
2102 if (!
MI.isCall() &&
MI.definesRegister(ARM::SP))
2110 unsigned NumCycles,
unsigned ExtraPredCycles,
2120 if (!Pred->
empty()) {
2122 if (LastMI->
getOpcode() == ARM::t2Bcc) {
2131 MBB, 0, 0, Probability);
2136 unsigned TCycles,
unsigned TExtra,
2138 unsigned FCycles,
unsigned FExtra,
2155 const unsigned ScalingUpFactor = 1024;
2157 unsigned PredCost = (TCycles + FCycles + TExtra + FExtra) * ScalingUpFactor;
2158 unsigned UnpredCost;
2159 if (!Subtarget.hasBranchPredictor()) {
2162 unsigned NotTakenBranchCost = 1;
2164 unsigned TUnpredCycles, FUnpredCycles;
2167 TUnpredCycles = TCycles + NotTakenBranchCost;
2168 FUnpredCycles = TakenBranchCost;
2171 TUnpredCycles = TCycles + TakenBranchCost;
2172 FUnpredCycles = FCycles + NotTakenBranchCost;
2175 PredCost -= 1 * ScalingUpFactor;
2178 unsigned TUnpredCost = Probability.
scale(TUnpredCycles * ScalingUpFactor);
2179 unsigned FUnpredCost = Probability.
getCompl().
scale(FUnpredCycles * ScalingUpFactor);
2180 UnpredCost = TUnpredCost + FUnpredCost;
2183 if (Subtarget.
isThumb2() && TCycles + FCycles > 4) {
2184 PredCost += ((TCycles + FCycles - 4) / 4) * ScalingUpFactor;
2187 unsigned TUnpredCost = Probability.
scale(TCycles * ScalingUpFactor);
2188 unsigned FUnpredCost =
2190 UnpredCost = TUnpredCost + FUnpredCost;
2191 UnpredCost += 1 * ScalingUpFactor;
2195 return PredCost <= UnpredCost;
2200 unsigned NumInsts)
const {
2208 unsigned MaxInsts = Subtarget.
restrictIT() ? 1 : 4;
2217 if (
MI.getOpcode() == ARM::t2Bcc &&
2240 return Subtarget.isProfitableToUnpredicate();
2248 int PIdx =
MI.findFirstPredOperandIdx();
2254 PredReg =
MI.getOperand(PIdx+1).getReg();
2263 if (Opc == ARM::t2B)
2272 unsigned OpIdx2)
const {
2273 switch (
MI.getOpcode()) {
2275 case ARM::t2MOVCCr: {
2300 if (!Reg.isVirtual())
2302 if (!
MRI.hasOneNonDBGUse(Reg))
2314 if (MO.isFI() || MO.isCPI() || MO.isJTI())
2321 if (MO.getReg().isPhysical())
2323 if (MO.isDef() && !MO.isDead())
2326 bool DontMoveAcrossStores =
true;
2327 if (!
MI->isSafeToMove(
nullptr, DontMoveAcrossStores))
2334 unsigned &TrueOp,
unsigned &FalseOp,
2335 bool &Optimizable)
const {
2336 assert((
MI.getOpcode() == ARM::MOVCCr ||
MI.getOpcode() == ARM::t2MOVCCr) &&
2337 "Unknown select instruction");
2346 Cond.push_back(
MI.getOperand(3));
2347 Cond.push_back(
MI.getOperand(4));
2356 bool PreferFalse)
const {
2357 assert((
MI.getOpcode() == ARM::MOVCCr ||
MI.getOpcode() == ARM::t2MOVCCr) &&
2358 "Unknown select instruction");
2361 bool Invert = !
DefMI;
2363 DefMI = canFoldIntoMOVCC(
MI.getOperand(1).getReg(),
MRI,
this);
2370 Register DestReg =
MI.getOperand(0).getReg();
2373 if (!
MRI.constrainRegClass(DestReg, FalseClass))
2375 if (!
MRI.constrainRegClass(DestReg, TrueClass))
2386 i != e && !DefDesc.
operands()[i].isPredicate(); ++i)
2389 unsigned CondCode =
MI.getOperand(3).getImm();
2394 NewMI.
add(
MI.getOperand(4));
2405 NewMI.
add(FalseReg);
2436 {ARM::ADDSri, ARM::ADDri},
2437 {ARM::ADDSrr, ARM::ADDrr},
2438 {ARM::ADDSrsi, ARM::ADDrsi},
2439 {ARM::ADDSrsr, ARM::ADDrsr},
2441 {ARM::SUBSri, ARM::SUBri},
2442 {ARM::SUBSrr, ARM::SUBrr},
2443 {ARM::SUBSrsi, ARM::SUBrsi},
2444 {ARM::SUBSrsr, ARM::SUBrsr},
2446 {ARM::RSBSri, ARM::RSBri},
2447 {ARM::RSBSrsi, ARM::RSBrsi},
2448 {ARM::RSBSrsr, ARM::RSBrsr},
2450 {ARM::tADDSi3, ARM::tADDi3},
2451 {ARM::tADDSi8, ARM::tADDi8},
2452 {ARM::tADDSrr, ARM::tADDrr},
2453 {ARM::tADCS, ARM::tADC},
2455 {ARM::tSUBSi3, ARM::tSUBi3},
2456 {ARM::tSUBSi8, ARM::tSUBi8},
2457 {ARM::tSUBSrr, ARM::tSUBrr},
2458 {ARM::tSBCS, ARM::tSBC},
2459 {ARM::tRSBS, ARM::tRSB},
2460 {ARM::tLSLSri, ARM::tLSLri},
2462 {ARM::t2ADDSri, ARM::t2ADDri},
2463 {ARM::t2ADDSrr, ARM::t2ADDrr},
2464 {ARM::t2ADDSrs, ARM::t2ADDrs},
2466 {ARM::t2SUBSri, ARM::t2SUBri},
2467 {ARM::t2SUBSrr, ARM::t2SUBrr},
2468 {ARM::t2SUBSrs, ARM::t2SUBrs},
2470 {ARM::t2RSBSri, ARM::t2RSBri},
2471 {ARM::t2RSBSrs, ARM::t2RSBrs},
2476 if (OldOpc == Entry.PseudoOpc)
2477 return Entry.MachineOpc;
2488 if (NumBytes == 0 && DestReg != BaseReg) {
2497 bool isSub = NumBytes < 0;
2498 if (isSub) NumBytes = -NumBytes;
2502 unsigned ThisVal = NumBytes & llvm::rotr<uint32_t>(0xFF, RotAmt);
2503 assert(ThisVal &&
"Didn't extract field correctly");
2506 NumBytes &= ~ThisVal;
2511 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
2524 unsigned NumBytes) {
2535 if (!IsPush && !IsPop)
2538 bool IsVFPPushPop =
MI->getOpcode() == ARM::VSTMDDB_UPD ||
2539 MI->getOpcode() == ARM::VLDMDIA_UPD;
2540 bool IsT1PushPop =
MI->getOpcode() == ARM::tPUSH ||
2541 MI->getOpcode() == ARM::tPOP ||
2542 MI->getOpcode() == ARM::tPOP_RET;
2544 assert((IsT1PushPop || (
MI->getOperand(0).getReg() == ARM::SP &&
2545 MI->getOperand(1).getReg() == ARM::SP)) &&
2546 "trying to fold sp update into non-sp-updating push/pop");
2551 if (NumBytes % (IsVFPPushPop ? 8 : 4) != 0)
2556 int RegListIdx = IsT1PushPop ? 2 : 4;
2559 unsigned RegsNeeded;
2562 RegsNeeded = NumBytes / 8;
2563 RegClass = &ARM::DPRRegClass;
2565 RegsNeeded = NumBytes / 4;
2566 RegClass = &ARM::GPRRegClass;
2576 unsigned FirstRegEnc = -1;
2579 for (
int i =
MI->getNumOperands() - 1; i >= RegListIdx; --i) {
2584 TRI->getEncodingValue(MO.
getReg()) < FirstRegEnc)
2585 FirstRegEnc =
TRI->getEncodingValue(MO.
getReg());
2588 const MCPhysReg *CSRegs =
TRI->getCalleeSavedRegs(&MF);
2591 for (
int CurRegEnc = FirstRegEnc - 1; CurRegEnc >= 0 && RegsNeeded;
2593 unsigned CurReg = RegClass->
getRegister(CurRegEnc);
2594 if (IsT1PushPop && CurRegEnc >
TRI->getEncodingValue(ARM::R7))
2601 false,
false,
true));
2611 MI->getParent()->computeRegisterLiveness(
TRI, CurReg,
MI) !=
2633 for (
int i =
MI->getNumOperands() - 1; i >= RegListIdx; --i)
2634 MI->removeOperand(i);
2647 unsigned Opcode =
MI.getOpcode();
2653 if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
2656 if (Opcode == ARM::ADDri) {
2657 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
2660 MI.setDesc(
TII.get(ARM::MOVr));
2661 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
2662 MI.removeOperand(FrameRegIdx+1);
2668 MI.setDesc(
TII.get(ARM::SUBri));
2674 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
2675 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(
Offset);
2683 unsigned ThisImmVal =
Offset & llvm::rotr<uint32_t>(0xFF, RotAmt);
2690 "Bit extraction didn't work?");
2691 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
2693 unsigned ImmIdx = 0;
2695 unsigned NumBits = 0;
2699 ImmIdx = FrameRegIdx + 1;
2700 InstrOffs =
MI.getOperand(ImmIdx).getImm();
2704 ImmIdx = FrameRegIdx+2;
2711 ImmIdx = FrameRegIdx+2;
2722 ImmIdx = FrameRegIdx+1;
2730 ImmIdx = FrameRegIdx+1;
2740 ImmIdx = FrameRegIdx+1;
2741 InstrOffs =
MI.getOperand(ImmIdx).getImm();
2750 Offset += InstrOffs * Scale;
2751 assert((
Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
2761 int ImmedOffset =
Offset / Scale;
2762 unsigned Mask = (1 << NumBits) - 1;
2763 if ((
unsigned)
Offset <= Mask * Scale) {
2765 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
2771 ImmedOffset = -ImmedOffset;
2773 ImmedOffset |= 1 << NumBits;
2781 ImmedOffset = ImmedOffset & Mask;
2784 ImmedOffset = -ImmedOffset;
2786 ImmedOffset |= 1 << NumBits;
2802 Register &SrcReg2, int64_t &CmpMask,
2803 int64_t &CmpValue)
const {
2804 switch (
MI.getOpcode()) {
2809 SrcReg =
MI.getOperand(0).getReg();
2812 CmpValue =
MI.getOperand(1).getImm();
2817 SrcReg =
MI.getOperand(0).getReg();
2818 SrcReg2 =
MI.getOperand(1).getReg();
2824 SrcReg =
MI.getOperand(0).getReg();
2826 CmpMask =
MI.getOperand(1).getImm();
2839 int CmpMask,
bool CommonUse) {
2840 switch (
MI->getOpcode()) {
2843 if (CmpMask !=
MI->getOperand(2).getImm())
2845 if (SrcReg ==
MI->getOperand(CommonUse ? 1 : 0).getReg())
2935 switch (
MI->getOpcode()) {
2936 default:
return false;
3032 if (!
MI)
return false;
3035 if (CmpMask != ~0) {
3039 UI =
MRI->use_instr_begin(SrcReg), UE =
MRI->use_instr_end();
3041 if (UI->getParent() != CmpInstr.
getParent())
3050 if (!
MI)
return false;
3059 if (
I ==
B)
return false;
3070 else if (
MI->getParent() != CmpInstr.
getParent() || CmpValue != 0) {
3075 if (CmpInstr.
getOpcode() == ARM::CMPri ||
3083 bool IsThumb1 =
false;
3100 if (
MI && IsThumb1) {
3102 if (
I !=
E && !
MI->readsRegister(ARM::CPSR,
TRI)) {
3103 bool CanReorder =
true;
3104 for (;
I !=
E; --
I) {
3105 if (
I->getOpcode() != ARM::tMOVi8) {
3111 MI =
MI->removeFromParent();
3122 bool SubAddIsThumb1 =
false;
3137 if (Instr.modifiesRegister(ARM::CPSR,
TRI) ||
3138 Instr.readsRegister(ARM::CPSR,
TRI))
3160 IsThumb1 = SubAddIsThumb1;
3175 bool isSafe =
false;
3178 while (!isSafe && ++
I !=
E) {
3180 for (
unsigned IO = 0, EO = Instr.getNumOperands();
3181 !isSafe && IO != EO; ++IO) {
3195 bool IsInstrVSel =
true;
3196 switch (Instr.getOpcode()) {
3198 IsInstrVSel =
false;
3232 bool IsSub = Opc == ARM::SUBrr || Opc == ARM::t2SUBrr ||
3233 Opc == ARM::SUBri || Opc == ARM::t2SUBri ||
3234 Opc == ARM::tSUBrr || Opc == ARM::tSUBi3 ||
3236 unsigned OpI = Opc != ARM::tSUBrr ? 1 : 2;
3248 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
3282 if (Succ->isLiveIn(ARM::CPSR))
3289 unsigned CPSRRegNum =
MI->getNumExplicitOperands() - 1;
3290 MI->getOperand(CPSRRegNum).setReg(ARM::CPSR);
3291 MI->getOperand(CPSRRegNum).setIsDef(
true);
3299 for (
unsigned i = 0, e = OperandsToUpdate.
size(); i < e; i++)
3300 OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
3302 MI->clearRegisterDeads(ARM::CPSR);
3316 int64_t CmpMask, CmpValue;
3318 if (Next !=
MI.getParent()->end() &&
3329 unsigned DefOpc =
DefMI.getOpcode();
3330 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm &&
3331 DefOpc != ARM::tMOVi32imm)
3333 if (!
DefMI.getOperand(1).isImm())
3337 if (!
MRI->hasOneNonDBGUse(Reg))
3353 if (
UseMI.getOperand(NumOps - 1).
getReg() == ARM::CPSR)
3359 unsigned UseOpc =
UseMI.getOpcode();
3360 unsigned NewUseOpc = 0;
3362 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
3363 bool Commute =
false;
3365 default:
return false;
3373 case ARM::t2EORrr: {
3379 if (UseOpc == ARM::SUBrr && Commute)
3385 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::ADDri : ARM::SUBri;
3388 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::SUBri : ARM::ADDri;
3402 case ARM::ORRrr: NewUseOpc = ARM::ORRri;
break;
3403 case ARM::EORrr: NewUseOpc = ARM::EORri;
break;
3407 case ARM::t2SUBrr: {
3408 if (UseOpc == ARM::t2SUBrr && Commute)
3413 const bool ToSP =
DefMI.getOperand(0).
getReg() == ARM::SP;
3414 const unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri;
3415 const unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri;
3417 NewUseOpc = UseOpc == ARM::t2ADDrr ? t2ADD : t2SUB;
3420 NewUseOpc = UseOpc == ARM::t2ADDrr ? t2SUB : t2ADD;
3435 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri;
break;
3436 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri;
break;
3443 unsigned OpIdx = Commute ? 2 : 1;
3445 bool isKill =
UseMI.getOperand(OpIdx).isKill();
3447 Register NewReg =
MRI->createVirtualRegister(TRC);
3455 UseMI.getOperand(1).setReg(NewReg);
3456 UseMI.getOperand(1).setIsKill();
3457 UseMI.getOperand(2).ChangeToImmediate(SOImmValV2);
3458 DefMI.eraseFromParent();
3465 case ARM::t2ADDspImm:
3466 case ARM::t2SUBspImm:
3476 switch (
MI.getOpcode()) {
3480 assert(UOps >= 0 &&
"bad # UOps");
3488 unsigned ShOpVal =
MI.getOperand(3).getImm();
3493 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3501 if (!
MI.getOperand(2).getReg())
3504 unsigned ShOpVal =
MI.getOperand(3).getImm();
3509 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3519 case ARM::LDRSB_POST:
3520 case ARM::LDRSH_POST: {
3523 return (Rt == Rm) ? 4 : 3;
3526 case ARM::LDR_PRE_REG:
3527 case ARM::LDRB_PRE_REG: {
3532 unsigned ShOpVal =
MI.getOperand(4).getImm();
3537 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3543 case ARM::STR_PRE_REG:
3544 case ARM::STRB_PRE_REG: {
3545 unsigned ShOpVal =
MI.getOperand(4).getImm();
3550 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3557 case ARM::STRH_PRE: {
3567 case ARM::LDR_POST_REG:
3568 case ARM::LDRB_POST_REG:
3569 case ARM::LDRH_POST: {
3572 return (Rt == Rm) ? 3 : 2;
3575 case ARM::LDR_PRE_IMM:
3576 case ARM::LDRB_PRE_IMM:
3577 case ARM::LDR_POST_IMM:
3578 case ARM::LDRB_POST_IMM:
3579 case ARM::STRB_POST_IMM:
3580 case ARM::STRB_POST_REG:
3581 case ARM::STRB_PRE_IMM:
3582 case ARM::STRH_POST:
3583 case ARM::STR_POST_IMM:
3584 case ARM::STR_POST_REG:
3585 case ARM::STR_PRE_IMM:
3588 case ARM::LDRSB_PRE:
3589 case ARM::LDRSH_PRE: {
3596 unsigned ShOpVal =
MI.getOperand(4).getImm();
3601 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3614 return (Rt == Rn) ? 3 : 2;
3625 case ARM::LDRD_POST:
3626 case ARM::t2LDRD_POST:
3629 case ARM::STRD_POST:
3630 case ARM::t2STRD_POST:
3633 case ARM::LDRD_PRE: {
3640 return (Rt == Rn) ? 4 : 3;
3643 case ARM::t2LDRD_PRE: {
3646 return (Rt == Rn) ? 4 : 3;
3649 case ARM::STRD_PRE: {
3657 case ARM::t2STRD_PRE:
3660 case ARM::t2LDR_POST:
3661 case ARM::t2LDRB_POST:
3662 case ARM::t2LDRB_PRE:
3663 case ARM::t2LDRSBi12:
3664 case ARM::t2LDRSBi8:
3665 case ARM::t2LDRSBpci:
3667 case ARM::t2LDRH_POST:
3668 case ARM::t2LDRH_PRE:
3670 case ARM::t2LDRSB_POST:
3671 case ARM::t2LDRSB_PRE:
3672 case ARM::t2LDRSH_POST:
3673 case ARM::t2LDRSH_PRE:
3674 case ARM::t2LDRSHi12:
3675 case ARM::t2LDRSHi8:
3676 case ARM::t2LDRSHpci:
3680 case ARM::t2LDRDi8: {
3683 return (Rt == Rn) ? 3 : 2;
3686 case ARM::t2STRB_POST:
3687 case ARM::t2STRB_PRE:
3690 case ARM::t2STRH_POST:
3691 case ARM::t2STRH_PRE:
3693 case ARM::t2STR_POST:
3694 case ARM::t2STR_PRE:
3725 E =
MI.memoperands_end();
3727 Size += (*I)->getSize();
3734 return std::min(
Size / 4, 16U);
3739 unsigned UOps = 1 + NumRegs;
3743 case ARM::VLDMDIA_UPD:
3744 case ARM::VLDMDDB_UPD:
3745 case ARM::VLDMSIA_UPD:
3746 case ARM::VLDMSDB_UPD:
3747 case ARM::VSTMDIA_UPD:
3748 case ARM::VSTMDDB_UPD:
3749 case ARM::VSTMSIA_UPD:
3750 case ARM::VSTMSDB_UPD:
3751 case ARM::LDMIA_UPD:
3752 case ARM::LDMDA_UPD:
3753 case ARM::LDMDB_UPD:
3754 case ARM::LDMIB_UPD:
3755 case ARM::STMIA_UPD:
3756 case ARM::STMDA_UPD:
3757 case ARM::STMDB_UPD:
3758 case ARM::STMIB_UPD:
3759 case ARM::tLDMIA_UPD:
3760 case ARM::tSTMIA_UPD:
3761 case ARM::t2LDMIA_UPD:
3762 case ARM::t2LDMDB_UPD:
3763 case ARM::t2STMIA_UPD:
3764 case ARM::t2STMDB_UPD:
3767 case ARM::LDMIA_RET:
3769 case ARM::t2LDMIA_RET:
3778 if (!ItinData || ItinData->
isEmpty())
3782 unsigned Class =
Desc.getSchedClass();
3784 if (ItinUOps >= 0) {
3791 unsigned Opc =
MI.getOpcode();
3810 case ARM::VLDMDIA_UPD:
3811 case ARM::VLDMDDB_UPD:
3813 case ARM::VLDMSIA_UPD:
3814 case ARM::VLDMSDB_UPD:
3816 case ARM::VSTMDIA_UPD:
3817 case ARM::VSTMDDB_UPD:
3819 case ARM::VSTMSIA_UPD:
3820 case ARM::VSTMSDB_UPD: {
3821 unsigned NumRegs =
MI.getNumOperands() -
Desc.getNumOperands();
3822 return (NumRegs / 2) + (NumRegs % 2) + 1;
3825 case ARM::LDMIA_RET:
3830 case ARM::LDMIA_UPD:
3831 case ARM::LDMDA_UPD:
3832 case ARM::LDMDB_UPD:
3833 case ARM::LDMIB_UPD:
3838 case ARM::STMIA_UPD:
3839 case ARM::STMDA_UPD:
3840 case ARM::STMDB_UPD:
3841 case ARM::STMIB_UPD:
3843 case ARM::tLDMIA_UPD:
3844 case ARM::tSTMIA_UPD:
3848 case ARM::t2LDMIA_RET:
3851 case ARM::t2LDMIA_UPD:
3852 case ARM::t2LDMDB_UPD:
3855 case ARM::t2STMIA_UPD:
3856 case ARM::t2STMDB_UPD: {
3857 unsigned NumRegs =
MI.getNumOperands() -
Desc.getNumOperands() + 1;
3869 unsigned UOps = (NumRegs / 2);
3875 unsigned UOps = (NumRegs / 2);
3878 if ((NumRegs % 2) || !
MI.hasOneMemOperand() ||
3893 unsigned DefIdx,
unsigned DefAlign)
const {
3902 DefCycle = RegNo / 2 + 1;
3907 bool isSLoad =
false;
3912 case ARM::VLDMSIA_UPD:
3913 case ARM::VLDMSDB_UPD:
3920 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
3924 DefCycle = RegNo + 2;
3934 unsigned DefIdx,
unsigned DefAlign)
const {
3944 DefCycle = RegNo / 2;
3950 DefCycle = (RegNo / 2);
3953 if ((RegNo % 2) || DefAlign < 8)
3959 DefCycle = RegNo + 2;
3969 unsigned UseIdx,
unsigned UseAlign)
const {
3977 UseCycle = RegNo / 2 + 1;
3982 bool isSStore =
false;
3987 case ARM::VSTMSIA_UPD:
3988 case ARM::VSTMSDB_UPD:
3995 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
3999 UseCycle = RegNo + 2;
4009 unsigned UseIdx,
unsigned UseAlign)
const {
4016 UseCycle = RegNo / 2;
4022 UseCycle = (RegNo / 2);
4025 if ((RegNo % 2) || UseAlign < 8)
4037 unsigned DefIdx,
unsigned DefAlign,
4039 unsigned UseIdx,
unsigned UseAlign)
const {
4050 bool LdmBypass =
false;
4057 case ARM::VLDMDIA_UPD:
4058 case ARM::VLDMDDB_UPD:
4060 case ARM::VLDMSIA_UPD:
4061 case ARM::VLDMSDB_UPD:
4062 DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
4065 case ARM::LDMIA_RET:
4070 case ARM::LDMIA_UPD:
4071 case ARM::LDMDA_UPD:
4072 case ARM::LDMDB_UPD:
4073 case ARM::LDMIB_UPD:
4075 case ARM::tLDMIA_UPD:
4077 case ARM::t2LDMIA_RET:
4080 case ARM::t2LDMIA_UPD:
4081 case ARM::t2LDMDB_UPD:
4083 DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
4098 case ARM::VSTMDIA_UPD:
4099 case ARM::VSTMDDB_UPD:
4101 case ARM::VSTMSIA_UPD:
4102 case ARM::VSTMSDB_UPD:
4103 UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
4110 case ARM::STMIA_UPD:
4111 case ARM::STMDA_UPD:
4112 case ARM::STMDB_UPD:
4113 case ARM::STMIB_UPD:
4114 case ARM::tSTMIA_UPD:
4119 case ARM::t2STMIA_UPD:
4120 case ARM::t2STMDB_UPD:
4121 UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
4129 UseCycle = DefCycle - UseCycle + 1;
4138 UseClass, UseIdx)) {
4148 unsigned &DefIdx,
unsigned &Dist) {
4153 assert(II->isInsideBundle() &&
"Empty bundle?");
4156 while (II->isInsideBundle()) {
4157 Idx = II->findRegisterDefOperandIdx(Reg,
false,
true,
TRI);
4164 assert(
Idx != -1 &&
"Cannot find bundled definition!");
4171 unsigned &UseIdx,
unsigned &Dist) {
4175 assert(II->isInsideBundle() &&
"Empty bundle?");
4180 while (II !=
E && II->isInsideBundle()) {
4181 Idx = II->findRegisterUseOperandIdx(Reg,
false,
TRI);
4184 if (II->getOpcode() != ARM::t2IT)
4212 unsigned ShOpVal =
DefMI.getOperand(3).getImm();
4222 case ARM::t2LDRSHs: {
4224 unsigned ShAmt =
DefMI.getOperand(3).getImm();
4225 if (ShAmt == 0 || ShAmt == 2)
4230 }
else if (Subtarget.
isSwift()) {
4237 unsigned ShOpVal =
DefMI.getOperand(3).getImm();
4242 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
4253 case ARM::t2LDRSHs: {
4255 unsigned ShAmt =
DefMI.getOperand(3).getImm();
4256 if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
4263 if (DefAlign < 8 && Subtarget.checkVLDnAccessAlignment()) {
4270 case ARM::VLD1q8wb_fixed:
4271 case ARM::VLD1q16wb_fixed:
4272 case ARM::VLD1q32wb_fixed:
4273 case ARM::VLD1q64wb_fixed:
4274 case ARM::VLD1q8wb_register:
4275 case ARM::VLD1q16wb_register:
4276 case ARM::VLD1q32wb_register:
4277 case ARM::VLD1q64wb_register:
4284 case ARM::VLD2d8wb_fixed:
4285 case ARM::VLD2d16wb_fixed:
4286 case ARM::VLD2d32wb_fixed:
4287 case ARM::VLD2q8wb_fixed:
4288 case ARM::VLD2q16wb_fixed:
4289 case ARM::VLD2q32wb_fixed:
4290 case ARM::VLD2d8wb_register:
4291 case ARM::VLD2d16wb_register:
4292 case ARM::VLD2d32wb_register:
4293 case ARM::VLD2q8wb_register:
4294 case ARM::VLD2q16wb_register:
4295 case ARM::VLD2q32wb_register:
4300 case ARM::VLD3d8_UPD:
4301 case ARM::VLD3d16_UPD:
4302 case ARM::VLD3d32_UPD:
4303 case ARM::VLD1d64Twb_fixed:
4304 case ARM::VLD1d64Twb_register:
4305 case ARM::VLD3q8_UPD:
4306 case ARM::VLD3q16_UPD:
4307 case ARM::VLD3q32_UPD:
4312 case ARM::VLD4d8_UPD:
4313 case ARM::VLD4d16_UPD:
4314 case ARM::VLD4d32_UPD:
4315 case ARM::VLD1d64Qwb_fixed:
4316 case ARM::VLD1d64Qwb_register:
4317 case ARM::VLD4q8_UPD:
4318 case ARM::VLD4q16_UPD:
4319 case ARM::VLD4q32_UPD:
4320 case ARM::VLD1DUPq8:
4321 case ARM::VLD1DUPq16:
4322 case ARM::VLD1DUPq32:
4323 case ARM::VLD1DUPq8wb_fixed:
4324 case ARM::VLD1DUPq16wb_fixed:
4325 case ARM::VLD1DUPq32wb_fixed:
4326 case ARM::VLD1DUPq8wb_register:
4327 case ARM::VLD1DUPq16wb_register:
4328 case ARM::VLD1DUPq32wb_register:
4329 case ARM::VLD2DUPd8:
4330 case ARM::VLD2DUPd16:
4331 case ARM::VLD2DUPd32:
4332 case ARM::VLD2DUPd8wb_fixed:
4333 case ARM::VLD2DUPd16wb_fixed:
4334 case ARM::VLD2DUPd32wb_fixed:
4335 case ARM::VLD2DUPd8wb_register:
4336 case ARM::VLD2DUPd16wb_register:
4337 case ARM::VLD2DUPd32wb_register:
4338 case ARM::VLD4DUPd8:
4339 case ARM::VLD4DUPd16:
4340 case ARM::VLD4DUPd32:
4341 case ARM::VLD4DUPd8_UPD:
4342 case ARM::VLD4DUPd16_UPD:
4343 case ARM::VLD4DUPd32_UPD:
4345 case ARM::VLD1LNd16:
4346 case ARM::VLD1LNd32:
4347 case ARM::VLD1LNd8_UPD:
4348 case ARM::VLD1LNd16_UPD:
4349 case ARM::VLD1LNd32_UPD:
4351 case ARM::VLD2LNd16:
4352 case ARM::VLD2LNd32:
4353 case ARM::VLD2LNq16:
4354 case ARM::VLD2LNq32:
4355 case ARM::VLD2LNd8_UPD:
4356 case ARM::VLD2LNd16_UPD:
4357 case ARM::VLD2LNd32_UPD:
4358 case ARM::VLD2LNq16_UPD:
4359 case ARM::VLD2LNq32_UPD:
4361 case ARM::VLD4LNd16:
4362 case ARM::VLD4LNd32:
4363 case ARM::VLD4LNq16:
4364 case ARM::VLD4LNq32:
4365 case ARM::VLD4LNd8_UPD:
4366 case ARM::VLD4LNd16_UPD:
4367 case ARM::VLD4LNd32_UPD:
4368 case ARM::VLD4LNq16_UPD:
4369 case ARM::VLD4LNq32_UPD:
4383 unsigned UseIdx)
const {
4385 if (!ItinData || ItinData->
isEmpty())
4392 unsigned DefAdj = 0;
4393 if (
DefMI.isBundle())
4402 unsigned UseAdj = 0;
4403 if (
UseMI.isBundle()) {
4410 return getOperandLatencyImpl(
4411 ItinData, *ResolvedDefMI, DefIdx, ResolvedDefMI->
getDesc(), DefAdj, DefMO,
4412 Reg, *ResolvedUseMI, UseIdx, ResolvedUseMI->
getDesc(), UseAdj);
4415int ARMBaseInstrInfo::getOperandLatencyImpl(
4417 unsigned DefIdx,
const MCInstrDesc &DefMCID,
unsigned DefAdj,
4419 unsigned UseIdx,
const MCInstrDesc &UseMCID,
unsigned UseAdj)
const {
4420 if (Reg == ARM::CPSR) {
4421 if (
DefMI.getOpcode() == ARM::FMSTAT) {
4423 return Subtarget.
isLikeA9() ? 1 : 20;
4427 if (
UseMI.isBranch())
4449 unsigned DefAlign =
DefMI.hasOneMemOperand()
4452 unsigned UseAlign =
UseMI.hasOneMemOperand()
4464 int Adj = DefAdj + UseAdj;
4468 if (Adj >= 0 || (
int)
Latency > -Adj) {
4477 SDNode *DefNode,
unsigned DefIdx,
4478 SDNode *UseNode,
unsigned UseIdx)
const {
4484 if (isZeroCost(DefMCID.
Opcode))
4487 if (!ItinData || ItinData->
isEmpty())
4488 return DefMCID.
mayLoad() ? 3 : 1;
4493 int Threshold = 1 + Adj;
4498 auto *DefMN = cast<MachineSDNode>(DefNode);
4499 unsigned DefAlign = !DefMN->memoperands_empty()
4500 ? (*DefMN->memoperands_begin())->
getAlign().value()
4502 auto *UseMN = cast<MachineSDNode>(UseNode);
4503 unsigned UseAlign = !UseMN->memoperands_empty()
4504 ? (*UseMN->memoperands_begin())->
getAlign().value()
4507 UseMCID, UseIdx, UseAlign);
4519 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
4529 case ARM::t2LDRSHs: {
4532 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
4533 if (ShAmt == 0 || ShAmt == 2)
4546 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
4549 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
4566 if (DefAlign < 8 && Subtarget.checkVLDnAccessAlignment())
4573 case ARM::VLD1q8wb_register:
4574 case ARM::VLD1q16wb_register:
4575 case ARM::VLD1q32wb_register:
4576 case ARM::VLD1q64wb_register:
4577 case ARM::VLD1q8wb_fixed:
4578 case ARM::VLD1q16wb_fixed:
4579 case ARM::VLD1q32wb_fixed:
4580 case ARM::VLD1q64wb_fixed:
4584 case ARM::VLD2q8Pseudo:
4585 case ARM::VLD2q16Pseudo:
4586 case ARM::VLD2q32Pseudo:
4587 case ARM::VLD2d8wb_fixed:
4588 case ARM::VLD2d16wb_fixed:
4589 case ARM::VLD2d32wb_fixed:
4590 case ARM::VLD2q8PseudoWB_fixed:
4591 case ARM::VLD2q16PseudoWB_fixed:
4592 case ARM::VLD2q32PseudoWB_fixed:
4593 case ARM::VLD2d8wb_register:
4594 case ARM::VLD2d16wb_register:
4595 case ARM::VLD2d32wb_register:
4596 case ARM::VLD2q8PseudoWB_register:
4597 case ARM::VLD2q16PseudoWB_register:
4598 case ARM::VLD2q32PseudoWB_register:
4599 case ARM::VLD3d8Pseudo:
4600 case ARM::VLD3d16Pseudo:
4601 case ARM::VLD3d32Pseudo:
4602 case ARM::VLD1d8TPseudo:
4603 case ARM::VLD1d16TPseudo:
4604 case ARM::VLD1d32TPseudo:
4605 case ARM::VLD1d64TPseudo:
4606 case ARM::VLD1d64TPseudoWB_fixed:
4607 case ARM::VLD1d64TPseudoWB_register:
4608 case ARM::VLD3d8Pseudo_UPD:
4609 case ARM::VLD3d16Pseudo_UPD:
4610 case ARM::VLD3d32Pseudo_UPD:
4611 case ARM::VLD3q8Pseudo_UPD:
4612 case ARM::VLD3q16Pseudo_UPD:
4613 case ARM::VLD3q32Pseudo_UPD:
4614 case ARM::VLD3q8oddPseudo:
4615 case ARM::VLD3q16oddPseudo:
4616 case ARM::VLD3q32oddPseudo:
4617 case ARM::VLD3q8oddPseudo_UPD:
4618 case ARM::VLD3q16oddPseudo_UPD:
4619 case ARM::VLD3q32oddPseudo_UPD:
4620 case ARM::VLD4d8Pseudo:
4621 case ARM::VLD4d16Pseudo:
4622 case ARM::VLD4d32Pseudo:
4623 case ARM::VLD1d8QPseudo:
4624 case ARM::VLD1d16QPseudo:
4625 case ARM::VLD1d32QPseudo:
4626 case ARM::VLD1d64QPseudo:
4627 case ARM::VLD1d64QPseudoWB_fixed:
4628 case ARM::VLD1d64QPseudoWB_register:
4629 case ARM::VLD1q8HighQPseudo:
4630 case ARM::VLD1q8LowQPseudo_UPD:
4631 case ARM::VLD1q8HighTPseudo:
4632 case ARM::VLD1q8LowTPseudo_UPD:
4633 case ARM::VLD1q16HighQPseudo:
4634 case ARM::VLD1q16LowQPseudo_UPD:
4635 case ARM::VLD1q16HighTPseudo:
4636 case ARM::VLD1q16LowTPseudo_UPD:
4637 case ARM::VLD1q32HighQPseudo:
4638 case ARM::VLD1q32LowQPseudo_UPD:
4639 case ARM::VLD1q32HighTPseudo:
4640 case ARM::VLD1q32LowTPseudo_UPD:
4641 case ARM::VLD1q64HighQPseudo:
4642 case ARM::VLD1q64LowQPseudo_UPD:
4643 case ARM::VLD1q64HighTPseudo:
4644 case ARM::VLD1q64LowTPseudo_UPD:
4645 case ARM::VLD4d8Pseudo_UPD:
4646 case ARM::VLD4d16Pseudo_UPD:
4647 case ARM::VLD4d32Pseudo_UPD:
4648 case ARM::VLD4q8Pseudo_UPD:
4649 case ARM::VLD4q16Pseudo_UPD:
4650 case ARM::VLD4q32Pseudo_UPD:
4651 case ARM::VLD4q8oddPseudo:
4652 case ARM::VLD4q16oddPseudo:
4653 case ARM::VLD4q32oddPseudo:
4654 case ARM::VLD4q8oddPseudo_UPD:
4655 case ARM::VLD4q16oddPseudo_UPD:
4656 case ARM::VLD4q32oddPseudo_UPD:
4657 case ARM::VLD1DUPq8:
4658 case ARM::VLD1DUPq16:
4659 case ARM::VLD1DUPq32:
4660 case ARM::VLD1DUPq8wb_fixed:
4661 case ARM::VLD1DUPq16wb_fixed:
4662 case ARM::VLD1DUPq32wb_fixed:
4663 case ARM::VLD1DUPq8wb_register:
4664 case ARM::VLD1DUPq16wb_register:
4665 case ARM::VLD1DUPq32wb_register:
4666 case ARM::VLD2DUPd8:
4667 case ARM::VLD2DUPd16:
4668 case ARM::VLD2DUPd32:
4669 case ARM::VLD2DUPd8wb_fixed:
4670 case ARM::VLD2DUPd16wb_fixed:
4671 case ARM::VLD2DUPd32wb_fixed:
4672 case ARM::VLD2DUPd8wb_register:
4673 case ARM::VLD2DUPd16wb_register:
4674 case ARM::VLD2DUPd32wb_register:
4675 case ARM::VLD2DUPq8EvenPseudo:
4676 case ARM::VLD2DUPq8OddPseudo:
4677 case ARM::VLD2DUPq16EvenPseudo:
4678 case ARM::VLD2DUPq16OddPseudo:
4679 case ARM::VLD2DUPq32EvenPseudo:
4680 case ARM::VLD2DUPq32OddPseudo:
4681 case ARM::VLD3DUPq8EvenPseudo:
4682 case ARM::VLD3DUPq8OddPseudo:
4683 case ARM::VLD3DUPq16EvenPseudo:
4684 case ARM::VLD3DUPq16OddPseudo:
4685 case ARM::VLD3DUPq32EvenPseudo:
4686 case ARM::VLD3DUPq32OddPseudo:
4687 case ARM::VLD4DUPd8Pseudo:
4688 case ARM::VLD4DUPd16Pseudo:
4689 case ARM::VLD4DUPd32Pseudo:
4690 case ARM::VLD4DUPd8Pseudo_UPD:
4691 case ARM::VLD4DUPd16Pseudo_UPD:
4692 case ARM::VLD4DUPd32Pseudo_UPD:
4693 case ARM::VLD4DUPq8EvenPseudo:
4694 case ARM::VLD4DUPq8OddPseudo:
4695 case ARM::VLD4DUPq16EvenPseudo:
4696 case ARM::VLD4DUPq16OddPseudo:
4697 case ARM::VLD4DUPq32EvenPseudo:
4698 case ARM::VLD4DUPq32OddPseudo:
4699 case ARM::VLD1LNq8Pseudo:
4700 case ARM::VLD1LNq16Pseudo:
4701 case ARM::VLD1LNq32Pseudo:
4702 case ARM::VLD1LNq8Pseudo_UPD:
4703 case ARM::VLD1LNq16Pseudo_UPD:
4704 case ARM::VLD1LNq32Pseudo_UPD:
4705 case ARM::VLD2LNd8Pseudo:
4706 case ARM::VLD2LNd16Pseudo:
4707 case ARM::VLD2LNd32Pseudo:
4708 case ARM::VLD2LNq16Pseudo:
4709 case ARM::VLD2LNq32Pseudo:
4710 case ARM::VLD2LNd8Pseudo_UPD:
4711 case ARM::VLD2LNd16Pseudo_UPD:
4712 case ARM::VLD2LNd32Pseudo_UPD:
4713 case ARM::VLD2LNq16Pseudo_UPD:
4714 case ARM::VLD2LNq32Pseudo_UPD:
4715 case ARM::VLD4LNd8Pseudo:
4716 case ARM::VLD4LNd16Pseudo:
4717 case ARM::VLD4LNd32Pseudo:
4718 case ARM::VLD4LNq16Pseudo:
4719 case ARM::VLD4LNq32Pseudo:
4720 case ARM::VLD4LNd8Pseudo_UPD:
4721 case ARM::VLD4LNd16Pseudo_UPD:
4722 case ARM::VLD4LNd32Pseudo_UPD:
4723 case ARM::VLD4LNq16Pseudo_UPD:
4724 case ARM::VLD4LNq32Pseudo_UPD:
4734unsigned ARMBaseInstrInfo::getPredicationCost(
const MachineInstr &
MI)
const {
4735 if (
MI.isCopyLike() ||
MI.isInsertSubreg() ||
MI.isRegSequence() ||
4745 !Subtarget.cheapPredicableCPSRDef())) {
4755 unsigned *PredCost)
const {
4756 if (
MI.isCopyLike() ||
MI.isInsertSubreg() ||
MI.isRegSequence() ||
4762 if (
MI.isBundle()) {
4766 while (++
I !=
E &&
I->isInsideBundle()) {
4767 if (
I->getOpcode() != ARM::t2IT)
4768 Latency += getInstrLatency(ItinData, *
I, PredCost);
4775 !Subtarget.cheapPredicableCPSRDef()))) {
4783 return MI.mayLoad() ? 3 : 1;
4796 MI.hasOneMemOperand() ? (*
MI.memoperands_begin())->
getAlign().value() : 0;
4798 if (Adj >= 0 || (
int)
Latency > -Adj) {
4806 if (!
Node->isMachineOpcode())
4809 if (!ItinData || ItinData->
isEmpty())
4812 unsigned Opcode =
Node->getMachineOpcode();
4822bool ARMBaseInstrInfo::hasHighOperandLatency(
const TargetSchedModel &SchedModel,
4827 unsigned UseIdx)
const {
4830 if (Subtarget.nonpipelinedVFP() &&
4845 unsigned DefIdx)
const {
4847 if (!ItinData || ItinData->
isEmpty())
4852 unsigned DefClass =
DefMI.getDesc().getSchedClass();
4854 return (DefCycle != -1 && DefCycle <= 2);
4862 ErrInfo =
"Pseudo flag setting opcodes only exist in Selection DAG";
4865 if (
MI.getOpcode() == ARM::tMOVr && !Subtarget.hasV6Ops()) {
4867 if (!ARM::hGPRRegClass.
contains(
MI.getOperand(0).getReg()) &&
4868 !ARM::hGPRRegClass.contains(
MI.getOperand(1).getReg())) {
4869 ErrInfo =
"Non-flag-setting Thumb1 mov is v6-only";
4873 if (
MI.getOpcode() == ARM::tPUSH ||
4874 MI.getOpcode() == ARM::tPOP ||