From 8c15c7ba7eaecc8220d72532f3e90dda744ae12e Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Tue, 2 May 2017 01:57:48 +0000 Subject: [PATCH] [AVR] Save/restore the frame pointer for all functions A recent commit I made made it so that we only did this for signal or interrupt handlers. This broke normal functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301893 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AVR/AVRFrameLowering.cpp | 21 ++++++++++----------- test/CodeGen/AVR/calling-conv/c/stack.ll | 8 ++++---- test/CodeGen/AVR/return.ll | 24 ++++++++++++------------ test/CodeGen/AVR/varargs.ll | 6 +++--- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/lib/Target/AVR/AVRFrameLowering.cpp b/lib/Target/AVR/AVRFrameLowering.cpp index 3c37a1a9989..25232d2e47e 100644 --- a/lib/Target/AVR/AVRFrameLowering.cpp +++ b/lib/Target/AVR/AVRFrameLowering.cpp @@ -66,18 +66,17 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, .setMIFlag(MachineInstr::FrameSetup); } + // Save the frame pointer if we have one. + if (HasFP) { + BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) + .addReg(AVR::R29R28, RegState::Kill) + .setMIFlag(MachineInstr::FrameSetup); + } + // Emit special prologue code to save R1, R0 and SREG in interrupt/signal // handlers before saving any other registers. if (CallConv == CallingConv::AVR_INTR || CallConv == CallingConv::AVR_SIGNAL) { - - // Save the frame pointer if we have one. - if (HasFP) { - BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) - .addReg(AVR::R29R28, RegState::Kill) - .setMIFlag(MachineInstr::FrameSetup); - } - BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) .addReg(AVR::R1R0, RegState::Kill) .setMIFlag(MachineInstr::FrameSetup); @@ -173,11 +172,11 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF, .addImm(0x3f) .addReg(AVR::R0, RegState::Kill); BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0); - - if (hasFP(MF)) - BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28); } + if (hasFP(MF)) + BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28); + // Early exit if there is no need to restore the frame pointer. if (!FrameSize) { return; diff --git a/test/CodeGen/AVR/calling-conv/c/stack.ll b/test/CodeGen/AVR/calling-conv/c/stack.ll index 00ff7d1acd8..52b6427476a 100644 --- a/test/CodeGen/AVR/calling-conv/c/stack.ll +++ b/test/CodeGen/AVR/calling-conv/c/stack.ll @@ -11,15 +11,15 @@ define void @ret_void_args_i64_i64_i32(i64 %a, i64 %b, i32 %c) { ; CHECK-NEXT: in r29, 62 ; Load the top two bytes from the 32-bit int. - ; CHECK-NEXT: ldd r24, Y+7 - ; CHECK-NEXT: ldd r25, Y+8 + ; CHECK-NEXT: ldd r24, Y+5 + ; CHECK-NEXT: ldd r25, Y+6 ; Store the top two bytes of the 32-bit int to memory. ; CHECK-NEXT: sts 7, r25 ; CHECK-NEXT: sts 6, r24 ; Load the bottom two bytes from the 32-bit int. - ; CHECK-NEXT: ldd r24, Y+5 - ; CHECK-NEXT: ldd r25, Y+6 + ; CHECK-NEXT: ldd r24, Y+3 + ; CHECK-NEXT: ldd r25, Y+4 ; Store the bottom two bytes of the 32-bit int to memory. ; CHECK-NEXT: sts 5, r25 ; CHECK-NEXT: sts 4, r24 diff --git a/test/CodeGen/AVR/return.ll b/test/CodeGen/AVR/return.ll index d57f435fd11..1f80576af28 100644 --- a/test/CodeGen/AVR/return.ll +++ b/test/CodeGen/AVR/return.ll @@ -96,14 +96,14 @@ define i64 @return64_arg2(i64 %x, i64 %y, i64 %z) { ; CHECK-LABEL: return64_arg2: ; CHECK: push r28 ; CHECK: push r29 -; CHECK: ldd r18, Y+5 -; CHECK: ldd r19, Y+6 -; CHECK: ldd r20, Y+7 -; CHECK: ldd r21, Y+8 -; CHECK: ldd r22, Y+9 -; CHECK: ldd r23, Y+10 -; CHECK: ldd r24, Y+11 -; CHECK: ldd r25, Y+12 +; CHECK: ldd r18, Y+3 +; CHECK: ldd r19, Y+4 +; CHECK: ldd r20, Y+5 +; CHECK: ldd r21, Y+6 +; CHECK: ldd r22, Y+7 +; CHECK: ldd r23, Y+8 +; CHECK: ldd r24, Y+9 +; CHECK: ldd r25, Y+10 ; CHECK: pop r29 ; CHECK: pop r28 ret i64 %z @@ -113,10 +113,10 @@ define i32 @return64_trunc(i32 %a, i32 %b, i32 %c, i64 %d) { ; CHECK-LABEL: return64_trunc: ; CHECK: push r28 ; CHECK: push r29 -; CHECK: ldd r22, Y+5 -; CHECK: ldd r23, Y+6 -; CHECK: ldd r24, Y+7 -; CHECK: ldd r25, Y+8 +; CHECK: ldd r22, Y+3 +; CHECK: ldd r23, Y+4 +; CHECK: ldd r24, Y+5 +; CHECK: ldd r25, Y+6 ; CHECK: pop r29 ; CHECK: pop r28 %result = trunc i64 %d to i32 diff --git a/test/CodeGen/AVR/varargs.ll b/test/CodeGen/AVR/varargs.ll index 4959f2d880c..6f727cda582 100644 --- a/test/CodeGen/AVR/varargs.ll +++ b/test/CodeGen/AVR/varargs.ll @@ -7,12 +7,12 @@ declare void @llvm.va_end(i8*) define i16 @varargs1(i8* nocapture %x, ...) { ; CHECK-LABEL: varargs1: ; CHECK: movw r20, r28 -; CHECK: subi r20, 215 +; CHECK: subi r20, 217 ; CHECK: sbci r21, 255 ; CHECK: movw r24, r28 ; CHECK: adiw r24, 3 -; CHECK: ldd r22, Y+39 -; CHECK: ldd r23, Y+40 +; CHECK: ldd r22, Y+37 +; CHECK: ldd r23, Y+38 ; CHECK: call %buffer = alloca [32 x i8] %ap = alloca i8* -- 2.50.1