| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc < %s -mtriple=avr | FileCheck %s | |
| declare ptr @llvm.frameaddress.p0(i32 immarg) | |
| declare void @use(ptr) | |
| ; The frame pointer is Y (r29:r28), which is set up to contain the stack | |
| ; pointer after the frame has been allocated. | |
| define ptr @frameaddress_0() { | |
| ; CHECK-LABEL: frameaddress_0: | |
| ; CHECK: ; %bb.0: | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: mov r24, r28 | |
| ; CHECK-NEXT: mov r25, r29 | |
| ; CHECK-NEXT: pop r29 | |
| ; CHECK-NEXT: pop r28 | |
| ; CHECK-NEXT: ret | |
| %1 = call ptr @llvm.frameaddress.p0(i32 0) | |
| ret ptr %1 | |
| } | |
| ; Walking the frame chain is not possible, because the slot holding the | |
| ; caller's Y is at a function dependent offset above Y. Return zero instead. | |
| define ptr @frameaddress_1() { | |
| ; CHECK-LABEL: frameaddress_1: | |
| ; CHECK: ; %bb.0: | |
| ; CHECK-NEXT: ldi r24, 0 | |
| ; CHECK-NEXT: ldi r25, 0 | |
| ; CHECK-NEXT: ret | |
| %1 = call ptr @llvm.frameaddress.p0(i32 1) | |
| ret ptr %1 | |
| } | |
| ; Local objects are addressed relative to Y, the same value that is returned | |
| ; by llvm.frameaddress(0). | |
| define ptr @frameaddress_alloca() { | |
| ; CHECK-LABEL: frameaddress_alloca: | |
| ; CHECK: ; %bb.0: | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: sbiw r28, 4 | |
| ; CHECK-NEXT: in r0, 63 | |
| ; CHECK-NEXT: cli | |
| ; CHECK-NEXT: out 62, r29 | |
| ; CHECK-NEXT: out 63, r0 | |
| ; CHECK-NEXT: out 61, r28 | |
| ; CHECK-NEXT: ldi r24, 42 | |
| ; CHECK-NEXT: std Y+1, r24 | |
| ; CHECK-NEXT: mov r24, r28 | |
| ; CHECK-NEXT: mov r25, r29 | |
| ; CHECK-NEXT: adiw r24, 1 | |
| ; CHECK-NEXT: rcall use | |
| ; CHECK-NEXT: mov r24, r28 | |
| ; CHECK-NEXT: mov r25, r29 | |
| ; CHECK-NEXT: adiw r28, 4 | |
| ; CHECK-NEXT: in r0, 63 | |
| ; CHECK-NEXT: cli | |
| ; CHECK-NEXT: out 62, r29 | |
| ; CHECK-NEXT: out 63, r0 | |
| ; CHECK-NEXT: out 61, r28 | |
| ; CHECK-NEXT: pop r29 | |
| ; CHECK-NEXT: pop r28 | |
| ; CHECK-NEXT: ret | |
| %x = alloca i8, i32 4 | |
| store i8 42, ptr %x | |
| call void @use(ptr %x) | |
| %1 = call ptr @llvm.frameaddress.p0(i32 0) | |
| ret ptr %1 | |
| } |