LLVM  10.0.0svn
XCoreRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the XCore implementation of the MRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "XCoreRegisterInfo.h"
14 #include "XCore.h"
15 #include "XCoreInstrInfo.h"
17 #include "XCoreSubtarget.h"
18 #include "llvm/ADT/BitVector.h"
19 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/Type.h"
28 #include "llvm/Support/Debug.h"
35 
36 using namespace llvm;
37 
38 #define DEBUG_TYPE "xcore-reg-info"
39 
40 #define GET_REGINFO_TARGET_DESC
41 #include "XCoreGenRegisterInfo.inc"
42 
44  : XCoreGenRegisterInfo(XCore::LR) {
45 }
46 
47 // helper functions
48 static inline bool isImmUs(unsigned val) {
49  return val <= 11;
50 }
51 
52 static inline bool isImmU6(unsigned val) {
53  return val < (1 << 6);
54 }
55 
56 static inline bool isImmU16(unsigned val) {
57  return val < (1 << 16);
58 }
59 
60 
62  const XCoreInstrInfo &TII,
63  unsigned Reg, unsigned FrameReg, int Offset ) {
64  MachineInstr &MI = *II;
65  MachineBasicBlock &MBB = *MI.getParent();
66  DebugLoc dl = MI.getDebugLoc();
67 
68  switch (MI.getOpcode()) {
69  case XCore::LDWFI:
70  BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
71  .addReg(FrameReg)
72  .addImm(Offset)
74  break;
75  case XCore::STWFI:
76  BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
77  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
78  .addReg(FrameReg)
79  .addImm(Offset)
81  break;
82  case XCore::LDAWFI:
83  BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
84  .addReg(FrameReg)
85  .addImm(Offset);
86  break;
87  default:
88  llvm_unreachable("Unexpected Opcode");
89  }
90 }
91 
93  const XCoreInstrInfo &TII,
94  unsigned Reg, unsigned FrameReg,
95  int Offset, RegScavenger *RS ) {
96  assert(RS && "requiresRegisterScavenging failed");
97  MachineInstr &MI = *II;
98  MachineBasicBlock &MBB = *MI.getParent();
99  DebugLoc dl = MI.getDebugLoc();
100  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
101  RS->setRegUsed(ScratchOffset);
102  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
103 
104  switch (MI.getOpcode()) {
105  case XCore::LDWFI:
106  BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
107  .addReg(FrameReg)
108  .addReg(ScratchOffset, RegState::Kill)
110  break;
111  case XCore::STWFI:
112  BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
113  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
114  .addReg(FrameReg)
115  .addReg(ScratchOffset, RegState::Kill)
117  break;
118  case XCore::LDAWFI:
119  BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
120  .addReg(FrameReg)
121  .addReg(ScratchOffset, RegState::Kill);
122  break;
123  default:
124  llvm_unreachable("Unexpected Opcode");
125  }
126 }
127 
129  const XCoreInstrInfo &TII,
130  unsigned Reg, int Offset) {
131  MachineInstr &MI = *II;
132  MachineBasicBlock &MBB = *MI.getParent();
133  DebugLoc dl = MI.getDebugLoc();
134  bool isU6 = isImmU6(Offset);
135 
136  switch (MI.getOpcode()) {
137  int NewOpcode;
138  case XCore::LDWFI:
139  NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
140  BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
141  .addImm(Offset)
143  break;
144  case XCore::STWFI:
145  NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
146  BuildMI(MBB, II, dl, TII.get(NewOpcode))
147  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
148  .addImm(Offset)
150  break;
151  case XCore::LDAWFI:
152  NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
153  BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
154  .addImm(Offset);
155  break;
156  default:
157  llvm_unreachable("Unexpected Opcode");
158  }
159 }
160 
162  const XCoreInstrInfo &TII,
163  unsigned Reg, int Offset, RegScavenger *RS ) {
164  assert(RS && "requiresRegisterScavenging failed");
165  MachineInstr &MI = *II;
166  MachineBasicBlock &MBB = *MI.getParent();
167  DebugLoc dl = MI.getDebugLoc();
168  unsigned OpCode = MI.getOpcode();
169 
170  unsigned ScratchBase;
171  if (OpCode==XCore::STWFI) {
172  ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
173  RS->setRegUsed(ScratchBase);
174  } else
175  ScratchBase = Reg;
176  BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);
177  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
178  RS->setRegUsed(ScratchOffset);
179  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
180 
181  switch (OpCode) {
182  case XCore::LDWFI:
183  BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
184  .addReg(ScratchBase, RegState::Kill)
185  .addReg(ScratchOffset, RegState::Kill)
187  break;
188  case XCore::STWFI:
189  BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
190  .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
191  .addReg(ScratchBase, RegState::Kill)
192  .addReg(ScratchOffset, RegState::Kill)
194  break;
195  case XCore::LDAWFI:
196  BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
197  .addReg(ScratchBase, RegState::Kill)
198  .addReg(ScratchOffset, RegState::Kill);
199  break;
200  default:
201  llvm_unreachable("Unexpected Opcode");
202  }
203 }
204 
206  return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
207 }
208 
209 const MCPhysReg *
211  // The callee saved registers LR & FP are explicitly handled during
212  // emitPrologue & emitEpilogue and related functions.
213  static const MCPhysReg CalleeSavedRegs[] = {
214  XCore::R4, XCore::R5, XCore::R6, XCore::R7,
215  XCore::R8, XCore::R9, XCore::R10,
216  0
217  };
218  static const MCPhysReg CalleeSavedRegsFP[] = {
219  XCore::R4, XCore::R5, XCore::R6, XCore::R7,
220  XCore::R8, XCore::R9,
221  0
222  };
223  const XCoreFrameLowering *TFI = getFrameLowering(*MF);
224  if (TFI->hasFP(*MF))
225  return CalleeSavedRegsFP;
226  return CalleeSavedRegs;
227 }
228 
230  BitVector Reserved(getNumRegs());
231  const XCoreFrameLowering *TFI = getFrameLowering(MF);
232 
233  Reserved.set(XCore::CP);
234  Reserved.set(XCore::DP);
235  Reserved.set(XCore::SP);
236  Reserved.set(XCore::LR);
237  if (TFI->hasFP(MF)) {
238  Reserved.set(XCore::R10);
239  }
240  return Reserved;
241 }
242 
243 bool
245  return true;
246 }
247 
248 bool
250  return true;
251 }
252 
253 bool
255  return false;
256 }
257 
258 void
260  int SPAdj, unsigned FIOperandNum,
261  RegScavenger *RS) const {
262  assert(SPAdj == 0 && "Unexpected");
263  MachineInstr &MI = *II;
264  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
265  int FrameIndex = FrameOp.getIndex();
266 
267  MachineFunction &MF = *MI.getParent()->getParent();
268  const XCoreInstrInfo &TII =
269  *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
270 
271  const XCoreFrameLowering *TFI = getFrameLowering(MF);
272  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
273  int StackSize = MF.getFrameInfo().getStackSize();
274 
275  #ifndef NDEBUG
276  LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n");
277  LLVM_DEBUG(errs() << "<--------->\n");
278  LLVM_DEBUG(MI.print(errs()));
279  LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n");
280  LLVM_DEBUG(errs() << "FrameOffset : " << Offset << "\n");
281  LLVM_DEBUG(errs() << "StackSize : " << StackSize << "\n");
282 #endif
283 
284  Offset += StackSize;
285 
286  Register FrameReg = getFrameRegister(MF);
287 
288  // Special handling of DBG_VALUE instructions.
289  if (MI.isDebugValue()) {
290  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
291  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
292  return;
293  }
294 
295  // fold constant into offset.
296  Offset += MI.getOperand(FIOperandNum + 1).getImm();
297  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
298 
299  assert(Offset%4 == 0 && "Misaligned stack offset");
300  LLVM_DEBUG(errs() << "Offset : " << Offset << "\n"
301  << "<--------->\n");
302  Offset/=4;
303 
304  Register Reg = MI.getOperand(0).getReg();
305  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
306 
307  if (TFI->hasFP(MF)) {
308  if (isImmUs(Offset))
309  InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
310  else
311  InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
312  } else {
313  if (isImmU16(Offset))
314  InsertSPImmInst(II, TII, Reg, Offset);
315  else
316  InsertSPConstInst(II, TII, Reg, Offset, RS);
317  }
318  // Erase old instruction.
319  MachineBasicBlock &MBB = *MI.getParent();
320  MBB.erase(II);
321 }
322 
323 
325  const XCoreFrameLowering *TFI = getFrameLowering(MF);
326 
327  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
328 }
BitVector & set()
Definition: BitVector.h:397
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:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
unsigned Reg
A debug info location.
Definition: DebugLoc.h:33
MachineModuleInfo & getMMI() const
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override
Register getFrameRegister(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:411
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...
Definition: MCRegister.h:19
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)
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:552
bool isDebugValue() const
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:594
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
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.
void ChangeToRegister(Register 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...
static void InsertSPConstInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, int Offset, RegScavenger *RS)
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())
unsigned scavengeRegister(const TargetRegisterClass *RC, MachineBasicBlock::iterator I, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available and do the appropriate bookkeeping.
void setRegUsed(unsigned Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
IRTranslator LLVM IR MI
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...