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!");
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();
241 unsigned SrcReg,
unsigned LowLowOpcode,
242 unsigned Size,
bool KillSrc,
243 bool UndefSrc)
const {
247 if (DestIsHigh && SrcIsHigh)
248 Opcode = SystemZ::RISBHH;
249 else if (DestIsHigh && !SrcIsHigh)
250 Opcode = SystemZ::RISBHL;
251 else if (!DestIsHigh && SrcIsHigh)
252 Opcode = SystemZ::RISBLH;
257 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
267 unsigned OpIdx2)
const {
270 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
274 switch (
MI.getOpcode()) {
275 case SystemZ::SELRMux:
276 case SystemZ::SELFHR:
279 case SystemZ::LOCRMux:
280 case SystemZ::LOCFHR:
282 case SystemZ::LOCGR: {
283 auto &WorkingMI = cloneIfNew(
MI);
285 unsigned CCValid = WorkingMI.getOperand(3).getImm();
286 unsigned CCMask = WorkingMI.getOperand(4).getImm();
287 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
304 if ((
MCID.TSFlags & Flag) &&
MI.getOperand(1).isFI() &&
305 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).getReg() == 0) {
306 FrameIndex =
MI.getOperand(1).getIndex();
307 return MI.getOperand(0).getReg();
313 int &FrameIndex)
const {
318 int &FrameIndex)
const {
323 int &FrameIndex)
const {
340 return MI.getOperand(0).getReg();
346 int &FrameIndex)
const {
363 return MI.getOperand(0).getReg();
370 int &SrcFrameIndex)
const {
373 if (
MI.getOpcode() != SystemZ::MVC || !
MI.getOperand(0).isFI() ||
374 MI.getOperand(1).getImm() != 0 || !
MI.getOperand(3).isFI() ||
375 MI.getOperand(4).getImm() != 0)
379 int64_t
Length =
MI.getOperand(2).getImm();
380 unsigned FI1 =
MI.getOperand(0).getIndex();
381 unsigned FI2 =
MI.getOperand(3).getIndex();
386 DestFrameIndex = FI1;
395 bool AllowModify)
const {
401 while (
I !=
MBB.begin()) {
403 if (
I->isDebugInstr())
408 if (!isUnpredicatedTerminator(*
I))
418 if (!Branch.hasMBBTarget())
428 TBB = Branch.getMBBTarget();
433 MBB.erase(std::next(
I),
MBB.end());
439 if (
MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
441 I->eraseFromParent();
447 TBB = Branch.getMBBTarget();
455 TBB = Branch.getMBBTarget();
462 assert(
Cond.size() == 2 &&
TBB &&
"Should have seen a conditional branch");
466 if (
TBB != Branch.getMBBTarget())
470 unsigned OldCCValid =
Cond[0].getImm();
471 unsigned OldCCMask =
Cond[1].getImm();
472 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
483 int *BytesRemoved)
const {
484 assert(!BytesRemoved &&
"code size not handled");
490 while (
I !=
MBB.begin()) {
492 if (
I->isDebugInstr())
499 I->eraseFromParent();
509 assert(
Cond.size() == 2 &&
"Invalid condition");
519 int *BytesAdded)
const {
525 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
527 "SystemZ branch conditions have one component!");
528 assert(!BytesAdded &&
"code size not handled");
532 assert(!FBB &&
"Unconditional branch with multiple successors!");
539 unsigned CCValid =
Cond[0].getImm();
540 unsigned CCMask =
Cond[1].getImm();
555 int64_t &
Value)
const {
556 assert(
MI.isCompare() &&
"Caller should have checked for a comparison");
558 if (
MI.getNumExplicitOperands() == 2 &&
MI.getOperand(0).isReg() &&
559 MI.getOperand(1).isImm()) {
560 SrcReg =
MI.getOperand(0).getReg();
562 Value =
MI.getOperand(1).getImm();
574 SelectExpansion &Exp)
const {
576 if (!STI.hasLoadStoreOnCond())
578 if (Pred.size() != 2)
589 if ((STI.hasLoadStoreOnCond2() &&
590 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
591 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
592 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
612 assert(Pred.size() == 2 &&
"Invalid condition");
613 unsigned CCValid = Pred[0].getImm();
614 unsigned CCMask = Pred[1].getImm();
617 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
618 if (STI.hasMiscellaneousExtensions3())
619 Opc = SystemZ::SELRMux;
620 else if (STI.hasLoadStoreOnCond2())
621 Opc = SystemZ::LOCRMux;
632 }
else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
633 if (STI.hasMiscellaneousExtensions3())
634 Opc = SystemZ::SELGR;
636 Opc = SystemZ::LOCGR;
648 unsigned DefOpc =
DefMI.getOpcode();
650 if (DefOpc == SystemZ::VGBM) {
651 int64_t ImmVal =
DefMI.getOperand(1).getImm();
666 MRI->
getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
676 UseMI.setDesc(
get(SystemZ::REG_SEQUENCE));
677 UseMI.getOperand(1).setReg(TmpReg);
679 .
addImm(SystemZ::subreg_h64)
681 .
addImm(SystemZ::subreg_l64);
684 DefMI.eraseFromParent();
691 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
692 DefOpc != SystemZ::LGHI)
694 if (
DefMI.getOperand(0).getReg() != Reg)
696 int32_t ImmVal = (int32_t)
DefMI.getOperand(1).getImm();
698 unsigned UseOpc =
UseMI.getOpcode();
704 case SystemZ::SELRMux:
707 case SystemZ::LOCRMux:
708 if (!STI.hasLoadStoreOnCond2())
710 NewUseOpc = SystemZ::LOCHIMux;
711 if (
UseMI.getOperand(2).getReg() == Reg)
713 else if (
UseMI.getOperand(1).getReg() == Reg)
714 UseIdx = 2, CommuteIdx = 1;
722 if (!STI.hasLoadStoreOnCond2())
724 NewUseOpc = SystemZ::LOCGHI;
725 if (
UseMI.getOperand(2).getReg() == Reg)
727 else if (
UseMI.getOperand(1).getReg() == Reg)
728 UseIdx = 2, CommuteIdx = 1;
736 if (CommuteIdx != -1)
737 if (!commuteInstruction(
UseMI,
false, CommuteIdx, UseIdx))
743 UseMI.tieOperands(0, 1);
744 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
746 DefMI.eraseFromParent();
752 unsigned Opcode =
MI.getOpcode();
753 if (Opcode == SystemZ::Return ||
754 Opcode == SystemZ::Return_XPLINK ||
755 Opcode == SystemZ::Trap ||
756 Opcode == SystemZ::CallJG ||
757 Opcode == SystemZ::CallBR)
764 unsigned NumCycles,
unsigned ExtraPredCycles,
774 if (
MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap &&
778 return NumCycles == 1;
783 unsigned NumCyclesT,
unsigned ExtraPredCyclesT,
785 unsigned NumCyclesF,
unsigned ExtraPredCyclesF,
795 return NumCycles == 1;
800 assert(Pred.size() == 2 &&
"Invalid condition");
801 unsigned CCValid = Pred[0].getImm();
802 unsigned CCMask = Pred[1].getImm();
803 assert(CCMask > 0 && CCMask < 15 &&
"Invalid predicate");
804 unsigned Opcode =
MI.getOpcode();
805 if (Opcode == SystemZ::Trap) {
806 MI.setDesc(
get(SystemZ::CondTrap));
812 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
813 MI.setDesc(
get(Opcode == SystemZ::Return ? SystemZ::CondReturn
814 : SystemZ::CondReturn_XPLINK));
821 if (Opcode == SystemZ::CallJG) {
823 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
826 MI.setDesc(
get(SystemZ::CallBRCL));
835 if (Opcode == SystemZ::CallBR) {
837 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
840 MI.setDesc(
get(SystemZ::CallBCR));
856 bool RenamableSrc)
const {
860 if (SystemZ::GR128BitRegClass.
contains(DestReg, SrcReg)) {
862 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
866 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
872 if (SystemZ::GRX32BitRegClass.
contains(DestReg, SrcReg)) {
873 emitGRX32Move(
MBB,
MBBI,
DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
879 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
880 SystemZ::FP128BitRegClass.
contains(SrcReg)) {
882 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
883 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
885 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
886 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
893 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
894 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
896 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
897 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
899 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
900 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
902 if (DestRegHi != SrcReg.
asMCReg())
909 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
910 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
911 MCRegister DestRegHi = RI.getSubReg(DestReg, SystemZ::subreg_h64);
912 MCRegister DestRegLo = RI.getSubReg(DestReg, SystemZ::subreg_l64);
913 MCRegister SrcRegHi = RI.getSubReg(SrcReg, SystemZ::subreg_h64);
914 MCRegister SrcRegLo = RI.getSubReg(SrcReg, SystemZ::subreg_l64);
926 if (DestReg == SystemZ::CC) {
928 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
935 if (SystemZ::GR128BitRegClass.
contains(DestReg) &&
936 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
937 MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64);
938 MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64);
942 .
addReg(SystemZ::NoRegister)
947 .
addReg(SystemZ::NoRegister)
952 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
953 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
955 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64))
956 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64));
962 if (SystemZ::GR64BitRegClass.
contains(DestReg, SrcReg))
963 Opcode = SystemZ::LGR;
964 else if (SystemZ::FP16BitRegClass.
contains(DestReg, SrcReg))
965 Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
966 else if (SystemZ::FP32BitRegClass.
contains(DestReg, SrcReg))
968 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
969 else if (SystemZ::FP64BitRegClass.
contains(DestReg, SrcReg))
970 Opcode = SystemZ::LDR;
971 else if (SystemZ::FP128BitRegClass.
contains(DestReg, SrcReg))
972 Opcode = SystemZ::LXR;
973 else if (SystemZ::VR16BitRegClass.
contains(DestReg, SrcReg))
974 Opcode = SystemZ::VLR16;
975 else if (SystemZ::VR32BitRegClass.
contains(DestReg, SrcReg))
976 Opcode = SystemZ::VLR32;
977 else if (SystemZ::VR64BitRegClass.
contains(DestReg, SrcReg))
978 Opcode = SystemZ::VLR64;
979 else if (SystemZ::VR128BitRegClass.
contains(DestReg, SrcReg))
980 Opcode = SystemZ::VLR;
981 else if (SystemZ::AR32BitRegClass.
contains(DestReg, SrcReg))
982 Opcode = SystemZ::CPYA;
983 else if (SystemZ::GR64BitRegClass.
contains(DestReg) &&
984 SystemZ::FP64BitRegClass.
contains(SrcReg))
985 Opcode = SystemZ::LGDR;
986 else if (SystemZ::FP64BitRegClass.
contains(DestReg) &&
987 SystemZ::GR64BitRegClass.
contains(SrcReg))
988 Opcode = SystemZ::LDGR;
1005 unsigned LoadOpcode, StoreOpcode;
1022 unsigned LoadOpcode, StoreOpcode;
1032 return ((
MCID.TSFlags & Flag) &&
1034 MI->getOperand(3).getReg() == 0);
1040 LogicOp() =
default;
1041 LogicOp(
unsigned regSize,
unsigned immLSB,
unsigned immSize)
1042 :
RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1044 explicit operator bool()
const {
return RegSize; }
1047 unsigned ImmLSB = 0;
1048 unsigned ImmSize = 0;
1055 case SystemZ::NILMux:
return LogicOp(32, 0, 16);
1056 case SystemZ::NIHMux:
return LogicOp(32, 16, 16);
1057 case SystemZ::NILL64:
return LogicOp(64, 0, 16);
1058 case SystemZ::NILH64:
return LogicOp(64, 16, 16);
1059 case SystemZ::NIHL64:
return LogicOp(64, 32, 16);
1060 case SystemZ::NIHH64:
return LogicOp(64, 48, 16);
1061 case SystemZ::NIFMux:
return LogicOp(32, 0, 32);
1062 case SystemZ::NILF64:
return LogicOp(64, 0, 32);
1063 case SystemZ::NIHF64:
return LogicOp(64, 32, 32);
1064 default:
return LogicOp();
1072 if (CCDef !=
nullptr)
1091 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
1093 uint64_t
Imm =
MI.getOperand(2).getImm() <<
And.ImmLSB;
1096 unsigned Start,
End;
1099 if (
And.RegSize == 64) {
1100 NewOpcode = SystemZ::RISBG;
1102 if (STI.hasMiscellaneousExtensions())
1103 NewOpcode = SystemZ::RISBGN;
1105 NewOpcode = SystemZ::RISBMux;
1133 bool Invert)
const {
1139 Opc = *InverseOpcode;
1146 case SystemZ::WFADB:
1147 case SystemZ::WFASB:
1148 case SystemZ::WFAXB:
1149 case SystemZ::VFADB:
1150 case SystemZ::VFASB:
1151 case SystemZ::WFMDB:
1152 case SystemZ::WFMSB:
1153 case SystemZ::WFMXB:
1154 case SystemZ::VFMDB:
1155 case SystemZ::VFMSB:
1163std::optional<unsigned>
1167 case SystemZ::WFADB:
1168 return SystemZ::WFSDB;
1169 case SystemZ::WFASB:
1170 return SystemZ::WFSSB;
1171 case SystemZ::WFAXB:
1172 return SystemZ::WFSXB;
1173 case SystemZ::VFADB:
1174 return SystemZ::VFSDB;
1175 case SystemZ::VFASB:
1176 return SystemZ::VFSSB;
1178 case SystemZ::WFSDB:
1179 return SystemZ::WFADB;
1180 case SystemZ::WFSSB:
1181 return SystemZ::WFASB;
1182 case SystemZ::WFSXB:
1183 return SystemZ::WFAXB;
1184 case SystemZ::VFSDB:
1185 return SystemZ::VFADB;
1186 case SystemZ::VFSSB:
1187 return SystemZ::VFASB;
1189 return std::nullopt;
1202 unsigned Opcode =
MI.getOpcode();
1207 bool CCLiveAtMI =
true;
1212 CCLiveRange = &LIS->
getRegUnit(*CCUnits.begin());
1213 CCLiveAtMI = CCLiveRange->
liveAt(MISlot);
1216 if (
Ops.size() == 2 &&
Ops[0] == 0 &&
Ops[1] == 1) {
1217 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1218 isInt<8>(
MI.getOperand(2).getImm()) && !
MI.getOperand(3).getReg()) {
1221 MI.getDebugLoc(),
get(SystemZ::AGSI))
1224 .
addImm(
MI.getOperand(2).getImm());
1234 if (
Ops.size() != 1)
1237 unsigned OpNum =
Ops[0];
1241 (RC == &SystemZ::FP16BitRegClass &&
Size == 4 && !STI.hasVector())) &&
1242 "Invalid size combination");
1245 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1248 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1250 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1253 .
addImm(
MI.getOperand(2).getImm());
1259 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1260 isInt<8>((int32_t)
MI.getOperand(2).getImm())) ||
1261 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1264 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1266 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1269 .
addImm((int8_t)
MI.getOperand(2).getImm());
1274 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1275 isInt<8>((int32_t)-
MI.getOperand(2).getImm())) ||
1276 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1279 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1281 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1284 .
addImm((int8_t)-
MI.getOperand(2).getImm());
1289 unsigned MemImmOpc = 0;
1291 case SystemZ::LHIMux:
1292 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI;
break;
1293 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI;
break;
1294 case SystemZ::CHIMux:
1295 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI;
break;
1296 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI;
break;
1297 case SystemZ::CLFIMux:
1300 MemImmOpc = SystemZ::CLFHSI;
1302 case SystemZ::CLGFI:
1304 MemImmOpc = SystemZ::CLGHSI;
1309 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1313 .
addImm(
MI.getOperand(1).getImm());
1315 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1316 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1317 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1321 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1322 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1324 .
add(
MI.getOperand(1))
1332 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1333 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1335 .
add(
MI.getOperand(0))
1355 if (OpNum == 0 &&
MI.hasOneMemOperand()) {
1360 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1365 .
add(
MI.getOperand(1))
1371 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1373 .
add(
MI.getOperand(1))
1386 unsigned NumOps =
MI.getNumExplicitOperands();
1387 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1388 if (MemOpcode == -1 ||
1389 (CCLiveAtMI && !
MI.definesRegister(SystemZ::CC,
nullptr) &&
1390 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1396 for (
unsigned I = 0, E =
MCID.getNumOperands();
I != E; ++
I) {
1401 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1407 !(SystemZ::FP32BitRegClass.
contains(PhysReg) ||
1408 SystemZ::FP64BitRegClass.
contains(PhysReg) ||
1409 SystemZ::VF128BitRegClass.
contains(PhysReg)))
1414 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1415 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1419 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1424 bool NeedsCommute =
false;
1425 if ((
MI.getOpcode() == SystemZ::CR ||
MI.getOpcode() == SystemZ::CGR ||
1426 MI.getOpcode() == SystemZ::CLR ||
MI.getOpcode() == SystemZ::CLGR ||
1427 MI.getOpcode() == SystemZ::WFCDB ||
MI.getOpcode() == SystemZ::WFCSB ||
1428 MI.getOpcode() == SystemZ::WFKDB ||
MI.getOpcode() == SystemZ::WFKSB) &&
1430 NeedsCommute =
true;
1432 bool CCOperands =
false;
1433 if (
MI.getOpcode() == SystemZ::LOCRMux ||
MI.getOpcode() == SystemZ::LOCGR ||
1434 MI.getOpcode() == SystemZ::SELRMux ||
MI.getOpcode() == SystemZ::SELGR) {
1436 "LOCR/SELR instruction operands corrupt?");
1452 : ((OpNum == 1 &&
MI.isCommutable())
1453 ?
MI.getOperand(2).getReg()
1455 if (DstPhys && !SystemZ::GRH32BitRegClass.
contains(DstPhys) && SrcReg &&
1457 NeedsCommute = (OpNum == 1);
1463 if ((OpNum ==
NumOps - 1) || NeedsCommute || FusedFPOp) {
1466 assert(AccessBytes != 0 &&
"Size of access should be known");
1467 assert(AccessBytes <=
Size &&
"Access outside the frame index");
1470 MI.getDebugLoc(),
get(MemOpcode));
1471 if (
MI.isCompare()) {
1472 assert(
NumOps == 2 &&
"Expected 2 register operands for a compare.");
1473 MIB.
add(
MI.getOperand(NeedsCommute ? 1 : 0));
1475 else if (FusedFPOp) {
1476 MIB.
add(
MI.getOperand(0));
1477 MIB.
add(
MI.getOperand(3));
1478 MIB.
add(
MI.getOperand(OpNum == 1 ? 2 : 1));
1481 MIB.
add(
MI.getOperand(0));
1483 MIB.
add(
MI.getOperand(2));
1485 for (
unsigned I = 1;
I < OpNum; ++
I)
1486 MIB.
add(
MI.getOperand(
I));
1492 unsigned CCValid =
MI.getOperand(
NumOps).getImm();
1493 unsigned CCMask =
MI.getOperand(
NumOps + 1).getImm();
1495 MIB.
addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1498 (!
MI.definesRegister(SystemZ::CC,
nullptr) ||
1499 MI.registerDefIsDead(SystemZ::CC,
nullptr))) {
1507 if (MO.isReg() && MO.getReg().isVirtual()) {
1509 if (MRI.
getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1511 else if (MRI.
getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1513 else if (MRI.
getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1540 unsigned LoadOpc = 0;
1541 unsigned RegMemOpcode = 0;
1543 RegMemOpcode =
MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1544 :
MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1545 :
MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1548 LoadOpc = SystemZ::VL64;
1549 FPRC = &SystemZ::FP64BitRegClass;
1551 RegMemOpcode =
MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1552 :
MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1553 :
MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1556 LoadOpc = SystemZ::VL32;
1557 FPRC = &SystemZ::FP32BitRegClass;
1560 if (!RegMemOpcode || LoadMI.
getOpcode() != LoadOpc)
1564 if (
get(RegMemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)) {
1566 if (MII ==
MBB->begin()) {
1567 if (
MBB->isLiveIn(SystemZ::CC))
1572 if (MII->definesRegister(SystemZ::CC,
nullptr)) {
1573 if (!MII->registerDefIsDead(SystemZ::CC,
nullptr))
1581 if (
Ops.size() != 1 || FoldAsLoadDefReg !=
MI.getOperand(
Ops[0]).getReg())
1587 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1588 FoldAsLoadDefReg != RHS.getReg())
1597 BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(RegMemOpcode), DstReg)
1611 switch (
MI.getOpcode()) {
1613 splitMove(
MI, SystemZ::LG);
1616 case SystemZ::ST128:
1617 splitMove(
MI, SystemZ::STG);
1621 splitMove(
MI, SystemZ::LD);
1625 splitMove(
MI, SystemZ::STD);
1628 case SystemZ::LBMux:
1629 expandRXYPseudo(
MI, SystemZ::LB, SystemZ::LBH);
1632 case SystemZ::LHMux:
1633 expandRXYPseudo(
MI, SystemZ::LH, SystemZ::LHH);
1636 case SystemZ::LLCRMux:
1637 expandZExtPseudo(
MI, SystemZ::LLCR, 8);
1640 case SystemZ::LLHRMux:
1641 expandZExtPseudo(
MI, SystemZ::LLHR, 16);
1644 case SystemZ::LLCMux:
1645 expandRXYPseudo(
MI, SystemZ::LLC, SystemZ::LLCH);
1648 case SystemZ::LLHMux:
1649 expandRXYPseudo(
MI, SystemZ::LLH, SystemZ::LLHH);
1653 expandRXYPseudo(
MI, SystemZ::L, SystemZ::LFH);
1656 case SystemZ::LOCMux:
1657 expandLOCPseudo(
MI, SystemZ::LOC, SystemZ::LOCFH);
1660 case SystemZ::LOCHIMux:
1661 expandLOCPseudo(
MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1664 case SystemZ::STCMux:
1665 expandRXYPseudo(
MI, SystemZ::STC, SystemZ::STCH);
1668 case SystemZ::STHMux:
1669 expandRXYPseudo(
MI, SystemZ::STH, SystemZ::STHH);
1672 case SystemZ::STMux:
1673 expandRXYPseudo(
MI, SystemZ::ST, SystemZ::STFH);
1676 case SystemZ::STOCMux:
1677 expandLOCPseudo(
MI, SystemZ::STOC, SystemZ::STOCFH);
1680 case SystemZ::LHIMux:
1681 expandRIPseudo(
MI, SystemZ::LHI, SystemZ::IIHF,
true);
1684 case SystemZ::IIFMux:
1685 expandRIPseudo(
MI, SystemZ::IILF, SystemZ::IIHF,
false);
1688 case SystemZ::IILMux:
1689 expandRIPseudo(
MI, SystemZ::IILL, SystemZ::IIHL,
false);
1692 case SystemZ::IIHMux:
1693 expandRIPseudo(
MI, SystemZ::IILH, SystemZ::IIHH,
false);
1696 case SystemZ::NIFMux:
1697 expandRIPseudo(
MI, SystemZ::NILF, SystemZ::NIHF,
false);
1700 case SystemZ::NILMux:
1701 expandRIPseudo(
MI, SystemZ::NILL, SystemZ::NIHL,
false);
1704 case SystemZ::NIHMux:
1705 expandRIPseudo(
MI, SystemZ::NILH, SystemZ::NIHH,
false);
1708 case SystemZ::OIFMux:
1709 expandRIPseudo(
MI, SystemZ::OILF, SystemZ::OIHF,
false);
1712 case SystemZ::OILMux:
1713 expandRIPseudo(
MI, SystemZ::OILL, SystemZ::OIHL,
false);
1716 case SystemZ::OIHMux:
1717 expandRIPseudo(
MI, SystemZ::OILH, SystemZ::OIHH,
false);
1720 case SystemZ::XIFMux:
1721 expandRIPseudo(
MI, SystemZ::XILF, SystemZ::XIHF,
false);
1724 case SystemZ::TMLMux:
1725 expandRIPseudo(
MI, SystemZ::TMLL, SystemZ::TMHL,
false);
1728 case SystemZ::TMHMux:
1729 expandRIPseudo(
MI, SystemZ::TMLH, SystemZ::TMHH,
false);
1732 case SystemZ::AHIMux:
1733 expandRIPseudo(
MI, SystemZ::AHI, SystemZ::AIH,
false);
1736 case SystemZ::AHIMuxK:
1737 expandRIEPseudo(
MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1740 case SystemZ::AFIMux:
1741 expandRIPseudo(
MI, SystemZ::AFI, SystemZ::AIH,
false);
1744 case SystemZ::CHIMux:
1745 expandRIPseudo(
MI, SystemZ::CHI, SystemZ::CIH,
false);
1748 case SystemZ::CFIMux:
1749 expandRIPseudo(
MI, SystemZ::CFI, SystemZ::CIH,
false);
1752 case SystemZ::CLFIMux:
1753 expandRIPseudo(
MI, SystemZ::CLFI, SystemZ::CLIH,
false);
1757 expandRXYPseudo(
MI, SystemZ::C, SystemZ::CHF);
1760 case SystemZ::CLMux:
1761 expandRXYPseudo(
MI, SystemZ::CL, SystemZ::CLHF);
1764 case SystemZ::RISBMux: {
1767 if (SrcIsHigh == DestIsHigh)
1768 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1770 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1771 MI.getOperand(5).setImm(
MI.getOperand(5).getImm() ^ 32);
1776 case SystemZ::ADJDYNALLOC:
1777 splitAdjDynAlloc(
MI);
1780 case SystemZ::MOV_STACKGUARD:
1781 expandStackGuardPseudo(
MI, SystemZ::MVC);
1784 case SystemZ::CMP_STACKGUARD:
1785 expandStackGuardPseudo(
MI, SystemZ::CLC);
1794 unsigned Opcode)
const {
1797 const auto DL =
MI.getDebugLoc();
1799 StringRef GuardType = M->getStackProtectorGuard();
1802 Register AddrReg =
MI.getOperand(0).getReg();
1805 AddrReg !=
MI.getOperand(1).getReg() &&
1806 "Scratch register for stack guard address blocked by operand register.");
1810 if (GuardType.
empty() || (GuardType ==
"tls")) {
1812 enum { OFFSET_PSALAA = 0x4B8 };
1813 enum { OFFSET_CEELAA_STACK_GUARD = 0x98 };
1820 Offset = OFFSET_CEELAA_STACK_GUARD;
1827 }
else if (GuardType ==
"global") {
1844 MI.removeFromParent();
1848 if (
MI.isInlineAsm()) {
1850 const char *AsmStr =
MI.getOperand(0).getSymbolName();
1853 else if (
MI.getOpcode() == SystemZ::PATCHPOINT)
1855 else if (
MI.getOpcode() == SystemZ::STACKMAP)
1856 return MI.getOperand(1).getImm();
1857 else if (
MI.getOpcode() == SystemZ::FENTRY_CALL)
1859 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)
1861 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_RET)
1862 return 18 + (
MI.getOperand(0).
getImm() == SystemZ::CondReturn ? 4 : 0);
1863 if (
MI.getOpcode() == TargetOpcode::BUNDLE)
1864 return getInstBundleSize(
MI);
1865 if (
MI.getOpcode() == SystemZ::LOAD_TLS_BLOCK_ADDR)
1868 if (
MI.getOpcode() == SystemZ::LOAD_GLOBAL_STACKGUARD_ADDR)
1872 return MI.getDesc().getSize();
1877 switch (
MI.getOpcode()) {
1888 MI.getOperand(1).getImm(), &
MI.getOperand(2));
1891 case SystemZ::BRCTH:
1895 case SystemZ::BRCTG:
1902 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1907 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1912 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1914 case SystemZ::CLGIJ:
1915 case SystemZ::CLGRJ:
1917 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1919 case SystemZ::INLINEASM_BR:
1929 unsigned &LoadOpcode,
1930 unsigned &StoreOpcode)
const {
1931 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1932 LoadOpcode = SystemZ::L;
1933 StoreOpcode = SystemZ::ST;
1934 }
else if (RC == &SystemZ::GRH32BitRegClass) {
1935 LoadOpcode = SystemZ::LFH;
1936 StoreOpcode = SystemZ::STFH;
1937 }
else if (RC == &SystemZ::GRX32BitRegClass) {
1938 LoadOpcode = SystemZ::LMux;
1939 StoreOpcode = SystemZ::STMux;
1940 }
else if (RC == &SystemZ::GR64BitRegClass ||
1941 RC == &SystemZ::ADDR64BitRegClass) {
1942 LoadOpcode = SystemZ::LG;
1943 StoreOpcode = SystemZ::STG;
1944 }
else if (RC == &SystemZ::GR128BitRegClass ||
1945 RC == &SystemZ::ADDR128BitRegClass) {
1946 LoadOpcode = SystemZ::L128;
1947 StoreOpcode = SystemZ::ST128;
1948 }
else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
1949 LoadOpcode = SystemZ::LE16;
1950 StoreOpcode = SystemZ::STE16;
1951 }
else if (RC == &SystemZ::FP32BitRegClass) {
1952 LoadOpcode = SystemZ::LE;
1953 StoreOpcode = SystemZ::STE;
1954 }
else if (RC == &SystemZ::FP64BitRegClass) {
1955 LoadOpcode = SystemZ::LD;
1956 StoreOpcode = SystemZ::STD;
1957 }
else if (RC == &SystemZ::FP128BitRegClass) {
1958 LoadOpcode = SystemZ::LX;
1959 StoreOpcode = SystemZ::STX;
1960 }
else if (RC == &SystemZ::FP16BitRegClass ||
1961 RC == &SystemZ::VR16BitRegClass) {
1962 LoadOpcode = SystemZ::VL16;
1963 StoreOpcode = SystemZ::VST16;
1964 }
else if (RC == &SystemZ::VR32BitRegClass) {
1965 LoadOpcode = SystemZ::VL32;
1966 StoreOpcode = SystemZ::VST32;
1967 }
else if (RC == &SystemZ::VR64BitRegClass) {
1968 LoadOpcode = SystemZ::VL64;
1969 StoreOpcode = SystemZ::VST64;
1970 }
else if (RC == &SystemZ::VF128BitRegClass ||
1971 RC == &SystemZ::VR128BitRegClass) {
1972 LoadOpcode = SystemZ::VL;
1973 StoreOpcode = SystemZ::VST;
1985 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1986 if (Disp12Opcode >= 0)
1987 return Disp12Opcode;
1995 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1996 if (Disp20Opcode >= 0)
1997 return Disp20Opcode;
2004 if (
MI &&
MI->getOperand(0).isReg()) {
2009 return SystemZ::LEY;
2010 case SystemZ::VST32:
2011 return SystemZ::STEY;
2013 return SystemZ::LDY;
2014 case SystemZ::VST64:
2015 return SystemZ::STDY;
2027 return SystemZ::getDisp12Opcode(Opcode) >= 0;
2028 return SystemZ::getDisp20Opcode(Opcode) >= 0;
2033 case SystemZ::L:
return SystemZ::LT;
2034 case SystemZ::LY:
return SystemZ::LT;
2035 case SystemZ::LG:
return SystemZ::LTG;
2036 case SystemZ::LGF:
return SystemZ::LTGF;
2037 case SystemZ::LR:
return SystemZ::LTR;
2038 case SystemZ::LGFR:
return SystemZ::LTGFR;
2039 case SystemZ::LGR:
return SystemZ::LTGR;
2040 case SystemZ::LCDFR:
return SystemZ::LCDBR;
2041 case SystemZ::LPDFR:
return SystemZ::LPDBR;
2042 case SystemZ::LNDFR:
return SystemZ::LNDBR;
2043 case SystemZ::LCDFR_32:
return SystemZ::LCEBR;
2044 case SystemZ::LPDFR_32:
return SystemZ::LPEBR;
2045 case SystemZ::LNDFR_32:
return SystemZ::LNEBR;
2050 case SystemZ::RISBGN:
return SystemZ::RISBG;
2056 unsigned &Start,
unsigned &
End)
const {
2066 Start = 63 - (LSB +
Length - 1);
2074 assert(LSB > 0 &&
"Bottom bit must be set");
2075 assert(LSB +
Length < BitSize &&
"Top bit must be set");
2076 Start = 63 - (LSB - 1);
2094 case SystemZ::CLGFI:
2100 if (!STI.hasMiscellaneousExtensions())
2102 if (!(
MI &&
MI->getOperand(3).getReg() == 0))
2110 return SystemZ::CRJ;
2112 return SystemZ::CGRJ;
2114 return SystemZ::CIJ;
2116 return SystemZ::CGIJ;
2118 return SystemZ::CLRJ;
2120 return SystemZ::CLGRJ;
2122 return SystemZ::CLIJ;
2123 case SystemZ::CLGFI:
2124 return SystemZ::CLGIJ;
2131 return SystemZ::CRBReturn;
2133 return SystemZ::CGRBReturn;
2135 return SystemZ::CIBReturn;
2137 return SystemZ::CGIBReturn;
2139 return SystemZ::CLRBReturn;
2141 return SystemZ::CLGRBReturn;
2143 return SystemZ::CLIBReturn;
2144 case SystemZ::CLGFI:
2145 return SystemZ::CLGIBReturn;
2152 return SystemZ::CRBCall;
2154 return SystemZ::CGRBCall;
2156 return SystemZ::CIBCall;
2158 return SystemZ::CGIBCall;
2160 return SystemZ::CLRBCall;
2162 return SystemZ::CLGRBCall;
2164 return SystemZ::CLIBCall;
2165 case SystemZ::CLGFI:
2166 return SystemZ::CLGIBCall;
2173 return SystemZ::CRT;
2175 return SystemZ::CGRT;
2177 return SystemZ::CIT;
2179 return SystemZ::CGIT;
2181 return SystemZ::CLRT;
2183 return SystemZ::CLGRT;
2185 return SystemZ::CLFIT;
2186 case SystemZ::CLGFI:
2187 return SystemZ::CLGIT;
2189 return SystemZ::CLT;
2191 return SystemZ::CLGT;
2202 return (
MI.getOpcode() == SystemZ::LTEBR ||
2203 MI.getOpcode() == SystemZ::LTDBR ||
2204 MI.getOpcode() == SystemZ::LTXBR) &&
2205 MI.getOperand(0).isDead();
2211 return Compare.isCompare() && Compare.getNumExplicitOperands() == 2 &&
2212 Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
2224 MBBI->getOperand(1).isReg() && !
MBBI->mayLoad() &&
2225 "Not a compare reg/reg.");
2231 if (
MI.readsRegister(SystemZ::CC,
nullptr)) {
2232 unsigned Flags =
MI.getDesc().TSFlags;
2238 if (
MI.definesRegister(SystemZ::CC,
nullptr)) {
2246 if (!
LiveRegs.available(SystemZ::CC))
2251 for (
unsigned Idx = 0; Idx < CCUsers.
size(); ++Idx) {
2252 unsigned Flags = CCUsers[Idx]->getDesc().TSFlags;
2254 0 : CCUsers[Idx]->getNumExplicitOperands() - 2);
2255 MachineOperand &CCMaskMO = CCUsers[Idx]->getOperand(FirstOpNum + 1);
2257 CCMaskMO.
setImm(NewCCMask);
2295 if (!STI.hasLoadAndTrap())
2300 return SystemZ::LAT;
2302 return SystemZ::LGAT;
2304 return SystemZ::LFHAT;
2306 return SystemZ::LLGFAT;
2308 return SystemZ::LLGTAT;
2315 unsigned Reg, uint64_t
Value)
const {
2317 unsigned Opcode = 0;
2319 Opcode = SystemZ::LGHI;
2321 Opcode = SystemZ::LLILL;
2323 Opcode = SystemZ::LLILH;
2327 Opcode = SystemZ::LGFI;
2334 assert (MRI.
isSSA() &&
"Huge values only handled before reg-alloc .");
2347 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
2348 if (
I >=
MCID.getNumOperands())
2356 ((
MCOI.RegClass != -1 && !
Op.isReg() && !
Op.isFI()) ||
2357 (
MCOI.RegClass == -1 && !
Op.isImm()))) {
2358 ErrInfo =
"Addressing mode operands corrupt!";
2381 bool SameVal = (VALa && VALb && (VALa == VALb));
2385 if (PSVa && PSVb && (PSVa == PSVb))
2391 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2392 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2393 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2395 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
2404 int64_t &ImmVal)
const {
2406 if (
MI.getOpcode() == SystemZ::VGBM && Reg ==
MI.getOperand(0).getReg()) {
2407 ImmVal =
MI.getOperand(1).getImm();
2415std::optional<DestSourcePair>
2421 return std::nullopt;
2424std::pair<unsigned, unsigned>
2426 return std::make_pair(TF, 0u);
2433 static const std::pair<unsigned, const char *> TargetFlags[] = {
2434 {MO_GOT,
"systemz-got"},
2435 {MO_INDNTPOFF,
"systemz-indntpoff"},
2436 {MO_ADA_DATA_SYMBOL_ADDR,
"systemz-ada-datasymboladdr"},
2437 {MO_ADA_INDIRECT_FUNC_DESC,
"systemz-ada-indirectfuncdesc"},
2438 {MO_ADA_DIRECT_FUNC_DESC,
"systemz-ada-directfuncdesc"}};
2447 return MI.getOpcode() == SystemZ::FENCE ||
2448 MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER;
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
Module.h This file contains the declarations for the Module class.
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)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Module * getParent()
Get the module that this global value is contained inside of...
SlotIndexes * getSlotIndexes() const
VNInfo::Allocator & getVNInfoAllocator()
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
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.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
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...
A Module instance is used to store all the information related to an LLVM module.
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.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
virtual int getStackPointerBias()=0
virtual int getCallFrameSize()=0
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveIntervals *LIS) const override
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 canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, SelectExpansion &) const override
bool isPredicable(const MachineInstr &MI) const override
Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) 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
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 bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
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)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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.
@ End
Run the machine verifier once, at the end of the pipeline.
constexpr RegState getUndefRegState(bool B)
MCRegisterClass TargetRegisterClass