Skip to content

Commit 6c040dd

Browse files
authored
Merge pull request #66 from dylanmckay/avr-pick-upstream-llvm-fixes
[AVR] Cherry-pick 17 upstream AVR backend fixes into the Rust LLVM fork
2 parents 0ddefec + 12dfdd3 commit 6c040dd

36 files changed

+1868
-419
lines changed

llvm/lib/Target/AVR/AVRCallingConv.td

+1-17
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,13 @@
66
//
77
//===----------------------------------------------------------------------===//
88
// This describes the calling conventions for AVR architecture.
9+
// Normal functions use a special calling convention, solved in code.
910
//===----------------------------------------------------------------------===//
1011

1112
//===----------------------------------------------------------------------===//
1213
// AVR Return Value Calling Convention
1314
//===----------------------------------------------------------------------===//
1415

15-
def RetCC_AVR : CallingConv
16-
<[
17-
// i8 is returned in R24.
18-
CCIfType<[i8], CCAssignToReg<[R24]>>,
19-
20-
// i16 are returned in R25:R24, R23:R22, R21:R20 and R19:R18.
21-
CCIfType<[i16], CCAssignToReg<[R25R24, R23R22, R21R20, R19R18]>>
22-
]>;
23-
2416
// Special return value calling convention for runtime functions.
2517
def RetCC_AVR_BUILTIN : CallingConv
2618
<[
@@ -41,14 +33,6 @@ def ArgCC_AVR_Vararg : CallingConv
4133
CCAssignToStack<2, 1>
4234
]>;
4335

44-
// Special argument calling convention for
45-
// division runtime functions.
46-
def ArgCC_AVR_BUILTIN_DIV : CallingConv
47-
<[
48-
CCIfType<[i8], CCAssignToReg<[R24,R22]>>,
49-
CCIfType<[i16], CCAssignToReg<[R25R24, R23R22]>>
50-
]>;
51-
5236
//===----------------------------------------------------------------------===//
5337
// Callee-saved register lists.
5438
//===----------------------------------------------------------------------===//

llvm/lib/Target/AVR/AVRDevices.td

+13-5
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ def FeatureTinyEncoding : SubtargetFeature<"tinyencoding",
121121
"The device has Tiny core specific "
122122
"instruction encodings">;
123123

124+
// The device has CPU registers mapped in data address space
125+
def FeatureMMR : SubtargetFeature<"memmappedregs", "m_hasMemMappedGPR",
126+
"true", "The device has CPU registers "
127+
"mapped in data address space">;
128+
124129
class ELFArch<string name> : SubtargetFeature<"", "ELFArch",
125130
!strconcat("ELF::",name), "">;
126131

@@ -152,7 +157,7 @@ def ELFArchXMEGA7 : ELFArch<"EF_AVR_ARCH_XMEGA7">;
152157
// device should have.
153158
def FamilyAVR0 : Family<"avr0", []>;
154159

155-
def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM]>;
160+
def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM, FeatureMMR]>;
156161

157162
def FamilyAVR2 : Family<"avr2",
158163
[FamilyAVR1, FeatureIJMPCALL, FeatureADDSUBIW,
@@ -190,11 +195,14 @@ def FamilyAVR6 : Family<"avr6",
190195

191196
def FamilyTiny : Family<"avrtiny",
192197
[FamilyAVR0, FeatureBREAK, FeatureSRAM,
193-
FeatureTinyEncoding]>;
198+
FeatureTinyEncoding, FeatureMMR]>;
194199

195200
def FamilyXMEGA : Family<"xmega",
196-
[FamilyAVR51, FeatureEIJMPCALL, FeatureSPMX,
197-
FeatureDES]>;
201+
[FamilyAVR0, FeatureLPM, FeatureIJMPCALL, FeatureADDSUBIW,
202+
FeatureSRAM, FeatureJMPCALL, FeatureMultiplication,
203+
FeatureMOVW, FeatureLPMX, FeatureSPM,
204+
FeatureBREAK, FeatureEIJMPCALL, FeatureSPMX,
205+
FeatureDES, FeatureELPM, FeatureELPMX]>;
198206

199207
def FamilyXMEGAU : Family<"xmegau",
200208
[FamilyXMEGA, FeatureRMW]>;
@@ -208,7 +216,7 @@ def FeatureSetSpecial : FeatureSet<"special",
208216
FeatureLPM, FeatureLPMX, FeatureELPM,
209217
FeatureELPMX, FeatureSPM, FeatureSPMX,
210218
FeatureDES, FeatureRMW,
211-
FeatureMultiplication, FeatureBREAK]>;
219+
FeatureMultiplication, FeatureBREAK, FeatureMMR]>;
212220

