1 //===-- AVRRegisterInfo.cpp - AVR Register Information --------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the AVR implementation of the TargetRegisterInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "AVRRegisterInfo.h"
15 #include "llvm/ADT/BitVector.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/CodeGen/TargetFrameLowering.h"
24 #include "AVRInstrInfo.h"
25 #include "AVRMachineFunctionInfo.h"
26 #include "AVRTargetMachine.h"
27 #include "MCTargetDesc/AVRMCTargetDesc.h"
29 #define GET_REGINFO_TARGET_DESC
30 #include "AVRGenRegisterInfo.inc"
34 AVRRegisterInfo::AVRRegisterInfo() : AVRGenRegisterInfo(0) {}
37 AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
38 const AVRMachineFunctionInfo
*AFI
= MF
->getInfo
<AVRMachineFunctionInfo
>();
40 return AFI
->isInterruptOrSignalHandler()
41 ? CSR_Interrupts_SaveList
42 : CSR_Normal_SaveList
;
46 AVRRegisterInfo::getCallPreservedMask(const MachineFunction
&MF
,
47 CallingConv::ID CC
) const {
48 const AVRMachineFunctionInfo
*AFI
= MF
.getInfo
<AVRMachineFunctionInfo
>();
50 return AFI
->isInterruptOrSignalHandler()
51 ? CSR_Interrupts_RegMask
55 BitVector
AVRRegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
56 BitVector
Reserved(getNumRegs());
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
);
64 // Reserve the stack pointer.
65 Reserved
.set(AVR::SPL
);
66 Reserved
.set(AVR::SPH
);
67 Reserved
.set(AVR::SP
);
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.
73 // Instead we just unconditionally reserve the Y register.
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
);
85 const TargetRegisterClass
*
86 AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass
*RC
,
87 const MachineFunction
&MF
) const {
88 const TargetRegisterInfo
*TRI
= MF
.getSubtarget().getRegisterInfo();
89 if (TRI
->isTypeLegalForClass(*RC
, MVT::i16
)) {
90 return &AVR::DREGSRegClass
;
93 if (TRI
->isTypeLegalForClass(*RC
, MVT::i8
)) {
94 return &AVR::GPR8RegClass
;
97 llvm_unreachable("Invalid register size");
100 /// Fold a frame offset shared between two add instructions into a single one.
101 static void foldFrameOffset(MachineBasicBlock::iterator
&II
, int &Offset
,
103 MachineInstr
&MI
= *II
;
104 int Opcode
= MI
.getOpcode();
106 // Don't bother trying if the next instruction is not an add or a sub.
107 if ((Opcode
!= AVR::SUBIWRdK
) && (Opcode
!= AVR::ADIWRdK
)) {
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()) {
117 // Add the offset in the next instruction to our offset.
120 Offset
+= -MI
.getOperand(2).getImm();
123 Offset
+= MI
.getOperand(2).getImm();
127 // Finally remove the instruction.
129 MI
.eraseFromParent();
132 void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
133 int SPAdj
, unsigned FIOperandNum
,
134 RegScavenger
*RS
) const {
135 assert(SPAdj
== 0 && "Unexpected SPAdj value");
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
);
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();
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);
161 assert(Offset
> 0 && "Invalid offset");
163 // We need to materialize the offset via an add instruction.
165 Register DstReg
= MI
.getOperand(0).getReg();
166 assert(DstReg
!= AVR::R29R28
&& "Dest reg cannot be the frame pointer");
168 II
++; // Skip over the FRMIDX (and now MOVW) instruction.
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
176 // movw r31:r30, r29:r28
179 foldFrameOffset(II
, Offset
, DstReg
);
181 // Select the best opcode based on DstReg and the offset size.
186 if (isUInt
<6>(Offset
)) {
187 Opcode
= AVR::ADIWRdK
;
193 // This opcode will get expanded into a pair of subi/sbci.
194 Opcode
= AVR::SUBIWRdK
;
200 MachineInstr
*New
= BuildMI(MBB
, II
, dl
, TII
.get(Opcode
), DstReg
)
201 .addReg(DstReg
, RegState::Kill
)
203 New
->getOperand(3).setIsDead();
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
212 unsigned AddOpc
= AVR::ADIWRdK
, SubOpc
= AVR::SBIWRdK
;
213 int AddOffset
= Offset
- 63 + 1;
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
;
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);
228 MachineInstr
*New
= BuildMI(MBB
, II
, dl
, TII
.get(AddOpc
), AVR::R29R28
)
229 .addReg(AVR::R29R28
, RegState::Kill
)
231 New
->getOperand(3).setIsDead();
234 BuildMI(MBB
, std::next(II
), dl
, TII
.get(AVR::OUTARr
))
236 .addReg(AVR::R0
, RegState::Kill
);
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);
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
);
252 Register
AVRRegisterInfo::getFrameRegister(const MachineFunction
&MF
) const {
253 const TargetFrameLowering
*TFI
= MF
.getSubtarget().getFrameLowering();
254 if (TFI
->hasFP(MF
)) {
255 // The Y pointer register
262 const TargetRegisterClass
*
263 AVRRegisterInfo::getPointerRegClass(const MachineFunction
&MF
,
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
;
271 void AVRRegisterInfo::splitReg(Register Reg
, Register
&LoReg
,
272 Register
&HiReg
) const {
273 assert(AVR::DREGSRegClass
.contains(Reg
) && "can only split 16-bit registers");
275 LoReg
= getSubReg(Reg
, AVR::sub_lo
);
276 HiReg
= getSubReg(Reg
, AVR::sub_hi
);
279 bool AVRRegisterInfo::shouldCoalesce(MachineInstr
*MI
,
280 const TargetRegisterClass
*SrcRC
,
282 const TargetRegisterClass
*DstRC
,
284 const TargetRegisterClass
*NewRC
,
285 LiveIntervals
&LIS
) const {
286 if(this->getRegClass(AVR::PTRDISPREGSRegClassID
)->hasSubClassEq(NewRC
)) {
290 return TargetRegisterInfo::shouldCoalesce(MI
, SrcRC
, SubReg
, DstRC
, DstSubReg
, NewRC
, LIS
);
293 } // end of namespace llvm