LLVM  13.0.0git
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)
73  .addMemOperand(*MI.memoperands_begin());
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)
80  .addMemOperand(*MI.memoperands_begin());
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)
109  .addMemOperand(*MI.memoperands_begin());
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)
116  .addMemOperand(*MI.memoperands_begin());
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)
142  .addMemOperand(*MI.memoperands_begin());
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)
149  .addMemOperand(*MI.memoperands_begin());
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)
186  .addMemOperand(*MI.memoperands_begin());
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)
193  .addMemOperand(*MI.memoperands_begin());
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.needsFrameMoves();
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 false;
251 }
252 
253 void
255  int SPAdj, unsigned FIOperandNum,
256  RegScavenger *RS) const {
257  assert(SPAdj == 0 && "Unexpected");
258  MachineInstr &MI = *II;
259  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
260  int FrameIndex = FrameOp.getIndex();
261 
262  MachineFunction &MF = *MI.getParent()->getParent();
263  const XCoreInstrInfo &TII =
264  *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
265 
266  const XCoreFrameLowering *TFI = getFrameLowering(MF);
268  int StackSize = MF.getFrameInfo().getStackSize();
269 
270  #ifndef NDEBUG
271  LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n");
272  LLVM_DEBUG(errs() << "<--------->\n");
273  LLVM_DEBUG(MI.print(errs()));
274  LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n");
275  LLVM_DEBUG(errs() << "FrameOffset : " << Offset << "\n");
276  LLVM_DEBUG(errs() << "StackSize : " << StackSize << "\n");
277 #endif
278 
279  Offset += StackSize;
280 
281  Register FrameReg = getFrameRegister(MF);
282 
283  // Special handling of DBG_VALUE instructions.
284  if (MI.isDebugValue()) {
285  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
286  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
287  return;
288  }
289 
290  // fold constant into offset.
291  Offset += MI.getOperand(FIOperandNum + 1).getImm();
292  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
293 
294  assert(Offset%4 == 0 && "Misaligned stack offset");
295  LLVM_DEBUG(errs() << "Offset : " << Offset << "\n"
296  << "<--------->\n");
297  Offset/=4;
298 
299  Register Reg = MI.getOperand(0).getReg();
300  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
301 
302  if (TFI->hasFP(MF)) {
303  if (isImmUs(Offset))
304  InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
305  else
306  InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
307  } else {
308  if (isImmU16(Offset))
309  InsertSPImmInst(II, TII, Reg, Offset);
310  else
311  InsertSPConstInst(II, TII, Reg, Offset, RS);
312  }
313  // Erase old instruction.
314  MachineBasicBlock &MBB = *MI.getParent();
315  MBB.erase(II);
316 }
317 
318 
320  const XCoreFrameLowering *TFI = getFrameLowering(MF);
321 
322  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
323 }
XCoreRegisterInfo.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
MathExtras.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
TargetFrameLowering.h
llvm::XCoreRegisterInfo::requiresRegisterScavenging
bool requiresRegisterScavenging(const MachineFunction &MF) const override
Definition: XCoreRegisterInfo.cpp:244
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
XCore.h
XCoreGenRegisterInfo
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::XCoreFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Definition: XCoreFrameLowering.cpp:218
llvm::XCoreRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: XCoreRegisterInfo.cpp:229
ErrorHandling.h
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
R4
#define R4(n)
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
STLExtras.h
llvm::XCoreRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Definition: XCoreRegisterInfo.cpp:254
llvm::XCoreRegisterInfo::needsFrameMoves
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
Definition: XCoreRegisterInfo.cpp:205
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
MachineRegisterInfo.h
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1299
llvm::XCoreInstrInfo
Definition: XCoreInstrInfo.h:24
llvm::XCoreRegisterInfo::getCalleeSavedRegs
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
Definition: XCoreRegisterInfo.cpp:210
TargetMachine.h
llvm::RegScavenger::scavengeRegister
Register 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.
Definition: RegisterScavenging.cpp:521
XCoreInstrInfo.h
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
XCoreMachineFunctionInfo.h
BitVector.h
llvm::MachineFrameInfo::getStackSize
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Definition: MachineFrameInfo.h:551
llvm::MachineFrameInfo::getObjectOffset
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
Definition: MachineFrameInfo.h:492
llvm::BitVector
Definition: BitVector.h:74
XCoreSubtarget.h
Type.h
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::Pass::print
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:125
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:622
val
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 the input will be treated as an leaving the upper bits uninitialised For i64 store i32 val
Definition: README.txt:15
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
InsertSPImmInst
static void InsertSPImmInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, int Offset)
Definition: XCoreRegisterInfo.cpp:128
llvm::XCoreRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: XCoreRegisterInfo.cpp:319
llvm::RegScavenger
Definition: RegisterScavenging.h:34
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:541
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:638
InsertFPConstInst
static void InsertFPConstInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, unsigned FrameReg, int Offset, RegScavenger *RS)
Definition: XCoreRegisterInfo.cpp:92
llvm::MachineInstrBuilder::addMemOperand
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Definition: MachineInstrBuilder.h:202
MachineModuleInfo.h
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
R6
#define R6(n)
llvm::MachineFunction
Definition: MachineFunction.h:230
TargetOptions.h
isImmU6
static bool isImmU6(unsigned val)
Definition: XCoreRegisterInfo.cpp:52
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
isImmU16
static bool isImmU16(unsigned val)
Definition: XCoreRegisterInfo.cpp:56
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
llvm::HexagonISD::CP
@ CP
Definition: HexagonISelLowering.h:53
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::needsFrameMoves
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
Definition: MachineFunction.cpp:587
llvm::XCoreFrameLowering
Definition: XCoreFrameLowering.h:23
uint16_t
MachineFrameInfo.h
llvm::MachineOperand::getIndex
int getIndex() const
Definition: MachineOperand.h:557
llvm::RegScavenger::setRegUsed
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Definition: RegisterScavenging.cpp:53
Function.h
isImmUs
static bool isImmUs(unsigned val)
Definition: XCoreRegisterInfo.cpp:48
InsertFPImmInst
static void InsertFPImmInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, unsigned FrameReg, int Offset)
Definition: XCoreRegisterInfo.cpp:61
DP
So we should use XX3Form_Rcr to implement instrinsic Convert DP outs ins xscvdpsp No builtin are required Round &Convert QP DP(dword[1] is set to zero) No builtin are required Round to Quad Precision because you need to assign rounding mode in instruction Provide builtin(set f128:$vT,(int_ppc_vsx_xsrqpi f128:$vB))(set f128 yields< n x< ty > >< result > yields< ty >< result > No builtin are required Load Store load store see def memrix16 in PPCInstrInfo td Load Store Vector load store outs ins lxsdx set load store with conversion from to DP
Definition: README_P9.txt:520
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:508
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::XCoreRegisterInfo::XCoreRegisterInfo
XCoreRegisterInfo()
Definition: XCoreRegisterInfo.cpp:43
llvm::PseudoProbeAttributes::Reserved
@ Reserved
InsertSPConstInst
static void InsertSPConstInst(MachineBasicBlock::iterator II, const XCoreInstrInfo &TII, unsigned Reg, int Offset, RegScavenger *RS)
Definition: XCoreRegisterInfo.cpp:161
llvm::XCoreRegisterInfo::useFPForScavengingIndex
bool useFPForScavengingIndex(const MachineFunction &MF) const override
Definition: XCoreRegisterInfo.cpp:249
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
RegisterScavenging.h
raw_ostream.h
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
Debug.h