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"));
66 { ARM::VMLAS, ARM::VMULS, ARM::VADDS,
false,
false },
67 { ARM::VMLSS, ARM::VMULS, ARM::VSUBS,
false,
false },
68 { ARM::VMLAD, ARM::VMULD, ARM::VADDD,
false,
false },
69 { ARM::VMLSD, ARM::VMULD, ARM::VSUBD,
false,
false },
70 { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS,
true,
false },
71 { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS,
true,
false },
72 { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD,
true,
false },
73 { ARM::VNMLSD, ARM::VMULD, ARM::VSUBD,
true,
false },
76 { ARM::VMLAfd, ARM::VMULfd, ARM::VADDfd,
false,
false },
77 { ARM::VMLSfd, ARM::VMULfd, ARM::VSUBfd,
false,
false },
78 { ARM::VMLAfq, ARM::VMULfq, ARM::VADDfq,
false,
false },
79 { ARM::VMLSfq, ARM::VMULfq, ARM::VSUBfq,
false,
false },
80 { ARM::VMLAslfd, ARM::VMULslfd, ARM::VADDfd,
false,
true },
81 { ARM::VMLSslfd, ARM::VMULslfd, ARM::VSUBfd,
false,
true },
82 { ARM::VMLAslfq, ARM::VMULslfq, ARM::VADDfq,
false,
true },
83 { ARM::VMLSslfq, ARM::VMULslfq, ARM::VSUBfq,
false,
true },
102 if (usePreRAHazardRecognizer()) {
104 static_cast<const ARMSubtarget *
>(STI)->getInstrItineraryData();
129 default:
return nullptr;
152 unsigned WBReg = WB.
getReg();
153 unsigned BaseReg = Base.
getReg();
154 unsigned OffReg = Offset.
getReg();
168 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
174 }
else if (Amt != 0) {
178 get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
188 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
202 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
210 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
220 std::vector<MachineInstr*> NewMIs;
235 NewMIs.push_back(MemMI);
236 NewMIs.push_back(UpdateMI);
253 NewMIs.push_back(UpdateMI);
254 NewMIs.push_back(MemMI);
266 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
271 for (
unsigned j = 0; j < 2; ++j) {
278 VI.
Kills.push_back(NewMI);
287 MFI->insert(MBBI, NewMIs[1]);
288 MFI->insert(MBBI, NewMIs[0]);
297 bool AllowModify)
const {
302 if (I == MBB.
begin())
308 while (
isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
313 bool CantAnalyze =
false;
316 while (I->isDebugValue() || !I->isTerminator()) {
317 if (I == MBB.
begin())
328 TBB = I->getOperand(0).getMBB();
334 assert(!FBB &&
"FBB should have been null.");
336 TBB = I->getOperand(0).getMBB();
339 }
else if (I->isReturn()) {
362 while (DI != MBB.
end()) {
373 if (I == MBB.
begin())
386 int *BytesRemoved)
const {
387 assert(!BytesRemoved &&
"code size not handled");
398 I->eraseFromParent();
402 if (I == MBB.
begin())
return 1;
408 I->eraseFromParent();
417 int *BytesAdded)
const {
418 assert(!BytesAdded &&
"code size not handled");
427 assert(TBB &&
"insertBranch must not be told to insert a fallthrough");
429 "ARM branch conditions have two components!");
466 while (++I != E && I->isInsideBundle()) {
467 int PIdx = I->findFirstPredOperandIdx();
468 if (PIdx != -1 && I->getOperand(PIdx).getImm() !=
ARMCC::AL)
484 .addImm(Pred[0].getImm())
485 .addReg(Pred[1].
getReg());
492 PMO.
setImm(Pred[0].getImm());
501 if (Pred1.
size() > 2 || Pred2.
size() > 2)
541 for (
const auto &MO : MI->
operands())
542 if (MO.isReg() && MO.getReg() == ARM::CPSR && MO.isDef() && !MO.isDead())
549 default:
return true;
605 for (
unsigned i = 0, e =
MI->getNumOperands();
i != e; ++
i) {
609 if (MO.
getReg() != ARM::CPSR)
638 case TargetOpcode::BUNDLE:
639 return getInstBundleLength(MI);
640 case ARM::MOVi16_ga_pcrel:
641 case ARM::MOVTi16_ga_pcrel:
642 case ARM::t2MOVi16_ga_pcrel:
643 case ARM::t2MOVTi16_ga_pcrel:
646 case ARM::t2MOVi32imm:
648 case ARM::CONSTPOOL_ENTRY:
649 case ARM::JUMPTABLE_INSTS:
650 case ARM::JUMPTABLE_ADDRS:
651 case ARM::JUMPTABLE_TBB:
652 case ARM::JUMPTABLE_TBH:
656 case ARM::Int_eh_sjlj_longjmp:
658 case ARM::tInt_eh_sjlj_longjmp:
660 case ARM::tInt_WIN_eh_sjlj_longjmp:
662 case ARM::Int_eh_sjlj_setjmp:
663 case ARM::Int_eh_sjlj_setjmp_nofp:
665 case ARM::tInt_eh_sjlj_setjmp:
666 case ARM::t2Int_eh_sjlj_setjmp:
667 case ARM::t2Int_eh_sjlj_setjmp_nofp:
674 unsigned ARMBaseInstrInfo::getInstBundleLength(
const MachineInstr &
MI)
const {
678 while (++I != E && I->isInsideBundle()) {
679 assert(!I->isBundle() &&
"No nested bundle!");
687 unsigned DestReg,
bool KillSrc,
689 unsigned Opc = Subtarget.
isThumb()
690 ? (Subtarget.
isMClass() ? ARM::t2MRS_M : ARM::t2MRS_AR)
694 BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), DestReg);
708 unsigned SrcReg,
bool KillSrc,
710 unsigned Opc = Subtarget.
isThumb()
711 ? (Subtarget.
isMClass() ? ARM::t2MSR_M : ARM::t2MSR_AR)
730 const DebugLoc &DL,
unsigned DestReg,
731 unsigned SrcReg,
bool KillSrc)
const {
732 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
733 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
735 if (GPRDest && GPRSrc) {
741 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
742 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
745 if (SPRDest && SPRSrc)
747 else if (GPRDest && SPRSrc)
749 else if (SPRDest && GPRSrc)
753 else if (ARM::QPRRegClass.
contains(DestReg, SrcReg))
759 if (Opc == ARM::VORRq)
766 unsigned BeginIdx = 0;
767 unsigned SubRegs = 0;
771 if (ARM::QQPRRegClass.
contains(DestReg, SrcReg)) {
773 BeginIdx = ARM::qsub_0;
775 }
else if (ARM::QQQQPRRegClass.
contains(DestReg, SrcReg)) {
777 BeginIdx = ARM::qsub_0;
780 }
else if (ARM::DPairRegClass.
contains(DestReg, SrcReg)) {
782 BeginIdx = ARM::dsub_0;
784 }
else if (ARM::DTripleRegClass.
contains(DestReg, SrcReg)) {
786 BeginIdx = ARM::dsub_0;
788 }
else if (ARM::DQuadRegClass.
contains(DestReg, SrcReg)) {
790 BeginIdx = ARM::dsub_0;
792 }
else if (ARM::GPRPairRegClass.
contains(DestReg, SrcReg)) {
793 Opc = Subtarget.
isThumb2() ? ARM::tMOVr : ARM::MOVr;
794 BeginIdx = ARM::gsub_0;
796 }
else if (ARM::DPairSpcRegClass.
contains(DestReg, SrcReg)) {
798 BeginIdx = ARM::dsub_0;
801 }
else if (ARM::DTripleSpcRegClass.
contains(DestReg, SrcReg)) {
803 BeginIdx = ARM::dsub_0;
806 }
else if (ARM::DQuadSpcRegClass.
contains(DestReg, SrcReg)) {
808 BeginIdx = ARM::dsub_0;
813 BeginIdx = ARM::ssub_0;
815 }
else if (SrcReg == ARM::CPSR) {
818 }
else if (DestReg == ARM::CPSR) {
819 copyToCPSR(MBB, I, SrcReg, KillSrc, Subtarget);
823 assert(Opc &&
"Impossible reg-to-reg copy");
830 BeginIdx = BeginIdx + ((SubRegs - 1) * Spacing);
836 for (
unsigned i = 0;
i != SubRegs; ++
i) {
837 unsigned Dst = TRI->
getSubReg(DestReg, BeginIdx +
i * Spacing);
838 unsigned Src = TRI->
getSubReg(SrcReg, BeginIdx +
i * Spacing);
839 assert(Dst && Src &&
"Bad sub-register");
841 assert(!DstRegs.
count(Src) &&
"destructive vector copy");
844 Mov =
BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), Dst).
addReg(Src);
846 if (Opc == ARM::VORRq)
850 if (Opc == ARM::MOVr)
861 unsigned SubIdx,
unsigned State,
864 return MIB.
addReg(Reg, State);
868 return MIB.
addReg(Reg, State, SubIdx);
873 unsigned SrcReg,
bool isKill,
int FI,
877 if (I != MBB.
end()) DL = I->getDebugLoc();
888 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
891 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
892 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
895 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
900 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
903 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
904 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
908 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
917 .addFrameIndex(FI).addMemOperand(MMO));
919 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
925 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
929 .addFrameIndex(FI).addImm(16)
931 .addMemOperand(MMO));
936 .addMemOperand(MMO));
942 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
946 .addFrameIndex(FI).addImm(16)
948 .addMemOperand(MMO));
955 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
956 AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
962 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
967 .addFrameIndex(FI).addImm(16)
969 .addMemOperand(MMO));
976 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
977 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
978 AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
984 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
990 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
991 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
992 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
993 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
994 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
995 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
996 AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
1030 case ARM::VST1d64TPseudo:
1031 case ARM::VST1d64QPseudo:
1051 return MI.
mayStore() && hasStoreToStackSlot(MI, Dummy, FrameIndex);
1056 unsigned DestReg,
int FI,
1060 if (I != MBB.
end()) DL = I->getDebugLoc();
1070 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1072 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1074 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1076 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1081 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1083 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
1084 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1088 MIB =
BuildMI(MBB, I, DL,
get(ARM::LDRD));
1098 .addFrameIndex(FI).addMemOperand(MMO));
1109 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
1112 .addFrameIndex(FI).addImm(16)
1113 .addMemOperand(MMO));
1117 .addMemOperand(MMO));
1123 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1126 .addFrameIndex(FI).addImm(16)
1127 .addMemOperand(MMO));
1132 .addMemOperand(MMO));
1143 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
1146 .addFrameIndex(FI).addImm(16)
1147 .addMemOperand(MMO));
1164 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1212 case ARM::VLD1d64TPseudo:
1213 case ARM::VLD1d64QPseudo:
1233 return MI.
mayLoad() && hasLoadFromStackSlot(MI, Dummy, FrameIndex);
1240 bool isThumb2 = Subtarget.
isThumb2();
1247 if (isThumb1 || !MI->getOperand(1).isDead()) {
1248 LDM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA_UPD
1249 : isThumb1 ? ARM::tLDMIA_UPD
1253 LDM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA : ARM::LDMIA));
1256 if (isThumb1 || !MI->getOperand(0).isDead()) {
1257 STM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA_UPD
1258 : isThumb1 ? ARM::tSTMIA_UPD
1262 STM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA : ARM::STMIA));
1271 for(
unsigned I = 5; I < MI->getNumOperands(); ++
I)
1272 ScratchRegs.
push_back(MI->getOperand(I).getReg());
1273 std::sort(ScratchRegs.
begin(), ScratchRegs.
end(),
1274 [&TRI](
const unsigned &Reg1,
1275 const unsigned &Reg2) ->
bool {
1280 for (
const auto &
Reg : ScratchRegs) {
1290 if (MI.
getOpcode() == TargetOpcode::LOAD_STACK_GUARD) {
1292 "LOAD_STACK_GUARD currently supported only for MachO.");
1293 expandLoadStackGuard(MI);
1314 if (!ARM::SPRRegClass.
contains(DstRegS, SrcRegS))
1322 if (!DstRegD || !SrcRegD)
1342 if (ImpDefIdx != -1)
1376 assert(MCPE.isMachineConstantPoolEntry() &&
1377 "Expecting a machine constantpool entry!");
1389 if (ACPV->isGlobalValue())
1391 cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
ARMCP::CPValue,
1392 4, ACPV->getModifier(), ACPV->mustAddCurrentAddress());
1393 else if (ACPV->isExtSymbol())
1396 cast<ARMConstantPoolSymbol>(ACPV)->
getSymbol(), PCLabelId, 4);
1397 else if (ACPV->isBlockAddress())
1399 Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
1401 else if (ACPV->isLSDA())
1404 else if (ACPV->isMachineBasicBlock())
1407 cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
1416 unsigned DestReg,
unsigned SubIdx,
1427 case ARM::tLDRpci_pic:
1428 case ARM::t2LDRpci_pic: {
1446 case ARM::tLDRpci_pic:
1447 case ARM::t2LDRpci_pic: {
1462 if (Opcode == ARM::t2LDRpci ||
1463 Opcode == ARM::t2LDRpci_pic ||
1464 Opcode == ARM::tLDRpci ||
1465 Opcode == ARM::tLDRpci_pic ||
1466 Opcode == ARM::LDRLIT_ga_pcrel ||
1467 Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1468 Opcode == ARM::tLDRLIT_ga_pcrel ||
1469 Opcode == ARM::MOV_ga_pcrel ||
1470 Opcode == ARM::MOV_ga_pcrel_ldr ||
1471 Opcode == ARM::t2MOV_ga_pcrel) {
1482 if (Opcode == ARM::LDRLIT_ga_pcrel ||
1483 Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1484 Opcode == ARM::tLDRLIT_ga_pcrel ||
1485 Opcode == ARM::MOV_ga_pcrel ||
1486 Opcode == ARM::MOV_ga_pcrel_ldr ||
1487 Opcode == ARM::t2MOV_ga_pcrel)
1499 if (isARMCP0 && isARMCP1) {
1505 }
else if (!isARMCP0 && !isARMCP1) {
1509 }
else if (Opcode == ARM::PICLDR) {
1517 if (Addr0 != Addr1) {
1555 int64_t &Offset2)
const {
1576 case ARM::t2LDRSHi8:
1578 case ARM::t2LDRBi12:
1579 case ARM::t2LDRSHi12:
1596 case ARM::t2LDRSHi8:
1598 case ARM::t2LDRBi12:
1599 case ARM::t2LDRSHi12:
1613 if (isa<ConstantSDNode>(Load1->
getOperand(1)) &&
1615 Offset1 = cast<ConstantSDNode>(Load1->
getOperand(1))->getSExtValue();
1616 Offset2 = cast<ConstantSDNode>(Load2->
getOperand(1))->getSExtValue();
1635 int64_t Offset1, int64_t Offset2,
1636 unsigned NumLoads)
const {
1640 assert(Offset2 > Offset1);
1642 if ((Offset2 - Offset1) / 8 > 64)
1688 while (++I != MBB->
end() && I->isDebugValue())
1690 if (I != MBB->
end() && I->getOpcode() == ARM::t2IT)
1709 unsigned NumCycles,
unsigned ExtraPredCycles,
1719 if (!Pred->
empty()) {
1721 if (LastMI->
getOpcode() == ARM::t2Bcc) {
1723 if (CmpMI != Pred->
begin()) {
1725 if (CmpMI->getOpcode() == ARM::tCMPi8 ||
1726 CmpMI->getOpcode() == ARM::t2CMPri) {
1727 unsigned Reg = CmpMI->getOperand(0).getReg();
1728 unsigned PredReg = 0;
1730 if (P ==
ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
1742 const unsigned ScalingUpFactor = 1024;
1743 unsigned UnpredCost = Probability.
scale(NumCycles * ScalingUpFactor);
1744 UnpredCost += ScalingUpFactor;
1747 return (NumCycles + ExtraPredCycles) * ScalingUpFactor <= UnpredCost;
1752 unsigned TCycles,
unsigned TExtra,
1754 unsigned FCycles,
unsigned FExtra,
1756 if (!TCycles || !FCycles)
1762 const unsigned ScalingUpFactor = 1024;
1763 unsigned TUnpredCost = Probability.
scale(TCycles * ScalingUpFactor);
1764 unsigned FUnpredCost =
1766 unsigned UnpredCost = TUnpredCost + FUnpredCost;
1767 UnpredCost += 1 * ScalingUpFactor;
1770 return (TCycles + FCycles + TExtra + FExtra) * ScalingUpFactor <= UnpredCost;
1785 unsigned &PredReg) {
1802 if (Opc == ARM::t2B)
1811 unsigned OpIdx2)
const {
1814 case ARM::t2MOVCCr: {
1816 unsigned PredReg = 0;
1819 if (CC ==
ARMCC::AL || PredReg != ARM::CPSR)
1866 bool DontMoveAcrossStores =
true;
1874 unsigned &TrueOp,
unsigned &FalseOp,
1875 bool &Optimizable)
const {
1877 "Unknown select instruction");
1896 bool PreferFalse)
const {
1898 "Unknown select instruction");
1901 bool Invert = !DefMI;
1921 for (
unsigned i = 1, e = DefDesc.getNumOperands();
1922 i != e && !DefDesc.OpInfo[
i].isPredicate(); ++
i)
1946 SeenMIs.
erase(DefMI);
1972 {ARM::ADDSri, ARM::ADDri},
1973 {ARM::ADDSrr, ARM::ADDrr},
1974 {ARM::ADDSrsi, ARM::ADDrsi},
1975 {ARM::ADDSrsr, ARM::ADDrsr},
1977 {ARM::SUBSri, ARM::SUBri},
1978 {ARM::SUBSrr, ARM::SUBrr},
1979 {ARM::SUBSrsi, ARM::SUBrsi},
1980 {ARM::SUBSrsr, ARM::SUBrsr},
1982 {ARM::RSBSri, ARM::RSBri},
1983 {ARM::RSBSrsi, ARM::RSBrsi},
1984 {ARM::RSBSrsr, ARM::RSBrsr},
1986 {ARM::t2ADDSri, ARM::t2ADDri},
1987 {ARM::t2ADDSrr, ARM::t2ADDrr},
1988 {ARM::t2ADDSrs, ARM::t2ADDrs},
1990 {ARM::t2SUBSri, ARM::t2SUBri},
1991 {ARM::t2SUBSrr, ARM::t2SUBrr},
1992 {ARM::t2SUBSrs, ARM::t2SUBrs},
1994 {ARM::t2RSBSri, ARM::t2RSBri},
1995 {ARM::t2RSBSrs, ARM::t2RSBrs},
2007 const DebugLoc &dl,
unsigned DestReg,
2008 unsigned BaseReg,
int NumBytes,
2012 if (NumBytes == 0 && DestReg != BaseReg) {
2013 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), DestReg)
2020 bool isSub = NumBytes < 0;
2021 if (isSub) NumBytes = -NumBytes;
2026 assert(ThisVal &&
"Didn't extract field correctly");
2029 NumBytes &= ~ThisVal;
2034 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
2035 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
2045 unsigned NumBytes) {
2056 if (!IsPush && !IsPop)
2059 bool IsVFPPushPop = MI->
getOpcode() == ARM::VSTMDDB_UPD ||
2061 bool IsT1PushPop = MI->
getOpcode() == ARM::tPUSH ||
2067 "trying to fold sp update into non-sp-updating push/pop");
2072 if (NumBytes % (IsVFPPushPop ? 8 : 4) != 0)
2077 int RegListIdx = IsT1PushPop ? 2 : 4;
2080 unsigned RegsNeeded;
2083 RegsNeeded = NumBytes / 8;
2084 RegClass = &ARM::DPRRegClass;
2086 RegsNeeded = NumBytes / 4;
2087 RegClass = &ARM::GPRRegClass;
2097 unsigned FirstRegEnc = -1;
2111 for (
int CurRegEnc = FirstRegEnc - 1; CurRegEnc >= 0 && RegsNeeded;
2113 unsigned CurReg = RegClass->
getRegister(CurRegEnc);
2119 false,
false,
true));
2156 for (
int i = RegList.
size() - 1;
i >= 0; --
i)
2163 unsigned FrameReg,
int &
Offset,
2174 if (Opcode == ARM::ADDri) {
2178 MI.
setDesc(TII.get(ARM::MOVr));
2183 }
else if (Offset < 0) {
2186 MI.
setDesc(TII.get(ARM::SUBri));
2204 Offset &= ~ThisImmVal;
2208 "Bit extraction didn't work?");
2211 unsigned ImmIdx = 0;
2213 unsigned NumBits = 0;
2217 ImmIdx = FrameRegIdx + 1;
2223 ImmIdx = FrameRegIdx+2;
2231 ImmIdx = FrameRegIdx+2;
2243 ImmIdx = FrameRegIdx+1;
2255 Offset += InstrOffs * Scale;
2256 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
2266 int ImmedOffset = Offset / Scale;
2267 unsigned Mask = (1 << NumBits) - 1;
2268 if ((
unsigned)Offset <= Mask * Scale) {
2276 ImmedOffset = -ImmedOffset;
2278 ImmedOffset |= 1 << NumBits;
2286 ImmedOffset = ImmedOffset &
Mask;
2289 ImmedOffset = -ImmedOffset;
2291 ImmedOffset |= 1 << NumBits;
2294 Offset &= ~(Mask*Scale);
2298 Offset = (isSub) ? -Offset : Offset;
2307 unsigned &SrcReg2,
int &CmpMask,
2308 int &CmpValue)
const {
2343 int CmpMask,
bool CommonUse) {
2382 unsigned SrcReg2,
int ImmValue,
2412 MachineInstr &CmpInstr,
unsigned SrcReg,
unsigned SrcReg2,
int CmpMask,
2416 if (!MI)
return false;
2419 if (CmpMask != ~0) {
2425 if (UI->getParent() != CmpInstr.
getParent())
2434 if (!MI)
return false;
2443 if (I == B)
return false;
2458 if (CmpInstr.
getOpcode() == ARM::CMPri ||
2469 for (; I !=
E; --
I) {
2500 bool IsThumb1 =
false;
2551 case ARM::t2LSLrr: {
2560 bool isSafe =
false;
2563 while (!isSafe && ++I != E) {
2566 !isSafe && IO != EO; ++IO) {
2580 bool IsInstrVSel =
true;
2583 IsInstrVSel =
false;
2619 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
2654 if ((*SI)->isLiveIn(ARM::CPSR))
2670 for (
unsigned i = 0, e = OperandsToUpdate.
size();
i < e;
i++)
2671 OperandsToUpdate[
i].first->setImm(OperandsToUpdate[
i].second);
2684 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm)
2713 unsigned NewUseOpc = 0;
2715 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
2716 bool Commute =
false;
2718 default:
return false;
2726 case ARM::t2EORrr: {
2732 if (UseOpc == ARM::SUBrr && Commute)
2738 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::ADDri : ARM::SUBri;
2741 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::SUBri : ARM::ADDri;
2756 case ARM::ORRrr: NewUseOpc = ARM::ORRri;
break;
2757 case ARM::EORrr: NewUseOpc = ARM::EORri;
break;
2762 case ARM::t2SUBrr: {
2763 if (UseOpc == ARM::t2SUBrr && Commute)
2769 NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2ADDri : ARM::t2SUBri;
2772 NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2SUBri : ARM::t2ADDri;
2780 case ARM::t2EORrr: {
2787 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri;
break;
2788 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri;
break;
2796 unsigned OpIdx = Commute ? 2 : 1;
2802 get(NewUseOpc), NewReg)
2805 UseMI.
setDesc(
get(NewUseOpc));
2819 assert(UOps >= 0 &&
"bad # UOps");
2832 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2848 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2858 case ARM::LDRSB_POST:
2859 case ARM::LDRSH_POST: {
2862 return (Rt == Rm) ? 4 : 3;
2865 case ARM::LDR_PRE_REG:
2866 case ARM::LDRB_PRE_REG: {
2876 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2882 case ARM::STR_PRE_REG:
2883 case ARM::STRB_PRE_REG: {
2889 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2896 case ARM::STRH_PRE: {
2906 case ARM::LDR_POST_REG:
2907 case ARM::LDRB_POST_REG:
2908 case ARM::LDRH_POST: {
2911 return (Rt == Rm) ? 3 : 2;
2914 case ARM::LDR_PRE_IMM:
2915 case ARM::LDRB_PRE_IMM:
2916 case ARM::LDR_POST_IMM:
2917 case ARM::LDRB_POST_IMM:
2918 case ARM::STRB_POST_IMM:
2919 case ARM::STRB_POST_REG:
2920 case ARM::STRB_PRE_IMM:
2921 case ARM::STRH_POST:
2922 case ARM::STR_POST_IMM:
2923 case ARM::STR_POST_REG:
2924 case ARM::STR_PRE_IMM:
2927 case ARM::LDRSB_PRE:
2928 case ARM::LDRSH_PRE: {
2940 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2953 return (Rt == Rn) ? 3 : 2;
2964 case ARM::LDRD_POST:
2965 case ARM::t2LDRD_POST:
2968 case ARM::STRD_POST:
2969 case ARM::t2STRD_POST:
2972 case ARM::LDRD_PRE: {
2979 return (Rt == Rn) ? 4 : 3;
2982 case ARM::t2LDRD_PRE: {
2985 return (Rt == Rn) ? 4 : 3;
2988 case ARM::STRD_PRE: {
2996 case ARM::t2STRD_PRE:
2999 case ARM::t2LDR_POST:
3000 case ARM::t2LDRB_POST:
3001 case ARM::t2LDRB_PRE:
3002 case ARM::t2LDRSBi12:
3003 case ARM::t2LDRSBi8:
3004 case ARM::t2LDRSBpci:
3006 case ARM::t2LDRH_POST:
3007 case ARM::t2LDRH_PRE:
3009 case ARM::t2LDRSB_POST:
3010 case ARM::t2LDRSB_PRE:
3011 case ARM::t2LDRSH_POST:
3012 case ARM::t2LDRSH_PRE:
3013 case ARM::t2LDRSHi12:
3014 case ARM::t2LDRSHi8:
3015 case ARM::t2LDRSHpci:
3019 case ARM::t2LDRDi8: {
3022 return (Rt == Rn) ? 3 : 2;
3025 case ARM::t2STRB_POST:
3026 case ARM::t2STRB_PRE:
3029 case ARM::t2STRH_POST:
3030 case ARM::t2STRH_PRE:
3032 case ARM::t2STR_POST:
3033 case ARM::t2STR_PRE:
3066 Size += (*I)->getSize();
3073 unsigned UOps = 1 + NumRegs;
3077 case ARM::VLDMDIA_UPD:
3078 case ARM::VLDMDDB_UPD:
3079 case ARM::VLDMSIA_UPD:
3080 case ARM::VLDMSDB_UPD:
3081 case ARM::VSTMDIA_UPD:
3082 case ARM::VSTMDDB_UPD:
3083 case ARM::VSTMSIA_UPD:
3084 case ARM::VSTMSDB_UPD:
3085 case ARM::LDMIA_UPD:
3086 case ARM::LDMDA_UPD:
3087 case ARM::LDMDB_UPD:
3088 case ARM::LDMIB_UPD:
3089 case ARM::STMIA_UPD:
3090 case ARM::STMDA_UPD:
3091 case ARM::STMDB_UPD:
3092 case ARM::STMIB_UPD:
3093 case ARM::tLDMIA_UPD:
3094 case ARM::tSTMIA_UPD:
3095 case ARM::t2LDMIA_UPD:
3096 case ARM::t2LDMDB_UPD:
3097 case ARM::t2STMIA_UPD:
3098 case ARM::t2STMDB_UPD:
3101 case ARM::LDMIA_RET:
3103 case ARM::t2LDMIA_RET:
3112 if (!ItinData || ItinData->
isEmpty())
3118 if (ItinUOps >= 0) {
3144 case ARM::VLDMDIA_UPD:
3145 case ARM::VLDMDDB_UPD:
3147 case ARM::VLDMSIA_UPD:
3148 case ARM::VLDMSDB_UPD:
3150 case ARM::VSTMDIA_UPD:
3151 case ARM::VSTMDDB_UPD:
3153 case ARM::VSTMSIA_UPD:
3154 case ARM::VSTMSDB_UPD: {
3156 return (NumRegs / 2) + (NumRegs % 2) + 1;
3159 case ARM::LDMIA_RET:
3164 case ARM::LDMIA_UPD:
3165 case ARM::LDMDA_UPD:
3166 case ARM::LDMDB_UPD:
3167 case ARM::LDMIB_UPD:
3172 case ARM::STMIA_UPD:
3173 case ARM::STMDA_UPD:
3174 case ARM::STMDB_UPD:
3175 case ARM::STMIB_UPD:
3177 case ARM::tLDMIA_UPD:
3178 case ARM::tSTMIA_UPD:
3182 case ARM::t2LDMIA_RET:
3185 case ARM::t2LDMIA_UPD:
3186 case ARM::t2LDMDB_UPD:
3189 case ARM::t2STMIA_UPD:
3190 case ARM::t2STMDB_UPD: {
3203 unsigned UOps = (NumRegs / 2);
3209 unsigned UOps = (NumRegs / 2);
3227 unsigned DefIdx,
unsigned DefAlign)
const {
3236 DefCycle = RegNo / 2 + 1;
3241 bool isSLoad =
false;
3246 case ARM::VLDMSIA_UPD:
3247 case ARM::VLDMSDB_UPD:
3254 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
3258 DefCycle = RegNo + 2;
3268 unsigned DefIdx,
unsigned DefAlign)
const {
3278 DefCycle = RegNo / 2;
3284 DefCycle = (RegNo / 2);
3287 if ((RegNo % 2) || DefAlign < 8)
3293 DefCycle = RegNo + 2;
3303 unsigned UseIdx,
unsigned UseAlign)
const {
3311 UseCycle = RegNo / 2 + 1;
3316 bool isSStore =
false;
3321 case ARM::VSTMSIA_UPD:
3322 case ARM::VSTMSDB_UPD:
3329 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
3333 UseCycle = RegNo + 2;
3343 unsigned UseIdx,
unsigned UseAlign)
const {
3350 UseCycle = RegNo / 2;
3356 UseCycle = (RegNo / 2);
3359 if ((RegNo % 2) || UseAlign < 8)
3371 unsigned DefIdx,
unsigned DefAlign,
3373 unsigned UseIdx,
unsigned UseAlign)
const {
3384 bool LdmBypass =
false;
3391 case ARM::VLDMDIA_UPD:
3392 case ARM::VLDMDDB_UPD:
3394 case ARM::VLDMSIA_UPD:
3395 case ARM::VLDMSDB_UPD:
3396 DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3399 case ARM::LDMIA_RET:
3404 case ARM::LDMIA_UPD:
3405 case ARM::LDMDA_UPD:
3406 case ARM::LDMDB_UPD:
3407 case ARM::LDMIB_UPD:
3409 case ARM::tLDMIA_UPD:
3411 case ARM::t2LDMIA_RET:
3414 case ARM::t2LDMIA_UPD:
3415 case ARM::t2LDMDB_UPD:
3417 DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3432 case ARM::VSTMDIA_UPD:
3433 case ARM::VSTMDDB_UPD:
3435 case ARM::VSTMSIA_UPD:
3436 case ARM::VSTMSDB_UPD:
3437 UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3444 case ARM::STMIA_UPD:
3445 case ARM::STMDA_UPD:
3446 case ARM::STMDB_UPD:
3447 case ARM::STMIB_UPD:
3448 case ARM::tSTMIA_UPD:
3453 case ARM::t2STMIA_UPD:
3454 case ARM::t2STMDB_UPD:
3455 UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3463 UseCycle = DefCycle - UseCycle + 1;
3472 UseClass, UseIdx)) {
3482 unsigned &DefIdx,
unsigned &Dist) {
3487 assert(II->isInsideBundle() &&
"Empty bundle?");
3490 while (II->isInsideBundle()) {
3491 Idx = II->findRegisterDefOperandIdx(Reg,
false,
true, TRI);
3498 assert(Idx != -1 &&
"Cannot find bundled definition!");
3505 unsigned &UseIdx,
unsigned &Dist) {
3509 assert(II->isInsideBundle() &&
"Empty bundle?");
3514 while (II != E && II->isInsideBundle()) {
3515 Idx = II->findRegisterUseOperandIdx(Reg,
false, TRI);
3518 if (II->getOpcode() != ARM::t2IT)
3556 case ARM::t2LDRSHs: {
3559 if (ShAmt == 0 || ShAmt == 2)
3564 }
else if (Subtarget.
isSwift()) {
3576 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3587 case ARM::t2LDRSHs: {
3590 if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
3604 case ARM::VLD1q8wb_fixed:
3605 case ARM::VLD1q16wb_fixed:
3606 case ARM::VLD1q32wb_fixed:
3607 case ARM::VLD1q64wb_fixed:
3608 case ARM::VLD1q8wb_register:
3609 case ARM::VLD1q16wb_register:
3610 case ARM::VLD1q32wb_register:
3611 case ARM::VLD1q64wb_register:
3618 case ARM::VLD2d8wb_fixed:
3619 case ARM::VLD2d16wb_fixed:
3620 case ARM::VLD2d32wb_fixed:
3621 case ARM::VLD2q8wb_fixed:
3622 case ARM::VLD2q16wb_fixed:
3623 case ARM::VLD2q32wb_fixed:
3624 case ARM::VLD2d8wb_register:
3625 case ARM::VLD2d16wb_register:
3626 case ARM::VLD2d32wb_register:
3627 case ARM::VLD2q8wb_register:
3628 case ARM::VLD2q16wb_register:
3629 case ARM::VLD2q32wb_register:
3634 case ARM::VLD3d8_UPD:
3635 case ARM::VLD3d16_UPD:
3636 case ARM::VLD3d32_UPD:
3637 case ARM::VLD1d64Twb_fixed:
3638 case ARM::VLD1d64Twb_register:
3639 case ARM::VLD3q8_UPD:
3640 case ARM::VLD3q16_UPD:
3641 case ARM::VLD3q32_UPD:
3646 case ARM::VLD4d8_UPD:
3647 case ARM::VLD4d16_UPD:
3648 case ARM::VLD4d32_UPD:
3649 case ARM::VLD1d64Qwb_fixed:
3650 case ARM::VLD1d64Qwb_register:
3651 case ARM::VLD4q8_UPD:
3652 case ARM::VLD4q16_UPD:
3653 case ARM::VLD4q32_UPD:
3654 case ARM::VLD1DUPq8:
3655 case ARM::VLD1DUPq16:
3656 case ARM::VLD1DUPq32:
3657 case ARM::VLD1DUPq8wb_fixed:
3658 case ARM::VLD1DUPq16wb_fixed:
3659 case ARM::VLD1DUPq32wb_fixed:
3660 case ARM::VLD1DUPq8wb_register:
3661 case ARM::VLD1DUPq16wb_register:
3662 case ARM::VLD1DUPq32wb_register:
3663 case ARM::VLD2DUPd8:
3664 case ARM::VLD2DUPd16:
3665 case ARM::VLD2DUPd32:
3666 case ARM::VLD2DUPd8wb_fixed:
3667 case ARM::VLD2DUPd16wb_fixed:
3668 case ARM::VLD2DUPd32wb_fixed:
3669 case ARM::VLD2DUPd8wb_register:
3670 case ARM::VLD2DUPd16wb_register:
3671 case ARM::VLD2DUPd32wb_register:
3672 case ARM::VLD4DUPd8:
3673 case ARM::VLD4DUPd16:
3674 case ARM::VLD4DUPd32:
3675 case ARM::VLD4DUPd8_UPD:
3676 case ARM::VLD4DUPd16_UPD:
3677 case ARM::VLD4DUPd32_UPD:
3679 case ARM::VLD1LNd16:
3680 case ARM::VLD1LNd32:
3681 case ARM::VLD1LNd8_UPD:
3682 case ARM::VLD1LNd16_UPD:
3683 case ARM::VLD1LNd32_UPD:
3685 case ARM::VLD2LNd16:
3686 case ARM::VLD2LNd32:
3687 case ARM::VLD2LNq16:
3688 case ARM::VLD2LNq32:
3689 case ARM::VLD2LNd8_UPD:
3690 case ARM::VLD2LNd16_UPD:
3691 case ARM::VLD2LNd32_UPD:
3692 case ARM::VLD2LNq16_UPD:
3693 case ARM::VLD2LNq32_UPD:
3695 case ARM::VLD4LNd16:
3696 case ARM::VLD4LNd32:
3697 case ARM::VLD4LNq16:
3698 case ARM::VLD4LNq32:
3699 case ARM::VLD4LNd8_UPD:
3700 case ARM::VLD4LNd16_UPD:
3701 case ARM::VLD4LNd32_UPD:
3702 case ARM::VLD4LNq16_UPD:
3703 case ARM::VLD4LNq32_UPD:
3717 unsigned UseIdx)
const {
3719 if (!ItinData || ItinData->
isEmpty())
3726 unsigned DefAdj = 0;
3736 unsigned UseAdj = 0;
3744 return getOperandLatencyImpl(
3745 ItinData, *ResolvedDefMI, DefIdx, ResolvedDefMI->
getDesc(), DefAdj, DefMO,
3746 Reg, *ResolvedUseMI, UseIdx, ResolvedUseMI->getDesc(), UseAdj);
3749 int ARMBaseInstrInfo::getOperandLatencyImpl(
3751 unsigned DefIdx,
const MCInstrDesc &DefMCID,
unsigned DefAdj,
3753 unsigned UseIdx,
const MCInstrDesc &UseMCID,
unsigned UseAdj)
const {
3754 if (Reg == ARM::CPSR) {
3757 return Subtarget.
isLikeA9() ? 1 : 20;
3765 unsigned Latency = getInstrLatency(ItinData, DefMI);
3771 if (Latency > 0 && Subtarget.
isThumb2()) {
3798 int Adj = DefAdj + UseAdj;
3802 if (Adj >= 0 || (
int)Latency > -Adj) {
3803 return Latency + Adj;
3811 SDNode *DefNode,
unsigned DefIdx,
3812 SDNode *UseNode,
unsigned UseIdx)
const {
3818 if (isZeroCost(DefMCID.
Opcode))
3821 if (!ItinData || ItinData->
isEmpty())
3822 return DefMCID.
mayLoad() ? 3 : 1;
3828 return Latency <= Threshold ? 1 : Latency - Adj;
3839 UseMCID, UseIdx, UseAlign);
3851 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3861 case ARM::t2LDRSHs: {
3864 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3865 if (ShAmt == 0 || ShAmt == 2)
3870 }
else if (DefIdx == 0 && Latency > 2 && Subtarget.
isSwift()) {
3878 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
3881 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3891 case ARM::t2LDRSHs: {
3906 case ARM::VLD1q8wb_register:
3907 case ARM::VLD1q16wb_register:
3908 case ARM::VLD1q32wb_register:
3909 case ARM::VLD1q64wb_register:
3910 case ARM::VLD1q8wb_fixed:
3911 case ARM::VLD1q16wb_fixed:
3912 case ARM::VLD1q32wb_fixed:
3913 case ARM::VLD1q64wb_fixed:
3917 case ARM::VLD2q8Pseudo:
3918 case ARM::VLD2q16Pseudo:
3919 case ARM::VLD2q32Pseudo:
3920 case ARM::VLD2d8wb_fixed:
3921 case ARM::VLD2d16wb_fixed:
3922 case ARM::VLD2d32wb_fixed:
3923 case ARM::VLD2q8PseudoWB_fixed:
3924 case ARM::VLD2q16PseudoWB_fixed:
3925 case ARM::VLD2q32PseudoWB_fixed:
3926 case ARM::VLD2d8wb_register:
3927 case ARM::VLD2d16wb_register:
3928 case ARM::VLD2d32wb_register:
3929 case ARM::VLD2q8PseudoWB_register:
3930 case ARM::VLD2q16PseudoWB_register:
3931 case ARM::VLD2q32PseudoWB_register:
3932 case ARM::VLD3d8Pseudo:
3933 case ARM::VLD3d16Pseudo:
3934 case ARM::VLD3d32Pseudo:
3935 case ARM::VLD1d64TPseudo:
3936 case ARM::VLD1d64TPseudoWB_fixed:
3937 case ARM::VLD3d8Pseudo_UPD:
3938 case ARM::VLD3d16Pseudo_UPD:
3939 case ARM::VLD3d32Pseudo_UPD:
3940 case ARM::VLD3q8Pseudo_UPD:
3941 case ARM::VLD3q16Pseudo_UPD:
3942 case ARM::VLD3q32Pseudo_UPD:
3943 case ARM::VLD3q8oddPseudo:
3944 case ARM::VLD3q16oddPseudo:
3945 case ARM::VLD3q32oddPseudo:
3946 case ARM::VLD3q8oddPseudo_UPD:
3947 case ARM::VLD3q16oddPseudo_UPD:
3948 case ARM::VLD3q32oddPseudo_UPD:
3949 case ARM::VLD4d8Pseudo:
3950 case ARM::VLD4d16Pseudo:
3951 case ARM::VLD4d32Pseudo:
3952 case ARM::VLD1d64QPseudo:
3953 case ARM::VLD1d64QPseudoWB_fixed:
3954 case ARM::VLD4d8Pseudo_UPD:
3955 case ARM::VLD4d16Pseudo_UPD:
3956 case ARM::VLD4d32Pseudo_UPD:
3957 case ARM::VLD4q8Pseudo_UPD:
3958 case ARM::VLD4q16Pseudo_UPD:
3959 case ARM::VLD4q32Pseudo_UPD:
3960 case ARM::VLD4q8oddPseudo:
3961 case ARM::VLD4q16oddPseudo:
3962 case ARM::VLD4q32oddPseudo:
3963 case ARM::VLD4q8oddPseudo_UPD:
3964 case ARM::VLD4q16oddPseudo_UPD:
3965 case ARM::VLD4q32oddPseudo_UPD:
3966 case ARM::VLD1DUPq8:
3967 case ARM::VLD1DUPq16:
3968 case ARM::VLD1DUPq32:
3969 case ARM::VLD1DUPq8wb_fixed:
3970 case ARM::VLD1DUPq16wb_fixed:
3971 case ARM::VLD1DUPq32wb_fixed:
3972 case ARM::VLD1DUPq8wb_register:
3973 case ARM::VLD1DUPq16wb_register:
3974 case ARM::VLD1DUPq32wb_register:
3975 case ARM::VLD2DUPd8:
3976 case ARM::VLD2DUPd16:
3977 case ARM::VLD2DUPd32:
3978 case ARM::VLD2DUPd8wb_fixed:
3979 case ARM::VLD2DUPd16wb_fixed:
3980 case ARM::VLD2DUPd32wb_fixed:
3981 case ARM::VLD2DUPd8wb_register:
3982 case ARM::VLD2DUPd16wb_register:
3983 case ARM::VLD2DUPd32wb_register:
3984 case ARM::VLD4DUPd8Pseudo:
3985 case ARM::VLD4DUPd16Pseudo:
3986 case ARM::VLD4DUPd32Pseudo:
3987 case ARM::VLD4DUPd8Pseudo_UPD:
3988 case ARM::VLD4DUPd16Pseudo_UPD:
3989 case ARM::VLD4DUPd32Pseudo_UPD:
3990 case ARM::VLD1LNq8Pseudo:
3991 case ARM::VLD1LNq16Pseudo:
3992 case ARM::VLD1LNq32Pseudo:
3993 case ARM::VLD1LNq8Pseudo_UPD:
3994 case ARM::VLD1LNq16Pseudo_UPD:
3995 case ARM::VLD1LNq32Pseudo_UPD:
3996 case ARM::VLD2LNd8Pseudo:
3997 case ARM::VLD2LNd16Pseudo:
3998 case ARM::VLD2LNd32Pseudo:
3999 case ARM::VLD2LNq16Pseudo:
4000 case ARM::VLD2LNq32Pseudo:
4001 case ARM::VLD2LNd8Pseudo_UPD:
4002 case ARM::VLD2LNd16Pseudo_UPD:
4003 case ARM::VLD2LNd32Pseudo_UPD:
4004 case ARM::VLD2LNq16Pseudo_UPD:
4005 case ARM::VLD2LNq32Pseudo_UPD:
4006 case ARM::VLD4LNd8Pseudo:
4007 case ARM::VLD4LNd16Pseudo:
4008 case ARM::VLD4LNd32Pseudo:
4009 case ARM::VLD4LNq16Pseudo:
4010 case ARM::VLD4LNq32Pseudo:
4011 case ARM::VLD4LNd8Pseudo_UPD:
4012 case ARM::VLD4LNd16Pseudo_UPD:
4013 case ARM::VLD4LNd32Pseudo_UPD:
4014 case ARM::VLD4LNq16Pseudo_UPD:
4015 case ARM::VLD4LNq32Pseudo_UPD:
4025 unsigned ARMBaseInstrInfo::getPredicationCost(
const MachineInstr &MI)
const {
4045 unsigned *PredCost)
const {
4053 unsigned Latency = 0;
4056 while (++I != E && I->isInsideBundle()) {
4057 if (I->getOpcode() != ARM::t2IT)
4058 Latency += getInstrLatency(ItinData, *I, PredCost);
4087 if (Adj >= 0 || (
int)Latency > -Adj) {
4088 return Latency + Adj;
4098 if (!ItinData || ItinData->
isEmpty())
4111 bool ARMBaseInstrInfo::hasHighOperandLatency(
const TargetSchedModel &SchedModel,
4116 unsigned UseIdx)
const {
4132 bool ARMBaseInstrInfo::hasLowDefLatency(
const TargetSchedModel &SchedModel,
4134 unsigned DefIdx)
const {
4136 if (!ItinData || ItinData->
isEmpty())
4143 return (DefCycle != -1 && DefCycle <= 2);
4148 bool ARMBaseInstrInfo::verifyInstruction(
const MachineInstr &MI,
4151 ErrInfo =
"Pseudo flag setting opcodes only exist in Selection DAG";
4160 unsigned LoadImmOpc,
4161 unsigned LoadOpc)
const {
4163 "ROPI/RWPI not currently supported with stack guard");
4167 unsigned Reg = MI->getOperand(0).getReg();
4169 cast<GlobalValue>((*MI->memoperands_begin())->getValue());
4172 BuildMI(MBB, MI, DL,
get(LoadImmOpc), Reg)
4176 MIB =
BuildMI(MBB, MI, DL,
get(LoadOpc), Reg);
4183 MIB.addMemOperand(MMO);
4187 MIB =
BuildMI(MBB, MI, DL,
get(LoadOpc), Reg);
4189 MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
4195 unsigned &AddSubOpc,
4196 bool &NegAcc,
bool &HasLane)
const {
4198 if (I == MLxEntryMap.
end())
4228 std::pair<uint16_t, uint16_t>
4249 return std::make_pair(
ExeNEON, 0);
4254 return std::make_pair(
ExeNEON, 0);
4257 return std::make_pair(
ExeVFP, 0);
4263 unsigned SReg,
unsigned &Lane) {
4267 if (DReg != ARM::NoRegister)
4273 assert(DReg &&
"S-register with no D super-register?");
4294 unsigned Lane,
unsigned &ImplicitSReg) {
4304 (Lane & 1) ? ARM::ssub_0 : ARM::ssub_1);
4320 unsigned Domain)
const {
4321 unsigned DstReg, SrcReg, DReg;
4368 MI.
setDesc(
get(ARM::VGETLNi32));
4388 unsigned ImplicitSReg;
4397 MI.
setDesc(
get(ARM::VSETLNi32));
4407 if (ImplicitSReg != 0)
4419 unsigned DstLane = 0, SrcLane = 0, DDst, DSrc;
4423 unsigned ImplicitSReg;
4433 MI.
setDesc(
get(ARM::VDUPLN32d));
4443 if (ImplicitSReg != 0)
4467 unsigned CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst;
4471 CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst;
4478 if (SrcLane == DstLane)
4481 MI.
setDesc(
get(ARM::VEXTd32));
4486 CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst;
4487 CurUndef = CurReg == DSrc && !MI.
readsRegister(CurReg, TRI);
4490 CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst;
4491 CurUndef = CurReg == DSrc && !MI.
readsRegister(CurReg, TRI);
4497 if (SrcLane != DstLane)
4503 if (ImplicitSReg != 0)
4531 if (!PartialUpdateClearance)
4534 assert(TRI &&
"Need TRI instance");
4539 unsigned Reg = MO.
getReg();
4548 case ARM::VMOVv4i16:
4549 case ARM::VMOVv2i32:
4550 case ARM::VMOVv2f32:
4551 case ARM::VMOVv1i64:
4556 case ARM::VLD1LNd32:
4573 }
else if (ARM::SPRRegClass.
contains(Reg)) {
4583 return PartialUpdateClearance;
4591 assert(TRI &&
"Need TRI instance");
4594 unsigned Reg = MO.
getReg();
4596 "Can't break virtual register dependencies.");
4597 unsigned DReg =
Reg;
4600 if (ARM::SPRRegClass.
contains(Reg)) {
4601 DReg = ARM::D0 + (Reg - ARM::S0) / 2;
4605 assert(ARM::DPRRegClass.
contains(DReg) &&
"Can only break D-reg deps");
4623 return Subtarget.getFeatureBits()[ARM::HasV6KOps];
4633 ((ShImm == 1 || ShImm == 2) &&
4655 RegSubRegPairAndIdx(MOReg->
getReg(), MOReg->
getSubReg(), ARM::ssub_0));
4659 RegSubRegPairAndIdx(MOReg->
getReg(), MOReg->
getSubReg(), ARM::ssub_1));
4667 RegSubRegPairAndIdx &InputReg)
const {
4680 InputReg.SubIdx = DefIdx == 0 ? ARM::ssub_0 : ARM::ssub_1;
4687 const MachineInstr &MI,
unsigned DefIdx, RegSubRegPair &BaseReg,
4688 RegSubRegPairAndIdx &InsertedReg)
const {
4693 case ARM::VSETLNi32:
4701 InsertedReg.Reg = MOInsertedReg.
getReg();
4702 InsertedReg.SubReg = MOInsertedReg.
getSubReg();
4703 InsertedReg.SubIdx = MOIndex.
getImm() == 0 ? ARM::ssub_0 : ARM::ssub_1;
MachineConstantPoolValue * MachineCPVal
bool isPredicable(MachineInstr &MI) const override
isPredicable - Return true if the specified instruction can be predicated.
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
virtual MachineInstr * duplicate(MachineInstr &Orig, MachineFunction &MF) const
Create a duplicate of the Orig instruction in MF.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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.
const GlobalValue * getGlobal() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
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.
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
unsigned getMispredictionPenalty() const
unsigned getRegister(unsigned i) const
Return the specified register in the class.
bool DefinesPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred) const override
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...
int getNumMicroOps(unsigned ItinClassIndx) const
Return the number of micro-ops that the given class decodes to.
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)
unsigned getPartialUpdateClearance() const
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.
bool expandPostRAPseudo(MachineInstr &MI) const override
void setIsUndef(bool Val=true)
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg, int CmpMask, bool CommonUse)
isSuitableForMask - Identify a suitable 'and' instruction that operates on the given source register ...
bool isPredicated(const MachineInstr &MI) const override
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...
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...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this 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
unsigned getPartialRegUpdateClearance(const MachineInstr &, unsigned, const TargetRegisterInfo *) 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...
bool checkVLDnAccessAlignment() const
bool isThumb1Only() const
iterator_range< mop_iterator > operands()
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
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 unsigned getSOImmValRotate(unsigned Imm)
getSOImmValRotate - Try to handle Imm with an immediate shifter operand, computing the rotate amount ...
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
return AArch64::GPR64RegClass contains(Reg)
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.
const ARMBaseInstrInfo * getInstrInfo() const override
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
bool removeKill(MachineInstr &MI)
removeKill - Delete a kill corresponding to the specified machine instruction.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void clearKillInfo()
Clears kill flags on all operands.
Can load/store 1 register/cycle.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
unsigned getSize() const
Return the size of the register in bytes, which is also the size of a stack slot allocated to hold a ...
int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
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 ...
struct fuzzer::@269 Flags
Provide an instruction scheduling machine model to CodeGen passes.
const HexagonInstrInfo * TII
const TargetRegisterInfo * getTargetRegisterInfo() const
bool useNEONForFPMovs() 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.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
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 reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
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
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
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override
The memory access is dereferenceable (i.e., doesn't trap).
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...
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
INLINEASM - Represents an inline asm block.
LLVM_NODISCARD bool empty() const
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 PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
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 unsigned getAlignment(GlobalVariable *GV)
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.
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
Can load/store 2 registers/cycle, but needs an extra cycle if the access is not 64-bit aligned...
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
unsigned getNumMicroOps(const InstrItineraryData *ItinData, const MachineInstr &MI) const override
bool isV8EligibleForIT(InstrType *Instr)
bool isCopyLike() const
Return true if the instruction behaves like a copy.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Itinerary data supplied by a subtarget to be used by a target.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
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.
struct llvm::MachineOperand::@38::@39 Reg
bool dontWidenVMOVS() const
unsigned getUndefRegState(bool B)
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
Return a null-terminated list of all of the callee-saved registers on this target.
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.
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
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.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
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...
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
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
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs)
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
unsigned const MachineRegisterInfo * MRI
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
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
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...
MachineInstrBuilder & UseMI
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 ...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
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...
unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) 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 getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Returns the size of the specified MachineInstr.
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
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 fully dead.
static const MachineInstr * getBundledUseMI(const TargetRegisterInfo *TRI, const MachineInstr &MI, unsigned Reg, unsigned &UseIdx, unsigned &Dist)
bool isIdenticalTo(const MachineInstr &Other, MICheckType Check=CheckDefs) const
Return true if this instruction is identical to Other.
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.
MachineInstr * duplicate(MachineInstr &Orig, MachineFunction &MF) const override
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.
self_iterator getIterator()
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.
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()
Register is known to be (at least partially) live.
succ_iterator succ_begin()
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const 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 getSubReg() const
VarInfo & getVarInfo(unsigned RegIdx)
getVarInfo - Return the VarInfo structure for the specified VIRTUAL register.
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition, otherwise returns AL.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
static const MachineInstr * getBundledDefMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &DefIdx, unsigned &Dist)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ARMLdStMultipleTiming getLdStMultipleTiming() const
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
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.
The memory access writes data.
std::pair< uint16_t, uint16_t > getExecutionDomain(const MachineInstr &MI) const override
VFP/NEON execution domains.
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)
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const override
Iterator for intrusive lists based on ilist_node.
static bool isUncondBranchOpcode(int Opc)
virtual unsigned getUnindexedOpcode(unsigned Opc) const =0
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
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...
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
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.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Map pseudo instructions that imply an 'S' bit onto real opcodes.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
void breakPartialRegDependency(MachineInstr &, unsigned, const TargetRegisterInfo *TRI) const override
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.
instr_iterator getInstrIterator() const
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
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
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
unsigned getNumLDMAddresses(const MachineInstr &MI) const
Get the number of addresses by LDM or VLDM or zero for unknown.
AddrMode
ARM Addressing Modes.
static AddrOpc getAM3Op(unsigned AM3Opc)
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.
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.
The memory access reads data.
TargetSubtargetInfo - Generic base class for all target subtargets.
bool nonpipelinedVFP() const
static bool isPopOpcode(int Opc)
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData, const MachineInstr &MI)
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).
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...
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
static CondCodes getOppositeCondition(CondCodes CC)
static const AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[]
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
unsigned getSchedClass() const
Return the scheduling class for this instruction.
void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr &MI, bool AddIfNotFound=false)
addVirtualRegisterDead - Add information about the fact that the specified register is dead after bei...
uint64_t scale(uint64_t Num) const
Scale a large integer.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
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...
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
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
int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool isCall(QueryType Type=AnyInBundle) const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
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.
The memory access always returns the same value (or traps).
iterator find(const KeyT &Val)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isProfitableToUnpredicate() const
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...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
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.
unsigned isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
int getPreISelOperandLatencyAdjustment() const
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...
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
virtual const ARMBaseRegisterInfo & getRegisterInfo() const =0
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
static unsigned getSORegOffset(unsigned Op)
Can load/store 1 register/cycle, but needs an extra cycle for address computation and potentially als...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
static use_instr_iterator use_instr_end()
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
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
Can load/store 2 registers/cycle.
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
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...
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.
union llvm::MachineConstantPoolEntry::@35 Val
The constant itself.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
bool isRegSequence() const
bool isThumb2Function() const
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 bool isT2SOImmTwoPartVal(unsigned Imm)
static unsigned getNumMicroOpsSingleIssuePlusExtras(unsigned Opc, unsigned NumRegs)
bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1, const MachineRegisterInfo *MRI) const override
static unsigned getSOImmTwoPartFirst(unsigned V)
getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it...
MachineInstr * convertToThreeAddress(MachineFunction::iterator &MFI, MachineInstr &MI, LiveVariables *LV) 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
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...
void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr &MI, bool AddIfNotFound=false)
addVirtualRegisterKilled - Add information about the fact that the specified register is killed after...
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
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
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.
BranchProbability getCompl() const
static bool isCPSRDefined(const MachineInstr *MI)
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
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.