LLVM  13.0.0git
AVRRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- AVRRegisterInfo.cpp - AVR 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 AVR implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AVRRegisterInfo.h"
14 
15 #include "llvm/ADT/BitVector.h"
20 #include "llvm/IR/Function.h"
22 
23 #include "AVR.h"
24 #include "AVRInstrInfo.h"
25 #include "AVRMachineFunctionInfo.h"
26 #include "AVRTargetMachine.h"
28 
29 #define GET_REGINFO_TARGET_DESC
30 #include "AVRGenRegisterInfo.inc"
31 
32 namespace llvm {
33 
35 
36 const uint16_t *
39 
40  return AFI->isInterruptOrSignalHandler()
41  ? CSR_Interrupts_SaveList
42  : CSR_Normal_SaveList;
43 }
44 
45 const uint32_t *
47  CallingConv::ID CC) const {
49 
50  return AFI->isInterruptOrSignalHandler()
51  ? CSR_Interrupts_RegMask
52  : CSR_Normal_RegMask;
53 }
54 
56  BitVector Reserved(getNumRegs());
57 
58  // Reserve the intermediate result registers r1 and r2
59  // The result of instructions like 'mul' is always stored here.
60  Reserved.set(AVR::R0);
61  Reserved.set(AVR::R1);
62  Reserved.set(AVR::R1R0);
63 
64  // Reserve the stack pointer.
65  Reserved.set(AVR::SPL);
66  Reserved.set(AVR::SPH);
67  Reserved.set(AVR::SP);
68 
69  // We tenatively reserve the frame pointer register r29:r28 because the
70  // function may require one, but we cannot tell until register allocation
71  // is complete, which can be too late.
72  //
73  // Instead we just unconditionally reserve the Y register.
74  //
75  // TODO: Write a pass to enumerate functions which reserved the Y register
76  // but didn't end up needing a frame pointer. In these, we can
77  // convert one or two of the spills inside to use the Y register.
78  Reserved.set(AVR::R28);
79  Reserved.set(AVR::R29);
80  Reserved.set(AVR::R29R28);
81 
82  return Reserved;
83 }
84 
85 const TargetRegisterClass *
87  const MachineFunction &MF) const {
89  if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
90  return &AVR::DREGSRegClass;
91  }
92 
93  if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
94  return &AVR::GPR8RegClass;
95  }
96 
97  llvm_unreachable("Invalid register size");
98 }
99 
100 /// Fold a frame offset shared between two add instructions into a single one.
102  Register DstReg) {
103  MachineInstr &MI = *II;
104  int Opcode = MI.getOpcode();
105 
106  // Don't bother trying if the next instruction is not an add or a sub.
107  if ((Opcode != AVR::SUBIWRdK) && (Opcode != AVR::ADIWRdK)) {
108  return;
109  }
110 
111  // Check that DstReg matches with next instruction, otherwise the instruction
112  // is not related to stack address manipulation.
113  if (DstReg != MI.getOperand(0).getReg()) {
114  return;
115  }
116 
117  // Add the offset in the next instruction to our offset.
118  switch (Opcode) {
119  case AVR::SUBIWRdK:
120  Offset += -MI.getOperand(2).getImm();
121  break;
122  case AVR::ADIWRdK:
123  Offset += MI.getOperand(2).getImm();
124  break;
125  }
126 
127  // Finally remove the instruction.
128  II++;
129  MI.eraseFromParent();
130 }
131 
133  int SPAdj, unsigned FIOperandNum,
134  RegScavenger *RS) const {
135  assert(SPAdj == 0 && "Unexpected SPAdj value");
136 
137  MachineInstr &MI = *II;
138  DebugLoc dl = MI.getDebugLoc();
139  MachineBasicBlock &MBB = *MI.getParent();
140  const MachineFunction &MF = *MBB.getParent();
141  const AVRTargetMachine &TM = (const AVRTargetMachine &)MF.getTarget();
142  const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
143  const MachineFrameInfo &MFI = MF.getFrameInfo();
144  const TargetFrameLowering *TFI = TM.getSubtargetImpl()->getFrameLowering();
145  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
146  int Offset = MFI.getObjectOffset(FrameIndex);
147 
148  // Add one to the offset because SP points to an empty slot.
149  Offset += MFI.getStackSize() - TFI->getOffsetOfLocalArea() + 1;
150  // Fold incoming offset.
151  Offset += MI.getOperand(FIOperandNum + 1).getImm();
152 
153  // This is actually "load effective address" of the stack slot
154  // instruction. We have only two-address instructions, thus we need to
155  // expand it into move + add.
156  if (MI.getOpcode() == AVR::FRMIDX) {
157  MI.setDesc(TII.get(AVR::MOVWRdRr));
158  MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
159  MI.RemoveOperand(2);
160 
161  assert(Offset > 0 && "Invalid offset");
162 
163  // We need to materialize the offset via an add instruction.
164  unsigned Opcode;
165  Register DstReg = MI.getOperand(0).getReg();
166  assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
167 
168  II++; // Skip over the FRMIDX (and now MOVW) instruction.
169 
170  // Generally, to load a frame address two add instructions are emitted that
171  // could get folded into a single one:
172  // movw r31:r30, r29:r28
173  // adiw r31:r30, 29
174  // adiw r31:r30, 16
175  // to:
176  // movw r31:r30, r29:r28
177  // adiw r31:r30, 45
178  if (II != MBB.end())
179  foldFrameOffset(II, Offset, DstReg);
180 
181  // Select the best opcode based on DstReg and the offset size.
182  switch (DstReg) {
183  case AVR::R25R24:
184  case AVR::R27R26:
185  case AVR::R31R30: {
186  if (isUInt<6>(Offset)) {
187  Opcode = AVR::ADIWRdK;
188  break;
189  }
191  }
192  default: {
193  // This opcode will get expanded into a pair of subi/sbci.
194  Opcode = AVR::SUBIWRdK;
195  Offset = -Offset;
196  break;
197  }
198  }
199 
200  MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
201  .addReg(DstReg, RegState::Kill)
202  .addImm(Offset);
203  New->getOperand(3).setIsDead();
204 
205  return;
206  }
207 
208  // If the offset is too big we have to adjust and restore the frame pointer
209  // to materialize a valid load/store with displacement.
210  //:TODO: consider using only one adiw/sbiw chain for more than one frame index
211  if (Offset > 62) {
212  unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK;
213  int AddOffset = Offset - 63 + 1;
214 
215  // For huge offsets where adiw/sbiw cannot be used use a pair of subi/sbci.
216  if ((Offset - 63 + 1) > 63) {
217  AddOpc = AVR::SUBIWRdK;
218  SubOpc = AVR::SUBIWRdK;
219  AddOffset = -AddOffset;
220  }
221 
222  // It is possible that the spiller places this frame instruction in between
223  // a compare and branch, invalidating the contents of SREG set by the
224  // compare instruction because of the add/sub pairs. Conservatively save and
225  // restore SREG before and after each add/sub pair.
226  BuildMI(MBB, II, dl, TII.get(AVR::INRdA), AVR::R0).addImm(0x3f);
227 
228  MachineInstr *New = BuildMI(MBB, II, dl, TII.get(AddOpc), AVR::R29R28)
229  .addReg(AVR::R29R28, RegState::Kill)
230  .addImm(AddOffset);
231  New->getOperand(3).setIsDead();
232 
233  // Restore SREG.
234  BuildMI(MBB, std::next(II), dl, TII.get(AVR::OUTARr))
235  .addImm(0x3f)
236  .addReg(AVR::R0, RegState::Kill);
237 
238  // No need to set SREG as dead here otherwise if the next instruction is a
239  // cond branch it will be using a dead register.
240  BuildMI(MBB, std::next(II), dl, TII.get(SubOpc), AVR::R29R28)
241  .addReg(AVR::R29R28, RegState::Kill)
242  .addImm(Offset - 63 + 1);
243 
244  Offset = 62;
245  }
246 
247  MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
248  assert(isUInt<6>(Offset) && "Offset is out of range");
249  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
250 }
251 
254  if (TFI->hasFP(MF)) {
255  // The Y pointer register
256  return AVR::R28;
257  }
258 
259  return AVR::SP;
260 }
261 
262 const TargetRegisterClass *
264  unsigned Kind) const {
265  // FIXME: Currently we're using avr-gcc as reference, so we restrict
266  // ptrs to Y and Z regs. Though avr-gcc has buggy implementation
267  // of memory constraint, so we can fix it and bit avr-gcc here ;-)
268  return &AVR::PTRDISPREGSRegClass;
269 }
270 
272  Register &HiReg) const {
273  assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers");
274 
275  LoReg = getSubReg(Reg, AVR::sub_lo);
276  HiReg = getSubReg(Reg, AVR::sub_hi);
277 }
278 
280  const TargetRegisterClass *SrcRC,
281  unsigned SubReg,
282  const TargetRegisterClass *DstRC,
283  unsigned DstSubReg,
284  const TargetRegisterClass *NewRC,
285  LiveIntervals &LIS) const {
286  if(this->getRegClass(AVR::PTRDISPREGSRegClassID)->hasSubClassEq(NewRC)) {
287  return false;
288  }
289 
290  return TargetRegisterInfo::shouldCoalesce(MI, SrcRC, SubReg, DstRC, DstSubReg, NewRC, LIS);
291 }
292 
293 } // end of namespace llvm
llvm::AVRRegisterInfo::getCalleeSavedRegs
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=0) const override
Definition: AVRRegisterInfo.cpp:37
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
TargetFrameLowering.h
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:43
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::AVRTargetMachine
A generic AVR implementation.
Definition: AVRTargetMachine.h:28
llvm::AVRRegisterInfo::shouldCoalesce
bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override
Definition: AVRRegisterInfo.cpp:279
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
MachineRegisterInfo.h
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::TargetFrameLowering::getOffsetOfLocalArea
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Definition: TargetFrameLowering.h:140
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:674
llvm::AVRRegisterInfo::AVRRegisterInfo
AVRRegisterInfo()
Definition: AVRRegisterInfo.cpp:34
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
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::AVRRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: AVRRegisterInfo.cpp:252
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
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
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:95
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:576
llvm::AVRRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: AVRRegisterInfo.cpp:55
AVRGenRegisterInfo
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::RegScavenger
Definition: RegisterScavenging.h:34
AVRTargetMachine.h
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:41
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:592
AVRMCTargetDesc.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
llvm::foldFrameOffset
static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, Register DstReg)
Fold a frame offset shared between two add instructions into a single one.
Definition: AVRRegisterInfo.cpp:101
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::AVRRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override
Definition: AVRRegisterInfo.cpp:46
AVRRegisterInfo.h
llvm::TargetRegisterInfo::shouldCoalesce
virtual bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const
Subtarget Hooks.
Definition: TargetRegisterInfo.h:1023
llvm::AVRRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const override
Stack Frame Processing Methods.
Definition: AVRRegisterInfo.cpp:132
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
uint32_t
AVRMachineFunctionInfo.h
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:281
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:73
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:93
uint16_t
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:572
MachineFrameInfo.h
Function.h
llvm::AVRRegisterInfo::getLargestLegalSuperClass
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
Definition: AVRRegisterInfo.cpp:86
llvm::AVRRegisterInfo::splitReg
void splitReg(Register Reg, Register &LoReg, Register &HiReg) const
Splits a 16-bit DREGS register into the lo/hi register pair.
Definition: AVRRegisterInfo.cpp:271
getRegClass
static int getRegClass(RegisterKind Is, unsigned RegWidth)
Definition: AMDGPUAsmParser.cpp:2185
llvm::LiveIntervals
Definition: LiveIntervals.h:54
AVR.h
llvm::AVRMachineFunctionInfo::isInterruptOrSignalHandler
bool isInterruptOrSignalHandler() const
Checks if the function is some form of interrupt service routine.
Definition: AVRMachineFunctionInfo.h:72
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
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::PseudoProbeAttributes::Reserved
@ Reserved
llvm::AVRMachineFunctionInfo
Contains AVR-specific information for each MachineFunction.
Definition: AVRMachineFunctionInfo.h:21
AVRInstrInfo.h
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:42
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
SubReg
unsigned SubReg
Definition: AArch64AdvSIMDScalarPass.cpp:104
llvm::AVRRegisterInfo::getPointerRegClass
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
Definition: AVRRegisterInfo.cpp:263