LLVM  14.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 
40  return AFI->isInterruptOrSignalHandler() ? CSR_Interrupts_SaveList
41  : CSR_Normal_SaveList;
42 }
43 
44 const uint32_t *
46  CallingConv::ID CC) const {
48 
49  return AFI->isInterruptOrSignalHandler() ? CSR_Interrupts_RegMask
50  : CSR_Normal_RegMask;
51 }
52 
54  BitVector Reserved(getNumRegs());
55 
56  // Reserve the intermediate result registers r1 and r2
57  // The result of instructions like 'mul' is always stored here.
58  Reserved.set(AVR::R0);
59  Reserved.set(AVR::R1);
60  Reserved.set(AVR::R1R0);
61 
62  // Reserve the stack pointer.
63  Reserved.set(AVR::SPL);
64  Reserved.set(AVR::SPH);
65  Reserved.set(AVR::SP);
66 
67  // We tenatively reserve the frame pointer register r29:r28 because the
68  // function may require one, but we cannot tell until register allocation
69  // is complete, which can be too late.
70  //
71  // Instead we just unconditionally reserve the Y register.
72  //
73  // TODO: Write a pass to enumerate functions which reserved the Y register
74  // but didn't end up needing a frame pointer. In these, we can
75  // convert one or two of the spills inside to use the Y register.
76  Reserved.set(AVR::R28);
77  Reserved.set(AVR::R29);
78  Reserved.set(AVR::R29R28);
79 
80  return Reserved;
81 }
82 
83 const TargetRegisterClass *
85  const MachineFunction &MF) const {
87  if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
88  return &AVR::DREGSRegClass;
89  }
90 
91  if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
92  return &AVR::GPR8RegClass;
93  }
94 
95  llvm_unreachable("Invalid register size");
96 }
97 
98 /// Fold a frame offset shared between two add instructions into a single one.
100  Register DstReg) {
101  MachineInstr &MI = *II;
102  int Opcode = MI.getOpcode();
103 
104  // Don't bother trying if the next instruction is not an add or a sub.
105  if ((Opcode != AVR::SUBIWRdK) && (Opcode != AVR::ADIWRdK)) {
106  return;
107  }
108 
109  // Check that DstReg matches with next instruction, otherwise the instruction
110  // is not related to stack address manipulation.
111  if (DstReg != MI.getOperand(0).getReg()) {
112  return;
113  }
114 
115  // Add the offset in the next instruction to our offset.
116  switch (Opcode) {
117  case AVR::SUBIWRdK:
118  Offset += -MI.getOperand(2).getImm();
119  break;
120  case AVR::ADIWRdK:
121  Offset += MI.getOperand(2).getImm();
122  break;
123  }
124 
125  // Finally remove the instruction.
126  II++;
127  MI.eraseFromParent();
128 }
129 
131  int SPAdj, unsigned FIOperandNum,
132  RegScavenger *RS) const {
133  assert(SPAdj == 0 && "Unexpected SPAdj value");
134 
135  MachineInstr &MI = *II;
136  DebugLoc dl = MI.getDebugLoc();
137  MachineBasicBlock &MBB = *MI.getParent();
138  const MachineFunction &MF = *MBB.getParent();
139  const AVRTargetMachine &TM = (const AVRTargetMachine &)MF.getTarget();
140  const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
141  const MachineFrameInfo &MFI = MF.getFrameInfo();
142  const TargetFrameLowering *TFI = TM.getSubtargetImpl()->getFrameLowering();
143  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
144  int Offset = MFI.getObjectOffset(FrameIndex);
145 
146  // Add one to the offset because SP points to an empty slot.
147  Offset += MFI.getStackSize() - TFI->getOffsetOfLocalArea() + 1;
148  // Fold incoming offset.
149  Offset += MI.getOperand(FIOperandNum + 1).getImm();
150 
151  // This is actually "load effective address" of the stack slot
152  // instruction. We have only two-address instructions, thus we need to
153  // expand it into move + add.
154  if (MI.getOpcode() == AVR::FRMIDX) {
155  MI.setDesc(TII.get(AVR::MOVWRdRr));
156  MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
157  MI.RemoveOperand(2);
158 
159  assert(Offset > 0 && "Invalid offset");
160 
161  // We need to materialize the offset via an add instruction.
162  unsigned Opcode;
163  Register DstReg = MI.getOperand(0).getReg();
164  assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
165 
166  II++; // Skip over the FRMIDX (and now MOVW) instruction.
167 
168  // Generally, to load a frame address two add instructions are emitted that
169  // could get folded into a single one:
170  // movw r31:r30, r29:r28
171  // adiw r31:r30, 29
172  // adiw r31:r30, 16
173  // to:
174  // movw r31:r30, r29:r28
175  // adiw r31:r30, 45
176  if (II != MBB.end())
177  foldFrameOffset(II, Offset, DstReg);
178 
179  // Select the best opcode based on DstReg and the offset size.
180  switch (DstReg) {
181  case AVR::R25R24:
182  case AVR::R27R26:
183  case AVR::R31R30: {
184  if (isUInt<6>(Offset)) {
185  Opcode = AVR::ADIWRdK;
186  break;
187  }
189  }
190  default: {
191  // This opcode will get expanded into a pair of subi/sbci.
192  Opcode = AVR::SUBIWRdK;
193  Offset = -Offset;
194  break;
195  }
196  }
197 
198  MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
199  .addReg(DstReg, RegState::Kill)
200  .addImm(Offset);
201  New->getOperand(3).setIsDead();
202 
203  return;
204  }
205 
206  // If the offset is too big we have to adjust and restore the frame pointer
207  // to materialize a valid load/store with displacement.
208  //: TODO: consider using only one adiw/sbiw chain for more than one frame
209  //: index
210  if (Offset > 62) {
211  unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK;
212  int AddOffset = Offset - 63 + 1;
213 
214  // For huge offsets where adiw/sbiw cannot be used use a pair of subi/sbci.
215  if ((Offset - 63 + 1) > 63) {
216  AddOpc = AVR::SUBIWRdK;
217  SubOpc = AVR::SUBIWRdK;
218  AddOffset = -AddOffset;
219  }
220 
221  // It is possible that the spiller places this frame instruction in between
222  // a compare and branch, invalidating the contents of SREG set by the
223  // compare instruction because of the add/sub pairs. Conservatively save and
224  // restore SREG before and after each add/sub pair.
225  BuildMI(MBB, II, dl, TII.get(AVR::INRdA), AVR::R0).addImm(0x3f);
226 
227  MachineInstr *New = BuildMI(MBB, II, dl, TII.get(AddOpc), AVR::R29R28)
228  .addReg(AVR::R29R28, RegState::Kill)
229  .addImm(AddOffset);
230  New->getOperand(3).setIsDead();
231 
232  // Restore SREG.
233  BuildMI(MBB, std::next(II), dl, TII.get(AVR::OUTARr))
234  .addImm(0x3f)
235  .addReg(AVR::R0, RegState::Kill);
236 
237  // No need to set SREG as dead here otherwise if the next instruction is a
238  // cond branch it will be using a dead register.
239  BuildMI(MBB, std::next(II), dl, TII.get(SubOpc), AVR::R29R28)
240  .addReg(AVR::R29R28, RegState::Kill)
241  .addImm(Offset - 63 + 1);
242 
243  Offset = 62;
244  }
245 
246  MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
247  assert(isUInt<6>(Offset) && "Offset is out of range");
248  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
249 }
250 
253  if (TFI->hasFP(MF)) {
254  // The Y pointer register
255  return AVR::R28;
256  }
257 
258  return AVR::SP;
259 }
260 
261 const TargetRegisterClass *
263  unsigned Kind) const {
264  // FIXME: Currently we're using avr-gcc as reference, so we restrict
265  // ptrs to Y and Z regs. Though avr-gcc has buggy implementation
266  // of memory constraint, so we can fix it and bit avr-gcc here ;-)
267  return &AVR::PTRDISPREGSRegClass;
268 }
269 
271  Register &HiReg) const {
272  assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers");
273 
274  LoReg = getSubReg(Reg, AVR::sub_lo);
275  HiReg = getSubReg(Reg, AVR::sub_hi);
276 }
277 
279  MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
280  const TargetRegisterClass *DstRC, unsigned DstSubReg,
281  const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
282  if (this->getRegClass(AVR::PTRDISPREGSRegClassID)->hasSubClassEq(NewRC)) {
283  return false;
284  }
285 
286  return TargetRegisterInfo::shouldCoalesce(MI, SrcRC, SubReg, DstRC, DstSubReg,
287  NewRC, LIS);
288 }
289 
290 } // 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:103
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::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:43
llvm::BitVector::set
BitVector & set()
Definition: BitVector.h:343
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:278
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:233
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
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:724
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:251
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:553
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:494
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:626
llvm::AVRRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: AVRRegisterInfo.cpp:53
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:44
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:642
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:99
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::AVRRegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override
Definition: AVRRegisterInfo.cpp:45
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:1025
llvm::AVRRegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const override
Stack Frame Processing Methods.
Definition: AVRRegisterInfo.cpp:130
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:273
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::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:622
MachineFrameInfo.h
Function.h
llvm::AVRRegisterInfo::getLargestLegalSuperClass
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
Definition: AVRRegisterInfo.cpp:84
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:270
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:74
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::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
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:45
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:262