LLVM  10.0.0svn
RISCVRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- RISCVRegisterInfo.cpp - RISCV Register Information ------*- C++ -*-===//
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 RISCV implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVRegisterInfo.h"
14 #include "RISCV.h"
15 #include "RISCVSubtarget.h"
23 
24 #define GET_REGINFO_TARGET_DESC
25 #include "RISCVGenRegisterInfo.inc"
26 
27 using namespace llvm;
28 
29 static_assert(RISCV::X1 == RISCV::X0 + 1, "Register list not consecutive");
30 static_assert(RISCV::X31 == RISCV::X0 + 31, "Register list not consecutive");
31 static_assert(RISCV::F1_F == RISCV::F0_F + 1, "Register list not consecutive");
32 static_assert(RISCV::F31_F == RISCV::F0_F + 31,
33  "Register list not consecutive");
34 static_assert(RISCV::F1_D == RISCV::F0_D + 1, "Register list not consecutive");
35 static_assert(RISCV::F31_D == RISCV::F0_D + 31,
36  "Register list not consecutive");
37 
39  : RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0,
40  /*PC*/0, HwMode) {}
41 
42 const MCPhysReg *
44  auto &Subtarget = MF->getSubtarget<RISCVSubtarget>();
45  if (MF->getFunction().hasFnAttribute("interrupt")) {
46  if (Subtarget.hasStdExtD())
47  return CSR_XLEN_F64_Interrupt_SaveList;
48  if (Subtarget.hasStdExtF())
49  return CSR_XLEN_F32_Interrupt_SaveList;
50  return CSR_Interrupt_SaveList;
51  }
52 
53  switch (Subtarget.getTargetABI()) {
54  default:
55  llvm_unreachable("Unrecognized ABI");
57  case RISCVABI::ABI_LP64:
58  return CSR_ILP32_LP64_SaveList;
61  return CSR_ILP32F_LP64F_SaveList;
64  return CSR_ILP32D_LP64D_SaveList;
65  }
66 }
67 
69  const TargetFrameLowering *TFI = getFrameLowering(MF);
70  BitVector Reserved(getNumRegs());
71 
72  // Use markSuperRegs to ensure any register aliases are also reserved
73  markSuperRegs(Reserved, RISCV::X0); // zero
74  markSuperRegs(Reserved, RISCV::X1); // ra
75  markSuperRegs(Reserved, RISCV::X2); // sp
76  markSuperRegs(Reserved, RISCV::X3); // gp
77  markSuperRegs(Reserved, RISCV::X4); // tp
78  if (TFI->hasFP(MF))
79  markSuperRegs(Reserved, RISCV::X8); // fp
80  assert(checkAllSuperRegsMarked(Reserved));
81  return Reserved;
82 }
83 
84 bool RISCVRegisterInfo::isConstantPhysReg(unsigned PhysReg) const {
85  return PhysReg == RISCV::X0;
86 }
87 
89  return CSR_NoRegs_RegMask;
90 }
91 
93  int SPAdj, unsigned FIOperandNum,
94  RegScavenger *RS) const {
95  assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
96 
97  MachineInstr &MI = *II;
98  MachineFunction &MF = *MI.getParent()->getParent();
100  const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
101  DebugLoc DL = MI.getDebugLoc();
102 
103  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
104  unsigned FrameReg;
105  int Offset =
106  getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg) +
107  MI.getOperand(FIOperandNum + 1).getImm();
108 
109  if (!isInt<32>(Offset)) {
111  "Frame offsets outside of the signed 32-bit range not supported");
112  }
113 
114  MachineBasicBlock &MBB = *MI.getParent();
115  bool FrameRegIsKill = false;
116 
117  if (!isInt<12>(Offset)) {
118  assert(isInt<32>(Offset) && "Int32 expected");
119  // The offset won't fit in an immediate, so use a scratch register instead
120  // Modify Offset and FrameReg appropriately
121  Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
122  TII->movImm(MBB, II, DL, ScratchReg, Offset);
123  BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
124  .addReg(FrameReg)
125  .addReg(ScratchReg, RegState::Kill);
126  Offset = 0;
127  FrameReg = ScratchReg;
128  FrameRegIsKill = true;
129  }
130 
131  MI.getOperand(FIOperandNum)
132  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
133  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
134 }
135 
137  const TargetFrameLowering *TFI = getFrameLowering(MF);
138  return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2;
139 }
140 
141 const uint32_t *
143  CallingConv::ID /*CC*/) const {
144  auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
145  if (MF.getFunction().hasFnAttribute("interrupt")) {
146  if (Subtarget.hasStdExtD())
147  return CSR_XLEN_F64_Interrupt_RegMask;
148  if (Subtarget.hasStdExtF())
149  return CSR_XLEN_F32_Interrupt_RegMask;
150  return CSR_Interrupt_RegMask;
151  }
152 
153  switch (Subtarget.getTargetABI()) {
154  default:
155  llvm_unreachable("Unrecognized ABI");
156  case RISCVABI::ABI_ILP32:
157  case RISCVABI::ABI_LP64:
158  return CSR_ILP32_LP64_RegMask;
160  case RISCVABI::ABI_LP64F:
161  return CSR_ILP32F_LP64F_RegMask;
163  case RISCVABI::ABI_LP64D:
164  return CSR_ILP32D_LP64D_RegMask;
165  }
166 }
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Register getFrameRegister(const MachineFunction &MF) const override
const uint32_t * getNoPreservedMask() const override
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:384
BitVector getReservedRegs(const MachineFunction &MF) const override
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:323
A debug info location.
Definition: DebugLoc.h:33
bool isConstantPhysReg(unsigned PhysReg) const override
RISCVRegisterInfo(unsigned HwMode)
const HexagonInstrInfo * TII
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
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...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:345
Information about stack frame layout on the target.
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:255
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
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