LLVM  15.0.0git
CSKYRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- 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 CSKY implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CSKYRegisterInfo.h"
14 #include "CSKY.h"
15 #include "CSKYSubtarget.h"
19 #include "llvm/MC/MCContext.h"
20 
21 #define GET_REGINFO_TARGET_DESC
22 #include "CSKYGenRegisterInfo.inc"
23 
24 using namespace llvm;
25 
27  : CSKYGenRegisterInfo(CSKY::R15, 0, 0, 0) {}
28 
29 const uint32_t *
31  CallingConv::ID Id) const {
32  const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();
33  if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())
34  return CSR_GPR_FPR64_RegMask;
35  if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())
36  return CSR_GPR_FPR32_RegMask;
37  return CSR_I32_RegMask;
38 }
39 
41  const TargetFrameLowering *TFI = getFrameLowering(MF);
42  return TFI->hasFP(MF) ? CSKY::R8 : CSKY::R14;
43 }
44 
46  const CSKYFrameLowering *TFI = getFrameLowering(MF);
47  const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();
48  BitVector Reserved(getNumRegs());
49 
50  // Reserve the base register if we need to allocate
51  // variable-sized objects at runtime.
52  if (TFI->hasBP(MF))
53  markSuperRegs(Reserved, CSKY::R7); // bp
54 
55  if (TFI->hasFP(MF))
56  markSuperRegs(Reserved, CSKY::R8); // fp
57 
58  if (!STI.hasE2()) {
59  for (unsigned i = 0; i < 6; i++)
60  markSuperRegs(Reserved, CSKY::R8 + i); // R8 - R13
61  }
62 
63  markSuperRegs(Reserved, CSKY::R14); // sp
64  markSuperRegs(Reserved, CSKY::R15); // lr
65 
66  if (!STI.hasHighRegisters()) {
67  for (unsigned i = 0; i < 10; i++)
68  markSuperRegs(Reserved, CSKY::R16 + i); // R16 - R25
69  }
70 
71  markSuperRegs(Reserved, CSKY::R26);
72  markSuperRegs(Reserved, CSKY::R27);
73  markSuperRegs(Reserved, CSKY::R28); // gp
74  markSuperRegs(Reserved, CSKY::R29);
75  markSuperRegs(Reserved, CSKY::R30);
76  markSuperRegs(Reserved, CSKY::R31); // tp
77 
78  assert(checkAllSuperRegsMarked(Reserved));
79  return Reserved;
80 }
81 
83  return CSR_NoRegs_RegMask;
84 }
85 
86 const MCPhysReg *
88  const CSKYSubtarget &STI = MF->getSubtarget<CSKYSubtarget>();
89  if (MF->getFunction().hasFnAttribute("interrupt")) {
90  if (STI.hasFPUv3DoubleFloat())
91  return CSR_GPR_FPR64v3_ISR_SaveList;
92  if (STI.hasFPUv3SingleFloat())
93  return CSR_GPR_FPR32v3_ISR_SaveList;
94  if (STI.hasFPUv2DoubleFloat())
95  return CSR_GPR_FPR64_ISR_SaveList;
96  if (STI.hasFPUv2SingleFloat())
97  return CSR_GPR_FPR32_ISR_SaveList;
98  return CSR_GPR_ISR_SaveList;
99  }
100 
101  if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())
102  return CSR_GPR_FPR64_SaveList;
103  if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())
104  return CSR_GPR_FPR32_SaveList;
105  return CSR_I32_SaveList;
106 }
107 
109  int &Offset) {
110  const MCInstrDesc &Desc = MI->getDesc();
111  unsigned AddrMode = (Desc.TSFlags & CSKYII::AddrModeMask);
112  unsigned i = 0;
113  for (; !MI->getOperand(i).isFI(); ++i) {
114  assert(i + 1 < MI->getNumOperands() &&
115  "Instr doesn't have FrameIndex operand!");
116  }
117 
118  if (MI->getOpcode() == CSKY::ADDI32) {
119  if (!isUInt<12>(std::abs(Offset) - 1))
120  return false;
121  if (Offset < 0) {
122  MI->setDesc(TII->get(CSKY::SUBI32));
123  Offset = -Offset;
124  }
125 
126  return true;
127  }
128 
129  if (MI->getOpcode() == CSKY::ADDI16XZ)
130  return false;
131 
132  if (Offset < 0)
133  return false;
134 
135  unsigned NumBits = 0;
136  unsigned Scale = 1;
137  switch (AddrMode) {
138  case CSKYII::AddrMode32B:
139  Scale = 1;
140  NumBits = 12;
141  break;
142  case CSKYII::AddrMode32H:
143  Scale = 2;
144  NumBits = 12;
145  break;
147  Scale = 4;
148  NumBits = 12;
149  break;
150  case CSKYII::AddrMode16B:
151  Scale = 1;
152  NumBits = 5;
153  break;
154  case CSKYII::AddrMode16H:
155  Scale = 2;
156  NumBits = 5;
157  break;
158  case CSKYII::AddrMode16W:
159  Scale = 4;
160  NumBits = 5;
161  break;
163  Scale = 4;
164  NumBits = 8;
165  break;
166  default:
167  llvm_unreachable("Unsupported addressing mode!");
168  }
169 
170  // Cannot encode offset.
171  if ((Offset & (Scale - 1)) != 0)
172  return false;
173 
174  unsigned Mask = (1 << NumBits) - 1;
175  if ((unsigned)Offset <= Mask * Scale)
176  return true;
177 
178  // Offset out of range.
179  return false;
180 }
181 
183  int SPAdj, unsigned FIOperandNum,
184  RegScavenger *RS) const {
185  assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
186 
187  MachineInstr *MI = &*II;
188  MachineBasicBlock &MBB = *MI->getParent();
189  MachineFunction &MF = *MI->getParent()->getParent();
191  const CSKYInstrInfo *TII = MF.getSubtarget<CSKYSubtarget>().getInstrInfo();
192  DebugLoc DL = MI->getDebugLoc();
193  const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();
194 
195  switch (MI->getOpcode()) {
196  default:
197  break;
198  case CSKY::RESTORE_CARRY: {
199  Register NewReg = STI.hasE2()
200  ? MRI.createVirtualRegister(&CSKY::GPRRegClass)
201  : MRI.createVirtualRegister(&CSKY::mGPRRegClass);
202 
203  auto *Temp = BuildMI(MBB, II, DL, TII->get(CSKY::LD32W), NewReg)
204  .add(MI->getOperand(1))
205  .add(MI->getOperand(2))
206  .getInstr();
207 
208  BuildMI(MBB, II, DL, TII->get(STI.hasE2() ? CSKY::BTSTI32 : CSKY::BTSTI16),
209  MI->getOperand(0).getReg())
210  .addReg(NewReg, getKillRegState(true))
211  .addImm(0);
212 
213  MI = Temp;
214 
215  MBB.erase(II);
216  break;
217  }
218  case CSKY::SPILL_CARRY: {
219  Register NewReg;
220  if (STI.hasE2()) {
221  NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
222  BuildMI(MBB, II, DL, TII->get(CSKY::MVC32), NewReg)
223  .add(MI->getOperand(0));
224  } else {
225  NewReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);
226  BuildMI(MBB, II, DL, TII->get(CSKY::MOVI16), NewReg).addImm(0);
227  BuildMI(MBB, II, DL, TII->get(CSKY::ADDC16))
228  .addReg(NewReg, RegState::Define)
229  .addReg(MI->getOperand(0).getReg(), RegState::Define)
230  .addReg(NewReg, getKillRegState(true))
231  .addReg(NewReg, getKillRegState(true))
232  .addReg(MI->getOperand(0).getReg());
233 
234  BuildMI(MBB, II, DL, TII->get(CSKY::BTSTI16), MI->getOperand(0).getReg())
235  .addReg(NewReg)
236  .addImm(0);
237  }
238 
239  MI = BuildMI(MBB, II, DL, TII->get(CSKY::ST32W))
240  .addReg(NewReg, getKillRegState(true))
241  .add(MI->getOperand(1))
242  .add(MI->getOperand(2))
243  .getInstr();
244 
245  MBB.erase(II);
246 
247  break;
248  }
249  }
250 
251  int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
252  Register FrameReg;
253  int Offset = getFrameLowering(MF)
254  ->getFrameIndexReference(MF, FrameIndex, FrameReg)
255  .getFixed() +
256  MI->getOperand(FIOperandNum + 1).getImm();
257 
258  if (!isInt<32>(Offset))
260  "Frame offsets outside of the signed 32-bit range not supported");
261 
262  bool FrameRegIsKill = false;
264  if (!IsLegalOffset(TII, MI, Offset)) {
265  assert(isInt<32>(Offset) && "Int32 expected");
266  // The offset won't fit in an immediate, so use a scratch register instead
267  // Modify Offset and FrameReg appropriately
268  assert(Offset >= 0);
269  Register ScratchReg = TII->movImm(MBB, NewII, DL, Offset);
270  BuildMI(MBB, NewII, DL,
271  TII->get(STI.hasE2() ? CSKY::ADDU32 : CSKY::ADDU16XZ), ScratchReg)
272  .addReg(ScratchReg, RegState::Kill)
273  .addReg(FrameReg);
274 
275  Offset = 0;
276  FrameReg = ScratchReg;
277  FrameRegIsKill = true;
278  }
279 
280  if (Offset == 0 &&
281  (MI->getOpcode() == CSKY::ADDI32 || MI->getOpcode() == CSKY::ADDI16XZ)) {
282  MI->setDesc(TII->get(TargetOpcode::COPY));
283  MI->getOperand(FIOperandNum)
284  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
285  MI->removeOperand(FIOperandNum + 1);
286  } else {
287  MI->getOperand(FIOperandNum)
288  .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
289  MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
290  }
291 }
i
i
Definition: README.txt:29
llvm::CSKYII::AddrMode32SDF
@ AddrMode32SDF
Definition: CSKYBaseInfo.h:36
llvm::CSKYFrameLowering
Definition: CSKYFrameLowering.h:21
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::CSKYII::AddrMode32WD
@ AddrMode32WD
Definition: CSKYBaseInfo.h:32
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:43
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::CSKYRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override
Definition: CSKYRegisterInfo.cpp:182
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
CSKYRegisterInfo.h
llvm::CSKYInstrInfo
Definition: CSKYInstrInfo.h:26
llvm::CSKYII::AddrMode16W
@ AddrMode16W
Definition: CSKYBaseInfo.h:35
CSKY.h
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1295
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::CSKYRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: CSKYRegisterInfo.cpp:45
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:650
llvm::MCInstrDesc::TSFlags
uint64_t TSFlags
Definition: MCInstrDesc.h:205
llvm::CSKYSubtarget::hasFPUv2SingleFloat
bool hasFPUv2SingleFloat() const
Definition: CSKYSubtarget.h:139
CSKYSubtarget.h
MCContext.h
llvm::CSKYRegisterInfo::getNoPreservedMask
const uint32_t * getNoPreservedMask() const override
Definition: CSKYRegisterInfo.cpp:82
llvm::CSKYII::AddrMode16B
@ AddrMode16B
Definition: CSKYBaseInfo.h:33
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:127
llvm::CSKYRegisterInfo::CSKYRegisterInfo
CSKYRegisterInfo()
Definition: CSKYRegisterInfo.cpp:26
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:197
llvm::TargetFrameLowering::hasFP
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::BitVector
Definition: BitVector.h:75
llvm::CSKYFrameLowering::hasBP
bool hasBP(const MachineFunction &MF) const
Definition: CSKYFrameLowering.cpp:44
llvm::CSKYSubtarget
Definition: CSKYSubtarget.h:30
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::CSKYII::AddrMode16H
@ AddrMode16H
Definition: CSKYBaseInfo.h:34
llvm::CSKYFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Definition: CSKYFrameLowering.cpp:35
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:640
llvm::Function::hasFnAttribute
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:625
llvm::isInt< 32 >
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:373
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::CSKYII::AddrModeMask
@ AddrModeMask
Definition: CSKYBaseInfo.h:56
llvm::RegScavenger
Definition: RegisterScavenging.h:34
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::CSKYII::AddrMode32B
@ AddrMode32B
Definition: CSKYBaseInfo.h:30
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
CSKYGenRegisterInfo
llvm::MachineFunction
Definition: MachineFunction.h:241
llvm::CSKYRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: CSKYRegisterInfo.cpp:40
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
AddrMode
AddrMode
Definition: MSP430Disassembler.cpp:142
llvm::MachineInstrBuilder::getInstr
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Definition: MachineInstrBuilder.h:89
llvm::CSKYRegisterInfo::getCalleeSavedRegs
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Definition: CSKYRegisterInfo.cpp:87
llvm::CSKYII::AddrMode32H
@ AddrMode32H
Definition: CSKYBaseInfo.h:31
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:606
uint16_t
MachineFrameInfo.h
llvm::CSKYSubtarget::hasFPUv3SingleFloat
bool hasFPUv3SingleFloat() const
Definition: CSKYSubtarget.h:144
llvm::CSKYSubtarget::hasFPUv2DoubleFloat
bool hasFPUv2DoubleFloat() const
Definition: CSKYSubtarget.h:140
IsLegalOffset
static bool IsLegalOffset(const CSKYInstrInfo *TII, MachineInstr *MI, int &Offset)
Definition: CSKYRegisterInfo.cpp:108
llvm::CSKYSubtarget::hasFPUv3DoubleFloat
bool hasFPUv3DoubleFloat() const
Definition: CSKYSubtarget.h:145
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:508
llvm::CSKYRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID id) const override
Definition: CSKYRegisterInfo.cpp:30
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::CSKYSubtarget::hasE2
bool hasE2() const
Definition: CSKYSubtarget.h:187
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
RegisterScavenging.h
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:235
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::abs
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1281
llvm::CSKYSubtarget::hasHighRegisters
bool hasHighRegisters() const
Definition: CSKYSubtarget.h:168