29 #define GET_INSTRINFO_CTOR_DTOR
30 #include "AArch64GenInstrInfo.inc"
34 RI(STI.getTargetTriple()), Subtarget(STI) {}
97 bool AllowModify)
const {
103 if (!isUnpredicatedTerminator(I))
110 unsigned LastOpc = LastInst->
getOpcode();
111 if (I == MBB.
begin() || !isUnpredicatedTerminator(--I)) {
126 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
133 LastInst = SecondLastInst;
135 if (I == MBB.
begin() || !isUnpredicatedTerminator(--I)) {
141 SecondLastOpc = SecondLastInst->
getOpcode();
147 if (SecondLastInst && I != MBB.
begin() && isUnpredicatedTerminator(--I))
182 if (Cond[0].getImm() != -1) {
188 switch (Cond[1].getImm()) {
192 Cond[1].setImm(AArch64::CBNZW);
195 Cond[1].setImm(AArch64::CBZW);
198 Cond[1].setImm(AArch64::CBNZX);
201 Cond[1].setImm(AArch64::CBZX);
204 Cond[1].setImm(AArch64::TBNZW);
207 Cond[1].setImm(AArch64::TBZW);
210 Cond[1].setImm(AArch64::TBNZX);
213 Cond[1].setImm(AArch64::TBZX);
231 I->eraseFromParent();
235 if (I == MBB.
begin())
242 I->eraseFromParent();
246 void AArch64InstrInfo::instantiateCondBranch(
249 if (Cond[0].getImm() != -1) {
258 MIB.
addImm(Cond[3].getImm());
267 assert(TBB &&
"InsertBranch must not be told to insert a fallthrough");
271 BuildMI(&MBB, DL,
get(AArch64::B)).addMBB(TBB);
273 instantiateCondBranch(MBB, DL, TBB, Cond);
278 instantiateCondBranch(MBB, DL, TBB, Cond);
298 unsigned *NewVReg =
nullptr) {
303 bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.
getRegClass(VReg));
306 unsigned SrcOpNum = 0;
308 case AArch64::ADDSXri:
309 case AArch64::ADDSWri:
314 case AArch64::ADDXri:
315 case AArch64::ADDWri:
321 Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr;
324 case AArch64::ORNXrr:
325 case AArch64::ORNWrr: {
328 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
331 Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr;
335 case AArch64::SUBSXrr:
336 case AArch64::SUBSWrr:
341 case AArch64::SUBXrr:
342 case AArch64::SUBWrr: {
345 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
348 Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr;
354 assert(Opc && SrcOpNum &&
"Missing parameters");
363 unsigned TrueReg,
unsigned FalseReg,
int &CondCycles,
int &TrueCycles,
364 int &FalseCycles)
const {
373 unsigned ExtraCondLat = Cond.
size() != 1;
377 if (AArch64::GPR64allRegClass.hasSubClassEq(RC) ||
378 AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
380 CondCycles = 1 + ExtraCondLat;
381 TrueCycles = FalseCycles = 1;
391 if (AArch64::FPR64RegClass.hasSubClassEq(RC) ||
392 AArch64::FPR32RegClass.hasSubClassEq(RC)) {
393 CondCycles = 5 + ExtraCondLat;
394 TrueCycles = FalseCycles = 2;
406 unsigned TrueReg,
unsigned FalseReg)
const {
411 switch (Cond.
size()) {
420 switch (Cond[1].getImm()) {
440 unsigned SrcReg = Cond[2].getReg();
444 BuildMI(MBB, I, DL,
get(AArch64::SUBSXri), AArch64::XZR)
450 BuildMI(MBB, I, DL,
get(AArch64::SUBSWri), AArch64::WZR)
459 switch (Cond[1].getImm()) {
472 if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW)
473 BuildMI(MBB, I, DL,
get(AArch64::ANDSWri), AArch64::WZR)
478 BuildMI(MBB, I, DL,
get(AArch64::ANDSXri), AArch64::XZR)
488 bool TryFold =
false;
490 RC = &AArch64::GPR64RegClass;
491 Opc = AArch64::CSELXr;
494 RC = &AArch64::GPR32RegClass;
495 Opc = AArch64::CSELWr;
498 RC = &AArch64::FPR64RegClass;
499 Opc = AArch64::FCSELDrrr;
501 RC = &AArch64::FPR32RegClass;
502 Opc = AArch64::FCSELSrrr;
504 assert(RC &&
"Unsupported regclass");
508 unsigned NewVReg = 0;
547 case AArch64::ADDWri:
548 case AArch64::ADDXri:
549 case AArch64::SUBWri:
550 case AArch64::SUBXri:
554 case AArch64::ANDWri:
555 case AArch64::ANDXri:
556 case AArch64::EORWri:
557 case AArch64::EORXri:
558 case AArch64::ORRWri:
559 case AArch64::ORRXri:
563 case AArch64::ANDWrr:
564 case AArch64::ANDXrr:
565 case AArch64::BICWrr:
566 case AArch64::BICXrr:
567 case AArch64::EONWrr:
568 case AArch64::EONXrr:
569 case AArch64::EORWrr:
570 case AArch64::EORXrr:
571 case AArch64::ORNWrr:
572 case AArch64::ORNXrr:
573 case AArch64::ORRWrr:
574 case AArch64::ORRXrr:
582 unsigned &SrcReg,
unsigned &DstReg,
583 unsigned &SubIdx)
const {
587 case AArch64::SBFMXri:
588 case AArch64::UBFMXri:
596 SubIdx = AArch64::sub_32;
606 unsigned BaseRegA = 0, BaseRegB = 0;
607 int OffsetA = 0, OffsetB = 0;
608 int WidthA = 0, WidthB = 0;
610 assert(MIa && MIa->
mayLoadOrStore() &&
"MIa must be a load or store.");
611 assert(MIb && MIb->
mayLoadOrStore() &&
"MIb must be a load or store.");
624 if (BaseRegA == BaseRegB) {
625 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
626 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
627 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
628 if (LowOffset + LowWidth <= HighOffset)
639 unsigned &SrcReg2,
int &CmpMask,
640 int &CmpValue)
const {
644 case AArch64::SUBSWrr:
645 case AArch64::SUBSWrs:
646 case AArch64::SUBSWrx:
647 case AArch64::SUBSXrr:
648 case AArch64::SUBSXrs:
649 case AArch64::SUBSXrx:
650 case AArch64::ADDSWrr:
651 case AArch64::ADDSWrs:
652 case AArch64::ADDSWrx:
653 case AArch64::ADDSXrr:
654 case AArch64::ADDSXrs:
655 case AArch64::ADDSXrx:
662 case AArch64::SUBSWri:
663 case AArch64::ADDSWri:
664 case AArch64::SUBSXri:
665 case AArch64::ADDSXri:
672 case AArch64::ANDSWri:
673 case AArch64::ANDSXri:
686 MI->
getOpcode() == AArch64::ANDSWri ? 32 : 64) != 0);
695 assert(MBB &&
"Can't get MachineBasicBlock here");
697 assert(MF &&
"Can't get MachineFunction here");
702 for (
unsigned OpIdx = 0, EndIdx = Instr->
getNumOperands(); OpIdx < EndIdx;
717 "Operand has register constraints without being a register!");
737 bool MIDefinesZeroReg =
false;
739 MIDefinesZeroReg =
true;
744 case AArch64::ADDSWrr:
745 return AArch64::ADDWrr;
746 case AArch64::ADDSWri:
747 return MIDefinesZeroReg ? AArch64::ADDSWri : AArch64::ADDWri;
748 case AArch64::ADDSWrs:
749 return MIDefinesZeroReg ? AArch64::ADDSWrs : AArch64::ADDWrs;
750 case AArch64::ADDSWrx:
751 return AArch64::ADDWrx;
752 case AArch64::ADDSXrr:
753 return AArch64::ADDXrr;
754 case AArch64::ADDSXri:
755 return MIDefinesZeroReg ? AArch64::ADDSXri : AArch64::ADDXri;
756 case AArch64::ADDSXrs:
757 return MIDefinesZeroReg ? AArch64::ADDSXrs : AArch64::ADDXrs;
758 case AArch64::ADDSXrx:
759 return AArch64::ADDXrx;
760 case AArch64::SUBSWrr:
761 return AArch64::SUBWrr;
762 case AArch64::SUBSWri:
763 return MIDefinesZeroReg ? AArch64::SUBSWri : AArch64::SUBWri;
764 case AArch64::SUBSWrs:
765 return MIDefinesZeroReg ? AArch64::SUBSWrs : AArch64::SUBWrs;
766 case AArch64::SUBSWrx:
767 return AArch64::SUBWrx;
768 case AArch64::SUBSXrr:
769 return AArch64::SUBXrr;
770 case AArch64::SUBSXri:
771 return MIDefinesZeroReg ? AArch64::SUBSXri : AArch64::SUBXri;
772 case AArch64::SUBSXrs:
773 return MIDefinesZeroReg ? AArch64::SUBSXrs : AArch64::SUBXrs;
774 case AArch64::SUBSXrx:
775 return AArch64::SUBXrx;
782 const bool CheckOnlyCCWrites,
797 for (--I; I != E; --
I) {
815 MachineInstr *CmpInstr,
unsigned SrcReg,
unsigned SrcReg2,
int CmpMask,
820 if (Cmp_NZCV != -1) {
835 assert(succeeded &&
"Some operands reg class are incompatible!");
842 assert((CmpValue == 0 || CmpValue == 1) &&
"CmpValue must be 0 or 1!");
843 if (CmpValue != 0 || SrcReg2 != 0)
855 bool CheckOnlyCCWrites =
false;
864 case AArch64::ADDSWrr:
865 case AArch64::ADDSWri:
866 case AArch64::ADDSXrr:
867 case AArch64::ADDSXri:
868 case AArch64::SUBSWrr:
869 case AArch64::SUBSWri:
870 case AArch64::SUBSXrr:
871 case AArch64::SUBSXri:
873 case AArch64::ADDWrr: NewOpc = AArch64::ADDSWrr;
break;
874 case AArch64::ADDWri: NewOpc = AArch64::ADDSWri;
break;
875 case AArch64::ADDXrr: NewOpc = AArch64::ADDSXrr;
break;
876 case AArch64::ADDXri: NewOpc = AArch64::ADDSXri;
break;
877 case AArch64::ADCWr: NewOpc = AArch64::ADCSWr;
break;
878 case AArch64::ADCXr: NewOpc = AArch64::ADCSXr;
break;
879 case AArch64::SUBWrr: NewOpc = AArch64::SUBSWrr;
break;
880 case AArch64::SUBWri: NewOpc = AArch64::SUBSWri;
break;
881 case AArch64::SUBXrr: NewOpc = AArch64::SUBSXrr;
break;
882 case AArch64::SUBXri: NewOpc = AArch64::SUBSXri;
break;
883 case AArch64::SBCWr: NewOpc = AArch64::SBCSWr;
break;
884 case AArch64::SBCXr: NewOpc = AArch64::SBCSXr;
break;
885 case AArch64::ANDWri: NewOpc = AArch64::ANDSWri;
break;
886 case AArch64::ANDXri: NewOpc = AArch64::ANDSXri;
break;
898 !IsSafe && ++
I != E;) {
900 for (
unsigned IO = 0, EO = Instr.
getNumOperands(); !IsSafe && IO != EO;
923 case AArch64::CSINVWr:
924 case AArch64::CSINVXr:
925 case AArch64::CSINCWr:
926 case AArch64::CSINCXr:
927 case AArch64::CSELWr:
928 case AArch64::CSELXr:
929 case AArch64::CSNEGWr:
930 case AArch64::CSNEGXr:
931 case AArch64::FCSELSrrr:
932 case AArch64::FCSELDrrr:
967 assert(succeeded &&
"Some operands reg class are incompatible!");
979 unsigned Reg = MI->getOperand(0).getReg();
981 cast<GlobalValue>((*MI->memoperands_begin())->getValue());
989 BuildMI(MBB, MI, DL,
get(AArch64::LDRXui), Reg)
993 BuildMI(MBB, MI, DL,
get(AArch64::MOVZXi), Reg)
995 BuildMI(MBB, MI, DL,
get(AArch64::MOVKXi), Reg)
998 BuildMI(MBB, MI, DL,
get(AArch64::MOVKXi), Reg)
1001 BuildMI(MBB, MI, DL,
get(AArch64::MOVKXi), Reg)
1004 BuildMI(MBB, MI, DL,
get(AArch64::LDRXui), Reg)
1011 BuildMI(MBB, MI, DL,
get(AArch64::LDRXui), Reg)
1027 case AArch64::ADDSWrs:
1028 case AArch64::ADDSXrs:
1029 case AArch64::ADDWrs:
1030 case AArch64::ADDXrs:
1031 case AArch64::ANDSWrs:
1032 case AArch64::ANDSXrs:
1033 case AArch64::ANDWrs:
1034 case AArch64::ANDXrs:
1035 case AArch64::BICSWrs:
1036 case AArch64::BICSXrs:
1037 case AArch64::BICWrs:
1038 case AArch64::BICXrs:
1039 case AArch64::CRC32Brr:
1040 case AArch64::CRC32CBrr:
1041 case AArch64::CRC32CHrr:
1042 case AArch64::CRC32CWrr:
1043 case AArch64::CRC32CXrr:
1044 case AArch64::CRC32Hrr:
1045 case AArch64::CRC32Wrr:
1046 case AArch64::CRC32Xrr:
1047 case AArch64::EONWrs:
1048 case AArch64::EONXrs:
1049 case AArch64::EORWrs:
1050 case AArch64::EORXrs:
1051 case AArch64::ORNWrs:
1052 case AArch64::ORNXrs:
1053 case AArch64::ORRWrs:
1054 case AArch64::ORRXrs:
1055 case AArch64::SUBSWrs:
1056 case AArch64::SUBSXrs:
1057 case AArch64::SUBWrs:
1058 case AArch64::SUBXrs:
1073 case AArch64::ADDSWrx:
1074 case AArch64::ADDSXrx:
1075 case AArch64::ADDSXrx64:
1076 case AArch64::ADDWrx:
1077 case AArch64::ADDXrx:
1078 case AArch64::ADDXrx64:
1079 case AArch64::SUBSWrx:
1080 case AArch64::SUBSXrx:
1081 case AArch64::SUBSXrx64:
1082 case AArch64::SUBWrx:
1083 case AArch64::SUBXrx:
1084 case AArch64::SUBXrx64:
1101 case AArch64::MOVZWi:
1102 case AArch64::MOVZXi:
1109 case AArch64::ANDWri:
1111 case AArch64::ANDXri:
1128 return (AArch64::GPR32RegClass.
contains(DstReg) ||
1129 AArch64::GPR64RegClass.
contains(DstReg));
1131 case AArch64::ORRXrs:
1138 case AArch64::ADDXri:
1158 return (AArch64::FPR64RegClass.
contains(DstReg) ||
1159 AArch64::FPR128RegClass.
contains(DstReg));
1161 case AArch64::ORRv16i8:
1164 "invalid ORRv16i8 operands");
1177 case AArch64::LDRWui:
1178 case AArch64::LDRXui:
1179 case AArch64::LDRBui:
1180 case AArch64::LDRHui:
1181 case AArch64::LDRSui:
1182 case AArch64::LDRDui:
1183 case AArch64::LDRQui:
1200 case AArch64::STRWui:
1201 case AArch64::STRXui:
1202 case AArch64::STRBui:
1203 case AArch64::STRHui:
1204 case AArch64::STRSui:
1205 case AArch64::STRDui:
1206 case AArch64::STRQui:
1224 case AArch64::LDRBBroW:
1225 case AArch64::LDRBroW:
1226 case AArch64::LDRDroW:
1227 case AArch64::LDRHHroW:
1228 case AArch64::LDRHroW:
1229 case AArch64::LDRQroW:
1230 case AArch64::LDRSBWroW:
1231 case AArch64::LDRSBXroW:
1232 case AArch64::LDRSHWroW:
1233 case AArch64::LDRSHXroW:
1234 case AArch64::LDRSWroW:
1235 case AArch64::LDRSroW:
1236 case AArch64::LDRWroW:
1237 case AArch64::LDRXroW:
1238 case AArch64::STRBBroW:
1239 case AArch64::STRBroW:
1240 case AArch64::STRDroW:
1241 case AArch64::STRHHroW:
1242 case AArch64::STRHroW:
1243 case AArch64::STRQroW:
1244 case AArch64::STRSroW:
1245 case AArch64::STRWroW:
1246 case AArch64::STRXroW:
1247 case AArch64::LDRBBroX:
1248 case AArch64::LDRBroX:
1249 case AArch64::LDRDroX:
1250 case AArch64::LDRHHroX:
1251 case AArch64::LDRHroX:
1252 case AArch64::LDRQroX:
1253 case AArch64::LDRSBWroX:
1254 case AArch64::LDRSBXroX:
1255 case AArch64::LDRSHWroX:
1256 case AArch64::LDRSHXroX:
1257 case AArch64::LDRSWroX:
1258 case AArch64::LDRSroX:
1259 case AArch64::LDRWroX:
1260 case AArch64::LDRXroX:
1261 case AArch64::STRBBroX:
1262 case AArch64::STRBroX:
1263 case AArch64::STRDroX:
1264 case AArch64::STRHHroX:
1265 case AArch64::STRHroX:
1266 case AArch64::STRQroX:
1267 case AArch64::STRSroX:
1268 case AArch64::STRWroX:
1269 case AArch64::STRXroX:
1281 "Too many target MO flags");
1283 if (MM->getFlags() &
1297 "Too many target MO flags");
1309 case AArch64::STRSui:
1310 case AArch64::STRDui:
1311 case AArch64::STRQui:
1312 case AArch64::STRXui:
1313 case AArch64::STRWui:
1314 case AArch64::LDRSui:
1315 case AArch64::LDRDui:
1316 case AArch64::LDRQui:
1317 case AArch64::LDRXui:
1318 case AArch64::LDRWui:
1330 MachineInstr *LdSt,
unsigned &BaseReg,
int &Offset,
int &Width,
1344 case AArch64::LDURQi:
1345 case AArch64::STURQi:
1349 case AArch64::LDURXi:
1350 case AArch64::LDURDi:
1351 case AArch64::STURXi:
1352 case AArch64::STURDi:
1356 case AArch64::LDURWi:
1357 case AArch64::LDURSi:
1358 case AArch64::LDURSWi:
1359 case AArch64::STURWi:
1360 case AArch64::STURSi:
1364 case AArch64::LDURHi:
1365 case AArch64::LDURHHi:
1366 case AArch64::LDURSHXi:
1367 case AArch64::LDURSHWi:
1368 case AArch64::STURHi:
1369 case AArch64::STURHHi:
1373 case AArch64::LDURBi:
1374 case AArch64::LDURBBi:
1375 case AArch64::LDURSBXi:
1376 case AArch64::LDURSBWi:
1377 case AArch64::STURBi:
1378 case AArch64::STURBBi:
1382 case AArch64::LDRXui:
1383 case AArch64::STRXui:
1386 case AArch64::LDRWui:
1387 case AArch64::STRWui:
1390 case AArch64::LDRBui:
1391 case AArch64::STRBui:
1394 case AArch64::LDRHui:
1395 case AArch64::STRHui:
1398 case AArch64::LDRSui:
1399 case AArch64::STRSui:
1402 case AArch64::LDRDui:
1403 case AArch64::STRDui:
1406 case AArch64::LDRQui:
1407 case AArch64::STRQui:
1410 case AArch64::LDRBBui:
1411 case AArch64::STRBBui:
1414 case AArch64::LDRHHui:
1415 case AArch64::STRHHui:
1430 unsigned NumLoads)
const {
1443 return Ofs1 + 1 == Ofs2;
1452 if (Second->
getOpcode() != AArch64::Bcc)
1457 case AArch64::SUBSWri:
1458 case AArch64::ADDSWri:
1459 case AArch64::ANDSWri:
1460 case AArch64::SUBSXri:
1461 case AArch64::ADDSXri:
1462 case AArch64::ANDSXri:
1480 unsigned Reg,
unsigned SubIdx,
1484 return MIB.
addReg(Reg, State);
1488 return MIB.
addReg(Reg, State, SubIdx);
1495 return ((DestReg - SrcReg) & 0x1f) < NumRegs;
1500 unsigned DestReg,
unsigned SrcReg,
bool KillSrc,
unsigned Opcode,
1503 "Unexpected register copy without NEON");
1505 uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
1506 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
1507 unsigned NumRegs = Indices.
size();
1509 int SubReg = 0, End = NumRegs, Incr = 1;
1511 SubReg = NumRegs - 1;
1516 for (; SubReg != End; SubReg += Incr) {
1519 AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI);
1526 unsigned DestReg,
unsigned SrcReg,
1527 bool KillSrc)
const {
1528 if (AArch64::GPR32spRegClass.
contains(DestReg) &&
1529 (AArch64::GPR32spRegClass.
contains(SrcReg) || SrcReg == AArch64::WZR)) {
1532 if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
1537 &AArch64::GPR64spRegClass);
1539 &AArch64::GPR64spRegClass);
1544 BuildMI(MBB, I, DL,
get(AArch64::ADDXri), DestRegX)
1550 BuildMI(MBB, I, DL,
get(AArch64::ADDWri), DestReg)
1562 &AArch64::GPR64spRegClass);
1564 &AArch64::GPR64spRegClass);
1569 BuildMI(MBB, I, DL,
get(AArch64::ORRXrr), DestRegX)
1575 BuildMI(MBB, I, DL,
get(AArch64::ORRWrr), DestReg)
1583 if (AArch64::GPR64spRegClass.
contains(DestReg) &&
1584 (AArch64::GPR64spRegClass.
contains(SrcReg) || SrcReg == AArch64::XZR)) {
1585 if (DestReg == AArch64::SP || SrcReg == AArch64::SP) {
1587 BuildMI(MBB, I, DL,
get(AArch64::ADDXri), DestReg)
1596 BuildMI(MBB, I, DL,
get(AArch64::ORRXrr), DestReg)
1604 if (AArch64::DDDDRegClass.
contains(DestReg) &&
1605 AArch64::DDDDRegClass.
contains(SrcReg)) {
1606 static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1,
1607 AArch64::dsub2, AArch64::dsub3 };
1614 if (AArch64::DDDRegClass.
contains(DestReg) &&
1615 AArch64::DDDRegClass.
contains(SrcReg)) {
1616 static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1,
1624 if (AArch64::DDRegClass.
contains(DestReg) &&
1625 AArch64::DDRegClass.
contains(SrcReg)) {
1626 static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1 };
1633 if (AArch64::QQQQRegClass.
contains(DestReg) &&
1634 AArch64::QQQQRegClass.
contains(SrcReg)) {
1635 static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1,
1636 AArch64::qsub2, AArch64::qsub3 };
1643 if (AArch64::QQQRegClass.
contains(DestReg) &&
1644 AArch64::QQQRegClass.
contains(SrcReg)) {
1645 static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1,
1653 if (AArch64::QQRegClass.
contains(DestReg) &&
1654 AArch64::QQRegClass.
contains(SrcReg)) {
1655 static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1 };
1661 if (AArch64::FPR128RegClass.
contains(DestReg) &&
1662 AArch64::FPR128RegClass.
contains(SrcReg)) {
1664 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
1668 BuildMI(MBB, I, DL,
get(AArch64::STRQpre))
1673 BuildMI(MBB, I, DL,
get(AArch64::LDRQpre))
1682 if (AArch64::FPR64RegClass.
contains(DestReg) &&
1683 AArch64::FPR64RegClass.
contains(SrcReg)) {
1685 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::dsub,
1686 &AArch64::FPR128RegClass);
1687 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::dsub,
1688 &AArch64::FPR128RegClass);
1689 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
1693 BuildMI(MBB, I, DL,
get(AArch64::FMOVDr), DestReg)
1699 if (AArch64::FPR32RegClass.
contains(DestReg) &&
1700 AArch64::FPR32RegClass.
contains(SrcReg)) {
1702 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::ssub,
1703 &AArch64::FPR128RegClass);
1704 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::ssub,
1705 &AArch64::FPR128RegClass);
1706 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
1710 BuildMI(MBB, I, DL,
get(AArch64::FMOVSr), DestReg)
1716 if (AArch64::FPR16RegClass.
contains(DestReg) &&
1717 AArch64::FPR16RegClass.
contains(SrcReg)) {
1719 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
1720 &AArch64::FPR128RegClass);
1721 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
1722 &AArch64::FPR128RegClass);
1723 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
1727 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
1728 &AArch64::FPR32RegClass);
1729 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
1730 &AArch64::FPR32RegClass);
1731 BuildMI(MBB, I, DL,
get(AArch64::FMOVSr), DestReg)
1737 if (AArch64::FPR8RegClass.
contains(DestReg) &&
1738 AArch64::FPR8RegClass.
contains(SrcReg)) {
1740 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
1741 &AArch64::FPR128RegClass);
1742 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
1743 &AArch64::FPR128RegClass);
1744 BuildMI(MBB, I, DL,
get(AArch64::ORRv16i8), DestReg)
1748 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
1749 &AArch64::FPR32RegClass);
1750 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
1751 &AArch64::FPR32RegClass);
1752 BuildMI(MBB, I, DL,
get(AArch64::FMOVSr), DestReg)
1759 if (AArch64::FPR64RegClass.
contains(DestReg) &&
1760 AArch64::GPR64RegClass.
contains(SrcReg)) {
1761 BuildMI(MBB, I, DL,
get(AArch64::FMOVXDr), DestReg)
1765 if (AArch64::GPR64RegClass.
contains(DestReg) &&
1766 AArch64::FPR64RegClass.
contains(SrcReg)) {
1767 BuildMI(MBB, I, DL,
get(AArch64::FMOVDXr), DestReg)
1772 if (AArch64::FPR32RegClass.
contains(DestReg) &&
1773 AArch64::GPR32RegClass.
contains(SrcReg)) {
1774 BuildMI(MBB, I, DL,
get(AArch64::FMOVWSr), DestReg)
1778 if (AArch64::GPR32RegClass.
contains(DestReg) &&
1779 AArch64::FPR32RegClass.
contains(SrcReg)) {
1780 BuildMI(MBB, I, DL,
get(AArch64::FMOVSWr), DestReg)
1786 assert(AArch64::GPR64RegClass.
contains(SrcReg) &&
"Invalid NZCV copy");
1787 BuildMI(MBB, I, DL,
get(AArch64::MSR))
1795 assert(AArch64::GPR64RegClass.
contains(DestReg) &&
"Invalid NZCV copy");
1796 BuildMI(MBB, I, DL,
get(AArch64::MRS))
1811 if (MBBI != MBB.
end())
1812 DL = MBBI->getDebugLoc();
1824 if (AArch64::FPR8RegClass.hasSubClassEq(RC))
1825 Opc = AArch64::STRBui;
1828 if (AArch64::FPR16RegClass.hasSubClassEq(RC))
1829 Opc = AArch64::STRHui;
1832 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
1833 Opc = AArch64::STRWui;
1837 assert(SrcReg != AArch64::WSP);
1838 }
else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
1839 Opc = AArch64::STRSui;
1842 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
1843 Opc = AArch64::STRXui;
1847 assert(SrcReg != AArch64::SP);
1848 }
else if (AArch64::FPR64RegClass.hasSubClassEq(RC))
1849 Opc = AArch64::STRDui;
1852 if (AArch64::FPR128RegClass.hasSubClassEq(RC))
1853 Opc = AArch64::STRQui;
1854 else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
1856 "Unexpected register store without NEON");
1857 Opc = AArch64::ST1Twov1d, Offset =
false;
1861 if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
1863 "Unexpected register store without NEON");
1864 Opc = AArch64::ST1Threev1d, Offset =
false;
1868 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
1870 "Unexpected register store without NEON");
1871 Opc = AArch64::ST1Fourv1d, Offset =
false;
1872 }
else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
1874 "Unexpected register store without NEON");
1875 Opc = AArch64::ST1Twov2d, Offset =
false;
1879 if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
1881 "Unexpected register store without NEON");
1882 Opc = AArch64::ST1Threev2d, Offset =
false;
1886 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
1888 "Unexpected register store without NEON");
1889 Opc = AArch64::ST1Fourv2d, Offset =
false;
1893 assert(Opc &&
"Unknown register class");
1909 if (MBBI != MBB.
end())
1910 DL = MBBI->getDebugLoc();
1922 if (AArch64::FPR8RegClass.hasSubClassEq(RC))
1923 Opc = AArch64::LDRBui;
1926 if (AArch64::FPR16RegClass.hasSubClassEq(RC))
1927 Opc = AArch64::LDRHui;
1930 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
1931 Opc = AArch64::LDRWui;
1935 assert(DestReg != AArch64::WSP);
1936 }
else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
1937 Opc = AArch64::LDRSui;
1940 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
1941 Opc = AArch64::LDRXui;
1945 assert(DestReg != AArch64::SP);
1946 }
else if (AArch64::FPR64RegClass.hasSubClassEq(RC))
1947 Opc = AArch64::LDRDui;
1950 if (AArch64::FPR128RegClass.hasSubClassEq(RC))
1951 Opc = AArch64::LDRQui;
1952 else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
1954 "Unexpected register load without NEON");
1955 Opc = AArch64::LD1Twov1d, Offset =
false;
1959 if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
1961 "Unexpected register load without NEON");
1962 Opc = AArch64::LD1Threev1d, Offset =
false;
1966 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
1968 "Unexpected register load without NEON");
1969 Opc = AArch64::LD1Fourv1d, Offset =
false;
1970 }
else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
1972 "Unexpected register load without NEON");
1973 Opc = AArch64::LD1Twov2d, Offset =
false;
1977 if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
1979 "Unexpected register load without NEON");
1980 Opc = AArch64::LD1Threev2d, Offset =
false;
1984 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
1986 "Unexpected register load without NEON");
1987 Opc = AArch64::LD1Fourv2d, Offset =
false;
1991 assert(Opc &&
"Unknown register class");
2003 unsigned DestReg,
unsigned SrcReg,
int Offset,
2006 if (DestReg == SrcReg && Offset == 0)
2009 bool isSub = Offset < 0;
2026 Opc = isSub ? AArch64::SUBSXri : AArch64::ADDSXri;
2028 Opc = isSub ? AArch64::SUBXri : AArch64::ADDXri;
2029 const unsigned MaxEncoding = 0xfff;
2030 const unsigned ShiftSize = 12;
2031 const unsigned MaxEncodableValue = MaxEncoding << ShiftSize;
2032 while (((
unsigned)Offset) >= (1 << ShiftSize)) {
2034 if (((
unsigned)Offset) > MaxEncodableValue) {
2035 ThisVal = MaxEncodableValue;
2037 ThisVal = Offset & MaxEncodableValue;
2039 assert((ThisVal >> ShiftSize) <= MaxEncoding &&
2040 "Encoding cannot handle value that big");
2041 BuildMI(MBB, MBBI, DL, TII->
get(Opc), DestReg)
2043 .
addImm(ThisVal >> ShiftSize)
2052 BuildMI(MBB, MBBI, DL, TII->
get(Opc), DestReg)
2078 if (SrcReg == AArch64::SP &&
2083 if (DstReg == AArch64::SP &&
2095 bool *OutUseUnscaledOp,
2096 unsigned *OutUnscaledOp,
2097 int *EmittableOffset) {
2099 bool IsSigned =
false;
2101 unsigned ImmIdx = 2;
2102 unsigned UnscaledOp = 0;
2104 if (EmittableOffset)
2105 *EmittableOffset = 0;
2106 if (OutUseUnscaledOp)
2107 *OutUseUnscaledOp =
false;
2114 case AArch64::LD1Twov2d:
2115 case AArch64::LD1Threev2d:
2116 case AArch64::LD1Fourv2d:
2117 case AArch64::LD1Twov1d:
2118 case AArch64::LD1Threev1d:
2119 case AArch64::LD1Fourv1d:
2120 case AArch64::ST1Twov2d:
2121 case AArch64::ST1Threev2d:
2122 case AArch64::ST1Fourv2d:
2123 case AArch64::ST1Twov1d:
2124 case AArch64::ST1Threev1d:
2125 case AArch64::ST1Fourv1d:
2127 case AArch64::PRFMui:
2129 UnscaledOp = AArch64::PRFUMi;
2131 case AArch64::LDRXui:
2133 UnscaledOp = AArch64::LDURXi;
2135 case AArch64::LDRWui:
2137 UnscaledOp = AArch64::LDURWi;
2139 case AArch64::LDRBui:
2141 UnscaledOp = AArch64::LDURBi;
2143 case AArch64::LDRHui:
2145 UnscaledOp = AArch64::LDURHi;
2147 case AArch64::LDRSui:
2149 UnscaledOp = AArch64::LDURSi;
2151 case AArch64::LDRDui:
2153 UnscaledOp = AArch64::LDURDi;
2155 case AArch64::LDRQui:
2157 UnscaledOp = AArch64::LDURQi;
2159 case AArch64::LDRBBui:
2161 UnscaledOp = AArch64::LDURBBi;
2163 case AArch64::LDRHHui:
2165 UnscaledOp = AArch64::LDURHHi;
2167 case AArch64::LDRSBXui:
2169 UnscaledOp = AArch64::LDURSBXi;
2171 case AArch64::LDRSBWui:
2173 UnscaledOp = AArch64::LDURSBWi;
2175 case AArch64::LDRSHXui:
2177 UnscaledOp = AArch64::LDURSHXi;
2179 case AArch64::LDRSHWui:
2181 UnscaledOp = AArch64::LDURSHWi;
2183 case AArch64::LDRSWui:
2185 UnscaledOp = AArch64::LDURSWi;
2188 case AArch64::STRXui:
2190 UnscaledOp = AArch64::STURXi;
2192 case AArch64::STRWui:
2194 UnscaledOp = AArch64::STURWi;
2196 case AArch64::STRBui:
2198 UnscaledOp = AArch64::STURBi;
2200 case AArch64::STRHui:
2202 UnscaledOp = AArch64::STURHi;
2204 case AArch64::STRSui:
2206 UnscaledOp = AArch64::STURSi;
2208 case AArch64::STRDui:
2210 UnscaledOp = AArch64::STURDi;
2212 case AArch64::STRQui:
2214 UnscaledOp = AArch64::STURQi;
2216 case AArch64::STRBBui:
2218 UnscaledOp = AArch64::STURBBi;
2220 case AArch64::STRHHui:
2222 UnscaledOp = AArch64::STURHHi;
2225 case AArch64::LDPXi:
2226 case AArch64::LDPDi:
2227 case AArch64::STPXi:
2228 case AArch64::STPDi:
2232 case AArch64::LDPQi:
2233 case AArch64::STPQi:
2237 case AArch64::LDPWi:
2238 case AArch64::LDPSi:
2239 case AArch64::STPWi:
2240 case AArch64::STPSi:
2245 case AArch64::LDURXi:
2246 case AArch64::LDURWi:
2247 case AArch64::LDURBi:
2248 case AArch64::LDURHi:
2249 case AArch64::LDURSi:
2250 case AArch64::LDURDi:
2251 case AArch64::LDURQi:
2252 case AArch64::LDURHHi:
2253 case AArch64::LDURBBi:
2254 case AArch64::LDURSBXi:
2255 case AArch64::LDURSBWi:
2256 case AArch64::LDURSHXi:
2257 case AArch64::LDURSHWi:
2258 case AArch64::LDURSWi:
2259 case AArch64::STURXi:
2260 case AArch64::STURWi:
2261 case AArch64::STURBi:
2262 case AArch64::STURHi:
2263 case AArch64::STURSi:
2264 case AArch64::STURDi:
2265 case AArch64::STURQi:
2266 case AArch64::STURBBi:
2267 case AArch64::STURHHi:
2274 bool useUnscaledOp =
false;
2278 if ((Offset & (Scale - 1)) != 0 || (Offset < 0 && UnscaledOp != 0))
2279 useUnscaledOp =
true;
2288 }
else if (UnscaledOp == 0 || useUnscaledOp) {
2299 int MaxOff = (1 << (MaskBits - IsSigned)) - 1;
2300 int MinOff = (IsSigned ? (-MaxOff - 1) : 0);
2301 if (Offset >= MinOff && Offset <= MaxOff) {
2302 if (EmittableOffset)
2303 *EmittableOffset = Offset;
2306 int NewOff = Offset < 0 ? MinOff : MaxOff;
2307 if (EmittableOffset)
2308 *EmittableOffset = NewOff;
2309 Offset = (Offset - NewOff) * Scale;
2311 if (OutUseUnscaledOp)
2312 *OutUseUnscaledOp = useUnscaledOp;
2314 *OutUnscaledOp = UnscaledOp;
2320 unsigned FrameReg,
int &Offset,
2323 unsigned ImmIdx = FrameRegIdx + 1;
2325 if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) {
2336 unsigned UnscaledOp;
2339 &UnscaledOp, &NewOffset);
2345 MI.
setDesc(TII->get(UnscaledOp));
2367 case AArch64::ADDSWrr:
2368 case AArch64::ADDSWri:
2369 case AArch64::ADDSXrr:
2370 case AArch64::ADDSXri:
2371 case AArch64::SUBSWrr:
2372 case AArch64::SUBSXrr:
2374 case AArch64::SUBSWri:
2375 case AArch64::SUBSXri:
2386 case AArch64::ADDWrr:
2387 case AArch64::ADDWri:
2388 case AArch64::SUBWrr:
2389 case AArch64::ADDSWrr:
2390 case AArch64::ADDSWri:
2391 case AArch64::SUBSWrr:
2393 case AArch64::SUBWri:
2394 case AArch64::SUBSWri:
2405 case AArch64::ADDXrr:
2406 case AArch64::ADDXri:
2407 case AArch64::SUBXrr:
2408 case AArch64::ADDSXrr:
2409 case AArch64::ADDSXri:
2410 case AArch64::SUBSXrr:
2412 case AArch64::SUBXri:
2413 case AArch64::SUBSXri:
2427 unsigned MulOpc,
unsigned ZeroReg) {
2483 case AArch64::ADDWrr:
2485 "ADDWrr does not have register operands");
2497 case AArch64::ADDXrr:
2509 case AArch64::SUBWrr:
2521 case AArch64::SUBXrr:
2533 case AArch64::ADDWri:
2540 case AArch64::ADDXri:
2547 case AArch64::SUBWri:
2554 case AArch64::SUBXri:
2579 unsigned IdxMulOpd,
unsigned MaddOpc,
2581 assert(IdxMulOpd == 1 || IdxMulOpd == 2);
2583 unsigned IdxOtherOpd = IdxMulOpd == 1 ? 2 : 1;
2630 unsigned IdxMulOpd,
unsigned MaddOpc,
2632 assert(IdxMulOpd == 1 || IdxMulOpd == 2);
2687 Opc = AArch64::MADDWrrr;
2688 RC = &AArch64::GPR32RegClass;
2690 Opc = AArch64::MADDXrrr;
2691 RC = &AArch64::GPR64RegClass;
2693 MUL =
genMadd(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC);
2702 Opc = AArch64::MADDWrrr;
2703 RC = &AArch64::GPR32RegClass;
2705 Opc = AArch64::MADDXrrr;
2706 RC = &AArch64::GPR64RegClass;
2708 MUL =
genMadd(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC);
2718 unsigned BitSize, OrrOpc, ZeroReg;
2720 OrrOpc = AArch64::ORRWri;
2721 OrrRC = &AArch64::GPR32spRegClass;
2723 ZeroReg = AArch64::WZR;
2724 Opc = AArch64::MADDWrrr;
2725 RC = &AArch64::GPR32RegClass;
2727 OrrOpc = AArch64::ORRXri;
2728 OrrRC = &AArch64::GPR64spRegClass;
2730 ZeroReg = AArch64::XZR;
2731 Opc = AArch64::MADDXrrr;
2732 RC = &AArch64::GPR64RegClass;
2741 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize);
2749 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
2750 MUL =
genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
2762 unsigned SubOpc, ZeroReg;
2764 SubOpc = AArch64::SUBWrr;
2765 SubRC = &AArch64::GPR32spRegClass;
2766 ZeroReg = AArch64::WZR;
2767 Opc = AArch64::MADDWrrr;
2768 RC = &AArch64::GPR32RegClass;
2770 SubOpc = AArch64::SUBXrr;
2771 SubRC = &AArch64::GPR64spRegClass;
2772 ZeroReg = AArch64::XZR;
2773 Opc = AArch64::MADDXrrr;
2774 RC = &AArch64::GPR64RegClass;
2783 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
2784 MUL =
genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
2794 Opc = AArch64::MSUBWrrr;
2795 RC = &AArch64::GPR32RegClass;
2797 Opc = AArch64::MSUBXrrr;
2798 RC = &AArch64::GPR64RegClass;
2800 MUL =
genMadd(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC);
2810 unsigned BitSize, OrrOpc, ZeroReg;
2812 OrrOpc = AArch64::ORRWri;
2813 OrrRC = &AArch64::GPR32spRegClass;
2815 ZeroReg = AArch64::WZR;
2816 Opc = AArch64::MADDWrrr;
2817 RC = &AArch64::GPR32RegClass;
2819 OrrOpc = AArch64::ORRXri;
2820 OrrRC = &AArch64::GPR64spRegClass;
2822 ZeroReg = AArch64::XZR;
2823 Opc = AArch64::MADDXrrr;
2824 RC = &AArch64::GPR64RegClass;
2832 uint64_t UImm = -Imm << (64 - BitSize) >> (64 - BitSize);
2840 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
2841 MUL =
genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC);
2872 bool IsNegativeBranch =
false;
2873 bool IsTestAndBranch =
false;
2874 unsigned TargetBBInMI = 0;
2884 case AArch64::CBNZW:
2885 case AArch64::CBNZX:
2887 IsNegativeBranch =
true;
2892 IsTestAndBranch =
true;
2894 case AArch64::TBNZW:
2895 case AArch64::TBNZX:
2897 IsNegativeBranch =
true;
2898 IsTestAndBranch =
true;
2908 assert(MI->
getParent() &&
"Incomplete machine instruciton\n");
2919 if (!(DefMI->
getOpcode() == AArch64::CSINCWr &&
2922 !(DefMI->
getOpcode() == AArch64::CSINCXr &&
2932 bool CheckOnlyCCWrites =
true;
2941 if (IsNegativeBranch)
bool hasExtendedReg(const MachineInstr *MI) const
Returns true if there is an extendable register and that the extending value is non-zero.
unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const override
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
void push_back(const T &Elt)
The memory access reads data.
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
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...
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address...
const AArch64RegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
The memory access writes data.
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex) const override
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg, unsigned &Offset, const TargetRegisterInfo *TRI) 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...
MachineBasicBlock * getMBB() const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasSubClassEq(const TargetRegisterClass *RC) const
hasSubClassEq - Returns true if RC is a sub-class of or equal to this class.
static CondCode getInvertedCondCode(CondCode Code)
bool hasZeroCycleRegMove() const
Describe properties that are true of each instruction in the target description file.
static bool isVirtualRegister(unsigned Reg)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
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 ...
bool hasZeroCycleZeroing() const
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
Offset can apply, at least partly.
bool use_nodbg_empty(unsigned RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const char * getSymbolName() const
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address...
void getNoopForMachoTarget(MCInst &NopInst) const override
bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
iterator_range< mmo_iterator > memoperands()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
getMachineMemOperand - Allocate a new MachineMemOperand.
iterator_range< succ_iterator > successors()
bool optimizeCondBranch(MachineInstr *MI) const override
Replace csincr-branch sequence by simple conditional branch.
bool isLdStPairSuppressed(const MachineInstr *MI) const
Return true if pairing the given load or store is hinted to be unprofitable.
bool getMemOpBaseRegImmOfsWidth(MachineInstr *LdSt, unsigned &BaseReg, int &Offset, int &Width, const TargetRegisterInfo *TRI) const
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...
static bool getMemDoShift(unsigned Imm)
getMemDoShift - Extract the "do shift" flag value for load/store instructions.
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 ...
COPY - Target-independent register copy.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
MachineMemOperand - A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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 eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const TargetRegisterClass * getRegClass(unsigned Reg) const
getRegClass - Return the register class of the specified virtual register.
bool useMachineCombiner() const override
useMachineCombiner - AArch64 supports MachineCombiner
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static bool canCombineWithMUL(MachineBasicBlock &MBB, MachineOperand &MO, unsigned MulOpc, unsigned ZeroReg)
static const PseudoSourceValue * getFixedStack(int FI)
A pseudo source value referencing a fixed stack frame entry, e.g., a spill slot.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
INLINEASM - Represents an inline asm block.
static bool isCombineInstrCandidate64(unsigned Opc)
unsigned getNumOperands() const
Access to explicit operands of the instruction.
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, DebugLoc DL) const override
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.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
AArch64InstrInfo(const AArch64Subtarget &STI)
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DstReg, ArrayRef< MachineOperand > Cond, unsigned TrueReg, unsigned FalseReg) const override
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
MachineInstr * emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, uint64_t Offset, const MDNode *Var, const MDNode *Expr, DebugLoc DL) const
static AArch64_AM::ShiftExtendType getMemExtendType(unsigned Imm)
getExtendType - Extract the extend type for the offset operand of loads/stores.
bool isAsCheapAsAMove(const MachineInstr *MI) const override
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
getMatchingSuperReg - Return a super-register of the specified register Reg so its sub-register of in...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
iterator getLastNonDebugInstr()
getLastNonDebugInstr - returns an iterator to the last non-debug instruction in the basic block...
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, unsigned, unsigned, int &, int &, int &) const override
bool hasShiftedReg(const MachineInstr *MI) const
Returns true if there is a shiftable register and that the shift value is non-zero.
size_t size() const
size - Get the array size.
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
Instances of this class represent a single low-level machine instruction.
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
static bool isCondBranchOpcode(int Opc)
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< MachineCombinerPattern::MC_PATTERN > &Patterns) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in <Root...
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
unsigned getDefRegState(bool B)
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned RemoveBranch(MachineBasicBlock &MBB) const override
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address...
static MachineInstr * genMadd(MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineInstr &Root, SmallVectorImpl< MachineInstr * > &InsInstrs, unsigned IdxMulOpd, unsigned MaddOpc, const TargetRegisterClass *RC)
genMadd - Generate madd instruction and combine mul and add.
static bool modifiesConditionCode(MachineInstr *From, MachineInstr *To, const bool CheckOnlyCCWrites, const TargetRegisterInfo *TRI)
True when condition code could be modified on the instruction trace starting at from and ending at to...
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, int Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
bool isFPRCopy(const MachineInstr *MI) const
Does this instruction rename an FPR without modifying bits?
static bool UpdateOperandRegClass(MachineInstr *Instr)
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
Returns true if this instruction has the same cost (or less) than a move instruction.
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...
const MachineOperand & getOperand(unsigned i) const
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
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...
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
This pseudo-instruction loads the stack guard value.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
bool isGPRZero(const MachineInstr *MI) const
Does this instruction set its full destination register to zero?
bool empty() const
empty - Check if the array is empty.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
unsigned getSubReg() const
bool shouldScheduleAdjacent(MachineInstr *First, MachineInstr *Second) const override
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MachinePointerInfo - This class contains a discriminated union of information about pointers in memor...
bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, unsigned &SubIdx) const override
unsigned char ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const
ClassifyGlobalReference - Find the target operand flags that describe how a global value should be re...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
static unsigned getRegClass(bool IsVgpr, unsigned RegWidth)
unsigned getOpcode() const
Return the opcode number for this descriptor.
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...
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
bool shouldClusterLoads(MachineInstr *FirstLdSt, MachineInstr *SecondLdSt, unsigned NumLoads) const override
Detect opportunities for ldp/stp formation.
bool memoperands_empty() const
static bool isIndirectBranchOpcode(int Opc)
void suppressLdStPair(MachineInstr *MI) const
Hint that pairing the given load or store is unprofitable.
unsigned GetInstSizeInBytes(const MachineInstr *MI) const
GetInstSize - Return the number of bytes of code the specified instruction may be.
void setOpcode(unsigned Op)
static bool isUncondBranchOpcode(int Opc)
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
static bool isCombineInstrCandidate(unsigned Opc)
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineInstrBuilder & addFrameIndex(int Idx) const
void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, llvm::ArrayRef< unsigned > Indices) const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
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.
Target - Wrapper for Target specific information.
const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
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.
KILL - This instruction is a noop that is used only to adjust the liveness of registers.
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.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
bool isLiveIn(unsigned Reg) const
isLiveIn - Return true if the specified register is in the live in set.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
bool isGPRCopy(const MachineInstr *MI) const
Does this instruction rename a GPR without modifying bits?
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static MachineOperand CreateImm(int64_t Val)
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page...
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
static unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg)
static bool isCombineInstrCandidate32(unsigned Opc)
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
void genAlternativeCodeSequence(MachineInstr &Root, MachineCombinerPattern::MC_PATTERN Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
bool areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb, AliasAnalysis *AA=nullptr) const override
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
static unsigned convertFlagSettingOpcode(const MachineInstr *MI)
Return the opcode that does not set flags when possible - otherwise return the original opcode...
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
Primary interface to the complete machine description for the target machine.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const override
void addOperand(const MCOperand &Op)
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
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...
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
static bool isCombineInstrSettingFlag(unsigned Opc)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
static MCOperand createImm(int64_t Val)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, unsigned NumRegs)
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
bool isScaledAddr(const MachineInstr *MI) const
Return true if this is load/store scales or extends its register offset.
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.