49#define GET_INSTRINFO_CTOR_DTOR
50#define GET_INSTRMAP_INFO
51#include "SystemZGenInstrInfo.inc"
53#define DEBUG_TYPE "systemz-II"
61void SystemZInstrInfo::anchor() {}
65 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister(),
72 unsigned NewOpcode)
const {
80 MBB->insert(LowPartMI, HighPartMI);
88 HighRegOp.
setReg(RI.getSubReg(HighRegOp.
getReg(), SystemZ::subreg_h64));
89 LowRegOp.
setReg(RI.getSubReg(LowRegOp.
getReg(), SystemZ::subreg_l64));
100 assert(HighOpcode && LowOpcode &&
"Both offsets should be in range");
105 if (
MI->mayStore()) {
117 auto overlapsAddressReg = [&](
Register Reg) ->
bool {
118 return RI.regsOverlap(
Reg,
MI->getOperand(1).getReg()) ||
119 RI.regsOverlap(
Reg,
MI->getOperand(3).getReg());
121 if (overlapsAddressReg(HighRegOp.
getReg())) {
123 "Both loads clobber address!");
139 MachineOperand &OffsetMO =
MI->getOperand(2);
140 SystemZCallingConventionRegisters *Regs = STI.getSpecialRegisters();
147 assert(NewOpcode &&
"No support for huge argument lists yet");
148 MI->setDesc(
get(NewOpcode));
158void SystemZInstrInfo::expandRIPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
160 bool ConvertHigh)
const {
163 MI.setDesc(
get(IsHigh ? HighOpcode : LowOpcode));
164 if (IsHigh && ConvertHigh)
165 MI.getOperand(1).setImm(uint32_t(
MI.getOperand(1).getImm()));
172void SystemZInstrInfo::expandRIEPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
174 unsigned HighOpcode)
const {
179 if (!DestIsHigh && !SrcIsHigh)
180 MI.setDesc(
get(LowOpcodeK));
182 if (DestReg != SrcReg) {
183 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(), DestReg, SrcReg,
184 SystemZ::LR, 32,
MI.getOperand(1).isKill(),
185 MI.getOperand(1).isUndef());
186 MI.getOperand(1).setReg(DestReg);
188 MI.setDesc(
get(DestIsHigh ? HighOpcode : LowOpcode));
189 MI.tieOperands(0, 1);
196void SystemZInstrInfo::expandRXYPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
197 unsigned HighOpcode)
const {
201 MI.getOperand(2).getImm());
202 MI.setDesc(
get(Opcode));
208void SystemZInstrInfo::expandLOCPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
209 unsigned HighOpcode)
const {
212 MI.setDesc(
get(Opcode));
218void SystemZInstrInfo::expandZExtPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
219 unsigned Size)
const {
220 MachineInstrBuilder MIB =
221 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(),
222 MI.getOperand(0).getReg(),
MI.getOperand(1).getReg(), LowOpcode,
223 Size,
MI.getOperand(1).isKill(),
MI.getOperand(1).isUndef());
229 MI.eraseFromParent();
241 unsigned SrcReg,
unsigned LowLowOpcode,
242 unsigned Size,
bool KillSrc,
243 bool UndefSrc)
const {
247 if (DestIsHigh && SrcIsHigh)
248 Opcode = SystemZ::RISBHH;
249 else if (DestIsHigh && !SrcIsHigh)
250 Opcode = SystemZ::RISBHL;
251 else if (!DestIsHigh && SrcIsHigh)
252 Opcode = SystemZ::RISBLH;
257 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
267 unsigned OpIdx2)
const {
270 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
274 switch (
MI.getOpcode()) {
275 case SystemZ::SELRMux:
276 case SystemZ::SELFHR:
279 case SystemZ::LOCRMux:
280 case SystemZ::LOCFHR:
282 case SystemZ::LOCGR: {
283 auto &WorkingMI = cloneIfNew(
MI);
285 unsigned CCValid = WorkingMI.getOperand(3).getImm();
286 unsigned CCMask = WorkingMI.getOperand(4).getImm();
287 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
304 if ((
MCID.TSFlags & Flag) &&
MI.getOperand(1).isFI() &&
305 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).getReg() == 0) {
306 FrameIndex =
MI.getOperand(1).getIndex();
307 return MI.getOperand(0).getReg();
313 int &FrameIndex)
const {
318 int &FrameIndex)
const {
323 int &FrameIndex)
const {
340 return MI.getOperand(0).getReg();
346 int &FrameIndex)
const {
363 return MI.getOperand(0).getReg();
370 int &SrcFrameIndex)
const {
373 if (
MI.getOpcode() != SystemZ::MVC || !
MI.getOperand(0).isFI() ||
374 MI.getOperand(1).getImm() != 0 || !
MI.getOperand(3).isFI() ||
375 MI.getOperand(4).getImm() != 0)
379 int64_t
Length =
MI.getOperand(2).getImm();
380 unsigned FI1 =
MI.getOperand(0).getIndex();
381 unsigned FI2 =
MI.getOperand(3).getIndex();
386 DestFrameIndex = FI1;
395 bool AllowModify)
const {
401 while (
I !=
MBB.begin()) {
403 if (
I->isDebugInstr())
408 if (!isUnpredicatedTerminator(*
I))
418 if (!Branch.hasMBBTarget())
428 TBB = Branch.getMBBTarget();
433 MBB.erase(std::next(
I),
MBB.end());
439 if (
MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
441 I->eraseFromParent();
447 TBB = Branch.getMBBTarget();
455 TBB = Branch.getMBBTarget();
462 assert(
Cond.size() == 2 &&
TBB &&
"Should have seen a conditional branch");
466 if (
TBB != Branch.getMBBTarget())
470 unsigned OldCCValid =
Cond[0].getImm();
471 unsigned OldCCMask =
Cond[1].getImm();
472 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
483 int *BytesRemoved)
const {
484 assert(!BytesRemoved &&
"code size not handled");
490 while (
I !=
MBB.begin()) {
492 if (
I->isDebugInstr())
499 I->eraseFromParent();
509 assert(
Cond.size() == 2 &&
"Invalid condition");
519 int *BytesAdded)
const {
525 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
527 "SystemZ branch conditions have one component!");
528 assert(!BytesAdded &&
"code size not handled");
532 assert(!FBB &&
"Unconditional branch with multiple successors!");
539 unsigned CCValid =
Cond[0].getImm();
540 unsigned CCMask =
Cond[1].getImm();
555 int64_t &
Value)
const {
556 assert(
MI.isCompare() &&
"Caller should have checked for a comparison");
558 if (
MI.getNumExplicitOperands() == 2 &&
MI.getOperand(0).isReg() &&
559 MI.getOperand(1).isImm()) {
560 SrcReg =
MI.getOperand(0).getReg();
562 Value =
MI.getOperand(1).getImm();
575 int &FalseCycles)
const {
577 if (!STI.hasLoadStoreOnCond())
579 if (Pred.size() != 2)
590 if ((STI.hasLoadStoreOnCond2() &&
591 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
592 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
593 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
613 assert(Pred.size() == 2 &&
"Invalid condition");
614 unsigned CCValid = Pred[0].getImm();
615 unsigned CCMask = Pred[1].getImm();
618 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
619 if (STI.hasMiscellaneousExtensions3())
620 Opc = SystemZ::SELRMux;
621 else if (STI.hasLoadStoreOnCond2())
622 Opc = SystemZ::LOCRMux;
633 }
else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
634 if (STI.hasMiscellaneousExtensions3())
635 Opc = SystemZ::SELGR;
637 Opc = SystemZ::LOCGR;
649 unsigned DefOpc =
DefMI.getOpcode();
651 if (DefOpc == SystemZ::VGBM) {
652 int64_t ImmVal =
DefMI.getOperand(1).getImm();
667 MRI->
getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
677 UseMI.setDesc(
get(SystemZ::REG_SEQUENCE));
678 UseMI.getOperand(1).setReg(TmpReg);
680 .
addImm(SystemZ::subreg_h64)
682 .
addImm(SystemZ::subreg_l64);
685 DefMI.eraseFromParent();
692 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
693 DefOpc != SystemZ::LGHI)
695 if (
DefMI.getOperand(0).getReg() != Reg)
697 int32_t ImmVal = (int32_t)
DefMI.getOperand(1).getImm();
699 unsigned UseOpc =
UseMI.getOpcode();
705 case SystemZ::SELRMux:
708 case SystemZ::LOCRMux:
709 if (!STI.hasLoadStoreOnCond2())
711 NewUseOpc = SystemZ::LOCHIMux;
712 if (
UseMI.getOperand(2).getReg() == Reg)
714 else if (
UseMI.getOperand(1).getReg() == Reg)
715 UseIdx = 2, CommuteIdx = 1;
723 if (!STI.hasLoadStoreOnCond2())
725 NewUseOpc = SystemZ::LOCGHI;
726 if (
UseMI.getOperand(2).getReg() == Reg)
728 else if (
UseMI.getOperand(1).getReg() == Reg)
729 UseIdx = 2, CommuteIdx = 1;
737 if (CommuteIdx != -1)
738 if (!commuteInstruction(
UseMI,
false, CommuteIdx, UseIdx))
744 UseMI.tieOperands(0, 1);
745 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
747 DefMI.eraseFromParent();
753 unsigned Opcode =
MI.getOpcode();
754 if (Opcode == SystemZ::Return ||
755 Opcode == SystemZ::Return_XPLINK ||
756 Opcode == SystemZ::Trap ||
757 Opcode == SystemZ::CallJG ||
758 Opcode == SystemZ::CallBR)
765 unsigned NumCycles,
unsigned ExtraPredCycles,
775 if (
MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap &&
779 return NumCycles == 1;
784 unsigned NumCyclesT,
unsigned ExtraPredCyclesT,
786 unsigned NumCyclesF,
unsigned ExtraPredCyclesF,
796 return NumCycles == 1;
801 assert(Pred.size() == 2 &&
"Invalid condition");
802 unsigned CCValid = Pred[0].getImm();
803 unsigned CCMask = Pred[1].getImm();
804 assert(CCMask > 0 && CCMask < 15 &&
"Invalid predicate");
805 unsigned Opcode =
MI.getOpcode();
806 if (Opcode == SystemZ::Trap) {
807 MI.setDesc(
get(SystemZ::CondTrap));
813 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
814 MI.setDesc(
get(Opcode == SystemZ::Return ? SystemZ::CondReturn
815 : SystemZ::CondReturn_XPLINK));
822 if (Opcode == SystemZ::CallJG) {
824 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
827 MI.setDesc(
get(SystemZ::CallBRCL));
836 if (Opcode == SystemZ::CallBR) {
838 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
841 MI.setDesc(
get(SystemZ::CallBCR));
857 bool RenamableSrc)
const {
861 if (SystemZ::GR128BitRegClass.
contains(DestReg, SrcReg)) {
863 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
867 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
873 if (SystemZ::GRX32BitRegClass.
contains(DestReg, SrcReg)) {
874 emitGRX32Move(
MBB,
MBBI,
DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
880 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
881 SystemZ::FP128BitRegClass.
contains(SrcReg)) {
883 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
884 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
886 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
887 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
894 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
895 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
897 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
898 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
900 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
901 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
903 if (DestRegHi != SrcReg.
asMCReg())
910 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
911 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
912 MCRegister DestRegHi = RI.getSubReg(DestReg, SystemZ::subreg_h64);
913 MCRegister DestRegLo = RI.getSubReg(DestReg, SystemZ::subreg_l64);
914 MCRegister SrcRegHi = RI.getSubReg(SrcReg, SystemZ::subreg_h64);
915 MCRegister SrcRegLo = RI.getSubReg(SrcReg, SystemZ::subreg_l64);
927 if (DestReg == SystemZ::CC) {
929 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
936 if (SystemZ::GR128BitRegClass.
contains(DestReg) &&
937 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
938 MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64);
939 MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64);
943 .
addReg(SystemZ::NoRegister)
948 .
addReg(SystemZ::NoRegister)
953 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
954 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
956 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64))
957 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64));
963 if (SystemZ::GR64BitRegClass.
contains(DestReg, SrcReg))
964 Opcode = SystemZ::LGR;
965 else if (SystemZ::FP16BitRegClass.
contains(DestReg, SrcReg))
966 Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
967 else if (SystemZ::FP32BitRegClass.
contains(DestReg, SrcReg))
969 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
970 else if (SystemZ::FP64BitRegClass.
contains(DestReg, SrcReg))
971 Opcode = SystemZ::LDR;
972 else if (SystemZ::FP128BitRegClass.
contains(DestReg, SrcReg))
973 Opcode = SystemZ::LXR;
974 else if (SystemZ::VR16BitRegClass.
contains(DestReg, SrcReg))
975 Opcode = SystemZ::VLR16;
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;
984 else if (SystemZ::GR64BitRegClass.
contains(DestReg) &&
985 SystemZ::FP64BitRegClass.
contains(SrcReg))
986 Opcode = SystemZ::LGDR;
987 else if (SystemZ::FP64BitRegClass.
contains(DestReg) &&
988 SystemZ::GR64BitRegClass.
contains(SrcReg))
989 Opcode = SystemZ::LDGR;
1006 unsigned LoadOpcode, StoreOpcode;
1023 unsigned LoadOpcode, StoreOpcode;
1033 return ((
MCID.TSFlags & Flag) &&
1035 MI->getOperand(3).getReg() == 0);
1041 LogicOp() =
default;
1042 LogicOp(
unsigned regSize,
unsigned immLSB,
unsigned immSize)
1043 :
RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1045 explicit operator bool()
const {
return RegSize; }
1048 unsigned ImmLSB = 0;
1049 unsigned ImmSize = 0;
1056 case SystemZ::NILMux:
return LogicOp(32, 0, 16);
1057 case SystemZ::NIHMux:
return LogicOp(32, 16, 16);
1058 case SystemZ::NILL64:
return LogicOp(64, 0, 16);
1059 case SystemZ::NILH64:
return LogicOp(64, 16, 16);
1060 case SystemZ::NIHL64:
return LogicOp(64, 32, 16);
1061 case SystemZ::NIHH64:
return LogicOp(64, 48, 16);
1062 case SystemZ::NIFMux:
return LogicOp(32, 0, 32);
1063 case SystemZ::NILF64:
return LogicOp(64, 0, 32);
1064 case SystemZ::NIHF64:
return LogicOp(64, 32, 32);
1065 default:
return LogicOp();
1073 if (CCDef !=
nullptr)
1092 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
1094 uint64_t
Imm =
MI.getOperand(2).getImm() <<
And.ImmLSB;
1097 unsigned Start, End;
1100 if (
And.RegSize == 64) {
1101 NewOpcode = SystemZ::RISBG;
1103 if (STI.hasMiscellaneousExtensions())
1104 NewOpcode = SystemZ::RISBGN;
1106 NewOpcode = SystemZ::RISBMux;
1134 bool Invert)
const {
1140 Opc = *InverseOpcode;
1147 case SystemZ::WFADB:
1148 case SystemZ::WFASB:
1149 case SystemZ::WFAXB:
1150 case SystemZ::VFADB:
1151 case SystemZ::VFASB:
1152 case SystemZ::WFMDB:
1153 case SystemZ::WFMSB:
1154 case SystemZ::WFMXB:
1155 case SystemZ::VFMDB:
1156 case SystemZ::VFMSB:
1164std::optional<unsigned>
1168 case SystemZ::WFADB:
1169 return SystemZ::WFSDB;
1170 case SystemZ::WFASB:
1171 return SystemZ::WFSSB;
1172 case SystemZ::WFAXB:
1173 return SystemZ::WFSXB;
1174 case SystemZ::VFADB:
1175 return SystemZ::VFSDB;
1176 case SystemZ::VFASB:
1177 return SystemZ::VFSSB;
1179 case SystemZ::WFSDB:
1180 return SystemZ::WFADB;
1181 case SystemZ::WFSSB:
1182 return SystemZ::WFASB;
1183 case SystemZ::WFSXB:
1184 return SystemZ::WFAXB;
1185 case SystemZ::VFSDB:
1186 return SystemZ::VFADB;
1187 case SystemZ::VFSSB:
1188 return SystemZ::VFASB;
1190 return std::nullopt;
1203 unsigned Opcode =
MI.getOpcode();
1208 bool CCLiveAtMI =
true;
1213 CCLiveRange = &LIS->
getRegUnit(*CCUnits.begin());
1214 CCLiveAtMI = CCLiveRange->
liveAt(MISlot);
1217 if (
Ops.size() == 2 &&
Ops[0] == 0 &&
Ops[1] == 1) {
1218 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1219 isInt<8>(
MI.getOperand(2).getImm()) && !
MI.getOperand(3).getReg()) {
1222 MI.getDebugLoc(),
get(SystemZ::AGSI))
1225 .
addImm(
MI.getOperand(2).getImm());
1235 if (
Ops.size() != 1)
1238 unsigned OpNum =
Ops[0];
1242 (RC == &SystemZ::FP16BitRegClass &&
Size == 4 && !STI.hasVector())) &&
1243 "Invalid size combination");
1246 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1249 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1251 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1254 .
addImm(
MI.getOperand(2).getImm());
1260 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1261 isInt<8>((int32_t)
MI.getOperand(2).getImm())) ||
1262 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1265 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1267 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1270 .
addImm((int8_t)
MI.getOperand(2).getImm());
1275 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1276 isInt<8>((int32_t)-
MI.getOperand(2).getImm())) ||
1277 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1280 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1282 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1285 .
addImm((int8_t)-
MI.getOperand(2).getImm());
1290 unsigned MemImmOpc = 0;
1292 case SystemZ::LHIMux:
1293 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI;
break;
1294 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI;
break;
1295 case SystemZ::CHIMux:
1296 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI;
break;
1297 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI;
break;
1298 case SystemZ::CLFIMux:
1301 MemImmOpc = SystemZ::CLFHSI;
1303 case SystemZ::CLGFI:
1305 MemImmOpc = SystemZ::CLGHSI;
1310 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1314 .
addImm(
MI.getOperand(1).getImm());
1316 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1317 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1318 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1322 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1323 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1325 .
add(
MI.getOperand(1))
1333 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1334 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1336 .
add(
MI.getOperand(0))
1356 if (OpNum == 0 &&
MI.hasOneMemOperand()) {
1361 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1366 .
add(
MI.getOperand(1))
1372 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1374 .
add(
MI.getOperand(1))
1387 unsigned NumOps =
MI.getNumExplicitOperands();
1388 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1389 if (MemOpcode == -1 ||
1390 (CCLiveAtMI && !
MI.definesRegister(SystemZ::CC,
nullptr) &&
1391 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1397 for (
unsigned I = 0, E =
MCID.getNumOperands();
I != E; ++
I) {
1402 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1408 !(SystemZ::FP32BitRegClass.
contains(PhysReg) ||
1409 SystemZ::FP64BitRegClass.
contains(PhysReg) ||
1410 SystemZ::VF128BitRegClass.
contains(PhysReg)))
1415 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1416 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1420 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1425 bool NeedsCommute =
false;
1426 if ((
MI.getOpcode() == SystemZ::CR ||
MI.getOpcode() == SystemZ::CGR ||
1427 MI.getOpcode() == SystemZ::CLR ||
MI.getOpcode() == SystemZ::CLGR ||
1428 MI.getOpcode() == SystemZ::WFCDB ||
MI.getOpcode() == SystemZ::WFCSB ||
1429 MI.getOpcode() == SystemZ::WFKDB ||
MI.getOpcode() == SystemZ::WFKSB) &&
1431 NeedsCommute =
true;
1433 bool CCOperands =
false;
1434 if (
MI.getOpcode() == SystemZ::LOCRMux ||
MI.getOpcode() == SystemZ::LOCGR ||
1435 MI.getOpcode() == SystemZ::SELRMux ||
MI.getOpcode() == SystemZ::SELGR) {
1437 "LOCR/SELR instruction operands corrupt?");
1453 : ((OpNum == 1 &&
MI.isCommutable())
1454 ?
MI.getOperand(2).getReg()
1456 if (DstPhys && !SystemZ::GRH32BitRegClass.
contains(DstPhys) && SrcReg &&
1458 NeedsCommute = (OpNum == 1);
1464 if ((OpNum ==
NumOps - 1) || NeedsCommute || FusedFPOp) {
1467 assert(AccessBytes != 0 &&
"Size of access should be known");
1468 assert(AccessBytes <=
Size &&
"Access outside the frame index");
1471 MI.getDebugLoc(),
get(MemOpcode));
1472 if (
MI.isCompare()) {
1473 assert(
NumOps == 2 &&
"Expected 2 register operands for a compare.");
1474 MIB.
add(
MI.getOperand(NeedsCommute ? 1 : 0));
1476 else if (FusedFPOp) {
1477 MIB.
add(
MI.getOperand(0));
1478 MIB.
add(
MI.getOperand(3));
1479 MIB.
add(
MI.getOperand(OpNum == 1 ? 2 : 1));
1482 MIB.
add(
MI.getOperand(0));
1484 MIB.
add(
MI.getOperand(2));
1486 for (
unsigned I = 1;
I < OpNum; ++
I)
1487 MIB.
add(
MI.getOperand(
I));
1493 unsigned CCValid =
MI.getOperand(
NumOps).getImm();
1494 unsigned CCMask =
MI.getOperand(
NumOps + 1).getImm();
1496 MIB.
addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1499 (!
MI.definesRegister(SystemZ::CC,
nullptr) ||
1500 MI.registerDefIsDead(SystemZ::CC,
nullptr))) {
1508 if (MO.isReg() && MO.getReg().isVirtual()) {
1510 if (MRI.
getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1512 else if (MRI.
getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1514 else if (MRI.
getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1541 unsigned LoadOpc = 0;
1542 unsigned RegMemOpcode = 0;
1544 RegMemOpcode =
MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1545 :
MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1546 :
MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1549 LoadOpc = SystemZ::VL64;
1550 FPRC = &SystemZ::FP64BitRegClass;
1552 RegMemOpcode =
MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1553 :
MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1554 :
MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1557 LoadOpc = SystemZ::VL32;
1558 FPRC = &SystemZ::FP32BitRegClass;
1561 if (!RegMemOpcode || LoadMI.
getOpcode() != LoadOpc)
1565 if (
get(RegMemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)) {
1567 if (MII ==
MBB->begin()) {
1568 if (
MBB->isLiveIn(SystemZ::CC))
1573 if (MII->definesRegister(SystemZ::CC,
nullptr)) {
1574 if (!MII->registerDefIsDead(SystemZ::CC,
nullptr))
1582 if (
Ops.size() != 1 || FoldAsLoadDefReg !=
MI.getOperand(
Ops[0]).getReg())
1588 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1589 FoldAsLoadDefReg != RHS.getReg())
1598 BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(RegMemOpcode), DstReg)
1612 switch (
MI.getOpcode()) {
1614 splitMove(
MI, SystemZ::LG);
1617 case SystemZ::ST128:
1618 splitMove(
MI, SystemZ::STG);
1622 splitMove(
MI, SystemZ::LD);
1626 splitMove(
MI, SystemZ::STD);
1629 case SystemZ::LBMux:
1630 expandRXYPseudo(
MI, SystemZ::LB, SystemZ::LBH);
1633 case SystemZ::LHMux:
1634 expandRXYPseudo(
MI, SystemZ::LH, SystemZ::LHH);
1637 case SystemZ::LLCRMux:
1638 expandZExtPseudo(
MI, SystemZ::LLCR, 8);
1641 case SystemZ::LLHRMux:
1642 expandZExtPseudo(
MI, SystemZ::LLHR, 16);
1645 case SystemZ::LLCMux:
1646 expandRXYPseudo(
MI, SystemZ::LLC, SystemZ::LLCH);
1649 case SystemZ::LLHMux:
1650 expandRXYPseudo(
MI, SystemZ::LLH, SystemZ::LLHH);
1654 expandRXYPseudo(
MI, SystemZ::L, SystemZ::LFH);
1657 case SystemZ::LOCMux:
1658 expandLOCPseudo(
MI, SystemZ::LOC, SystemZ::LOCFH);
1661 case SystemZ::LOCHIMux:
1662 expandLOCPseudo(
MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1665 case SystemZ::STCMux:
1666 expandRXYPseudo(
MI, SystemZ::STC, SystemZ::STCH);
1669 case SystemZ::STHMux:
1670 expandRXYPseudo(
MI, SystemZ::STH, SystemZ::STHH);
1673 case SystemZ::STMux:
1674 expandRXYPseudo(
MI, SystemZ::ST, SystemZ::STFH);
1677 case SystemZ::STOCMux:
1678 expandLOCPseudo(
MI, SystemZ::STOC, SystemZ::STOCFH);
1681 case SystemZ::LHIMux:
1682 expandRIPseudo(
MI, SystemZ::LHI, SystemZ::IIHF,
true);
1685 case SystemZ::IIFMux:
1686 expandRIPseudo(
MI, SystemZ::IILF, SystemZ::IIHF,
false);
1689 case SystemZ::IILMux:
1690 expandRIPseudo(
MI, SystemZ::IILL, SystemZ::IIHL,
false);
1693 case SystemZ::IIHMux:
1694 expandRIPseudo(
MI, SystemZ::IILH, SystemZ::IIHH,
false);
1697 case SystemZ::NIFMux:
1698 expandRIPseudo(
MI, SystemZ::NILF, SystemZ::NIHF,
false);
1701 case SystemZ::NILMux:
1702 expandRIPseudo(
MI, SystemZ::NILL, SystemZ::NIHL,
false);
1705 case SystemZ::NIHMux:
1706 expandRIPseudo(
MI, SystemZ::NILH, SystemZ::NIHH,
false);
1709 case SystemZ::OIFMux:
1710 expandRIPseudo(
MI, SystemZ::OILF, SystemZ::OIHF,
false);
1713 case SystemZ::OILMux:
1714 expandRIPseudo(
MI, SystemZ::OILL, SystemZ::OIHL,
false);
1717 case SystemZ::OIHMux:
1718 expandRIPseudo(
MI, SystemZ::OILH, SystemZ::OIHH,
false);
1721 case SystemZ::XIFMux:
1722 expandRIPseudo(
MI, SystemZ::XILF, SystemZ::XIHF,
false);
1725 case SystemZ::TMLMux:
1726 expandRIPseudo(
MI, SystemZ::TMLL, SystemZ::TMHL,
false);
1729 case SystemZ::TMHMux:
1730 expandRIPseudo(
MI, SystemZ::TMLH, SystemZ::TMHH,
false);
1733 case SystemZ::AHIMux:
1734 expandRIPseudo(
MI, SystemZ::AHI, SystemZ::AIH,
false);
1737 case SystemZ::AHIMuxK:
1738 expandRIEPseudo(
MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1741 case SystemZ::AFIMux:
1742 expandRIPseudo(
MI, SystemZ::AFI, SystemZ::AIH,
false);
1745 case SystemZ::CHIMux:
1746 expandRIPseudo(
MI, SystemZ::CHI, SystemZ::CIH,
false);
1749 case SystemZ::CFIMux:
1750 expandRIPseudo(
MI, SystemZ::CFI, SystemZ::CIH,
false);
1753 case SystemZ::CLFIMux:
1754 expandRIPseudo(
MI, SystemZ::CLFI, SystemZ::CLIH,
false);
1758 expandRXYPseudo(
MI, SystemZ::C, SystemZ::CHF);
1761 case SystemZ::CLMux:
1762 expandRXYPseudo(
MI, SystemZ::CL, SystemZ::CLHF);
1765 case SystemZ::RISBMux: {
1768 if (SrcIsHigh == DestIsHigh)
1769 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1771 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1772 MI.getOperand(5).setImm(
MI.getOperand(5).getImm() ^ 32);
1777 case SystemZ::ADJDYNALLOC:
1778 splitAdjDynAlloc(
MI);
1781 case SystemZ::MOV_STACKGUARD:
1782 expandStackGuardPseudo(
MI, SystemZ::MVC);
1785 case SystemZ::CMP_STACKGUARD:
1786 expandStackGuardPseudo(
MI, SystemZ::CLC);
1795 unsigned Opcode)
const {
1798 const auto DL =
MI.getDebugLoc();
1800 StringRef GuardType = M->getStackProtectorGuard();
1803 Register AddrReg =
MI.getOperand(0).getReg();
1806 AddrReg !=
MI.getOperand(1).getReg() &&
1807 "Scratch register for stack guard address blocked by operand register.");
1811 if (GuardType.
empty() || (GuardType ==
"tls")) {
1813 enum { OFFSET_PSALAA = 0x4B8 };
1814 enum { OFFSET_CEELAA_STACK_GUARD = 0x98 };
1821 Offset = OFFSET_CEELAA_STACK_GUARD;
1828 }
else if (GuardType ==
"global") {
1845 MI.removeFromParent();
1849 if (
MI.isInlineAsm()) {
1851 const char *AsmStr =
MI.getOperand(0).getSymbolName();
1854 else if (
MI.getOpcode() == SystemZ::PATCHPOINT)
1856 else if (
MI.getOpcode() == SystemZ::STACKMAP)
1857 return MI.getOperand(1).getImm();
1858 else if (
MI.getOpcode() == SystemZ::FENTRY_CALL)
1860 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)
1862 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_RET)
1863 return 18 + (
MI.getOperand(0).
getImm() == SystemZ::CondReturn ? 4 : 0);
1864 if (
MI.getOpcode() == TargetOpcode::BUNDLE)
1865 return getInstBundleSize(
MI);
1866 if (
MI.getOpcode() == SystemZ::LOAD_TLS_BLOCK_ADDR)
1869 if (
MI.getOpcode() == SystemZ::LOAD_GLOBAL_STACKGUARD_ADDR)
1873 return MI.getDesc().getSize();
1878 switch (
MI.getOpcode()) {
1889 MI.getOperand(1).getImm(), &
MI.getOperand(2));
1892 case SystemZ::BRCTH:
1896 case SystemZ::BRCTG:
1903 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1908 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1913 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1915 case SystemZ::CLGIJ:
1916 case SystemZ::CLGRJ:
1918 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1920 case SystemZ::INLINEASM_BR:
1930 unsigned &LoadOpcode,
1931 unsigned &StoreOpcode)
const {
1932 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1933 LoadOpcode = SystemZ::L;
1934 StoreOpcode = SystemZ::ST;
1935 }
else if (RC == &SystemZ::GRH32BitRegClass) {
1936 LoadOpcode = SystemZ::LFH;
1937 StoreOpcode = SystemZ::STFH;
1938 }
else if (RC == &SystemZ::GRX32BitRegClass) {
1939 LoadOpcode = SystemZ::LMux;
1940 StoreOpcode = SystemZ::STMux;
1941 }
else if (RC == &SystemZ::GR64BitRegClass ||
1942 RC == &SystemZ::ADDR64BitRegClass) {
1943 LoadOpcode = SystemZ::LG;
1944 StoreOpcode = SystemZ::STG;
1945 }
else if (RC == &SystemZ::GR128BitRegClass ||
1946 RC == &SystemZ::ADDR128BitRegClass) {
1947 LoadOpcode = SystemZ::L128;
1948 StoreOpcode = SystemZ::ST128;
1949 }
else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
1950 LoadOpcode = SystemZ::LE16;
1951 StoreOpcode = SystemZ::STE16;
1952 }
else if (RC == &SystemZ::FP32BitRegClass) {
1953 LoadOpcode = SystemZ::LE;
1954 StoreOpcode = SystemZ::STE;
1955 }
else if (RC == &SystemZ::FP64BitRegClass) {
1956 LoadOpcode = SystemZ::LD;
1957 StoreOpcode = SystemZ::STD;
1958 }
else if (RC == &SystemZ::FP128BitRegClass) {
1959 LoadOpcode = SystemZ::LX;
1960 StoreOpcode = SystemZ::STX;
1961 }
else if (RC == &SystemZ::FP16BitRegClass ||
1962 RC == &SystemZ::VR16BitRegClass) {
1963 LoadOpcode = SystemZ::VL16;
1964 StoreOpcode = SystemZ::VST16;
1965 }
else if (RC == &SystemZ::VR32BitRegClass) {
1966 LoadOpcode = SystemZ::VL32;
1967 StoreOpcode = SystemZ::VST32;
1968 }
else if (RC == &SystemZ::VR64BitRegClass) {
1969 LoadOpcode = SystemZ::VL64;
1970 StoreOpcode = SystemZ::VST64;
1971 }
else if (RC == &SystemZ::VF128BitRegClass ||
1972 RC == &SystemZ::VR128BitRegClass) {
1973 LoadOpcode = SystemZ::VL;
1974 StoreOpcode = SystemZ::VST;
1986 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1987 if (Disp12Opcode >= 0)
1988 return Disp12Opcode;
1996 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1997 if (Disp20Opcode >= 0)
1998 return Disp20Opcode;
2005 if (
MI &&
MI->getOperand(0).isReg()) {
2010 return SystemZ::LEY;
2011 case SystemZ::VST32:
2012 return SystemZ::STEY;
2014 return SystemZ::LDY;
2015 case SystemZ::VST64:
2016 return SystemZ::STDY;
2028 return SystemZ::getDisp12Opcode(Opcode) >= 0;
2029 return SystemZ::getDisp20Opcode(Opcode) >= 0;
2034 case SystemZ::L:
return SystemZ::LT;
2035 case SystemZ::LY:
return SystemZ::LT;
2036 case SystemZ::LG:
return SystemZ::LTG;
2037 case SystemZ::LGF:
return SystemZ::LTGF;
2038 case SystemZ::LR:
return SystemZ::LTR;
2039 case SystemZ::LGFR:
return SystemZ::LTGFR;
2040 case SystemZ::LGR:
return SystemZ::LTGR;
2041 case SystemZ::LCDFR:
return SystemZ::LCDBR;
2042 case SystemZ::LPDFR:
return SystemZ::LPDBR;
2043 case SystemZ::LNDFR:
return SystemZ::LNDBR;
2044 case SystemZ::LCDFR_32:
return SystemZ::LCEBR;
2045 case SystemZ::LPDFR_32:
return SystemZ::LPEBR;
2046 case SystemZ::LNDFR_32:
return SystemZ::LNEBR;
2051 case SystemZ::RISBGN:
return SystemZ::RISBG;
2057 unsigned &Start,
unsigned &End)
const {
2067 Start = 63 - (LSB +
Length - 1);
2075 assert(LSB > 0 &&
"Bottom bit must be set");
2076 assert(LSB +
Length < BitSize &&
"Top bit must be set");
2077 Start = 63 - (LSB - 1);
2078 End = 63 - (LSB +
Length);
2095 case SystemZ::CLGFI:
2101 if (!STI.hasMiscellaneousExtensions())
2103 if (!(
MI &&
MI->getOperand(3).getReg() == 0))
2111 return SystemZ::CRJ;
2113 return SystemZ::CGRJ;
2115 return SystemZ::CIJ;
2117 return SystemZ::CGIJ;
2119 return SystemZ::CLRJ;
2121 return SystemZ::CLGRJ;
2123 return SystemZ::CLIJ;
2124 case SystemZ::CLGFI:
2125 return SystemZ::CLGIJ;
2132 return SystemZ::CRBReturn;
2134 return SystemZ::CGRBReturn;
2136 return SystemZ::CIBReturn;
2138 return SystemZ::CGIBReturn;
2140 return SystemZ::CLRBReturn;
2142 return SystemZ::CLGRBReturn;
2144 return SystemZ::CLIBReturn;
2145 case SystemZ::CLGFI:
2146 return SystemZ::CLGIBReturn;
2153 return SystemZ::CRBCall;
2155 return SystemZ::CGRBCall;
2157 return SystemZ::CIBCall;
2159 return SystemZ::CGIBCall;
2161 return SystemZ::CLRBCall;
2163 return SystemZ::CLGRBCall;
2165 return SystemZ::CLIBCall;
2166 case SystemZ::CLGFI:
2167 return SystemZ::CLGIBCall;
2174 return SystemZ::CRT;
2176 return SystemZ::CGRT;
2178 return SystemZ::CIT;
2180 return SystemZ::CGIT;
2182 return SystemZ::CLRT;
2184 return SystemZ::CLGRT;
2186 return SystemZ::CLFIT;
2187 case SystemZ::CLGFI:
2188 return SystemZ::CLGIT;
2190 return SystemZ::CLT;
2192 return SystemZ::CLGT;
2203 return (
MI.getOpcode() == SystemZ::LTEBR ||
2204 MI.getOpcode() == SystemZ::LTDBR ||
2205 MI.getOpcode() == SystemZ::LTXBR) &&
2206 MI.getOperand(0).isDead();
2212 return Compare.isCompare() && Compare.getNumExplicitOperands() == 2 &&
2213 Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
2225 MBBI->getOperand(1).isReg() && !
MBBI->mayLoad() &&
2226 "Not a compare reg/reg.");
2232 if (
MI.readsRegister(SystemZ::CC,
nullptr)) {
2233 unsigned Flags =
MI.getDesc().TSFlags;
2239 if (
MI.definesRegister(SystemZ::CC,
nullptr)) {
2247 if (!
LiveRegs.available(SystemZ::CC))
2252 for (
unsigned Idx = 0; Idx < CCUsers.
size(); ++Idx) {
2253 unsigned Flags = CCUsers[Idx]->getDesc().TSFlags;
2255 0 : CCUsers[Idx]->getNumExplicitOperands() - 2);
2256 MachineOperand &CCMaskMO = CCUsers[Idx]->getOperand(FirstOpNum + 1);
2258 CCMaskMO.
setImm(NewCCMask);
2296 if (!STI.hasLoadAndTrap())
2301 return SystemZ::LAT;
2303 return SystemZ::LGAT;
2305 return SystemZ::LFHAT;
2307 return SystemZ::LLGFAT;
2309 return SystemZ::LLGTAT;
2316 unsigned Reg, uint64_t
Value)
const {
2318 unsigned Opcode = 0;
2320 Opcode = SystemZ::LGHI;
2322 Opcode = SystemZ::LLILL;
2324 Opcode = SystemZ::LLILH;
2328 Opcode = SystemZ::LGFI;
2335 assert (MRI.
isSSA() &&
"Huge values only handled before reg-alloc .");
2348 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
2349 if (
I >=
MCID.getNumOperands())
2357 ((
MCOI.RegClass != -1 && !
Op.isReg() && !
Op.isFI()) ||
2358 (
MCOI.RegClass == -1 && !
Op.isImm()))) {
2359 ErrInfo =
"Addressing mode operands corrupt!";
2382 bool SameVal = (VALa && VALb && (VALa == VALb));
2386 if (PSVa && PSVb && (PSVa == PSVb))
2392 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2393 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2394 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2396 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
2405 int64_t &ImmVal)
const {
2407 if (
MI.getOpcode() == SystemZ::VGBM && Reg ==
MI.getOperand(0).getReg()) {
2408 ImmVal =
MI.getOperand(1).getImm();
2416std::optional<DestSourcePair>
2422 return std::nullopt;
2425std::pair<unsigned, unsigned>
2427 return std::make_pair(TF, 0u);
2434 static const std::pair<unsigned, const char *> TargetFlags[] = {
2435 {MO_GOT,
"systemz-got"},
2436 {MO_INDNTPOFF,
"systemz-indntpoff"},
2437 {MO_ADA_DATA_SYMBOL_ADDR,
"systemz-ada-datasymboladdr"},
2438 {MO_ADA_INDIRECT_FUNC_DESC,
"systemz-ada-indirectfuncdesc"},
2439 {MO_ADA_DIRECT_FUNC_DESC,
"systemz-ada-directfuncdesc"}};
2448 return MI.getOpcode() == SystemZ::FENCE ||
2449 MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER;
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
DXIL Forward Handle Accesses
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag)
static void transferDeadCC(MachineInstr *OldMI, MachineInstr *NewMI)
static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI, MachineInstr::MIFlag Flag)
static int isSimpleMove(const MachineInstr &MI, int &FrameIndex, unsigned Flag)
static LogicOp interpretAndImmediate(unsigned Opcode)
static uint64_t allOnes(unsigned int Count)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Module * getParent()
Get the module that this global value is contained inside of...
SlotIndexes * getSlotIndexes() const
VNInfo::Allocator & getVNInfoAllocator()
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
LLVM_ABI VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
A set of register units used to track register liveness.
TypeSize getValue() const
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
This holds information about one operand of a machine instruction, indicating the register class for ...
Wrapper class representing physical registers. Should be passed by value.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
bool registerDefIsDead(Register Reg, const TargetRegisterInfo *TRI) const
Returns true if the register is dead in this machine instruction.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
void setFlag(MIFlag Flag)
Set a MI flag.
const MachineOperand & getOperand(unsigned i) const
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
LLVM_ABI bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
const PseudoSourceValue * getPseudoValue() const
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
const Value * getValue() const
Return the base address of the memory access.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
A Module instance is used to store all the information related to an LLVM module.
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
virtual int getStackPointerBias()=0
virtual int getCallFrameSize()=0
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveIntervals *LIS) const override
unsigned getLoadAndTrap(unsigned Opcode) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
unsigned getLoadAndTest(unsigned Opcode) const
MCInst getNop() const override
bool isPredicable(const MachineInstr &MI) const override
Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const override
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset, const MachineInstr *MI=nullptr) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg, int64_t &ImmVal) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool hasDisplacementPairInsn(unsigned Opcode) const
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned CommuteOpIdx1, unsigned CommuteOpIdx2) const override
Commutes the operands in the given instruction by changing the operands order and/or changing the ins...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
bool isCompareZero(const MachineInstr &Compare) const
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool isLoadAndTestAsCmp(const MachineInstr &MI) const
unsigned getFusedCompare(unsigned Opcode, SystemZII::FusedCompareType Type, const MachineInstr *MI=nullptr) const
bool expandPostRAPseudo(MachineInstr &MBBI) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode) const
bool isRxSBGMask(uint64_t Mask, unsigned BitSize, unsigned &Start, unsigned &End) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
Register getCompareSourceReg(const MachineInstr &Compare) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
SystemZInstrInfo(const SystemZSubtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned Reg, uint64_t Value) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getAccessSize(unsigned int Flags)
unsigned getFirstReg(unsigned Reg)
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_CMP_GT
const unsigned CCMASK_ANY
static bool isImmLL(uint64_t Val)
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_CMP_EQ
const unsigned CCMASK_ICMP
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
int32_t getTargetMemOpcode(uint32_t Opcode)
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
bool isHighReg(unsigned int Reg)
const unsigned CCMASK_CMP_UO
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
constexpr RegState getKillRegState(bool B)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr RegState getUndefRegState(bool B)
MCRegisterClass TargetRegisterClass