LLVM  3.7.0
SystemZRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- SystemZRegisterInfo.cpp - SystemZ register information ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "SystemZInstrInfo.h"
11 #include "SystemZRegisterInfo.h"
12 #include "SystemZSubtarget.h"
16 
17 using namespace llvm;
18 
19 #define GET_REGINFO_TARGET_DESC
20 #include "SystemZGenRegisterInfo.inc"
21 
23  : SystemZGenRegisterInfo(SystemZ::R14D) {}
24 
25 const MCPhysReg *
27  return CSR_SystemZ_SaveList;
28 }
29 
30 const uint32_t *
32  CallingConv::ID CC) const {
33  return CSR_SystemZ_RegMask;
34 }
35 
38  BitVector Reserved(getNumRegs());
39  const SystemZFrameLowering *TFI = getFrameLowering(MF);
40 
41  if (TFI->hasFP(MF)) {
42  // R11D is the frame pointer. Reserve all aliases.
43  Reserved.set(SystemZ::R11D);
44  Reserved.set(SystemZ::R11L);
45  Reserved.set(SystemZ::R11H);
46  Reserved.set(SystemZ::R10Q);
47  }
48 
49  // R15D is the stack pointer. Reserve all aliases.
50  Reserved.set(SystemZ::R15D);
51  Reserved.set(SystemZ::R15L);
52  Reserved.set(SystemZ::R15H);
53  Reserved.set(SystemZ::R14Q);
54  return Reserved;
55 }
56 
57 void
59  int SPAdj, unsigned FIOperandNum,
60  RegScavenger *RS) const {
61  assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
62 
63  MachineBasicBlock &MBB = *MI->getParent();
64  MachineFunction &MF = *MBB.getParent();
65  auto *TII =
66  static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
67  const SystemZFrameLowering *TFI = getFrameLowering(MF);
68  DebugLoc DL = MI->getDebugLoc();
69 
70  // Decompose the frame index into a base and offset.
71  int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
72  unsigned BasePtr = getFrameRegister(MF);
73  int64_t Offset = (TFI->getFrameIndexOffset(MF, FrameIndex) +
74  MI->getOperand(FIOperandNum + 1).getImm());
75 
76  // Special handling of dbg_value instructions.
77  if (MI->isDebugValue()) {
78  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
79  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
80  return;
81  }
82 
83  // See if the offset is in range, or if an equivalent instruction that
84  // accepts the offset exists.
85  unsigned Opcode = MI->getOpcode();
86  unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
87  if (OpcodeForOffset)
88  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
89  else {
90  // Create an anchor point that is in range. Start at 0xffff so that
91  // can use LLILH to load the immediate.
92  int64_t OldOffset = Offset;
93  int64_t Mask = 0xffff;
94  do {
95  Offset = OldOffset & Mask;
96  OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
97  Mask >>= 1;
98  assert(Mask && "One offset must be OK");
99  } while (!OpcodeForOffset);
100 
101  unsigned ScratchReg =
102  MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
103  int64_t HighOffset = OldOffset - Offset;
104 
105  if (MI->getDesc().TSFlags & SystemZII::HasIndex
106  && MI->getOperand(FIOperandNum + 2).getReg() == 0) {
107  // Load the offset into the scratch register and use it as an index.
108  // The scratch register then dies here.
109  TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
110  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
111  MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
112  false, false, true);
113  } else {
114  // Load the anchor address into a scratch register.
115  unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);
116  if (LAOpcode)
117  BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg)
118  .addReg(BasePtr).addImm(HighOffset).addReg(0);
119  else {
120  // Load the high offset into the scratch register and use it as
121  // an index.
122  TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
123  BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg)
124  .addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
125  }
126 
127  // Use the scratch register as the base. It then dies here.
128  MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
129  false, false, true);
130  }
131  }
132  MI->setDesc(TII->get(OpcodeForOffset));
133  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
134 }
135 
136 unsigned
138  const SystemZFrameLowering *TFI = getFrameLowering(MF);
139  return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D;
140 }
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
BitVector & set()
Definition: BitVector.h:218
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
BitVector getReservedRegs(const MachineFunction &MF) const override
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
int getFrameIndexOffset(const MachineFunction &MF, int FI) const override
getFrameIndexOffset - Returns the displacement from the frame register to the stack frame of the spec...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
A debug info location.
Definition: DebugLoc.h:34
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const HexagonInstrInfo * TII
unsigned getFrameRegister(const MachineFunction &MF) const override
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...