LLVM  8.0.1
XCoreRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- XCoreRegisterInfo.cpp - XCore 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 // This file contains the XCore implementation of the MRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "XCoreRegisterInfo.h"
15 #include "XCore.h"
16 #include "XCoreInstrInfo.h"
18 #include "XCoreSubtarget.h"
19 #include "llvm/ADT/BitVector.h"
20 #include "llvm/ADT/STLExtras.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/Support/Debug.h"
36 
37 using namespace llvm;
38 
39 #define DEBUG_TYPE "xcore-reg-info"
40 
41 #define GET_REGINFO_TARGET_DESC
42 #include "XCoreGenRegisterInfo.inc"
43 
45  : XCoreGenRegisterInfo(XCore::LR) {
46 }
47 
48 // helper functions
49 static inline bool isImmUs(unsigned val) {
50  return val <= 11;
51 }
52 
53 static inline bool isImmU6(unsigned val) {
54  return val < (1 << 6);
55 }
56 
57 static inline bool isImmU16(unsigned val) {
58  return val < (1 << 16);
59 }
60 
61 
63  const XCoreInstrInfo &TII,
64  unsigned Reg, unsigned FrameReg, int Offset ) {
65  MachineInstr &MI = *II;
66  MachineBasicBlock &MBB = *MI.getParent();
67  DebugLoc dl = MI.getDebugLoc();
68 
69  switch (MI.getOpcode()) {
70  case XCore::LDWFI:
71  BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
72  .addReg(FrameReg)
73  .addImm(Offset)
75  break;
76  case XCore::STWFI:
77  BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
78  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
79  .addReg(FrameReg)
80  .addImm(Offset)
82  break;
83  case XCore::LDAWFI:
84  BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
85  .addReg(FrameReg)
86  .addImm(Offset);
87  break;
88  default:
89  llvm_unreachable("Unexpected Opcode");
90  }
91 }
92 
94  const XCoreInstrInfo &TII,
95  unsigned Reg, unsigned FrameReg,
96  int Offset, RegScavenger *RS ) {
97  assert(RS && "requiresRegisterScavenging failed");
98  MachineInstr &MI = *II;
99  MachineBasicBlock &MBB = *MI.getParent();
100  DebugLoc dl = MI.getDebugLoc();
101  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
102  RS->setRegUsed(ScratchOffset);
103  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
104 
105  switch (MI.getOpcode()) {
106  case XCore::LDWFI:
107  BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
108  .addReg(FrameReg)
109  .addReg(ScratchOffset, RegState::Kill)
111  break;
112  case XCore::STWFI:
113  BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
114  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
115  .addReg(FrameReg)
116  .addReg(ScratchOffset, RegState::Kill)
118  break;
119  case XCore::LDAWFI:
120  BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
121  .addReg(FrameReg)
122  .addReg(ScratchOffset, RegState::Kill);
123  break;
124  default:
125  llvm_unreachable("Unexpected Opcode");
126  }
127 }
128 
130  const XCoreInstrInfo &TII,
131  unsigned Reg, int Offset) {
132  MachineInstr &MI = *II;
133  MachineBasicBlock &MBB = *MI.getParent();
134  DebugLoc dl = MI.getDebugLoc();
135  bool isU6 = isImmU6(Offset);
136 
137  switch (MI.getOpcode()) {
138  int NewOpcode;
139  case XCore::LDWFI:
140  NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
141  BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
142  .addImm(Offset)
144  break;
145  case XCore::STWFI:
146  NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
147  BuildMI(MBB, II, dl, TII.get(NewOpcode))
148  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
149  .addImm(Offset)
151  break;
152  case XCore::LDAWFI:
153  NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
154  BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
155  .addImm(Offset);
156  break;
157  default:
158  llvm_unreachable("Unexpected Opcode");
159  }
160 }
161 
163  const XCoreInstrInfo &TII,
164  unsigned Reg, int Offset, RegScavenger *RS ) {
165  assert(RS && "requiresRegisterScavenging failed");
166  MachineInstr &MI = *II;
167  MachineBasicBlock &MBB = *MI.getParent();
168  DebugLoc dl = MI.getDebugLoc();
169  unsigned OpCode = MI.getOpcode();
170 
171  unsigned ScratchBase;
172  if (OpCode==XCore::STWFI) {
173  ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
174  RS->setRegUsed(ScratchBase);
175  } else
176  ScratchBase = Reg;
177  BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);
178  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
179  RS->setRegUsed(ScratchOffset);
180  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
181 
182  switch (OpCode) {
183  case XCore::LDWFI:
184  BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
185  .addReg(ScratchBase, RegState::Kill)
186  .addReg(ScratchOffset, RegState::Kill)
188  break;
189  case XCore::STWFI:
190  BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
191  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
192  .addReg(ScratchBase, RegState::Kill)
193  .addReg(ScratchOffset, RegState::Kill)
195  break;
196  case XCore::LDAWFI:
197  BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
198  .addReg(ScratchBase, RegState::Kill)
199  .addReg(ScratchOffset, RegState::Kill);
200  break;
201  default:
202  llvm_unreachable("Unexpected Opcode");
203  }
204 }
205 
207  return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
208 }
209 
210 const MCPhysReg *
212  // The callee saved registers LR & FP are explicitly handled during
213  // emitPrologue & emitEpilogue and related functions.
214  static const MCPhysReg CalleeSavedRegs[] = {
215  XCore::R4, XCore::R5, XCore::R6, XCore::R7,
216  XCore::R8, XCore::R9, XCore::R10,
217  0
218  };
219  static const MCPhysReg CalleeSavedRegsFP[] = {
220  XCore::R4, XCore::R5, XCore::R6, XCore::R7,
221  XCore::R8, XCore::R9,
222  0
223  };
224  const XCoreFrameLowering *TFI = getFrameLowering(*MF);
225  if (TFI->hasFP(*MF))
226  return CalleeSavedRegsFP;
227  return CalleeSavedRegs;
228 }
229 
231  BitVector Reserved(getNumRegs());
232  const XCoreFrameLowering *TFI = getFrameLowering(MF);
233 
234  Reserved.set(XCore::CP);
235  Reserved.set(XCore::DP);
236  Reserved.set(XCore::SP);
237  Reserved.set(XCore::LR);
238  if (TFI->hasFP(MF)) {
239  Reserved.set(XCore::R10);
240  }
241  return Reserved;
242 }
243 
244 bool
246  return true;
247 }
248 
249 bool
251  return true;
252 }
253 
254 bool
256  return false;
257 }
258 
259 void
261  int SPAdj, unsigned FIOperandNum,
262  RegScavenger *RS) const {
263  assert(SPAdj == 0 && "Unexpected");
264  MachineInstr &MI = *II;
265  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
266  int FrameIndex = FrameOp.getIndex();
267 
268  MachineFunction &MF = *MI.getParent()->getParent();
269  const XCoreInstrInfo &TII =
270  *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
271 
272  const XCoreFrameLowering *TFI = getFrameLowering(MF);
273  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
274  int StackSize = MF.getFrameInfo().getStackSize();
275 
276  #ifndef NDEBUG
277  LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n");
278  LLVM_DEBUG(errs() << "<--------->\n");
279  LLVM_DEBUG(MI.print(errs()));
280  LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n");
281  LLVM_DEBUG(errs() << "FrameOffset : " << Offset << "\n");
282  LLVM_DEBUG(errs() << "StackSize : " << StackSize << "\n");
283 #endif
284 
285  Offset += StackSize;
286 
287  unsigned FrameReg = getFrameRegister(MF);
288 
289  // Special handling of DBG_VALUE instructions.
290  if (MI.isDebugValue()) {
291  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
292  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
293  return;
294  }
295 
296  // fold constant into offset.
297  Offset += MI.getOperand(FIOperandNum + 1).getImm();
298  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
299 
300  assert(Offset%4 == 0 && "Misaligned stack offset");
301  LLVM_DEBUG(errs() << "Offset : " << Offset << "\n"
302  << "<--------->\n");
303  Offset/=4;
304 
305  unsigned Reg = MI.getOperand(0).getReg();
306  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
307 
308  if (TFI->hasFP(MF)) {
309  if (isImmUs(Offset))
310  InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
311  else
312  InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
313  } else {
314  if (isImmU16(Offset))
315  InsertSPImmInst(II, TII, Reg, Offset);
316  else
317  InsertSPConstInst(II, TII, Reg, Offset, RS);
318  }
319  // Erase old instruction.
320  MachineBasicBlock &MBB = *MI.getParent();
321  MBB.erase(II);
322 }
323 
324 
326  const XCoreFrameLowering *TFI = getFrameLowering(MF);
327 
328  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
329 }
BitVector & set()
Definition: BitVector.h:398
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
#define R4(n)
bool hasDebugInfo() const
Returns true if valid debug info is present.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
A debug info location.
Definition: DebugLoc.h:34
MachineModuleInfo & getMMI() const
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override
return AArch64::GPR64RegClass contains(Reg)
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
virtual const TargetInstrInfo * getInstrInfo() const
unsigned getKillRegState(bool B)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
MachineBasicBlock::iterator loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Reg, uint64_t Value) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool useFPForScavengingIndex(const MachineFunction &MF) const override
This file declares the machine register scavenger class.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static void InsertSPImmInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, int Offset)
unsigned getFrameRegister(const MachineFunction &MF) const override
static void InsertFPConstInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, unsigned FrameReg, int Offset, RegScavenger *RS)
void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
bool requiresRegisterScavenging(const MachineFunction &MF) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define R6(n)
static bool isImmUs(unsigned val)
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:534
bool isDebugValue() const
Definition: MachineInstr.h:997
MachineOperand class - Representation of each machine instruction operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
BitVector getReservedRegs(const MachineFunction &MF) const override
static bool isImmU6(unsigned val)
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
Definition: Function.h:573
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
Representation of each machine instruction.
Definition: MachineInstr.h:64
static bool isImmU16(unsigned val)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned scavengeRegister(const TargetRegisterClass *RC, MachineBasicBlock::iterator I, int SPAdj)
Make a register of the specific register class available and do the appropriate bookkeeping.
static void InsertSPConstInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, int Offset, RegScavenger *RS)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
static void InsertFPImmInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, unsigned FrameReg, int Offset)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setRegUsed(unsigned Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
IRTranslator LLVM IR MI
#define LLVM_DEBUG(X)
Definition: Debug.h:123
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...