53 #define GET_INSTRINFO_CTOR_DTOR 54 #include "AArch64GenInstrInfo.inc" 58 cl::desc(
"Restrict range of TB[N]Z instructions (DEBUG)"));
62 cl::desc(
"Restrict range of CB[N]Z instructions (DEBUG)"));
66 cl::desc(
"Restrict range of Bcc instructions (DEBUG)"));
71 RI(STI.getTargetTriple()), Subtarget(STI) {}
85 unsigned NumBytes = 0;
92 case TargetOpcode::DBG_VALUE:
94 case TargetOpcode::IMPLICIT_DEF:
98 case TargetOpcode::STACKMAP:
101 assert(NumBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
103 case TargetOpcode::PATCHPOINT:
106 assert(NumBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
112 case AArch64::JumpTableDest32:
113 case AArch64::JumpTableDest16:
114 case AArch64::JumpTableDest8:
178 int64_t BrOffset)
const {
180 assert(Bits >= 3 &&
"max branch displacement must be enough to jump" 181 "over conditional branch expansion");
182 return isIntN(Bits, BrOffset / 4);
211 bool AllowModify)
const {
217 if (!isUnpredicatedTerminator(*I))
224 unsigned LastOpc = LastInst->
getOpcode();
225 if (I == MBB.
begin() || !isUnpredicatedTerminator(*--I)) {
240 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
247 LastInst = SecondLastInst;
249 if (I == MBB.
begin() || !isUnpredicatedTerminator(*--I)) {
254 SecondLastInst = &*
I;
255 SecondLastOpc = SecondLastInst->
getOpcode();
261 if (SecondLastInst && I != MBB.
begin() && isUnpredicatedTerminator(*--I))
277 I->eraseFromParent();
286 I->eraseFromParent();
296 if (Cond[0].getImm() != -1) {
302 switch (Cond[1].getImm()) {
306 Cond[1].setImm(AArch64::CBNZW);
309 Cond[1].setImm(AArch64::CBZW);
312 Cond[1].setImm(AArch64::CBNZX);
315 Cond[1].setImm(AArch64::CBZX);
318 Cond[1].setImm(AArch64::TBNZW);
321 Cond[1].setImm(AArch64::TBZW);
324 Cond[1].setImm(AArch64::TBNZX);
327 Cond[1].setImm(AArch64::TBZX);
336 int *BytesRemoved)
const {
346 I->eraseFromParent();
350 if (I == MBB.
begin()) {
363 I->eraseFromParent();
370 void AArch64InstrInfo::instantiateCondBranch(
373 if (Cond[0].getImm() != -1) {
380 BuildMI(&MBB, DL,
get(Cond[1].getImm())).
add(Cond[2]);
382 MIB.
addImm(Cond[3].getImm());
391 assert(TBB &&
"insertBranch must not be told to insert a fallthrough");
397 instantiateCondBranch(MBB, DL, TBB, Cond);
406 instantiateCondBranch(MBB, DL, TBB, Cond);
430 unsigned *NewVReg =
nullptr) {
435 bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.
getRegClass(VReg));
438 unsigned SrcOpNum = 0;
440 case AArch64::ADDSXri:
441 case AArch64::ADDSWri:
447 case AArch64::ADDXri:
448 case AArch64::ADDWri:
454 Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr;
457 case AArch64::ORNXrr:
458 case AArch64::ORNWrr: {
461 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
464 Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr;
468 case AArch64::SUBSXrr:
469 case AArch64::SUBSWrr:
475 case AArch64::SUBXrr:
476 case AArch64::SUBWrr: {
479 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
482 Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr;
488 assert(Opc && SrcOpNum &&
"Missing parameters");
497 unsigned TrueReg,
unsigned FalseReg,
498 int &CondCycles,
int &TrueCycles,
499 int &FalseCycles)
const {
508 unsigned ExtraCondLat = Cond.
size() != 1;
512 if (AArch64::GPR64allRegClass.hasSubClassEq(RC) ||
513 AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
515 CondCycles = 1 + ExtraCondLat;
516 TrueCycles = FalseCycles = 1;
526 if (AArch64::FPR64RegClass.hasSubClassEq(RC) ||
527 AArch64::FPR32RegClass.hasSubClassEq(RC)) {
528 CondCycles = 5 + ExtraCondLat;
529 TrueCycles = FalseCycles = 2;
539 const DebugLoc &DL,
unsigned DstReg,
541 unsigned TrueReg,
unsigned FalseReg)
const {
546 switch (Cond.
size()) {
555 switch (Cond[1].getImm()) {
575 unsigned SrcReg = Cond[2].getReg();
579 BuildMI(MBB, I, DL,
get(AArch64::SUBSXri), AArch64::XZR)
585 BuildMI(MBB, I, DL,
get(AArch64::SUBSWri), AArch64::WZR)
594 switch (Cond[1].getImm()) {
607 if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW)
608 BuildMI(MBB, I, DL,
get(AArch64::ANDSWri), AArch64::WZR)
613 BuildMI(MBB, I, DL,
get(AArch64::ANDSXri), AArch64::XZR)
623 bool TryFold =
false;
625 RC = &AArch64::GPR64RegClass;
626 Opc = AArch64::CSELXr;
629 RC = &AArch64::GPR32RegClass;
630 Opc = AArch64::CSELWr;
633 RC = &AArch64::FPR64RegClass;
634 Opc = AArch64::FCSELDrrr;
636 RC = &AArch64::FPR32RegClass;
637 Opc = AArch64::FCSELSrrr;
639 assert(RC &&
"Unsupported regclass");
643 unsigned NewVReg = 0;
667 BuildMI(MBB, I, DL,
get(Opc), DstReg)
676 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize);
692 if (Opcode == AArch64::FMOVH0 ||
693 Opcode == AArch64::FMOVS0 ||
694 Opcode == AArch64::FMOVD0)
699 if (Opcode == TargetOpcode::COPY &&
708 if (isExynosCheapAsMove(MI))
721 case AArch64::ADDWri:
722 case AArch64::ADDXri:
723 case AArch64::SUBWri:
724 case AArch64::SUBXri:
728 case AArch64::ANDWri:
729 case AArch64::ANDXri:
730 case AArch64::EORWri:
731 case AArch64::EORXri:
732 case AArch64::ORRWri:
733 case AArch64::ORRXri:
737 case AArch64::ANDWrr:
738 case AArch64::ANDXrr:
739 case AArch64::BICWrr:
740 case AArch64::BICXrr:
741 case AArch64::EONWrr:
742 case AArch64::EONXrr:
743 case AArch64::EORWrr:
744 case AArch64::EORXrr:
745 case AArch64::ORNWrr:
746 case AArch64::ORNXrr:
747 case AArch64::ORRWrr:
748 case AArch64::ORRXrr:
753 case AArch64::MOVi32imm:
755 case AArch64::MOVi64imm:
767 case AArch64::ADDWrs:
768 case AArch64::ADDXrs:
769 case AArch64::ADDSWrs:
770 case AArch64::ADDSXrs: {
778 case AArch64::ADDWrx:
779 case AArch64::ADDXrx:
780 case AArch64::ADDXrx64:
781 case AArch64::ADDSWrx:
782 case AArch64::ADDSXrx:
783 case AArch64::ADDSXrx64: {
796 case AArch64::SUBWrs:
797 case AArch64::SUBSWrs: {
800 return ShiftVal == 0 ||
804 case AArch64::SUBXrs:
805 case AArch64::SUBSXrs: {
808 return ShiftVal == 0 ||
812 case AArch64::SUBWrx:
813 case AArch64::SUBXrx:
814 case AArch64::SUBXrx64:
815 case AArch64::SUBSWrx:
816 case AArch64::SUBSXrx:
817 case AArch64::SUBSXrx64: {
830 case AArch64::LDRBBroW:
831 case AArch64::LDRBBroX:
832 case AArch64::LDRBroW:
833 case AArch64::LDRBroX:
834 case AArch64::LDRDroW:
835 case AArch64::LDRDroX:
836 case AArch64::LDRHHroW:
837 case AArch64::LDRHHroX:
838 case AArch64::LDRHroW:
839 case AArch64::LDRHroX:
840 case AArch64::LDRQroW:
841 case AArch64::LDRQroX:
842 case AArch64::LDRSBWroW:
843 case AArch64::LDRSBWroX:
844 case AArch64::LDRSBXroW:
845 case AArch64::LDRSBXroX:
846 case AArch64::LDRSHWroW:
847 case AArch64::LDRSHWroX:
848 case AArch64::LDRSHXroW:
849 case AArch64::LDRSHXroX:
850 case AArch64::LDRSWroW:
851 case AArch64::LDRSWroX:
852 case AArch64::LDRSroW:
853 case AArch64::LDRSroX:
854 case AArch64::LDRWroW:
855 case AArch64::LDRWroX:
856 case AArch64::LDRXroW:
857 case AArch64::LDRXroX:
858 case AArch64::PRFMroW:
859 case AArch64::PRFMroX:
860 case AArch64::STRBBroW:
861 case AArch64::STRBBroX:
862 case AArch64::STRBroW:
863 case AArch64::STRBroX:
864 case AArch64::STRDroW:
865 case AArch64::STRDroX:
866 case AArch64::STRHHroW:
867 case AArch64::STRHHroX:
868 case AArch64::STRHroW:
869 case AArch64::STRHroX:
870 case AArch64::STRQroW:
871 case AArch64::STRQroX:
872 case AArch64::STRSroW:
873 case AArch64::STRSroX:
874 case AArch64::STRWroW:
875 case AArch64::STRWroX:
876 case AArch64::STRXroW:
877 case AArch64::STRXroX: {
889 case AArch64::SEH_StackAlloc:
890 case AArch64::SEH_SaveFPLR:
891 case AArch64::SEH_SaveFPLR_X:
892 case AArch64::SEH_SaveReg:
893 case AArch64::SEH_SaveReg_X:
894 case AArch64::SEH_SaveRegP:
895 case AArch64::SEH_SaveRegP_X:
896 case AArch64::SEH_SaveFReg:
897 case AArch64::SEH_SaveFReg_X:
898 case AArch64::SEH_SaveFRegP:
899 case AArch64::SEH_SaveFRegP_X:
900 case AArch64::SEH_SetFP:
901 case AArch64::SEH_AddFP:
902 case AArch64::SEH_Nop:
903 case AArch64::SEH_PrologEnd:
904 case AArch64::SEH_EpilogStart:
905 case AArch64::SEH_EpilogEnd:
911 unsigned &SrcReg,
unsigned &DstReg,
912 unsigned &SubIdx)
const {
916 case AArch64::SBFMXri:
917 case AArch64::UBFMXri:
925 SubIdx = AArch64::sub_32;
934 int64_t OffsetA = 0, OffsetB = 0;
935 unsigned WidthA = 0, WidthB = 0;
952 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
953 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
954 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
955 if (LowOffset + LowWidth <= HighOffset)
986 unsigned &SrcReg2,
int &CmpMask,
987 int &CmpValue)
const {
997 case AArch64::SUBSWrr:
998 case AArch64::SUBSWrs:
999 case AArch64::SUBSWrx:
1000 case AArch64::SUBSXrr:
1001 case AArch64::SUBSXrs:
1002 case AArch64::SUBSXrx:
1003 case AArch64::ADDSWrr:
1004 case AArch64::ADDSWrs:
1005 case AArch64::ADDSWrx:
1006 case AArch64::ADDSXrr:
1007 case AArch64::ADDSXrs:
1008 case AArch64::ADDSXrx:
1015 case AArch64::SUBSWri:
1016 case AArch64::ADDSWri:
1017 case AArch64::SUBSXri:
1018 case AArch64::ADDSXri:
1025 case AArch64::ANDSWri:
1026 case AArch64::ANDSXri:
1039 MI.
getOpcode() == AArch64::ANDSWri ? 32 : 64) != 0;
1048 assert(MBB &&
"Can't get MachineBasicBlock here");
1050 assert(MF &&
"Can't get MachineFunction here");
1055 for (
unsigned OpIdx = 0, EndIdx = Instr.
getNumOperands(); OpIdx < EndIdx;
1062 if (!OpRegCstraints)
1070 "Operand has register constraints without being a register!");
1074 if (!OpRegCstraints->
contains(Reg))
1090 bool MIDefinesZeroReg =
false;
1092 MIDefinesZeroReg =
true;
1097 case AArch64::ADDSWrr:
1098 return AArch64::ADDWrr;
1099 case AArch64::ADDSWri:
1100 return MIDefinesZeroReg ? AArch64::ADDSWri : AArch64::ADDWri;
1101 case AArch64::ADDSWrs:
1102 return MIDefinesZeroReg ? AArch64::ADDSWrs : AArch64::ADDWrs;
1103 case AArch64::ADDSWrx:
1104 return AArch64::ADDWrx;
1105 case AArch64::ADDSXrr:
1106 return AArch64::ADDXrr;
1107 case AArch64::ADDSXri:
1108 return MIDefinesZeroReg ? AArch64::ADDSXri : AArch64::ADDXri;
1109 case AArch64::ADDSXrs:
1110 return MIDefinesZeroReg ? AArch64::ADDSXrs : AArch64::ADDXrs;
1111 case AArch64::ADDSXrx:
1112 return AArch64::ADDXrx;
1113 case AArch64::SUBSWrr:
1114 return AArch64::SUBWrr;
1115 case AArch64::SUBSWri:
1116 return MIDefinesZeroReg ? AArch64::SUBSWri : AArch64::SUBWri;
1117 case AArch64::SUBSWrs:
1118 return MIDefinesZeroReg ? AArch64::SUBSWrs : AArch64::SUBWrs;
1119 case AArch64::SUBSWrx:
1120 return AArch64::SUBWrx;
1121 case AArch64::SUBSXrr:
1122 return AArch64::SUBXrr;
1123 case AArch64::SUBSXri:
1124 return MIDefinesZeroReg ? AArch64::SUBSXri : AArch64::SUBXri;
1125 case AArch64::SUBSXrs:
1126 return MIDefinesZeroReg ? AArch64::SUBSXrs : AArch64::SUBXrs;
1127 case AArch64::SUBSXrx:
1128 return AArch64::SUBXrx;
1143 if (To == To->getParent()->begin())
1148 if (To->getParent() != From->getParent())
1154 return MI.getIterator() ==
From;
1155 }) != To->getParent()->rend());
1158 for (--To; To !=
From; --To) {
1181 MachineInstr &CmpInstr,
unsigned SrcReg,
unsigned SrcReg2,
int CmpMask,
1188 if (DeadNZCVIdx != -1) {
1203 assert(succeeded &&
"Some operands reg class are incompatible!");
1210 assert((CmpValue == 0 || CmpValue == 1) &&
"CmpValue must be 0 or 1!");
1211 if (CmpValue != 0 || SrcReg2 != 0)
1218 return substituteCmpToZero(CmpInstr, SrcReg, MRI);
1228 return AArch64::INSTRUCTION_LIST_END;
1230 case AArch64::ADDSWrr:
1231 case AArch64::ADDSWri:
1232 case AArch64::ADDSXrr:
1233 case AArch64::ADDSXri:
1234 case AArch64::SUBSWrr:
1235 case AArch64::SUBSWri:
1236 case AArch64::SUBSXrr:
1237 case AArch64::SUBSXri:
1240 case AArch64::ADDWrr:
1241 return AArch64::ADDSWrr;
1242 case AArch64::ADDWri:
1243 return AArch64::ADDSWri;
1244 case AArch64::ADDXrr:
1245 return AArch64::ADDSXrr;
1246 case AArch64::ADDXri:
1247 return AArch64::ADDSXri;
1248 case AArch64::ADCWr:
1249 return AArch64::ADCSWr;
1250 case AArch64::ADCXr:
1251 return AArch64::ADCSXr;
1252 case AArch64::SUBWrr:
1253 return AArch64::SUBSWrr;
1254 case AArch64::SUBWri:
1255 return AArch64::SUBSWri;
1256 case AArch64::SUBXrr:
1257 return AArch64::SUBSXrr;
1258 case AArch64::SUBXri:
1259 return AArch64::SUBSXri;
1260 case AArch64::SBCWr:
1261 return AArch64::SBCSWr;
1262 case AArch64::SBCXr:
1263 return AArch64::SBCSXr;
1264 case AArch64::ANDWri:
1265 return AArch64::ANDSWri;
1266 case AArch64::ANDXri:
1267 return AArch64::ANDSXri;
1274 if (BB->isLiveIn(AArch64::NZCV))
1287 UsedNZCV() =
default;
1289 UsedNZCV &
operator|=(
const UsedNZCV &UsedFlags) {
1290 this->N |= UsedFlags.N;
1291 this->Z |= UsedFlags.Z;
1292 this->C |= UsedFlags.C;
1293 this->V |= UsedFlags.V;
1308 case AArch64::Bcc: {
1314 case AArch64::CSINVWr:
1315 case AArch64::CSINVXr:
1316 case AArch64::CSINCWr:
1317 case AArch64::CSINCXr:
1318 case AArch64::CSELWr:
1319 case AArch64::CSELXr:
1320 case AArch64::CSNEGWr:
1321 case AArch64::CSNEGXr:
1322 case AArch64::FCSELSrrr:
1323 case AArch64::FCSELDrrr: {
1376 return Opcode == AArch64::ADDSWri || Opcode == AArch64::ADDSXri;
1380 return Opcode == AArch64::SUBSWri || Opcode == AArch64::SUBSXri;
1397 assert(
sForm(*MI) != AArch64::INSTRUCTION_LIST_END);
1400 const unsigned CmpOpcode = CmpInstr->
getOpcode();
1416 UsedNZCV NZCVUsedAfterCmp;
1432 return !NZCVUsedAfterCmp.C && !NZCVUsedAfterCmp.V;
1439 bool AArch64InstrInfo::substituteCmpToZero(
1450 unsigned NewOpc =
sForm(*MI);
1451 if (NewOpc == AArch64::INSTRUCTION_LIST_END)
1462 assert(succeeded &&
"Some operands reg class are incompatible!");
1468 if (MI.
getOpcode() != TargetOpcode::LOAD_STACK_GUARD &&
1483 FirstEpilogSEH != MBB.
begin())
1484 FirstEpilogSEH = std::prev(FirstEpilogSEH);
1485 if (FirstEpilogSEH != MBB.
begin())
1486 FirstEpilogSEH = std::next(FirstEpilogSEH);
1490 BuildMI(MBB, FirstEpilogSEH, DL, TII->
get(AArch64::ADDXri))
1502 unsigned char OpFlags = Subtarget.ClassifyGlobalReference(GV, TM);
1508 BuildMI(MBB, MI, DL,
get(AArch64::LDRXui), Reg)
1513 BuildMI(MBB, MI, DL,
get(AArch64::MOVZXi), Reg)
1516 BuildMI(MBB, MI, DL,
get(AArch64::MOVKXi), Reg)
1520 BuildMI(MBB, MI, DL,
get(AArch64::MOVKXi), Reg)
1524 BuildMI(MBB, MI, DL,
get(AArch64::MOVKXi), Reg)
1528 BuildMI(MBB, MI, DL,
get(AArch64::LDRXui), Reg)
1539 BuildMI(MBB, MI, DL,
get(AArch64::LDRXui), Reg)
1556 case AArch64::MOVZWi:
1557 case AArch64::MOVZXi:
1564 case AArch64::ANDWri:
1566 case AArch64::ANDXri:
1568 case TargetOpcode::COPY:
1580 case TargetOpcode::COPY: {
1583 return (AArch64::GPR32RegClass.
contains(DstReg) ||
1584 AArch64::GPR64RegClass.
contains(DstReg));
1586 case AArch64::ORRXrs:
1593 case AArch64::ADDXri:
1610 case TargetOpcode::COPY: {
1613 return (AArch64::FPR64RegClass.
contains(DstReg) ||
1614 AArch64::FPR128RegClass.
contains(DstReg));
1616 case AArch64::ORRv16i8:
1619 "invalid ORRv16i8 operands");
1632 case AArch64::LDRWui:
1633 case AArch64::LDRXui:
1634 case AArch64::LDRBui:
1635 case AArch64::LDRHui:
1636 case AArch64::LDRSui:
1637 case AArch64::LDRDui:
1638 case AArch64::LDRQui:
1655 case AArch64::STRWui:
1656 case AArch64::STRXui:
1657 case AArch64::STRBui:
1658 case AArch64::STRHui:
1659 case AArch64::STRSui:
1660 case AArch64::STRDui:
1661 case AArch64::STRQui:
1697 case AArch64::STURSi:
1698 case AArch64::STURDi:
1699 case AArch64::STURQi:
1700 case AArch64::STURBBi:
1701 case AArch64::STURHHi:
1702 case AArch64::STURWi:
1703 case AArch64::STURXi:
1704 case AArch64::LDURSi:
1705 case AArch64::LDURDi:
1706 case AArch64::LDURQi:
1707 case AArch64::LDURWi:
1708 case AArch64::LDURXi:
1709 case AArch64::LDURSWi:
1710 case AArch64::LDURHHi:
1711 case AArch64::LDURBBi:
1712 case AArch64::LDURSBWi:
1713 case AArch64::LDURSHWi:
1723 case AArch64::STRSui:
1724 case AArch64::STRDui:
1725 case AArch64::STRQui:
1726 case AArch64::STRXui:
1727 case AArch64::STRWui:
1728 case AArch64::LDRSui:
1729 case AArch64::LDRDui:
1730 case AArch64::LDRQui:
1731 case AArch64::LDRXui:
1732 case AArch64::LDRWui:
1733 case AArch64::LDRSWui:
1735 case AArch64::STURSi:
1736 case AArch64::STURDi:
1737 case AArch64::STURQi:
1738 case AArch64::STURWi:
1739 case AArch64::STURXi:
1740 case AArch64::LDURSi:
1741 case AArch64::LDURDi:
1742 case AArch64::LDURQi:
1743 case AArch64::LDURWi:
1744 case AArch64::LDURXi:
1745 case AArch64::LDURSWi:
1756 case AArch64::ADDWri:
1758 return AArch64::ADDSWri;
1759 case AArch64::ADDWrr:
1761 return AArch64::ADDSWrr;
1762 case AArch64::ADDWrs:
1764 return AArch64::ADDSWrs;
1765 case AArch64::ADDWrx:
1767 return AArch64::ADDSWrx;
1768 case AArch64::ANDWri:
1770 return AArch64::ANDSWri;
1771 case AArch64::ANDWrr:
1773 return AArch64::ANDSWrr;
1774 case AArch64::ANDWrs:
1776 return AArch64::ANDSWrs;
1777 case AArch64::BICWrr:
1779 return AArch64::BICSWrr;
1780 case AArch64::BICWrs:
1782 return AArch64::BICSWrs;
1783 case AArch64::SUBWri:
1785 return AArch64::SUBSWri;
1786 case AArch64::SUBWrr:
1788 return AArch64::SUBSWrr;
1789 case AArch64::SUBWrs:
1791 return AArch64::SUBSWrs;
1792 case AArch64::SUBWrx:
1794 return AArch64::SUBSWrx;
1796 case AArch64::ADDXri:
1798 return AArch64::ADDSXri;
1799 case AArch64::ADDXrr:
1801 return AArch64::ADDSXrr;
1802 case AArch64::ADDXrs:
1804 return AArch64::ADDSXrs;
1805 case AArch64::ADDXrx:
1807 return AArch64::ADDSXrx;
1808 case AArch64::ANDXri:
1810 return AArch64::ANDSXri;
1811 case AArch64::ANDXrr:
1813 return AArch64::ANDSXrr;
1814 case AArch64::ANDXrs:
1816 return AArch64::ANDSXrs;
1817 case AArch64::BICXrr:
1819 return AArch64::BICSXrr;
1820 case AArch64::BICXrs:
1822 return AArch64::BICSXrs;
1823 case AArch64::SUBXri:
1825 return AArch64::SUBSXri;
1826 case AArch64::SUBXrr:
1828 return AArch64::SUBSXrr;
1829 case AArch64::SUBXrs:
1831 return AArch64::SUBSXrs;
1832 case AArch64::SUBXrx:
1834 return AArch64::SUBSXrx;
1847 "Expected a reg or frame index operand.");
1867 if (Subtarget.isPaired128Slow()) {
1871 case AArch64::LDURQi:
1872 case AArch64::STURQi:
1873 case AArch64::LDRQui:
1874 case AArch64::STRQui:
1912 int64_t Dummy1, Dummy2;
1931 "getMemOperandWithOffset only supports base " 1932 "operands of type register or frame index.");
1941 assert(OfsOp.isImm() &&
"Offset operand wasn't immediate.");
1946 unsigned &Width, int64_t &MinOffset,
1947 int64_t &MaxOffset)
const {
1952 MinOffset = MaxOffset = 0;
1954 case AArch64::STRWpost:
1955 case AArch64::LDRWpost:
1961 case AArch64::LDURQi:
1962 case AArch64::STURQi:
1968 case AArch64::LDURXi:
1969 case AArch64::LDURDi:
1970 case AArch64::STURXi:
1971 case AArch64::STURDi:
1977 case AArch64::LDURWi:
1978 case AArch64::LDURSi:
1979 case AArch64::LDURSWi:
1980 case AArch64::STURWi:
1981 case AArch64::STURSi:
1987 case AArch64::LDURHi:
1988 case AArch64::LDURHHi:
1989 case AArch64::LDURSHXi:
1990 case AArch64::LDURSHWi:
1991 case AArch64::STURHi:
1992 case AArch64::STURHHi:
1998 case AArch64::LDURBi:
1999 case AArch64::LDURBBi:
2000 case AArch64::LDURSBXi:
2001 case AArch64::LDURSBWi:
2002 case AArch64::STURBi:
2003 case AArch64::STURBBi:
2009 case AArch64::LDPQi:
2010 case AArch64::LDNPQi:
2011 case AArch64::STPQi:
2012 case AArch64::STNPQi:
2018 case AArch64::LDRQui:
2019 case AArch64::STRQui:
2024 case AArch64::LDPXi:
2025 case AArch64::LDPDi:
2026 case AArch64::LDNPXi:
2027 case AArch64::LDNPDi:
2028 case AArch64::STPXi:
2029 case AArch64::STPDi:
2030 case AArch64::STNPXi:
2031 case AArch64::STNPDi:
2037 case AArch64::LDRXui:
2038 case AArch64::LDRDui:
2039 case AArch64::STRXui:
2040 case AArch64::STRDui:
2045 case AArch64::LDPWi:
2046 case AArch64::LDPSi:
2047 case AArch64::LDNPWi:
2048 case AArch64::LDNPSi:
2049 case AArch64::STPWi:
2050 case AArch64::STPSi:
2051 case AArch64::STNPWi:
2052 case AArch64::STNPSi:
2058 case AArch64::LDRWui:
2059 case AArch64::LDRSui:
2060 case AArch64::LDRSWui:
2061 case AArch64::STRWui:
2062 case AArch64::STRSui:
2067 case AArch64::LDRHui:
2068 case AArch64::LDRHHui:
2069 case AArch64::STRHui:
2070 case AArch64::STRHHui:
2075 case AArch64::LDRBui:
2076 case AArch64::LDRBBui:
2077 case AArch64::STRBui:
2078 case AArch64::STRBBui:
2092 case AArch64::LDURQi:
2093 case AArch64::STURQi:
2095 case AArch64::LDURXi:
2096 case AArch64::LDURDi:
2097 case AArch64::STURXi:
2098 case AArch64::STURDi:
2100 case AArch64::LDURWi:
2101 case AArch64::LDURSi:
2102 case AArch64::LDURSWi:
2103 case AArch64::STURWi:
2104 case AArch64::STURSi:
2113 if (OffsetStride == 0)
2117 if (Offset % OffsetStride != 0)
2122 Offset /= OffsetStride;
2130 if (OffsetStride == 0)
2135 Offset *= OffsetStride;
2140 if (FirstOpc == SecondOpc)
2146 case AArch64::LDRWui:
2147 case AArch64::LDURWi:
2148 return SecondOpc == AArch64::LDRSWui || SecondOpc == AArch64::LDURSWi;
2149 case AArch64::LDRSWui:
2150 case AArch64::LDURSWi:
2151 return SecondOpc == AArch64::LDRWui || SecondOpc == AArch64::LDURWi;
2158 int64_t Offset1,
unsigned Opcode1,
int FI2,
2159 int64_t Offset2,
unsigned Opcode2) {
2165 assert(ObjectOffset1 <= ObjectOffset2 &&
"Object offsets are not ordered.");
2169 ObjectOffset1 += Offset1;
2170 ObjectOffset2 += Offset2;
2175 return ObjectOffset1 + 1 == ObjectOffset2;
2186 unsigned NumLoads)
const {
2193 "Only base registers and frame indices are supported.");
2207 unsigned FirstOpc = FirstLdSt.
getOpcode();
2208 unsigned SecondOpc = SecondLdSt.
getOpcode();
2228 if (Offset1 > 63 || Offset1 < -64)
2233 if (BaseOp1.
isFI()) {
2235 "Caller should have ordered offsets.");
2240 BaseOp2.
getIndex(), Offset2, SecondOpc);
2244 "Caller should have ordered offsets.");
2246 return Offset1 + 1 == Offset2;
2250 unsigned Reg,
unsigned SubIdx,
2254 return MIB.
addReg(Reg, State);
2258 return MIB.
addReg(Reg, State, SubIdx);
2265 return ((DestReg - SrcReg) & 0x1f) < NumRegs;
2270 const DebugLoc &DL,
unsigned DestReg,
2271 unsigned SrcReg,
bool KillSrc,
2274 assert(Subtarget.hasNEON() &&
"Unexpected register copy without NEON");
2276 uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
2277 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
2278 unsigned NumRegs = Indices.
size();
2280 int SubReg = 0, End = NumRegs, Incr = 1;
2282 SubReg = NumRegs - 1;
2287 for (; SubReg != End; SubReg += Incr) {
2290 AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI);
2298 unsigned SrcReg,
bool KillSrc,
2299 unsigned Opcode,
unsigned ZeroReg,
2302 unsigned NumRegs = Indices.
size();
2307 assert(DestEncoding % NumRegs == 0 && SrcEncoding % NumRegs == 0 &&
2308 "GPR reg sequences should not be able to overlap");
2322 const DebugLoc &DL,
unsigned DestReg,
2323 unsigned SrcReg,
bool KillSrc)
const {
2324 if (AArch64::GPR32spRegClass.
contains(DestReg) &&
2325 (AArch64::GPR32spRegClass.
contains(SrcReg) || SrcReg == AArch64::WZR)) {
2328 if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
2330 if (Subtarget.hasZeroCycleRegMove()) {
2333 &AArch64::GPR64spRegClass);
2335 &AArch64::GPR64spRegClass);
2340 BuildMI(MBB, I, DL,
get(AArch64::ADDXri), DestRegX)
2346 BuildMI(MBB, I, DL,
get(AArch64::ADDWri), DestReg)
2351 }
else if (SrcReg == AArch64::WZR && Subtarget.hasZeroCycleZeroingGP()) {
2352 BuildMI(MBB, I, DL,
get(AArch64::MOVZWi), DestReg)
2356 if (Subtarget.hasZeroCycleRegMove()) {
2359 &AArch64::GPR64spRegClass);
2361 &AArch64::GPR64spRegClass);
2366 BuildMI(MBB, I, DL,
get(AArch64::ORRXrr), DestRegX)
2372 BuildMI(MBB, I, DL,
get(AArch64::ORRWrr), DestReg)
2380 if (AArch64::GPR64spRegClass.
contains(DestReg) &&
2381 (AArch64::GPR64spRegClass.
contains(SrcReg) || SrcReg == AArch64::XZR)) {
2382 if (DestReg == AArch64::SP || SrcReg == AArch64::SP) {
2384 BuildMI(MBB, I, DL,
get(AArch64::ADDXri), DestReg)
2388 }
else if (SrcReg == AArch64::XZR && Subtarget.hasZeroCycleZeroingGP()) {
2389 BuildMI(MBB, I, DL,
get(AArch64::MOVZXi), DestReg)
2394 BuildMI(MBB, I, DL,
get(AArch64::ORRXrr), DestReg)
2402 if (AArch64::DDDDRegClass.
contains(DestReg) &&
2403 AArch64::DDDDRegClass.
contains(SrcReg)) {
2404 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1,
2405 AArch64::dsub2, AArch64::dsub3};
2412 if (AArch64::DDDRegClass.
contains(DestReg) &&
2413 AArch64::DDDRegClass.
contains(SrcReg)) {
2414 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1,
2422 if (AArch64::DDRegClass.
contains(DestReg) &&
2423 AArch64::DDRegClass.
contains(SrcReg)) {
2424 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1};
2431 if (AArch64::QQQQRegClass.
contains(DestReg) &&
2432 AArch64::QQQQRegClass.
contains(SrcReg)) {
2433 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1,
2434 AArch64::qsub2, AArch64::qsub3};
2441 if (AArch64::QQQRegClass.
contains(DestReg) &&
2442 AArch64::QQQRegClass.
contains(SrcReg)) {
2443 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1,
2451 if (AArch64::QQRegClass.
contains(DestReg) &&
2452 AArch64::QQRegClass.
contains(SrcReg)) {
2453 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1};
2459 if (AArch64::XSeqPairsClassRegClass.
contains(DestReg) &&
2460 AArch64::XSeqPairsClassRegClass.
contains(SrcReg)) {
2461 static const unsigned Indices[] = {AArch64::sube64, AArch64::subo64};
2462 copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRXrs,
2463 AArch64::XZR, Indices);
2467 if (AArch64::WSeqPairsClassRegClass.
contains(DestReg) &&
2468 AArch64::WSeqPairsClassRegClass.
contains(SrcReg)) {
2469 static const unsigned Indices[] = {AArch64::sube32, AArch64::subo32};
2470 copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRWrs,
2471 AArch64::WZR, Indices);
2475 if (AArch64::FPR128RegClass.
contains(DestReg) &&
2476 AArch64::FPR128RegClass.
contains(SrcReg)) {
2477 if (Subtarget.hasNEON()) {
2478 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
2482 BuildMI(MBB, I, DL,
get(AArch64::STRQpre))
2487 BuildMI(MBB, I, DL,
get(AArch64::LDRQpre))
2496 if (AArch64::FPR64RegClass.
contains(DestReg) &&
2497 AArch64::FPR64RegClass.
contains(SrcReg)) {
2498 if (Subtarget.hasNEON()) {
2499 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::dsub,
2500 &AArch64::FPR128RegClass);
2501 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::dsub,
2502 &AArch64::FPR128RegClass);
2503 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
2507 BuildMI(MBB, I, DL,
get(AArch64::FMOVDr), DestReg)
2513 if (AArch64::FPR32RegClass.
contains(DestReg) &&
2514 AArch64::FPR32RegClass.
contains(SrcReg)) {
2515 if (Subtarget.hasNEON()) {
2516 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::ssub,
2517 &AArch64::FPR128RegClass);
2518 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::ssub,
2519 &AArch64::FPR128RegClass);
2520 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
2524 BuildMI(MBB, I, DL,
get(AArch64::FMOVSr), DestReg)
2530 if (AArch64::FPR16RegClass.
contains(DestReg) &&
2531 AArch64::FPR16RegClass.
contains(SrcReg)) {
2532 if (Subtarget.hasNEON()) {
2533 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
2534 &AArch64::FPR128RegClass);
2535 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
2536 &AArch64::FPR128RegClass);
2537 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
2541 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
2542 &AArch64::FPR32RegClass);
2543 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
2544 &AArch64::FPR32RegClass);
2545 BuildMI(MBB, I, DL,
get(AArch64::FMOVSr), DestReg)
2551 if (AArch64::FPR8RegClass.
contains(DestReg) &&
2552 AArch64::FPR8RegClass.
contains(SrcReg)) {
2553 if (Subtarget.hasNEON()) {
2554 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
2555 &AArch64::FPR128RegClass);
2556 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
2557 &AArch64::FPR128RegClass);
2558 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
2562 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
2563 &AArch64::FPR32RegClass);
2564 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
2565 &AArch64::FPR32RegClass);
2566 BuildMI(MBB, I, DL,
get(AArch64::FMOVSr), DestReg)
2573 if (AArch64::FPR64RegClass.
contains(DestReg) &&
2574 AArch64::GPR64RegClass.
contains(SrcReg)) {
2575 BuildMI(MBB, I, DL,
get(AArch64::FMOVXDr), DestReg)
2579 if (AArch64::GPR64RegClass.
contains(DestReg) &&
2580 AArch64::FPR64RegClass.
contains(SrcReg)) {
2581 BuildMI(MBB, I, DL,
get(AArch64::FMOVDXr), DestReg)
2586 if (AArch64::FPR32RegClass.
contains(DestReg) &&
2587 AArch64::GPR32RegClass.
contains(SrcReg)) {
2588 BuildMI(MBB, I, DL,
get(AArch64::FMOVWSr), DestReg)
2592 if (AArch64::GPR32RegClass.
contains(DestReg) &&
2593 AArch64::FPR32RegClass.
contains(SrcReg)) {
2594 BuildMI(MBB, I, DL,
get(AArch64::FMOVSWr), DestReg)
2599 if (DestReg == AArch64::NZCV) {
2600 assert(AArch64::GPR64RegClass.
contains(SrcReg) &&
"Invalid NZCV copy");
2601 BuildMI(MBB, I, DL,
get(AArch64::MSR))
2602 .
addImm(AArch64SysReg::NZCV)
2608 if (SrcReg == AArch64::NZCV) {
2609 assert(AArch64::GPR64RegClass.
contains(DestReg) &&
"Invalid NZCV copy");
2610 BuildMI(MBB, I, DL,
get(AArch64::MRS), DestReg)
2611 .
addImm(AArch64SysReg::NZCV)
2623 unsigned SrcReg,
bool IsKill,
2624 unsigned SubIdx0,
unsigned SubIdx1,
int FI,
2626 unsigned SrcReg0 = SrcReg;
2627 unsigned SrcReg1 = SrcReg;
2629 SrcReg0 = TRI.
getSubReg(SrcReg, SubIdx0);
2631 SrcReg1 = TRI.
getSubReg(SrcReg, SubIdx1);
2657 if (AArch64::FPR8RegClass.hasSubClassEq(RC))
2658 Opc = AArch64::STRBui;
2661 if (AArch64::FPR16RegClass.hasSubClassEq(RC))
2662 Opc = AArch64::STRHui;
2665 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
2666 Opc = AArch64::STRWui;
2670 assert(SrcReg != AArch64::WSP);
2671 }
else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
2672 Opc = AArch64::STRSui;
2675 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
2676 Opc = AArch64::STRXui;
2680 assert(SrcReg != AArch64::SP);
2681 }
else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) {
2682 Opc = AArch64::STRDui;
2683 }
else if (AArch64::WSeqPairsClassRegClass.hasSubClassEq(RC)) {
2685 get(AArch64::STPWi), SrcReg, isKill,
2686 AArch64::sube32, AArch64::subo32, FI, MMO);
2691 if (AArch64::FPR128RegClass.hasSubClassEq(RC))
2692 Opc = AArch64::STRQui;
2693 else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
2694 assert(Subtarget.hasNEON() &&
"Unexpected register store without NEON");
2695 Opc = AArch64::ST1Twov1d;
2697 }
else if (AArch64::XSeqPairsClassRegClass.hasSubClassEq(RC)) {
2699 get(AArch64::STPXi), SrcReg, isKill,
2700 AArch64::sube64, AArch64::subo64, FI, MMO);
2705 if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
2706 assert(Subtarget.hasNEON() &&
"Unexpected register store without NEON");
2707 Opc = AArch64::ST1Threev1d;
2712 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
2713 assert(Subtarget.hasNEON() &&
"Unexpected register store without NEON");
2714 Opc = AArch64::ST1Fourv1d;
2716 }
else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
2717 assert(Subtarget.hasNEON() &&
"Unexpected register store without NEON");
2718 Opc = AArch64::ST1Twov2d;
2723 if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
2724 assert(Subtarget.hasNEON() &&
"Unexpected register store without NEON");
2725 Opc = AArch64::ST1Threev2d;
2730 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
2731 assert(Subtarget.hasNEON() &&
"Unexpected register store without NEON");
2732 Opc = AArch64::ST1Fourv2d;
2737 assert(Opc &&
"Unknown register class");
2752 unsigned DestReg,
unsigned SubIdx0,
2753 unsigned SubIdx1,
int FI,
2755 unsigned DestReg0 = DestReg;
2756 unsigned DestReg1 = DestReg;
2757 bool IsUndef =
true;
2759 DestReg0 = TRI.
getSubReg(DestReg, SubIdx0);
2761 DestReg1 = TRI.
getSubReg(DestReg, SubIdx1);
2788 if (AArch64::FPR8RegClass.hasSubClassEq(RC))
2789 Opc = AArch64::LDRBui;
2792 if (AArch64::FPR16RegClass.hasSubClassEq(RC))
2793 Opc = AArch64::LDRHui;
2796 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
2797 Opc = AArch64::LDRWui;
2801 assert(DestReg != AArch64::WSP);
2802 }
else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
2803 Opc = AArch64::LDRSui;
2806 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
2807 Opc = AArch64::LDRXui;
2811 assert(DestReg != AArch64::SP);
2812 }
else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) {
2813 Opc = AArch64::LDRDui;
2814 }
else if (AArch64::WSeqPairsClassRegClass.hasSubClassEq(RC)) {
2816 get(AArch64::LDPWi), DestReg, AArch64::sube32,
2817 AArch64::subo32, FI, MMO);
2822 if (AArch64::FPR128RegClass.hasSubClassEq(RC))
2823 Opc = AArch64::LDRQui;
2824 else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
2825 assert(Subtarget.hasNEON() &&
"Unexpected register load without NEON");
2826 Opc = AArch64::LD1Twov1d;
2828 }
else if (AArch64::XSeqPairsClassRegClass.hasSubClassEq(RC)) {
2830 get(AArch64::LDPXi), DestReg, AArch64::sube64,
2831 AArch64::subo64, FI, MMO);
2836 if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
2837 assert(Subtarget.hasNEON() &&
"Unexpected register load without NEON");
2838 Opc = AArch64::LD1Threev1d;
2843 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
2844 assert(Subtarget.hasNEON() &&
"Unexpected register load without NEON");
2845 Opc = AArch64::LD1Fourv1d;
2847 }
else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
2848 assert(Subtarget.hasNEON() &&
"Unexpected register load without NEON");
2849 Opc = AArch64::LD1Twov2d;
2854 if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
2855 assert(Subtarget.hasNEON() &&
"Unexpected register load without NEON");
2856 Opc = AArch64::LD1Threev2d;
2861 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
2862 assert(Subtarget.hasNEON() &&
"Unexpected register load without NEON");
2863 Opc = AArch64::LD1Fourv2d;
2868 assert(Opc &&
"Unknown register class");
2880 unsigned DestReg,
unsigned SrcReg,
int Offset,
2884 if (DestReg == SrcReg && Offset == 0)
2887 assert((DestReg != AArch64::SP || Offset % 16 == 0) &&
2888 "SP increment/decrement not 16-byte aligned");
2890 bool isSub = Offset < 0;
2907 Opc = isSub ? AArch64::SUBSXri : AArch64::ADDSXri;
2909 Opc = isSub ? AArch64::SUBXri : AArch64::ADDXri;
2910 const unsigned MaxEncoding = 0xfff;
2911 const unsigned ShiftSize = 12;
2912 const unsigned MaxEncodableValue = MaxEncoding << ShiftSize;
2913 while (((
unsigned)Offset) >= (1 << ShiftSize)) {
2915 if (((
unsigned)Offset) > MaxEncodableValue) {
2916 ThisVal = MaxEncodableValue;
2918 ThisVal = Offset & MaxEncodableValue;
2920 assert((ThisVal >> ShiftSize) <= MaxEncoding &&
2921 "Encoding cannot handle value that big");
2922 BuildMI(MBB, MBBI, DL, TII->
get(Opc), DestReg)
2924 .
addImm(ThisVal >> ShiftSize)
2928 if (NeedsWinCFI && SrcReg == AArch64::SP && DestReg == AArch64::SP)
2929 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_StackAlloc))
2938 BuildMI(MBB, MBBI, DL, TII->
get(Opc), DestReg)
2945 if ((DestReg ==
AArch64::FP && SrcReg == AArch64::SP) ||
2946 (SrcReg ==
AArch64::FP && DestReg == AArch64::SP)) {
2948 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_SetFP)).
2951 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_AddFP)).
2953 }
else if (DestReg == AArch64::SP) {
2954 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_StackAlloc)).
2980 if (SrcReg == AArch64::SP &&
2985 if (DstReg == AArch64::SP &&
3018 (Ops[0] == 0 || Ops[0] == 1)) {
3019 bool IsSpill = Ops[0] == 0;
3020 bool IsFill = !IsSpill;
3026 unsigned DstReg = DstMO.
getReg();
3027 unsigned SrcReg = SrcMO.
getReg();
3039 "Mismatched register size in non subreg COPY");
3046 return &*--InsertPt;
3058 if (IsSpill && DstMO.
isUndef() &&
3061 "Unexpected subreg on physical register");
3063 unsigned SpillSubreg;
3068 case AArch64::sub_32:
3070 if (AArch64::GPR32RegClass.
contains(SrcReg)) {
3071 SpillRC = &AArch64::GPR64RegClass;
3072 SpillSubreg = AArch64::sub_32;
3073 }
else if (AArch64::FPR32RegClass.
contains(SrcReg)) {
3074 SpillRC = &AArch64::FPR64RegClass;
3075 SpillSubreg = AArch64::ssub;
3080 if (AArch64::FPR64RegClass.
contains(SrcReg)) {
3081 SpillRC = &AArch64::FPR128RegClass;
3082 SpillSubreg = AArch64::dsub;
3089 if (
unsigned WidenedSrcReg =
3093 return &*--InsertPt;
3112 case AArch64::sub_32:
3113 FillRC = &AArch64::GPR32RegClass;
3116 FillRC = &AArch64::FPR32RegClass;
3119 FillRC = &AArch64::FPR64RegClass;
3126 "Mismatched regclass size on folded subreg COPY");
3143 bool *OutUseUnscaledOp,
3144 unsigned *OutUnscaledOp,
3145 int *EmittableOffset) {
3147 bool IsSigned =
false;
3149 unsigned ImmIdx = 2;
3150 unsigned UnscaledOp = 0;
3152 if (EmittableOffset)
3153 *EmittableOffset = 0;
3154 if (OutUseUnscaledOp)
3155 *OutUseUnscaledOp =
false;
3162 case AArch64::LD1Twov2d:
3163 case AArch64::LD1Threev2d:
3164 case AArch64::LD1Fourv2d:
3165 case AArch64::LD1Twov1d:
3166 case AArch64::LD1Threev1d:
3167 case AArch64::LD1Fourv1d:
3168 case AArch64::ST1Twov2d:
3169 case AArch64::ST1Threev2d:
3170 case AArch64::ST1Fourv2d:
3171 case AArch64::ST1Twov1d:
3172 case AArch64::ST1Threev1d:
3173 case AArch64::ST1Fourv1d:
3175 case AArch64::PRFMui:
3177 UnscaledOp = AArch64::PRFUMi;
3179 case AArch64::LDRXui:
3181 UnscaledOp = AArch64::LDURXi;
3183 case AArch64::LDRWui:
3185 UnscaledOp = AArch64::LDURWi;
3187 case AArch64::LDRBui:
3189 UnscaledOp = AArch64::LDURBi;
3191 case AArch64::LDRHui:
3193 UnscaledOp = AArch64::LDURHi;
3195 case AArch64::LDRSui:
3197 UnscaledOp = AArch64::LDURSi;
3199 case AArch64::LDRDui:
3201 UnscaledOp = AArch64::LDURDi;
3203 case AArch64::LDRQui:
3205 UnscaledOp = AArch64::LDURQi;
3207 case AArch64::LDRBBui:
3209 UnscaledOp = AArch64::LDURBBi;
3211 case AArch64::LDRHHui:
3213 UnscaledOp = AArch64::LDURHHi;
3215 case AArch64::LDRSBXui:
3217 UnscaledOp = AArch64::LDURSBXi;
3219 case AArch64::LDRSBWui:
3221 UnscaledOp = AArch64::LDURSBWi;
3223 case AArch64::LDRSHXui:
3225 UnscaledOp = AArch64::LDURSHXi;
3227 case AArch64::LDRSHWui:
3229 UnscaledOp = AArch64::LDURSHWi;
3231 case AArch64::LDRSWui:
3233 UnscaledOp = AArch64::LDURSWi;
3236 case AArch64::STRXui:
3238 UnscaledOp = AArch64::STURXi;
3240 case AArch64::STRWui:
3242 UnscaledOp = AArch64::STURWi;
3244 case AArch64::STRBui:
3246 UnscaledOp = AArch64::STURBi;
3248 case AArch64::STRHui:
3250 UnscaledOp = AArch64::STURHi;
3252 case AArch64::STRSui:
3254 UnscaledOp = AArch64::STURSi;
3256 case AArch64::STRDui:
3258 UnscaledOp = AArch64::STURDi;
3260 case AArch64::STRQui:
3262 UnscaledOp = AArch64::STURQi;
3264 case AArch64::STRBBui:
3266 UnscaledOp = AArch64::STURBBi;
3268 case AArch64::STRHHui:
3270 UnscaledOp = AArch64::STURHHi;
3273 case AArch64::LDPXi:
3274 case AArch64::LDPDi:
3275 case AArch64::STPXi:
3276 case AArch64::STPDi:
3277 case AArch64::LDNPXi:
3278 case AArch64::LDNPDi:
3279 case AArch64::STNPXi:
3280 case AArch64::STNPDi:
3285 case AArch64::LDPQi:
3286 case AArch64::STPQi:
3287 case AArch64::LDNPQi:
3288 case AArch64::STNPQi:
3293 case AArch64::LDPWi:
3294 case AArch64::LDPSi:
3295 case AArch64::STPWi:
3296 case AArch64::STPSi:
3297 case AArch64::LDNPWi:
3298 case AArch64::LDNPSi:
3299 case AArch64::STNPWi:
3300 case AArch64::STNPSi:
3306 case AArch64::LDURXi:
3307 case AArch64::LDURWi:
3308 case AArch64::LDURBi:
3309 case AArch64::LDURHi:
3310 case AArch64::LDURSi:
3311 case AArch64::LDURDi:
3312 case AArch64::LDURQi:
3313 case AArch64::LDURHHi:
3314 case AArch64::LDURBBi:
3315 case AArch64::LDURSBXi:
3316 case AArch64::LDURSBWi:
3317 case AArch64::LDURSHXi:
3318 case AArch64::LDURSHWi:
3319 case AArch64::LDURSWi:
3320 case AArch64::STURXi:
3321 case AArch64::STURWi:
3322 case AArch64::STURBi:
3323 case AArch64::STURHi:
3324 case AArch64::STURSi:
3325 case AArch64::STURDi:
3326 case AArch64::STURQi:
3327 case AArch64::STURBBi:
3328 case AArch64::STURHHi:
3335 bool useUnscaledOp =
false;
3339 if ((Offset & (Scale - 1)) != 0 || (Offset < 0 && UnscaledOp != 0))
3340 useUnscaledOp =
true;
3349 }
else if (UnscaledOp == 0 || useUnscaledOp) {
3360 int MaxOff = (1 << (MaskBits - IsSigned)) - 1;
3361 int MinOff = (IsSigned ? (-MaxOff - 1) : 0);
3362 if (Offset >= MinOff && Offset <= MaxOff) {
3363 if (EmittableOffset)
3364 *EmittableOffset =
Offset;
3367 int NewOff = Offset < 0 ? MinOff : MaxOff;
3368 if (EmittableOffset)
3369 *EmittableOffset = NewOff;
3370 Offset = (Offset - NewOff) * Scale;
3372 if (OutUseUnscaledOp)
3373 *OutUseUnscaledOp = useUnscaledOp;
3375 *OutUnscaledOp = UnscaledOp;
3381 unsigned FrameReg,
int &
Offset,
3384 unsigned ImmIdx = FrameRegIdx + 1;
3386 if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) {
3397 unsigned UnscaledOp;
3400 &UnscaledOp, &NewOffset);
3406 MI.
setDesc(TII->get(UnscaledOp));
3426 case AArch64::ADDSWrr:
3427 case AArch64::ADDSWri:
3428 case AArch64::ADDSXrr:
3429 case AArch64::ADDSXri:
3430 case AArch64::SUBSWrr:
3431 case AArch64::SUBSXrr:
3433 case AArch64::SUBSWri:
3434 case AArch64::SUBSXri:
3445 case AArch64::ADDWrr:
3446 case AArch64::ADDWri:
3447 case AArch64::SUBWrr:
3448 case AArch64::ADDSWrr:
3449 case AArch64::ADDSWri:
3450 case AArch64::SUBSWrr:
3452 case AArch64::SUBWri:
3453 case AArch64::SUBSWri:
3464 case AArch64::ADDXrr:
3465 case AArch64::ADDXri:
3466 case AArch64::SUBXrr:
3467 case AArch64::ADDSXrr:
3468 case AArch64::ADDSXri:
3469 case AArch64::SUBSXrr:
3471 case AArch64::SUBXri:
3472 case AArch64::SUBSXri:
3485 case AArch64::FADDSrr:
3486 case AArch64::FADDDrr:
3487 case AArch64::FADDv2f32:
3488 case AArch64::FADDv2f64:
3489 case AArch64::FADDv4f32:
3490 case AArch64::FSUBSrr:
3491 case AArch64::FSUBDrr:
3492 case AArch64::FSUBv2f32:
3493 case AArch64::FSUBv2f64:
3494 case AArch64::FSUBv4f32:
3511 unsigned CombineOpc,
unsigned ZeroReg = 0,
3512 bool CheckZeroReg =
false) {
3540 unsigned MulOpc,
unsigned ZeroReg) {
3541 return canCombine(MBB, MO, MulOpc, ZeroReg,
true);
3558 case AArch64::FADDDrr:
3559 case AArch64::FADDSrr:
3560 case AArch64::FADDv2f32:
3561 case AArch64::FADDv2f64:
3562 case AArch64::FADDv4f32:
3563 case AArch64::FMULDrr:
3564 case AArch64::FMULSrr:
3565 case AArch64::FMULX32:
3566 case AArch64::FMULX64:
3567 case AArch64::FMULXv2f32:
3568 case AArch64::FMULXv2f64:
3569 case AArch64::FMULXv4f32:
3570 case AArch64::FMULv2f32:
3571 case AArch64::FMULv2f64:
3572 case AArch64::FMULv4f32:
3604 case AArch64::ADDWrr:
3606 "ADDWrr does not have register operands");
3618 case AArch64::ADDXrr:
3630 case AArch64::SUBWrr:
3642 case AArch64::SUBXrr:
3654 case AArch64::ADDWri:
3661 case AArch64::ADDXri:
3668 case AArch64::SUBWri:
3675 case AArch64::SUBXri:
3699 assert(
false &&
"Unsupported FP instruction in combiner\n");
3701 case AArch64::FADDSrr:
3703 "FADDWrr does not have register operands");
3708 AArch64::FMULv1i32_indexed)) {
3716 AArch64::FMULv1i32_indexed)) {
3721 case AArch64::FADDDrr:
3726 AArch64::FMULv1i64_indexed)) {
3734 AArch64::FMULv1i64_indexed)) {
3739 case AArch64::FADDv2f32:
3741 AArch64::FMULv2i32_indexed)) {
3745 AArch64::FMULv2f32)) {
3750 AArch64::FMULv2i32_indexed)) {
3754 AArch64::FMULv2f32)) {
3759 case AArch64::FADDv2f64:
3761 AArch64::FMULv2i64_indexed)) {
3765 AArch64::FMULv2f64)) {
3770 AArch64::FMULv2i64_indexed)) {
3774 AArch64::FMULv2f64)) {
3779 case AArch64::FADDv4f32:
3781 AArch64::FMULv4i32_indexed)) {
3785 AArch64::FMULv4f32)) {
3790 AArch64::FMULv4i32_indexed)) {
3794 AArch64::FMULv4f32)) {
3800 case AArch64::FSUBSrr:
3809 AArch64::FMULv1i32_indexed)) {
3818 case AArch64::FSUBDrr:
3827 AArch64::FMULv1i64_indexed)) {
3836 case AArch64::FSUBv2f32:
3838 AArch64::FMULv2i32_indexed)) {
3842 AArch64::FMULv2f32)) {
3847 AArch64::FMULv2i32_indexed)) {
3851 AArch64::FMULv2f32)) {
3856 case AArch64::FSUBv2f64:
3858 AArch64::FMULv2i64_indexed)) {
3862 AArch64::FMULv2f64)) {
3867 AArch64::FMULv2i64_indexed)) {
3871 AArch64::FMULv2f64)) {
3876 case AArch64::FSUBv4f32:
3878 AArch64::FMULv4i32_indexed)) {
3882 AArch64::FMULv4f32)) {
3887 AArch64::FMULv4i32_indexed)) {
3891 AArch64::FMULv4f32)) {
3990 const unsigned *ReplacedAddend =
nullptr) {
3991 assert(IdxMulOpd == 1 || IdxMulOpd == 2);
3993 unsigned IdxOtherOpd = IdxMulOpd == 1 ? 2 : 1;
4003 if (ReplacedAddend) {
4005 SrcReg2 = *ReplacedAddend;
4039 assert(
false &&
"Invalid FMA instruction kind \n");
4067 unsigned IdxMulOpd,
unsigned MaddOpc,
unsigned VR,
4069 assert(IdxMulOpd == 1 || IdxMulOpd == 2);
4117 DelInstrs, InstrIdxForVirtReg);
4126 Opc = AArch64::MADDWrrr;
4127 RC = &AArch64::GPR32RegClass;
4129 Opc = AArch64::MADDXrrr;
4130 RC = &AArch64::GPR64RegClass;
4141 Opc = AArch64::MADDWrrr;
4142 RC = &AArch64::GPR32RegClass;
4144 Opc = AArch64::MADDXrrr;
4145 RC = &AArch64::GPR64RegClass;
4157 unsigned BitSize, OrrOpc, ZeroReg;
4159 OrrOpc = AArch64::ORRWri;
4160 OrrRC = &AArch64::GPR32spRegClass;
4162 ZeroReg = AArch64::WZR;
4163 Opc = AArch64::MADDWrrr;
4164 RC = &AArch64::GPR32RegClass;
4166 OrrOpc = AArch64::ORRXri;
4167 OrrRC = &AArch64::GPR64spRegClass;
4169 ZeroReg = AArch64::XZR;
4170 Opc = AArch64::MADDXrrr;
4171 RC = &AArch64::GPR64RegClass;
4188 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
4189 MUL =
genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
4201 unsigned SubOpc, ZeroReg;
4203 SubOpc = AArch64::SUBWrr;
4204 SubRC = &AArch64::GPR32spRegClass;
4205 ZeroReg = AArch64::WZR;
4206 Opc = AArch64::MADDWrrr;
4207 RC = &AArch64::GPR32RegClass;
4209 SubOpc = AArch64::SUBXrr;
4210 SubRC = &AArch64::GPR64spRegClass;
4211 ZeroReg = AArch64::XZR;
4212 Opc = AArch64::MADDXrrr;
4213 RC = &AArch64::GPR64RegClass;
4222 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
4223 MUL =
genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
4233 Opc = AArch64::MSUBWrrr;
4234 RC = &AArch64::GPR32RegClass;
4236 Opc = AArch64::MSUBXrrr;
4237 RC = &AArch64::GPR64RegClass;
4249 unsigned BitSize, OrrOpc, ZeroReg;
4251 OrrOpc = AArch64::ORRWri;
4252 OrrRC = &AArch64::GPR32spRegClass;
4254 ZeroReg = AArch64::WZR;
4255 Opc = AArch64::MADDWrrr;
4256 RC = &AArch64::GPR32RegClass;
4258 OrrOpc = AArch64::ORRXri;
4259 OrrRC = &AArch64::GPR64spRegClass;
4261 ZeroReg = AArch64::XZR;
4262 Opc = AArch64::MADDXrrr;
4263 RC = &AArch64::GPR64RegClass;
4279 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
4280 MUL =
genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
4292 Opc = AArch64::FMADDSrrr;
4293 RC = &AArch64::FPR32RegClass;
4295 Opc = AArch64::FMADDDrrr;
4296 RC = &AArch64::FPR64RegClass;
4307 Opc = AArch64::FMADDSrrr;
4308 RC = &AArch64::FPR32RegClass;
4310 Opc = AArch64::FMADDDrrr;
4311 RC = &AArch64::FPR64RegClass;
4317 Opc = AArch64::FMLAv1i32_indexed;
4318 RC = &AArch64::FPR32RegClass;
4323 Opc = AArch64::FMLAv1i32_indexed;
4324 RC = &AArch64::FPR32RegClass;
4330 Opc = AArch64::FMLAv1i64_indexed;
4331 RC = &AArch64::FPR64RegClass;
4336 Opc = AArch64::FMLAv1i64_indexed;
4337 RC = &AArch64::FPR64RegClass;
4344 RC = &AArch64::FPR64RegClass;
4346 Opc = AArch64::FMLAv2i32_indexed;
4350 Opc = AArch64::FMLAv2f32;
4357 RC = &AArch64::FPR64RegClass;
4359 Opc = AArch64::FMLAv2i32_indexed;
4363 Opc = AArch64::FMLAv2f32;
4371 RC = &AArch64::FPR128RegClass;
4373 Opc = AArch64::FMLAv2i64_indexed;
4377 Opc = AArch64::FMLAv2f64;
4384 RC = &AArch64::FPR128RegClass;
4386 Opc = AArch64::FMLAv2i64_indexed;
4390 Opc = AArch64::FMLAv2f64;
4398 RC = &AArch64::FPR128RegClass;
4400 Opc = AArch64::FMLAv4i32_indexed;
4404 Opc = AArch64::FMLAv4f32;
4412 RC = &AArch64::FPR128RegClass;
4414 Opc = AArch64::FMLAv4i32_indexed;
4418 Opc = AArch64::FMLAv4f32;
4431 Opc = AArch64::FNMSUBSrrr;
4432 RC = &AArch64::FPR32RegClass;
4434 Opc = AArch64::FNMSUBDrrr;
4435 RC = &AArch64::FPR64RegClass;
4448 Opc = AArch64::FNMADDSrrr;
4449 RC = &AArch64::FPR32RegClass;
4451 Opc = AArch64::FNMADDDrrr;
4452 RC = &AArch64::FPR64RegClass;
4465 Opc = AArch64::FMSUBSrrr;
4466 RC = &AArch64::FPR32RegClass;
4468 Opc = AArch64::FMSUBDrrr;
4469 RC = &AArch64::FPR64RegClass;
4476 Opc = AArch64::FMLSv1i32_indexed;
4477 RC = &AArch64::FPR32RegClass;
4483 Opc = AArch64::FMLSv1i64_indexed;
4484 RC = &AArch64::FPR64RegClass;
4491 RC = &AArch64::FPR64RegClass;
4493 Opc = AArch64::FMLSv2i32_indexed;
4497 Opc = AArch64::FMLSv2f32;
4505 RC = &AArch64::FPR128RegClass;
4507 Opc = AArch64::FMLSv2i64_indexed;
4511 Opc = AArch64::FMLSv2f64;
4519 RC = &AArch64::FPR128RegClass;
4521 Opc = AArch64::FMLSv4i32_indexed;
4525 Opc = AArch64::FMLSv4f32;
4532 RC = &AArch64::FPR64RegClass;
4538 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
4540 Opc = AArch64::FMLAv2i32_indexed;
4544 Opc = AArch64::FMLAv2f32;
4552 RC = &AArch64::FPR128RegClass;
4558 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
4560 Opc = AArch64::FMLAv4i32_indexed;
4564 Opc = AArch64::FMLAv4f32;
4572 RC = &AArch64::FPR128RegClass;
4578 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
4580 Opc = AArch64::FMLAv2i64_indexed;
4584 Opc = AArch64::FMLAv2f64;
4634 bool IsNegativeBranch =
false;
4635 bool IsTestAndBranch =
false;
4636 unsigned TargetBBInMI = 0;
4646 case AArch64::CBNZW:
4647 case AArch64::CBNZX:
4649 IsNegativeBranch =
true;
4654 IsTestAndBranch =
true;
4656 case AArch64::TBNZW:
4657 case AArch64::TBNZX:
4659 IsNegativeBranch =
true;
4660 IsTestAndBranch =
true;
4681 while (DefMI->
isCopy()) {
4694 case AArch64::ANDWri:
4695 case AArch64::ANDXri: {
4696 if (IsTestAndBranch)
4703 bool Is32Bit = (DefMI->
getOpcode() == AArch64::ANDWri);
4710 unsigned NewReg = MO.
getReg();
4720 unsigned Opc = (Imm < 32)
4721 ? (IsNegativeBranch ? AArch64::TBNZW : AArch64::TBZW)
4722 : (IsNegativeBranch ? AArch64::TBNZX : AArch64::TBZX);
4735 if (!Is32Bit && Imm < 32)
4741 case AArch64::CSINCWr:
4742 case AArch64::CSINCXr: {
4761 if (IsNegativeBranch)
4770 std::pair<unsigned, unsigned>
4773 return std::make_pair(TF & Mask, TF & ~Mask);
4778 using namespace AArch64II;
4780 static const std::pair<unsigned, const char *>
TargetFlags[] = {
4782 {
MO_G3,
"aarch64-g3"}, {
MO_G2,
"aarch64-g2"},
4783 {
MO_G1,
"aarch64-g1"}, {
MO_G0,
"aarch64-g0"},
4790 using namespace AArch64II;
4792 static const std::pair<unsigned, const char *>
TargetFlags[] = {
4795 {
MO_S,
"aarch64-s"}, {
MO_TLS,
"aarch64-tls"},
4802 static const std::pair<MachineMemOperand::Flags, const char *>
TargetFlags[] =
4911 for (
unsigned Reg : AArch64::GPR64RegClass) {
4913 Reg != AArch64::LR &&
4914 Reg != AArch64::X16 &&
4915 Reg != AArch64::X17 &&
4926 std::vector<outliner::Candidate> &RepeatedSequenceLocs)
const {
4928 unsigned SequenceSize =
4929 std::accumulate(FirstCand.
front(), std::next(FirstCand.
back()), 0,
4935 unsigned FlagsSetInAll = 0xF;
4939 std::for_each(RepeatedSequenceLocs.begin(), RepeatedSequenceLocs.end(),
4941 FlagsSetInAll &=
C.Flags;
4971 RepeatedSequenceLocs.erase(
std::remove_if(RepeatedSequenceLocs.begin(),
4972 RepeatedSequenceLocs.end(),
4973 CantGuaranteeValueAcrossCall),
4974 RepeatedSequenceLocs.end());
4977 if (RepeatedSequenceLocs.size() < 2)
4984 unsigned LastInstrOpcode = RepeatedSequenceLocs[0].back()->getOpcode();
4987 auto SetCandidateCallInfo =
4988 [&RepeatedSequenceLocs](
unsigned CallID,
unsigned NumBytesForCall) {
4990 C.setCallInfo(CallID, NumBytesForCall);
4994 unsigned NumBytesToCreateFrame = 4;
5024 Base->
getReg() != AArch64::SP)
5032 unsigned DummyWidth;
5036 if (Offset < MinOffset * Scale || Offset > MaxOffset * Scale)
5052 FirstCand.
front(), std::next(FirstCand.
back()), IsSafeToFixup);
5056 if (RepeatedSequenceLocs[0].back()->isTerminator()) {
5058 NumBytesToCreateFrame = 0;
5063 (LastInstrOpcode == AArch64::BLR && !HasBTI)) {
5066 NumBytesToCreateFrame = 0;
5074 unsigned NumBytesNoStackCalls = 0;
5075 std::vector<outliner::Candidate> CandidatesWithoutStackFixups;
5082 NumBytesNoStackCalls += 4;
5084 CandidatesWithoutStackFixups.push_back(C);
5089 else if (findRegisterToSaveLRTo(C)) {
5090 NumBytesNoStackCalls += 12;
5092 CandidatesWithoutStackFixups.push_back(C);
5098 NumBytesNoStackCalls += 12;
5100 CandidatesWithoutStackFixups.push_back(C);
5106 NumBytesNoStackCalls += SequenceSize;
5113 if (!AllStackInstrsSafe ||
5114 NumBytesNoStackCalls <= RepeatedSequenceLocs.size() * 12) {
5115 RepeatedSequenceLocs = CandidatesWithoutStackFixups;
5122 if (RepeatedSequenceLocs.size() < 2) {
5123 RepeatedSequenceLocs.clear();
5133 bool ModStackToSaveLR =
false;
5136 ModStackToSaveLR =
true;
5145 ModStackToSaveLR =
true;
5147 if (ModStackToSaveLR) {
5149 if (!AllStackInstrsSafe) {
5150 RepeatedSequenceLocs.clear();
5155 NumBytesToCreateFrame += 8;
5160 NumBytesToCreateFrame, FrameID);
5190 unsigned &Flags)
const {
5194 "Suitable Machine Function for outlining must track liveness");
5201 bool W16AvailableInBlock = LRU.available(AArch64::W16);
5202 bool W17AvailableInBlock = LRU.available(AArch64::W17);
5203 bool NZCVAvailableInBlock = LRU.available(AArch64::NZCV);
5207 if (W16AvailableInBlock && W17AvailableInBlock && NZCVAvailableInBlock)
5211 LRU.addLiveOuts(MBB);
5215 if (W16AvailableInBlock && !LRU.available(AArch64::W16))
5217 if (W17AvailableInBlock && !LRU.available(AArch64::W17))
5219 if (NZCVAvailableInBlock && !LRU.available(AArch64::NZCV))
5232 bool CanSaveLR =
false;
5238 for (
unsigned Reg : AArch64::GPR64RegClass) {
5240 Reg != AArch64::X16 &&
Reg != AArch64::X17 && LRU.available(
Reg)) {
5249 if (!CanSaveLR && !LRU.available(AArch64::LR))
5257 unsigned Flags)
const {
5289 if (MOP.isCPI() || MOP.isJTI() || MOP.isCFIIndex() || MOP.isFI() ||
5290 MOP.isTargetIndex())
5294 if (MOP.isReg() && !MOP.isImplicit() &&
5295 (MOP.getReg() == AArch64::LR || MOP.getReg() == AArch64::W30))
5323 if (MOP.isGlobal()) {
5331 if (Callee && Callee->
getName() ==
"\01_mcount")
5343 return UnknownCallOutlineType;
5351 return UnknownCallOutlineType;
5359 return UnknownCallOutlineType;
5385 if (!
MI.mayLoadOrStore() ||
5392 int64_t Dummy1, Dummy2;
5395 assert(StackOffsetOperand.
isImm() &&
"Stack offset wasn't immediate!");
5397 assert(Scale != 0 &&
"Unexpected opcode!");
5402 int64_t NewImm = (Offset + 16) / Scale;
5403 StackOffsetOperand.
setImm(NewImm);
5414 unsigned TailOpcode;
5416 TailOpcode = AArch64::TCRETURNdi;
5419 TailOpcode = AArch64::TCRETURNriALL;
5430 return MI.isCall() && !
MI.isReturn();
5436 "Can only fix up stack references once");
5437 fixupPostOutline(MBB);
5447 Et = std::prev(MBB.
end());
5455 It = MBB.
insert(It, STRXpre);
5462 int64_t StackPosEntry =
5470 int64_t LRPosEntry =
5482 Et = MBB.
insert(Et, LDRXpost);
5501 fixupPostOutline(MBB);
5537 unsigned Reg = findRegisterToSaveLRTo(C);
5538 assert(Reg != 0 &&
"No callee-saved register available?");
5563 It = MBB.
insert(It, Save);
5572 It = MBB.
insert(It, Restore);
5581 #define GET_INSTRINFO_HELPERS 5582 #include "AArch64GenInstrInfo.inc" bool getMemOperandWithOffsetWidth(MachineInstr &MI, MachineOperand *&BaseOp, int64_t &Offset, unsigned &Width, const TargetRegisterInfo *TRI) const
static bool isStridedAccess(const MachineInstr &MI)
Return true if the given load or store is a strided memory access.
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
const MachineInstrBuilder & add(const MachineOperand &MO) const
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address...
static bool isFPRCopy(const MachineInstr &MI)
Does this instruction rename an FPR without modifying bits?
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
instr_iterator instr_begin()
bool use_nodbg_empty(unsigned RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register...
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
static unsigned getArithShiftValue(unsigned Imm)
getArithShiftValue - get the arithmetic shift value.
bool contains(unsigned Reg) const
Return true if the specified register is included in this register class.
bool isCall(QueryType Type=AnyInBundle) const
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
This class represents lattice values for constants.
unsigned getNumObjects() const
Return the number of objects.
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
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...
A Module instance is used to store all the information related to an LLVM module. ...
static bool isGPRCopy(const MachineInstr &MI)
Does this instruction rename a GPR without modifying bits?
static bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl< MachineCombinerPattern > &Patterns)
Floating-Point Support.
static unsigned sForm(MachineInstr &Instr)
Get opcode of S version of Instr.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void initLRU(const TargetRegisterInfo &TRI)
Compute the registers that are live across this Candidate.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
static CondCode getInvertedCondCode(CondCode Code)
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
void setIsUndef(bool Val=true)
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION
static bool isSUBSRegImm(unsigned Opcode)
static bool processLogicalImmediate(uint64_t Imm, unsigned RegSize, uint64_t &Encoding)
processLogicalImmediate - Determine if an immediate value can be encoded as the immediate operand of ...
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr) const override
unsigned getSubReg() const
LiveRegUnits LRU
Contains physical register liveness information for the MBB containing this Candidate.
Offset can apply, at least partly.
const SetOfInstructions & getLOHRelated() const
Emit a save, restore, call, and return.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
unsigned const TargetRegisterInfo * TRI
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address...
MachineModuleInfo & getMMI() const
bool hasOneDef(unsigned RegNo) const
Return true if there is exactly one operand defining the specified register.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
iterator_range< mop_iterator > operands()
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static unsigned convertToNonFlagSettingOpc(const MachineInstr &MI)
Return the opcode that does not set flags when possible - otherwise return the original opcode...
bool hasCustomCheapAsMoveHandling() const
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
An individual sequence of instructions to be replaced with a call to an outlined function.
static unsigned getOffsetStride(unsigned Opc)
static bool isLdStPairSuppressed(const MachineInstr &MI)
Return true if pairing the given load or store is hinted to be unprofitable.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
static bool isUnscaledLdSt(unsigned Opc)
Return true if this is an unscaled load/store.
return AArch64::GPR64RegClass contains(Reg)
iterator_range< succ_iterator > successors()
static const MachineInstrBuilder & AddSubReg(const MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI)
MO_G2 - A symbol operand with this flag (granule 2) represents the bits 32-47 of a 64-bit address...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A description of a memory reference used in the backend.
bool isAssociativeAndCommutative(const MachineInstr &Inst) const override
Return true when Inst is associative and commutative so that it can be reassociated.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static bool isSEHInstruction(const MachineInstr &MI)
Return true if the instructions is a SEH instruciton used for unwinding on Windows.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
static void suppressLdStPair(MachineInstr &MI)
Hint that pairing the given load or store is unprofitable.
const HexagonInstrInfo * TII
static bool isPairableLdStInst(const MachineInstr &MI)
Return true if pairing the given load or store may be paired with another.
static AArch64CC::CondCode findCondCodeUsedByInstr(const MachineInstr &Instr)
Find a condition code used by the instruction.
static bool canBeExpandedToORR(const MachineInstr &MI, unsigned BitSize)
Returns true if a MOVi32imm or MOVi64imm can be expanded to an ORRxx.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, int Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
unsigned getNumOperands() const
Retuns the total number of operands.
bool getMemOpInfo(unsigned Opcode, unsigned &Scale, unsigned &Width, int64_t &MinOffset, int64_t &MaxOffset) const
Returns true if opcode Opc is a memory operation.
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, const outliner::Candidate &C) const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOutlinerClass
Constants defining how certain sequences should be outlined.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool useMachineCombiner() const override
AArch64 supports MachineCombiner.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
static int getRegClass(RegisterKind Is, unsigned RegWidth)
unsigned FrameConstructionID
Target-defined identifier for constructing a frame for this function.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static UsedNZCV getUsedNZCV(AArch64CC::CondCode CC)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static bool isFalkorShiftExtFast(const MachineInstr &MI)
Returns true if the instruction has a shift by immediate that can be executed in one cycle less...
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
static bool canCombineWithMUL(MachineBasicBlock &MBB, MachineOperand &MO, unsigned MulOpc, unsigned ZeroReg)
const char * getSymbolName() const
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
zlib-gnu style compression
INLINEASM - Represents an inline asm block.
static bool isCombineInstrCandidate64(unsigned Opc)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
static bool shouldClusterFI(const MachineFrameInfo &MFI, int FI1, int64_t Offset1, unsigned Opcode1, int FI2, int64_t Offset2, unsigned Opcode2)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
AArch64InstrInfo(const AArch64Subtarget &STI)
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
bool available(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
static bool canCombineWithFMUL(MachineBasicBlock &MBB, MachineOperand &MO, unsigned MulOpc)
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type. ...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< MachineCombinerPattern > &Patterns) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, unsigned, unsigned, int &, int &, int &) const override
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc, unsigned ZeroReg=0, bool CheckZeroReg=false)
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
virtual const TargetInstrInfo * getInstrInfo() const
static const MachineMemOperand::Flags MOSuppressPair
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
unsigned getUndefRegState(bool B)
amdgpu Simplify well known AMD library false Value * Callee
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
static bool canPairLdStOpc(unsigned FirstOpc, unsigned SecondOpc)
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()
Instances of this class represent a single low-level machine instruction.
unsigned getKillRegState(bool B)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, unsigned ZeroReg, llvm::ArrayRef< unsigned > Indices) const
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
static bool isCondBranchOpcode(int Opc)
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
This class is intended to be used as a base class for asm properties and features specific to the tar...
unsigned getDefRegState(bool B)
MachineBasicBlock::iterator & back()
static bool isCombineInstrCandidateFP(const MachineInstr &Inst)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool getMemOperandWithOffset(MachineInstr &MI, MachineOperand *&BaseOp, int64_t &Offset, const TargetRegisterInfo *TRI) const override
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
bool hasLinkOnceODRLinkage() const
initializer< Ty > init(const Ty &Val)
MachineInstrBundleIterator< MachineInstr > iterator
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
FPOpFusion::FPOpFusionMode AllowFPOpFusion
AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
const AArch64RegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
bool LRUWasSet
True if initLRU has been called on this Candidate.
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address...
unsigned const MachineRegisterInfo * MRI
bool shouldClusterMemOps(MachineOperand &BaseOp1, MachineOperand &BaseOp2, unsigned NumLoads) const override
Detect opportunities for ldp/stp formation.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
InstrType
Represents how an instruction should be mapped by the outliner.
LiveRegUnits UsedInSequence
Contains the accumulated register liveness information for the instructions in this Candidate...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void genAlternativeCodeSequence(MachineInstr &Root, MachineCombinerPattern Pattern, SmallVectorImpl< MachineInstr *> &InsInstrs, SmallVectorImpl< MachineInstr *> &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
bool hasExynosCheapAsMoveHandling() const
unsigned CallConstructionID
Identifier denoting the instructions to emit to call an outlined function from this point...
static cl::opt< unsigned > BCCDisplacementBits("aarch64-bcc-offset-bits", cl::Hidden, cl::init(19), cl::desc("Restrict range of Bcc instructions (DEBUG)"))
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm)
The information necessary to create an outlined function for some class of candidate.
void setCallInfo(unsigned CID, unsigned CO)
Set the CallConstructionID and CallOverhead of this candidate to CID and CO respectively.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
static cl::opt< unsigned > CBZDisplacementBits("aarch64-cbz-offset-bits", cl::Hidden, cl::init(19), cl::desc("Restrict range of CB[N]Z instructions (DEBUG)"))
static bool canInstrSubstituteCmpInstr(MachineInstr *MI, MachineInstr *CmpInstr, const TargetRegisterInfo *TRI)
Check if CmpInstr can be substituted by MI.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void setImm(int64_t immVal)
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
bool def_empty(unsigned RegNo) const
def_empty - Return true if there are no instructions defining the specified register (it may be live-...
MI-level patchpoint operands.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
bool areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA=nullptr) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool expandPostRAPseudo(MachineInstr &MI) const override
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
const MachineInstrBuilder & addFrameIndex(int Idx) const
bool isThroughputPattern(MachineCombinerPattern Pattern) const override
Return true when a code sequence can improve throughput.
MachineCombinerPattern
These are instruction patterns matched by the machine combiner pass.
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< MachineCombinerPattern > &Patterns) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in Root...
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
MO_HI12 - This flag indicates that a symbol operand represents the bits 13-24 of a 64-bit address...
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
MachineBasicBlock::iterator & front()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned DstReg, ArrayRef< MachineOperand > Cond, unsigned TrueReg, unsigned FalseReg) const override
Emit a call and tail-call.
bool isDebugInstr() const
This class contains a discriminated union of information about pointers in memory operands...
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, unsigned &SubIdx) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
void setIsKill(bool Val=true)
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
The memory access writes data.
static unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg, unsigned *NewVReg=nullptr)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
static bool isIndirectBranchOpcode(int Opc)
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
void setOpcode(unsigned Op)
static bool isUncondBranchOpcode(int Opc)
void getNoop(MCInst &NopInst) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
BlockVerifier::State From
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr...
MachineOperand class - Representation of each machine instruction operand.
bool hasSection() const
Check if this global has a custom object file section.
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
MachineInstrBuilder MachineInstrBuilder & DefMI
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
static bool unscaleOffset(unsigned Opc, int64_t &Offset)
static bool isCombineInstrCandidate(unsigned Opc)
outliner::InstrType getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override
bool optimizeCondBranch(MachineInstr &MI) const override
Replace csincr-branch sequence by simple conditional branch.
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
void addRegisterDefined(unsigned Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Target - Wrapper for Target specific information.
bool isCandidateToMergeOrPair(MachineInstr &MI) const
Return true if this is a load/store that can be potentially paired/merged.
static bool getMaddPatterns(MachineInstr &Root, SmallVectorImpl< MachineCombinerPattern > &Patterns)
Find instructions that can be turned into madd.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
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 readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
static unsigned convertToFlagSettingOpc(unsigned Opc, bool &Is64Bit)
Return the opcode that set flags when possible.
static cl::opt< unsigned > TBZDisplacementBits("aarch64-tbz-offset-bits", cl::Hidden, cl::init(14), cl::desc("Restrict range of TB[N]Z instructions (DEBUG)"))
Optional< bool > hasRedZone() const
MO_S - Indicates that the bits of the symbol operand represented by MO_G0 etc are signed...
CATCHRET - Represents a return from a catch block funclet.
const MachineBasicBlock * getParent() 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.
static MachineInstr * genMaddR(MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineInstr &Root, SmallVectorImpl< MachineInstr *> &InsInstrs, unsigned IdxMulOpd, unsigned MaddOpc, unsigned VR, const TargetRegisterClass *RC)
genMaddR - Generate madd instruction and combine mul and add using an extra virtual register Example ...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
bool isReservedReg(const MachineFunction &MF, unsigned Reg) const
Representation of each machine instruction.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static bool isGPRZero(const MachineInstr &MI)
Does this instruction set its full destination register to zero?
bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, int CmpValue, const MachineRegisterInfo *MRI) const override
optimizeCompareInstr - Convert the instruction supplying the argument to the comparison into one that...
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new 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...
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MI-level stackmap operands.
virtual void genAlternativeCodeSequence(MachineInstr &Root, MachineCombinerPattern Pattern, SmallVectorImpl< MachineInstr *> &InsInstrs, SmallVectorImpl< MachineInstr *> &DelInstrs, DenseMap< unsigned, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "...
void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, llvm::ArrayRef< unsigned > Indices) const
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...
static bool areCFlagsAliveInSuccessors(MachineBasicBlock *MBB)
Check if AArch64::NZCV should be alive in successors of MBB.
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
StringRef getName() const
Return a constant reference to the value's name.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
static MachineOperand CreateImm(int64_t Val)
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page...
void setSubReg(unsigned subReg)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool tracksLiveness() const
tracksLiveness - Returns true when tracking register liveness accurately.
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 isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
static unsigned getBranchDisplacementBits(unsigned Opc)
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
static void storeRegPairToStackSlot(const TargetRegisterInfo &TRI, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MCInstrDesc &MCID, unsigned SrcReg, bool IsKill, unsigned SubIdx0, unsigned SubIdx1, int FI, MachineMemOperand *MMO)
A set of register units used to track register liveness.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg)
static bool isCombineInstrCandidate32(unsigned Opc)
bool hasZeroCycleZeroingFP() const
static bool scaleOffset(unsigned Opc, int64_t &Offset)
bool memoperands_empty() const
Return true if we don't have any memory operands which described the memory access done by this instr...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
bool hasZeroCycleZeroingGP() const
static void loadRegPairFromStackSlot(const TargetRegisterInfo &TRI, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MCInstrDesc &MCID, unsigned DestReg, unsigned SubIdx0, unsigned SubIdx1, int FI, MachineMemOperand *MMO)
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
static bool areCFlagsAccessedBetweenInstrs(MachineBasicBlock::iterator From, MachineBasicBlock::iterator To, const TargetRegisterInfo *TRI, const AccessKind AccessToCheck=AK_All)
True when condition flags are accessed (either by writing or reading) on the instruction trace starti...
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.
unsigned getOpcode() const
Return the opcode number for this descriptor.
Primary interface to the complete machine description for the target machine.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
void addOperand(const MCOperand &Op)
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow...
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
MachineOperand & getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const
Return the immediate offset of the base register in a load/store LdSt.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
UnaryPredicate for_each(R &&Range, UnaryPredicate P)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly...
static bool isCombineInstrSettingFlag(unsigned Opc)
const MachineOperand & getOperand(unsigned i) const
outliner::OutlinedFunction getOutliningCandidateInfo(std::vector< outliner::Candidate > &RepeatedSequenceLocs) const override
bool isIndirectDebugValue() const
A DBG_VALUE is indirect iff the first operand is a register and the second operand is an immediate...
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
static MCOperand createImm(int64_t Val)
MachineFunction * getMF() const
static MachineInstr * genFusedMultiply(MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineInstr &Root, SmallVectorImpl< MachineInstr *> &InsInstrs, unsigned IdxMulOpd, unsigned MaddOpc, const TargetRegisterClass *RC, FMAInstKind kind=FMAInstKind::Default, const unsigned *ReplacedAddend=nullptr)
genFusedMultiply - Generate fused multiply instructions.
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...
The operation is expected to be selectable directly by the target, and no transformation is necessary...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
static const MachineMemOperand::Flags MOStridedAccess
static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, unsigned NumRegs)
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
Returns true if this instruction has the same cost (or less) than a move instruction.
static bool UpdateOperandRegClass(MachineInstr &Instr)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool empty() const
empty - Check if the array is empty.
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
static bool isADDSRegImm(unsigned Opcode)