50#define GET_INSTRINFO_CTOR_DTOR
51#define GET_INSTRMAP_INFO
52#include "SystemZGenInstrInfo.inc"
54#define DEBUG_TYPE "systemz-II"
62void SystemZInstrInfo::anchor() {}
66 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister(),
73 unsigned NewOpcode)
const {
81 MBB->insert(LowPartMI, HighPartMI);
89 HighRegOp.
setReg(RI.getSubReg(HighRegOp.
getReg(), SystemZ::subreg_h64));
90 LowRegOp.
setReg(RI.getSubReg(LowRegOp.
getReg(), SystemZ::subreg_l64));
101 assert(HighOpcode && LowOpcode &&
"Both offsets should be in range");
106 if (
MI->mayStore()) {
118 auto overlapsAddressReg = [&](
Register Reg) ->
bool {
119 return RI.regsOverlap(
Reg,
MI->getOperand(1).getReg()) ||
120 RI.regsOverlap(
Reg,
MI->getOperand(3).getReg());
122 if (overlapsAddressReg(HighRegOp.
getReg())) {
124 "Both loads clobber address!");
137 MachineBasicBlock *
MBB =
MI->getParent();
140 MachineOperand &OffsetMO =
MI->getOperand(2);
141 SystemZCallingConventionRegisters *Regs = STI.getSpecialRegisters();
148 assert(NewOpcode &&
"No support for huge argument lists yet");
149 MI->setDesc(
get(NewOpcode));
159void SystemZInstrInfo::expandRIPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
161 bool ConvertHigh)
const {
164 MI.setDesc(
get(IsHigh ? HighOpcode : LowOpcode));
165 if (IsHigh && ConvertHigh)
166 MI.getOperand(1).setImm(uint32_t(
MI.getOperand(1).getImm()));
173void SystemZInstrInfo::expandRIEPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
175 unsigned HighOpcode)
const {
180 if (!DestIsHigh && !SrcIsHigh)
181 MI.setDesc(
get(LowOpcodeK));
183 if (DestReg != SrcReg) {
184 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(), DestReg, SrcReg,
185 SystemZ::LR, 32,
MI.getOperand(1).isKill(),
186 MI.getOperand(1).isUndef());
187 MI.getOperand(1).setReg(DestReg);
189 MI.setDesc(
get(DestIsHigh ? HighOpcode : LowOpcode));
190 MI.tieOperands(0, 1);
197void SystemZInstrInfo::expandRXYPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
198 unsigned HighOpcode)
const {
202 MI.getOperand(2).getImm());
203 MI.setDesc(
get(Opcode));
209void SystemZInstrInfo::expandLOCPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
210 unsigned HighOpcode)
const {
213 MI.setDesc(
get(Opcode));
219void SystemZInstrInfo::expandZExtPseudo(
MachineInstr &
MI,
unsigned LowOpcode,
220 unsigned Size)
const {
221 MachineInstrBuilder MIB =
222 emitGRX32Move(*
MI.getParent(),
MI,
MI.getDebugLoc(),
223 MI.getOperand(0).getReg(),
MI.getOperand(1).getReg(), LowOpcode,
224 Size,
MI.getOperand(1).isKill(),
MI.getOperand(1).isUndef());
230 MI.eraseFromParent();
242 unsigned SrcReg,
unsigned LowLowOpcode,
243 unsigned Size,
bool KillSrc,
244 bool UndefSrc)
const {
248 if (DestIsHigh && SrcIsHigh)
249 Opcode = SystemZ::RISBHH;
250 else if (DestIsHigh && !SrcIsHigh)
251 Opcode = SystemZ::RISBHL;
252 else if (!DestIsHigh && SrcIsHigh)
253 Opcode = SystemZ::RISBLH;
258 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
268 unsigned OpIdx2)
const {
271 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
275 switch (
MI.getOpcode()) {
276 case SystemZ::SELRMux:
277 case SystemZ::SELFHR:
280 case SystemZ::LOCRMux:
281 case SystemZ::LOCFHR:
283 case SystemZ::LOCGR: {
284 auto &WorkingMI = cloneIfNew(
MI);
286 unsigned CCValid = WorkingMI.getOperand(3).getImm();
287 unsigned CCMask = WorkingMI.getOperand(4).getImm();
288 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
305 if ((
MCID.TSFlags & Flag) &&
MI.getOperand(1).isFI() &&
306 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).getReg() == 0) {
307 FrameIndex =
MI.getOperand(1).getIndex();
308 return MI.getOperand(0).getReg();
314 int &FrameIndex)
const {
319 int &FrameIndex)
const {
324 int &FrameIndex)
const {
341 return MI.getOperand(0).getReg();
347 int &FrameIndex)
const {
364 return MI.getOperand(0).getReg();
371 int &SrcFrameIndex)
const {
374 if (
MI.getOpcode() != SystemZ::MVC || !
MI.getOperand(0).isFI() ||
375 MI.getOperand(1).getImm() != 0 || !
MI.getOperand(3).isFI() ||
376 MI.getOperand(4).getImm() != 0)
380 int64_t
Length =
MI.getOperand(2).getImm();
381 unsigned FI1 =
MI.getOperand(0).getIndex();
382 unsigned FI2 =
MI.getOperand(3).getIndex();
387 DestFrameIndex = FI1;
396 bool AllowModify)
const {
402 while (
I !=
MBB.begin()) {
404 if (
I->isDebugInstr())
409 if (!isUnpredicatedTerminator(*
I))
419 if (!Branch.hasMBBTarget())
429 TBB = Branch.getMBBTarget();
434 MBB.erase(std::next(
I),
MBB.end());
440 if (
MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
442 I->eraseFromParent();
448 TBB = Branch.getMBBTarget();
456 TBB = Branch.getMBBTarget();
463 assert(
Cond.size() == 2 &&
TBB &&
"Should have seen a conditional branch");
467 if (
TBB != Branch.getMBBTarget())
471 unsigned OldCCValid =
Cond[0].getImm();
472 unsigned OldCCMask =
Cond[1].getImm();
473 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
484 int *BytesRemoved)
const {
485 assert(!BytesRemoved &&
"code size not handled");
491 while (
I !=
MBB.begin()) {
493 if (
I->isDebugInstr())
500 I->eraseFromParent();
510 assert(
Cond.size() == 2 &&
"Invalid condition");
520 int *BytesAdded)
const {
526 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
528 "SystemZ branch conditions have one component!");
529 assert(!BytesAdded &&
"code size not handled");
533 assert(!FBB &&
"Unconditional branch with multiple successors!");
540 unsigned CCValid =
Cond[0].getImm();
541 unsigned CCMask =
Cond[1].getImm();
556 int64_t &
Value)
const {
557 assert(
MI.isCompare() &&
"Caller should have checked for a comparison");
559 if (
MI.getNumExplicitOperands() == 2 &&
MI.getOperand(0).isReg() &&
560 MI.getOperand(1).isImm()) {
561 SrcReg =
MI.getOperand(0).getReg();
563 Value =
MI.getOperand(1).getImm();
576 int &FalseCycles)
const {
578 if (!STI.hasLoadStoreOnCond())
580 if (Pred.size() != 2)
591 if ((STI.hasLoadStoreOnCond2() &&
592 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
593 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
594 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
614 assert(Pred.size() == 2 &&
"Invalid condition");
615 unsigned CCValid = Pred[0].getImm();
616 unsigned CCMask = Pred[1].getImm();
619 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
620 if (STI.hasMiscellaneousExtensions3())
621 Opc = SystemZ::SELRMux;
622 else if (STI.hasLoadStoreOnCond2())
623 Opc = SystemZ::LOCRMux;
634 }
else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
635 if (STI.hasMiscellaneousExtensions3())
636 Opc = SystemZ::SELGR;
638 Opc = SystemZ::LOCGR;
650 unsigned DefOpc =
DefMI.getOpcode();
652 if (DefOpc == SystemZ::VGBM) {
653 int64_t ImmVal =
DefMI.getOperand(1).getImm();
668 MRI->
getRegClass(CopyDstReg) == &SystemZ::GR128BitRegClass &&
678 UseMI.setDesc(
get(SystemZ::REG_SEQUENCE));
679 UseMI.getOperand(1).setReg(TmpReg);
681 .
addImm(SystemZ::subreg_h64)
683 .
addImm(SystemZ::subreg_l64);
686 DefMI.eraseFromParent();
693 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
694 DefOpc != SystemZ::LGHI)
696 if (
DefMI.getOperand(0).getReg() != Reg)
698 int32_t ImmVal = (int32_t)
DefMI.getOperand(1).getImm();
700 unsigned UseOpc =
UseMI.getOpcode();
706 case SystemZ::SELRMux:
709 case SystemZ::LOCRMux:
710 if (!STI.hasLoadStoreOnCond2())
712 NewUseOpc = SystemZ::LOCHIMux;
713 if (
UseMI.getOperand(2).getReg() == Reg)
715 else if (
UseMI.getOperand(1).getReg() == Reg)
716 UseIdx = 2, CommuteIdx = 1;
724 if (!STI.hasLoadStoreOnCond2())
726 NewUseOpc = SystemZ::LOCGHI;
727 if (
UseMI.getOperand(2).getReg() == Reg)
729 else if (
UseMI.getOperand(1).getReg() == Reg)
730 UseIdx = 2, CommuteIdx = 1;
738 if (CommuteIdx != -1)
739 if (!commuteInstruction(
UseMI,
false, CommuteIdx, UseIdx))
745 UseMI.tieOperands(0, 1);
746 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
748 DefMI.eraseFromParent();
754 unsigned Opcode =
MI.getOpcode();
755 if (Opcode == SystemZ::Return ||
756 Opcode == SystemZ::Return_XPLINK ||
757 Opcode == SystemZ::Trap ||
758 Opcode == SystemZ::CallJG ||
759 Opcode == SystemZ::CallBR)
766 unsigned NumCycles,
unsigned ExtraPredCycles,
776 if (
MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap &&
780 return NumCycles == 1;
785 unsigned NumCyclesT,
unsigned ExtraPredCyclesT,
787 unsigned NumCyclesF,
unsigned ExtraPredCyclesF,
797 return NumCycles == 1;
802 assert(Pred.size() == 2 &&
"Invalid condition");
803 unsigned CCValid = Pred[0].getImm();
804 unsigned CCMask = Pred[1].getImm();
805 assert(CCMask > 0 && CCMask < 15 &&
"Invalid predicate");
806 unsigned Opcode =
MI.getOpcode();
807 if (Opcode == SystemZ::Trap) {
808 MI.setDesc(
get(SystemZ::CondTrap));
814 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
815 MI.setDesc(
get(Opcode == SystemZ::Return ? SystemZ::CondReturn
816 : SystemZ::CondReturn_XPLINK));
823 if (Opcode == SystemZ::CallJG) {
825 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
828 MI.setDesc(
get(SystemZ::CallBRCL));
837 if (Opcode == SystemZ::CallBR) {
839 const uint32_t *RegMask =
MI.getOperand(1).getRegMask();
842 MI.setDesc(
get(SystemZ::CallBCR));
858 bool RenamableSrc)
const {
862 if (SystemZ::GR128BitRegClass.
contains(DestReg, SrcReg)) {
864 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
868 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
874 if (SystemZ::GRX32BitRegClass.
contains(DestReg, SrcReg)) {
875 emitGRX32Move(
MBB,
MBBI,
DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
881 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
882 SystemZ::FP128BitRegClass.
contains(SrcReg)) {
884 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
885 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
887 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
888 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
895 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
896 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
898 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
899 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
901 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
902 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
904 if (DestRegHi != SrcReg.
asMCReg())
911 if (SystemZ::FP128BitRegClass.
contains(DestReg) &&
912 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
913 MCRegister DestRegHi = RI.getSubReg(DestReg, SystemZ::subreg_h64);
914 MCRegister DestRegLo = RI.getSubReg(DestReg, SystemZ::subreg_l64);
915 MCRegister SrcRegHi = RI.getSubReg(SrcReg, SystemZ::subreg_h64);
916 MCRegister SrcRegLo = RI.getSubReg(SrcReg, SystemZ::subreg_l64);
928 if (DestReg == SystemZ::CC) {
930 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
937 if (SystemZ::GR128BitRegClass.
contains(DestReg) &&
938 SystemZ::VR128BitRegClass.
contains(SrcReg)) {
939 MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64);
940 MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64);
944 .
addReg(SystemZ::NoRegister)
949 .
addReg(SystemZ::NoRegister)
954 if (SystemZ::VR128BitRegClass.
contains(DestReg) &&
955 SystemZ::GR128BitRegClass.
contains(SrcReg)) {
957 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64))
958 .
addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64));
964 if (SystemZ::GR64BitRegClass.
contains(DestReg, SrcReg))
965 Opcode = SystemZ::LGR;
966 else if (SystemZ::FP16BitRegClass.
contains(DestReg, SrcReg))
967 Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
968 else if (SystemZ::FP32BitRegClass.
contains(DestReg, SrcReg))
970 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
971 else if (SystemZ::FP64BitRegClass.
contains(DestReg, SrcReg))
972 Opcode = SystemZ::LDR;
973 else if (SystemZ::FP128BitRegClass.
contains(DestReg, SrcReg))
974 Opcode = SystemZ::LXR;
975 else if (SystemZ::VR16BitRegClass.
contains(DestReg, SrcReg))
976 Opcode = SystemZ::VLR16;
977 else if (SystemZ::VR32BitRegClass.
contains(DestReg, SrcReg))
978 Opcode = SystemZ::VLR32;
979 else if (SystemZ::VR64BitRegClass.
contains(DestReg, SrcReg))
980 Opcode = SystemZ::VLR64;
981 else if (SystemZ::VR128BitRegClass.
contains(DestReg, SrcReg))
982 Opcode = SystemZ::VLR;
983 else if (SystemZ::AR32BitRegClass.
contains(DestReg, SrcReg))
984 Opcode = SystemZ::CPYA;
985 else if (SystemZ::GR64BitRegClass.
contains(DestReg) &&
986 SystemZ::FP64BitRegClass.
contains(SrcReg))
987 Opcode = SystemZ::LGDR;
988 else if (SystemZ::FP64BitRegClass.
contains(DestReg) &&
989 SystemZ::GR64BitRegClass.
contains(SrcReg))
990 Opcode = SystemZ::LDGR;
1007 unsigned LoadOpcode, StoreOpcode;
1024 unsigned LoadOpcode, StoreOpcode;
1034 return ((
MCID.TSFlags & Flag) &&
1036 MI->getOperand(3).getReg() == 0);
1042 LogicOp() =
default;
1043 LogicOp(
unsigned regSize,
unsigned immLSB,
unsigned immSize)
1044 :
RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1046 explicit operator bool()
const {
return RegSize; }
1049 unsigned ImmLSB = 0;
1050 unsigned ImmSize = 0;
1057 case SystemZ::NILMux:
return LogicOp(32, 0, 16);
1058 case SystemZ::NIHMux:
return LogicOp(32, 16, 16);
1059 case SystemZ::NILL64:
return LogicOp(64, 0, 16);
1060 case SystemZ::NILH64:
return LogicOp(64, 16, 16);
1061 case SystemZ::NIHL64:
return LogicOp(64, 32, 16);
1062 case SystemZ::NIHH64:
return LogicOp(64, 48, 16);
1063 case SystemZ::NIFMux:
return LogicOp(32, 0, 32);
1064 case SystemZ::NILF64:
return LogicOp(64, 0, 32);
1065 case SystemZ::NIHF64:
return LogicOp(64, 32, 32);
1066 default:
return LogicOp();
1074 if (CCDef !=
nullptr)
1096 unsigned Start, End;
1099 if (
And.RegSize == 64) {
1100 NewOpcode = SystemZ::RISBG;
1102 if (STI.hasMiscellaneousExtensions())
1103 NewOpcode = SystemZ::RISBGN;
1105 NewOpcode = SystemZ::RISBMux;
1121 unsigned NumOps =
MI.getNumOperands();
1124 if (
Op.isReg() &&
Op.isKill())
1138 bool Invert)
const {
1144 Opc = *InverseOpcode;
1151 case SystemZ::WFADB:
1152 case SystemZ::WFASB:
1153 case SystemZ::WFAXB:
1154 case SystemZ::VFADB:
1155 case SystemZ::VFASB:
1156 case SystemZ::WFMDB:
1157 case SystemZ::WFMSB:
1158 case SystemZ::WFMXB:
1159 case SystemZ::VFMDB:
1160 case SystemZ::VFMSB:
1168std::optional<unsigned>
1172 case SystemZ::WFADB:
1173 return SystemZ::WFSDB;
1174 case SystemZ::WFASB:
1175 return SystemZ::WFSSB;
1176 case SystemZ::WFAXB:
1177 return SystemZ::WFSXB;
1178 case SystemZ::VFADB:
1179 return SystemZ::VFSDB;
1180 case SystemZ::VFASB:
1181 return SystemZ::VFSSB;
1183 case SystemZ::WFSDB:
1184 return SystemZ::WFADB;
1185 case SystemZ::WFSSB:
1186 return SystemZ::WFASB;
1187 case SystemZ::WFSXB:
1188 return SystemZ::WFAXB;
1189 case SystemZ::VFSDB:
1190 return SystemZ::VFADB;
1191 case SystemZ::VFSSB:
1192 return SystemZ::VFASB;
1194 return std::nullopt;
1207 unsigned Opcode =
MI.getOpcode();
1212 bool CCLiveAtMI =
true;
1217 CCLiveRange = &LIS->
getRegUnit(*CCUnits.begin());
1218 CCLiveAtMI = CCLiveRange->
liveAt(MISlot);
1221 if (
Ops.size() == 2 &&
Ops[0] == 0 &&
Ops[1] == 1) {
1222 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1223 isInt<8>(
MI.getOperand(2).getImm()) && !
MI.getOperand(3).getReg()) {
1226 MI.getDebugLoc(),
get(SystemZ::AGSI))
1229 .
addImm(
MI.getOperand(2).getImm());
1239 if (
Ops.size() != 1)
1242 unsigned OpNum =
Ops[0];
1246 (RC == &SystemZ::FP16BitRegClass &&
Size == 4 && !STI.hasVector())) &&
1247 "Invalid size combination");
1250 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1253 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1255 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1258 .
addImm(
MI.getOperand(2).getImm());
1264 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1265 isInt<8>((int32_t)
MI.getOperand(2).getImm())) ||
1266 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1269 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1271 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1274 .
addImm((int8_t)
MI.getOperand(2).getImm());
1279 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1280 isInt<8>((int32_t)-
MI.getOperand(2).getImm())) ||
1281 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1284 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1286 BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
get(Opcode))
1289 .
addImm((int8_t)-
MI.getOperand(2).getImm());
1294 unsigned MemImmOpc = 0;
1296 case SystemZ::LHIMux:
1297 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI;
break;
1298 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI;
break;
1299 case SystemZ::CHIMux:
1300 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI;
break;
1301 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI;
break;
1302 case SystemZ::CLFIMux:
1305 MemImmOpc = SystemZ::CLFHSI;
1307 case SystemZ::CLGFI:
1309 MemImmOpc = SystemZ::CLGHSI;
1314 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1318 .
addImm(
MI.getOperand(1).getImm());
1320 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1321 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1322 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1326 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1327 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1329 .
add(
MI.getOperand(1))
1337 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1338 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1340 .
add(
MI.getOperand(0))
1360 if (OpNum == 0 &&
MI.hasOneMemOperand()) {
1365 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1370 .
add(
MI.getOperand(1))
1376 return BuildMI(*InsertPt->getParent(), InsertPt,
MI.getDebugLoc(),
1378 .
add(
MI.getOperand(1))
1391 unsigned NumOps =
MI.getNumExplicitOperands();
1392 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1393 if (MemOpcode == -1 ||
1394 (CCLiveAtMI && !
MI.definesRegister(SystemZ::CC,
nullptr) &&
1395 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1401 for (
unsigned I = 0, E =
MCID.getNumOperands();
I != E; ++
I) {
1406 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1412 !(SystemZ::FP32BitRegClass.
contains(PhysReg) ||
1413 SystemZ::FP64BitRegClass.
contains(PhysReg) ||
1414 SystemZ::VF128BitRegClass.
contains(PhysReg)))
1419 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1420 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1424 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1429 bool NeedsCommute =
false;
1430 if ((
MI.getOpcode() == SystemZ::CR ||
MI.getOpcode() == SystemZ::CGR ||
1431 MI.getOpcode() == SystemZ::CLR ||
MI.getOpcode() == SystemZ::CLGR ||
1432 MI.getOpcode() == SystemZ::WFCDB ||
MI.getOpcode() == SystemZ::WFCSB ||
1433 MI.getOpcode() == SystemZ::WFKDB ||
MI.getOpcode() == SystemZ::WFKSB) &&
1435 NeedsCommute =
true;
1437 bool CCOperands =
false;
1438 if (
MI.getOpcode() == SystemZ::LOCRMux ||
MI.getOpcode() == SystemZ::LOCGR ||
1439 MI.getOpcode() == SystemZ::SELRMux ||
MI.getOpcode() == SystemZ::SELGR) {
1441 "LOCR/SELR instruction operands corrupt?");
1457 : ((OpNum == 1 &&
MI.isCommutable())
1458 ?
MI.getOperand(2).getReg()
1460 if (DstPhys && !SystemZ::GRH32BitRegClass.
contains(DstPhys) && SrcReg &&
1462 NeedsCommute = (OpNum == 1);
1468 if ((OpNum ==
NumOps - 1) || NeedsCommute || FusedFPOp) {
1471 assert(AccessBytes != 0 &&
"Size of access should be known");
1472 assert(AccessBytes <=
Size &&
"Access outside the frame index");
1475 MI.getDebugLoc(),
get(MemOpcode));
1476 if (
MI.isCompare()) {
1477 assert(
NumOps == 2 &&
"Expected 2 register operands for a compare.");
1478 MIB.
add(
MI.getOperand(NeedsCommute ? 1 : 0));
1480 else if (FusedFPOp) {
1481 MIB.
add(
MI.getOperand(0));
1482 MIB.
add(
MI.getOperand(3));
1483 MIB.
add(
MI.getOperand(OpNum == 1 ? 2 : 1));
1486 MIB.
add(
MI.getOperand(0));
1488 MIB.
add(
MI.getOperand(2));
1490 for (
unsigned I = 1;
I < OpNum; ++
I)
1491 MIB.
add(
MI.getOperand(
I));
1497 unsigned CCValid =
MI.getOperand(
NumOps).getImm();
1498 unsigned CCMask =
MI.getOperand(
NumOps + 1).getImm();
1500 MIB.
addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1503 (!
MI.definesRegister(SystemZ::CC,
nullptr) ||
1504 MI.registerDefIsDead(SystemZ::CC,
nullptr))) {
1512 if (MO.isReg() && MO.getReg().isVirtual()) {
1514 if (MRI.
getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1516 else if (MRI.
getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1518 else if (MRI.
getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1545 unsigned LoadOpc = 0;
1546 unsigned RegMemOpcode = 0;
1548 RegMemOpcode =
MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1549 :
MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1550 :
MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1553 LoadOpc = SystemZ::VL64;
1554 FPRC = &SystemZ::FP64BitRegClass;
1556 RegMemOpcode =
MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1557 :
MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1558 :
MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1561 LoadOpc = SystemZ::VL32;
1562 FPRC = &SystemZ::FP32BitRegClass;
1565 if (!RegMemOpcode || LoadMI.
getOpcode() != LoadOpc)
1569 if (
get(RegMemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)) {
1571 if (MII ==
MBB->begin()) {
1572 if (
MBB->isLiveIn(SystemZ::CC))
1577 if (MII->definesRegister(SystemZ::CC,
nullptr)) {
1578 if (!MII->registerDefIsDead(SystemZ::CC,
nullptr))
1586 if (
Ops.size() != 1 || FoldAsLoadDefReg !=
MI.getOperand(
Ops[0]).getReg())
1592 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1593 FoldAsLoadDefReg != RHS.getReg())
1602 BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(RegMemOpcode), DstReg)
1616 switch (
MI.getOpcode()) {
1618 splitMove(
MI, SystemZ::LG);
1621 case SystemZ::ST128:
1622 splitMove(
MI, SystemZ::STG);
1626 splitMove(
MI, SystemZ::LD);
1630 splitMove(
MI, SystemZ::STD);
1633 case SystemZ::LBMux:
1634 expandRXYPseudo(
MI, SystemZ::LB, SystemZ::LBH);
1637 case SystemZ::LHMux:
1638 expandRXYPseudo(
MI, SystemZ::LH, SystemZ::LHH);
1641 case SystemZ::LLCRMux:
1642 expandZExtPseudo(
MI, SystemZ::LLCR, 8);
1645 case SystemZ::LLHRMux:
1646 expandZExtPseudo(
MI, SystemZ::LLHR, 16);
1649 case SystemZ::LLCMux:
1650 expandRXYPseudo(
MI, SystemZ::LLC, SystemZ::LLCH);
1653 case SystemZ::LLHMux:
1654 expandRXYPseudo(
MI, SystemZ::LLH, SystemZ::LLHH);
1658 expandRXYPseudo(
MI, SystemZ::L, SystemZ::LFH);
1661 case SystemZ::LOCMux:
1662 expandLOCPseudo(
MI, SystemZ::LOC, SystemZ::LOCFH);
1665 case SystemZ::LOCHIMux:
1666 expandLOCPseudo(
MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1669 case SystemZ::STCMux:
1670 expandRXYPseudo(
MI, SystemZ::STC, SystemZ::STCH);
1673 case SystemZ::STHMux:
1674 expandRXYPseudo(
MI, SystemZ::STH, SystemZ::STHH);
1677 case SystemZ::STMux:
1678 expandRXYPseudo(
MI, SystemZ::ST, SystemZ::STFH);
1681 case SystemZ::STOCMux:
1682 expandLOCPseudo(
MI, SystemZ::STOC, SystemZ::STOCFH);
1685 case SystemZ::LHIMux:
1686 expandRIPseudo(
MI, SystemZ::LHI, SystemZ::IIHF,
true);
1689 case SystemZ::IIFMux:
1690 expandRIPseudo(
MI, SystemZ::IILF, SystemZ::IIHF,
false);
1693 case SystemZ::IILMux:
1694 expandRIPseudo(
MI, SystemZ::IILL, SystemZ::IIHL,
false);
1697 case SystemZ::IIHMux:
1698 expandRIPseudo(
MI, SystemZ::IILH, SystemZ::IIHH,
false);
1701 case SystemZ::NIFMux:
1702 expandRIPseudo(
MI, SystemZ::NILF, SystemZ::NIHF,
false);
1705 case SystemZ::NILMux:
1706 expandRIPseudo(
MI, SystemZ::NILL, SystemZ::NIHL,
false);
1709 case SystemZ::NIHMux:
1710 expandRIPseudo(
MI, SystemZ::NILH, SystemZ::NIHH,
false);
1713 case SystemZ::OIFMux:
1714 expandRIPseudo(
MI, SystemZ::OILF, SystemZ::OIHF,
false);
1717 case SystemZ::OILMux:
1718 expandRIPseudo(
MI, SystemZ::OILL, SystemZ::OIHL,
false);
1721 case SystemZ::OIHMux:
1722 expandRIPseudo(
MI, SystemZ::OILH, SystemZ::OIHH,
false);
1725 case SystemZ::XIFMux:
1726 expandRIPseudo(
MI, SystemZ::XILF, SystemZ::XIHF,
false);
1729 case SystemZ::TMLMux:
1730 expandRIPseudo(
MI, SystemZ::TMLL, SystemZ::TMHL,
false);
1733 case SystemZ::TMHMux:
1734 expandRIPseudo(
MI, SystemZ::TMLH, SystemZ::TMHH,
false);
1737 case SystemZ::AHIMux:
1738 expandRIPseudo(
MI, SystemZ::AHI, SystemZ::AIH,
false);
1741 case SystemZ::AHIMuxK:
1742 expandRIEPseudo(
MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1745 case SystemZ::AFIMux:
1746 expandRIPseudo(
MI, SystemZ::AFI, SystemZ::AIH,
false);
1749 case SystemZ::CHIMux:
1750 expandRIPseudo(
MI, SystemZ::CHI, SystemZ::CIH,
false);
1753 case SystemZ::CFIMux:
1754 expandRIPseudo(
MI, SystemZ::CFI, SystemZ::CIH,
false);
1757 case SystemZ::CLFIMux:
1758 expandRIPseudo(
MI, SystemZ::CLFI, SystemZ::CLIH,
false);
1762 expandRXYPseudo(
MI, SystemZ::C, SystemZ::CHF);
1765 case SystemZ::CLMux:
1766 expandRXYPseudo(
MI, SystemZ::CL, SystemZ::CLHF);
1769 case SystemZ::RISBMux: {
1772 if (SrcIsHigh == DestIsHigh)
1773 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1775 MI.setDesc(
get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1776 MI.getOperand(5).setImm(
MI.getOperand(5).getImm() ^ 32);
1781 case SystemZ::ADJDYNALLOC:
1782 splitAdjDynAlloc(
MI);
1785 case SystemZ::MOV_STACKGUARD:
1786 expandStackGuardPseudo(
MI, SystemZ::MVC);
1789 case SystemZ::CMP_STACKGUARD:
1790 expandStackGuardPseudo(
MI, SystemZ::CLC);
1799 unsigned Opcode)
const {
1802 const auto DL =
MI.getDebugLoc();
1804 StringRef GuardType = M->getStackProtectorGuard();
1807 Register AddrReg =
MI.getOperand(0).getReg();
1810 AddrReg !=
MI.getOperand(1).getReg() &&
1811 "Scratch register for stack guard address blocked by operand register.");
1815 if (GuardType.
empty() || (GuardType ==
"tls")) {
1817 enum { OFFSET_PSALAA = 0x4B8 };
1818 enum { OFFSET_CEELAA_STACK_GUARD = 0x98 };
1825 Offset = OFFSET_CEELAA_STACK_GUARD;
1832 }
else if (GuardType ==
"global") {
1849 MI.removeFromParent();
1853 if (
MI.isInlineAsm()) {
1855 const char *AsmStr =
MI.getOperand(0).getSymbolName();
1858 else if (
MI.getOpcode() == SystemZ::PATCHPOINT)
1860 else if (
MI.getOpcode() == SystemZ::STACKMAP)
1861 return MI.getOperand(1).getImm();
1862 else if (
MI.getOpcode() == SystemZ::FENTRY_CALL)
1864 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)
1866 if (
MI.getOpcode() == TargetOpcode::PATCHABLE_RET)
1867 return 18 + (
MI.getOperand(0).
getImm() == SystemZ::CondReturn ? 4 : 0);
1868 if (
MI.getOpcode() == TargetOpcode::BUNDLE)
1869 return getInstBundleSize(
MI);
1870 if (
MI.getOpcode() == SystemZ::LOAD_TLS_BLOCK_ADDR)
1873 if (
MI.getOpcode() == SystemZ::LOAD_GLOBAL_STACKGUARD_ADDR)
1877 return MI.getDesc().getSize();
1882 switch (
MI.getOpcode()) {
1893 MI.getOperand(1).getImm(), &
MI.getOperand(2));
1896 case SystemZ::BRCTH:
1900 case SystemZ::BRCTG:
1907 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1912 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1917 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1919 case SystemZ::CLGIJ:
1920 case SystemZ::CLGRJ:
1922 MI.getOperand(2).getImm(), &
MI.getOperand(3));
1924 case SystemZ::INLINEASM_BR:
1934 unsigned &LoadOpcode,
1935 unsigned &StoreOpcode)
const {
1936 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1937 LoadOpcode = SystemZ::L;
1938 StoreOpcode = SystemZ::ST;
1939 }
else if (RC == &SystemZ::GRH32BitRegClass) {
1940 LoadOpcode = SystemZ::LFH;
1941 StoreOpcode = SystemZ::STFH;
1942 }
else if (RC == &SystemZ::GRX32BitRegClass) {
1943 LoadOpcode = SystemZ::LMux;
1944 StoreOpcode = SystemZ::STMux;
1945 }
else if (RC == &SystemZ::GR64BitRegClass ||
1946 RC == &SystemZ::ADDR64BitRegClass) {
1947 LoadOpcode = SystemZ::LG;
1948 StoreOpcode = SystemZ::STG;
1949 }
else if (RC == &SystemZ::GR128BitRegClass ||
1950 RC == &SystemZ::ADDR128BitRegClass) {
1951 LoadOpcode = SystemZ::L128;
1952 StoreOpcode = SystemZ::ST128;
1953 }
else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
1954 LoadOpcode = SystemZ::LE16;
1955 StoreOpcode = SystemZ::STE16;
1956 }
else if (RC == &SystemZ::FP32BitRegClass) {
1957 LoadOpcode = SystemZ::LE;
1958 StoreOpcode = SystemZ::STE;
1959 }
else if (RC == &SystemZ::FP64BitRegClass) {
1960 LoadOpcode = SystemZ::LD;
1961 StoreOpcode = SystemZ::STD;
1962 }
else if (RC == &SystemZ::FP128BitRegClass) {
1963 LoadOpcode = SystemZ::LX;
1964 StoreOpcode = SystemZ::STX;
1965 }
else if (RC == &SystemZ::FP16BitRegClass ||
1966 RC == &SystemZ::VR16BitRegClass) {
1967 LoadOpcode = SystemZ::VL16;
1968 StoreOpcode = SystemZ::VST16;
1969 }
else if (RC == &SystemZ::VR32BitRegClass) {
1970 LoadOpcode = SystemZ::VL32;
1971 StoreOpcode = SystemZ::VST32;
1972 }
else if (RC == &SystemZ::VR64BitRegClass) {
1973 LoadOpcode = SystemZ::VL64;
1974 StoreOpcode = SystemZ::VST64;
1975 }
else if (RC == &SystemZ::VF128BitRegClass ||
1976 RC == &SystemZ::VR128BitRegClass) {
1977 LoadOpcode = SystemZ::VL;
1978 StoreOpcode = SystemZ::VST;
1990 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1991 if (Disp12Opcode >= 0)
1992 return Disp12Opcode;
2000 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
2001 if (Disp20Opcode >= 0)
2002 return Disp20Opcode;
2009 if (
MI &&
MI->getOperand(0).isReg()) {
2014 return SystemZ::LEY;
2015 case SystemZ::VST32:
2016 return SystemZ::STEY;
2018 return SystemZ::LDY;
2019 case SystemZ::VST64:
2020 return SystemZ::STDY;
2032 return SystemZ::getDisp12Opcode(Opcode) >= 0;
2033 return SystemZ::getDisp20Opcode(Opcode) >= 0;
2038 case SystemZ::L:
return SystemZ::LT;
2039 case SystemZ::LY:
return SystemZ::LT;
2040 case SystemZ::LG:
return SystemZ::LTG;
2041 case SystemZ::LGF:
return SystemZ::LTGF;
2042 case SystemZ::LR:
return SystemZ::LTR;
2043 case SystemZ::LGFR:
return SystemZ::LTGFR;
2044 case SystemZ::LGR:
return SystemZ::LTGR;
2045 case SystemZ::LCDFR:
return SystemZ::LCDBR;
2046 case SystemZ::LPDFR:
return SystemZ::LPDBR;
2047 case SystemZ::LNDFR:
return SystemZ::LNDBR;
2048 case SystemZ::LCDFR_32:
return SystemZ::LCEBR;
2049 case SystemZ::LPDFR_32:
return SystemZ::LPEBR;
2050 case SystemZ::LNDFR_32:
return SystemZ::LNEBR;
2055 case SystemZ::RISBGN:
return SystemZ::RISBG;
2061 unsigned &Start,
unsigned &End)
const {
2071 Start = 63 - (LSB +
Length - 1);
2079 assert(LSB > 0 &&
"Bottom bit must be set");
2080 assert(LSB +
Length < BitSize &&
"Top bit must be set");
2081 Start = 63 - (LSB - 1);
2082 End = 63 - (LSB +
Length);
2099 case SystemZ::CLGFI:
2105 if (!STI.hasMiscellaneousExtensions())
2107 if (!(
MI &&
MI->getOperand(3).getReg() == 0))
2115 return SystemZ::CRJ;
2117 return SystemZ::CGRJ;
2119 return SystemZ::CIJ;
2121 return SystemZ::CGIJ;
2123 return SystemZ::CLRJ;
2125 return SystemZ::CLGRJ;
2127 return SystemZ::CLIJ;
2128 case SystemZ::CLGFI:
2129 return SystemZ::CLGIJ;
2136 return SystemZ::CRBReturn;
2138 return SystemZ::CGRBReturn;
2140 return SystemZ::CIBReturn;
2142 return SystemZ::CGIBReturn;
2144 return SystemZ::CLRBReturn;
2146 return SystemZ::CLGRBReturn;
2148 return SystemZ::CLIBReturn;
2149 case SystemZ::CLGFI:
2150 return SystemZ::CLGIBReturn;
2157 return SystemZ::CRBCall;
2159 return SystemZ::CGRBCall;
2161 return SystemZ::CIBCall;
2163 return SystemZ::CGIBCall;
2165 return SystemZ::CLRBCall;
2167 return SystemZ::CLGRBCall;
2169 return SystemZ::CLIBCall;
2170 case SystemZ::CLGFI:
2171 return SystemZ::CLGIBCall;
2178 return SystemZ::CRT;
2180 return SystemZ::CGRT;
2182 return SystemZ::CIT;
2184 return SystemZ::CGIT;
2186 return SystemZ::CLRT;
2188 return SystemZ::CLGRT;
2190 return SystemZ::CLFIT;
2191 case SystemZ::CLGFI:
2192 return SystemZ::CLGIT;
2194 return SystemZ::CLT;
2196 return SystemZ::CLGT;
2207 return (
MI.getOpcode() == SystemZ::LTEBR ||
2208 MI.getOpcode() == SystemZ::LTDBR ||
2209 MI.getOpcode() == SystemZ::LTXBR) &&
2210 MI.getOperand(0).isDead();
2216 return Compare.isCompare() && Compare.getNumExplicitOperands() == 2 &&
2217 Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
2229 MBBI->getOperand(1).isReg() && !
MBBI->mayLoad() &&
2230 "Not a compare reg/reg.");
2236 if (
MI.readsRegister(SystemZ::CC,
nullptr)) {
2237 unsigned Flags =
MI.getDesc().TSFlags;
2243 if (
MI.definesRegister(SystemZ::CC,
nullptr)) {
2251 if (!
LiveRegs.available(SystemZ::CC))
2256 for (
unsigned Idx = 0; Idx < CCUsers.
size(); ++Idx) {
2257 unsigned Flags = CCUsers[Idx]->getDesc().TSFlags;
2259 0 : CCUsers[Idx]->getNumExplicitOperands() - 2);
2260 MachineOperand &CCMaskMO = CCUsers[Idx]->getOperand(FirstOpNum + 1);
2262 CCMaskMO.
setImm(NewCCMask);
2300 if (!STI.hasLoadAndTrap())
2305 return SystemZ::LAT;
2307 return SystemZ::LGAT;
2309 return SystemZ::LFHAT;
2311 return SystemZ::LLGFAT;
2313 return SystemZ::LLGTAT;
2322 unsigned Opcode = 0;
2324 Opcode = SystemZ::LGHI;
2326 Opcode = SystemZ::LLILL;
2328 Opcode = SystemZ::LLILH;
2332 Opcode = SystemZ::LGFI;
2339 assert (MRI.
isSSA() &&
"Huge values only handled before reg-alloc .");
2352 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
2353 if (
I >=
MCID.getNumOperands())
2361 ((
MCOI.RegClass != -1 && !
Op.isReg() && !
Op.isFI()) ||
2362 (
MCOI.RegClass == -1 && !
Op.isImm()))) {
2363 ErrInfo =
"Addressing mode operands corrupt!";
2386 bool SameVal = (VALa && VALb && (VALa == VALb));
2390 if (PSVa && PSVb && (PSVa == PSVb))
2396 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2397 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2398 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2400 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
2409 int64_t &ImmVal)
const {
2411 if (
MI.getOpcode() == SystemZ::VGBM && Reg ==
MI.getOperand(0).getReg()) {
2412 ImmVal =
MI.getOperand(1).getImm();
2420std::optional<DestSourcePair>
2426 return std::nullopt;
2429std::pair<unsigned, unsigned>
2431 return std::make_pair(TF, 0u);
2438 static const std::pair<unsigned, const char *> TargetFlags[] = {
2439 {MO_GOT,
"systemz-got"},
2440 {MO_INDNTPOFF,
"systemz-indntpoff"},
2441 {MO_ADA_DATA_SYMBOL_ADDR,
"systemz-ada-datasymboladdr"},
2442 {MO_ADA_INDIRECT_FUNC_DESC,
"systemz-ada-indirectfuncdesc"},
2443 {MO_ADA_DIRECT_FUNC_DESC,
"systemz-ada-directfuncdesc"}};
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
DXIL Forward Handle Accesses
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.
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
LLVM_ABI VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
A set of register units used to track register liveness.
LLVM_ABI void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
TypeSize getValue() const
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
This holds information about one operand of a machine instruction, indicating the register class for ...
Wrapper class representing physical registers. Should be passed by value.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
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
unsigned getLoadAndTrap(unsigned Opcode) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
unsigned getLoadAndTest(unsigned Opcode) const
MCInst getNop() const override
bool isPredicable(const MachineInstr &MI) const override
Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const override
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset, const MachineInstr *MI=nullptr) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg, int64_t &ImmVal) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool hasDisplacementPairInsn(unsigned Opcode) const
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned CommuteOpIdx1, unsigned CommuteOpIdx2) const override
Commutes the operands in the given instruction by changing the operands order and/or changing the ins...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
bool isCompareZero(const MachineInstr &Compare) const
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool isLoadAndTestAsCmp(const MachineInstr &MI) const
unsigned getFusedCompare(unsigned Opcode, SystemZII::FusedCompareType Type, const MachineInstr *MI=nullptr) const
bool expandPostRAPseudo(MachineInstr &MBBI) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode) const
bool isRxSBGMask(uint64_t Mask, unsigned BitSize, unsigned &Start, unsigned &End) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
Register getCompareSourceReg(const MachineInstr &Compare) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
SystemZInstrInfo(const SystemZSubtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned Reg, uint64_t Value) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getAccessSize(unsigned int Flags)
unsigned getFirstReg(unsigned Reg)
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_CMP_GT
const unsigned CCMASK_ANY
static bool isImmLL(uint64_t Val)
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_CMP_EQ
const unsigned CCMASK_ICMP
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
int32_t getTargetMemOpcode(uint32_t Opcode)
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
bool isHighReg(unsigned int Reg)
const unsigned CCMASK_CMP_UO
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
constexpr RegState getKillRegState(bool B)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
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)