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