LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 "SystemZRegisterInfo.h"
11 #include "SystemZTargetMachine.h"
14 
15 #define GET_REGINFO_TARGET_DESC
16 #include "SystemZGenRegisterInfo.inc"
17 
18 using namespace llvm;
19 
21  : SystemZGenRegisterInfo(SystemZ::R14D), TM(tm) {}
22 
23 const uint16_t*
25  static const uint16_t CalleeSavedRegs[] = {
26  SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D,
27  SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D,
28  SystemZ::R14D, SystemZ::R15D,
29  SystemZ::F8D, SystemZ::F9D, SystemZ::F10D, SystemZ::F11D,
30  SystemZ::F12D, SystemZ::F13D, SystemZ::F14D, SystemZ::F15D,
31  0
32  };
33 
34  return CalleeSavedRegs;
35 }
36 
39  BitVector Reserved(getNumRegs());
41 
42  if (TFI->hasFP(MF)) {
43  // R11D is the frame pointer. Reserve all aliases.
44  Reserved.set(SystemZ::R11D);
45  Reserved.set(SystemZ::R11L);
46  Reserved.set(SystemZ::R11H);
47  Reserved.set(SystemZ::R10Q);
48  }
49 
50  // R15D is the stack pointer. Reserve all aliases.
51  Reserved.set(SystemZ::R15D);
52  Reserved.set(SystemZ::R15L);
53  Reserved.set(SystemZ::R15H);
54  Reserved.set(SystemZ::R14Q);
55  return Reserved;
56 }
57 
58 void
60  int SPAdj, unsigned FIOperandNum,
61  RegScavenger *RS) const {
62  assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
63 
64  MachineBasicBlock &MBB = *MI->getParent();
65  MachineFunction &MF = *MBB.getParent();
66  const SystemZInstrInfo &TII =
67  *static_cast<const SystemZInstrInfo*>(TM.getInstrInfo());
69  DebugLoc DL = MI->getDebugLoc();
70 
71  // Decompose the frame index into a base and offset.
72  int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
73  unsigned BasePtr = getFrameRegister(MF);
74  int64_t Offset = (TFI->getFrameIndexOffset(MF, FrameIndex) +
75  MI->getOperand(FIOperandNum + 1).getImm());
76 
77  // Special handling of dbg_value instructions.
78  if (MI->isDebugValue()) {
79  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
80  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
81  return;
82  }
83 
84  // See if the offset is in range, or if an equivalent instruction that
85  // accepts the offset exists.
86  unsigned Opcode = MI->getOpcode();
87  unsigned OpcodeForOffset = TII.getOpcodeForOffset(Opcode, Offset);
88  if (OpcodeForOffset)
89  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
90  else {
91  // Create an anchor point that is in range. Start at 0xffff so that
92  // can use LLILH to load the immediate.
93  int64_t OldOffset = Offset;
94  int64_t Mask = 0xffff;
95  do {
96  Offset = OldOffset & Mask;
97  OpcodeForOffset = TII.getOpcodeForOffset(Opcode, Offset);
98  Mask >>= 1;
99  assert(Mask && "One offset must be OK");
100  } while (!OpcodeForOffset);
101 
102  unsigned ScratchReg =
103  MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
104  int64_t HighOffset = OldOffset - Offset;
105 
106  if (MI->getDesc().TSFlags & SystemZII::HasIndex
107  && MI->getOperand(FIOperandNum + 2).getReg() == 0) {
108  // Load the offset into the scratch register and use it as an index.
109  // The scratch register then dies here.
110  TII.loadImmediate(MBB, MI, ScratchReg, HighOffset);
111  MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
112  MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
113  false, false, true);
114  } else {
115  // Load the anchor address into a scratch register.
116  unsigned LAOpcode = TII.getOpcodeForOffset(SystemZ::LA, HighOffset);
117  if (LAOpcode)
118  BuildMI(MBB, MI, DL, TII.get(LAOpcode),ScratchReg)
119  .addReg(BasePtr).addImm(HighOffset).addReg(0);
120  else {
121  // Load the high offset into the scratch register and use it as
122  // an index.
123  TII.loadImmediate(MBB, MI, ScratchReg, HighOffset);
124  BuildMI(MBB, MI, DL, TII.get(SystemZ::AGR),ScratchReg)
125  .addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
126  }
127 
128  // Use the scratch register as the base. It then dies here.
129  MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
130  false, false, true);
131  }
132  }
133  MI->setDesc(TII.get(OpcodeForOffset));
134  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
135 }
136 
137 unsigned
139  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
140  return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D;
141 }
const MachineFunction * getParent() const
BitVector & set()
Definition: BitVector.h:236
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const LLVM_OVERRIDE
virtual const SystemZInstrInfo * getInstrInfo() const LLVM_OVERRIDE
const HexagonInstrInfo * TII
virtual bool hasFP(const MachineFunction &MF) const =0
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned Reg, uint64_t Value) const
const MachineInstrBuilder & addImm(int64_t Val) const
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
SystemZRegisterInfo(SystemZTargetMachine &tm)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual BitVector getReservedRegs(const MachineFunction &MF) const LLVM_OVERRIDE
virtual const TargetFrameLowering * getFrameLowering() const
virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const
virtual unsigned getFrameRegister(const MachineFunction &MF) const LLVM_OVERRIDE
MachineRegisterInfo & getRegInfo()
const TargetMachine & getTarget() const
virtual const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=0) const LLVM_OVERRIDE
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const