49#define GET_INSTRINFO_CTOR_DTOR
50#define GET_INSTRMAP_INFO
51#include "SystemZGenInstrInfo.inc"
53#define DEBUG_TYPE "systemz-II"
61void SystemZInstrInfo::anchor() {}
65 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister(),
72 unsigned NewOpcode)
const {
80 MBB->insert(LowPartMI, HighPartMI);
88 HighRegOp.
setReg(RI.getSubReg(HighRegOp.
getReg(), SystemZ::subreg_h64));
89 LowRegOp.
setReg(RI.getSubReg(LowRegOp.
getReg(), SystemZ::subreg_l64));
100 assert(HighOpcode && LowOpcode &&
"Both offsets should be in range");
105 if (
MI->mayStore()) {
117 auto overlapsAddressReg = [&](
Register Reg) ->
bool {
118 return RI.regsOverlap(
Reg,
MI->getOperand(1).getReg()) ||
119 RI.regsOverlap(
Reg,
MI->getOperand(3).getReg());
121 if (overlapsAddressReg(HighRegOp.
getReg())) {
123 "Both loads clobber address!");
136 MachineBasicBlock *
MBB =
MI->getParent();
139 MachineOperand &OffsetMO =
MI->getOperand(2);
140 SystemZCallingConventionRegisters *Regs = STI.getSpecialRegisters();
147 assert(NewOpcode &&
"No support for huge argument lists yet");
148 MI->setDesc(
get(NewOpcode));
158void SystemZInstrInfo::expandRIPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
160 bool ConvertHigh)
const {
163 MI.setDesc(
get(IsHigh ? HighOpcode : LowOpcode));
164 if (IsHigh && ConvertHigh)
165 MI.getOperand(1).setImm(uint32_t(
MI.getOperand(1).getImm()));
172void SystemZInstrInfo::expandRIEPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
174 unsigned HighOpcode)
const {
179 if (!DestIsHigh && !SrcIsHigh)
180 MI.setDesc(
get(LowOpcodeK));
182 if (DestReg != SrcReg) {
183 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(), DestReg, SrcReg,
184 SystemZ::LR, 32,
MI.getOperand(1).isKill(),
185 MI.getOperand(1).isUndef());
186 MI.getOperand(1).setReg(DestReg);
188 MI.setDesc(
get(DestIsHigh ? HighOpcode : LowOpcode));
189 MI.tieOperands(0, 1);
196void SystemZInstrInfo::expandRXYPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
197 unsigned HighOpcode)
const {
201 MI.getOperand(2).getImm());
202 MI.setDesc(
get(Opcode));
208void SystemZInstrInfo::expandLOCPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
209 unsigned HighOpcode)
const {
212 MI.setDesc(
get(Opcode));
218void SystemZInstrInfo::expandZExtPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
219 unsigned Size)
const {
220 MachineInstrBuilder MIB =
221 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(),
222 MI.getOperand(0).getReg(),
MI.getOperand(1).getReg(), LowOpcode,
223 Size,
MI.getOperand(1).isKill(),
MI.getOperand(1).isUndef());
229 MI.eraseFromParent();
232void SystemZInstrInfo::expandLoadStackGuard(
MachineInstr *
MI)
const {
233 MachineBasicBlock *
MBB =
MI->getParent();
235 const Register Reg64 =
MI->getOperand(0).getReg();
236 const Register Reg32 = RI.getSubReg(Reg64, SystemZ::subreg_l32);
257 MI->setDesc(
get(SystemZ::LG));
258 MachineInstrBuilder(MF,
MI).addReg(Reg64).addImm(40).addReg(0);
270 unsigned SrcReg,
unsigned LowLowOpcode,
271 unsigned Size,
bool KillSrc,
272 bool UndefSrc)
const {
276 if (DestIsHigh && SrcIsHigh)
277 Opcode = SystemZ::RISBHH;
278 else if (DestIsHigh && !SrcIsHigh)
279 Opcode = SystemZ::RISBHL;
280 else if (!DestIsHigh && SrcIsHigh)
281 Opcode = SystemZ::RISBLH;
286 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
296 unsigned OpIdx2)
const {
299 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
303 switch (
MI.getOpcode()) {
304 case SystemZ::SELRMux:
305 case SystemZ::SELFHR:
308 case SystemZ::LOCRMux:
309 case SystemZ::LOCFHR:
311 case SystemZ::LOCGR: {
312 auto &WorkingMI = cloneIfNew(
MI);
314 unsigned CCValid = WorkingMI.getOperand(3).getImm();
315 unsigned CCMask = WorkingMI.getOperand(4).getImm();
316 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
333 if ((
MCID.TSFlags & Flag) &&
MI.getOperand(1).isFI() &&
334 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).getReg() == 0) {
335 FrameIndex =
MI.getOperand(1).getIndex();
336 return MI.getOperand(0).getReg();
342 int &FrameIndex)
const {
347 int &FrameIndex)
const {
352 int &FrameIndex)
const {
369 return MI.getOperand(0).getReg();
375 int &FrameIndex)
const {
392 return MI.getOperand(0).getReg();
399 int &SrcFrameIndex)
const {
402 if (
MI.getOpcode() != SystemZ::MVC || !
MI.getOperand(0).isFI() ||
403 MI.getOperand(1).getImm() != 0 || !
MI.getOperand(3).isFI() ||
404 MI.getOperand(4).getImm() != 0)
408 int64_t
Length =
MI.getOperand(2).getImm();
409 unsigned FI1 =
MI.getOperand(0).getIndex();
410 unsigned FI2 =
MI.getOperand(3).getIndex();
415 DestFrameIndex = FI1;
424 bool AllowModify)
const {
430 while (
I !=
MBB.begin()) {
432 if (
I->isDebugInstr())
437 if (!isUnpredicatedTerminator(*
I))
447 if (!Branch.hasMBBTarget())
457 TBB = Branch.getMBBTarget();
462 MBB.erase(std::next(
I),
MBB.end());
468 if (
MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
470 I->eraseFromParent();
476 TBB = Branch.getMBBTarget();
484 TBB = Branch.getMBBTarget();
491 assert(
Cond.size() == 2 &&
TBB &&
"Should have seen a conditional branch");
495 if (
TBB != Branch.getMBBTarget())
499 unsigned OldCCValid =
Cond[0].getImm();
500 unsigned OldCCMask =
Cond[1].getImm();
501 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
512 int *BytesRemoved)
const {
513 assert(!BytesRemoved &&
"code size not handled");
519 while (
I !=
MBB.begin()) {
521 if (
I->isDebugInstr())
528 I->eraseFromParent();
538 assert(
Cond.size() == 2 &&
"Invalid condition");
548 int *BytesAdded)
const {
554 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
556 "SystemZ branch conditions have one component!");
557 assert(!BytesAdded &&
"code size not handled");
561 assert(!FBB &&
"Unconditional branch with multiple successors!");
568 unsigned CCValid =
Cond[0].getImm();
569 unsigned CCMask =
Cond[1].getImm();
584 int64_t &
Value)
const {
585 assert(
MI.isCompare() &&
"Caller should have checked for a comparison");
587 if (
MI.getNumExplicitOperands() == 2 &&
MI.getOperand(0).isReg() &&
588 MI.getOperand(1).isImm()) {
589 SrcReg =
MI.getOperand(0).getReg();
591 Value =
MI.getOperand(1).getImm();
604 int &FalseCycles)
const {
606 if (!STI.hasLoadStoreOnCond())
608 if (Pred.size() != 2)
619 if ((STI.hasLoadStoreOnCond2() &&
620 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
621 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
622 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
642 assert(Pred.size() == 2 &&
"Invalid condition");
643 unsigned CCValid = Pred[0].getImm();
644 unsigned CCMask = Pred[1].getImm();
647 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
648 if (STI.hasMiscellaneousExtensions3())
649 Opc = SystemZ::SELRMux;
650 else if (STI.hasLoadStoreOnCond2())
651 Opc = SystemZ::LOCRMux;
662 }
else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
663 if (STI.hasMiscellaneousExtensions3())
664 Opc = SystemZ::SELGR;
666 Opc = SystemZ::LOCGR;
678 unsigned DefOpc =
DefMI.getOpcode();
680 if (DefOpc == SystemZ::VGBM) {
681 int64_t ImmVal =
DefMI.getOperand(1).getImm();
696 MRI->
getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
706 UseMI.setDesc(
get(SystemZ::REG_SEQUENCE));
707 UseMI.getOperand(1).setReg(TmpReg);
709 .
addImm(SystemZ::subreg_h64)
711 .
addImm(SystemZ::subreg_l64);
714 DefMI.eraseFromParent();
721 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
722 DefOpc != SystemZ::LGHI)
724 if (
DefMI.getOperand(0).getReg() != Reg)
726 int32_t ImmVal = (int32_t)
DefMI.getOperand(1).getImm();
728 unsigned UseOpc =
UseMI.getOpcode();
734 case SystemZ::SELRMux:
737 case SystemZ::LOCRMux:
738 if (!STI.hasLoadStoreOnCond2())
740 NewUseOpc = SystemZ::LOCHIMux;
741 if (
UseMI.getOperand(2).getReg() == Reg)
743 else if (
UseMI.getOperand(1).getReg() == Reg)
744 UseIdx = 2, CommuteIdx = 1;
752 if (!STI.hasLoadStoreOnCond2())
754 NewUseOpc = SystemZ::LOCGHI;
755 if (
UseMI.getOperand(2).getReg() == Reg)
757 else if (
UseMI.getOperand(1).getReg() == Reg)
758 UseIdx = 2, CommuteIdx = 1;
766 if (CommuteIdx != -1)
767 if (!commuteInstruction(
UseMI,
false, CommuteIdx, UseIdx))
773 UseMI.tieOperands(0, 1);
774 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
776 DefMI.eraseFromParent();
782 unsigned Opcode =
MI.getOpcode();
783 if (Opcode == SystemZ::Return ||
784 Opcode == SystemZ::Return_XPLINK ||
785 Opcode == SystemZ::Trap ||
786 Opcode == SystemZ::CallJG ||
787 Opcode == SystemZ::CallBR)
794 unsigned NumCycles,
unsigned ExtraPredCycles,
804 if (
MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap &&
808 return NumCycles == 1;
813 unsigned NumCyclesT,
unsigned ExtraPredCyclesT,
815 unsigned NumCyclesF,
unsigned ExtraPredCyclesF,
825 return NumCycles == 1;
830 assert(Pred.size() == 2 &&
"Invalid condition");
831 unsigned CCValid = Pred[0].getImm();
832 unsigned CCMask = Pred[1].getImm();
833 assert(CCMask > 0 && CCMask < 15 &&
"Invalid predicate");
834 unsigned Opcode =
MI.getOpcode();
835 if (Opcode == SystemZ::Trap) {
836 MI.setDesc(
get(SystemZ::CondTrap));
842 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
843 MI.setDesc(
get(Opcode == SystemZ::Return ? SystemZ::CondReturn
844 : SystemZ::CondReturn_XPLINK));
851 if (Opcode == SystemZ::CallJG) {
853 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
856 MI.setDesc(
get(SystemZ::CallBRCL));
865 if (Opcode == SystemZ::CallBR) {
867 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
870 MI.setDesc(
get(SystemZ::CallBCR));
886 bool RenamableSrc)
const {
890 if (SystemZ::GR128BitRegClass.
contains(DestReg, SrcReg)) {
892 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
896 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
902 if (SystemZ::GRX32BitRegClass.
contains(DestReg, SrcReg)) {
903 emitGRX32Move(
MBB,
MBBI,
DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
909 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
910 SystemZ::FP128BitRegClass.
contains(SrcReg)) {
912 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
913 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
915 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
916 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
923 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
924 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
926 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
927 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
929 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
930 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
932 if (DestRegHi != SrcReg.
asMCReg())
939 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
940 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
941 MCRegister DestRegHi = RI.getSubReg(DestReg, SystemZ::subreg_h64);
942 MCRegister DestRegLo = RI.getSubReg(DestReg, SystemZ::subreg_l64);
943 MCRegister SrcRegHi = RI.getSubReg(SrcReg, SystemZ::subreg_h64);
944 MCRegister SrcRegLo = RI.getSubReg(SrcReg, SystemZ::subreg_l64);
956 if (DestReg == SystemZ::CC) {
958 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
965 if (SystemZ::GR128BitRegClass.
contains(DestReg) &&
966 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
967 MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64);
968 MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64);
972 .
addReg(SystemZ::NoRegister)
977 .
addReg(SystemZ::NoRegister)
982 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
983 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
985 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64))
986 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64));
992 if (SystemZ::GR64BitRegClass.
contains(DestReg, SrcReg))
993 Opcode = SystemZ::LGR;
994 else if (SystemZ::FP16BitRegClass.
contains(DestReg, SrcReg))
995 Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
996 else if (SystemZ::FP32BitRegClass.
contains(DestReg, SrcReg))
998 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
999 else if (SystemZ::FP64BitRegClass.
contains(DestReg, SrcReg))
1000 Opcode = SystemZ::LDR;
1001 else if (SystemZ::FP128BitRegClass.
contains(DestReg, SrcReg))
1002 Opcode = SystemZ::LXR;
1003 else if (SystemZ::VR16BitRegClass.
contains(DestReg, SrcReg))
1004 Opcode = SystemZ::VLR16;
1005 else if (SystemZ::VR32BitRegClass.
contains(DestReg, SrcReg))
1006 Opcode = SystemZ::VLR32;
1007 else if (SystemZ::VR64BitRegClass.
contains(DestReg, SrcReg))
1008 Opcode = SystemZ::VLR64;
1009 else if (SystemZ::VR128BitRegClass.
contains(DestReg, SrcReg))
1010 Opcode = SystemZ::VLR;
1011 else if (SystemZ::AR32BitRegClass.
contains(DestReg, SrcReg))
1012 Opcode = SystemZ::CPYA;
1013 else if (SystemZ::GR64BitRegClass.
contains(DestReg) &&
1014 SystemZ::FP64BitRegClass.
contains(SrcReg))
1015 Opcode = SystemZ::LGDR;
1016 else if (SystemZ::FP64BitRegClass.
contains(DestReg) &&
1017 SystemZ::GR64BitRegClass.
contains(SrcReg))
1018 Opcode = SystemZ::LDGR;
1035 unsigned LoadOpcode, StoreOpcode;
1052 unsigned LoadOpcode, StoreOpcode;
1062 return ((
MCID.TSFlags & Flag) &&
1064 MI->getOperand(3).getReg() == 0);
1070 LogicOp() =
default;
1071 LogicOp(
unsigned regSize,
unsigned immLSB,
unsigned immSize)
1072 :
RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1074 explicit operator bool()
const {
return RegSize; }
1077 unsigned ImmLSB = 0;
1078 unsigned ImmSize = 0;
1085 case SystemZ::NILMux:
return LogicOp(32, 0, 16);
1086 case SystemZ::NIHMux:
return LogicOp(32, 16, 16);
1087 case SystemZ::NILL64:
return LogicOp(64, 0, 16);
1088 case SystemZ::NILH64:
return LogicOp(64, 16, 16);
1089 case SystemZ::NIHL64:
return LogicOp(64, 32, 16);
1090 case SystemZ::NIHH64:
return LogicOp(64, 48, 16);
1091 case SystemZ::NIFMux:
return LogicOp(32, 0, 32);
1092 case SystemZ::NILF64:
return LogicOp(64, 0, 32);
1093 case SystemZ::NIHF64:
return LogicOp(64, 32, 32);
1094 default:
return LogicOp();
1102 if (CCDef !=
nullptr)
1124 unsigned Start, End;
1127 if (
And.RegSize == 64) {
1128 NewOpcode = SystemZ::RISBG;
1130 if (STI.hasMiscellaneousExtensions())
1131 NewOpcode = SystemZ::RISBGN;
1133 NewOpcode = SystemZ::RISBMux;
1149 unsigned NumOps =
MI.getNumOperands();
1152 if (
Op.isReg() &&
Op.isKill())
1166 bool Invert)
const {
1172 Opc = *InverseOpcode;
1179 case SystemZ::WFADB:
1180 case SystemZ::WFASB:
1181 case SystemZ::WFAXB:
1182 case SystemZ::VFADB:
1183 case SystemZ::VFASB:
1184 case SystemZ::WFMDB:
1185 case SystemZ::WFMSB:
1186 case SystemZ::WFMXB:
1187 case SystemZ::VFMDB:
1188 case SystemZ::VFMSB:
1196std::optional<unsigned>
1200 case SystemZ::WFADB:
1201 return SystemZ::WFSDB;
1202 case SystemZ::WFASB:
1203 return SystemZ::WFSSB;
1204 case SystemZ::WFAXB:
1205 return SystemZ::WFSXB;
1206 case SystemZ::VFADB:
1207 return SystemZ::VFSDB;
1208 case SystemZ::VFASB:
1209 return SystemZ::VFSSB;
1211 case SystemZ::WFSDB:
1212 return SystemZ::WFADB;
1213 case SystemZ::WFSSB:
1214 return SystemZ::WFASB;
1215 case SystemZ::WFSXB:
1216 return SystemZ::WFAXB;
1217 case SystemZ::VFSDB:
1218 return SystemZ::VFADB;
1219 case SystemZ::VFSSB:
1220 return SystemZ::VFASB;
1222 return std::nullopt;
1235 unsigned Opcode =
MI.getOpcode();
1240 bool CCLiveAtMI =
true;
1245 CCLiveRange = &LIS->
getRegUnit(*CCUnits.begin());
1246 CCLiveAtMI = CCLiveRange->
liveAt(MISlot);
1249 if (
Ops.size() == 2 &&
Ops[0] == 0 &&
Ops[1] == 1) {
1250 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1251 isInt<8>(
MI.getOperand(2).getImm()) && !
MI.getOperand(3).getReg()) {
1254 MI.getDebugLoc(),
get(SystemZ::AGSI))
1257 .
addImm(
MI.getOperand(2).getImm());
1267 if (
Ops.size() != 1)
1270 unsigned OpNum =
Ops[0];
1274 (RC == &SystemZ::FP16BitRegClass &&
Size == 4 && !STI.hasVector())) &&
1275 "Invalid size combination");
1278 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1281 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1283 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1286 .
addImm(
MI.getOperand(2).getImm());
1292 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1293 isInt<8>((int32_t)
MI.getOperand(2).getImm())) ||
1294 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1297 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1299 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1302 .
addImm((int8_t)
MI.getOperand(2).getImm());
1307 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1308 isInt<8>((int32_t)-
MI.getOperand(2).getImm())) ||
1309 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1312 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1314 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1317 .
addImm((int8_t)-
MI.getOperand(2).getImm());
1322 unsigned MemImmOpc = 0;
1324 case SystemZ::LHIMux:
1325 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI;
break;
1326 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI;
break;
1327 case SystemZ::CHIMux:
1328 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI;
break;
1329 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI;
break;
1330 case SystemZ::CLFIMux:
1333 MemImmOpc = SystemZ::CLFHSI;
1335 case SystemZ::CLGFI:
1337 MemImmOpc = SystemZ::CLGHSI;
1342 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1346 .
addImm(
MI.getOperand(1).getImm());
1348 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1349 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1350 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1354 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1355 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1357 .
add(
MI.getOperand(1))
1365 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1366 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1368 .
add(
MI.getOperand(0))
1388 if (OpNum == 0 &&
MI.hasOneMemOperand()) {
1393 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1398 .
add(
MI.getOperand(1))
1404 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1406 .
add(
MI.getOperand(1))
1419 unsigned NumOps =
MI.getNumExplicitOperands();
1420 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1421 if (MemOpcode == -1 ||
1422 (CCLiveAtMI && !
MI.definesRegister(SystemZ::CC,
nullptr) &&
1423 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1429 for (
unsigned I = 0, E =
MCID.getNumOperands();
I != E; ++
I) {
1434 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1440 !(SystemZ::FP32BitRegClass.
contains(PhysReg) ||
1441 SystemZ::FP64BitRegClass.
contains(PhysReg) ||
1442 SystemZ::VF128BitRegClass.
contains(PhysReg)))
1447 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1448 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1452 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1457 bool NeedsCommute =
false;
1458 if ((
MI.getOpcode() == SystemZ::CR ||
MI.getOpcode() == SystemZ::CGR ||
1459 MI.getOpcode() == SystemZ::CLR ||
MI.getOpcode() == SystemZ::CLGR ||
1460 MI.getOpcode() == SystemZ::WFCDB ||
MI.getOpcode() == SystemZ::WFCSB ||
1461 MI.getOpcode() == SystemZ::WFKDB ||
MI.getOpcode() == SystemZ::WFKSB) &&
1463 NeedsCommute =
true;
1465 bool CCOperands =
false;
1466 if (
MI.getOpcode() == SystemZ::LOCRMux ||
MI.getOpcode() == SystemZ::LOCGR ||
1467 MI.getOpcode() == SystemZ::SELRMux ||
MI.getOpcode() == SystemZ::SELGR) {
1469 "LOCR/SELR instruction operands corrupt?");
1485 : ((OpNum == 1 &&
MI.isCommutable())
1486 ?
MI.getOperand(2).getReg()
1488 if (DstPhys && !SystemZ::GRH32BitRegClass.
contains(DstPhys) && SrcReg &&
1490 NeedsCommute = (OpNum == 1);
1496 if ((OpNum ==
NumOps - 1) || NeedsCommute || FusedFPOp) {
1499 assert(AccessBytes != 0 &&
"Size of access should be known");
1500 assert(AccessBytes <=
Size &&
"Access outside the frame index");
1503 MI.getDebugLoc(),
get(MemOpcode));
1504 if (
MI.isCompare()) {
1505 assert(
NumOps == 2 &&
"Expected 2 register operands for a compare.");
1506 MIB.
add(
MI.getOperand(NeedsCommute ? 1 : 0));
1508 else if (FusedFPOp) {
1509 MIB.
add(
MI.getOperand(0));
1510 MIB.
add(
MI.getOperand(3));
1511 MIB.
add(
MI.getOperand(OpNum == 1 ? 2 : 1));
1514 MIB.
add(
MI.getOperand(0));
1516 MIB.
add(
MI.getOperand(2));
1518 for (
unsigned I = 1;
I < OpNum; ++
I)
1519 MIB.
add(
MI.getOperand(
I));
1525 unsigned CCValid =
MI.getOperand(
NumOps).getImm();
1526 unsigned CCMask =
MI.getOperand(
NumOps + 1).getImm();
1528 MIB.
addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1531 (!
MI.definesRegister(SystemZ::CC,
nullptr) ||
1532 MI.registerDefIsDead(SystemZ::CC,
nullptr))) {
1540 if (MO.isReg() && MO.getReg().isVirtual()) {
1542 if (MRI.
getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1544 else if (MRI.
getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1546 else if (MRI.
getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1572 unsigned LoadOpc = 0;
1573 unsigned RegMemOpcode = 0;
1575 RegMemOpcode =
MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1576 :
MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1577 :
MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1580 LoadOpc = SystemZ::VL64;
1581 FPRC = &SystemZ::FP64BitRegClass;
1583 RegMemOpcode =
MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1584 :
MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1585 :
MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1588 LoadOpc = SystemZ::VL32;
1589 FPRC = &SystemZ::FP32BitRegClass;
1592 if (!RegMemOpcode || LoadMI.
getOpcode() != LoadOpc)
1596 if (
get(RegMemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)) {
1598 if (MII ==
MBB->begin()) {
1599 if (
MBB->isLiveIn(SystemZ::CC))
1604 if (MII->definesRegister(SystemZ::CC,
nullptr)) {
1605 if (!MII->registerDefIsDead(SystemZ::CC,
nullptr))
1613 if (
Ops.size() != 1 || FoldAsLoadDefReg !=
MI.getOperand(
Ops[0]).getReg())
1619 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1620 FoldAsLoadDefReg != RHS.getReg())
1627 BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(RegMemOpcode), DstReg)
1641 switch (
MI.getOpcode()) {
1643 splitMove(
MI, SystemZ::LG);
1646 case SystemZ::ST128:
1647 splitMove(
MI, SystemZ::STG);
1651 splitMove(
MI, SystemZ::LD);
1655 splitMove(
MI, SystemZ::STD);
1658 case SystemZ::LBMux:
1659 expandRXYPseudo(
MI, SystemZ::LB, SystemZ::LBH);
1662 case SystemZ::LHMux:
1663 expandRXYPseudo(
MI, SystemZ::LH, SystemZ::LHH);
1666 case SystemZ::LLCRMux:
1667 expandZExtPseudo(
MI, SystemZ::LLCR, 8);
1670 case SystemZ::LLHRMux:
1671 expandZExtPseudo(
MI, SystemZ::LLHR, 16);
1674 case SystemZ::LLCMux:
1675 expandRXYPseudo(
MI, SystemZ::LLC, SystemZ::LLCH);
1678 case SystemZ::LLHMux:
1679 expandRXYPseudo(
MI, SystemZ::LLH, SystemZ::LLHH);
1683 expandRXYPseudo(
MI, SystemZ::L, SystemZ::LFH);
1686 case SystemZ::LOCMux:
1687 expandLOCPseudo(
MI, SystemZ::LOC, SystemZ::LOCFH);
1690 case SystemZ::LOCHIMux:
1691 expandLOCPseudo(
MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1694 case SystemZ::STCMux:
1695 expandRXYPseudo(
MI, SystemZ::STC, SystemZ::STCH);
1698 case SystemZ::STHMux:
1699 expandRXYPseudo(
MI, SystemZ::STH, SystemZ::STHH);
1702 case SystemZ::STMux:
1703 expandRXYPseudo(
MI, SystemZ::ST, SystemZ::STFH);
1706 case SystemZ::STOCMux:
1707 expandLOCPseudo(
MI, SystemZ::STOC, SystemZ::STOCFH);
1710 case SystemZ::LHIMux:
1711 expandRIPseudo(
MI, SystemZ::LHI, SystemZ::IIHF,
true);
1714 case SystemZ::IIFMux:
1715 expandRIPseudo(
MI, SystemZ::IILF, SystemZ::IIHF,
false);
1718 case SystemZ::IILMux:
1719 expandRIPseudo(
MI, SystemZ::IILL, SystemZ::IIHL,
false);
1722 case SystemZ::IIHMux:
1723 expandRIPseudo(
MI, SystemZ::IILH, SystemZ::IIHH,
false);
1726 case SystemZ::NIFMux:
1727 expandRIPseudo(
MI, SystemZ::NILF, SystemZ::NIHF,
false);
1730 case SystemZ::NILMux:
1731 expandRIPseudo(
MI, SystemZ::NILL, SystemZ::NIHL,
false);
1734 case SystemZ::NIHMux:
1735 expandRIPseudo(
MI, SystemZ::NILH, SystemZ::NIHH,
false);
1738 case SystemZ::OIFMux:
1739 expandRIPseudo(
MI, SystemZ::OILF, SystemZ::OIHF,
false);
1742 case SystemZ::OILMux:
1743 expandRIPseudo(
MI, SystemZ::OILL, SystemZ::OIHL,
false);
1746 case SystemZ::OIHMux:
1747 expandRIPseudo(
MI, SystemZ::OILH, SystemZ::OIHH,
false);
1750 case SystemZ::XIFMux:
1751 expandRIPseudo(
MI, SystemZ::XILF, SystemZ::XIHF,
false);
1754 case SystemZ::TMLMux:
1755 expandRIPseudo(
MI, SystemZ::TMLL, SystemZ::TMHL,
false);
1758 case SystemZ::TMHMux:
1759 expandRIPseudo(
MI, SystemZ::TMLH, SystemZ::TMHH,
false);
1762 case SystemZ::AHIMux:
1763 expandRIPseudo(
MI, SystemZ::AHI, SystemZ::AIH,
false);
1766 case SystemZ::AHIMuxK:
1767 expandRIEPseudo(
MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1770 case SystemZ::AFIMux:
1771 expandRIPseudo(
MI, SystemZ::AFI, SystemZ::AIH,
false);
1774 case SystemZ::CHIMux:
1775 expandRIPseudo(
MI, SystemZ::CHI, SystemZ::CIH,
false);
1778 case SystemZ::CFIMux:
1779 expandRIPseudo(
MI, SystemZ::CFI, SystemZ::CIH,
false);
1782 case SystemZ::CLFIMux:
1783 expandRIPseudo(
MI, SystemZ::CLFI, SystemZ::CLIH,
false);
1787 expandRXYPseudo(
MI, SystemZ::C, SystemZ::CHF);
1790 case SystemZ::CLMux:
1791 expandRXYPseudo(
MI, SystemZ::CL, SystemZ::CLHF);
1794 case SystemZ::RISBMux: {
1797 if (SrcIsHigh == DestIsHigh)
1798 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1800 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1801 MI.getOperand(5).setImm(
MI.getOperand(5).getImm() ^ 32);
1806 case SystemZ::ADJDYNALLOC:
1807 splitAdjDynAlloc(
MI);
1810 case TargetOpcode::LOAD_STACK_GUARD:
1811 expandLoadStackGuard(&
MI);
1820 if (
MI.isInlineAsm()) {
1822 const char *AsmStr =
MI.getOperand(0).getSymbolName();
1825 else if (
MI.getOpcode() == SystemZ::PATCHPOINT)
1827 else if (
MI.getOpcode() == SystemZ::STACKMAP)
1828 return MI.getOperand(1).getImm();
1829 else if (
MI.getOpcode() == SystemZ::FENTRY_CALL)
1831 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)
1833 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_RET)
1834 return 18 + (
MI.getOperand(0).
getImm() == SystemZ::CondReturn ? 4 : 0);
1835 if (
MI.getOpcode() == TargetOpcode::BUNDLE)
1836 return getInstBundleSize(
MI);
1838 return MI.getDesc().getSize();
1843 switch (
MI.getOpcode()) {
1854 MI.getOperand(1).getImm(), &
MI.getOperand(2));
1857 case SystemZ::BRCTH:
1861 case SystemZ::BRCTG:
1868 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1873 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1878 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1880 case SystemZ::CLGIJ:
1881 case SystemZ::CLGRJ:
1883 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1885 case SystemZ::INLINEASM_BR:
1895 unsigned &LoadOpcode,
1896 unsigned &StoreOpcode)
const {
1897 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1898 LoadOpcode = SystemZ::L;
1899 StoreOpcode = SystemZ::ST;
1900 }
else if (RC == &SystemZ::GRH32BitRegClass) {
1901 LoadOpcode = SystemZ::LFH;
1902 StoreOpcode = SystemZ::STFH;
1903 }
else if (RC == &SystemZ::GRX32BitRegClass) {
1904 LoadOpcode = SystemZ::LMux;
1905 StoreOpcode = SystemZ::STMux;
1906 }
else if (RC == &SystemZ::GR64BitRegClass ||
1907 RC == &SystemZ::ADDR64BitRegClass) {
1908 LoadOpcode = SystemZ::LG;
1909 StoreOpcode = SystemZ::STG;
1910 }
else if (RC == &SystemZ::GR128BitRegClass ||
1911 RC == &SystemZ::ADDR128BitRegClass) {
1912 LoadOpcode = SystemZ::L128;
1913 StoreOpcode = SystemZ::ST128;
1914 }
else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
1915 LoadOpcode = SystemZ::LE16;
1916 StoreOpcode = SystemZ::STE16;
1917 }
else if (RC == &SystemZ::FP32BitRegClass) {
1918 LoadOpcode = SystemZ::LE;
1919 StoreOpcode = SystemZ::STE;
1920 }
else if (RC == &SystemZ::FP64BitRegClass) {
1921 LoadOpcode = SystemZ::LD;
1922 StoreOpcode = SystemZ::STD;
1923 }
else if (RC == &SystemZ::FP128BitRegClass) {
1924 LoadOpcode = SystemZ::LX;
1925 StoreOpcode = SystemZ::STX;
1926 }
else if (RC == &SystemZ::FP16BitRegClass ||
1927 RC == &SystemZ::VR16BitRegClass) {
1928 LoadOpcode = SystemZ::VL16;
1929 StoreOpcode = SystemZ::VST16;
1930 }
else if (RC == &SystemZ::VR32BitRegClass) {
1931 LoadOpcode = SystemZ::VL32;
1932 StoreOpcode = SystemZ::VST32;
1933 }
else if (RC == &SystemZ::VR64BitRegClass) {
1934 LoadOpcode = SystemZ::VL64;
1935 StoreOpcode = SystemZ::VST64;
1936 }
else if (RC == &SystemZ::VF128BitRegClass ||
1937 RC == &SystemZ::VR128BitRegClass) {
1938 LoadOpcode = SystemZ::VL;
1939 StoreOpcode = SystemZ::VST;
1951 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1952 if (Disp12Opcode >= 0)
1953 return Disp12Opcode;
1961 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1962 if (Disp20Opcode >= 0)
1963 return Disp20Opcode;
1970 if (
MI &&
MI->getOperand(0).isReg()) {
1975 return SystemZ::LEY;
1976 case SystemZ::VST32:
1977 return SystemZ::STEY;
1979 return SystemZ::LDY;
1980 case SystemZ::VST64:
1981 return SystemZ::STDY;
1993 return SystemZ::getDisp12Opcode(Opcode) >= 0;
1994 return SystemZ::getDisp20Opcode(Opcode) >= 0;
1999 case SystemZ::L:
return SystemZ::LT;
2000 case SystemZ::LY:
return SystemZ::LT;
2001 case SystemZ::LG:
return SystemZ::LTG;
2002 case SystemZ::LGF:
return SystemZ::LTGF;
2003 case SystemZ::LR:
return SystemZ::LTR;
2004 case SystemZ::LGFR:
return SystemZ::LTGFR;
2005 case SystemZ::LGR:
return SystemZ::LTGR;
2006 case SystemZ::LCDFR:
return SystemZ::LCDBR;
2007 case SystemZ::LPDFR:
return SystemZ::LPDBR;
2008 case SystemZ::LNDFR:
return SystemZ::LNDBR;
2009 case SystemZ::LCDFR_32:
return SystemZ::LCEBR;
2010 case SystemZ::LPDFR_32:
return SystemZ::LPEBR;
2011 case SystemZ::LNDFR_32:
return SystemZ::LNEBR;
2016 case SystemZ::RISBGN:
return SystemZ::RISBG;
2022 unsigned &Start,
unsigned &End)
const {
2032 Start = 63 - (LSB +
Length - 1);
2040 assert(LSB > 0 &&
"Bottom bit must be set");
2041 assert(LSB +
Length < BitSize &&
"Top bit must be set");
2042 Start = 63 - (LSB - 1);
2043 End = 63 - (LSB +
Length);
2060 case SystemZ::CLGFI:
2066 if (!STI.hasMiscellaneousExtensions())
2068 if (!(
MI &&
MI->getOperand(3).getReg() == 0))
2076 return SystemZ::CRJ;
2078 return SystemZ::CGRJ;
2080 return SystemZ::CIJ;
2082 return SystemZ::CGIJ;
2084 return SystemZ::CLRJ;
2086 return SystemZ::CLGRJ;
2088 return SystemZ::CLIJ;
2089 case SystemZ::CLGFI:
2090 return SystemZ::CLGIJ;
2097 return SystemZ::CRBReturn;
2099 return SystemZ::CGRBReturn;
2101 return SystemZ::CIBReturn;
2103 return SystemZ::CGIBReturn;
2105 return SystemZ::CLRBReturn;
2107 return SystemZ::CLGRBReturn;
2109 return SystemZ::CLIBReturn;
2110 case SystemZ::CLGFI:
2111 return SystemZ::CLGIBReturn;
2118 return SystemZ::CRBCall;
2120 return SystemZ::CGRBCall;
2122 return SystemZ::CIBCall;
2124 return SystemZ::CGIBCall;
2126 return SystemZ::CLRBCall;
2128 return SystemZ::CLGRBCall;
2130 return SystemZ::CLIBCall;
2131 case SystemZ::CLGFI:
2132 return SystemZ::CLGIBCall;
2139 return SystemZ::CRT;
2141 return SystemZ::CGRT;
2143 return SystemZ::CIT;
2145 return SystemZ::CGIT;
2147 return SystemZ::CLRT;
2149 return SystemZ::CLGRT;
2151 return SystemZ::CLFIT;
2152 case SystemZ::CLGFI:
2153 return SystemZ::CLGIT;
2155 return SystemZ::CLT;
2157 return SystemZ::CLGT;
2168 return (
MI.getOpcode() == SystemZ::LTEBR ||
2169 MI.getOpcode() == SystemZ::LTDBR ||
2170 MI.getOpcode() == SystemZ::LTXBR) &&
2171 MI.getOperand(0).isDead();
2177 return Compare.isCompare() && Compare.getNumExplicitOperands() == 2 &&
2178 Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
2190 MBBI->getOperand(1).isReg() && !
MBBI->mayLoad() &&
2191 "Not a compare reg/reg.");
2197 if (
MI.readsRegister(SystemZ::CC,
nullptr)) {
2198 unsigned Flags =
MI.getDesc().TSFlags;
2204 if (
MI.definesRegister(SystemZ::CC,
nullptr)) {
2212 if (!
LiveRegs.available(SystemZ::CC))
2217 for (
unsigned Idx = 0; Idx < CCUsers.
size(); ++Idx) {
2218 unsigned Flags = CCUsers[Idx]->getDesc().TSFlags;
2220 0 : CCUsers[Idx]->getNumExplicitOperands() - 2);
2221 MachineOperand &CCMaskMO = CCUsers[Idx]->getOperand(FirstOpNum + 1);
2223 CCMaskMO.
setImm(NewCCMask);
2261 if (!STI.hasLoadAndTrap())
2266 return SystemZ::LAT;
2268 return SystemZ::LGAT;
2270 return SystemZ::LFHAT;
2272 return SystemZ::LLGFAT;
2274 return SystemZ::LLGTAT;
2283 unsigned Opcode = 0;
2285 Opcode = SystemZ::LGHI;
2287 Opcode = SystemZ::LLILL;
2289 Opcode = SystemZ::LLILH;
2293 Opcode = SystemZ::LGFI;
2300 assert (MRI.
isSSA() &&
"Huge values only handled before reg-alloc .");
2313 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
2314 if (
I >=
MCID.getNumOperands())
2322 ((
MCOI.RegClass != -1 && !
Op.isReg() && !
Op.isFI()) ||
2323 (
MCOI.RegClass == -1 && !
Op.isImm()))) {
2324 ErrInfo =
"Addressing mode operands corrupt!";
2347 bool SameVal = (VALa && VALb && (VALa == VALb));
2351 if (PSVa && PSVb && (PSVa == PSVb))
2357 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2358 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2359 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2361 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
2370 int64_t &ImmVal)
const {
2372 if (
MI.getOpcode() == SystemZ::VGBM && Reg ==
MI.getOperand(0).getReg()) {
2373 ImmVal =
MI.getOperand(1).getImm();
2381std::optional<DestSourcePair>
2387 return std::nullopt;
2390std::pair<unsigned, unsigned>
2392 return std::make_pair(TF, 0u);
2399 static const std::pair<unsigned, const char *> TargetFlags[] = {
2400 {MO_ADA_DATA_SYMBOL_ADDR,
"systemz-ada-datasymboladdr"},
2401 {MO_ADA_INDIRECT_FUNC_DESC,
"systemz-ada-indirectfuncdesc"},
2402 {MO_ADA_DIRECT_FUNC_DESC,
"systemz-ada-directfuncdesc"}};
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
DXIL Forward Handle Accesses
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag)
static void transferDeadCC(MachineInstr *OldMI, MachineInstr *NewMI)
static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI, MachineInstr::MIFlag Flag)
static int isSimpleMove(const MachineInstr &MI, int &FrameIndex, unsigned Flag)
static LogicOp interpretAndImmediate(unsigned Opcode)
static uint64_t allOnes(unsigned int Count)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
SlotIndexes * getSlotIndexes() const
VNInfo::Allocator & getVNInfoAllocator()
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
LLVM_ABI VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
A set of register units used to track register liveness.
LLVM_ABI void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
TypeSize getValue() const
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
This holds information about one operand of a machine instruction, indicating the register class for ...
Wrapper class representing physical registers. Should be passed by value.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
bool registerDefIsDead(Register Reg, const TargetRegisterInfo *TRI) const
Returns true if the register is dead in this machine instruction.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
void setFlag(MIFlag Flag)
Set a MI flag.
const MachineOperand & getOperand(unsigned i) const
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
LLVM_ABI bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
const PseudoSourceValue * getPseudoValue() const
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
const Value * getValue() const
Return the base address of the memory access.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
virtual int getStackPointerBias()=0
virtual int getCallFrameSize()=0
unsigned getLoadAndTrap(unsigned Opcode) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
unsigned getLoadAndTest(unsigned Opcode) const
MCInst getNop() const override
bool isPredicable(const MachineInstr &MI) const override
Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const override
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset, const MachineInstr *MI=nullptr) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg, int64_t &ImmVal) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool hasDisplacementPairInsn(unsigned Opcode) const
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned CommuteOpIdx1, unsigned CommuteOpIdx2) const override
Commutes the operands in the given instruction by changing the operands order and/or changing the ins...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
bool isCompareZero(const MachineInstr &Compare) const
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool isLoadAndTestAsCmp(const MachineInstr &MI) const
unsigned getFusedCompare(unsigned Opcode, SystemZII::FusedCompareType Type, const MachineInstr *MI=nullptr) const
bool expandPostRAPseudo(MachineInstr &MBBI) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode) const
bool isRxSBGMask(uint64_t Mask, unsigned BitSize, unsigned &Start, unsigned &End) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
Register getCompareSourceReg(const MachineInstr &Compare) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
SystemZInstrInfo(const SystemZSubtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned Reg, uint64_t Value) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getAccessSize(unsigned int Flags)
unsigned getFirstReg(unsigned Reg)
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_CMP_GT
const unsigned CCMASK_ANY
static bool isImmLL(uint64_t Val)
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_CMP_EQ
const unsigned CCMASK_ICMP
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
int32_t getTargetMemOpcode(uint32_t Opcode)
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
bool isHighReg(unsigned int Reg)
const unsigned CCMASK_CMP_UO
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
constexpr RegState getKillRegState(bool B)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr RegState getUndefRegState(bool B)