48#define GET_INSTRINFO_CTOR_DTOR
49#define GET_INSTRMAP_INFO
50#include "SystemZGenInstrInfo.inc"
52#define DEBUG_TYPE "systemz-II"
56 return Count == 0 ? 0 : (
uint64_t(1) << (Count - 1) << 1) - 1;
60void SystemZInstrInfo::anchor() {}
64 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister(),
71 unsigned NewOpcode)
const {
87 HighRegOp.
setReg(RI.getSubReg(HighRegOp.
getReg(), SystemZ::subreg_h64));
88 LowRegOp.
setReg(RI.getSubReg(LowRegOp.
getReg(), SystemZ::subreg_l64));
99 assert(HighOpcode && LowOpcode &&
"Both offsets should be in range");
104 if (
MI->mayStore()) {
116 auto overlapsAddressReg = [&](
Register Reg) ->
bool {
117 return RI.regsOverlap(Reg,
MI->getOperand(1).getReg()) ||
118 RI.regsOverlap(Reg,
MI->getOperand(3).getReg());
120 if (overlapsAddressReg(HighRegOp.
getReg())) {
122 "Both loads clobber address!");
146 assert(NewOpcode &&
"No support for huge argument lists yet");
147 MI->setDesc(
get(NewOpcode));
157void SystemZInstrInfo::expandRIPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
159 bool ConvertHigh)
const {
162 MI.setDesc(
get(IsHigh ? HighOpcode : LowOpcode));
163 if (IsHigh && ConvertHigh)
164 MI.getOperand(1).setImm(
uint32_t(
MI.getOperand(1).getImm()));
171void SystemZInstrInfo::expandRIEPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
173 unsigned HighOpcode)
const {
178 if (!DestIsHigh && !SrcIsHigh)
179 MI.setDesc(
get(LowOpcodeK));
181 if (DestReg != SrcReg) {
182 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(), DestReg, SrcReg,
183 SystemZ::LR, 32,
MI.getOperand(1).isKill(),
184 MI.getOperand(1).isUndef());
185 MI.getOperand(1).setReg(DestReg);
187 MI.setDesc(
get(DestIsHigh ? HighOpcode : LowOpcode));
188 MI.tieOperands(0, 1);
195void SystemZInstrInfo::expandRXYPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
196 unsigned HighOpcode)
const {
200 MI.getOperand(2).getImm());
201 MI.setDesc(
get(Opcode));
207void SystemZInstrInfo::expandLOCPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
208 unsigned HighOpcode)
const {
211 MI.setDesc(
get(Opcode));
217void SystemZInstrInfo::expandZExtPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
218 unsigned Size)
const {
220 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(),
221 MI.getOperand(0).getReg(),
MI.getOperand(1).getReg(), LowOpcode,
222 Size,
MI.getOperand(1).isKill(),
MI.getOperand(1).isUndef());
228 MI.eraseFromParent();
231void SystemZInstrInfo::expandLoadStackGuard(
MachineInstr *
MI)
const {
234 const Register Reg64 =
MI->getOperand(0).getReg();
235 const Register Reg32 = RI.getSubReg(Reg64, SystemZ::subreg_l32);
256 MI->setDesc(
get(SystemZ::LG));
269 unsigned SrcReg,
unsigned LowLowOpcode,
270 unsigned Size,
bool KillSrc,
271 bool UndefSrc)
const {
275 if (DestIsHigh && SrcIsHigh)
276 Opcode = SystemZ::RISBHH;
277 else if (DestIsHigh && !SrcIsHigh)
278 Opcode = SystemZ::RISBHL;
279 else if (!DestIsHigh && SrcIsHigh)
280 Opcode = SystemZ::RISBLH;
285 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
295 unsigned OpIdx2)
const {
298 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
302 switch (
MI.getOpcode()) {
303 case SystemZ::SELRMux:
304 case SystemZ::SELFHR:
307 case SystemZ::LOCRMux:
308 case SystemZ::LOCFHR:
310 case SystemZ::LOCGR: {
311 auto &WorkingMI = cloneIfNew(
MI);
313 unsigned CCValid = WorkingMI.getOperand(3).getImm();
314 unsigned CCMask = WorkingMI.getOperand(4).getImm();
315 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
332 if ((MCID.
TSFlags & Flag) &&
MI.getOperand(1).isFI() &&
333 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).getReg() == 0) {
334 FrameIndex =
MI.getOperand(1).getIndex();
335 return MI.getOperand(0).getReg();
341 int &FrameIndex)
const {
346 int &FrameIndex)
const {
351 int &FrameIndex)
const {
366 cast<FixedStackPseudoSourceValue>(
Accesses.front()->getPseudoValue())
368 return MI.getOperand(0).getReg();
374 int &FrameIndex)
const {
389 cast<FixedStackPseudoSourceValue>(
Accesses.front()->getPseudoValue())
391 return MI.getOperand(0).getReg();
398 int &SrcFrameIndex)
const {
401 if (
MI.getOpcode() != SystemZ::MVC || !
MI.getOperand(0).isFI() ||
402 MI.getOperand(1).getImm() != 0 || !
MI.getOperand(3).isFI() ||
403 MI.getOperand(4).getImm() != 0)
407 int64_t
Length =
MI.getOperand(2).getImm();
408 unsigned FI1 =
MI.getOperand(0).getIndex();
409 unsigned FI2 =
MI.getOperand(3).getIndex();
414 DestFrameIndex = FI1;
423 bool AllowModify)
const {
431 if (
I->isDebugInstr())
436 if (!isUnpredicatedTerminator(*
I))
446 if (!Branch.hasMBBTarget())
456 TBB = Branch.getMBBTarget();
469 I->eraseFromParent();
475 TBB = Branch.getMBBTarget();
483 TBB = Branch.getMBBTarget();
490 assert(
Cond.size() == 2 &&
TBB &&
"Should have seen a conditional branch");
494 if (
TBB != Branch.getMBBTarget())
498 unsigned OldCCValid =
Cond[0].getImm();
499 unsigned OldCCMask =
Cond[1].getImm();
500 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
511 int *BytesRemoved)
const {
512 assert(!BytesRemoved &&
"code size not handled");
520 if (
I->isDebugInstr())
527 I->eraseFromParent();
537 assert(
Cond.size() == 2 &&
"Invalid condition");
547 int *BytesAdded)
const {
553 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
555 "SystemZ branch conditions have one component!");
556 assert(!BytesAdded &&
"code size not handled");
560 assert(!FBB &&
"Unconditional branch with multiple successors!");
567 unsigned CCValid =
Cond[0].getImm();
568 unsigned CCMask =
Cond[1].getImm();
583 int64_t &
Value)
const {
584 assert(
MI.isCompare() &&
"Caller should have checked for a comparison");
586 if (
MI.getNumExplicitOperands() == 2 &&
MI.getOperand(0).isReg() &&
587 MI.getOperand(1).isImm()) {
588 SrcReg =
MI.getOperand(0).getReg();
590 Value =
MI.getOperand(1).getImm();
603 int &FalseCycles)
const {
605 if (!STI.hasLoadStoreOnCond())
607 if (Pred.
size() != 2)
613 RI.getCommonSubClass(
MRI.getRegClass(TrueReg),
MRI.getRegClass(FalseReg));
618 if ((STI.hasLoadStoreOnCond2() &&
619 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
620 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
621 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
641 assert(Pred.
size() == 2 &&
"Invalid condition");
642 unsigned CCValid = Pred[0].getImm();
643 unsigned CCMask = Pred[1].getImm();
646 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
647 if (STI.hasMiscellaneousExtensions3())
648 Opc = SystemZ::SELRMux;
649 else if (STI.hasLoadStoreOnCond2())
650 Opc = SystemZ::LOCRMux;
653 MRI.constrainRegClass(DstReg, &SystemZ::GR32BitRegClass);
654 Register TReg =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
655 Register FReg =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
661 }
else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
662 if (STI.hasMiscellaneousExtensions3())
663 Opc = SystemZ::SELGR;
665 Opc = SystemZ::LOCGR;
677 unsigned DefOpc =
DefMI.getOpcode();
679 if (DefOpc == SystemZ::VGBM) {
680 int64_t ImmVal =
DefMI.getOperand(1).getImm();
695 MRI->getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
696 MRI->hasOneNonDBGUse(Reg)) {
700 Register TmpReg =
MRI->createVirtualRegister(&SystemZ::GR64BitRegClass);
705 UseMI.setDesc(
get(SystemZ::REG_SEQUENCE));
706 UseMI.getOperand(1).setReg(TmpReg);
708 .
addImm(SystemZ::subreg_h64)
710 .
addImm(SystemZ::subreg_l64);
712 if (
MRI->use_nodbg_empty(Reg))
713 DefMI.eraseFromParent();
720 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
721 DefOpc != SystemZ::LGHI)
725 int32_t ImmVal = (int32_t)
DefMI.getOperand(1).getImm();
727 unsigned UseOpc =
UseMI.getOpcode();
733 case SystemZ::SELRMux:
736 case SystemZ::LOCRMux:
737 if (!STI.hasLoadStoreOnCond2())
739 NewUseOpc = SystemZ::LOCHIMux;
743 UseIdx = 2, CommuteIdx = 1;
751 if (!STI.hasLoadStoreOnCond2())
753 NewUseOpc = SystemZ::LOCGHI;
757 UseIdx = 2, CommuteIdx = 1;
765 if (CommuteIdx != -1)
766 if (!commuteInstruction(
UseMI,
false, CommuteIdx, UseIdx))
769 bool DeleteDef =
MRI->hasOneNonDBGUse(Reg);
772 UseMI.tieOperands(0, 1);
773 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
775 DefMI.eraseFromParent();
781 unsigned Opcode =
MI.getOpcode();
782 if (Opcode == SystemZ::Return ||
783 Opcode == SystemZ::Return_XPLINK ||
784 Opcode == SystemZ::Trap ||
785 Opcode == SystemZ::CallJG ||
786 Opcode == SystemZ::CallBR)
793 unsigned NumCycles,
unsigned ExtraPredCycles,
807 return NumCycles == 1;
812 unsigned NumCyclesT,
unsigned ExtraPredCyclesT,
814 unsigned NumCyclesF,
unsigned ExtraPredCyclesF,
824 return NumCycles == 1;
829 assert(Pred.
size() == 2 &&
"Invalid condition");
830 unsigned CCValid = Pred[0].getImm();
831 unsigned CCMask = Pred[1].getImm();
832 assert(CCMask > 0 && CCMask < 15 &&
"Invalid predicate");
833 unsigned Opcode =
MI.getOpcode();
834 if (Opcode == SystemZ::Trap) {
835 MI.setDesc(
get(SystemZ::CondTrap));
841 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
842 MI.setDesc(
get(Opcode == SystemZ::Return ? SystemZ::CondReturn
843 : SystemZ::CondReturn_XPLINK));
850 if (Opcode == SystemZ::CallJG) {
852 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
855 MI.setDesc(
get(SystemZ::CallBRCL));
864 if (Opcode == SystemZ::CallBR) {
866 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
869 MI.setDesc(
get(SystemZ::CallBCR));
885 bool RenamableSrc)
const {
889 if (SystemZ::GR128BitRegClass.
contains(DestReg, SrcReg)) {
891 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
895 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
901 if (SystemZ::GRX32BitRegClass.
contains(DestReg, SrcReg)) {
902 emitGRX32Move(
MBB,
MBBI,
DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
908 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
909 SystemZ::FP128BitRegClass.
contains(SrcReg)) {
911 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
912 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
914 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
915 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
922 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
923 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
925 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
926 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
928 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
929 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
931 if (DestRegHi != SrcReg.
asMCReg())
938 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
939 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
940 MCRegister DestRegHi = RI.getSubReg(DestReg, SystemZ::subreg_h64);
941 MCRegister DestRegLo = RI.getSubReg(DestReg, SystemZ::subreg_l64);
942 MCRegister SrcRegHi = RI.getSubReg(SrcReg, SystemZ::subreg_h64);
943 MCRegister SrcRegLo = RI.getSubReg(SrcReg, SystemZ::subreg_l64);
955 if (DestReg == SystemZ::CC) {
957 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
964 if (SystemZ::GR128BitRegClass.
contains(DestReg) &&
965 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
966 MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64);
967 MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64);
971 .
addReg(SystemZ::NoRegister)
976 .
addReg(SystemZ::NoRegister)
981 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
982 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
984 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64))
985 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64));
991 if (SystemZ::GR64BitRegClass.
contains(DestReg, SrcReg))
992 Opcode = SystemZ::LGR;
993 else if (SystemZ::FP16BitRegClass.
contains(DestReg, SrcReg))
994 Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
995 else if (SystemZ::FP32BitRegClass.
contains(DestReg, SrcReg))
997 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
998 else if (SystemZ::FP64BitRegClass.
contains(DestReg, SrcReg))
999 Opcode = SystemZ::LDR;
1000 else if (SystemZ::FP128BitRegClass.
contains(DestReg, SrcReg))
1001 Opcode = SystemZ::LXR;
1002 else if (SystemZ::VR32BitRegClass.
contains(DestReg, SrcReg))
1003 Opcode = SystemZ::VLR32;
1004 else if (SystemZ::VR64BitRegClass.
contains(DestReg, SrcReg))
1005 Opcode = SystemZ::VLR64;
1006 else if (SystemZ::VR128BitRegClass.
contains(DestReg, SrcReg))
1007 Opcode = SystemZ::VLR;
1008 else if (SystemZ::AR32BitRegClass.
contains(DestReg, SrcReg))
1009 Opcode = SystemZ::CPYA;
1010 else if (SystemZ::GR64BitRegClass.
contains(DestReg) &&
1011 SystemZ::FP64BitRegClass.
contains(SrcReg))
1012 Opcode = SystemZ::LGDR;
1013 else if (SystemZ::FP64BitRegClass.
contains(DestReg) &&
1014 SystemZ::GR64BitRegClass.
contains(SrcReg))
1015 Opcode = SystemZ::LDGR;
1032 unsigned LoadOpcode, StoreOpcode;
1047 unsigned LoadOpcode, StoreOpcode;
1057 return ((MCID.
TSFlags & Flag) &&
1058 isUInt<12>(
MI->getOperand(2).getImm()) &&
1059 MI->getOperand(3).getReg() == 0);
1065 LogicOp() =
default;
1066 LogicOp(
unsigned regSize,
unsigned immLSB,
unsigned immSize)
1067 :
RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1069 explicit operator bool()
const {
return RegSize; }
1072 unsigned ImmLSB = 0;
1073 unsigned ImmSize = 0;
1080 case SystemZ::NILMux:
return LogicOp(32, 0, 16);
1081 case SystemZ::NIHMux:
return LogicOp(32, 16, 16);
1082 case SystemZ::NILL64:
return LogicOp(64, 0, 16);
1083 case SystemZ::NILH64:
return LogicOp(64, 16, 16);
1084 case SystemZ::NIHL64:
return LogicOp(64, 32, 16);
1085 case SystemZ::NIHH64:
return LogicOp(64, 48, 16);
1086 case SystemZ::NIFMux:
return LogicOp(32, 0, 32);
1087 case SystemZ::NILF64:
return LogicOp(64, 0, 32);
1088 case SystemZ::NIHF64:
return LogicOp(64, 32, 32);
1089 default:
return LogicOp();
1097 if (CCDef !=
nullptr)
1119 unsigned Start,
End;
1122 if (
And.RegSize == 64) {
1123 NewOpcode = SystemZ::RISBG;
1125 if (STI.hasMiscellaneousExtensions())
1126 NewOpcode = SystemZ::RISBGN;
1128 NewOpcode = SystemZ::RISBMux;
1144 unsigned NumOps =
MI.getNumOperands();
1145 for (
unsigned I = 1;
I < NumOps; ++
I) {
1147 if (
Op.isReg() &&
Op.isKill())
1161 bool Invert)
const {
1167 Opc = *InverseOpcode;
1174 case SystemZ::WFADB:
1175 case SystemZ::WFASB:
1176 case SystemZ::WFAXB:
1177 case SystemZ::VFADB:
1178 case SystemZ::VFASB:
1179 case SystemZ::WFMDB:
1180 case SystemZ::WFMSB:
1181 case SystemZ::WFMXB:
1182 case SystemZ::VFMDB:
1183 case SystemZ::VFMSB:
1191std::optional<unsigned>
1195 case SystemZ::WFADB:
1196 return SystemZ::WFSDB;
1197 case SystemZ::WFASB:
1198 return SystemZ::WFSSB;
1199 case SystemZ::WFAXB:
1200 return SystemZ::WFSXB;
1201 case SystemZ::VFADB:
1202 return SystemZ::VFSDB;
1203 case SystemZ::VFASB:
1204 return SystemZ::VFSSB;
1206 case SystemZ::WFSDB:
1207 return SystemZ::WFADB;
1208 case SystemZ::WFSSB:
1209 return SystemZ::WFASB;
1210 case SystemZ::WFSXB:
1211 return SystemZ::WFAXB;
1212 case SystemZ::VFSDB:
1213 return SystemZ::VFADB;
1214 case SystemZ::VFSSB:
1215 return SystemZ::VFASB;
1217 return std::nullopt;
1229 unsigned Opcode =
MI.getOpcode();
1234 bool CCLiveAtMI =
true;
1239 CCLiveRange = &LIS->
getRegUnit(*CCUnits.begin());
1240 CCLiveAtMI = CCLiveRange->
liveAt(MISlot);
1243 if (Ops.
size() == 2 && Ops[0] == 0 && Ops[1] == 1) {
1244 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1245 isInt<8>(
MI.getOperand(2).getImm()) && !
MI.getOperand(3).getReg()) {
1248 MI.getDebugLoc(),
get(SystemZ::AGSI))
1251 .
addImm(
MI.getOperand(2).getImm());
1261 if (Ops.
size() != 1)
1264 unsigned OpNum = Ops[0];
1268 (RC == &SystemZ::FP16BitRegClass &&
Size == 4 && !STI.hasVector())) &&
1269 "Invalid size combination");
1272 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1273 isInt<8>(
MI.getOperand(2).getImm())) {
1275 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1277 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1280 .
addImm(
MI.getOperand(2).getImm());
1286 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1287 isInt<8>((int32_t)
MI.getOperand(2).getImm())) ||
1288 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1289 isInt<8>(
MI.getOperand(2).getImm()))) {
1291 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1293 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1296 .
addImm((int8_t)
MI.getOperand(2).getImm());
1301 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1302 isInt<8>((int32_t)-
MI.getOperand(2).getImm())) ||
1303 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1304 isInt<8>((-
MI.getOperand(2).getImm())))) {
1306 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1308 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1311 .
addImm((int8_t)-
MI.getOperand(2).getImm());
1316 unsigned MemImmOpc = 0;
1318 case SystemZ::LHIMux:
1319 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI;
break;
1320 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI;
break;
1321 case SystemZ::CHIMux:
1322 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI;
break;
1323 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI;
break;
1324 case SystemZ::CLFIMux:
1326 if (isUInt<16>(
MI.getOperand(1).getImm()))
1327 MemImmOpc = SystemZ::CLFHSI;
1329 case SystemZ::CLGFI:
1330 if (isUInt<16>(
MI.getOperand(1).getImm()))
1331 MemImmOpc = SystemZ::CLGHSI;
1336 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1340 .
addImm(
MI.getOperand(1).getImm());
1342 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1343 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1344 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1348 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1349 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1351 .
add(
MI.getOperand(1))
1359 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1360 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1362 .
add(
MI.getOperand(0))
1382 if (OpNum == 0 &&
MI.hasOneMemOperand()) {
1387 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1392 .
add(
MI.getOperand(1))
1398 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1400 .
add(
MI.getOperand(1))
1413 unsigned NumOps =
MI.getNumExplicitOperands();
1414 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1415 if (MemOpcode == -1 ||
1416 (CCLiveAtMI && !
MI.definesRegister(SystemZ::CC,
nullptr) &&
1417 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1428 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1434 !(SystemZ::FP32BitRegClass.
contains(PhysReg) ||
1435 SystemZ::FP64BitRegClass.
contains(PhysReg) ||
1436 SystemZ::VF128BitRegClass.
contains(PhysReg)))
1441 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1442 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1446 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1451 bool NeedsCommute =
false;
1452 if ((
MI.getOpcode() == SystemZ::CR ||
MI.getOpcode() == SystemZ::CGR ||
1453 MI.getOpcode() == SystemZ::CLR ||
MI.getOpcode() == SystemZ::CLGR ||
1454 MI.getOpcode() == SystemZ::WFCDB ||
MI.getOpcode() == SystemZ::WFCSB ||
1455 MI.getOpcode() == SystemZ::WFKDB ||
MI.getOpcode() == SystemZ::WFKSB) &&
1457 NeedsCommute =
true;
1459 bool CCOperands =
false;
1460 if (
MI.getOpcode() == SystemZ::LOCRMux ||
MI.getOpcode() == SystemZ::LOCGR ||
1461 MI.getOpcode() == SystemZ::SELRMux ||
MI.getOpcode() == SystemZ::SELGR) {
1462 assert(
MI.getNumOperands() == 6 && NumOps == 5 &&
1463 "LOCR/SELR instruction operands corrupt?");
1478 Register SrcReg = (OpNum == 2 ?
MI.getOperand(1).getReg()
1479 : ((OpNum == 1 &&
MI.isCommutable())
1480 ?
MI.getOperand(2).getReg()
1482 if (DstPhys && !SystemZ::GRH32BitRegClass.
contains(DstPhys) && SrcReg &&
1484 NeedsCommute = (OpNum == 1);
1490 if ((OpNum == NumOps - 1) || NeedsCommute || FusedFPOp) {
1493 assert(AccessBytes != 0 &&
"Size of access should be known");
1494 assert(AccessBytes <=
Size &&
"Access outside the frame index");
1497 MI.getDebugLoc(),
get(MemOpcode));
1498 if (
MI.isCompare()) {
1499 assert(NumOps == 2 &&
"Expected 2 register operands for a compare.");
1500 MIB.
add(
MI.getOperand(NeedsCommute ? 1 : 0));
1502 else if (FusedFPOp) {
1503 MIB.
add(
MI.getOperand(0));
1504 MIB.
add(
MI.getOperand(3));
1505 MIB.
add(
MI.getOperand(OpNum == 1 ? 2 : 1));
1508 MIB.
add(
MI.getOperand(0));
1510 MIB.
add(
MI.getOperand(2));
1512 for (
unsigned I = 1;
I < OpNum; ++
I)
1513 MIB.
add(
MI.getOperand(
I));
1519 unsigned CCValid =
MI.getOperand(NumOps).getImm();
1520 unsigned CCMask =
MI.getOperand(NumOps + 1).getImm();
1522 MIB.
addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1525 (!
MI.definesRegister(SystemZ::CC,
nullptr) ||
1526 MI.registerDefIsDead(SystemZ::CC,
nullptr))) {
1534 if (MO.isReg() && MO.getReg().isVirtual()) {
1536 if (
MRI.getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1537 MRI.setRegClass(Reg, &SystemZ::FP32BitRegClass);
1538 else if (
MRI.getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1539 MRI.setRegClass(Reg, &SystemZ::FP64BitRegClass);
1540 else if (
MRI.getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1541 MRI.setRegClass(Reg, &SystemZ::VF128BitRegClass);
1566 unsigned LoadOpc = 0;
1567 unsigned RegMemOpcode = 0;
1569 RegMemOpcode =
MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1570 :
MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1571 :
MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1574 LoadOpc = SystemZ::VL64;
1575 FPRC = &SystemZ::FP64BitRegClass;
1577 RegMemOpcode =
MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1578 :
MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1579 :
MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1582 LoadOpc = SystemZ::VL32;
1583 FPRC = &SystemZ::FP32BitRegClass;
1586 if (!RegMemOpcode || LoadMI.
getOpcode() != LoadOpc)
1590 if (
get(RegMemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)) {
1592 assert(LoadMI != InsertPt &&
"Assuming InsertPt not to be first in MBB.");
1595 if (MII->definesRegister(SystemZ::CC,
nullptr)) {
1596 if (!MII->registerDefIsDead(SystemZ::CC,
nullptr))
1609 if (Ops.
size() != 1 || FoldAsLoadDefReg !=
MI.getOperand(Ops[0]).getReg())
1615 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1616 FoldAsLoadDefReg !=
RHS.getReg())
1623 BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(RegMemOpcode), DstReg)
1629 MRI->setRegClass(DstReg, FPRC);
1637 switch (
MI.getOpcode()) {
1639 splitMove(
MI, SystemZ::LG);
1642 case SystemZ::ST128:
1643 splitMove(
MI, SystemZ::STG);
1647 splitMove(
MI, SystemZ::LD);
1651 splitMove(
MI, SystemZ::STD);
1654 case SystemZ::LBMux:
1655 expandRXYPseudo(
MI, SystemZ::LB, SystemZ::LBH);
1658 case SystemZ::LHMux:
1659 expandRXYPseudo(
MI, SystemZ::LH, SystemZ::LHH);
1662 case SystemZ::LLCRMux:
1663 expandZExtPseudo(
MI, SystemZ::LLCR, 8);
1666 case SystemZ::LLHRMux:
1667 expandZExtPseudo(
MI, SystemZ::LLHR, 16);
1670 case SystemZ::LLCMux:
1671 expandRXYPseudo(
MI, SystemZ::LLC, SystemZ::LLCH);
1674 case SystemZ::LLHMux:
1675 expandRXYPseudo(
MI, SystemZ::LLH, SystemZ::LLHH);
1679 expandRXYPseudo(
MI, SystemZ::L, SystemZ::LFH);
1682 case SystemZ::LOCMux:
1683 expandLOCPseudo(
MI, SystemZ::LOC, SystemZ::LOCFH);
1686 case SystemZ::LOCHIMux:
1687 expandLOCPseudo(
MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1690 case SystemZ::STCMux:
1691 expandRXYPseudo(
MI, SystemZ::STC, SystemZ::STCH);
1694 case SystemZ::STHMux:
1695 expandRXYPseudo(
MI, SystemZ::STH, SystemZ::STHH);
1698 case SystemZ::STMux:
1699 expandRXYPseudo(
MI, SystemZ::ST, SystemZ::STFH);
1702 case SystemZ::STOCMux:
1703 expandLOCPseudo(
MI, SystemZ::STOC, SystemZ::STOCFH);
1706 case SystemZ::LHIMux:
1707 expandRIPseudo(
MI, SystemZ::LHI, SystemZ::IIHF,
true);
1710 case SystemZ::IIFMux:
1711 expandRIPseudo(
MI, SystemZ::IILF, SystemZ::IIHF,
false);
1714 case SystemZ::IILMux:
1715 expandRIPseudo(
MI, SystemZ::IILL, SystemZ::IIHL,
false);
1718 case SystemZ::IIHMux:
1719 expandRIPseudo(
MI, SystemZ::IILH, SystemZ::IIHH,
false);
1722 case SystemZ::NIFMux:
1723 expandRIPseudo(
MI, SystemZ::NILF, SystemZ::NIHF,
false);
1726 case SystemZ::NILMux:
1727 expandRIPseudo(
MI, SystemZ::NILL, SystemZ::NIHL,
false);
1730 case SystemZ::NIHMux:
1731 expandRIPseudo(
MI, SystemZ::NILH, SystemZ::NIHH,
false);
1734 case SystemZ::OIFMux:
1735 expandRIPseudo(
MI, SystemZ::OILF, SystemZ::OIHF,
false);
1738 case SystemZ::OILMux:
1739 expandRIPseudo(
MI, SystemZ::OILL, SystemZ::OIHL,
false);
1742 case SystemZ::OIHMux:
1743 expandRIPseudo(
MI, SystemZ::OILH, SystemZ::OIHH,
false);
1746 case SystemZ::XIFMux:
1747 expandRIPseudo(
MI, SystemZ::XILF, SystemZ::XIHF,
false);
1750 case SystemZ::TMLMux:
1751 expandRIPseudo(
MI, SystemZ::TMLL, SystemZ::TMHL,
false);
1754 case SystemZ::TMHMux:
1755 expandRIPseudo(
MI, SystemZ::TMLH, SystemZ::TMHH,
false);
1758 case SystemZ::AHIMux:
1759 expandRIPseudo(
MI, SystemZ::AHI, SystemZ::AIH,
false);
1762 case SystemZ::AHIMuxK:
1763 expandRIEPseudo(
MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1766 case SystemZ::AFIMux:
1767 expandRIPseudo(
MI, SystemZ::AFI, SystemZ::AIH,
false);
1770 case SystemZ::CHIMux:
1771 expandRIPseudo(
MI, SystemZ::CHI, SystemZ::CIH,
false);
1774 case SystemZ::CFIMux:
1775 expandRIPseudo(
MI, SystemZ::CFI, SystemZ::CIH,
false);
1778 case SystemZ::CLFIMux:
1779 expandRIPseudo(
MI, SystemZ::CLFI, SystemZ::CLIH,
false);
1783 expandRXYPseudo(
MI, SystemZ::C, SystemZ::CHF);
1786 case SystemZ::CLMux:
1787 expandRXYPseudo(
MI, SystemZ::CL, SystemZ::CLHF);
1790 case SystemZ::RISBMux: {
1793 if (SrcIsHigh == DestIsHigh)
1794 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1796 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1797 MI.getOperand(5).setImm(
MI.getOperand(5).getImm() ^ 32);
1802 case SystemZ::ADJDYNALLOC:
1803 splitAdjDynAlloc(
MI);
1806 case TargetOpcode::LOAD_STACK_GUARD:
1807 expandLoadStackGuard(&
MI);
1816 if (
MI.isInlineAsm()) {
1818 const char *AsmStr =
MI.getOperand(0).getSymbolName();
1821 else if (
MI.getOpcode() == SystemZ::PATCHPOINT)
1823 else if (
MI.getOpcode() == SystemZ::STACKMAP)
1824 return MI.getOperand(1).getImm();
1825 else if (
MI.getOpcode() == SystemZ::FENTRY_CALL)
1827 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)
1829 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_RET)
1830 return 18 + (
MI.getOperand(0).getImm() == SystemZ::CondReturn ? 4 : 0);
1832 return MI.getDesc().getSize();
1837 switch (
MI.getOpcode()) {
1848 MI.getOperand(1).getImm(), &
MI.getOperand(2));
1851 case SystemZ::BRCTH:
1855 case SystemZ::BRCTG:
1862 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1867 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1872 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1874 case SystemZ::CLGIJ:
1875 case SystemZ::CLGRJ:
1877 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1879 case SystemZ::INLINEASM_BR:
1889 unsigned &LoadOpcode,
1890 unsigned &StoreOpcode)
const {
1891 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1892 LoadOpcode = SystemZ::L;
1893 StoreOpcode = SystemZ::ST;
1894 }
else if (RC == &SystemZ::GRH32BitRegClass) {
1895 LoadOpcode = SystemZ::LFH;
1896 StoreOpcode = SystemZ::STFH;
1897 }
else if (RC == &SystemZ::GRX32BitRegClass) {
1898 LoadOpcode = SystemZ::LMux;
1899 StoreOpcode = SystemZ::STMux;
1900 }
else if (RC == &SystemZ::GR64BitRegClass ||
1901 RC == &SystemZ::ADDR64BitRegClass) {
1902 LoadOpcode = SystemZ::LG;
1903 StoreOpcode = SystemZ::STG;
1904 }
else if (RC == &SystemZ::GR128BitRegClass ||
1905 RC == &SystemZ::ADDR128BitRegClass) {
1906 LoadOpcode = SystemZ::L128;
1907 StoreOpcode = SystemZ::ST128;
1908 }
else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
1909 LoadOpcode = SystemZ::LE16;
1910 StoreOpcode = SystemZ::STE16;
1911 }
else if (RC == &SystemZ::FP32BitRegClass) {
1912 LoadOpcode = SystemZ::LE;
1913 StoreOpcode = SystemZ::STE;
1914 }
else if (RC == &SystemZ::FP64BitRegClass) {
1915 LoadOpcode = SystemZ::LD;
1916 StoreOpcode = SystemZ::STD;
1917 }
else if (RC == &SystemZ::FP128BitRegClass) {
1918 LoadOpcode = SystemZ::LX;
1919 StoreOpcode = SystemZ::STX;
1920 }
else if (RC == &SystemZ::FP16BitRegClass ||
1921 RC == &SystemZ::VR16BitRegClass) {
1922 LoadOpcode = SystemZ::VL16;
1923 StoreOpcode = SystemZ::VST16;
1924 }
else if (RC == &SystemZ::VR32BitRegClass) {
1925 LoadOpcode = SystemZ::VL32;
1926 StoreOpcode = SystemZ::VST32;
1927 }
else if (RC == &SystemZ::VR64BitRegClass) {
1928 LoadOpcode = SystemZ::VL64;
1929 StoreOpcode = SystemZ::VST64;
1930 }
else if (RC == &SystemZ::VF128BitRegClass ||
1931 RC == &SystemZ::VR128BitRegClass) {
1932 LoadOpcode = SystemZ::VL;
1933 StoreOpcode = SystemZ::VST;
1943 if (isUInt<12>(
Offset) && isUInt<12>(Offset2)) {
1945 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1946 if (Disp12Opcode >= 0)
1947 return Disp12Opcode;
1953 if (isInt<20>(
Offset) && isInt<20>(Offset2)) {
1955 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1956 if (Disp20Opcode >= 0)
1957 return Disp20Opcode;
1964 if (
MI &&
MI->getOperand(0).isReg()) {
1969 return SystemZ::LEY;
1970 case SystemZ::VST32:
1971 return SystemZ::STEY;
1973 return SystemZ::LDY;
1974 case SystemZ::VST64:
1975 return SystemZ::STDY;
1987 return SystemZ::getDisp12Opcode(Opcode) >= 0;
1988 return SystemZ::getDisp20Opcode(Opcode) >= 0;
1993 case SystemZ::L:
return SystemZ::LT;
1994 case SystemZ::LY:
return SystemZ::LT;
1995 case SystemZ::LG:
return SystemZ::LTG;
1996 case SystemZ::LGF:
return SystemZ::LTGF;
1997 case SystemZ::LR:
return SystemZ::LTR;
1998 case SystemZ::LGFR:
return SystemZ::LTGFR;
1999 case SystemZ::LGR:
return SystemZ::LTGR;
2000 case SystemZ::LCDFR:
return SystemZ::LCDBR;
2001 case SystemZ::LPDFR:
return SystemZ::LPDBR;
2002 case SystemZ::LNDFR:
return SystemZ::LNDBR;
2003 case SystemZ::LCDFR_32:
return SystemZ::LCEBR;
2004 case SystemZ::LPDFR_32:
return SystemZ::LPEBR;
2005 case SystemZ::LNDFR_32:
return SystemZ::LNEBR;
2010 case SystemZ::RISBGN:
return SystemZ::RISBG;
2016 unsigned &Start,
unsigned &
End)
const {
2026 Start = 63 - (LSB +
Length - 1);
2034 assert(LSB > 0 &&
"Bottom bit must be set");
2035 assert(LSB +
Length < BitSize &&
"Top bit must be set");
2036 Start = 63 - (LSB - 1);
2050 if (!(
MI && isInt<8>(
MI->getOperand(1).getImm())))
2054 case SystemZ::CLGFI:
2055 if (!(
MI && isUInt<8>(
MI->getOperand(1).getImm())))
2060 if (!STI.hasMiscellaneousExtensions())
2062 if (!(
MI &&
MI->getOperand(3).getReg() == 0))
2070 return SystemZ::CRJ;
2072 return SystemZ::CGRJ;
2074 return SystemZ::CIJ;
2076 return SystemZ::CGIJ;
2078 return SystemZ::CLRJ;
2080 return SystemZ::CLGRJ;
2082 return SystemZ::CLIJ;
2083 case SystemZ::CLGFI:
2084 return SystemZ::CLGIJ;
2091 return SystemZ::CRBReturn;
2093 return SystemZ::CGRBReturn;
2095 return SystemZ::CIBReturn;
2097 return SystemZ::CGIBReturn;
2099 return SystemZ::CLRBReturn;
2101 return SystemZ::CLGRBReturn;
2103 return SystemZ::CLIBReturn;
2104 case SystemZ::CLGFI:
2105 return SystemZ::CLGIBReturn;
2112 return SystemZ::CRBCall;
2114 return SystemZ::CGRBCall;
2116 return SystemZ::CIBCall;
2118 return SystemZ::CGIBCall;
2120 return SystemZ::CLRBCall;
2122 return SystemZ::CLGRBCall;
2124 return SystemZ::CLIBCall;
2125 case SystemZ::CLGFI:
2126 return SystemZ::CLGIBCall;
2133 return SystemZ::CRT;
2135 return SystemZ::CGRT;
2137 return SystemZ::CIT;
2139 return SystemZ::CGIT;
2141 return SystemZ::CLRT;
2143 return SystemZ::CLGRT;
2145 return SystemZ::CLFIT;
2146 case SystemZ::CLGFI:
2147 return SystemZ::CLGIT;
2149 return SystemZ::CLT;
2151 return SystemZ::CLGT;
2162 MBBI->getOperand(1).isReg() && !
MBBI->mayLoad() &&
2163 "Not a compare reg/reg.");
2169 if (
MI.readsRegister(SystemZ::CC,
nullptr)) {
2170 unsigned Flags =
MI.getDesc().TSFlags;
2176 if (
MI.definesRegister(SystemZ::CC,
nullptr)) {
2183 LiveRegs.addLiveOuts(*
MBB);
2184 if (!LiveRegs.available(SystemZ::CC))
2190 unsigned Flags = CCUsers[
Idx]->getDesc().TSFlags;
2192 0 : CCUsers[
Idx]->getNumExplicitOperands() - 2);
2195 CCMaskMO.
setImm(NewCCMask);
2233 if (!STI.hasLoadAndTrap())
2238 return SystemZ::LAT;
2240 return SystemZ::LGAT;
2242 return SystemZ::LFHAT;
2244 return SystemZ::LLGFAT;
2246 return SystemZ::LLGTAT;
2255 unsigned Opcode = 0;
2256 if (isInt<16>(
Value))
2257 Opcode = SystemZ::LGHI;
2259 Opcode = SystemZ::LLILL;
2261 Opcode = SystemZ::LLILH;
2264 else if (isInt<32>(
Value))
2265 Opcode = SystemZ::LGFI;
2272 assert (
MRI.isSSA() &&
"Huge values only handled before reg-alloc .");
2273 Register Reg0 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
2274 Register Reg1 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
2285 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
2296 ErrInfo =
"Addressing mode operands corrupt!";
2319 bool SameVal = (VALa && VALb && (VALa == VALb));
2323 if (PSVa && PSVb && (PSVa == PSVb))
2329 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2330 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2331 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2333 LowOffset + (int)LowWidth.
getValue() <= HighOffset)
2342 int64_t &ImmVal)
const {
2344 if (
MI.getOpcode() == SystemZ::VGBM && Reg ==
MI.getOperand(0).getReg()) {
2345 ImmVal =
MI.getOperand(1).getImm();
2353std::optional<DestSourcePair>
2359 return std::nullopt;
unsigned const MachineRegisterInfo * MRI
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
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Register const TargetRegisterInfo * TRI
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),...
size_t size() const
size - Get the array size.
This class represents an Operation in the Expression.
SlotIndexes * getSlotIndexes() const
VNInfo::Allocator & getVNInfoAllocator()
LiveRange & getRegUnit(unsigned 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
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
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...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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 '...
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
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.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Register getReg(unsigned Idx) const
Get the register for the operand index.
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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
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.
A SystemZ-specific class detailing special use registers particular for calling conventions.
virtual int getStackPointerBias()=0
virtual int getCallFrameSize()=0
unsigned getLoadAndTrap(unsigned Opcode) const
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
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) 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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
SystemZInstrInfo(SystemZSubtarget &STI)
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 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
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
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
bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
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
SystemZCallingConventionRegisters * getSpecialRegisters() const
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.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
static unsigned getAccessSize(unsigned int Flags)
unsigned getFirstReg(unsigned Reg)
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
int getTargetMemOpcode(uint16_t Opcode)
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)
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
bool isHighReg(unsigned int Reg)
const unsigned CCMASK_CMP_UO
Reg
All possible values of the reg field in the ModR/M byte.
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.
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)
unsigned getUndefRegState(bool B)
unsigned getKillRegState(bool B)