1284c1978SDimitry Andric //===-- SystemZRegisterInfo.cpp - SystemZ register information ------------===//
2284c1978SDimitry Andric //
3284c1978SDimitry Andric // The LLVM Compiler Infrastructure
4284c1978SDimitry Andric //
5284c1978SDimitry Andric // This file is distributed under the University of Illinois Open Source
6284c1978SDimitry Andric // License. See LICENSE.TXT for details.
7284c1978SDimitry Andric //
8284c1978SDimitry Andric //===----------------------------------------------------------------------===//
9284c1978SDimitry Andric
10284c1978SDimitry Andric #include "SystemZRegisterInfo.h"
11db17bf38SDimitry Andric #include "SystemZInstrInfo.h"
1291bc56edSDimitry Andric #include "SystemZSubtarget.h"
132cab237bSDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
142cab237bSDimitry Andric #include "llvm/ADT/SmallSet.h"
15284c1978SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
16284c1978SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
172cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
1991bc56edSDimitry Andric
2091bc56edSDimitry Andric using namespace llvm;
21284c1978SDimitry Andric
22284c1978SDimitry Andric #define GET_REGINFO_TARGET_DESC
23284c1978SDimitry Andric #include "SystemZGenRegisterInfo.inc"
24284c1978SDimitry Andric
SystemZRegisterInfo()2591bc56edSDimitry Andric SystemZRegisterInfo::SystemZRegisterInfo()
2691bc56edSDimitry Andric : SystemZGenRegisterInfo(SystemZ::R14D) {}
27284c1978SDimitry Andric
282cab237bSDimitry Andric // Given that MO is a GRX32 operand, return either GR32 or GRH32 if MO
292cab237bSDimitry Andric // somehow belongs in it. Otherwise, return GRX32.
getRC32(MachineOperand & MO,const VirtRegMap * VRM,const MachineRegisterInfo * MRI)302cab237bSDimitry Andric static const TargetRegisterClass *getRC32(MachineOperand &MO,
312cab237bSDimitry Andric const VirtRegMap *VRM,
322cab237bSDimitry Andric const MachineRegisterInfo *MRI) {
332cab237bSDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(MO.getReg());
342cab237bSDimitry Andric
352cab237bSDimitry Andric if (SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
362cab237bSDimitry Andric MO.getSubReg() == SystemZ::subreg_l32 ||
372cab237bSDimitry Andric MO.getSubReg() == SystemZ::subreg_hl32)
382cab237bSDimitry Andric return &SystemZ::GR32BitRegClass;
392cab237bSDimitry Andric if (SystemZ::GRH32BitRegClass.hasSubClassEq(RC) ||
402cab237bSDimitry Andric MO.getSubReg() == SystemZ::subreg_h32 ||
412cab237bSDimitry Andric MO.getSubReg() == SystemZ::subreg_hh32)
422cab237bSDimitry Andric return &SystemZ::GRH32BitRegClass;
432cab237bSDimitry Andric
442cab237bSDimitry Andric if (VRM && VRM->hasPhys(MO.getReg())) {
452cab237bSDimitry Andric unsigned PhysReg = VRM->getPhys(MO.getReg());
462cab237bSDimitry Andric if (SystemZ::GR32BitRegClass.contains(PhysReg))
472cab237bSDimitry Andric return &SystemZ::GR32BitRegClass;
482cab237bSDimitry Andric assert (SystemZ::GRH32BitRegClass.contains(PhysReg) &&
492cab237bSDimitry Andric "Phys reg not in GR32 or GRH32?");
502cab237bSDimitry Andric return &SystemZ::GRH32BitRegClass;
512cab237bSDimitry Andric }
522cab237bSDimitry Andric
532cab237bSDimitry Andric assert (RC == &SystemZ::GRX32BitRegClass);
542cab237bSDimitry Andric return RC;
552cab237bSDimitry Andric }
562cab237bSDimitry Andric
572cab237bSDimitry Andric bool
getRegAllocationHints(unsigned VirtReg,ArrayRef<MCPhysReg> Order,SmallVectorImpl<MCPhysReg> & Hints,const MachineFunction & MF,const VirtRegMap * VRM,const LiveRegMatrix * Matrix) const582cab237bSDimitry Andric SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg,
592cab237bSDimitry Andric ArrayRef<MCPhysReg> Order,
602cab237bSDimitry Andric SmallVectorImpl<MCPhysReg> &Hints,
612cab237bSDimitry Andric const MachineFunction &MF,
622cab237bSDimitry Andric const VirtRegMap *VRM,
632cab237bSDimitry Andric const LiveRegMatrix *Matrix) const {
642cab237bSDimitry Andric const MachineRegisterInfo *MRI = &MF.getRegInfo();
652cab237bSDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
66*b5893f02SDimitry Andric
67*b5893f02SDimitry Andric bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
68*b5893f02SDimitry Andric VirtReg, Order, Hints, MF, VRM, Matrix);
69*b5893f02SDimitry Andric
702cab237bSDimitry Andric if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {
712cab237bSDimitry Andric SmallVector<unsigned, 8> Worklist;
722cab237bSDimitry Andric SmallSet<unsigned, 4> DoneRegs;
732cab237bSDimitry Andric Worklist.push_back(VirtReg);
742cab237bSDimitry Andric while (Worklist.size()) {
752cab237bSDimitry Andric unsigned Reg = Worklist.pop_back_val();
762cab237bSDimitry Andric if (!DoneRegs.insert(Reg).second)
772cab237bSDimitry Andric continue;
782cab237bSDimitry Andric
792cab237bSDimitry Andric for (auto &Use : MRI->use_instructions(Reg))
802cab237bSDimitry Andric // For LOCRMux, see if the other operand is already a high or low
812cab237bSDimitry Andric // register, and in that case give the correpsonding hints for
822cab237bSDimitry Andric // VirtReg. LOCR instructions need both operands in either high or
832cab237bSDimitry Andric // low parts.
842cab237bSDimitry Andric if (Use.getOpcode() == SystemZ::LOCRMux) {
852cab237bSDimitry Andric MachineOperand &TrueMO = Use.getOperand(1);
862cab237bSDimitry Andric MachineOperand &FalseMO = Use.getOperand(2);
872cab237bSDimitry Andric const TargetRegisterClass *RC =
882cab237bSDimitry Andric TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI),
892cab237bSDimitry Andric getRC32(TrueMO, VRM, MRI));
902cab237bSDimitry Andric if (RC && RC != &SystemZ::GRX32BitRegClass) {
91*b5893f02SDimitry Andric // Pass the registers of RC as hints while making sure that if
92*b5893f02SDimitry Andric // any of these registers are copy hints, hint them first.
93*b5893f02SDimitry Andric SmallSet<unsigned, 4> CopyHints;
94*b5893f02SDimitry Andric CopyHints.insert(Hints.begin(), Hints.end());
95*b5893f02SDimitry Andric Hints.clear();
962cab237bSDimitry Andric for (MCPhysReg Reg : Order)
97*b5893f02SDimitry Andric if (CopyHints.count(Reg) &&
98*b5893f02SDimitry Andric RC->contains(Reg) && !MRI->isReserved(Reg))
99*b5893f02SDimitry Andric Hints.push_back(Reg);
100*b5893f02SDimitry Andric for (MCPhysReg Reg : Order)
101*b5893f02SDimitry Andric if (!CopyHints.count(Reg) &&
102*b5893f02SDimitry Andric RC->contains(Reg) && !MRI->isReserved(Reg))
1032cab237bSDimitry Andric Hints.push_back(Reg);
1042cab237bSDimitry Andric // Return true to make these hints the only regs available to
1052cab237bSDimitry Andric // RA. This may mean extra spilling but since the alternative is
1062cab237bSDimitry Andric // a jump sequence expansion of the LOCRMux, it is preferred.
1072cab237bSDimitry Andric return true;
1082cab237bSDimitry Andric }
1092cab237bSDimitry Andric
1102cab237bSDimitry Andric // Add the other operand of the LOCRMux to the worklist.
1112cab237bSDimitry Andric unsigned OtherReg =
1122cab237bSDimitry Andric (TrueMO.getReg() == Reg ? FalseMO.getReg() : TrueMO.getReg());
1132cab237bSDimitry Andric if (MRI->getRegClass(OtherReg) == &SystemZ::GRX32BitRegClass)
1142cab237bSDimitry Andric Worklist.push_back(OtherReg);
1152cab237bSDimitry Andric }
1162cab237bSDimitry Andric }
1172cab237bSDimitry Andric }
1182cab237bSDimitry Andric
119*b5893f02SDimitry Andric return BaseImplRetVal;
1202cab237bSDimitry Andric }
1212cab237bSDimitry Andric
12291bc56edSDimitry Andric const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const123284c1978SDimitry Andric SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
1244ba319b5SDimitry Andric const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1254ba319b5SDimitry Andric if (MF->getFunction().getCallingConv() == CallingConv::AnyReg)
1264ba319b5SDimitry Andric return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_SaveList
1274ba319b5SDimitry Andric : CSR_SystemZ_AllRegs_SaveList;
1283ca95b02SDimitry Andric if (MF->getSubtarget().getTargetLowering()->supportSwiftError() &&
1292cab237bSDimitry Andric MF->getFunction().getAttributes().hasAttrSomewhere(
1303ca95b02SDimitry Andric Attribute::SwiftError))
1313ca95b02SDimitry Andric return CSR_SystemZ_SwiftError_SaveList;
13291bc56edSDimitry Andric return CSR_SystemZ_SaveList;
13391bc56edSDimitry Andric }
134284c1978SDimitry Andric
13591bc56edSDimitry Andric const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID CC) const136ff0cc061SDimitry Andric SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
137ff0cc061SDimitry Andric CallingConv::ID CC) const {
1384ba319b5SDimitry Andric const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1394ba319b5SDimitry Andric if (CC == CallingConv::AnyReg)
1404ba319b5SDimitry Andric return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_RegMask
1414ba319b5SDimitry Andric : CSR_SystemZ_AllRegs_RegMask;
1423ca95b02SDimitry Andric if (MF.getSubtarget().getTargetLowering()->supportSwiftError() &&
1432cab237bSDimitry Andric MF.getFunction().getAttributes().hasAttrSomewhere(
1443ca95b02SDimitry Andric Attribute::SwiftError))
1453ca95b02SDimitry Andric return CSR_SystemZ_SwiftError_RegMask;
14691bc56edSDimitry Andric return CSR_SystemZ_RegMask;
147284c1978SDimitry Andric }
148284c1978SDimitry Andric
149284c1978SDimitry Andric BitVector
getReservedRegs(const MachineFunction & MF) const150284c1978SDimitry Andric SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
151284c1978SDimitry Andric BitVector Reserved(getNumRegs());
152875ed548SDimitry Andric const SystemZFrameLowering *TFI = getFrameLowering(MF);
153284c1978SDimitry Andric
154284c1978SDimitry Andric if (TFI->hasFP(MF)) {
155284c1978SDimitry Andric // R11D is the frame pointer. Reserve all aliases.
156284c1978SDimitry Andric Reserved.set(SystemZ::R11D);
157f785676fSDimitry Andric Reserved.set(SystemZ::R11L);
158f785676fSDimitry Andric Reserved.set(SystemZ::R11H);
159284c1978SDimitry Andric Reserved.set(SystemZ::R10Q);
160284c1978SDimitry Andric }
161284c1978SDimitry Andric
162284c1978SDimitry Andric // R15D is the stack pointer. Reserve all aliases.
163284c1978SDimitry Andric Reserved.set(SystemZ::R15D);
164f785676fSDimitry Andric Reserved.set(SystemZ::R15L);
165f785676fSDimitry Andric Reserved.set(SystemZ::R15H);
166284c1978SDimitry Andric Reserved.set(SystemZ::R14Q);
167d88c1a5aSDimitry Andric
168d88c1a5aSDimitry Andric // A0 and A1 hold the thread pointer.
169d88c1a5aSDimitry Andric Reserved.set(SystemZ::A0);
170d88c1a5aSDimitry Andric Reserved.set(SystemZ::A1);
171d88c1a5aSDimitry Andric
172284c1978SDimitry Andric return Reserved;
173284c1978SDimitry Andric }
174284c1978SDimitry Andric
175284c1978SDimitry Andric void
eliminateFrameIndex(MachineBasicBlock::iterator MI,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const176284c1978SDimitry Andric SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
177284c1978SDimitry Andric int SPAdj, unsigned FIOperandNum,
178284c1978SDimitry Andric RegScavenger *RS) const {
179284c1978SDimitry Andric assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
180284c1978SDimitry Andric
181284c1978SDimitry Andric MachineBasicBlock &MBB = *MI->getParent();
182284c1978SDimitry Andric MachineFunction &MF = *MBB.getParent();
18391bc56edSDimitry Andric auto *TII =
18439d628a0SDimitry Andric static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
185875ed548SDimitry Andric const SystemZFrameLowering *TFI = getFrameLowering(MF);
186284c1978SDimitry Andric DebugLoc DL = MI->getDebugLoc();
187284c1978SDimitry Andric
188284c1978SDimitry Andric // Decompose the frame index into a base and offset.
189284c1978SDimitry Andric int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
1907d523365SDimitry Andric unsigned BasePtr;
1917d523365SDimitry Andric int64_t Offset = (TFI->getFrameIndexReference(MF, FrameIndex, BasePtr) +
192284c1978SDimitry Andric MI->getOperand(FIOperandNum + 1).getImm());
193284c1978SDimitry Andric
194284c1978SDimitry Andric // Special handling of dbg_value instructions.
195284c1978SDimitry Andric if (MI->isDebugValue()) {
196284c1978SDimitry Andric MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
197284c1978SDimitry Andric MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
198284c1978SDimitry Andric return;
199284c1978SDimitry Andric }
200284c1978SDimitry Andric
201284c1978SDimitry Andric // See if the offset is in range, or if an equivalent instruction that
202284c1978SDimitry Andric // accepts the offset exists.
203284c1978SDimitry Andric unsigned Opcode = MI->getOpcode();
20491bc56edSDimitry Andric unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
2053ca95b02SDimitry Andric if (OpcodeForOffset) {
2063ca95b02SDimitry Andric if (OpcodeForOffset == SystemZ::LE &&
2073ca95b02SDimitry Andric MF.getSubtarget<SystemZSubtarget>().hasVector()) {
2083ca95b02SDimitry Andric // If LE is ok for offset, use LDE instead on z13.
2093ca95b02SDimitry Andric OpcodeForOffset = SystemZ::LDE32;
2103ca95b02SDimitry Andric }
211284c1978SDimitry Andric MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
2123ca95b02SDimitry Andric }
213284c1978SDimitry Andric else {
214284c1978SDimitry Andric // Create an anchor point that is in range. Start at 0xffff so that
215284c1978SDimitry Andric // can use LLILH to load the immediate.
216284c1978SDimitry Andric int64_t OldOffset = Offset;
217284c1978SDimitry Andric int64_t Mask = 0xffff;
218284c1978SDimitry Andric do {
219284c1978SDimitry Andric Offset = OldOffset & Mask;
22091bc56edSDimitry Andric OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
221284c1978SDimitry Andric Mask >>= 1;
222284c1978SDimitry Andric assert(Mask && "One offset must be OK");
223284c1978SDimitry Andric } while (!OpcodeForOffset);
224284c1978SDimitry Andric
225284c1978SDimitry Andric unsigned ScratchReg =
226284c1978SDimitry Andric MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
227284c1978SDimitry Andric int64_t HighOffset = OldOffset - Offset;
228284c1978SDimitry Andric
229284c1978SDimitry Andric if (MI->getDesc().TSFlags & SystemZII::HasIndex
230284c1978SDimitry Andric && MI->getOperand(FIOperandNum + 2).getReg() == 0) {
231284c1978SDimitry Andric // Load the offset into the scratch register and use it as an index.
232284c1978SDimitry Andric // The scratch register then dies here.
23391bc56edSDimitry Andric TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
234284c1978SDimitry Andric MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
235284c1978SDimitry Andric MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
236284c1978SDimitry Andric false, false, true);
237284c1978SDimitry Andric } else {
238284c1978SDimitry Andric // Load the anchor address into a scratch register.
23991bc56edSDimitry Andric unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);
240284c1978SDimitry Andric if (LAOpcode)
24191bc56edSDimitry Andric BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg)
242284c1978SDimitry Andric .addReg(BasePtr).addImm(HighOffset).addReg(0);
243284c1978SDimitry Andric else {
244284c1978SDimitry Andric // Load the high offset into the scratch register and use it as
245284c1978SDimitry Andric // an index.
24691bc56edSDimitry Andric TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
24791bc56edSDimitry Andric BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg)
248284c1978SDimitry Andric .addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
249284c1978SDimitry Andric }
250284c1978SDimitry Andric
251284c1978SDimitry Andric // Use the scratch register as the base. It then dies here.
252284c1978SDimitry Andric MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
253284c1978SDimitry Andric false, false, true);
254284c1978SDimitry Andric }
255284c1978SDimitry Andric }
25691bc56edSDimitry Andric MI->setDesc(TII->get(OpcodeForOffset));
257284c1978SDimitry Andric MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
258284c1978SDimitry Andric }
259284c1978SDimitry Andric
shouldCoalesce(MachineInstr * MI,const TargetRegisterClass * SrcRC,unsigned SubReg,const TargetRegisterClass * DstRC,unsigned DstSubReg,const TargetRegisterClass * NewRC,LiveIntervals & LIS) const2602cab237bSDimitry Andric bool SystemZRegisterInfo::shouldCoalesce(MachineInstr *MI,
2612cab237bSDimitry Andric const TargetRegisterClass *SrcRC,
2622cab237bSDimitry Andric unsigned SubReg,
2632cab237bSDimitry Andric const TargetRegisterClass *DstRC,
2642cab237bSDimitry Andric unsigned DstSubReg,
2652cab237bSDimitry Andric const TargetRegisterClass *NewRC,
2662cab237bSDimitry Andric LiveIntervals &LIS) const {
2672cab237bSDimitry Andric assert (MI->isCopy() && "Only expecting COPY instructions");
2682cab237bSDimitry Andric
2692cab237bSDimitry Andric // Coalesce anything which is not a COPY involving a subreg to/from GR128.
2702cab237bSDimitry Andric if (!(NewRC->hasSuperClassEq(&SystemZ::GR128BitRegClass) &&
2712cab237bSDimitry Andric (getRegSizeInBits(*SrcRC) <= 64 || getRegSizeInBits(*DstRC) <= 64)))
2722cab237bSDimitry Andric return true;
2732cab237bSDimitry Andric
2742cab237bSDimitry Andric // Allow coalescing of a GR128 subreg COPY only if the live ranges are small
2752cab237bSDimitry Andric // and local to one MBB with not too much interferring registers. Otherwise
2762cab237bSDimitry Andric // regalloc may run out of registers.
2772cab237bSDimitry Andric
2782cab237bSDimitry Andric unsigned WideOpNo = (getRegSizeInBits(*SrcRC) == 128 ? 1 : 0);
2792cab237bSDimitry Andric unsigned GR128Reg = MI->getOperand(WideOpNo).getReg();
2802cab237bSDimitry Andric unsigned GRNarReg = MI->getOperand((WideOpNo == 1) ? 0 : 1).getReg();
2812cab237bSDimitry Andric LiveInterval &IntGR128 = LIS.getInterval(GR128Reg);
2822cab237bSDimitry Andric LiveInterval &IntGRNar = LIS.getInterval(GRNarReg);
2832cab237bSDimitry Andric
2842cab237bSDimitry Andric // Check that the two virtual registers are local to MBB.
2852cab237bSDimitry Andric MachineBasicBlock *MBB = MI->getParent();
286*b5893f02SDimitry Andric MachineInstr *FirstMI_GR128 =
287*b5893f02SDimitry Andric LIS.getInstructionFromIndex(IntGR128.beginIndex());
288*b5893f02SDimitry Andric MachineInstr *FirstMI_GRNar =
289*b5893f02SDimitry Andric LIS.getInstructionFromIndex(IntGRNar.beginIndex());
290*b5893f02SDimitry Andric MachineInstr *LastMI_GR128 = LIS.getInstructionFromIndex(IntGR128.endIndex());
291*b5893f02SDimitry Andric MachineInstr *LastMI_GRNar = LIS.getInstructionFromIndex(IntGRNar.endIndex());
292*b5893f02SDimitry Andric if ((!FirstMI_GR128 || FirstMI_GR128->getParent() != MBB) ||
293*b5893f02SDimitry Andric (!FirstMI_GRNar || FirstMI_GRNar->getParent() != MBB) ||
294*b5893f02SDimitry Andric (!LastMI_GR128 || LastMI_GR128->getParent() != MBB) ||
295*b5893f02SDimitry Andric (!LastMI_GRNar || LastMI_GRNar->getParent() != MBB))
2962cab237bSDimitry Andric return false;
2972cab237bSDimitry Andric
298*b5893f02SDimitry Andric MachineBasicBlock::iterator MII = nullptr, MEE = nullptr;
2992cab237bSDimitry Andric if (WideOpNo == 1) {
300*b5893f02SDimitry Andric MII = FirstMI_GR128;
301*b5893f02SDimitry Andric MEE = LastMI_GRNar;
3022cab237bSDimitry Andric } else {
303*b5893f02SDimitry Andric MII = FirstMI_GRNar;
304*b5893f02SDimitry Andric MEE = LastMI_GR128;
3052cab237bSDimitry Andric }
3062cab237bSDimitry Andric
3072cab237bSDimitry Andric // Check if coalescing seems safe by finding the set of clobbered physreg
3082cab237bSDimitry Andric // pairs in the region.
3092cab237bSDimitry Andric BitVector PhysClobbered(getNumRegs());
3102cab237bSDimitry Andric MEE++;
3112cab237bSDimitry Andric for (; MII != MEE; ++MII) {
3122cab237bSDimitry Andric for (const MachineOperand &MO : MII->operands())
3132cab237bSDimitry Andric if (MO.isReg() && isPhysicalRegister(MO.getReg())) {
3142cab237bSDimitry Andric for (MCSuperRegIterator SI(MO.getReg(), this, true/*IncludeSelf*/);
3152cab237bSDimitry Andric SI.isValid(); ++SI)
3162cab237bSDimitry Andric if (NewRC->contains(*SI)) {
3172cab237bSDimitry Andric PhysClobbered.set(*SI);
3182cab237bSDimitry Andric break;
3192cab237bSDimitry Andric }
3202cab237bSDimitry Andric }
3212cab237bSDimitry Andric }
3222cab237bSDimitry Andric
3232cab237bSDimitry Andric // Demand an arbitrary margin of free regs.
3242cab237bSDimitry Andric unsigned const DemandedFreeGR128 = 3;
3252cab237bSDimitry Andric if (PhysClobbered.count() > (NewRC->getNumRegs() - DemandedFreeGR128))
3262cab237bSDimitry Andric return false;
3272cab237bSDimitry Andric
3282cab237bSDimitry Andric return true;
3292cab237bSDimitry Andric }
3302cab237bSDimitry Andric
331284c1978SDimitry Andric unsigned
getFrameRegister(const MachineFunction & MF) const332284c1978SDimitry Andric SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
333875ed548SDimitry Andric const SystemZFrameLowering *TFI = getFrameLowering(MF);
334284c1978SDimitry Andric return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D;
335284c1978SDimitry Andric }
3364ba319b5SDimitry Andric
3374ba319b5SDimitry Andric const TargetRegisterClass *
getCrossCopyRegClass(const TargetRegisterClass * RC) const3384ba319b5SDimitry Andric SystemZRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
3394ba319b5SDimitry Andric if (RC == &SystemZ::CCRRegClass)
3404ba319b5SDimitry Andric return &SystemZ::GR32BitRegClass;
3414ba319b5SDimitry Andric return RC;
3424ba319b5SDimitry Andric }
3434ba319b5SDimitry Andric
344