LLVM  15.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"
21 #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  const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
40  if (STI.hasTinyEncoding())
41  return AFI->isInterruptOrSignalHandler() ? CSR_InterruptsTiny_SaveList
42  : CSR_NormalTiny_SaveList;
43  else
44  return AFI->isInterruptOrSignalHandler() ? CSR_Interrupts_SaveList
45  : CSR_Normal_SaveList;
46 }
47 
48 const uint32_t *
50  CallingConv::ID CC) const {
51  const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
52  return STI.hasTinyEncoding() ? CSR_NormalTiny_RegMask : 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  // R0/R1/R1R0 are always reserved on both avr and avrtiny.
61  Reserved.set(AVR::R0);
62  Reserved.set(AVR::R1);
63  Reserved.set(AVR::R1R0);
64 
65  // Reserve the stack pointer.
66  Reserved.set(AVR::SPL);
67  Reserved.set(AVR::SPH);
68  Reserved.set(AVR::SP);
69 
70  // Reserve R2~R17 only on avrtiny.
72  // Reserve 8-bit registers R2~R15, Rtmp(R16) and Zero(R17).
73  for (unsigned Reg = AVR::R2; Reg <= AVR::R17; Reg++)
74  Reserved.set(Reg);
75  // Reserve 16-bit registers R3R2~R18R17.
76  for (unsigned Reg = AVR::R3R2; Reg <= AVR::R18R17; Reg++)
77  Reserved.set(Reg);
78  }
79 
80  // We tenatively reserve the frame pointer register r29:r28 because the
81  // function may require one, but we cannot tell until register allocation
82  // is complete, which can be too late.
83  //
84  // Instead we just unconditionally reserve the Y register.
85  //
86  // TODO: Write a pass to enumerate functions which reserved the Y register
87  // but didn't end up needing a frame pointer. In these, we can
88  // convert one or two of the spills inside to use the Y register.
89  Reserved.set(AVR::R28);
90  Reserved.set(AVR::R29);
91  Reserved.set(AVR::R29R28);
92 
93  return Reserved;
94 }
95 
96 const TargetRegisterClass *
98  const MachineFunction &MF) const {
100  if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
101  return &AVR::DREGSRegClass;
102  }
103 
104  if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
105  return &AVR::GPR8RegClass;
106  }
107 
108  llvm_unreachable("Invalid register size");
109 }
110 
111 /// Fold a frame offset shared between two add instructions into a single one.
112 static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset,
113  Register DstReg) {
114  MachineInstr &MI = *II;
115  int Opcode = MI.getOpcode();
116 
117  // Don't bother trying if the next instruction is not an add or a sub.
118  if ((Opcode != AVR::SUBIWRdK) && (Opcode != AVR::ADIWRdK)) {
119  return;
120  }
121 
122  // Check that DstReg matches with next instruction, otherwise the instruction
123  // is not related to stack address manipulation.
124  if (DstReg != MI.getOperand(0).getReg()) {
125  return;
126  }
127 
128  // Add the offset in the next instruction to our offset.
129  switch (Opcode) {
130  case AVR::SUBIWRdK:
131  Offset += -MI.getOperand(2).getImm();
132  break;
133  case AVR::ADIWRdK:
134  Offset += MI.getOperand(2).getImm();
135  break;
136  }
137 
138  // Finally remove the instruction.
139  II++;
140  MI.eraseFromParent();
141 }
142 
144  int SPAdj, unsigned FIOperandNum,
145  RegScavenger *RS) const {
146  assert(SPAdj == 0 && "Unexpected SPAdj value");
147 
148  MachineInstr &MI = *II;
149  DebugLoc dl = MI.getDebugLoc();
150  MachineBasicBlock &MBB = *MI.getParent();
151  const MachineFunction &MF = *MBB.getParent();
152  const AVRTargetMachine &TM = (const AVRTargetMachine &)MF.getTarget();
153  const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
154  const MachineFrameInfo &MFI = MF.getFrameInfo();
155  const TargetFrameLowering *TFI = TM.getSubtargetImpl()->getFrameLowering();
156  const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
157  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
158  int Offset = MFI.getObjectOffset(FrameIndex);
159 
160  // Add one to the offset because SP points to an empty slot.
161  Offset += MFI.getStackSize() - TFI->getOffsetOfLocalArea() + 1;
162  // Fold incoming offset.
163  Offset += MI.getOperand(FIOperandNum + 1).getImm();
164 
165  // This is actually "load effective address" of the stack slot
166  // instruction. We have only two-address instructions, thus we need to
167  // expand it into move + add.
168  if (MI.getOpcode() == AVR::FRMIDX) {
169  MI.setDesc(TII.get(AVR::MOVWRdRr));
170  MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
171  MI.removeOperand(2);
172 
173  assert(Offset > 0 && "Invalid offset");
174 
175  // We need to materialize the offset via an add instruction.
176  unsigned Opcode;
177  Register DstReg = MI.getOperand(0).getReg();
178  assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
179 
180  II++; // Skip over the FRMIDX (and now MOVW) instruction.
181 
182  // Generally, to load a frame address two add instructions are emitted that
183  // could get folded into a single one:
184  // movw r31:r30, r29:r28
185  // adiw r31:r30, 29
186  // adiw r31:r30, 16
187  // to:
188  // movw r31:r30, r29:r28
189  // adiw r31:r30, 45
190  if (II != MBB.end())
191  foldFrameOffset(II, Offset, DstReg);
192 
193  // Select the best opcode based on DstReg and the offset size.
194  switch (DstReg) {
195  case AVR::R25R24:
196  case AVR::R27R26:
197  case AVR::R31R30: {
198  if (isUInt<6>(Offset)) {
199  Opcode = AVR::ADIWRdK;
200  break;
201  }
203  }
204  default: {
205  // This opcode will get expanded into a pair of subi/sbci.
206  Opcode = AVR::SUBIWRdK;
207  Offset = -Offset;
208  break;
209  }
210  }
211 
212  MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
213  .addReg(DstReg, RegState::Kill)
214  .addImm(Offset);
215  New->getOperand(3).setIsDead();
216 
217  return;
218  }
219 
220  // If the offset is too big we have to adjust and restore the frame pointer
221  // to materialize a valid load/store with displacement.
222  //: TODO: consider using only one adiw/sbiw chain for more than one frame
223  //: index
224  if (Offset > 62) {
225  unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK;
226  int AddOffset = Offset - 63 + 1;
227 
228  // For huge offsets where adiw/sbiw cannot be used use a pair of subi/sbci.
229  if ((Offset - 63 + 1) > 63) {
230  AddOpc = AVR::SUBIWRdK;
231  SubOpc = AVR::SUBIWRdK;
232  AddOffset = -AddOffset;
233  }
234 
235  // It is possible that the spiller places this frame instruction in between
236  // a compare and branch, invalidating the contents of SREG set by the
237  // compare instruction because of the add/sub pairs. Conservatively save and
238  // restore SREG before and after each add/sub pair.
239  BuildMI(MBB, II, dl, TII.get(AVR::INRdA), AVR::R0)
240  .addImm(STI.getIORegSREG());
241 
242  MachineInstr *New = BuildMI(MBB, II, dl, TII.get(AddOpc), AVR::R29R28)
243  .addReg(AVR::R29R28, RegState::Kill)
244  .addImm(AddOffset);
245  New->getOperand(3).setIsDead();
246 
247  // Restore SREG.
248  BuildMI(MBB, std::next(II), dl, TII.get(AVR::OUTARr))
249  .addImm(STI.getIORegSREG())
250  .addReg(AVR::R0, RegState::Kill);
251 
252  // No need to set SREG as dead here otherwise if the next instruction is a
253  // cond branch it will be using a dead register.
254  BuildMI(MBB, std::next(II), dl, TII.get(SubOpc), AVR::R29R28)
255  .addReg(AVR::R29R28, RegState::Kill)
256  .addImm(Offset - 63 + 1);
257 
258  Offset = 62;
259  }
260 
261  MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
262  assert(isUInt<6>(Offset) && "Offset is out of range");
263  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
264 }
265 
268  if (TFI->hasFP(MF)) {
269  // The Y pointer register
270  return AVR::R28;
271  }
272 
273  return AVR::SP;
274 }
275 
276 const TargetRegisterClass *
278  unsigned Kind) const {
279  // FIXME: Currently we're using avr-gcc as reference, so we restrict
280  // ptrs to Y and Z regs. Though avr-gcc has buggy implementation
281  // of memory constraint, so we can fix it and bit avr-gcc here ;-)
282  return &AVR::PTRDISPREGSRegClass;
283 }
284 
286  Register &HiReg) const {
287  assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers");
288 
289  LoReg = getSubReg(Reg, AVR::sub_lo);
290  HiReg = getSubReg(Reg, AVR::sub_hi);
291 }
292 
294  MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
295  const TargetRegisterClass *DstRC, unsigned DstSubReg,
296  const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
297  if (this->getRegClass(AVR::PTRDISPREGSRegClassID)->hasSubClassEq(NewRC)) {
298  return false;
299  }
300 
301  return TargetRegisterInfo::shouldCoalesce(MI, SrcRC, SubReg, DstRC, DstSubReg,
302  NewRC, LIS);
303 }
304 
305 } // end of namespace llvm
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
TargetFrameLowering.h
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:43
llvm::AVRSubtarget::hasTinyEncoding
bool hasTinyEncoding() const
Definition: AVRSubtarget.h:81
llvm::BitVector::set
BitVector & set()
Definition: BitVector.h:344
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::AVRTargetMachine
A generic AVR implementation.
Definition: AVRTargetMachine.h:28
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
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:293
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:125
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:234
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
MachineRegisterInfo.h
R2
#define R2(n)
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:754
llvm::AVRSubtarget
A specific AVR target MCU.
Definition: AVRSubtarget.h:31
llvm::AVRRegisterInfo::AVRRegisterInfo
AVRRegisterInfo()
Definition: AVRRegisterInfo.cpp:34
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
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:266
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:577
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:518
llvm::BitVector
Definition: BitVector.h:75
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:94
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
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:66
llvm::RegScavenger
Definition: RegisterScavenging.h:34
AVRTargetMachine.h
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:46
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AVRRegisterInfo::getCalleeSavedRegs
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=nullptr) const override
Definition: AVRRegisterInfo.cpp:37
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:672
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:112
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::AVRRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override
Definition: AVRRegisterInfo.cpp:49
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:1036
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
AVRMachineFunctionInfo.h
llvm::AVRSubtarget::getIORegSREG
int getIORegSREG(void) const
Definition: AVRSubtarget.h:99
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:280
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
getRegClass
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
Definition: AArch64InstrInfo.cpp:3190
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:94
uint16_t
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:652
MachineFrameInfo.h
Function.h
llvm::AVRRegisterInfo::getLargestLegalSuperClass
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
Definition: AVRRegisterInfo.cpp:97
llvm::AVRRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Stack Frame Processing Methods.
Definition: AVRRegisterInfo.cpp:143
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:285
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:81
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:105
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::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:47
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:277