40 #define GET_INSTRINFO_CTOR_DTOR
41 #include "ARMGenInstrInfo.inc"
47 cl::desc(
"Enable ARM 2-addr to 3-addr conv"));
51 cl::desc(
"Widen ARM vmovs to vmovd when possible"));
56 cl::desc(
"Clearance before partial register updates"));
70 { ARM::VMLAS, ARM::VMULS, ARM::VADDS,
false,
false },
71 { ARM::VMLSS, ARM::VMULS, ARM::VSUBS,
false,
false },
72 { ARM::VMLAD, ARM::VMULD, ARM::VADDD,
false,
false },
73 { ARM::VMLSD, ARM::VMULD, ARM::VSUBD,
false,
false },
74 { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS,
true,
false },
75 { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS,
true,
false },
76 { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD,
true,
false },
77 { ARM::VNMLSD, ARM::VMULD, ARM::VSUBD,
true,
false },
80 { ARM::VMLAfd, ARM::VMULfd, ARM::VADDfd,
false,
false },
81 { ARM::VMLSfd, ARM::VMULfd, ARM::VSUBfd,
false,
false },
82 { ARM::VMLAfq, ARM::VMULfq, ARM::VADDfq,
false,
false },
83 { ARM::VMLSfq, ARM::VMULfq, ARM::VSUBfq,
false,
false },
84 { ARM::VMLAslfd, ARM::VMULslfd, ARM::VADDfd,
false,
true },
85 { ARM::VMLSslfd, ARM::VMULslfd, ARM::VSUBfd,
false,
true },
86 { ARM::VMLAslfq, ARM::VMULslfq, ARM::VADDfq,
false,
true },
87 { ARM::VMLSslfq, ARM::VMULslfq, ARM::VSUBfq,
false,
true },
95 assert(
false &&
"Duplicated entries?");
106 if (usePreRAHazardRecognizer()) {
135 default:
return NULL;
158 unsigned WBReg = WB.
getReg();
159 unsigned BaseReg = Base.
getReg();
160 unsigned OffReg = Offset.
getReg();
174 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
177 }
else if (Amt != 0) {
181 get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
186 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
197 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
202 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
209 std::vector<MachineInstr*> NewMIs;
219 NewMIs.push_back(MemMI);
220 NewMIs.push_back(UpdateMI);
232 NewMIs.push_back(UpdateMI);
233 NewMIs.push_back(MemMI);
245 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
250 for (
unsigned j = 0; j < 2; ++j) {
257 VI.
Kills.push_back(NewMI);
265 MFI->insert(MBBI, NewMIs[1]);
266 MFI->insert(MBBI, NewMIs[0]);
275 bool AllowModify)
const {
280 if (I == MBB.
begin())
291 bool CantAnalyze =
false;
294 while (I->isDebugValue() || !I->isTerminator()) {
295 if (I == MBB.
begin())
306 TBB = I->getOperand(0).getMBB();
312 assert(!FBB &&
"FBB should have been null.");
314 TBB = I->getOperand(0).getMBB();
317 }
else if (I->isReturn()) {
340 while (DI != MBB.
end()) {
351 if (I == MBB.
begin())
365 if (I == MBB.
begin())
return 0;
367 while (I->isDebugValue()) {
368 if (I == MBB.
begin())
377 I->eraseFromParent();
381 if (I == MBB.
begin())
return 1;
387 I->eraseFromParent();
404 assert(TBB &&
"InsertBranch must not be told to insert a fallthrough");
405 assert((Cond.
size() == 2 || Cond.
size() == 0) &&
406 "ARM branch conditions have two components!");
441 while (++I != E && I->isInsideBundle()) {
442 int PIdx = I->findFirstPredOperandIdx();
443 if (PIdx != -1 && I->getOperand(PIdx).getImm() !=
ARMCC::AL)
460 .addImm(Pred[0].getImm())
461 .addReg(Pred[1].
getReg());
468 PMO.
setImm(Pred[0].getImm());
478 if (Pred1.
size() > 2 || Pred2.
size() > 2)
503 std::vector<MachineOperand> &Pred)
const {
540 static unsigned getNumJTEntries(
const std::vector<MachineJumpTableEntry> &JT,
544 assert(JTI < JT.size());
545 return JT[JTI].MBBs.size();
573 return getInstBundleLength(MI);
574 case ARM::MOVi16_ga_pcrel:
575 case ARM::MOVTi16_ga_pcrel:
576 case ARM::t2MOVi16_ga_pcrel:
577 case ARM::t2MOVTi16_ga_pcrel:
580 case ARM::t2MOVi32imm:
582 case ARM::CONSTPOOL_ENTRY:
586 case ARM::Int_eh_sjlj_longjmp:
588 case ARM::tInt_eh_sjlj_longjmp:
590 case ARM::Int_eh_sjlj_setjmp:
591 case ARM::Int_eh_sjlj_setjmp_nofp:
593 case ARM::tInt_eh_sjlj_setjmp:
594 case ARM::t2Int_eh_sjlj_setjmp:
595 case ARM::t2Int_eh_sjlj_setjmp_nofp:
603 case ARM::t2TBH_JT: {
607 unsigned EntrySize = (Opc == ARM::t2TBB_JT)
608 ? 1 : ((Opc == ARM::t2TBH_JT) ? 2 : 4);
615 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
616 assert(JTI < JT.size());
624 unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;
626 if (Opc == ARM::t2TBB_JT && (NumEntries & 1))
631 return NumEntries * EntrySize + InstSize;
639 unsigned ARMBaseInstrInfo::getInstBundleLength(
const MachineInstr *
MI)
const {
643 while (++I != E && I->isInsideBundle()) {
644 assert(!I->isBundle() &&
"No nested bundle!");
652 unsigned DestReg,
unsigned SrcReg,
653 bool KillSrc)
const {
654 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
655 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
657 if (GPRDest && GPRSrc) {
663 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
664 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
667 if (SPRDest && SPRSrc)
669 else if (GPRDest && SPRSrc)
671 else if (SPRDest && GPRSrc)
673 else if (ARM::DPRRegClass.contains(DestReg, SrcReg))
675 else if (ARM::QPRRegClass.contains(DestReg, SrcReg))
681 if (Opc == ARM::VORRq)
688 unsigned BeginIdx = 0;
689 unsigned SubRegs = 0;
693 if (ARM::QQPRRegClass.contains(DestReg, SrcReg)) {
695 BeginIdx = ARM::qsub_0;
697 }
else if (ARM::QQQQPRRegClass.contains(DestReg, SrcReg)) {
699 BeginIdx = ARM::qsub_0;
702 }
else if (ARM::DPairRegClass.contains(DestReg, SrcReg)) {
704 BeginIdx = ARM::dsub_0;
706 }
else if (ARM::DTripleRegClass.contains(DestReg, SrcReg)) {
708 BeginIdx = ARM::dsub_0;
710 }
else if (ARM::DQuadRegClass.contains(DestReg, SrcReg)) {
712 BeginIdx = ARM::dsub_0;
714 }
else if (ARM::GPRPairRegClass.contains(DestReg, SrcReg)) {
715 Opc = Subtarget.
isThumb2() ? ARM::tMOVr : ARM::MOVr;
716 BeginIdx = ARM::gsub_0;
718 }
else if (ARM::DPairSpcRegClass.contains(DestReg, SrcReg)) {
720 BeginIdx = ARM::dsub_0;
723 }
else if (ARM::DTripleSpcRegClass.contains(DestReg, SrcReg)) {
725 BeginIdx = ARM::dsub_0;
728 }
else if (ARM::DQuadSpcRegClass.contains(DestReg, SrcReg)) {
730 BeginIdx = ARM::dsub_0;
735 assert(Opc &&
"Impossible reg-to-reg copy");
742 BeginIdx = BeginIdx + ((SubRegs - 1) * Spacing);
748 for (
unsigned i = 0; i != SubRegs; ++i) {
749 unsigned Dst = TRI->
getSubReg(DestReg, BeginIdx + i * Spacing);
750 unsigned Src = TRI->
getSubReg(SrcReg, BeginIdx + i * Spacing);
751 assert(Dst && Src &&
"Bad sub-register");
753 assert(!DstRegs.
count(Src) &&
"destructive vector copy");
756 Mov =
BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), Dst).
addReg(Src);
758 if (Opc == ARM::VORRq)
762 if (Opc == ARM::MOVr)
773 unsigned SubIdx,
unsigned State,
776 return MIB.
addReg(Reg, State);
780 return MIB.
addReg(Reg, State, SubIdx);
785 unsigned SrcReg,
bool isKill,
int FI,
789 if (I != MBB.
end()) DL = I->getDebugLoc();
802 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
805 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
806 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
809 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
814 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
817 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
818 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
822 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
831 .addFrameIndex(FI).addMemOperand(MMO));
833 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
839 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
843 .addFrameIndex(FI).addImm(16)
845 .addMemOperand(MMO));
850 .addMemOperand(MMO));
856 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
860 .addFrameIndex(FI).addImm(16)
862 .addMemOperand(MMO));
869 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
870 AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
876 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
881 .addFrameIndex(FI).addImm(16)
883 .addMemOperand(MMO));
890 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
891 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
892 AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
898 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
904 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
905 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
906 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
907 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
908 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
909 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
910 AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
948 case ARM::VST1d64TPseudo:
949 case ARM::VST1d64QPseudo:
971 return MI->
mayStore() && hasStoreToStackSlot(MI, Dummy, FrameIndex);
976 unsigned DestReg,
int FI,
980 if (I != MBB.
end()) DL = I->getDebugLoc();
993 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
995 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
997 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
999 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1004 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1006 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1007 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1011 MIB =
BuildMI(MBB, I, DL,
get(ARM::LDRD));
1021 .addFrameIndex(FI).addMemOperand(MMO));
1032 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
1035 .addFrameIndex(FI).addImm(16)
1036 .addMemOperand(MMO));
1040 .addMemOperand(MMO));
1046 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1049 .addFrameIndex(FI).addImm(16)
1050 .addMemOperand(MMO));
1055 .addMemOperand(MMO));
1066 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
1069 .addFrameIndex(FI).addImm(16)
1070 .addMemOperand(MMO));
1087 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1139 case ARM::VLD1d64TPseudo:
1140 case ARM::VLD1d64QPseudo:
1162 return MI->
mayLoad() && hasLoadFromStackSlot(MI, Dummy, FrameIndex);
1175 unsigned DstRegS = MI->getOperand(0).getReg();
1176 unsigned SrcRegS = MI->getOperand(1).getReg();
1177 if (!ARM::SPRRegClass.contains(DstRegS, SrcRegS))
1185 if (!DstRegD || !SrcRegD)
1191 if (!MI->definesRegister(DstRegD, TRI) || MI->readsRegister(DstRegD, TRI))
1195 if (MI->getOperand(0).isDead())
1205 if (ImpDefIdx != -1)
1206 MI->RemoveOperand(ImpDefIdx);
1209 MI->setDesc(
get(ARM::VMOVD));
1210 MI->getOperand(0).setReg(DstRegD);
1211 MI->getOperand(1).setReg(SrcRegD);
1218 MI->getOperand(1).setIsUndef();
1223 if (MI->getOperand(1).isKill()) {
1224 MI->getOperand(1).setIsKill(
false);
1225 MI->addRegisterKilled(SrcRegS, TRI,
true);
1228 DEBUG(
dbgs() <<
"replaced by: " << *MI);
1239 assert(MCPE.isMachineConstantPoolEntry() &&
1240 "Expecting a machine constantpool entry!");
1251 if (ACPV->isGlobalValue())
1253 Create(cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
1255 else if (ACPV->isExtSymbol())
1258 cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(), PCLabelId, 4);
1259 else if (ACPV->isBlockAddress())
1261 Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
1263 else if (ACPV->isLSDA())
1266 else if (ACPV->isMachineBasicBlock())
1269 cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
1279 unsigned DestReg,
unsigned SubIdx,
1290 case ARM::tLDRpci_pic:
1291 case ARM::t2LDRpci_pic: {
1308 case ARM::tLDRpci_pic:
1309 case ARM::t2LDRpci_pic: {
1324 if (Opcode == ARM::t2LDRpci ||
1325 Opcode == ARM::t2LDRpci_pic ||
1326 Opcode == ARM::tLDRpci ||
1327 Opcode == ARM::tLDRpci_pic ||
1328 Opcode == ARM::MOV_ga_dyn ||
1329 Opcode == ARM::MOV_ga_pcrel ||
1330 Opcode == ARM::MOV_ga_pcrel_ldr ||
1331 Opcode == ARM::t2MOV_ga_dyn ||
1332 Opcode == ARM::t2MOV_ga_pcrel) {
1343 if (Opcode == ARM::MOV_ga_dyn ||
1344 Opcode == ARM::MOV_ga_pcrel ||
1345 Opcode == ARM::MOV_ga_pcrel_ldr ||
1346 Opcode == ARM::t2MOV_ga_dyn ||
1347 Opcode == ARM::t2MOV_ga_pcrel)
1359 if (isARMCP0 && isARMCP1) {
1365 }
else if (!isARMCP0 && !isARMCP1) {
1369 }
else if (Opcode == ARM::PICLDR) {
1377 if (Addr0 != Addr1) {
1415 int64_t &Offset2)
const {
1436 case ARM::t2LDRSHi8:
1438 case ARM::t2LDRBi12:
1439 case ARM::t2LDRSHi12:
1456 case ARM::t2LDRSHi8:
1458 case ARM::t2LDRBi12:
1459 case ARM::t2LDRSHi12:
1473 if (isa<ConstantSDNode>(Load1->
getOperand(1)) &&
1475 Offset1 = cast<ConstantSDNode>(Load1->
getOperand(1))->getSExtValue();
1476 Offset2 = cast<ConstantSDNode>(Load2->
getOperand(1))->getSExtValue();
1495 int64_t Offset1, int64_t Offset2,
1496 unsigned NumLoads)
const {
1500 assert(Offset2 > Offset1);
1502 if ((Offset2 - Offset1) / 8 > 64)
1548 while (++I != MBB->
end() && I->isDebugValue())
1550 if (I != MBB->
end() && I->getOpcode() == ARM::t2IT)
1569 unsigned NumCycles,
unsigned ExtraPredCycles,
1575 unsigned UnpredCost = Probability.
getNumerator() * NumCycles;
1580 return (NumCycles + ExtraPredCycles) <= UnpredCost;
1585 unsigned TCycles,
unsigned TExtra,
1587 unsigned FCycles,
unsigned FExtra,
1589 if (!TCycles || !FCycles)
1593 unsigned TUnpredCost = Probability.
getNumerator() * TCycles;
1597 unsigned FUnpredCost = Comp * FCycles;
1600 unsigned UnpredCost = TUnpredCost + FUnpredCost;
1604 return (TCycles + FCycles + TExtra + FExtra) <= UnpredCost;
1636 if (Opc == ARM::t2B)
1647 case ARM::t2MOVCCr: {
1649 unsigned PredReg = 0;
1652 if (CC ==
ARMCC::AL || PredReg != ARM::CPSR)
1698 bool DontMoveAcrossStores =
true;
1706 unsigned &TrueOp,
unsigned &FalseOp,
1707 bool &Optimizable)
const {
1709 "Unknown select instruction");
1726 bool PreferFalse)
const {
1728 "Unknown select instruction");
1731 bool Invert = !DefMI;
1751 for (
unsigned i = 1, e = DefDesc.getNumOperands();
1752 i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
1791 {ARM::ADDSri, ARM::ADDri},
1792 {ARM::ADDSrr, ARM::ADDrr},
1793 {ARM::ADDSrsi, ARM::ADDrsi},
1794 {ARM::ADDSrsr, ARM::ADDrsr},
1796 {ARM::SUBSri, ARM::SUBri},
1797 {ARM::SUBSrr, ARM::SUBrr},
1798 {ARM::SUBSrsi, ARM::SUBrsi},
1799 {ARM::SUBSrsr, ARM::SUBrsr},
1801 {ARM::RSBSri, ARM::RSBri},
1802 {ARM::RSBSrsi, ARM::RSBrsi},
1803 {ARM::RSBSrsr, ARM::RSBrsr},
1805 {ARM::t2ADDSri, ARM::t2ADDri},
1806 {ARM::t2ADDSrr, ARM::t2ADDrr},
1807 {ARM::t2ADDSrs, ARM::t2ADDrs},
1809 {ARM::t2SUBSri, ARM::t2SUBri},
1810 {ARM::t2SUBSrr, ARM::t2SUBrr},
1811 {ARM::t2SUBSrs, ARM::t2SUBrs},
1813 {ARM::t2RSBSri, ARM::t2RSBri},
1814 {ARM::t2RSBSrs, ARM::t2RSBrs},
1826 unsigned DestReg,
unsigned BaseReg,
int NumBytes,
1829 if (NumBytes == 0 && DestReg != BaseReg) {
1830 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), DestReg)
1837 bool isSub = NumBytes < 0;
1838 if (isSub) NumBytes = -NumBytes;
1843 assert(ThisVal &&
"Didn't extract field correctly");
1846 NumBytes &= ~ThisVal;
1851 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
1852 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
1862 unsigned NumBytes) {
1873 if (!IsPush && !IsPop)
1876 bool IsVFPPushPop = MI->
getOpcode() == ARM::VSTMDDB_UPD ||
1878 bool IsT1PushPop = MI->
getOpcode() == ARM::tPUSH ||
1884 "trying to fold sp update into non-sp-updating push/pop");
1889 if (NumBytes % (IsVFPPushPop ? 8 : 4) != 0)
1894 int RegListIdx = IsT1PushPop ? 2 : 4;
1898 unsigned RD0Reg, RegsNeeded;
1901 RegsNeeded = NumBytes / 8;
1904 RegsNeeded = NumBytes / 4;
1918 for (
unsigned CurReg = FirstReg - 1; CurReg >= RD0Reg && RegsNeeded;
1919 --CurReg, --RegsNeeded) {
1925 false,
false,
true));
1951 for (
int i = RegList.
size() - 1; i >= 0; --i)
1958 unsigned FrameReg,
int &Offset,
1969 if (Opcode == ARM::ADDri) {
1973 MI.
setDesc(TII.get(ARM::MOVr));
1978 }
else if (Offset < 0) {
1981 MI.
setDesc(TII.get(ARM::SUBri));
1999 Offset &= ~ThisImmVal;
2003 "Bit extraction didn't work?");
2006 unsigned ImmIdx = 0;
2008 unsigned NumBits = 0;
2012 ImmIdx = FrameRegIdx + 1;
2018 ImmIdx = FrameRegIdx+2;
2026 ImmIdx = FrameRegIdx+2;
2038 ImmIdx = FrameRegIdx+1;
2050 Offset += InstrOffs * Scale;
2051 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
2061 int ImmedOffset = Offset / Scale;
2062 unsigned Mask = (1 << NumBits) - 1;
2063 if ((
unsigned)Offset <= Mask * Scale) {
2071 ImmedOffset = -ImmedOffset;
2073 ImmedOffset |= 1 << NumBits;
2081 ImmedOffset = ImmedOffset & Mask;
2084 ImmedOffset = -ImmedOffset;
2086 ImmedOffset |= 1 << NumBits;
2089 Offset &= ~(Mask*Scale);
2093 Offset = (isSub) ? -Offset : Offset;
2103 int &CmpMask,
int &CmpValue)
const {
2137 int CmpMask,
bool CommonUse) {
2186 unsigned SrcReg2,
int ImmValue,
2217 int CmpMask,
int CmpValue,
2221 if (!MI)
return false;
2224 if (CmpMask != ~0) {
2228 UE = MRI->
use_end(); UI != UE; ++UI) {
2229 if (UI->getParent() != CmpInstr->
getParent())
continue;
2237 if (!MI)
return false;
2246 if (I == B)
return false;
2260 if (CmpInstr->
getOpcode() == ARM::CMPri ||
2271 for (; I != E; --
I) {
2336 case ARM::t2EORri: {
2345 bool isSafe =
false;
2348 while (!isSafe && ++I != E) {
2351 !isSafe && IO != EO; ++IO) {
2376 OperandsToUpdate.
push_back(std::make_pair(&((*I).getOperand(IO-1)),
2400 SE = MBB->
succ_end(); SI != SE; ++SI)
2401 if ((*SI)->isLiveIn(ARM::CPSR))
2408 assert(!
isPredicated(MI) &&
"Can't use flags from predicated instruction");
2414 for (
unsigned i = 0, e = OperandsToUpdate.
size(); i < e; i++)
2415 OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
2428 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm)
2457 unsigned NewUseOpc = 0;
2459 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
2460 bool Commute =
false;
2462 default:
return false;
2470 case ARM::t2EORrr: {
2478 NewUseOpc = ARM::SUBri;
2490 case ARM::ADDrr: NewUseOpc = ARM::ADDri;
break;
2491 case ARM::ORRrr: NewUseOpc = ARM::ORRri;
break;
2492 case ARM::EORrr: NewUseOpc = ARM::EORri;
break;
2496 case ARM::t2SUBrr: {
2500 NewUseOpc = ARM::t2SUBri;
2505 case ARM::t2EORrr: {
2512 case ARM::t2ADDrr: NewUseOpc = ARM::t2ADDri;
break;
2513 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri;
break;
2514 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri;
break;
2522 unsigned OpIdx = Commute ? 2 : 1;
2528 get(NewUseOpc), NewReg)
2531 UseMI->
setDesc(
get(NewUseOpc));
2545 assert(UOps >= 0 &&
"bad # UOps");
2558 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2574 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2584 case ARM::LDRSB_POST:
2585 case ARM::LDRSH_POST: {
2588 return (Rt == Rm) ? 4 : 3;
2591 case ARM::LDR_PRE_REG:
2592 case ARM::LDRB_PRE_REG: {
2602 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2608 case ARM::STR_PRE_REG:
2609 case ARM::STRB_PRE_REG: {
2615 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2622 case ARM::STRH_PRE: {
2633 case ARM::LDR_POST_REG:
2634 case ARM::LDRB_POST_REG:
2635 case ARM::LDRH_POST: {
2638 return (Rt == Rm) ? 3 : 2;
2641 case ARM::LDR_PRE_IMM:
2642 case ARM::LDRB_PRE_IMM:
2643 case ARM::LDR_POST_IMM:
2644 case ARM::LDRB_POST_IMM:
2645 case ARM::STRB_POST_IMM:
2646 case ARM::STRB_POST_REG:
2647 case ARM::STRB_PRE_IMM:
2648 case ARM::STRH_POST:
2649 case ARM::STR_POST_IMM:
2650 case ARM::STR_POST_REG:
2651 case ARM::STR_PRE_IMM:
2654 case ARM::LDRSB_PRE:
2655 case ARM::LDRSH_PRE: {
2667 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2679 return (Rt == Rn) ? 3 : 2;
2689 case ARM::LDRD_POST:
2690 case ARM::t2LDRD_POST:
2693 case ARM::STRD_POST:
2694 case ARM::t2STRD_POST:
2697 case ARM::LDRD_PRE: {
2703 return (Rt == Rn) ? 4 : 3;
2706 case ARM::t2LDRD_PRE: {
2709 return (Rt == Rn) ? 4 : 3;
2712 case ARM::STRD_PRE: {
2719 case ARM::t2STRD_PRE:
2722 case ARM::t2LDR_POST:
2723 case ARM::t2LDRB_POST:
2724 case ARM::t2LDRB_PRE:
2725 case ARM::t2LDRSBi12:
2726 case ARM::t2LDRSBi8:
2727 case ARM::t2LDRSBpci:
2729 case ARM::t2LDRH_POST:
2730 case ARM::t2LDRH_PRE:
2732 case ARM::t2LDRSB_POST:
2733 case ARM::t2LDRSB_PRE:
2734 case ARM::t2LDRSH_POST:
2735 case ARM::t2LDRSH_PRE:
2736 case ARM::t2LDRSHi12:
2737 case ARM::t2LDRSHi8:
2738 case ARM::t2LDRSHpci:
2742 case ARM::t2LDRDi8: {
2745 return (Rt == Rn) ? 3 : 2;
2748 case ARM::t2STRB_POST:
2749 case ARM::t2STRB_PRE:
2752 case ARM::t2STRH_POST:
2753 case ARM::t2STRH_PRE:
2755 case ARM::t2STR_POST:
2756 case ARM::t2STR_PRE:
2788 Size += (*I)->getSize();
2796 if (!ItinData || ItinData->
isEmpty())
2802 if (ItinUOps >= 0) {
2828 case ARM::VLDMDIA_UPD:
2829 case ARM::VLDMDDB_UPD:
2831 case ARM::VLDMSIA_UPD:
2832 case ARM::VLDMSDB_UPD:
2834 case ARM::VSTMDIA_UPD:
2835 case ARM::VSTMDDB_UPD:
2837 case ARM::VSTMSIA_UPD:
2838 case ARM::VSTMSDB_UPD: {
2840 return (NumRegs / 2) + (NumRegs % 2) + 1;
2843 case ARM::LDMIA_RET:
2848 case ARM::LDMIA_UPD:
2849 case ARM::LDMDA_UPD:
2850 case ARM::LDMDB_UPD:
2851 case ARM::LDMIB_UPD:
2856 case ARM::STMIA_UPD:
2857 case ARM::STMDA_UPD:
2858 case ARM::STMDB_UPD:
2859 case ARM::STMIB_UPD:
2861 case ARM::tLDMIA_UPD:
2862 case ARM::tSTMIA_UPD:
2866 case ARM::t2LDMIA_RET:
2869 case ARM::t2LDMIA_UPD:
2870 case ARM::t2LDMDB_UPD:
2873 case ARM::t2STMIA_UPD:
2874 case ARM::t2STMDB_UPD: {
2877 int UOps = 1 + NumRegs;
2880 case ARM::VLDMDIA_UPD:
2881 case ARM::VLDMDDB_UPD:
2882 case ARM::VLDMSIA_UPD:
2883 case ARM::VLDMSDB_UPD:
2884 case ARM::VSTMDIA_UPD:
2885 case ARM::VSTMDDB_UPD:
2886 case ARM::VSTMSIA_UPD:
2887 case ARM::VSTMSDB_UPD:
2888 case ARM::LDMIA_UPD:
2889 case ARM::LDMDA_UPD:
2890 case ARM::LDMDB_UPD:
2891 case ARM::LDMIB_UPD:
2892 case ARM::STMIA_UPD:
2893 case ARM::STMDA_UPD:
2894 case ARM::STMDB_UPD:
2895 case ARM::STMIB_UPD:
2896 case ARM::tLDMIA_UPD:
2897 case ARM::tSTMIA_UPD:
2898 case ARM::t2LDMIA_UPD:
2899 case ARM::t2LDMDB_UPD:
2900 case ARM::t2STMIA_UPD:
2901 case ARM::t2STMDB_UPD:
2904 case ARM::LDMIA_RET:
2906 case ARM::t2LDMIA_RET:
2916 int A8UOps = (NumRegs / 2);
2921 int A9UOps = (NumRegs / 2);
2924 if ((NumRegs % 2) ||
2941 unsigned DefIdx,
unsigned DefAlign)
const {
2950 DefCycle = RegNo / 2 + 1;
2955 bool isSLoad =
false;
2960 case ARM::VLDMSIA_UPD:
2961 case ARM::VLDMSDB_UPD:
2968 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
2972 DefCycle = RegNo + 2;
2982 unsigned DefIdx,
unsigned DefAlign)
const {
2992 DefCycle = RegNo / 2;
2998 DefCycle = (RegNo / 2);
3001 if ((RegNo % 2) || DefAlign < 8)
3007 DefCycle = RegNo + 2;
3017 unsigned UseIdx,
unsigned UseAlign)
const {
3025 UseCycle = RegNo / 2 + 1;
3030 bool isSStore =
false;
3035 case ARM::VSTMSIA_UPD:
3036 case ARM::VSTMSDB_UPD:
3043 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
3047 UseCycle = RegNo + 2;
3057 unsigned UseIdx,
unsigned UseAlign)
const {
3064 UseCycle = RegNo / 2;
3070 UseCycle = (RegNo / 2);
3073 if ((RegNo % 2) || UseAlign < 8)
3085 unsigned DefIdx,
unsigned DefAlign,
3087 unsigned UseIdx,
unsigned UseAlign)
const {
3098 bool LdmBypass =
false;
3105 case ARM::VLDMDIA_UPD:
3106 case ARM::VLDMDDB_UPD:
3108 case ARM::VLDMSIA_UPD:
3109 case ARM::VLDMSDB_UPD:
3110 DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3113 case ARM::LDMIA_RET:
3118 case ARM::LDMIA_UPD:
3119 case ARM::LDMDA_UPD:
3120 case ARM::LDMDB_UPD:
3121 case ARM::LDMIB_UPD:
3123 case ARM::tLDMIA_UPD:
3125 case ARM::t2LDMIA_RET:
3128 case ARM::t2LDMIA_UPD:
3129 case ARM::t2LDMDB_UPD:
3131 DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3146 case ARM::VSTMDIA_UPD:
3147 case ARM::VSTMDDB_UPD:
3149 case ARM::VSTMSIA_UPD:
3150 case ARM::VSTMSDB_UPD:
3151 UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3158 case ARM::STMIA_UPD:
3159 case ARM::STMDA_UPD:
3160 case ARM::STMDB_UPD:
3161 case ARM::STMIB_UPD:
3162 case ARM::tSTMIA_UPD:
3167 case ARM::t2STMIA_UPD:
3168 case ARM::t2STMDB_UPD:
3169 UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3177 UseCycle = DefCycle - UseCycle + 1;
3186 UseClass, UseIdx)) {
3196 unsigned &DefIdx,
unsigned &Dist) {
3202 assert(II->isInsideBundle() &&
"Empty bundle?");
3205 while (II->isInsideBundle()) {
3206 Idx = II->findRegisterDefOperandIdx(Reg,
false,
true, TRI);
3213 assert(Idx != -1 &&
"Cannot find bundled definition!");
3220 unsigned &UseIdx,
unsigned &Dist) {
3224 assert(II->isInsideBundle() &&
"Empty bundle?");
3229 while (II != E && II->isInsideBundle()) {
3230 Idx = II->findRegisterUseOperandIdx(Reg,
false, TRI);
3233 if (II->getOpcode() != ARM::t2IT)
3271 case ARM::t2LDRSHs: {
3274 if (ShAmt == 0 || ShAmt == 2)
3279 }
else if (Subtarget.
isSwift()) {
3291 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3302 case ARM::t2LDRSHs: {
3305 if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
3312 if (DefAlign < 8 && Subtarget.
isLikeA9()) {
3319 case ARM::VLD1q8wb_fixed:
3320 case ARM::VLD1q16wb_fixed:
3321 case ARM::VLD1q32wb_fixed:
3322 case ARM::VLD1q64wb_fixed:
3323 case ARM::VLD1q8wb_register:
3324 case ARM::VLD1q16wb_register:
3325 case ARM::VLD1q32wb_register:
3326 case ARM::VLD1q64wb_register:
3333 case ARM::VLD2d8wb_fixed:
3334 case ARM::VLD2d16wb_fixed:
3335 case ARM::VLD2d32wb_fixed:
3336 case ARM::VLD2q8wb_fixed:
3337 case ARM::VLD2q16wb_fixed:
3338 case ARM::VLD2q32wb_fixed:
3339 case ARM::VLD2d8wb_register:
3340 case ARM::VLD2d16wb_register:
3341 case ARM::VLD2d32wb_register:
3342 case ARM::VLD2q8wb_register:
3343 case ARM::VLD2q16wb_register:
3344 case ARM::VLD2q32wb_register:
3349 case ARM::VLD3d8_UPD:
3350 case ARM::VLD3d16_UPD:
3351 case ARM::VLD3d32_UPD:
3352 case ARM::VLD1d64Twb_fixed:
3353 case ARM::VLD1d64Twb_register:
3354 case ARM::VLD3q8_UPD:
3355 case ARM::VLD3q16_UPD:
3356 case ARM::VLD3q32_UPD:
3361 case ARM::VLD4d8_UPD:
3362 case ARM::VLD4d16_UPD:
3363 case ARM::VLD4d32_UPD:
3364 case ARM::VLD1d64Qwb_fixed:
3365 case ARM::VLD1d64Qwb_register:
3366 case ARM::VLD4q8_UPD:
3367 case ARM::VLD4q16_UPD:
3368 case ARM::VLD4q32_UPD:
3369 case ARM::VLD1DUPq8:
3370 case ARM::VLD1DUPq16:
3371 case ARM::VLD1DUPq32:
3372 case ARM::VLD1DUPq8wb_fixed:
3373 case ARM::VLD1DUPq16wb_fixed:
3374 case ARM::VLD1DUPq32wb_fixed:
3375 case ARM::VLD1DUPq8wb_register:
3376 case ARM::VLD1DUPq16wb_register:
3377 case ARM::VLD1DUPq32wb_register:
3378 case ARM::VLD2DUPd8:
3379 case ARM::VLD2DUPd16:
3380 case ARM::VLD2DUPd32:
3381 case ARM::VLD2DUPd8wb_fixed:
3382 case ARM::VLD2DUPd16wb_fixed:
3383 case ARM::VLD2DUPd32wb_fixed:
3384 case ARM::VLD2DUPd8wb_register:
3385 case ARM::VLD2DUPd16wb_register:
3386 case ARM::VLD2DUPd32wb_register:
3387 case ARM::VLD4DUPd8:
3388 case ARM::VLD4DUPd16:
3389 case ARM::VLD4DUPd32:
3390 case ARM::VLD4DUPd8_UPD:
3391 case ARM::VLD4DUPd16_UPD:
3392 case ARM::VLD4DUPd32_UPD:
3394 case ARM::VLD1LNd16:
3395 case ARM::VLD1LNd32:
3396 case ARM::VLD1LNd8_UPD:
3397 case ARM::VLD1LNd16_UPD:
3398 case ARM::VLD1LNd32_UPD:
3400 case ARM::VLD2LNd16:
3401 case ARM::VLD2LNd32:
3402 case ARM::VLD2LNq16:
3403 case ARM::VLD2LNq32:
3404 case ARM::VLD2LNd8_UPD:
3405 case ARM::VLD2LNd16_UPD:
3406 case ARM::VLD2LNd32_UPD:
3407 case ARM::VLD2LNq16_UPD:
3408 case ARM::VLD2LNq32_UPD:
3410 case ARM::VLD4LNd16:
3411 case ARM::VLD4LNd32:
3412 case ARM::VLD4LNq16:
3413 case ARM::VLD4LNq32:
3414 case ARM::VLD4LNd8_UPD:
3415 case ARM::VLD4LNd16_UPD:
3416 case ARM::VLD4LNd32_UPD:
3417 case ARM::VLD4LNq16_UPD:
3418 case ARM::VLD4LNq32_UPD:
3434 unsigned UseIdx)
const {
3436 if (!ItinData || ItinData->
isEmpty())
3444 unsigned DefAdj = 0;
3454 unsigned UseAdj = 0;
3458 Reg, NewUseIdx, UseAdj);
3467 if (Reg == ARM::CPSR) {
3470 return Subtarget.
isLikeA9() ? 1 : 20;
3478 unsigned Latency = getInstrLatency(ItinData, DefMI);
3484 if (Latency > 0 && Subtarget.
isThumb2()) {
3487 hasAttribute(AttributeSet::FunctionIndex,
3504 *UseMCID, UseIdx, UseAlign);
3510 int Adj = DefAdj + UseAdj;
3514 if (Adj >= 0 || (
int)Latency > -Adj) {
3515 return Latency + Adj;
3523 SDNode *DefNode,
unsigned DefIdx,
3524 SDNode *UseNode,
unsigned UseIdx)
const {
3530 if (isZeroCost(DefMCID.
Opcode))
3533 if (!ItinData || ItinData->
isEmpty())
3534 return DefMCID.
mayLoad() ? 3 : 1;
3539 return Latency <= 2 ? 1 : Latency - 1;
3541 return Latency <= 3 ? 1 : Latency - 2;
3552 UseMCID, UseIdx, UseAlign);
3563 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3573 case ARM::t2LDRSHs: {
3576 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3577 if (ShAmt == 0 || ShAmt == 2)
3582 }
else if (DefIdx == 0 && Latency > 2 && Subtarget.
isSwift()) {
3590 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3593 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3603 case ARM::t2LDRSHs: {
3611 if (DefAlign < 8 && Subtarget.
isLikeA9())
3618 case ARM::VLD1q8wb_register:
3619 case ARM::VLD1q16wb_register:
3620 case ARM::VLD1q32wb_register:
3621 case ARM::VLD1q64wb_register:
3622 case ARM::VLD1q8wb_fixed:
3623 case ARM::VLD1q16wb_fixed:
3624 case ARM::VLD1q32wb_fixed:
3625 case ARM::VLD1q64wb_fixed:
3629 case ARM::VLD2q8Pseudo:
3630 case ARM::VLD2q16Pseudo:
3631 case ARM::VLD2q32Pseudo:
3632 case ARM::VLD2d8wb_fixed:
3633 case ARM::VLD2d16wb_fixed:
3634 case ARM::VLD2d32wb_fixed:
3635 case ARM::VLD2q8PseudoWB_fixed:
3636 case ARM::VLD2q16PseudoWB_fixed:
3637 case ARM::VLD2q32PseudoWB_fixed:
3638 case ARM::VLD2d8wb_register:
3639 case ARM::VLD2d16wb_register:
3640 case ARM::VLD2d32wb_register:
3641 case ARM::VLD2q8PseudoWB_register:
3642 case ARM::VLD2q16PseudoWB_register:
3643 case ARM::VLD2q32PseudoWB_register:
3644 case ARM::VLD3d8Pseudo:
3645 case ARM::VLD3d16Pseudo:
3646 case ARM::VLD3d32Pseudo:
3647 case ARM::VLD1d64TPseudo:
3648 case ARM::VLD3d8Pseudo_UPD:
3649 case ARM::VLD3d16Pseudo_UPD:
3650 case ARM::VLD3d32Pseudo_UPD:
3651 case ARM::VLD3q8Pseudo_UPD:
3652 case ARM::VLD3q16Pseudo_UPD:
3653 case ARM::VLD3q32Pseudo_UPD:
3654 case ARM::VLD3q8oddPseudo:
3655 case ARM::VLD3q16oddPseudo:
3656 case ARM::VLD3q32oddPseudo:
3657 case ARM::VLD3q8oddPseudo_UPD:
3658 case ARM::VLD3q16oddPseudo_UPD:
3659 case ARM::VLD3q32oddPseudo_UPD:
3660 case ARM::VLD4d8Pseudo:
3661 case ARM::VLD4d16Pseudo:
3662 case ARM::VLD4d32Pseudo:
3663 case ARM::VLD1d64QPseudo:
3664 case ARM::VLD4d8Pseudo_UPD:
3665 case ARM::VLD4d16Pseudo_UPD:
3666 case ARM::VLD4d32Pseudo_UPD:
3667 case ARM::VLD4q8Pseudo_UPD:
3668 case ARM::VLD4q16Pseudo_UPD:
3669 case ARM::VLD4q32Pseudo_UPD:
3670 case ARM::VLD4q8oddPseudo:
3671 case ARM::VLD4q16oddPseudo:
3672 case ARM::VLD4q32oddPseudo:
3673 case ARM::VLD4q8oddPseudo_UPD:
3674 case ARM::VLD4q16oddPseudo_UPD:
3675 case ARM::VLD4q32oddPseudo_UPD:
3676 case ARM::VLD1DUPq8:
3677 case ARM::VLD1DUPq16:
3678 case ARM::VLD1DUPq32:
3679 case ARM::VLD1DUPq8wb_fixed:
3680 case ARM::VLD1DUPq16wb_fixed:
3681 case ARM::VLD1DUPq32wb_fixed:
3682 case ARM::VLD1DUPq8wb_register:
3683 case ARM::VLD1DUPq16wb_register:
3684 case ARM::VLD1DUPq32wb_register:
3685 case ARM::VLD2DUPd8:
3686 case ARM::VLD2DUPd16:
3687 case ARM::VLD2DUPd32:
3688 case ARM::VLD2DUPd8wb_fixed:
3689 case ARM::VLD2DUPd16wb_fixed:
3690 case ARM::VLD2DUPd32wb_fixed:
3691 case ARM::VLD2DUPd8wb_register:
3692 case ARM::VLD2DUPd16wb_register:
3693 case ARM::VLD2DUPd32wb_register:
3694 case ARM::VLD4DUPd8Pseudo:
3695 case ARM::VLD4DUPd16Pseudo:
3696 case ARM::VLD4DUPd32Pseudo:
3697 case ARM::VLD4DUPd8Pseudo_UPD:
3698 case ARM::VLD4DUPd16Pseudo_UPD:
3699 case ARM::VLD4DUPd32Pseudo_UPD:
3700 case ARM::VLD1LNq8Pseudo:
3701 case ARM::VLD1LNq16Pseudo:
3702 case ARM::VLD1LNq32Pseudo:
3703 case ARM::VLD1LNq8Pseudo_UPD:
3704 case ARM::VLD1LNq16Pseudo_UPD:
3705 case ARM::VLD1LNq32Pseudo_UPD:
3706 case ARM::VLD2LNd8Pseudo:
3707 case ARM::VLD2LNd16Pseudo:
3708 case ARM::VLD2LNd32Pseudo:
3709 case ARM::VLD2LNq16Pseudo:
3710 case ARM::VLD2LNq32Pseudo:
3711 case ARM::VLD2LNd8Pseudo_UPD:
3712 case ARM::VLD2LNd16Pseudo_UPD:
3713 case ARM::VLD2LNd32Pseudo_UPD:
3714 case ARM::VLD2LNq16Pseudo_UPD:
3715 case ARM::VLD2LNq32Pseudo_UPD:
3716 case ARM::VLD4LNd8Pseudo:
3717 case ARM::VLD4LNd16Pseudo:
3718 case ARM::VLD4LNd32Pseudo:
3719 case ARM::VLD4LNq16Pseudo:
3720 case ARM::VLD4LNq32Pseudo:
3721 case ARM::VLD4LNd8Pseudo_UPD:
3722 case ARM::VLD4LNd16Pseudo_UPD:
3723 case ARM::VLD4LNd32Pseudo_UPD:
3724 case ARM::VLD4LNq16Pseudo_UPD:
3725 case ARM::VLD4LNq32Pseudo_UPD:
3735 unsigned ARMBaseInstrInfo::getPredicationCost(
const MachineInstr *MI)
const {
3755 unsigned *PredCost)
const {
3763 unsigned Latency = 0;
3766 while (++I != E && I->isInsideBundle()) {
3767 if (I->getOpcode() != ARM::t2IT)
3768 Latency += getInstrLatency(ItinData, I, PredCost);
3797 if (Adj >= 0 || (
int)Latency > -Adj) {
3798 return Latency + Adj;
3808 if (!ItinData || ItinData->
isEmpty())
3821 bool ARMBaseInstrInfo::
3834 int Latency = computeOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx);
3836 Latency = getInstrLatency(ItinData, DefMI);
3843 bool ARMBaseInstrInfo::
3846 if (!ItinData || ItinData->
isEmpty())
3853 return (DefCycle != -1 && DefCycle <= 2);
3858 bool ARMBaseInstrInfo::verifyInstruction(
const MachineInstr *MI,
3861 ErrInfo =
"Pseudo flag setting opcodes only exist in Selection DAG";
3869 unsigned &AddSubOpc,
3870 bool &NegAcc,
bool &HasLane)
const {
3872 if (I == MLxEntryMap.
end())
3902 std::pair<uint16_t, uint16_t>
3921 return std::make_pair(
ExeNEON, 0);
3926 return std::make_pair(
ExeNEON, 0);
3929 return std::make_pair(
ExeVFP, 0);
3935 unsigned SReg,
unsigned &Lane) {
3939 if (DReg != ARM::NoRegister)
3945 assert(DReg &&
"S-register with no D super-register?");
3966 unsigned DReg,
unsigned Lane,
3967 unsigned &ImplicitSReg) {
3977 (Lane & 1) ? ARM::ssub_0 : ARM::ssub_1);
3994 unsigned DstReg, SrcReg, DReg;
4007 assert(!
isPredicated(MI) &&
"Cannot predicate a VORRd");
4025 assert(!
isPredicated(MI) &&
"Cannot predicate a VGETLN");
4039 MI->
setDesc(
get(ARM::VGETLNi32));
4051 assert(!
isPredicated(MI) &&
"Cannot predicate a VSETLN");
4059 unsigned ImplicitSReg;
4068 MI->
setDesc(
get(ARM::VSETLNi32));
4078 if (ImplicitSReg != 0)
4090 unsigned DstLane = 0, SrcLane = 0, DDst, DSrc;
4094 unsigned ImplicitSReg;
4104 MI->
setDesc(
get(ARM::VDUPLN32d));
4114 if (ImplicitSReg != 0)
4133 get(ARM::VEXTd32), DDst);
4138 unsigned CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst;
4142 CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst;
4149 if (SrcLane == DstLane)
4152 MI->
setDesc(
get(ARM::VEXTd32));
4157 CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst;
4158 CurUndef = CurReg == DSrc && !MI->
readsRegister(CurReg, TRI);
4161 CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst;
4162 CurUndef = CurReg == DSrc && !MI->
readsRegister(CurReg, TRI);
4168 if (SrcLane != DstLane)
4174 if (ImplicitSReg != 0)
4206 assert(TRI &&
"Need TRI instance");
4220 case ARM::VMOVv4i16:
4221 case ARM::VMOVv2i32:
4222 case ARM::VMOVv2f32:
4223 case ARM::VMOVv1i64:
4228 case ARM::VLD1LNd32:
4245 }
else if (ARM::SPRRegClass.contains(Reg)) {
4264 assert(MI && OpNum < MI->getDesc().getNumDefs() &&
"OpNum is not a def");
4265 assert(TRI &&
"Need TRI instance");
4270 "Can't break virtual register dependencies.");
4271 unsigned DReg =
Reg;
4274 if (ARM::SPRRegClass.contains(Reg)) {
4275 DReg = ARM::D0 + (Reg - ARM::S0) / 2;
4279 assert(ARM::DPRRegClass.contains(DReg) &&
"Can only break D-reg deps");
4280 assert(MI->definesRegister(DReg, TRI) &&
"MI doesn't clobber full D-reg");
4291 get(ARM::FCONSTD), DReg).
addImm(96));
4296 return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0;
4306 ((ShImm == 1 || ShImm == 2) &&
virtual MachineInstr * duplicate(MachineInstr *Orig, MachineFunction &MF) const
MachineConstantPoolValue * MachineCPVal
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
void push_back(const T &Elt)
The memory access reads data.
const MachineFunction * getParent() const
virtual bool SubsumesPredicate(const SmallVectorImpl< MachineOperand > &Pred1, const SmallVectorImpl< MachineOperand > &Pred2) const
The machine constant pool.
The memory access writes data.
const GlobalValue * getGlobal() const
static cl::opt< unsigned > SwiftPartialUpdateClearance("swift-partial-update-clearance", cl::Hidden, cl::init(12), cl::desc("Clearance before partial register updates"))
LLVMContext & getContext() const
instr_iterator instr_end()
static unsigned char getAM3Offset(unsigned AM3Opc)
bool isBranch(QueryType Type=AnyInBundle) const
unsigned getMispredictionPenalty() const
bool removeKill(MachineInstr *MI)
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
static const MachineInstr * getBundledUseMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &UseIdx, unsigned &Dist)
int getNumMicroOps(unsigned ItinClassIndx) const
virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, int &FrameIndex) const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions. Register definitions always occur...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
static unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g. ARM instructions which can set condition cod...
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, const MachineInstr *MI) const
bool mayStore() const
Return true if this instruction could possibly modify memory. Instructions with this flag set are not...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
bool mayStore(QueryType Type=AnyInBundle) const
virtual bool isSchedulingBoundary(const MachineInstr *MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetMachine *TM, const ScheduleDAG *DAG) const
static bool isVirtualRegister(unsigned Reg)
virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, int64_t Offset2, unsigned NumLoads) const
static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg, int CmpMask, bool CommonUse)
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
bool isPredicable(QueryType Type=AllInBundle) const
bool readsVirtualRegister(unsigned Reg) const
virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
uint32_t getNumerator() const
static unsigned getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI, unsigned SReg, unsigned &Lane)
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, unsigned Reg, MachineInstr *MI, unsigned Neighborhood=10)
virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, int &FrameIndex) const
const MCInstrDesc & getDesc() const
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const
const char * getSymbolName() const
bool isThumbFunction() const
const SDValue & getOperand(unsigned Num) const
void setIsDead(bool Val=true)
const Function * getFunction() const
bool isThumb1Only() const
unsigned createPICLabelUId()
virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig, const TargetRegisterInfo &TRI) const
virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, int CmpValue, const MachineRegisterInfo *MRI) const
bool isTerminator(QueryType Type=AnyInBundle) const
static bool getImplicitSPRUseForDPRUse(const TargetRegisterInfo *TRI, MachineInstr *MI, unsigned DReg, unsigned Lane, unsigned &ImplicitSReg)
static unsigned getSOImmValRotate(unsigned Imm)
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
static unsigned rotr32(unsigned Val, unsigned Amt)
virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
static use_iterator use_end()
mmo_iterator memoperands_begin() const
const HexagonInstrInfo * TII
const TargetRegisterInfo * getTargetRegisterInfo() const
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
const MCAsmInfo * getMCAsmInfo() const
virtual MachineInstr * optimizeSelect(MachineInstr *MI, bool) const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
bool isCall() const
Return true if the instruction is a call.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setImplicit(bool Val=true)
bool mayLoad(QueryType Type=AnyInBundle) const
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
const TargetRegisterClass * getRegClass(unsigned Reg) const
unsigned getPartialRegUpdateClearance(const MachineInstr *, unsigned, const TargetRegisterInfo *) const
std::vector< MachineBasicBlock * >::iterator succ_iterator
bool memoperands_empty() const
bool tryFoldSPUpdateIntoPushPop(MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Abstract Stack Frame Information.
bool isPredicated(const MachineInstr *MI) const
virtual const InstrItineraryData * getInstrItineraryData() const
const MachineInstrBuilder & addImm(int64_t Val) const
static unsigned getT2SOImmTwoPartFirst(unsigned Imm)
unsigned getNumOperands() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isFpMLxInstruction(unsigned Opcode) const
void RemoveOperand(unsigned i)
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
size_t array_lengthof(T(&)[N])
Find the length of an array.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
virtual MachineInstr * commuteInstruction(MachineInstr *MI, bool NewMI=false) const
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
virtual bool produceSameValue(const MachineInstr *MI0, const MachineInstr *MI1, const MachineRegisterInfo *MRI) const
const MachineJumpTableInfo * getJumpTableInfo() const
static unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData, const MachineInstr *MI)
An entry in a MachineConstantPool.
static const ARM_MLxEntry ARM_MLxTable[]
ARM_MLxEntry - Record information about MLA / MLS instructions.
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const
unsigned getUndefRegState(bool B)
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
unsigned getKillRegState(bool B)
bool isMachineConstantPoolEntry() const
void ChangeToImmediate(int64_t ImmVal)
const MachineBasicBlock * getParent() const
static bool isCondBranchOpcode(int Opc)
const Constant * ConstVal
bool isDebugValue() const
bool isImplicitDef() const
mmo_iterator memoperands_end() const
bool isInsertSubreg() const
bundle_iterator< MachineInstr, instr_iterator > iterator
virtual MachineInstr * convertToThreeAddress(MachineFunction::iterator &MFI, MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const
virtual unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
std::pair< uint16_t, uint16_t > getExecutionDomain(const MachineInstr *MI) const
VFP/NEON execution domains.
initializer< Ty > init(const Ty &Val)
MachineInstr * duplicate(MachineInstr *Orig, MachineFunction &MF) const
bool regsOverlap(unsigned regA, unsigned regB) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
static unsigned char getAM5Offset(unsigned AM5Opc)
static unsigned getSOImmTwoPartSecond(unsigned V)
MachineInstr * commuteInstruction(MachineInstr *, bool=false) const
commuteInstruction - Handle commutable instructions.
virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, int64_t &Offset2) const
virtual bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, unsigned &SrcReg2, int &CmpMask, int &CmpValue) const
const MachineOperand & getOperand(unsigned i) const
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
static cl::opt< bool > WidenVMOVS("widen-vmovs", cl::Hidden, cl::init(true), cl::desc("Widen ARM vmovs to vmovd when possible"))
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
static bool isJumpTableBranchOpcode(int Opc)
unsigned getStageLatency(unsigned ItinClassIndx) const
virtual bool hasSameValue(ARMConstantPoolValue *ACPV)
static unsigned getT2SOImmTwoPartSecond(unsigned Imm)
Register is known to be dead.
ItTy next(ItTy it, Dist n)
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const
void setImm(int64_t immVal)
bool hasOneMemOperand() const
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
int64_t getOffset() const
static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg, unsigned SrcReg2, int ImmValue, MachineInstr *OI)
MachineConstantPool * getConstantPool()
LivenessQueryResult
Possible outcome of a register liveness query to computeRegisterLiveness()
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
Register is known to be live.
succ_iterator succ_begin()
union llvm::MachineConstantPoolEntry::@29 Val
The constant itself.
unsigned getSubReg() const
VarInfo & getVarInfo(unsigned RegIdx)
getVarInfo - Get (possibly creating) a VarInfo object for the given vreg.
static const MachineInstr * getBundledDefMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &DefIdx, unsigned &Dist)
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
void setIsKill(bool Val=true)
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
unsigned getOpcode() const
Return the opcode number for this descriptor.
std::vector< MachineInstr * > Kills
static AddrOpc getAM2Op(unsigned AM2Opc)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static const MachineInstrBuilder & AddDefaultCC(const MachineInstrBuilder &MIB)
static bool isIndirectBranchOpcode(int Opc)
virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const
virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, const BranchProbability &Probability) const
static bool isUncondBranchOpcode(int Opc)
virtual unsigned getUnindexedOpcode(unsigned Opc) const =0
void setDesc(const MCInstrDesc &tid)
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
bool isIdenticalTo(const MachineInstr *Other, MICheckType Check=CheckDefs) const
virtual bool PredicateInstruction(MachineInstr *MI, const SmallVectorImpl< MachineOperand > &Pred) const
static unsigned getAM2Offset(unsigned AM2Opc)
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI)
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
#define LLVM_ATTRIBUTE_NOINLINE
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
bool isSwiftFastImmShift(const MachineInstr *MI) const
bool mayLoad() const
Return true if this instruction could possibly read memory. Instructions with this flag set are not n...
MachineFrameInfo * getFrameInfo()
int findRegisterUseOperandIdx(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=NULL) const
static bool isPushOpcode(int Opc)
static bool isSOImmTwoPartVal(unsigned V)
const MachineInstrBuilder & addFrameIndex(int Idx) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
AttributeSet getAttributes() const
Return the attribute list for this Function.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
virtual bool analyzeSelect(const MachineInstr *MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const
virtual bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
int getMatchingCondBranchOpcode(int Opc)
static int adjustDefLatency(const ARMSubtarget &Subtarget, const MachineInstr *DefMI, const MCInstrDesc *DefMCID, unsigned DefAlign)
AddrMode
ARM Addressing Modes.
static AddrOpc getAM3Op(unsigned AM3Opc)
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA, bool &SawStore) const
int findFirstPredOperandIdx() const
MachineInstr * getUniqueVRegDef(unsigned Reg) const
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))
int getOperandLatency(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetMachine *TM, const ScheduleDAG *DAG) const
static int getSOImmVal(unsigned Arg)
ARMBaseInstrInfo(const ARMSubtarget &STI)
bool count(const T &V) const
count - Return true if the element is in the set.
bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI=0) const
Return true if this instruction implicitly defines the specified physical register.
static bool isPopOpcode(int Opc)
bool isSuperRegister(unsigned RegA, unsigned RegB) const
Returns true if RegB is a super-register of RegA.
static MachineInstr * canFoldIntoMOVCC(unsigned Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
bundle_iterator< const MachineInstr, const_instr_iterator > const_iterator
static bool isPhysicalRegister(unsigned Reg)
static CondCodes getOppositeCondition(CondCodes CC)
static const AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[]
unsigned getSchedClass() const
Return the scheduling class for this instruction. The scheduling class is an index into the InstrItin...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
uint32_t getDenominator() const
MachineRegisterInfo & getRegInfo()
use_iterator use_begin(unsigned RegNo) const
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
unsigned getNumLDMAddresses(const MachineInstr *MI) const
Get the number of addresses by LDM or VLDM or zero for unknown.
void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI, bool AddIfNotFound=false)
bool hasOneNonDBGUse(unsigned RegNo) const
bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
void setReg(unsigned Reg)
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool isCall(QueryType Type=AnyInBundle) const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=NULL) const
const TargetMachine & getTarget() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
void setExecutionDomain(MachineInstr *MI, unsigned Domain) const
static AddrOpc getAM5Op(unsigned AM5Opc)
virtual bool DefinesPredicate(MachineInstr *MI, std::vector< MachineOperand > &Pred) const
MachineInstr * getVRegDef(unsigned Reg) const
void breakPartialRegDependency(MachineBasicBlock::iterator, unsigned, const TargetRegisterInfo *TRI) const
unsigned getReg() const
getReg - Returns the register number.
static LLVM_ATTRIBUTE_NOINLINE unsigned getNumJTEntries(const std::vector< MachineJumpTableEntry > &JT, unsigned JTI)
FIXME: Works around a gcc miscompilation with -fstrict-aliasing.
static ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
virtual const ARMBaseRegisterInfo & getRegisterInfo() const =0
static unsigned getSORegOffset(unsigned Op)
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
virtual bool isPredicable(MachineInstr *MI) const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
void addRegisterDefined(unsigned Reg, const TargetRegisterInfo *RegInfo=0)
ItTy prior(ItTy it, Dist n)
const ARMSubtarget & getSubtarget() const
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
const std::vector< MachineConstantPoolEntry > & getConstants() const
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
bool isV8EligibleForIT(InstrType *Instr, int BLXOperandIndex=0)
const MCRegisterInfo & MRI
bool hasOptionalDef(QueryType Type=IgnoreBundle) const
bool isIdenticalTo(const MachineOperand &Other) const
bool isRegSequence() const
bool isThumb2Function() const
static bool isT2SOImmTwoPartVal(unsigned Imm)
static unsigned getSOImmTwoPartFirst(unsigned V)
iterator find(const KeyT &Val)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
virtual int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *UseMI, unsigned UseIdx) const
int64_t getObjectSize(int ObjectIdx) const
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
DebugLoc getDebugLoc() const
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, unsigned Reg, MachineRegisterInfo *MRI) const
void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI, bool AddIfNotFound=false)
static cl::opt< bool > EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, cl::desc("Enable ARM 2-addr to 3-addr conv"))
bool isMachineOpcode() const
static ShiftOpc getSORegShOp(unsigned Op)
unsigned getMachineOpcode() const
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Function must be optimized for size first.