LLVM  12.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();
140  const MachineFunction &MF = *MBB.getParent();
141  const AVRTargetMachine &TM = (const AVRTargetMachine &)MF.getTarget();
143  const MachineFrameInfo &MFI = MF.getFrameInfo();
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
bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override
const AVRInstrInfo * getInstrInfo() const override
Definition: AVRSubtarget.h:41
BitVector & set()
Definition: BitVector.h:398
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isInterruptOrSignalHandler() const
Checks if the function is some form of interrupt service routine.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:409
unsigned Reg
BitVector getReservedRegs(const MachineFunction &MF) const override
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
void setIsDead(bool Val=true)
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
return AArch64::GPR64RegClass contains(Reg)
const AVRSubtarget * getSubtargetImpl() const
MachineBasicBlock & MBB
const HexagonInstrInfo * TII
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned SubReg
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
static int getRegClass(RegisterKind Is, unsigned RegWidth)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:456
A generic AVR implementation.
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=0) const override
bool isTypeLegalForClass(const TargetRegisterClass &RC, MVT T) const
Return true if the given TargetRegisterClass has the ValueType T.
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override
void splitReg(Register Reg, Register &LoReg, Register &HiReg) const
Splits a 16-bit DREGS register into the lo/hi register pair.
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const override
Stack Frame Processing Methods.
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Contains AVR-specific information for each MachineFunction.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
virtual bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const
Subtarget Hooks.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
Information about stack frame layout on the target.
int64_t getImm() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:280
static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, Register DstReg)
Fold a frame offset shared between two add instructions into a single one.
Representation of each machine instruction.
Definition: MachineInstr.h:62
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Register getFrameRegister(const MachineFunction &MF) const override
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:62
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...
virtual const TargetFrameLowering * getFrameLowering() const
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:280
const TargetFrameLowering * getFrameLowering() const override
Definition: AVRSubtarget.h:42
IRTranslator LLVM IR MI
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
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