LLVM  6.0.0svn
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() ||
209 }
210 
211 const MCPhysReg *
213  // The callee saved registers LR & FP are explicitly handled during
214  // emitPrologue & emitEpilogue and related functions.
215  static const MCPhysReg CalleeSavedRegs[] = {
216  XCore::R4, XCore::R5, XCore::R6, XCore::R7,
217  XCore::R8, XCore::R9, XCore::R10,
218  0
219  };
220  static const MCPhysReg CalleeSavedRegsFP[] = {
221  XCore::R4, XCore::R5, XCore::R6, XCore::R7,
222  XCore::R8, XCore::R9,
223  0
224  };
225  const XCoreFrameLowering *TFI = getFrameLowering(*MF);
226  if (TFI->hasFP(*MF))
227  return CalleeSavedRegsFP;
228  return CalleeSavedRegs;
229 }
230 
232  BitVector Reserved(getNumRegs());
233  const XCoreFrameLowering *TFI = getFrameLowering(MF);
234 
235  Reserved.set(XCore::CP);
236  Reserved.set(XCore::DP);
237  Reserved.set(XCore::SP);
238  Reserved.set(XCore::LR);
239  if (TFI->hasFP(MF)) {
240  Reserved.set(XCore::R10);
241  }
242  return Reserved;
243 }
244 
245 bool
247  return true;
248 }
249 
250 bool
252  return true;
253 }
254 
255 bool
257  return false;
258 }
259 
260 void
262  int SPAdj, unsigned FIOperandNum,
263  RegScavenger *RS) const {
264  assert(SPAdj == 0 && "Unexpected");
265  MachineInstr &MI = *II;
266  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
267  int FrameIndex = FrameOp.getIndex();
268 
269  MachineFunction &MF = *MI.getParent()->getParent();
270  const XCoreInstrInfo &TII =
271  *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
272 
273  const XCoreFrameLowering *TFI = getFrameLowering(MF);
274  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
275  int StackSize = MF.getFrameInfo().getStackSize();
276 
277  #ifndef NDEBUG
278  DEBUG(errs() << "\nFunction : "
279  << MF.getName() << "\n");
280  DEBUG(errs() << "<--------->\n");
281  DEBUG(MI.print(errs()));
282  DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n");
283  DEBUG(errs() << "FrameOffset : " << Offset << "\n");
284  DEBUG(errs() << "StackSize : " << StackSize << "\n");
285  #endif
286 
287  Offset += StackSize;
288 
289  unsigned FrameReg = getFrameRegister(MF);
290 
291  // Special handling of DBG_VALUE instructions.
292  if (MI.isDebugValue()) {
293  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
294  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
295  return;
296  }
297 
298  // fold constant into offset.
299  Offset += MI.getOperand(FIOperandNum + 1).getImm();
300  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
301 
302  assert(Offset%4 == 0 && "Misaligned stack offset");
303  DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
304  Offset/=4;
305 
306  unsigned Reg = MI.getOperand(0).getReg();
307  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
308 
309  if (TFI->hasFP(MF)) {
310  if (isImmUs(Offset))
311  InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
312  else
313  InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
314  } else {
315  if (isImmU16(Offset))
316  InsertSPImmInst(II, TII, Reg, Offset);
317  else
318  InsertSPConstInst(II, TII, Reg, Offset, RS);
319  }
320  // Erase old instruction.
321  MachineBasicBlock &MBB = *MI.getParent();
322  MBB.erase(II);
323 }
324 
325 
327  const XCoreFrameLowering *TFI = getFrameLowering(MF);
328 
329  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
330 }
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.
Compute iterated dominance frontiers using a linear time algorithm.
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:257
unsigned getReg() const
getReg - Returns the register number.
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.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:279
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)
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:363
bool isDebugValue() const
Definition: MachineInstr.h:782
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
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
Definition: Function.h:497
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:139
Representation of each machine instruction.
Definition: MachineInstr.h:59
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.
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
void print(raw_ostream &OS, bool SkipOpers=false, bool SkipDebugLoc=false, const TargetInstrInfo *TII=nullptr) const
Debugging supportPrint this MI to OS.
static void InsertFPImmInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, unsigned FrameReg, int Offset)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setRegUsed(unsigned Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
#define DEBUG(X)
Definition: Debug.h:118
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:284
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned scavengeRegister(const TargetRegisterClass *RegClass, MachineBasicBlock::iterator I, int SPAdj)
Make a register of the specific register class available and do the appropriate bookkeeping.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...