213221
//===---------------------------------------------------------------------===//
214222
// AVR microcontrollers supported.

llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,8 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
597597

598598
// Load low byte.
599599
auto MIBLO = buildMI(MBB, MBBI, OpLo)
600-
.addReg(CurDstLoReg, RegState::Define)
601-
.addReg(SrcReg, RegState::Define);
600+
.addReg(CurDstLoReg, RegState::Define)
601+
.addReg(SrcReg);
602602

603603
// Push low byte onto stack if necessary.
604604
if (TmpReg)

llvm/lib/Target/AVR/AVRFrameLowering.cpp

+38-59
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,19 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
5757
DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
5858
const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
5959
const AVRInstrInfo &TII = *STI.getInstrInfo();
60+
const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
6061
bool HasFP = hasFP(MF);
6162

6263
// Interrupt handlers re-enable interrupts in function entry.
63-
if (CallConv == CallingConv::AVR_INTR) {
64+
if (AFI->isInterruptHandler()) {
6465
BuildMI(MBB, MBBI, DL, TII.get(AVR::BSETs))
6566
.addImm(0x07)
6667
.setMIFlag(MachineInstr::FrameSetup);
6768
}
6869

69-
// Save the frame pointer if we have one.
70-
if (HasFP) {
71-
BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
72-
.addReg(AVR::R29R28, RegState::Kill)
73-
.setMIFlag(MachineInstr::FrameSetup);
74-
}
75-
7670
// Emit special prologue code to save R1, R0 and SREG in interrupt/signal
7771
// handlers before saving any other registers.
78-
if (CallConv == CallingConv::AVR_INTR ||
79-
CallConv == CallingConv::AVR_SIGNAL) {
72+
if (AFI->isInterruptOrSignalHandler()) {
8073
BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
8174
.addReg(AVR::R1R0, RegState::Kill)
8275
.setMIFlag(MachineInstr::FrameSetup);
@@ -100,7 +93,6 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
10093
}
10194

10295
const MachineFrameInfo &MFI = MF.getFrameInfo();
103-
const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
10496
unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
10597

10698
// Skip the callee-saved push instructions.
@@ -143,13 +135,11 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
143135

144136
void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
145137
MachineBasicBlock &MBB) const {
146-
CallingConv::ID CallConv = MF.getFunction().getCallingConv();
147-
bool isHandler = (CallConv == CallingConv::AVR_INTR ||
148-
CallConv == CallingConv::AVR_SIGNAL);
138+
const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
149139

150140
// Early exit if the frame pointer is not needed in this function except for
151141
// signal/interrupt handlers where special code generation is required.
152-
if (!hasFP(MF) && !isHandler) {
142+
if (!hasFP(MF) && !AFI->isInterruptOrSignalHandler()) {
153143
return;
154144
}
155145

@@ -159,24 +149,20 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
159149

160150
DebugLoc DL = MBBI->getDebugLoc();
161151
const MachineFrameInfo &MFI = MF.getFrameInfo();
162-
const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
163152
unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
164153
const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
165154
const AVRInstrInfo &TII = *STI.getInstrInfo();
166155

167156
// Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal
168157
// handlers at the very end of the function, just before reti.
169-
if (isHandler) {
158+
if (AFI->isInterruptOrSignalHandler()) {
170159
BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0);
171160
BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr))
172161
.addImm(0x3f)
173162
.addReg(AVR::R0, RegState::Kill);
174163
BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0);
175164
}
176165

