LLVM  4.0.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 *
29  Attribute::SwiftError))
30  return CSR_SystemZ_SwiftError_SaveList;
31  return CSR_SystemZ_SaveList;
32 }
33 
34 const uint32_t *
36  CallingConv::ID CC) const {
39  Attribute::SwiftError))
40  return CSR_SystemZ_SwiftError_RegMask;
41  return CSR_SystemZ_RegMask;
42 }
43 
46  BitVector Reserved(getNumRegs());
47  const SystemZFrameLowering *TFI = getFrameLowering(MF);
48 
49  if (TFI->hasFP(MF)) {
50  // R11D is the frame pointer. Reserve all aliases.
51  Reserved.set(SystemZ::R11D);
52  Reserved.set(SystemZ::R11L);
53  Reserved.set(SystemZ::R11H);
54  Reserved.set(SystemZ::R10Q);
55  }
56 
57  // R15D is the stack pointer. Reserve all aliases.
58  Reserved.set(SystemZ::R15D);
59  Reserved.set(SystemZ::R15L);
60  Reserved.set(SystemZ::R15H);
61  Reserved.set(SystemZ::R14Q);
62 
63  // A0 and A1 hold the thread pointer.
64  Reserved.set(SystemZ::A0);
65  Reserved.set(SystemZ::A1);
66 
67  return Reserved;
68 }
69 
70 void
72  int SPAdj, unsigned FIOperandNum,
73  RegScavenger *RS) const {
74  assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
75 
76  MachineBasicBlock &MBB = *MI->getParent();
77  MachineFunction &MF = *MBB.getParent();
78  auto *TII =
79  static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
80  const SystemZFrameLowering *TFI = getFrameLowering(MF);
81  DebugLoc DL = MI->getDebugLoc();
82 
83  // Decompose the frame index into a base and offset.
84  int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
85  unsigned BasePtr;
86  int64_t Offset = (TFI->getFrameIndexReference(MF, FrameIndex, BasePtr) +
87  MI->getOperand(FIOperandNum + 1).getImm());
88 
89  // Special handling of dbg_value instructions.
90  if (MI->isDebugValue()) {
91  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
92  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
93  return;
94  }
95 
96  // See if the offset is in range, or if an equivalent instruction that
97  // accepts the offset exists.
98  unsigned Opcode = MI->getOpcode();
99  unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
100  if (OpcodeForOffset) {
101  if (OpcodeForOffset == SystemZ::LE &&
103  // If LE is ok for offset, use LDE instead on z13.
104  OpcodeForOffset = SystemZ::LDE32;
105  }
106  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
107  }
108  else {
109  // Create an anchor point that is in range. Start at 0xffff so that
110  // can use LLILH to load the immediate.
111  int64_t OldOffset = Offset;
112  int64_t Mask = 0xffff;
113  do {
114  Offset = OldOffset & Mask;
115  OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
116  Mask >>= 1;
117  assert(Mask && "One offset must be OK");
118  } while (!OpcodeForOffset);
119 
120  unsigned ScratchReg =
121  MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
122  int64_t HighOffset = OldOffset - Offset;
123 
124  if (MI->getDesc().TSFlags & SystemZII::HasIndex
125  && MI->getOperand(FIOperandNum + 2).getReg() == 0) {
126  // Load the offset into the scratch register and use it as an index.
127  // The scratch register then dies here.
128  TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
129  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
130  MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
131  false, false, true);
132  } else {
133  // Load the anchor address into a scratch register.
134  unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);
135  if (LAOpcode)
136  BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg)
137  .addReg(BasePtr).addImm(HighOffset).addReg(0);
138  else {
139  // Load the high offset into the scratch register and use it as
140  // an index.
141  TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
142  BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg)
143  .addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
144  }
145 
146  // Use the scratch register as the base. It then dies here.
147  MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
148  false, false, true);
149  }
150  }
151  MI->setDesc(TII->get(OpcodeForOffset));
152  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
153 }
154 
155 unsigned
157  const SystemZFrameLowering *TFI = getFrameLowering(MF);
158  return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D;
159 }
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
BitVector & set()
Definition: BitVector.h:219
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
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
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
Add a new immediate operand.
MachineBasicBlock * MBB
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override
virtual bool supportSwiftError() const
Return true if the target supports swifterror attribute.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
uint32_t Offset
virtual const TargetLowering * getTargetLowering() const
AttributeSet getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:176
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:81
IRTranslator LLVM IR MI
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.