aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp112
1 files changed, 80 insertions, 32 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index a6fb5ab0ee9e..ae6ca55a3609 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -61,7 +61,8 @@ void SystemZInstrInfo::anchor() {}
SystemZInstrInfo::SystemZInstrInfo(SystemZSubtarget &sti)
: SystemZGenInstrInfo(-1, -1),
- RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister()),
+ RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister(),
+ sti.getHwMode()),
STI(sti) {}
// MI is a 128-bit load or store. Split it into two 64-bit loads or stores,
@@ -346,6 +347,52 @@ Register SystemZInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore);
}
+Register SystemZInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,
+ int &FrameIndex) const {
+ // if this is not a simple load from memory, it's not a load from stack slot
+ // either.
+ const MCInstrDesc &MCID = MI.getDesc();
+ if (!(MCID.TSFlags & SystemZII::SimpleBDXLoad))
+ return 0;
+
+ // This version of isLoadFromStackSlot should only be used post frame-index
+ // elimination.
+ assert(!MI.getOperand(1).isFI());
+
+ // Now attempt to derive frame index from MachineMemOperands.
+ SmallVector<const MachineMemOperand *, 1> Accesses;
+ if (hasLoadFromStackSlot(MI, Accesses)) {
+ FrameIndex =
+ cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
+ ->getFrameIndex();
+ return MI.getOperand(0).getReg();
+ }
+ return 0;
+}
+
+Register SystemZInstrInfo::isStoreToStackSlotPostFE(const MachineInstr &MI,
+ int &FrameIndex) const {
+ // if this is not a simple store to memory, it's not a store to stack slot
+ // either.
+ const MCInstrDesc &MCID = MI.getDesc();
+ if (!(MCID.TSFlags & SystemZII::SimpleBDXStore))
+ return 0;
+
+ // This version of isStoreToStackSlot should only be used post frame-index
+ // elimination.
+ assert(!MI.getOperand(1).isFI());
+
+ // Now attempt to derive frame index from MachineMemOperands.
+ SmallVector<const MachineMemOperand *, 1> Accesses;
+ if (hasStoreToStackSlot(MI, Accesses)) {
+ FrameIndex =
+ cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
+ ->getFrameIndex();
+ return MI.getOperand(0).getReg();
+ }
+ return 0;
+}
+
bool SystemZInstrInfo::isStackSlotCopy(const MachineInstr &MI,
int &DestFrameIndex,
int &SrcFrameIndex) const {
@@ -624,31 +671,6 @@ void SystemZInstrInfo::insertSelect(MachineBasicBlock &MBB,
.addImm(CCValid).addImm(CCMask);
}
-MachineInstr *SystemZInstrInfo::optimizeLoadInstr(MachineInstr &MI,
- const MachineRegisterInfo *MRI,
- Register &FoldAsLoadDefReg,
- MachineInstr *&DefMI) const {
- // Check whether we can move the DefMI load, and that it only has one use.
- DefMI = MRI->getVRegDef(FoldAsLoadDefReg);
- assert(DefMI);
- bool SawStore = false;
- if (!DefMI->isSafeToMove(SawStore) || !MRI->hasOneNonDBGUse(FoldAsLoadDefReg))
- return nullptr;
-
- int UseOpIdx =
- MI.findRegisterUseOperandIdx(FoldAsLoadDefReg, /*TRI=*/nullptr);
- assert(UseOpIdx != -1 && "Expected FoldAsLoadDefReg to be used by MI.");
-
- // Check whether we can fold the load.
- if (MachineInstr *FoldMI =
- foldMemoryOperand(MI, {((unsigned)UseOpIdx)}, *DefMI)) {
- FoldAsLoadDefReg = 0;
- return FoldMI;
- }
-
- return nullptr;
-}
-
bool SystemZInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
Register Reg,
MachineRegisterInfo *MRI) const {
@@ -857,8 +879,8 @@ bool SystemZInstrInfo::PredicateInstruction(
void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
- const DebugLoc &DL, MCRegister DestReg,
- MCRegister SrcReg, bool KillSrc,
+ const DebugLoc &DL, Register DestReg,
+ Register SrcReg, bool KillSrc,
bool RenamableDest,
bool RenamableSrc) const {
// Split 128-bit GPR moves into two 64-bit moves. Add implicit uses of the
@@ -906,7 +928,7 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
- if (DestRegHi != SrcReg)
+ if (DestRegHi != SrcReg.asMCReg())
copyPhysReg(MBB, MBBI, DL, DestRegHi, SrcReg, false);
BuildMI(MBB, MBBI, DL, get(SystemZ::VREPG), DestRegLo)
.addReg(SrcReg, getKillRegState(KillSrc)).addImm(1);
@@ -968,6 +990,8 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
unsigned Opcode;
if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg))
Opcode = SystemZ::LGR;
+ else if (SystemZ::FP16BitRegClass.contains(DestReg, SrcReg))
+ Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg))
// For z13 we prefer LDR over LER to avoid partial register dependencies.
Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
@@ -983,6 +1007,12 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Opcode = SystemZ::VLR;
else if (SystemZ::AR32BitRegClass.contains(DestReg, SrcReg))
Opcode = SystemZ::CPYA;
+ else if (SystemZ::GR64BitRegClass.contains(DestReg) &&
+ SystemZ::FP64BitRegClass.contains(SrcReg))
+ Opcode = SystemZ::LGDR;
+ else if (SystemZ::FP64BitRegClass.contains(DestReg) &&
+ SystemZ::GR64BitRegClass.contains(SrcReg))
+ Opcode = SystemZ::LDGR;
else
llvm_unreachable("Impossible reg-to-reg copy");
@@ -1232,10 +1262,12 @@ MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl(
return nullptr;
unsigned OpNum = Ops[0];
- assert(Size * 8 ==
- TRI->getRegSizeInBits(*MF.getRegInfo()
- .getRegClass(MI.getOperand(OpNum).getReg())) &&
+ const TargetRegisterClass *RC =
+ MF.getRegInfo().getRegClass(MI.getOperand(OpNum).getReg());
+ assert((Size * 8 == TRI->getRegSizeInBits(*RC) ||
+ (RC == &SystemZ::FP16BitRegClass && Size == 4 && !STI.hasVector())) &&
"Invalid size combination");
+ (void)RC;
if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
isInt<8>(MI.getOperand(2).getImm())) {
@@ -1873,6 +1905,9 @@ void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,
RC == &SystemZ::ADDR128BitRegClass) {
LoadOpcode = SystemZ::L128;
StoreOpcode = SystemZ::ST128;
+ } else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
+ LoadOpcode = SystemZ::LE16;
+ StoreOpcode = SystemZ::STE16;
} else if (RC == &SystemZ::FP32BitRegClass) {
LoadOpcode = SystemZ::LE;
StoreOpcode = SystemZ::STE;
@@ -1882,6 +1917,10 @@ void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,
} else if (RC == &SystemZ::FP128BitRegClass) {
LoadOpcode = SystemZ::LX;
StoreOpcode = SystemZ::STX;
+ } else if (RC == &SystemZ::FP16BitRegClass ||
+ RC == &SystemZ::VR16BitRegClass) {
+ LoadOpcode = SystemZ::VL16;
+ StoreOpcode = SystemZ::VST16;
} else if (RC == &SystemZ::VR32BitRegClass) {
LoadOpcode = SystemZ::VL32;
StoreOpcode = SystemZ::VST32;
@@ -2310,3 +2349,12 @@ bool SystemZInstrInfo::getConstValDefinedInReg(const MachineInstr &MI,
return false;
}
+
+std::optional<DestSourcePair>
+SystemZInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
+ // if MI is a simple single-register copy operation, return operand pair
+ if (MI.isMoveReg())
+ return DestSourcePair(MI.getOperand(0), MI.getOperand(1));
+
+ return std::nullopt;
+}