177-
if (hasFP(MF))
178-
BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28);
179-
180166
// Early exit if there is no need to restore the frame pointer.
181167
if (!FrameSize) {
182168
return;
@@ -299,15 +285,10 @@ bool AVRFrameLowering::restoreCalleeSavedRegisters(
299285
}
300286

301287
/// Replace pseudo store instructions that pass arguments through the stack with
302-
/// real instructions. If insertPushes is true then all instructions are
303-
/// replaced with push instructions, otherwise regular std instructions are
304-
/// inserted.
288+
/// real instructions.
305289
static void fixStackStores(MachineBasicBlock &MBB,
306290
MachineBasicBlock::iterator MI,
307-
const TargetInstrInfo &TII, bool insertPushes) {
308-
const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
309-
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
310-
291+
const TargetInstrInfo &TII, Register FP) {
311292
// Iterate through the BB until we hit a call instruction or we reach the end.
312293
for (auto I = MI, E = MBB.end(); I != E && !I->isCall();) {
313294
MachineBasicBlock::iterator NextMI = std::next(I);
@@ -322,37 +303,14 @@ static void fixStackStores(MachineBasicBlock &MBB,
322303

323304
assert(MI.getOperand(0).getReg() == AVR::SP &&
324305
"Invalid register, should be SP!");
325-
if (insertPushes) {
326-
// Replace this instruction with a push.
327-
Register SrcReg = MI.getOperand(2).getReg();
328-
bool SrcIsKill = MI.getOperand(2).isKill();
329-
330-
// We can't use PUSHWRr here because when expanded the order of the new
331-
// instructions are reversed from what we need. Perform the expansion now.
332-
if (Opcode == AVR::STDWSPQRr) {
333-
BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
334-
.addReg(TRI.getSubReg(SrcReg, AVR::sub_hi),
335-
getKillRegState(SrcIsKill));
336-
BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
337-
.addReg(TRI.getSubReg(SrcReg, AVR::sub_lo),
338-
getKillRegState(SrcIsKill));
339-
} else {
340-
BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
341-
.addReg(SrcReg, getKillRegState(SrcIsKill));
342-
}
343-
344-
MI.eraseFromParent();
345-
I = NextMI;
346-
continue;
347-
}
348306

349307
// Replace this instruction with a regular store. Use Y as the base
350308
// pointer since it is guaranteed to contain a copy of SP.
351309
unsigned STOpc =
352310
(Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr;
353311

354312
MI.setDesc(TII.get(STOpc));
355-
MI.getOperand(0).setReg(AVR::R29R28);
313+
MI.getOperand(0).setReg(FP);
356314

357315
I = NextMI;
358316
}
@@ -368,26 +326,45 @@ MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr(
368326
// function entry. Delete the call frame pseudo and replace all pseudo stores
369327
// with real store instructions.
370328
if (hasReservedCallFrame(MF)) {
371-
fixStackStores(MBB, MI, TII, false);
329+
fixStackStores(MBB, MI, TII, AVR::R29R28);
372330
return MBB.erase(MI);
373331
}
374332

375333
DebugLoc DL = MI->getDebugLoc();
376334
unsigned int Opcode = MI->getOpcode();
377335
int Amount = TII.getFrameSize(*MI);
378336

379-
// Adjcallstackup does not need to allocate stack space for the call, instead
380-
// we insert push instructions that will allocate the necessary stack.
381-
// For adjcallstackdown we convert it into an 'adiw reg, <amt>' handling
382-
// the read and write of SP in I/O space.
337+
// ADJCALLSTACKUP and ADJCALLSTACKDOWN are converted to adiw/subi
338+
// instructions to read and write the stack pointer in I/O space.
383339
if (Amount != 0) {
384340
assert(getStackAlignment() == 1 && "Unsupported stack alignment");
385341

386342
if (Opcode == TII.getCallFrameSetupOpcode()) {
387-
fixStackStores(MBB, MI, TII, true);
343+
// Update the stack pointer.
344+
// In many cases this can be done far more efficiently by pushing the
345+
// relevant values directly to the stack. However, doing that correctly
346+
// (in the right order, possibly skipping some empty space for undef
347+
// values, etc) is tricky and thus left to be optimized in the future.
348+
BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP);
349+
350+
MachineInstr *New = BuildMI(MBB, MI, DL, TII.get(AVR::SUBIWRdK), AVR::R31R30)
351+
.addReg(AVR::R31R30, RegState::Kill)
352+
.addImm(Amount);
353+
New->getOperand(3).setIsDead();
354+
355+
BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP)
356+
.addReg(AVR::R31R30, RegState::Kill);
357+
358+
// Make sure the remaining stack stores are converted to real store
359+
// instructions.
360+
fixStackStores(MBB, MI, TII, AVR::R31R30);
388361
} else {
389362
assert(Opcode == TII.getCallFrameDestroyOpcode());
390363

364+
// Note that small stack changes could be implemented more efficiently
365+
// with a few pop instructions instead of the 8-9 instructions now
366+
// required.
367+
391368
// Select the best opcode to adjust SP based on the offset size.
392369
unsigned addOpcode;
393370
if (isUInt<6>(Amount)) {
@@ -419,8 +396,10 @@ void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF,
419396
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
420397

421398
// If we have a frame pointer, the Y register needs to be saved as well.
422-
// We don't do that here however - the prologue and epilogue generation
423-
// code will handle it specially.
399+
if (hasFP(MF)) {
400+
SavedRegs.set(AVR::R29);
401+
SavedRegs.set(AVR::R28);
402+
}
424403
}
425404
/// The frame analyzer pass.
426405
///

0 commit comments

Comments
 (0)