45 #define DEBUG_TYPE "arm-instrinfo"
47 #define GET_INSTRINFO_CTOR_DTOR
48 #include "ARMGenInstrInfo.inc"
52 cl::desc(
"Enable ARM 2-addr to 3-addr conv"));
56 cl::desc(
"Widen ARM vmovs to vmovd when possible"));
61 cl::desc(
"Clearance before partial register updates"));
75 { ARM::VMLAS, ARM::VMULS, ARM::VADDS,
false,
false },
76 { ARM::VMLSS, ARM::VMULS, ARM::VSUBS,
false,
false },
77 { ARM::VMLAD, ARM::VMULD, ARM::VADDD,
false,
false },
78 { ARM::VMLSD, ARM::VMULD, ARM::VSUBD,
false,
false },
79 { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS,
true,
false },
80 { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS,
true,
false },
81 { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD,
true,
false },
82 { ARM::VNMLSD, ARM::VMULD, ARM::VSUBD,
true,
false },
85 { ARM::VMLAfd, ARM::VMULfd, ARM::VADDfd,
false,
false },
86 { ARM::VMLSfd, ARM::VMULfd, ARM::VSUBfd,
false,
false },
87 { ARM::VMLAfq, ARM::VMULfq, ARM::VADDfq,
false,
false },
88 { ARM::VMLSfq, ARM::VMULfq, ARM::VSUBfq,
false,
false },
89 { ARM::VMLAslfd, ARM::VMULslfd, ARM::VADDfd,
false,
true },
90 { ARM::VMLSslfd, ARM::VMULslfd, ARM::VSUBfd,
false,
true },
91 { ARM::VMLAslfq, ARM::VMULslfq, ARM::VADDfq,
false,
true },
92 { ARM::VMLSslfq, ARM::VMULslfq, ARM::VSUBfq,
false,
true },
100 assert(
false &&
"Duplicated entries?");
111 if (usePreRAHazardRecognizer()) {
113 static_cast<const ARMSubtarget *
>(STI)->getInstrItineraryData();
141 default:
return nullptr;
164 unsigned WBReg = WB.
getReg();
165 unsigned BaseReg = Base.
getReg();
166 unsigned OffReg = Offset.
getReg();
180 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
183 }
else if (Amt != 0) {
187 get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
192 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
203 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
208 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
215 std::vector<MachineInstr*> NewMIs;
225 NewMIs.push_back(MemMI);
226 NewMIs.push_back(UpdateMI);
238 NewMIs.push_back(UpdateMI);
239 NewMIs.push_back(MemMI);
251 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
256 for (
unsigned j = 0; j < 2; ++j) {
263 VI.
Kills.push_back(NewMI);
271 MFI->insert(MBBI, NewMIs[1]);
272 MFI->insert(MBBI, NewMIs[0]);
281 bool AllowModify)
const {
286 if (I == MBB.
begin())
292 while (
isPredicated(I) || I->isTerminator() || I->isDebugValue()) {
297 bool CantAnalyze =
false;
300 while (I->isDebugValue() || !I->isTerminator()) {
301 if (I == MBB.
begin())
312 TBB = I->getOperand(0).getMBB();
318 assert(!FBB &&
"FBB should have been null.");
320 TBB = I->getOperand(0).getMBB();
323 }
else if (I->isReturn()) {
346 while (DI != MBB.
end()) {
357 if (I == MBB.
begin())
379 I->eraseFromParent();
383 if (I == MBB.
begin())
return 1;
389 I->eraseFromParent();
406 assert(TBB &&
"InsertBranch must not be told to insert a fallthrough");
407 assert((Cond.
size() == 2 || Cond.
size() == 0) &&
408 "ARM branch conditions have two components!");
445 while (++I != E && I->isInsideBundle()) {
446 int PIdx = I->findFirstPredOperandIdx();
447 if (PIdx != -1 && I->getOperand(PIdx).getImm() !=
ARMCC::AL)
463 .addImm(Pred[0].getImm())
464 .addReg(Pred[1].
getReg());
471 PMO.
setImm(Pred[0].getImm());
480 if (Pred1.
size() > 2 || Pred2.
size() > 2)
505 std::vector<MachineOperand> &Pred)
const {
520 for (
const auto &MO : MI->
operands())
521 if (MO.isReg() && MO.getReg() == ARM::CPSR && MO.isDef())
528 default:
return true;
581 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
585 if (MO.
getReg() != ARM::CPSR)
615 return getInstBundleLength(MI);
616 case ARM::MOVi16_ga_pcrel:
617 case ARM::MOVTi16_ga_pcrel:
618 case ARM::t2MOVi16_ga_pcrel:
619 case ARM::t2MOVTi16_ga_pcrel:
622 case ARM::t2MOVi32imm:
624 case ARM::CONSTPOOL_ENTRY:
625 case ARM::JUMPTABLE_INSTS:
626 case ARM::JUMPTABLE_ADDRS:
627 case ARM::JUMPTABLE_TBB:
628 case ARM::JUMPTABLE_TBH:
632 case ARM::Int_eh_sjlj_longjmp:
634 case ARM::tInt_eh_sjlj_longjmp:
636 case ARM::Int_eh_sjlj_setjmp:
637 case ARM::Int_eh_sjlj_setjmp_nofp:
639 case ARM::tInt_eh_sjlj_setjmp:
640 case ARM::t2Int_eh_sjlj_setjmp:
641 case ARM::t2Int_eh_sjlj_setjmp_nofp:
648 unsigned ARMBaseInstrInfo::getInstBundleLength(
const MachineInstr *
MI)
const {
652 while (++I != E && I->isInsideBundle()) {
653 assert(!I->isBundle() &&
"No nested bundle!");
661 unsigned DestReg,
bool KillSrc,
663 unsigned Opc = Subtarget.
isThumb()
664 ? (Subtarget.
isMClass() ? ARM::t2MRS_M : ARM::t2MRS_AR)
668 BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), DestReg);
682 unsigned SrcReg,
bool KillSrc,
684 unsigned Opc = Subtarget.
isThumb()
685 ? (Subtarget.
isMClass() ? ARM::t2MSR_M : ARM::t2MSR_AR)
704 unsigned DestReg,
unsigned SrcReg,
705 bool KillSrc)
const {
706 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
707 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
709 if (GPRDest && GPRSrc) {
715 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
716 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
719 if (SPRDest && SPRSrc)
721 else if (GPRDest && SPRSrc)
723 else if (SPRDest && GPRSrc)
727 else if (ARM::QPRRegClass.
contains(DestReg, SrcReg))
733 if (Opc == ARM::VORRq)
740 unsigned BeginIdx = 0;
741 unsigned SubRegs = 0;
745 if (ARM::QQPRRegClass.
contains(DestReg, SrcReg)) {
747 BeginIdx = ARM::qsub_0;
749 }
else if (ARM::QQQQPRRegClass.
contains(DestReg, SrcReg)) {
751 BeginIdx = ARM::qsub_0;
754 }
else if (ARM::DPairRegClass.
contains(DestReg, SrcReg)) {
756 BeginIdx = ARM::dsub_0;
758 }
else if (ARM::DTripleRegClass.
contains(DestReg, SrcReg)) {
760 BeginIdx = ARM::dsub_0;
762 }
else if (ARM::DQuadRegClass.
contains(DestReg, SrcReg)) {
764 BeginIdx = ARM::dsub_0;
766 }
else if (ARM::GPRPairRegClass.
contains(DestReg, SrcReg)) {
767 Opc = Subtarget.
isThumb2() ? ARM::tMOVr : ARM::MOVr;
768 BeginIdx = ARM::gsub_0;
770 }
else if (ARM::DPairSpcRegClass.
contains(DestReg, SrcReg)) {
772 BeginIdx = ARM::dsub_0;
775 }
else if (ARM::DTripleSpcRegClass.
contains(DestReg, SrcReg)) {
777 BeginIdx = ARM::dsub_0;
780 }
else if (ARM::DQuadSpcRegClass.
contains(DestReg, SrcReg)) {
782 BeginIdx = ARM::dsub_0;
787 BeginIdx = ARM::ssub_0;
789 }
else if (SrcReg == ARM::CPSR) {
792 }
else if (DestReg == ARM::CPSR) {
793 copyToCPSR(MBB, I, SrcReg, KillSrc, Subtarget);
797 assert(Opc &&
"Impossible reg-to-reg copy");
804 BeginIdx = BeginIdx + ((SubRegs - 1) * Spacing);
810 for (
unsigned i = 0; i != SubRegs; ++i) {
811 unsigned Dst = TRI->
getSubReg(DestReg, BeginIdx + i * Spacing);
812 unsigned Src = TRI->
getSubReg(SrcReg, BeginIdx + i * Spacing);
813 assert(Dst && Src &&
"Bad sub-register");
815 assert(!DstRegs.
count(Src) &&
"destructive vector copy");
818 Mov =
BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), Dst).
addReg(Src);
820 if (Opc == ARM::VORRq)
824 if (Opc == ARM::MOVr)
835 unsigned SubIdx,
unsigned State,
838 return MIB.
addReg(Reg, State);
842 return MIB.
addReg(Reg, State, SubIdx);
847 unsigned SrcReg,
bool isKill,
int FI,
851 if (I != MBB.
end()) DL = I->getDebugLoc();
864 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
867 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
868 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
871 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
876 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
879 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
880 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
884 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
893 .addFrameIndex(FI).addMemOperand(MMO));
895 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
901 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
905 .addFrameIndex(FI).addImm(16)
907 .addMemOperand(MMO));
912 .addMemOperand(MMO));
918 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
922 .addFrameIndex(FI).addImm(16)
924 .addMemOperand(MMO));
931 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
932 AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
938 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
943 .addFrameIndex(FI).addImm(16)
945 .addMemOperand(MMO));
952 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
953 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
954 AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
960 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
966 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
967 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
968 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
969 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
970 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
971 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
972 AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
1010 case ARM::VST1d64TPseudo:
1011 case ARM::VST1d64QPseudo:
1033 return MI->
mayStore() && hasStoreToStackSlot(MI, Dummy, FrameIndex);
1038 unsigned DestReg,
int FI,
1042 if (I != MBB.
end()) DL = I->getDebugLoc();
1055 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1057 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1059 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1061 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1066 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1068 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1069 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1073 MIB =
BuildMI(MBB, I, DL,
get(ARM::LDRD));
1083 .addFrameIndex(FI).addMemOperand(MMO));
1094 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
1097 .addFrameIndex(FI).addImm(16)
1098 .addMemOperand(MMO));
1102 .addMemOperand(MMO));
1108 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1111 .addFrameIndex(FI).addImm(16)
1112 .addMemOperand(MMO));
1117 .addMemOperand(MMO));
1128 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
1131 .addFrameIndex(FI).addImm(16)
1132 .addMemOperand(MMO));
1149 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1201 case ARM::VLD1d64TPseudo:
1202 case ARM::VLD1d64QPseudo:
1224 return MI->
mayLoad() && hasLoadFromStackSlot(MI, Dummy, FrameIndex);
1233 assert(
getSubtarget().getTargetTriple().isOSBinFormatMachO() &&
1234 "LOAD_STACK_GUARD currently supported only for MachO.");
1235 expandLoadStackGuard(MI, RM);
1236 MI->getParent()->erase(MI);
1250 unsigned DstRegS = MI->getOperand(0).getReg();
1251 unsigned SrcRegS = MI->getOperand(1).getReg();
1252 if (!ARM::SPRRegClass.
contains(DstRegS, SrcRegS))
1260 if (!DstRegD || !SrcRegD)
1266 if (!MI->definesRegister(DstRegD, TRI) || MI->readsRegister(DstRegD, TRI))
1270 if (MI->getOperand(0).isDead())
1280 if (ImpDefIdx != -1)
1281 MI->RemoveOperand(ImpDefIdx);
1284 MI->setDesc(
get(ARM::VMOVD));
1285 MI->getOperand(0).setReg(DstRegD);
1286 MI->getOperand(1).setReg(SrcRegD);
1293 MI->getOperand(1).setIsUndef();
1298 if (MI->getOperand(1).isKill()) {
1299 MI->getOperand(1).setIsKill(
false);
1300 MI->addRegisterKilled(SrcRegS, TRI,
true);
1303 DEBUG(
dbgs() <<
"replaced by: " << *MI);
1314 assert(MCPE.isMachineConstantPoolEntry() &&
1315 "Expecting a machine constantpool entry!");
1327 if (ACPV->isGlobalValue())
1329 Create(cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
1331 else if (ACPV->isExtSymbol())
1334 cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(), PCLabelId, 4);
1335 else if (ACPV->isBlockAddress())
1337 Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
1339 else if (ACPV->isLSDA())
1342 else if (ACPV->isMachineBasicBlock())
1345 cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
1355 unsigned DestReg,
unsigned SubIdx,
1366 case ARM::tLDRpci_pic:
1367 case ARM::t2LDRpci_pic: {
1384 case ARM::tLDRpci_pic:
1385 case ARM::t2LDRpci_pic: {
1400 if (Opcode == ARM::t2LDRpci ||
1401 Opcode == ARM::t2LDRpci_pic ||
1402 Opcode == ARM::tLDRpci ||
1403 Opcode == ARM::tLDRpci_pic ||
1404 Opcode == ARM::LDRLIT_ga_pcrel ||
1405 Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1406 Opcode == ARM::tLDRLIT_ga_pcrel ||
1407 Opcode == ARM::MOV_ga_pcrel ||
1408 Opcode == ARM::MOV_ga_pcrel_ldr ||
1409 Opcode == ARM::t2MOV_ga_pcrel) {
1420 if (Opcode == ARM::LDRLIT_ga_pcrel ||
1421 Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1422 Opcode == ARM::tLDRLIT_ga_pcrel ||
1423 Opcode == ARM::MOV_ga_pcrel ||
1424 Opcode == ARM::MOV_ga_pcrel_ldr ||
1425 Opcode == ARM::t2MOV_ga_pcrel)
1437 if (isARMCP0 && isARMCP1) {
1443 }
else if (!isARMCP0 && !isARMCP1) {
1447 }
else if (Opcode == ARM::PICLDR) {
1455 if (Addr0 != Addr1) {
1493 int64_t &Offset2)
const {
1514 case ARM::t2LDRSHi8:
1516 case ARM::t2LDRBi12:
1517 case ARM::t2LDRSHi12:
1534 case ARM::t2LDRSHi8:
1536 case ARM::t2LDRBi12:
1537 case ARM::t2LDRSHi12:
1551 if (isa<ConstantSDNode>(Load1->
getOperand(1)) &&
1553 Offset1 = cast<ConstantSDNode>(Load1->
getOperand(1))->getSExtValue();
1554 Offset2 = cast<ConstantSDNode>(Load2->
getOperand(1))->getSExtValue();
1573 int64_t Offset1, int64_t Offset2,
1574 unsigned NumLoads)
const {
1578 assert(Offset2 > Offset1);
1580 if ((Offset2 - Offset1) / 8 > 64)
1626 while (++I != MBB->
end() && I->isDebugValue())
1628 if (I != MBB->
end() && I->getOpcode() == ARM::t2IT)
1647 unsigned NumCycles,
unsigned ExtraPredCycles,
1659 if (!Pred->
empty()) {
1661 if (LastMI->
getOpcode() == ARM::t2Bcc) {
1663 if (CmpMI != Pred->
begin()) {
1665 if (CmpMI->getOpcode() == ARM::tCMPi8 ||
1666 CmpMI->getOpcode() == ARM::t2CMPri) {
1667 unsigned Reg = CmpMI->getOperand(0).getReg();
1668 unsigned PredReg = 0;
1670 if (P ==
ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
1680 unsigned UnpredCost = Probability.
getNumerator() * NumCycles;
1685 return (NumCycles + ExtraPredCycles) <= UnpredCost;
1690 unsigned TCycles,
unsigned TExtra,
1692 unsigned FCycles,
unsigned FExtra,
1694 if (!TCycles || !FCycles)
1698 unsigned TUnpredCost = Probability.
getNumerator() * TCycles;
1702 unsigned FUnpredCost = Comp * FCycles;
1705 unsigned UnpredCost = TUnpredCost + FUnpredCost;
1709 return (TCycles + FCycles + TExtra + FExtra) <= UnpredCost;
1741 if (Opc == ARM::t2B)
1752 case ARM::t2MOVCCr: {
1754 unsigned PredReg = 0;
1757 if (CC ==
ARMCC::AL || PredReg != ARM::CPSR)
1803 bool DontMoveAcrossStores =
true;
1811 unsigned &TrueOp,
unsigned &FalseOp,
1812 bool &Optimizable)
const {
1814 "Unknown select instruction");
1833 bool PreferFalse)
const {
1835 "Unknown select instruction");
1838 bool Invert = !DefMI;
1858 for (
unsigned i = 1, e = DefDesc.getNumOperands();
1859 i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
1883 SeenMIs.
erase(DefMI);
1909 {ARM::ADDSri, ARM::ADDri},
1910 {ARM::ADDSrr, ARM::ADDrr},
1911 {ARM::ADDSrsi, ARM::ADDrsi},
1912 {ARM::ADDSrsr, ARM::ADDrsr},
1914 {ARM::SUBSri, ARM::SUBri},
1915 {ARM::SUBSrr, ARM::SUBrr},
1916 {ARM::SUBSrsi, ARM::SUBrsi},
1917 {ARM::SUBSrsr, ARM::SUBrsr},
1919 {ARM::RSBSri, ARM::RSBri},
1920 {ARM::RSBSrsi, ARM::RSBrsi},
1921 {ARM::RSBSrsr, ARM::RSBrsr},
1923 {ARM::t2ADDSri, ARM::t2ADDri},
1924 {ARM::t2ADDSrr, ARM::t2ADDrr},
1925 {ARM::t2ADDSrs, ARM::t2ADDrs},
1927 {ARM::t2SUBSri, ARM::t2SUBri},
1928 {ARM::t2SUBSrr, ARM::t2SUBrr},
1929 {ARM::t2SUBSrs, ARM::t2SUBrs},
1931 {ARM::t2RSBSri, ARM::t2RSBri},
1932 {ARM::t2RSBSrs, ARM::t2RSBrs},
1944 unsigned DestReg,
unsigned BaseReg,
int NumBytes,
1947 if (NumBytes == 0 && DestReg != BaseReg) {
1948 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), DestReg)
1955 bool isSub = NumBytes < 0;
1956 if (isSub) NumBytes = -NumBytes;
1961 assert(ThisVal &&
"Didn't extract field correctly");
1964 NumBytes &= ~ThisVal;
1969 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
1970 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
1989 unsigned NumBytes) {
2000 if (!IsPush && !IsPop)
2003 bool IsVFPPushPop = MI->
getOpcode() == ARM::VSTMDDB_UPD ||
2005 bool IsT1PushPop = MI->
getOpcode() == ARM::tPUSH ||
2011 "trying to fold sp update into non-sp-updating push/pop");
2016 if (NumBytes % (IsVFPPushPop ? 8 : 4) != 0)
2021 int RegListIdx = IsT1PushPop ? 2 : 4;
2025 unsigned RD0Reg, RegsNeeded;
2028 RegsNeeded = NumBytes / 8;
2031 RegsNeeded = NumBytes / 4;
2045 for (
unsigned CurReg = FirstReg - 1; CurReg >= RD0Reg && RegsNeeded;
2052 false,
false,
true));
2091 for (
int i = RegList.
size() - 1; i >= 0; --i)
2098 unsigned FrameReg,
int &Offset,
2109 if (Opcode == ARM::ADDri) {
2113 MI.
setDesc(TII.get(ARM::MOVr));
2118 }
else if (Offset < 0) {
2121 MI.
setDesc(TII.get(ARM::SUBri));
2139 Offset &= ~ThisImmVal;
2143 "Bit extraction didn't work?");
2146 unsigned ImmIdx = 0;
2148 unsigned NumBits = 0;
2152 ImmIdx = FrameRegIdx + 1;
2158 ImmIdx = FrameRegIdx+2;
2166 ImmIdx = FrameRegIdx+2;
2178 ImmIdx = FrameRegIdx+1;
2190 Offset += InstrOffs * Scale;
2191 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
2201 int ImmedOffset = Offset / Scale;
2202 unsigned Mask = (1 << NumBits) - 1;
2203 if ((
unsigned)Offset <= Mask * Scale) {
2211 ImmedOffset = -ImmedOffset;
2213 ImmedOffset |= 1 << NumBits;
2221 ImmedOffset = ImmedOffset & Mask;
2224 ImmedOffset = -ImmedOffset;
2226 ImmedOffset |= 1 << NumBits;
2229 Offset &= ~(Mask*Scale);
2233 Offset = (isSub) ? -Offset : Offset;
2243 int &CmpMask,
int &CmpValue)
const {
2277 int CmpMask,
bool CommonUse) {
2316 unsigned SrcReg2,
int ImmValue,
2347 int CmpMask,
int CmpValue,
2351 if (!MI)
return false;
2354 if (CmpMask != ~0) {
2360 if (UI->getParent() != CmpInstr->
getParent())
continue;
2368 if (!MI)
return false;
2377 if (I == B)
return false;
2392 if (CmpInstr->
getOpcode() == ARM::CMPri ||
2403 for (; I != E; --
I) {
2468 case ARM::t2EORri: {
2477 bool isSafe =
false;
2480 while (!isSafe && ++I != E) {
2483 !isSafe && IO != EO; ++IO) {
2497 bool IsInstrVSel =
true;
2500 IsInstrVSel =
false;
2536 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
2571 if ((*SI)->isLiveIn(ARM::CPSR))
2578 assert(!
isPredicated(MI) &&
"Can't use flags from predicated instruction");
2584 for (
unsigned i = 0, e = OperandsToUpdate.
size(); i < e; i++)
2585 OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
2598 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm)
2627 unsigned NewUseOpc = 0;
2629 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
2630 bool Commute =
false;
2632 default:
return false;
2640 case ARM::t2EORrr: {
2648 NewUseOpc = ARM::SUBri;
2660 case ARM::ADDrr: NewUseOpc = ARM::ADDri;
break;
2661 case ARM::ORRrr: NewUseOpc = ARM::ORRri;
break;
2662 case ARM::EORrr: NewUseOpc = ARM::EORri;
break;
2666 case ARM::t2SUBrr: {
2670 NewUseOpc = ARM::t2SUBri;
2675 case ARM::t2EORrr: {
2682 case ARM::t2ADDrr: NewUseOpc = ARM::t2ADDri;
break;
2683 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri;
break;
2684 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri;
break;
2692 unsigned OpIdx = Commute ? 2 : 1;
2698 get(NewUseOpc), NewReg)
2701 UseMI->
setDesc(
get(NewUseOpc));
2715 assert(UOps >= 0 &&
"bad # UOps");
2728 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2744 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2754 case ARM::LDRSB_POST:
2755 case ARM::LDRSH_POST: {
2758 return (Rt == Rm) ? 4 : 3;
2761 case ARM::LDR_PRE_REG:
2762 case ARM::LDRB_PRE_REG: {
2772 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2778 case ARM::STR_PRE_REG:
2779 case ARM::STRB_PRE_REG: {
2785 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2792 case ARM::STRH_PRE: {
2803 case ARM::LDR_POST_REG:
2804 case ARM::LDRB_POST_REG:
2805 case ARM::LDRH_POST: {
2808 return (Rt == Rm) ? 3 : 2;
2811 case ARM::LDR_PRE_IMM:
2812 case ARM::LDRB_PRE_IMM:
2813 case ARM::LDR_POST_IMM:
2814 case ARM::LDRB_POST_IMM:
2815 case ARM::STRB_POST_IMM:
2816 case ARM::STRB_POST_REG:
2817 case ARM::STRB_PRE_IMM:
2818 case ARM::STRH_POST:
2819 case ARM::STR_POST_IMM:
2820 case ARM::STR_POST_REG:
2821 case ARM::STR_PRE_IMM:
2824 case ARM::LDRSB_PRE:
2825 case ARM::LDRSH_PRE: {
2837 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2849 return (Rt == Rn) ? 3 : 2;
2859 case ARM::LDRD_POST:
2860 case ARM::t2LDRD_POST:
2863 case ARM::STRD_POST:
2864 case ARM::t2STRD_POST:
2867 case ARM::LDRD_PRE: {
2873 return (Rt == Rn) ? 4 : 3;
2876 case ARM::t2LDRD_PRE: {
2879 return (Rt == Rn) ? 4 : 3;
2882 case ARM::STRD_PRE: {
2889 case ARM::t2STRD_PRE:
2892 case ARM::t2LDR_POST:
2893 case ARM::t2LDRB_POST:
2894 case ARM::t2LDRB_PRE:
2895 case ARM::t2LDRSBi12:
2896 case ARM::t2LDRSBi8:
2897 case ARM::t2LDRSBpci:
2899 case ARM::t2LDRH_POST:
2900 case ARM::t2LDRH_PRE:
2902 case ARM::t2LDRSB_POST:
2903 case ARM::t2LDRSB_PRE:
2904 case ARM::t2LDRSH_POST:
2905 case ARM::t2LDRSH_PRE:
2906 case ARM::t2LDRSHi12:
2907 case ARM::t2LDRSHi8:
2908 case ARM::t2LDRSHpci:
2912 case ARM::t2LDRDi8: {
2915 return (Rt == Rn) ? 3 : 2;
2918 case ARM::t2STRB_POST:
2919 case ARM::t2STRB_PRE:
2922 case ARM::t2STRH_POST:
2923 case ARM::t2STRH_PRE:
2925 case ARM::t2STR_POST:
2926 case ARM::t2STR_PRE:
2958 Size += (*I)->getSize();
2966 if (!ItinData || ItinData->
isEmpty())
2972 if (ItinUOps >= 0) {
2998 case ARM::VLDMDIA_UPD:
2999 case ARM::VLDMDDB_UPD:
3001 case ARM::VLDMSIA_UPD:
3002 case ARM::VLDMSDB_UPD:
3004 case ARM::VSTMDIA_UPD:
3005 case ARM::VSTMDDB_UPD:
3007 case ARM::VSTMSIA_UPD:
3008 case ARM::VSTMSDB_UPD: {
3010 return (NumRegs / 2) + (NumRegs % 2) + 1;
3013 case ARM::LDMIA_RET:
3018 case ARM::LDMIA_UPD:
3019 case ARM::LDMDA_UPD:
3020 case ARM::LDMDB_UPD:
3021 case ARM::LDMIB_UPD:
3026 case ARM::STMIA_UPD:
3027 case ARM::STMDA_UPD:
3028 case ARM::STMDB_UPD:
3029 case ARM::STMIB_UPD:
3031 case ARM::tLDMIA_UPD:
3032 case ARM::tSTMIA_UPD:
3036 case ARM::t2LDMIA_RET:
3039 case ARM::t2LDMIA_UPD:
3040 case ARM::t2LDMDB_UPD:
3043 case ARM::t2STMIA_UPD:
3044 case ARM::t2STMDB_UPD: {
3047 int UOps = 1 + NumRegs;
3050 case ARM::VLDMDIA_UPD:
3051 case ARM::VLDMDDB_UPD:
3052 case ARM::VLDMSIA_UPD:
3053 case ARM::VLDMSDB_UPD:
3054 case ARM::VSTMDIA_UPD:
3055 case ARM::VSTMDDB_UPD:
3056 case ARM::VSTMSIA_UPD:
3057 case ARM::VSTMSDB_UPD:
3058 case ARM::LDMIA_UPD:
3059 case ARM::LDMDA_UPD:
3060 case ARM::LDMDB_UPD:
3061 case ARM::LDMIB_UPD:
3062 case ARM::STMIA_UPD:
3063 case ARM::STMDA_UPD:
3064 case ARM::STMDB_UPD:
3065 case ARM::STMIB_UPD:
3066 case ARM::tLDMIA_UPD:
3067 case ARM::tSTMIA_UPD:
3068 case ARM::t2LDMIA_UPD:
3069 case ARM::t2LDMDB_UPD:
3070 case ARM::t2STMIA_UPD:
3071 case ARM::t2STMDB_UPD:
3074 case ARM::LDMIA_RET:
3076 case ARM::t2LDMIA_RET:
3086 int A8UOps = (NumRegs / 2);
3091 int A9UOps = (NumRegs / 2);
3094 if ((NumRegs % 2) ||
3111 unsigned DefIdx,
unsigned DefAlign)
const {
3120 DefCycle = RegNo / 2 + 1;
3125 bool isSLoad =
false;
3130 case ARM::VLDMSIA_UPD:
3131 case ARM::VLDMSDB_UPD:
3138 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
3142 DefCycle = RegNo + 2;
3152 unsigned DefIdx,
unsigned DefAlign)
const {
3162 DefCycle = RegNo / 2;
3168 DefCycle = (RegNo / 2);
3171 if ((RegNo % 2) || DefAlign < 8)
3177 DefCycle = RegNo + 2;
3187 unsigned UseIdx,
unsigned UseAlign)
const {
3195 UseCycle = RegNo / 2 + 1;
3200 bool isSStore =
false;
3205 case ARM::VSTMSIA_UPD:
3206 case ARM::VSTMSDB_UPD:
3213 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
3217 UseCycle = RegNo + 2;
3227 unsigned UseIdx,
unsigned UseAlign)
const {
3234 UseCycle = RegNo / 2;
3240 UseCycle = (RegNo / 2);
3243 if ((RegNo % 2) || UseAlign < 8)
3255 unsigned DefIdx,
unsigned DefAlign,
3257 unsigned UseIdx,
unsigned UseAlign)
const {
3268 bool LdmBypass =
false;
3275 case ARM::VLDMDIA_UPD:
3276 case ARM::VLDMDDB_UPD:
3278 case ARM::VLDMSIA_UPD:
3279 case ARM::VLDMSDB_UPD:
3280 DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3283 case ARM::LDMIA_RET:
3288 case ARM::LDMIA_UPD:
3289 case ARM::LDMDA_UPD:
3290 case ARM::LDMDB_UPD:
3291 case ARM::LDMIB_UPD:
3293 case ARM::tLDMIA_UPD:
3295 case ARM::t2LDMIA_RET:
3298 case ARM::t2LDMIA_UPD:
3299 case ARM::t2LDMDB_UPD:
3301 DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3316 case ARM::VSTMDIA_UPD:
3317 case ARM::VSTMDDB_UPD:
3319 case ARM::VSTMSIA_UPD:
3320 case ARM::VSTMSDB_UPD:
3321 UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3328 case ARM::STMIA_UPD:
3329 case ARM::STMDA_UPD:
3330 case ARM::STMDB_UPD:
3331 case ARM::STMIB_UPD:
3332 case ARM::tSTMIA_UPD:
3337 case ARM::t2STMIA_UPD:
3338 case ARM::t2STMDB_UPD:
3339 UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3347 UseCycle = DefCycle - UseCycle + 1;
3356 UseClass, UseIdx)) {
3366 unsigned &DefIdx,
unsigned &Dist) {
3371 assert(II->isInsideBundle() &&
"Empty bundle?");
3374 while (II->isInsideBundle()) {
3375 Idx = II->findRegisterDefOperandIdx(Reg,
false,
true, TRI);
3382 assert(Idx != -1 &&
"Cannot find bundled definition!");
3389 unsigned &UseIdx,
unsigned &Dist) {
3393 assert(II->isInsideBundle() &&
"Empty bundle?");
3398 while (II != E && II->isInsideBundle()) {
3399 Idx = II->findRegisterUseOperandIdx(Reg,
false, TRI);
3402 if (II->getOpcode() != ARM::t2IT)
3440 case ARM::t2LDRSHs: {
3443 if (ShAmt == 0 || ShAmt == 2)
3448 }
else if (Subtarget.
isSwift()) {
3460 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3471 case ARM::t2LDRSHs: {
3474 if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
3481 if (DefAlign < 8 && Subtarget.
isLikeA9()) {
3488 case ARM::VLD1q8wb_fixed:
3489 case ARM::VLD1q16wb_fixed:
3490 case ARM::VLD1q32wb_fixed:
3491 case ARM::VLD1q64wb_fixed:
3492 case ARM::VLD1q8wb_register:
3493 case ARM::VLD1q16wb_register:
3494 case ARM::VLD1q32wb_register:
3495 case ARM::VLD1q64wb_register:
3502 case ARM::VLD2d8wb_fixed:
3503 case ARM::VLD2d16wb_fixed:
3504 case ARM::VLD2d32wb_fixed:
3505 case ARM::VLD2q8wb_fixed:
3506 case ARM::VLD2q16wb_fixed:
3507 case ARM::VLD2q32wb_fixed:
3508 case ARM::VLD2d8wb_register:
3509 case ARM::VLD2d16wb_register:
3510 case ARM::VLD2d32wb_register:
3511 case ARM::VLD2q8wb_register:
3512 case ARM::VLD2q16wb_register:
3513 case ARM::VLD2q32wb_register:
3518 case ARM::VLD3d8_UPD:
3519 case ARM::VLD3d16_UPD:
3520 case ARM::VLD3d32_UPD:
3521 case ARM::VLD1d64Twb_fixed:
3522 case ARM::VLD1d64Twb_register:
3523 case ARM::VLD3q8_UPD:
3524 case ARM::VLD3q16_UPD:
3525 case ARM::VLD3q32_UPD:
3530 case ARM::VLD4d8_UPD:
3531 case ARM::VLD4d16_UPD:
3532 case ARM::VLD4d32_UPD:
3533 case ARM::VLD1d64Qwb_fixed:
3534 case ARM::VLD1d64Qwb_register:
3535 case ARM::VLD4q8_UPD:
3536 case ARM::VLD4q16_UPD:
3537 case ARM::VLD4q32_UPD:
3538 case ARM::VLD1DUPq8:
3539 case ARM::VLD1DUPq16:
3540 case ARM::VLD1DUPq32:
3541 case ARM::VLD1DUPq8wb_fixed:
3542 case ARM::VLD1DUPq16wb_fixed:
3543 case ARM::VLD1DUPq32wb_fixed:
3544 case ARM::VLD1DUPq8wb_register:
3545 case ARM::VLD1DUPq16wb_register:
3546 case ARM::VLD1DUPq32wb_register:
3547 case ARM::VLD2DUPd8:
3548 case ARM::VLD2DUPd16:
3549 case ARM::VLD2DUPd32:
3550 case ARM::VLD2DUPd8wb_fixed:
3551 case ARM::VLD2DUPd16wb_fixed:
3552 case ARM::VLD2DUPd32wb_fixed:
3553 case ARM::VLD2DUPd8wb_register:
3554 case ARM::VLD2DUPd16wb_register:
3555 case ARM::VLD2DUPd32wb_register:
3556 case ARM::VLD4DUPd8:
3557 case ARM::VLD4DUPd16:
3558 case ARM::VLD4DUPd32:
3559 case ARM::VLD4DUPd8_UPD:
3560 case ARM::VLD4DUPd16_UPD:
3561 case ARM::VLD4DUPd32_UPD:
3563 case ARM::VLD1LNd16:
3564 case ARM::VLD1LNd32:
3565 case ARM::VLD1LNd8_UPD:
3566 case ARM::VLD1LNd16_UPD:
3567 case ARM::VLD1LNd32_UPD:
3569 case ARM::VLD2LNd16:
3570 case ARM::VLD2LNd32:
3571 case ARM::VLD2LNq16:
3572 case ARM::VLD2LNq32:
3573 case ARM::VLD2LNd8_UPD:
3574 case ARM::VLD2LNd16_UPD:
3575 case ARM::VLD2LNd32_UPD:
3576 case ARM::VLD2LNq16_UPD:
3577 case ARM::VLD2LNq32_UPD:
3579 case ARM::VLD4LNd16:
3580 case ARM::VLD4LNd32:
3581 case ARM::VLD4LNq16:
3582 case ARM::VLD4LNq32:
3583 case ARM::VLD4LNd8_UPD:
3584 case ARM::VLD4LNd16_UPD:
3585 case ARM::VLD4LNd32_UPD:
3586 case ARM::VLD4LNq16_UPD:
3587 case ARM::VLD4LNq32_UPD:
3603 unsigned UseIdx)
const {
3605 if (!ItinData || ItinData->
isEmpty())
3613 unsigned DefAdj = 0;
3623 unsigned UseAdj = 0;
3627 Reg, NewUseIdx, UseAdj);
3636 if (Reg == ARM::CPSR) {
3639 return Subtarget.
isLikeA9() ? 1 : 20;
3647 unsigned Latency = getInstrLatency(ItinData, DefMI);
3653 if (Latency > 0 && Subtarget.
isThumb2()) {
3671 *UseMCID, UseIdx, UseAlign);
3677 int Adj = DefAdj + UseAdj;
3681 if (Adj >= 0 || (
int)Latency > -Adj) {
3682 return Latency + Adj;
3690 SDNode *DefNode,
unsigned DefIdx,
3691 SDNode *UseNode,
unsigned UseIdx)
const {
3697 if (isZeroCost(DefMCID.
Opcode))
3700 if (!ItinData || ItinData->
isEmpty())
3701 return DefMCID.
mayLoad() ? 3 : 1;
3706 return Latency <= 2 ? 1 : Latency - 1;
3708 return Latency <= 3 ? 1 : Latency - 2;
3719 UseMCID, UseIdx, UseAlign);
3731 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3741 case ARM::t2LDRSHs: {
3744 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3745 if (ShAmt == 0 || ShAmt == 2)
3750 }
else if (DefIdx == 0 && Latency > 2 && Subtarget.
isSwift()) {
3758 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3761 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3771 case ARM::t2LDRSHs: {
3779 if (DefAlign < 8 && Subtarget.
isLikeA9())
3786 case ARM::VLD1q8wb_register:
3787 case ARM::VLD1q16wb_register:
3788 case ARM::VLD1q32wb_register:
3789 case ARM::VLD1q64wb_register:
3790 case ARM::VLD1q8wb_fixed:
3791 case ARM::VLD1q16wb_fixed:
3792 case ARM::VLD1q32wb_fixed:
3793 case ARM::VLD1q64wb_fixed:
3797 case ARM::VLD2q8Pseudo:
3798 case ARM::VLD2q16Pseudo:
3799 case ARM::VLD2q32Pseudo:
3800 case ARM::VLD2d8wb_fixed:
3801 case ARM::VLD2d16wb_fixed:
3802 case ARM::VLD2d32wb_fixed:
3803 case ARM::VLD2q8PseudoWB_fixed:
3804 case ARM::VLD2q16PseudoWB_fixed:
3805 case ARM::VLD2q32PseudoWB_fixed:
3806 case ARM::VLD2d8wb_register:
3807 case ARM::VLD2d16wb_register:
3808 case ARM::VLD2d32wb_register:
3809 case ARM::VLD2q8PseudoWB_register:
3810 case ARM::VLD2q16PseudoWB_register:
3811 case ARM::VLD2q32PseudoWB_register:
3812 case ARM::VLD3d8Pseudo:
3813 case ARM::VLD3d16Pseudo:
3814 case ARM::VLD3d32Pseudo:
3815 case ARM::VLD1d64TPseudo:
3816 case ARM::VLD1d64TPseudoWB_fixed:
3817 case ARM::VLD3d8Pseudo_UPD:
3818 case ARM::VLD3d16Pseudo_UPD:
3819 case ARM::VLD3d32Pseudo_UPD:
3820 case ARM::VLD3q8Pseudo_UPD:
3821 case ARM::VLD3q16Pseudo_UPD:
3822 case ARM::VLD3q32Pseudo_UPD:
3823 case ARM::VLD3q8oddPseudo:
3824 case ARM::VLD3q16oddPseudo:
3825 case ARM::VLD3q32oddPseudo:
3826 case ARM::VLD3q8oddPseudo_UPD:
3827 case ARM::VLD3q16oddPseudo_UPD:
3828 case ARM::VLD3q32oddPseudo_UPD:
3829 case ARM::VLD4d8Pseudo:
3830 case ARM::VLD4d16Pseudo:
3831 case ARM::VLD4d32Pseudo:
3832 case ARM::VLD1d64QPseudo:
3833 case ARM::VLD1d64QPseudoWB_fixed:
3834 case ARM::VLD4d8Pseudo_UPD:
3835 case ARM::VLD4d16Pseudo_UPD:
3836 case ARM::VLD4d32Pseudo_UPD:
3837 case ARM::VLD4q8Pseudo_UPD:
3838 case ARM::VLD4q16Pseudo_UPD:
3839 case ARM::VLD4q32Pseudo_UPD:
3840 case ARM::VLD4q8oddPseudo:
3841 case ARM::VLD4q16oddPseudo:
3842 case ARM::VLD4q32oddPseudo:
3843 case ARM::VLD4q8oddPseudo_UPD:
3844 case ARM::VLD4q16oddPseudo_UPD:
3845 case ARM::VLD4q32oddPseudo_UPD:
3846 case ARM::VLD1DUPq8:
3847 case ARM::VLD1DUPq16:
3848 case ARM::VLD1DUPq32:
3849 case ARM::VLD1DUPq8wb_fixed:
3850 case ARM::VLD1DUPq16wb_fixed:
3851 case ARM::VLD1DUPq32wb_fixed:
3852 case ARM::VLD1DUPq8wb_register:
3853 case ARM::VLD1DUPq16wb_register:
3854 case ARM::VLD1DUPq32wb_register:
3855 case ARM::VLD2DUPd8:
3856 case ARM::VLD2DUPd16:
3857 case ARM::VLD2DUPd32:
3858 case ARM::VLD2DUPd8wb_fixed:
3859 case ARM::VLD2DUPd16wb_fixed:
3860 case ARM::VLD2DUPd32wb_fixed:
3861 case ARM::VLD2DUPd8wb_register:
3862 case ARM::VLD2DUPd16wb_register:
3863 case ARM::VLD2DUPd32wb_register:
3864 case ARM::VLD4DUPd8Pseudo:
3865 case ARM::VLD4DUPd16Pseudo:
3866 case ARM::VLD4DUPd32Pseudo:
3867 case ARM::VLD4DUPd8Pseudo_UPD:
3868 case ARM::VLD4DUPd16Pseudo_UPD:
3869 case ARM::VLD4DUPd32Pseudo_UPD:
3870 case ARM::VLD1LNq8Pseudo:
3871 case ARM::VLD1LNq16Pseudo:
3872 case ARM::VLD1LNq32Pseudo:
3873 case ARM::VLD1LNq8Pseudo_UPD:
3874 case ARM::VLD1LNq16Pseudo_UPD:
3875 case ARM::VLD1LNq32Pseudo_UPD:
3876 case ARM::VLD2LNd8Pseudo:
3877 case ARM::VLD2LNd16Pseudo:
3878 case ARM::VLD2LNd32Pseudo:
3879 case ARM::VLD2LNq16Pseudo:
3880 case ARM::VLD2LNq32Pseudo:
3881 case ARM::VLD2LNd8Pseudo_UPD:
3882 case ARM::VLD2LNd16Pseudo_UPD:
3883 case ARM::VLD2LNd32Pseudo_UPD:
3884 case ARM::VLD2LNq16Pseudo_UPD:
3885 case ARM::VLD2LNq32Pseudo_UPD:
3886 case ARM::VLD4LNd8Pseudo:
3887 case ARM::VLD4LNd16Pseudo:
3888 case ARM::VLD4LNd32Pseudo:
3889 case ARM::VLD4LNq16Pseudo:
3890 case ARM::VLD4LNq32Pseudo:
3891 case ARM::VLD4LNd8Pseudo_UPD:
3892 case ARM::VLD4LNd16Pseudo_UPD:
3893 case ARM::VLD4LNd32Pseudo_UPD:
3894 case ARM::VLD4LNq16Pseudo_UPD:
3895 case ARM::VLD4LNq32Pseudo_UPD:
3905 unsigned ARMBaseInstrInfo::getPredicationCost(
const MachineInstr *MI)
const {
3925 unsigned *PredCost)
const {
3933 unsigned Latency = 0;
3936 while (++I != E && I->isInsideBundle()) {
3937 if (I->getOpcode() != ARM::t2IT)
3938 Latency += getInstrLatency(ItinData, I, PredCost);
3967 if (Adj >= 0 || (
int)Latency > -Adj) {
3968 return Latency + Adj;
3978 if (!ItinData || ItinData->
isEmpty())
3991 bool ARMBaseInstrInfo::
4012 bool ARMBaseInstrInfo::
4016 if (!ItinData || ItinData->
isEmpty())
4023 return (DefCycle != -1 && DefCycle <= 2);
4028 bool ARMBaseInstrInfo::verifyInstruction(
const MachineInstr *MI,
4031 ErrInfo =
"Pseudo flag setting opcodes only exist in Selection DAG";
4040 unsigned LoadImmOpc,
4045 unsigned Reg = MI->getOperand(0).getReg();
4047 cast<GlobalValue>((*MI->memoperands_begin())->getValue());
4050 BuildMI(MBB, MI, DL,
get(LoadImmOpc), Reg)
4054 MIB =
BuildMI(MBB, MI, DL,
get(LoadOpc), Reg);
4059 MIB.addMemOperand(MMO);
4063 MIB =
BuildMI(MBB, MI, DL,
get(LoadOpc), Reg);
4065 MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
4071 unsigned &AddSubOpc,
4072 bool &NegAcc,
bool &HasLane)
const {
4074 if (I == MLxEntryMap.
end())
4104 std::pair<uint16_t, uint16_t>
4125 return std::make_pair(
ExeNEON, 0);
4130 return std::make_pair(
ExeNEON, 0);
4133 return std::make_pair(
ExeVFP, 0);
4139 unsigned SReg,
unsigned &Lane) {
4143 if (DReg != ARM::NoRegister)
4149 assert(DReg &&
"S-register with no D super-register?");
4170 unsigned DReg,
unsigned Lane,
4171 unsigned &ImplicitSReg) {
4181 (Lane & 1) ? ARM::ssub_0 : ARM::ssub_1);
4198 unsigned DstReg, SrcReg, DReg;
4211 assert(!
isPredicated(MI) &&
"Cannot predicate a VORRd");
4214 assert(Subtarget.
hasNEON() &&
"VORRd requires NEON");
4232 assert(!
isPredicated(MI) &&
"Cannot predicate a VGETLN");
4246 MI->
setDesc(
get(ARM::VGETLNi32));
4258 assert(!
isPredicated(MI) &&
"Cannot predicate a VSETLN");
4266 unsigned ImplicitSReg;
4275 MI->
setDesc(
get(ARM::VSETLNi32));
4285 if (ImplicitSReg != 0)
4297 unsigned DstLane = 0, SrcLane = 0, DDst, DSrc;
4301 unsigned ImplicitSReg;
4311 MI->
setDesc(
get(ARM::VDUPLN32d));
4321 if (ImplicitSReg != 0)
4340 get(ARM::VEXTd32), DDst);
4345 unsigned CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst;
4349 CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst;
4356 if (SrcLane == DstLane)
4359 MI->
setDesc(
get(ARM::VEXTd32));
4364 CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst;
4365 CurUndef = CurReg == DSrc && !MI->
readsRegister(CurReg, TRI);
4368 CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst;
4369 CurUndef = CurReg == DSrc && !MI->
readsRegister(CurReg, TRI);
4375 if (SrcLane != DstLane)
4381 if (ImplicitSReg != 0)
4413 assert(TRI &&
"Need TRI instance");
4427 case ARM::VMOVv4i16:
4428 case ARM::VMOVv2i32:
4429 case ARM::VMOVv2f32:
4430 case ARM::VMOVv1i64:
4435 case ARM::VLD1LNd32:
4452 }
else if (ARM::SPRRegClass.
contains(Reg)) {
4471 assert(MI && OpNum < MI->
getDesc().getNumDefs() &&
"OpNum is not a def");
4472 assert(TRI &&
"Need TRI instance");
4477 "Can't break virtual register dependencies.");
4478 unsigned DReg =
Reg;
4481 if (ARM::SPRRegClass.
contains(Reg)) {
4482 DReg = ARM::D0 + (Reg - ARM::S0) / 2;
4486 assert(ARM::DPRRegClass.
contains(DReg) &&
"Can only break D-reg deps");
4487 assert(MI->definesRegister(DReg, TRI) &&
"MI doesn't clobber full D-reg");
4498 get(ARM::FCONSTD), DReg).
addImm(96));
4503 return Subtarget.getFeatureBits()[ARM::HasV6KOps];
4513 ((ShImm == 1 || ShImm == 2) &&
4535 RegSubRegPairAndIdx(MOReg->
getReg(), MOReg->
getSubReg(), ARM::ssub_0));
4539 RegSubRegPairAndIdx(MOReg->
getReg(), MOReg->
getSubReg(), ARM::ssub_1));
4547 RegSubRegPairAndIdx &InputReg)
const {
4560 InputReg.SubIdx = DefIdx == 0 ? ARM::ssub_0 : ARM::ssub_1;
4567 const MachineInstr &MI,
unsigned DefIdx, RegSubRegPair &BaseReg,
4568 RegSubRegPairAndIdx &InsertedReg)
const {
4573 case ARM::VSETLNi32:
4581 InsertedReg.Reg = MOInsertedReg.
getReg();
4582 InsertedReg.SubReg = MOInsertedReg.
getSubReg();
4583 InsertedReg.SubIdx = MOIndex.
getImm() == 0 ? ARM::ssub_0 : ARM::ssub_1;
virtual MachineInstr * duplicate(MachineInstr *Orig, MachineFunction &MF) const
Create a duplicate of the Orig instruction in MF.
MachineConstantPoolValue * MachineCPVal
void push_back(const T &Elt)
The memory access reads data.
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const override
bool getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const override
Build the equivalent inputs of a INSERT_SUBREG for the given MI and DefIdx.
The memory access writes data.
const GlobalValue * getGlobal() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
static cl::opt< unsigned > SwiftPartialUpdateClearance("swift-partial-update-clearance", cl::Hidden, cl::init(12), cl::desc("Clearance before partial register updates"))
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
instr_iterator instr_end()
static unsigned char getAM3Offset(unsigned AM3Opc)
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
unsigned getMispredictionPenalty() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
bool removeKill(MachineInstr *MI)
removeKill - Delete a kill corresponding to the specified machine instruction.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
static const MachineInstr * getBundledUseMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &UseIdx, unsigned &Dist)
int getNumMicroOps(unsigned ItinClassIndx) const
Return the number of micro-ops that the given class decodes to.
bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
MachineInstr * duplicate(MachineInstr *Orig, MachineFunction &MF) const override
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
bool mayStore() const
Return true if this instruction could possibly modify memory.
ARMConstantPoolValue - ARM specific constantpool value.
void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
Describe properties that are true of each instruction in the target description file.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
static bool isVirtualRegister(unsigned Reg)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
unsigned getNumMicroOps(const InstrItineraryData *ItinData, const MachineInstr *MI) const override
static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg, int CmpMask, bool CommonUse)
isSuitableForMask - Identify a suitable 'and' instruction that operates on the given source register ...
std::pair< uint16_t, uint16_t > getExecutionDomain(const MachineInstr *MI) const override
VFP/NEON execution domains.
bool isPredicable(QueryType Type=AllInBundle) const
Return true if this instruction has a predicate operand that controls execution.
bool readsVirtualRegister(unsigned Reg) const
Return true if the MachineInstr reads the specified virtual register.
virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
uint32_t getNumerator() const
static unsigned getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI, unsigned SReg, unsigned &Lane)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, int CmpValue, const MachineRegisterInfo *MRI) const override
optimizeCompareInstr - Convert the instruction to set the zero flag so that we can remove a "comparis...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const
GetInstSize - Returns the size of the specified MachineInstr.
const char * getSymbolName() const
bool isThumbFunction() const
VarInfo - This represents the regions where a virtual register is live in the program.
const SDValue & getOperand(unsigned Num) const
void setIsDead(bool Val=true)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool produceSameValue(const MachineInstr *MI0, const MachineInstr *MI1, const MachineRegisterInfo *MRI) const override
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, int &FrameIndex) const override
bool isThumb1Only() const
iterator_range< mop_iterator > operands()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
getMachineMemOperand - Allocate a new MachineMemOperand.
unsigned createPICLabelUId()
static bool isThumb(const MCSubtargetInfo &STI)
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
static bool getImplicitSPRUseForDPRUse(const TargetRegisterInfo *TRI, MachineInstr *MI, unsigned DReg, unsigned Lane, unsigned &ImplicitSReg)
getImplicitSPRUseForDPRUse - Given a use of a DPR register and lane, set ImplicitSReg to a register n...
static unsigned getSOImmValRotate(unsigned Imm)
getSOImmValRotate - Try to handle Imm with an immediate shifter operand, computing the rotate amount ...
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
getFixedStack - Return a MachinePointerInfo record that refers to the the specified FrameIndex...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
static unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void clearKillInfo()
Clears kill flags on all operands.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
MachineMemOperand - A description of a memory reference used in the backend.
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
mmo_iterator memoperands_begin() const
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Provide an instruction scheduling machine model to CodeGen passes.
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
Return target specific asm information.
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, DebugLoc DL) const override
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
use_instr_iterator use_instr_begin(unsigned RegNo) const
bool isCall() const
Return true if the instruction is a call.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setImplicit(bool Val=true)
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
rewriteARMFrameIndex / rewriteT2FrameIndex - Rewrite MI to access 'Offset' bytes from the FP...
const TargetRegisterClass * getRegClass(unsigned Reg) const
getRegClass - Return the register class of the specified virtual register.
std::vector< MachineBasicBlock * >::iterator succ_iterator
Reg
All possible values of the reg field in the ModR/M byte.
bool memoperands_empty() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, int64_t Offset2, unsigned NumLoads) const override
shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to determine (in conjunction w...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
INLINEASM - Represents an inline asm block.
static unsigned getT2SOImmTwoPartFirst(unsigned Imm)
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
bool isFpMLxInstruction(unsigned Opcode) const
isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS instruction.
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, const BranchProbability &Probability) const override
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
virtual MachineInstr * commuteInstruction(MachineInstr *MI, bool NewMI=false) const
If a target has any instructions that are commutable but require converting to different instructions...
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
getMatchingSuperReg - Return a super-register of the specified register Reg so its sub-register of in...
bool isV8EligibleForIT(InstrType *Instr)
bool isCopyLike() const
Return true if the instruction behaves like a copy.
static unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData, const MachineInstr *MI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool PredicateInstruction(MachineInstr *MI, ArrayRef< MachineOperand > Pred) const override
Itinerary data supplied by a subtarget to be used by a target.
iterator getLastNonDebugInstr()
getLastNonDebugInstr - returns an iterator to the last non-debug instruction in the basic block...
This class is a data container for one entry in a MachineConstantPool.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
static const ARM_MLxEntry ARM_MLxTable[]
unsigned getMatchingCondBranchOpcode(unsigned Opc)
ARM_MLxEntry - Record information about MLA / MLS instructions.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
unsigned getUndefRegState(bool B)
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
getCalleeSavedRegs - Return a null-terminated list of all of the callee saved registers on this targe...
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, unsigned Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been <def>ined and not <kill>ed as of just before Before...
size_t size() const
size - Get the array size.
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
reverse_iterator rbegin()
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
static bool isCondBranchOpcode(int Opc)
bool IsCPSRDead< MachineInstr >(MachineInstr *MI)
const Constant * ConstVal
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
bool isDebugValue() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool isImplicitDef() const
mmo_iterator memoperands_end() const
bool isInsertSubreg() const
bundle_iterator< MachineInstr, instr_iterator > iterator
static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs)
initializer< Ty > init(const Ty &Val)
bool regsOverlap(unsigned regA, unsigned regB) const
regsOverlap - Returns true if the two registers are equal or alias each other.
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
HazardRecognizer - This determines whether or not an instruction can be issued this cycle...
const InstrItineraryData * getInstrItineraries() const
static bool isAnySubRegLive(unsigned Reg, const TargetRegisterInfo *TRI, MachineInstr *MI)
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, int64_t &Offset2) const override
areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to determine if two loads are lo...
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition, otherwise returns AL.
static unsigned char getAM5Offset(unsigned AM5Opc)
static unsigned getSOImmTwoPartSecond(unsigned V)
getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, return the second chunk of ...
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found...
bool isSchedulingBoundary(const MachineInstr *MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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"))
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static bool isJumpTableBranchOpcode(int Opc)
unsigned getStageLatency(unsigned ItinClassIndx) const
Return the total stage latency of the given class.
virtual bool hasSameValue(ARMConstantPoolValue *ACPV)
hasSameValue - Return true if this ARM constpool value can share the same constantpool entry as anoth...
static bool isEligibleForITBlock(const MachineInstr *MI)
static unsigned getT2SOImmTwoPartSecond(unsigned Imm)
Register is known to be dead.
This pseudo-instruction loads the stack guard value.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void copyFromCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, bool KillSrc, const ARMSubtarget &Subtarget) const
void setImm(int64_t immVal)
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineInstr * commuteInstruction(MachineInstr *, bool=false) const override
commuteInstruction - Handle commutable instructions.
static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg, unsigned SrcReg2, int ImmValue, MachineInstr *OI)
isRedundantFlagInstr - check whether the first instruction, whose only purpose is to update flags...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
MachineInstr * optimizeSelect(MachineInstr *MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool empty() const
empty - Check if the array is empty.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
LivenessQueryResult
Possible outcome of a register liveness query to computeRegisterLiveness()
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
Register is known to be live.
succ_iterator succ_begin()
unsigned getSubReg() const
void breakPartialRegDependency(MachineBasicBlock::iterator, unsigned, const TargetRegisterInfo *TRI) const override
VarInfo & getVarInfo(unsigned RegIdx)
getVarInfo - Return the VarInfo structure for the specified VIRTUAL register.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSubRegIterator enumerates all sub-registers of Reg.
pred_iterator pred_begin()
static const MachineInstr * getBundledDefMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &DefIdx, unsigned &Dist)
struct llvm::MachineOperand::@33::@34 Reg
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)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, int &FrameIndex) const override
bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, unsigned &SrcReg2, int &CmpMask, int &CmpValue) const override
analyzeCompare - For a comparison instruction, return the source registers in SrcReg and SrcReg2 if h...
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
The memory access is invariant.
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.
bool isInsertSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic INSERT_SUBREG instructions...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
std::vector< MachineInstr * > Kills
Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...
static AddrOpc getAM2Op(unsigned AM2Opc)
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
ARMConstantPoolConstant - ARM-specific constant pool values for Constants, Functions, and BlockAddresses.
int findRegisterUseOperandIdx(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a use of the specific register or -1 if it is not found...
static const MachineInstrBuilder & AddDefaultCC(const MachineInstrBuilder &MIB)
static bool isIndirectBranchOpcode(int Opc)
static bool isUncondBranchOpcode(int Opc)
virtual unsigned getUnindexedOpcode(unsigned Opc) const =0
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
unsigned RemoveBranch(MachineBasicBlock &MBB) const override
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
bool isIdenticalTo(const MachineInstr *Other, MICheckType Check=CheckDefs) const
Return true if this instruction is identical to (same opcode and same operands as) the specified inst...
bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const
GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
static unsigned getAM2Offset(unsigned AM2Opc)
ARMConstantPoolSymbol - ARM-specific constantpool values for external symbols.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
CloneMachineInstr - Create a new MachineInstr which is a copy of the 'Orig' instruction, identical in all ways except the instruction has no parent, prev, or next.
static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI)
Create a copy of a const pool value.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
Map pseudo instructions that imply an 'S' bit onto real opcodes.
An SDNode that represents everything that will be needed to construct a MachineInstr.
bool isSwiftFastImmShift(const MachineInstr *MI) const
Returns true if the instruction has a shift by immediate that can be executed in one cycle less...
bool mayLoad() const
Return true if this instruction could possibly read memory.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Represents one node in the SelectionDAG.
static bool isPushOpcode(int Opc)
static bool isSOImmTwoPartVal(unsigned V)
isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVa...
ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic block.
const MachineInstrBuilder & addFrameIndex(int Idx) const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
BUNDLE - This instruction represents an instruction bundle.
void addRegisterDefined(unsigned Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
void copyToCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, bool KillSrc, const ARMSubtarget &Subtarget) const
static int adjustDefLatency(const ARMSubtarget &Subtarget, const MachineInstr *DefMI, const MCInstrDesc *DefMCID, unsigned DefAlign)
Return the number of cycles to add to (or subtract from) the static itinerary based on the def opcode...
bool isPredicable(MachineInstr *MI) const override
isPredicable - Return true if the specified instruction can be predicated.
AddrMode
ARM Addressing Modes.
static AddrOpc getAM3Op(unsigned AM3Opc)
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate...
bool isExtractSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic EXTRACT_SUBREG instructions...
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool DefinesPredicate(MachineInstr *MI, std::vector< MachineOperand > &Pred) const override
int getOperandLatency(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
Compute and return the use operand latency of a given itinerary class and operand index if the value ...
static int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
ARMBaseInstrInfo(const ARMSubtarget &STI)
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, unsigned Reg, MachineRegisterInfo *MRI) const override
FoldImmediate - 'Reg' is known to be defined by a move immediate instruction, try to fold the immedia...
static bool isPopOpcode(int Opc)
bool isSuperRegister(unsigned RegA, unsigned RegB) const
Returns true if RegB is a super-register of RegA.
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static MachinePointerInfo getGOT()
getGOT - Return a MachinePointerInfo record that refers to a GOT entry.
Representation of each machine instruction.
static MachineInstr * canFoldIntoMOVCC(unsigned Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
Identify instructions that can be folded into a MOVCC instruction, and return the defining instructio...
bundle_iterator< const MachineInstr, const_instr_iterator > const_iterator
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
static CondCodes getOppositeCondition(CondCodes CC)
static const AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[]
unsigned getSchedClass() const
Return the scheduling class for this instruction.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
uint32_t getDenominator() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const override
Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.
Register liveness not decidable from local neighborhood.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
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)
addVirtualRegisterDead - Add information about the fact that the specified register is dead after bei...
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
Return true if there is a pipeline forwarding between instructions of itinerary classes DefClass and ...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool isCall(QueryType Type=AnyInBundle) const
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override
bool isPredicated(const MachineInstr *MI) const override
bool getRegSequenceLikeInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const override
Build the equivalent inputs of a REG_SEQUENCE for the given MI and DefIdx.
iterator find(const KeyT &Val)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
union llvm::MachineConstantPoolEntry::@30 Val
The constant itself.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *UseMI, unsigned UseIdx) const override
bool analyzeSelect(const MachineInstr *MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
static AddrOpc getAM5Op(unsigned AM5Opc)
unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, const MachineInstr *UseMI, unsigned UseOperIdx) const
Compute operand latency based on the available machine model.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const override
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
unsigned getReg() const
getReg - Returns the register number.
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
ARMHazardRecognizer handles special constraints that are not expressed in the scheduling itinerary...
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
static use_instr_iterator use_instr_end()
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const override
bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
const ARMSubtarget & getSubtarget() const
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const std::vector< MachineConstantPoolEntry > & getConstants() const
StringRef - Represent a constant reference to a string, i.e.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
bool hasOptionalDef(QueryType Type=IgnoreBundle) const
Set if this instruction has an optional definition, e.g.
unsigned getPartialRegUpdateClearance(const MachineInstr *, unsigned, const TargetRegisterInfo *) const override
bool isIdenticalTo(const MachineOperand &Other) const
isIdenticalTo - Return true if this operand is identical to the specified operand.
bool isRegSequence() const
bool isThumb2Function() const
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc, Reloc::Model RM) const
static bool isT2SOImmTwoPartVal(unsigned Imm)
static unsigned getSOImmTwoPartFirst(unsigned V)
getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it...
void setExecutionDomain(MachineInstr *MI, unsigned Domain) const override
bool isRegSequenceLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic REG_SEQUENCE instructions.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
bool isEmpty() const
Returns true if there are no itineraries.
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
Assign this MachineInstr's memory reference descriptor list.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const
MachineInstr * convertToThreeAddress(MachineFunction::iterator &MFI, MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const override
void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI, bool AddIfNotFound=false)
addVirtualRegisterKilled - Add information about the fact that the specified register is killed after...
static cl::opt< bool > EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, cl::desc("Enable ARM 2-addr to 3-addr conv"))
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig, const TargetRegisterInfo &TRI) const override
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
static ShiftOpc getSORegShOp(unsigned Op)
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
static bool isCPSRDefined(const MachineInstr *MI)
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
Function must be optimized for size first.