47#define GET_INSTRINFO_CTOR_DTOR
48#define GET_INSTRMAP_INFO
49#include "SystemZGenInstrInfo.inc"
51#define DEBUG_TYPE "systemz-II"
55 return Count == 0 ? 0 : (
uint64_t(1) << (Count - 1) << 1) - 1;
59void SystemZInstrInfo::anchor() {}
63 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister()),
69 unsigned NewOpcode)
const {
85 HighRegOp.
setReg(RI.getSubReg(HighRegOp.
getReg(), SystemZ::subreg_h64));
86 LowRegOp.
setReg(RI.getSubReg(LowRegOp.
getReg(), SystemZ::subreg_l64));
97 assert(HighOpcode && LowOpcode &&
"Both offsets should be in range");
102 if (
MI->mayStore()) {
114 auto overlapsAddressReg = [&](
Register Reg) ->
bool {
115 return RI.regsOverlap(Reg,
MI->getOperand(1).getReg()) ||
116 RI.regsOverlap(Reg,
MI->getOperand(3).getReg());
118 if (overlapsAddressReg(HighRegOp.
getReg())) {
120 "Both loads clobber address!");
144 assert(NewOpcode &&
"No support for huge argument lists yet");
145 MI->setDesc(
get(NewOpcode));
155void SystemZInstrInfo::expandRIPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
157 bool ConvertHigh)
const {
160 MI.setDesc(
get(IsHigh ? HighOpcode : LowOpcode));
161 if (IsHigh && ConvertHigh)
162 MI.getOperand(1).setImm(
uint32_t(
MI.getOperand(1).getImm()));
169void SystemZInstrInfo::expandRIEPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
171 unsigned HighOpcode)
const {
176 if (!DestIsHigh && !SrcIsHigh)
177 MI.setDesc(
get(LowOpcodeK));
179 if (DestReg != SrcReg) {
180 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(), DestReg, SrcReg,
181 SystemZ::LR, 32,
MI.getOperand(1).isKill(),
182 MI.getOperand(1).isUndef());
183 MI.getOperand(1).setReg(DestReg);
185 MI.setDesc(
get(DestIsHigh ? HighOpcode : LowOpcode));
186 MI.tieOperands(0, 1);
193void SystemZInstrInfo::expandRXYPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
194 unsigned HighOpcode)
const {
198 MI.getOperand(2).getImm());
199 MI.setDesc(
get(Opcode));
205void SystemZInstrInfo::expandLOCPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
206 unsigned HighOpcode)
const {
209 MI.setDesc(
get(Opcode));
215void SystemZInstrInfo::expandZExtPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
216 unsigned Size)
const {
218 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(),
219 MI.getOperand(0).getReg(),
MI.getOperand(1).getReg(), LowOpcode,
220 Size,
MI.getOperand(1).isKill(),
MI.getOperand(1).isUndef());
226 MI.eraseFromParent();
229void SystemZInstrInfo::expandLoadStackGuard(
MachineInstr *
MI)
const {
232 const Register Reg64 =
MI->getOperand(0).getReg();
233 const Register Reg32 = RI.getSubReg(Reg64, SystemZ::subreg_l32);
254 MI->setDesc(
get(SystemZ::LG));
267 unsigned SrcReg,
unsigned LowLowOpcode,
268 unsigned Size,
bool KillSrc,
269 bool UndefSrc)
const {
273 if (DestIsHigh && SrcIsHigh)
274 Opcode = SystemZ::RISBHH;
275 else if (DestIsHigh && !SrcIsHigh)
276 Opcode = SystemZ::RISBHL;
277 else if (!DestIsHigh && SrcIsHigh)
278 Opcode = SystemZ::RISBLH;
283 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
293 unsigned OpIdx2)
const {
296 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
300 switch (
MI.getOpcode()) {
301 case SystemZ::SELRMux:
302 case SystemZ::SELFHR:
305 case SystemZ::LOCRMux:
306 case SystemZ::LOCFHR:
308 case SystemZ::LOCGR: {
309 auto &WorkingMI = cloneIfNew(
MI);
311 unsigned CCValid = WorkingMI.getOperand(3).getImm();
312 unsigned CCMask = WorkingMI.getOperand(4).getImm();
313 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
330 if ((MCID.
TSFlags & Flag) &&
MI.getOperand(1).isFI() &&
331 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).getReg() == 0) {
332 FrameIndex =
MI.getOperand(1).getIndex();
333 return MI.getOperand(0).getReg();
339 int &FrameIndex)
const {
344 int &FrameIndex)
const {
350 int &SrcFrameIndex)
const {
353 if (
MI.getOpcode() != SystemZ::MVC || !
MI.getOperand(0).isFI() ||
354 MI.getOperand(1).getImm() != 0 || !
MI.getOperand(3).isFI() ||
355 MI.getOperand(4).getImm() != 0)
359 int64_t
Length =
MI.getOperand(2).getImm();
360 unsigned FI1 =
MI.getOperand(0).getIndex();
361 unsigned FI2 =
MI.getOperand(3).getIndex();
366 DestFrameIndex = FI1;
375 bool AllowModify)
const {
383 if (
I->isDebugInstr())
388 if (!isUnpredicatedTerminator(*
I))
398 if (!Branch.hasMBBTarget())
408 TBB = Branch.getMBBTarget();
421 I->eraseFromParent();
427 TBB = Branch.getMBBTarget();
435 TBB = Branch.getMBBTarget();
442 assert(
Cond.size() == 2 &&
TBB &&
"Should have seen a conditional branch");
446 if (
TBB != Branch.getMBBTarget())
450 unsigned OldCCValid =
Cond[0].getImm();
451 unsigned OldCCMask =
Cond[1].getImm();
452 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
463 int *BytesRemoved)
const {
464 assert(!BytesRemoved &&
"code size not handled");
472 if (
I->isDebugInstr())
479 I->eraseFromParent();
489 assert(
Cond.size() == 2 &&
"Invalid condition");
499 int *BytesAdded)
const {
505 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
507 "SystemZ branch conditions have one component!");
508 assert(!BytesAdded &&
"code size not handled");
512 assert(!FBB &&
"Unconditional branch with multiple successors!");
519 unsigned CCValid =
Cond[0].getImm();
520 unsigned CCMask =
Cond[1].getImm();
535 int64_t &
Value)
const {
536 assert(
MI.isCompare() &&
"Caller should have checked for a comparison");
538 if (
MI.getNumExplicitOperands() == 2 &&
MI.getOperand(0).isReg() &&
539 MI.getOperand(1).isImm()) {
540 SrcReg =
MI.getOperand(0).getReg();
542 Value =
MI.getOperand(1).getImm();
555 int &FalseCycles)
const {
557 if (!STI.hasLoadStoreOnCond())
559 if (Pred.
size() != 2)
565 RI.getCommonSubClass(
MRI.getRegClass(TrueReg),
MRI.getRegClass(FalseReg));
570 if ((STI.hasLoadStoreOnCond2() &&
571 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
572 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
573 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
593 assert(Pred.
size() == 2 &&
"Invalid condition");
594 unsigned CCValid = Pred[0].getImm();
595 unsigned CCMask = Pred[1].getImm();
598 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
599 if (STI.hasMiscellaneousExtensions3())
600 Opc = SystemZ::SELRMux;
601 else if (STI.hasLoadStoreOnCond2())
602 Opc = SystemZ::LOCRMux;
605 MRI.constrainRegClass(DstReg, &SystemZ::GR32BitRegClass);
606 Register TReg =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
607 Register FReg =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
613 }
else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
614 if (STI.hasMiscellaneousExtensions3())
615 Opc = SystemZ::SELGR;
617 Opc = SystemZ::LOCGR;
631 DefMI =
MRI->getVRegDef(FoldAsLoadDefReg);
633 bool SawStore =
false;
635 !
MRI->hasOneNonDBGUse(FoldAsLoadDefReg))
639 MI.findRegisterUseOperandIdx(FoldAsLoadDefReg,
nullptr);
640 assert(UseOpIdx != -1 &&
"Expected FoldAsLoadDefReg to be used by MI.");
645 FoldAsLoadDefReg = 0;
655 unsigned DefOpc =
DefMI.getOpcode();
657 if (DefOpc == SystemZ::VGBM) {
658 int64_t ImmVal =
DefMI.getOperand(1).getImm();
673 MRI->getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
674 MRI->hasOneNonDBGUse(Reg)) {
678 Register TmpReg =
MRI->createVirtualRegister(&SystemZ::GR64BitRegClass);
683 UseMI.setDesc(
get(SystemZ::REG_SEQUENCE));
684 UseMI.getOperand(1).setReg(TmpReg);
686 .
addImm(SystemZ::subreg_h64)
688 .
addImm(SystemZ::subreg_l64);
690 if (
MRI->use_nodbg_empty(Reg))
691 DefMI.eraseFromParent();
698 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
699 DefOpc != SystemZ::LGHI)
703 int32_t ImmVal = (int32_t)
DefMI.getOperand(1).getImm();
705 unsigned UseOpc =
UseMI.getOpcode();
711 case SystemZ::SELRMux:
714 case SystemZ::LOCRMux:
715 if (!STI.hasLoadStoreOnCond2())
717 NewUseOpc = SystemZ::LOCHIMux;
721 UseIdx = 2, CommuteIdx = 1;
729 if (!STI.hasLoadStoreOnCond2())
731 NewUseOpc = SystemZ::LOCGHI;
735 UseIdx = 2, CommuteIdx = 1;
743 if (CommuteIdx != -1)
744 if (!commuteInstruction(
UseMI,
false, CommuteIdx, UseIdx))
747 bool DeleteDef =
MRI->hasOneNonDBGUse(Reg);
750 UseMI.tieOperands(0, 1);
751 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
753 DefMI.eraseFromParent();
759 unsigned Opcode =
MI.getOpcode();
760 if (Opcode == SystemZ::Return ||
761 Opcode == SystemZ::Return_XPLINK ||
762 Opcode == SystemZ::Trap ||
763 Opcode == SystemZ::CallJG ||
764 Opcode == SystemZ::CallBR)
771 unsigned NumCycles,
unsigned ExtraPredCycles,
785 return NumCycles == 1;
790 unsigned NumCyclesT,
unsigned ExtraPredCyclesT,
792 unsigned NumCyclesF,
unsigned ExtraPredCyclesF,
802 return NumCycles == 1;
807 assert(Pred.
size() == 2 &&
"Invalid condition");
808 unsigned CCValid = Pred[0].getImm();
809 unsigned CCMask = Pred[1].getImm();
810 assert(CCMask > 0 && CCMask < 15 &&
"Invalid predicate");
811 unsigned Opcode =
MI.getOpcode();
812 if (Opcode == SystemZ::Trap) {
813 MI.setDesc(
get(SystemZ::CondTrap));
819 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
820 MI.setDesc(
get(Opcode == SystemZ::Return ? SystemZ::CondReturn
821 : SystemZ::CondReturn_XPLINK));
828 if (Opcode == SystemZ::CallJG) {
830 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
833 MI.setDesc(
get(SystemZ::CallBRCL));
842 if (Opcode == SystemZ::CallBR) {
844 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
847 MI.setDesc(
get(SystemZ::CallBCR));
865 if (SystemZ::GR128BitRegClass.
contains(DestReg, SrcReg)) {
867 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
871 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
877 if (SystemZ::GRX32BitRegClass.
contains(DestReg, SrcReg)) {
878 emitGRX32Move(
MBB,
MBBI,
DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
884 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
885 SystemZ::FP128BitRegClass.
contains(SrcReg)) {
887 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
888 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
890 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
891 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
898 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
899 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
901 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
902 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
904 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
905 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
907 if (DestRegHi != SrcReg)
914 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
915 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
916 MCRegister DestRegHi = RI.getSubReg(DestReg, SystemZ::subreg_h64);
917 MCRegister DestRegLo = RI.getSubReg(DestReg, SystemZ::subreg_l64);
918 MCRegister SrcRegHi = RI.getSubReg(SrcReg, SystemZ::subreg_h64);
919 MCRegister SrcRegLo = RI.getSubReg(SrcReg, SystemZ::subreg_l64);
931 if (DestReg == SystemZ::CC) {
933 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
940 if (SystemZ::GR128BitRegClass.
contains(DestReg) &&
941 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
942 MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64);
943 MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64);
947 .
addReg(SystemZ::NoRegister)
952 .
addReg(SystemZ::NoRegister)
957 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
958 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
960 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64))
961 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64));
967 if (SystemZ::GR64BitRegClass.
contains(DestReg, SrcReg))
968 Opcode = SystemZ::LGR;
969 else if (SystemZ::FP32BitRegClass.
contains(DestReg, SrcReg))
971 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
972 else if (SystemZ::FP64BitRegClass.
contains(DestReg, SrcReg))
973 Opcode = SystemZ::LDR;
974 else if (SystemZ::FP128BitRegClass.
contains(DestReg, SrcReg))
975 Opcode = SystemZ::LXR;
976 else if (SystemZ::VR32BitRegClass.
contains(DestReg, SrcReg))
977 Opcode = SystemZ::VLR32;
978 else if (SystemZ::VR64BitRegClass.
contains(DestReg, SrcReg))
979 Opcode = SystemZ::VLR64;
980 else if (SystemZ::VR128BitRegClass.
contains(DestReg, SrcReg))
981 Opcode = SystemZ::VLR;
982 else if (SystemZ::AR32BitRegClass.
contains(DestReg, SrcReg))
983 Opcode = SystemZ::CPYA;
999 unsigned LoadOpcode, StoreOpcode;
1016 unsigned LoadOpcode, StoreOpcode;
1026 return ((MCID.
TSFlags & Flag) &&
1027 isUInt<12>(
MI->getOperand(2).getImm()) &&
1028 MI->getOperand(3).getReg() == 0);
1034 LogicOp() =
default;
1035 LogicOp(
unsigned regSize,
unsigned immLSB,
unsigned immSize)
1036 :
RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1038 explicit operator bool()
const {
return RegSize; }
1041 unsigned ImmLSB = 0;
1042 unsigned ImmSize = 0;
1049 case SystemZ::NILMux:
return LogicOp(32, 0, 16);
1050 case SystemZ::NIHMux:
return LogicOp(32, 16, 16);
1051 case SystemZ::NILL64:
return LogicOp(64, 0, 16);
1052 case SystemZ::NILH64:
return LogicOp(64, 16, 16);
1053 case SystemZ::NIHL64:
return LogicOp(64, 32, 16);
1054 case SystemZ::NIHH64:
return LogicOp(64, 48, 16);
1055 case SystemZ::NIFMux:
return LogicOp(32, 0, 32);
1056 case SystemZ::NILF64:
return LogicOp(64, 0, 32);
1057 case SystemZ::NIHF64:
return LogicOp(64, 32, 32);
1058 default:
return LogicOp();
1066 if (CCDef !=
nullptr)
1088 unsigned Start,
End;
1091 if (
And.RegSize == 64) {
1092 NewOpcode = SystemZ::RISBG;
1094 if (STI.hasMiscellaneousExtensions())
1095 NewOpcode = SystemZ::RISBGN;
1097 NewOpcode = SystemZ::RISBMux;
1113 unsigned NumOps =
MI.getNumOperands();
1114 for (
unsigned I = 1;
I < NumOps; ++
I) {
1116 if (
Op.isReg() &&
Op.isKill())
1121 LIS->ReplaceMachineInstrInMaps(
MI, *MIB);
1130 bool Invert)
const {
1136 Opc = *InverseOpcode;
1143 case SystemZ::WFADB:
1144 case SystemZ::WFASB:
1145 case SystemZ::WFAXB:
1146 case SystemZ::VFADB:
1147 case SystemZ::VFASB:
1148 case SystemZ::WFMDB:
1149 case SystemZ::WFMSB:
1150 case SystemZ::WFMXB:
1151 case SystemZ::VFMDB:
1152 case SystemZ::VFMSB:
1160std::optional<unsigned>
1164 case SystemZ::WFADB:
1165 return SystemZ::WFSDB;
1166 case SystemZ::WFASB:
1167 return SystemZ::WFSSB;
1168 case SystemZ::WFAXB:
1169 return SystemZ::WFSXB;
1170 case SystemZ::VFADB:
1171 return SystemZ::VFSDB;
1172 case SystemZ::VFASB:
1173 return SystemZ::VFSSB;
1175 case SystemZ::WFSDB:
1176 return SystemZ::WFADB;
1177 case SystemZ::WFSSB:
1178 return SystemZ::WFASB;
1179 case SystemZ::WFSXB:
1180 return SystemZ::WFAXB;
1181 case SystemZ::VFSDB:
1182 return SystemZ::VFADB;
1183 case SystemZ::VFSSB:
1184 return SystemZ::VFASB;
1186 return std::nullopt;
1198 unsigned Opcode =
MI.getOpcode();
1203 bool CCLiveAtMI =
true;
1205 MISlot =
LIS->getSlotIndexes()->getInstructionIndex(
MI).getRegSlot();
1208 CCLiveRange = &
LIS->getRegUnit(*CCUnits.begin());
1209 CCLiveAtMI = CCLiveRange->
liveAt(MISlot);
1212 if (Ops.
size() == 2 && Ops[0] == 0 && Ops[1] == 1) {
1213 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1214 isInt<8>(
MI.getOperand(2).getImm()) && !
MI.getOperand(3).getReg()) {
1217 MI.getDebugLoc(),
get(SystemZ::AGSI))
1220 .
addImm(
MI.getOperand(2).getImm());
1230 if (Ops.
size() != 1)
1233 unsigned OpNum = Ops[0];
1237 "Invalid size combination");
1239 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1240 isInt<8>(
MI.getOperand(2).getImm())) {
1242 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1244 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1247 .
addImm(
MI.getOperand(2).getImm());
1253 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1254 isInt<8>((int32_t)
MI.getOperand(2).getImm())) ||
1255 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1256 isInt<8>((int64_t)
MI.getOperand(2).getImm()))) {
1258 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1260 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1263 .
addImm((int8_t)
MI.getOperand(2).getImm());
1268 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1269 isInt<8>((int32_t)-
MI.getOperand(2).getImm())) ||
1270 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1271 isInt<8>((int64_t)-
MI.getOperand(2).getImm()))) {
1273 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1275 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1278 .
addImm((int8_t)-
MI.getOperand(2).getImm());
1283 unsigned MemImmOpc = 0;
1285 case SystemZ::LHIMux:
1286 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI;
break;
1287 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI;
break;
1288 case SystemZ::CHIMux:
1289 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI;
break;
1290 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI;
break;
1291 case SystemZ::CLFIMux:
1293 if (isUInt<16>(
MI.getOperand(1).getImm()))
1294 MemImmOpc = SystemZ::CLFHSI;
1296 case SystemZ::CLGFI:
1297 if (isUInt<16>(
MI.getOperand(1).getImm()))
1298 MemImmOpc = SystemZ::CLGHSI;
1303 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1307 .
addImm(
MI.getOperand(1).getImm());
1309 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1310 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1311 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1315 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1316 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1318 .
add(
MI.getOperand(1))
1326 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1327 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1329 .
add(
MI.getOperand(0))
1349 if (OpNum == 0 &&
MI.hasOneMemOperand()) {
1354 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1359 .
add(
MI.getOperand(1))
1365 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1367 .
add(
MI.getOperand(1))
1380 unsigned NumOps =
MI.getNumExplicitOperands();
1381 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1382 if (MemOpcode == -1 ||
1383 (CCLiveAtMI && !
MI.definesRegister(SystemZ::CC,
nullptr) &&
1384 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1395 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1401 !(SystemZ::FP32BitRegClass.
contains(PhysReg) ||
1402 SystemZ::FP64BitRegClass.
contains(PhysReg) ||
1403 SystemZ::VF128BitRegClass.
contains(PhysReg)))
1408 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1409 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1413 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1418 bool NeedsCommute =
false;
1419 if ((
MI.getOpcode() == SystemZ::CR ||
MI.getOpcode() == SystemZ::CGR ||
1420 MI.getOpcode() == SystemZ::CLR ||
MI.getOpcode() == SystemZ::CLGR ||
1421 MI.getOpcode() == SystemZ::WFCDB ||
MI.getOpcode() == SystemZ::WFCSB ||
1422 MI.getOpcode() == SystemZ::WFKDB ||
MI.getOpcode() == SystemZ::WFKSB) &&
1424 NeedsCommute =
true;
1426 bool CCOperands =
false;
1427 if (
MI.getOpcode() == SystemZ::LOCRMux ||
MI.getOpcode() == SystemZ::LOCGR ||
1428 MI.getOpcode() == SystemZ::SELRMux ||
MI.getOpcode() == SystemZ::SELGR) {
1429 assert(
MI.getNumOperands() == 6 && NumOps == 5 &&
1430 "LOCR/SELR instruction operands corrupt?");
1445 Register SrcReg = (OpNum == 2 ?
MI.getOperand(1).getReg()
1446 : ((OpNum == 1 &&
MI.isCommutable())
1447 ?
MI.getOperand(2).getReg()
1449 if (DstPhys && !SystemZ::GRH32BitRegClass.
contains(DstPhys) && SrcReg &&
1451 NeedsCommute = (OpNum == 1);
1457 if ((OpNum == NumOps - 1) || NeedsCommute || FusedFPOp) {
1460 assert(AccessBytes != 0 &&
"Size of access should be known");
1461 assert(AccessBytes <=
Size &&
"Access outside the frame index");
1464 MI.getDebugLoc(),
get(MemOpcode));
1465 if (
MI.isCompare()) {
1466 assert(NumOps == 2 &&
"Expected 2 register operands for a compare.");
1467 MIB.
add(
MI.getOperand(NeedsCommute ? 1 : 0));
1469 else if (FusedFPOp) {
1470 MIB.
add(
MI.getOperand(0));
1471 MIB.
add(
MI.getOperand(3));
1472 MIB.
add(
MI.getOperand(OpNum == 1 ? 2 : 1));
1475 MIB.
add(
MI.getOperand(0));
1477 MIB.
add(
MI.getOperand(2));
1479 for (
unsigned I = 1;
I < OpNum; ++
I)
1480 MIB.
add(
MI.getOperand(
I));
1486 unsigned CCValid =
MI.getOperand(NumOps).getImm();
1487 unsigned CCMask =
MI.getOperand(NumOps + 1).getImm();
1489 MIB.
addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1492 (!
MI.definesRegister(SystemZ::CC,
nullptr) ||
1493 MI.registerDefIsDead(SystemZ::CC,
nullptr))) {
1501 if (MO.isReg() && MO.getReg().isVirtual()) {
1503 if (
MRI.getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1504 MRI.setRegClass(Reg, &SystemZ::FP32BitRegClass);
1505 else if (
MRI.getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1506 MRI.setRegClass(Reg, &SystemZ::FP64BitRegClass);
1507 else if (
MRI.getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1508 MRI.setRegClass(Reg, &SystemZ::VF128BitRegClass);
1533 unsigned LoadOpc = 0;
1534 unsigned RegMemOpcode = 0;
1536 RegMemOpcode =
MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1537 :
MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1538 :
MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1541 LoadOpc = SystemZ::VL64;
1542 FPRC = &SystemZ::FP64BitRegClass;
1544 RegMemOpcode =
MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1545 :
MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1546 :
MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1549 LoadOpc = SystemZ::VL32;
1550 FPRC = &SystemZ::FP32BitRegClass;
1553 if (!RegMemOpcode || LoadMI.
getOpcode() != LoadOpc)
1557 if (
get(RegMemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)) {
1559 assert(LoadMI != InsertPt &&
"Assuming InsertPt not to be first in MBB.");
1562 if (MII->definesRegister(SystemZ::CC,
nullptr)) {
1563 if (!MII->registerDefIsDead(SystemZ::CC,
nullptr))
1576 if (Ops.
size() != 1 || FoldAsLoadDefReg !=
MI.getOperand(Ops[0]).getReg())
1582 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1583 FoldAsLoadDefReg !=
RHS.getReg())
1590 BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(RegMemOpcode), DstReg)
1596 MRI->setRegClass(DstReg, FPRC);
1604 switch (
MI.getOpcode()) {
1606 splitMove(
MI, SystemZ::LG);
1609 case SystemZ::ST128:
1610 splitMove(
MI, SystemZ::STG);
1614 splitMove(
MI, SystemZ::LD);
1618 splitMove(
MI, SystemZ::STD);
1621 case SystemZ::LBMux:
1622 expandRXYPseudo(
MI, SystemZ::LB, SystemZ::LBH);
1625 case SystemZ::LHMux:
1626 expandRXYPseudo(
MI, SystemZ::LH, SystemZ::LHH);
1629 case SystemZ::LLCRMux:
1630 expandZExtPseudo(
MI, SystemZ::LLCR, 8);
1633 case SystemZ::LLHRMux:
1634 expandZExtPseudo(
MI, SystemZ::LLHR, 16);
1637 case SystemZ::LLCMux:
1638 expandRXYPseudo(
MI, SystemZ::LLC, SystemZ::LLCH);
1641 case SystemZ::LLHMux:
1642 expandRXYPseudo(
MI, SystemZ::LLH, SystemZ::LLHH);
1646 expandRXYPseudo(
MI, SystemZ::L, SystemZ::LFH);
1649 case SystemZ::LOCMux:
1650 expandLOCPseudo(
MI, SystemZ::LOC, SystemZ::LOCFH);
1653 case SystemZ::LOCHIMux:
1654 expandLOCPseudo(
MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1657 case SystemZ::STCMux:
1658 expandRXYPseudo(
MI, SystemZ::STC, SystemZ::STCH);
1661 case SystemZ::STHMux:
1662 expandRXYPseudo(
MI, SystemZ::STH, SystemZ::STHH);
1665 case SystemZ::STMux:
1666 expandRXYPseudo(
MI, SystemZ::ST, SystemZ::STFH);
1669 case SystemZ::STOCMux:
1670 expandLOCPseudo(
MI, SystemZ::STOC, SystemZ::STOCFH);
1673 case SystemZ::LHIMux:
1674 expandRIPseudo(
MI, SystemZ::LHI, SystemZ::IIHF,
true);
1677 case SystemZ::IIFMux:
1678 expandRIPseudo(
MI, SystemZ::IILF, SystemZ::IIHF,
false);
1681 case SystemZ::IILMux:
1682 expandRIPseudo(
MI, SystemZ::IILL, SystemZ::IIHL,
false);
1685 case SystemZ::IIHMux:
1686 expandRIPseudo(
MI, SystemZ::IILH, SystemZ::IIHH,
false);
1689 case SystemZ::NIFMux:
1690 expandRIPseudo(
MI, SystemZ::NILF, SystemZ::NIHF,
false);
1693 case SystemZ::NILMux:
1694 expandRIPseudo(
MI, SystemZ::NILL, SystemZ::NIHL,
false);
1697 case SystemZ::NIHMux:
1698 expandRIPseudo(
MI, SystemZ::NILH, SystemZ::NIHH,
false);
1701 case SystemZ::OIFMux:
1702 expandRIPseudo(
MI, SystemZ::OILF, SystemZ::OIHF,
false);
1705 case SystemZ::OILMux:
1706 expandRIPseudo(
MI, SystemZ::OILL, SystemZ::OIHL,
false);
1709 case SystemZ::OIHMux:
1710 expandRIPseudo(
MI, SystemZ::OILH, SystemZ::OIHH,
false);
1713 case SystemZ::XIFMux:
1714 expandRIPseudo(
MI, SystemZ::XILF, SystemZ::XIHF,
false);
1717 case SystemZ::TMLMux:
1718 expandRIPseudo(
MI, SystemZ::TMLL, SystemZ::TMHL,
false);
1721 case SystemZ::TMHMux:
1722 expandRIPseudo(
MI, SystemZ::TMLH, SystemZ::TMHH,
false);
1725 case SystemZ::AHIMux:
1726 expandRIPseudo(
MI, SystemZ::AHI, SystemZ::AIH,
false);
1729 case SystemZ::AHIMuxK:
1730 expandRIEPseudo(
MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1733 case SystemZ::AFIMux:
1734 expandRIPseudo(
MI, SystemZ::AFI, SystemZ::AIH,
false);
1737 case SystemZ::CHIMux:
1738 expandRIPseudo(
MI, SystemZ::CHI, SystemZ::CIH,
false);
1741 case SystemZ::CFIMux:
1742 expandRIPseudo(
MI, SystemZ::CFI, SystemZ::CIH,
false);
1745 case SystemZ::CLFIMux:
1746 expandRIPseudo(
MI, SystemZ::CLFI, SystemZ::CLIH,
false);
1750 expandRXYPseudo(
MI, SystemZ::C, SystemZ::CHF);
1753 case SystemZ::CLMux:
1754 expandRXYPseudo(
MI, SystemZ::CL, SystemZ::CLHF);
1757 case SystemZ::RISBMux: {
1760 if (SrcIsHigh == DestIsHigh)
1761 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1763 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1764 MI.getOperand(5).setImm(
MI.getOperand(5).getImm() ^ 32);
1769 case SystemZ::ADJDYNALLOC:
1770 splitAdjDynAlloc(
MI);
1773 case TargetOpcode::LOAD_STACK_GUARD:
1774 expandLoadStackGuard(&
MI);
1783 if (
MI.isInlineAsm()) {
1785 const char *AsmStr =
MI.getOperand(0).getSymbolName();
1788 else if (
MI.getOpcode() == SystemZ::PATCHPOINT)
1790 else if (
MI.getOpcode() == SystemZ::STACKMAP)
1791 return MI.getOperand(1).getImm();
1792 else if (
MI.getOpcode() == SystemZ::FENTRY_CALL)
1795 return MI.getDesc().getSize();
1800 switch (
MI.getOpcode()) {
1811 MI.getOperand(1).getImm(), &
MI.getOperand(2));
1814 case SystemZ::BRCTH:
1818 case SystemZ::BRCTG:
1825 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1830 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1835 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1837 case SystemZ::CLGIJ:
1838 case SystemZ::CLGRJ:
1840 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1842 case SystemZ::INLINEASM_BR:
1852 unsigned &LoadOpcode,
1853 unsigned &StoreOpcode)
const {
1854 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1855 LoadOpcode = SystemZ::L;
1856 StoreOpcode = SystemZ::ST;
1857 }
else if (RC == &SystemZ::GRH32BitRegClass) {
1858 LoadOpcode = SystemZ::LFH;
1859 StoreOpcode = SystemZ::STFH;
1860 }
else if (RC == &SystemZ::GRX32BitRegClass) {
1861 LoadOpcode = SystemZ::LMux;
1862 StoreOpcode = SystemZ::STMux;
1863 }
else if (RC == &SystemZ::GR64BitRegClass ||
1864 RC == &SystemZ::ADDR64BitRegClass) {
1865 LoadOpcode = SystemZ::LG;
1866 StoreOpcode = SystemZ::STG;
1867 }
else if (RC == &SystemZ::GR128BitRegClass ||
1868 RC == &SystemZ::ADDR128BitRegClass) {
1869 LoadOpcode = SystemZ::L128;
1870 StoreOpcode = SystemZ::ST128;
1871 }
else if (RC == &SystemZ::FP32BitRegClass) {
1872 LoadOpcode = SystemZ::LE;
1873 StoreOpcode = SystemZ::STE;
1874 }
else if (RC == &SystemZ::FP64BitRegClass) {
1875 LoadOpcode = SystemZ::LD;
1876 StoreOpcode = SystemZ::STD;
1877 }
else if (RC == &SystemZ::FP128BitRegClass) {
1878 LoadOpcode = SystemZ::LX;
1879 StoreOpcode = SystemZ::STX;
1880 }
else if (RC == &SystemZ::VR32BitRegClass) {
1881 LoadOpcode = SystemZ::VL32;
1882 StoreOpcode = SystemZ::VST32;
1883 }
else if (RC == &SystemZ::VR64BitRegClass) {
1884 LoadOpcode = SystemZ::VL64;
1885 StoreOpcode = SystemZ::VST64;
1886 }
else if (RC == &SystemZ::VF128BitRegClass ||
1887 RC == &SystemZ::VR128BitRegClass) {
1888 LoadOpcode = SystemZ::VL;
1889 StoreOpcode = SystemZ::VST;
1899 if (isUInt<12>(
Offset) && isUInt<12>(Offset2)) {
1901 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1902 if (Disp12Opcode >= 0)
1903 return Disp12Opcode;
1909 if (isInt<20>(
Offset) && isInt<20>(Offset2)) {
1911 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1912 if (Disp20Opcode >= 0)
1913 return Disp20Opcode;
1920 if (
MI &&
MI->getOperand(0).isReg()) {
1925 return SystemZ::LEY;
1926 case SystemZ::VST32:
1927 return SystemZ::STEY;
1929 return SystemZ::LDY;
1930 case SystemZ::VST64:
1931 return SystemZ::STDY;
1943 return SystemZ::getDisp12Opcode(Opcode) >= 0;
1944 return SystemZ::getDisp20Opcode(Opcode) >= 0;
1949 case SystemZ::L:
return SystemZ::LT;
1950 case SystemZ::LY:
return SystemZ::LT;
1951 case SystemZ::LG:
return SystemZ::LTG;
1952 case SystemZ::LGF:
return SystemZ::LTGF;
1953 case SystemZ::LR:
return SystemZ::LTR;
1954 case SystemZ::LGFR:
return SystemZ::LTGFR;
1955 case SystemZ::LGR:
return SystemZ::LTGR;
1956 case SystemZ::LCDFR:
return SystemZ::LCDBR;
1957 case SystemZ::LPDFR:
return SystemZ::LPDBR;
1958 case SystemZ::LNDFR:
return SystemZ::LNDBR;
1959 case SystemZ::LCDFR_32:
return SystemZ::LCEBR;
1960 case SystemZ::LPDFR_32:
return SystemZ::LPEBR;
1961 case SystemZ::LNDFR_32:
return SystemZ::LNEBR;
1966 case SystemZ::RISBGN:
return SystemZ::RISBG;
1972 unsigned &Start,
unsigned &
End)
const {
1982 Start = 63 - (LSB +
Length - 1);
1990 assert(LSB > 0 &&
"Bottom bit must be set");
1991 assert(LSB +
Length < BitSize &&
"Top bit must be set");
1992 Start = 63 - (LSB - 1);
2006 if (!(
MI && isInt<8>(
MI->getOperand(1).getImm())))
2010 case SystemZ::CLGFI:
2011 if (!(
MI && isUInt<8>(
MI->getOperand(1).getImm())))
2016 if (!STI.hasMiscellaneousExtensions())
2018 if (!(
MI &&
MI->getOperand(3).getReg() == 0))
2026 return SystemZ::CRJ;
2028 return SystemZ::CGRJ;
2030 return SystemZ::CIJ;
2032 return SystemZ::CGIJ;
2034 return SystemZ::CLRJ;
2036 return SystemZ::CLGRJ;
2038 return SystemZ::CLIJ;
2039 case SystemZ::CLGFI:
2040 return SystemZ::CLGIJ;
2047 return SystemZ::CRBReturn;
2049 return SystemZ::CGRBReturn;
2051 return SystemZ::CIBReturn;
2053 return SystemZ::CGIBReturn;
2055 return SystemZ::CLRBReturn;
2057 return SystemZ::CLGRBReturn;
2059 return SystemZ::CLIBReturn;
2060 case SystemZ::CLGFI:
2061 return SystemZ::CLGIBReturn;
2068 return SystemZ::CRBCall;
2070 return SystemZ::CGRBCall;
2072 return SystemZ::CIBCall;
2074 return SystemZ::CGIBCall;
2076 return SystemZ::CLRBCall;
2078 return SystemZ::CLGRBCall;
2080 return SystemZ::CLIBCall;
2081 case SystemZ::CLGFI:
2082 return SystemZ::CLGIBCall;
2089 return SystemZ::CRT;
2091 return SystemZ::CGRT;
2093 return SystemZ::CIT;
2095 return SystemZ::CGIT;
2097 return SystemZ::CLRT;
2099 return SystemZ::CLGRT;
2101 return SystemZ::CLFIT;
2102 case SystemZ::CLGFI:
2103 return SystemZ::CLGIT;
2105 return SystemZ::CLT;
2107 return SystemZ::CLGT;
2118 MBBI->getOperand(1).isReg() && !
MBBI->mayLoad() &&
2119 "Not a compare reg/reg.");
2125 if (
MI.readsRegister(SystemZ::CC,
nullptr)) {
2126 unsigned Flags =
MI.getDesc().TSFlags;
2132 if (
MI.definesRegister(SystemZ::CC,
nullptr)) {
2146 unsigned Flags = CCUsers[
Idx]->getDesc().TSFlags;
2148 0 : CCUsers[
Idx]->getNumExplicitOperands() - 2);
2151 CCMaskMO.
setImm(NewCCMask);
2189 if (!STI.hasLoadAndTrap())
2194 return SystemZ::LAT;
2196 return SystemZ::LGAT;
2198 return SystemZ::LFHAT;
2200 return SystemZ::LLGFAT;
2202 return SystemZ::LLGTAT;
2211 unsigned Opcode = 0;
2212 if (isInt<16>(
Value))
2213 Opcode = SystemZ::LGHI;
2215 Opcode = SystemZ::LLILL;
2217 Opcode = SystemZ::LLILH;
2220 else if (isInt<32>(
Value))
2221 Opcode = SystemZ::LGFI;
2228 assert (
MRI.isSSA() &&
"Huge values only handled before reg-alloc .");
2229 Register Reg0 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
2230 Register Reg1 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
2241 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
2252 ErrInfo =
"Addressing mode operands corrupt!";
2275 bool SameVal = (VALa && VALb && (VALa == VALb));
2279 if (PSVa && PSVb && (PSVa == PSVb))
2285 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2286 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2287 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2289 LowOffset + (int)LowWidth.
getValue() <= HighOffset)
2298 int64_t &ImmVal)
const {
2300 if (
MI.getOpcode() == SystemZ::VGBM && Reg ==
MI.getOperand(0).getReg()) {
2301 ImmVal =
MI.getOperand(1).getImm();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
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
unsigned const TargetRegisterInfo * TRI
INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME, false, false) char RISCVCoalesceVSETVLI const LiveIntervals * LIS
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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.
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
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.
bool available(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
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.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
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.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
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.
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 '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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)
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.
bool isSafeToMove(AAResults *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
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.
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.
iterator_range< mop_iterator > operands()
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...
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)
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.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
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
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
bool isPredicable(const MachineInstr &MI) const override
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const override
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) 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 * optimizeLoadInstr(MachineInstr &MI, const MachineRegisterInfo *MRI, Register &FoldAsLoadDefReg, MachineInstr *&DefMI) 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 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) 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
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) 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
getRegisterInfo - If register information is available, return it.
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.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getUndefRegState(bool B)
@ And
Bitwise or logical AND of integers.
unsigned getKillRegState(bool B)