| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc < %s -mtriple=avr -mattr=avr6 | FileCheck %s | |
| ; RUN: llc -mtriple=avr -mcpu=attiny10 -o - %s | FileCheck %s --check-prefix=TINY | |
| ; RUN: llc -mtriple=avr -mcpu=attiny2313 -o - %s | FileCheck %s --check-prefix=FULL | |
| declare i16 @allocate(ptr, ptr) | |
| ; Test taking an address of an alloca with a small offset (adiw) | |
| define i16 @alloca_addressof_small() { | |
| ; CHECK-LABEL: alloca_addressof_small: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: subi r28, 64 | |
| ; CHECK-NEXT: sbci r29, 0 | |
| ; 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: movw r24, r28 | |
| ; CHECK-NEXT: adiw r24, 17 | |
| ; CHECK-NEXT: movw r30, r28 | |
| ; CHECK-NEXT: adiw r30, 39 | |
| ; CHECK-NEXT: movw r22, r30 | |
| ; CHECK-NEXT: call allocate | |
| ; CHECK-NEXT: subi r28, 192 | |
| ; CHECK-NEXT: sbci r29, 255 | |
| ; 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 | |
| ; | |
| ; TINY-LABEL: alloca_addressof_small: | |
| ; TINY: ; %bb.0: ; %entry | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: subi r28, 64 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: mov r24, r28 | |
| ; TINY-NEXT: mov r25, r29 | |
| ; TINY-NEXT: subi r24, 239 | |
| ; TINY-NEXT: sbci r25, 255 | |
| ; TINY-NEXT: mov r22, r28 | |
| ; TINY-NEXT: mov r23, r29 | |
| ; TINY-NEXT: subi r22, 217 | |
| ; TINY-NEXT: sbci r23, 255 | |
| ; TINY-NEXT: rcall allocate | |
| ; TINY-NEXT: subi r28, 192 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ; | |
| ; FULL-LABEL: alloca_addressof_small: | |
| ; FULL: ; %bb.0: ; %entry | |
| ; FULL-NEXT: push r28 | |
| ; FULL-NEXT: push r29 | |
| ; FULL-NEXT: in r28, 61 | |
| ; FULL-NEXT: clr r29 | |
| ; FULL-NEXT: subi r28, 64 | |
| ; FULL-NEXT: sbci r29, 0 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: movw r24, r28 | |
| ; FULL-NEXT: adiw r24, 17 | |
| ; FULL-NEXT: movw r30, r28 | |
| ; FULL-NEXT: adiw r30, 39 | |
| ; FULL-NEXT: movw r22, r30 | |
| ; FULL-NEXT: rcall allocate | |
| ; FULL-NEXT: subi r28, 192 | |
| ; FULL-NEXT: sbci r29, 255 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: pop r29 | |
| ; FULL-NEXT: pop r28 | |
| ; FULL-NEXT: ret | |
| entry: | |
| ; Test that Y is saved | |
| %p = alloca [18 x i16] | |
| %k = alloca [14 x i16] | |
| %arrayidx = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 8 | |
| %arrayidx1 = getelementptr inbounds [18 x i16], ptr %p, i16 0, i16 5 | |
| %call = call i16 @allocate(ptr %arrayidx, ptr %arrayidx1) | |
| ret i16 %call | |
| } | |
| ; Test taking an address of an alloca with a big offset (subi/sbci pair) | |
| define i16 @alloca_addressof_big() { | |
| ; CHECK-LABEL: alloca_addressof_big: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: subi r28, 138 | |
| ; CHECK-NEXT: sbci r29, 0 | |
| ; 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: movw r24, r28 | |
| ; CHECK-NEXT: adiw r24, 17 | |
| ; CHECK-NEXT: movw r22, r28 | |
| ; CHECK-NEXT: subi r22, 145 | |
| ; CHECK-NEXT: sbci r23, 255 | |
| ; CHECK-NEXT: call allocate | |
| ; CHECK-NEXT: subi r28, 118 | |
| ; CHECK-NEXT: sbci r29, 255 | |
| ; 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 | |
| ; | |
| ; TINY-LABEL: alloca_addressof_big: | |
| ; TINY: ; %bb.0: ; %entry | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: subi r28, 138 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: mov r24, r28 | |
| ; TINY-NEXT: mov r25, r29 | |
| ; TINY-NEXT: subi r24, 239 | |
| ; TINY-NEXT: sbci r25, 255 | |
| ; TINY-NEXT: mov r22, r28 | |
| ; TINY-NEXT: mov r23, r29 | |
| ; TINY-NEXT: subi r22, 145 | |
| ; TINY-NEXT: sbci r23, 255 | |
| ; TINY-NEXT: rcall allocate | |
| ; TINY-NEXT: subi r28, 118 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ; | |
| ; FULL-LABEL: alloca_addressof_big: | |
| ; FULL: ; %bb.0: ; %entry | |
| ; FULL-NEXT: push r28 | |
| ; FULL-NEXT: push r29 | |
| ; FULL-NEXT: in r28, 61 | |
| ; FULL-NEXT: clr r29 | |
| ; FULL-NEXT: subi r28, 138 | |
| ; FULL-NEXT: sbci r29, 0 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: movw r24, r28 | |
| ; FULL-NEXT: adiw r24, 17 | |
| ; FULL-NEXT: movw r22, r28 | |
| ; FULL-NEXT: subi r22, 145 | |
| ; FULL-NEXT: sbci r23, 255 | |
| ; FULL-NEXT: rcall allocate | |
| ; FULL-NEXT: subi r28, 118 | |
| ; FULL-NEXT: sbci r29, 255 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: pop r29 | |
| ; FULL-NEXT: pop r28 | |
| ; FULL-NEXT: ret | |
| entry: | |
| %p = alloca [55 x i16] | |
| %k = alloca [14 x i16] | |
| %arrayidx = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 8 | |
| %arrayidx1 = getelementptr inbounds [55 x i16], ptr %p, i16 0, i16 41 | |
| %call = call i16 @allocate(ptr %arrayidx, ptr %arrayidx1) | |
| ret i16 %call | |
| } | |
| ; Test writing to an allocated variable with a small and a big offset | |
| define i16 @alloca_write(i16 %x) { | |
| ; CHECK-LABEL: alloca_write: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: sbiw r28, 58 | |
| ; 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: ldi r25, 0 | |
| ; CHECK-NEXT: std Y+24, r25 | |
| ; CHECK-NEXT: std Y+23, r24 | |
| ; CHECK-NEXT: ldi r24, 22 | |
| ; CHECK-NEXT: ldi r25, 0 | |
| ; CHECK-NEXT: in r0, 63 | |
| ; CHECK-NEXT: adiw r28, 57 | |
| ; CHECK-NEXT: std Y+63, r25 | |
| ; CHECK-NEXT: std Y+62, r24 | |
| ; CHECK-NEXT: sbiw r28, 57 | |
| ; CHECK-NEXT: out 63, r0 | |
| ; CHECK-NEXT: movw r24, r28 | |
| ; CHECK-NEXT: adiw r24, 1 | |
| ; CHECK-NEXT: movw r22, r28 | |
| ; CHECK-NEXT: subi r22, 227 | |
| ; CHECK-NEXT: sbci r23, 255 | |
| ; CHECK-NEXT: call allocate | |
| ; CHECK-NEXT: adiw r28, 58 | |
| ; 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 | |
| ; | |
| ; TINY-LABEL: alloca_write: | |
| ; TINY: ; %bb.0: ; %entry | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: subi r28, 58 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: ldi r24, 42 | |
| ; TINY-NEXT: ldi r25, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 233 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: st Y+, r24 | |
| ; TINY-NEXT: st Y+, r25 | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 23 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: ldi r24, 22 | |
| ; TINY-NEXT: ldi r25, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 137 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: st Y+, r24 | |
| ; TINY-NEXT: st Y+, r25 | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 119 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: mov r24, r28 | |
| ; TINY-NEXT: mov r25, r29 | |
| ; TINY-NEXT: subi r24, 255 | |
| ; TINY-NEXT: sbci r25, 255 | |
| ; TINY-NEXT: mov r22, r28 | |
| ; TINY-NEXT: mov r23, r29 | |
| ; TINY-NEXT: subi r22, 227 | |
| ; TINY-NEXT: sbci r23, 255 | |
| ; TINY-NEXT: rcall allocate | |
| ; TINY-NEXT: subi r28, 198 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ; | |
| ; FULL-LABEL: alloca_write: | |
| ; FULL: ; %bb.0: ; %entry | |
| ; FULL-NEXT: push r28 | |
| ; FULL-NEXT: push r29 | |
| ; FULL-NEXT: in r28, 61 | |
| ; FULL-NEXT: clr r29 | |
| ; FULL-NEXT: sbiw r28, 58 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: ldi r24, 42 | |
| ; FULL-NEXT: ldi r25, 0 | |
| ; FULL-NEXT: std Y+24, r25 | |
| ; FULL-NEXT: std Y+23, r24 | |
| ; FULL-NEXT: ldi r24, 22 | |
| ; FULL-NEXT: ldi r25, 0 | |
| ; FULL-NEXT: in r0, 63 | |
| ; FULL-NEXT: adiw r28, 57 | |
| ; FULL-NEXT: std Y+63, r25 | |
| ; FULL-NEXT: std Y+62, r24 | |
| ; FULL-NEXT: sbiw r28, 57 | |
| ; FULL-NEXT: out 63, r0 | |
| ; FULL-NEXT: movw r24, r28 | |
| ; FULL-NEXT: adiw r24, 1 | |
| ; FULL-NEXT: movw r22, r28 | |
| ; FULL-NEXT: subi r22, 227 | |
| ; FULL-NEXT: sbci r23, 255 | |
| ; FULL-NEXT: rcall allocate | |
| ; FULL-NEXT: adiw r28, 58 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: pop r29 | |
| ; FULL-NEXT: pop r28 | |
| ; FULL-NEXT: ret | |
| entry: | |
| ; Small offset here | |
| ; Big offset here | |
| %p = alloca [15 x i16] | |
| %k = alloca [14 x i16] | |
| %arrayidx = getelementptr inbounds [15 x i16], ptr %p, i16 0, i16 45 | |
| store i16 22, ptr %arrayidx | |
| %arrayidx1 = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 11 | |
| store i16 42, ptr %arrayidx1 | |
| %arrayidx2 = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 0 | |
| %arrayidx3 = getelementptr inbounds [15 x i16], ptr %p, i16 0, i16 0 | |
| %call = call i16 @allocate(ptr %arrayidx2, ptr %arrayidx3) | |
| ret i16 %call | |
| } | |
| ; Test writing to an allocated variable with a huge offset that cant be | |
| ; materialized with adiw/sbiw but with a subi/sbci pair. | |
| define void @alloca_write_huge() { | |
| ; CHECK-LABEL: alloca_write_huge: | |
| ; CHECK: ; %bb.0: | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: subi r28, 24 | |
| ; CHECK-NEXT: sbci r29, 1 | |
| ; 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, 22 | |
| ; CHECK-NEXT: ldi r25, 0 | |
| ; CHECK-NEXT: in r0, 63 | |
| ; CHECK-NEXT: subi r28, 41 | |
| ; CHECK-NEXT: sbci r29, 255 | |
| ; CHECK-NEXT: std Y+63, r25 | |
| ; CHECK-NEXT: std Y+62, r24 | |
| ; CHECK-NEXT: subi r28, 215 | |
| ; CHECK-NEXT: sbci r29, 0 | |
| ; CHECK-NEXT: out 63, r0 | |
| ; CHECK-NEXT: movw r24, r28 | |
| ; CHECK-NEXT: adiw r24, 1 | |
| ; CHECK-NEXT: ldi r22, 0 | |
| ; CHECK-NEXT: ldi r23, 0 | |
| ; CHECK-NEXT: call allocate | |
| ; CHECK-NEXT: subi r28, 232 | |
| ; CHECK-NEXT: sbci r29, 254 | |
| ; 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 | |
| ; | |
| ; TINY-LABEL: alloca_write_huge: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: subi r28, 24 | |
| ; TINY-NEXT: sbci r29, 1 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: ldi r24, 22 | |
| ; TINY-NEXT: ldi r25, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 235 | |
| ; TINY-NEXT: sbci r29, 254 | |
| ; TINY-NEXT: st Y+, r24 | |
| ; TINY-NEXT: st Y+, r25 | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 21 | |
| ; TINY-NEXT: sbci r29, 1 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: mov r24, r28 | |
| ; TINY-NEXT: mov r25, r29 | |
| ; TINY-NEXT: subi r24, 255 | |
| ; TINY-NEXT: sbci r25, 255 | |
| ; TINY-NEXT: ldi r22, 0 | |
| ; TINY-NEXT: ldi r23, 0 | |
| ; TINY-NEXT: rcall allocate | |
| ; TINY-NEXT: subi r28, 232 | |
| ; TINY-NEXT: sbci r29, 254 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ; | |
| ; FULL-LABEL: alloca_write_huge: | |
| ; FULL: ; %bb.0: | |
| ; FULL-NEXT: push r28 | |
| ; FULL-NEXT: push r29 | |
| ; FULL-NEXT: in r28, 61 | |
| ; FULL-NEXT: clr r29 | |
| ; FULL-NEXT: subi r28, 24 | |
| ; FULL-NEXT: sbci r29, 1 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: ldi r24, 22 | |
| ; FULL-NEXT: ldi r25, 0 | |
| ; FULL-NEXT: in r0, 63 | |
| ; FULL-NEXT: subi r28, 41 | |
| ; FULL-NEXT: sbci r29, 255 | |
| ; FULL-NEXT: std Y+63, r25 | |
| ; FULL-NEXT: std Y+62, r24 | |
| ; FULL-NEXT: subi r28, 215 | |
| ; FULL-NEXT: sbci r29, 0 | |
| ; FULL-NEXT: out 63, r0 | |
| ; FULL-NEXT: movw r24, r28 | |
| ; FULL-NEXT: adiw r24, 1 | |
| ; FULL-NEXT: ldi r22, 0 | |
| ; FULL-NEXT: ldi r23, 0 | |
| ; FULL-NEXT: rcall allocate | |
| ; FULL-NEXT: subi r28, 232 | |
| ; FULL-NEXT: sbci r29, 254 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: pop r29 | |
| ; FULL-NEXT: pop r28 | |
| ; FULL-NEXT: ret | |
| %k = alloca [140 x i16] | |
| %arrayidx = getelementptr inbounds [140 x i16], ptr %k, i16 0, i16 138 | |
| store i16 22, ptr %arrayidx | |
| %arraydecay = getelementptr inbounds [140 x i16], ptr %k, i16 0, i16 0 | |
| call i16 @allocate(ptr %arraydecay, ptr null) | |
| ret void | |
| } | |
| ; Test that stores to stack slots work on reduced tiny cores, which don't | |
| ; support the `std` instruction. The store pseudo must materialize the frame | |
| ; index as SP and be expanded using pointer adjustments instead of `std`. | |
| define void @bytealloca() { | |
| ; CHECK-LABEL: bytealloca: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: sbiw r28, 1 | |
| ; 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: std Y+1, r1 | |
| ; CHECK-NEXT: adiw r28, 1 | |
| ; 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 | |
| ; | |
| ; TINY-LABEL: bytealloca: | |
| ; TINY: ; %bb.0: ; %entry | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: subi r28, 1 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 255 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: st Y, r17 | |
| ; TINY-NEXT: subi r28, 1 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: subi r28, 255 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ; | |
| ; FULL-LABEL: bytealloca: | |
| ; FULL: ; %bb.0: ; %entry | |
| ; FULL-NEXT: push r28 | |
| ; FULL-NEXT: push r29 | |
| ; FULL-NEXT: in r28, 61 | |
| ; FULL-NEXT: clr r29 | |
| ; FULL-NEXT: sbiw r28, 1 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: std Y+1, r1 | |
| ; FULL-NEXT: adiw r28, 1 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: pop r29 | |
| ; FULL-NEXT: pop r28 | |
| ; FULL-NEXT: ret | |
| entry: | |
| %a = alloca i8, align 1 | |
| store i8 0, ptr %a, align 1 | |
| ret void | |
| } | |
| define i16 @wordalloca() { | |
| ; CHECK-LABEL: wordalloca: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: push r28 | |
| ; CHECK-NEXT: push r29 | |
| ; CHECK-NEXT: in r28, 61 | |
| ; CHECK-NEXT: in r29, 62 | |
| ; CHECK-NEXT: sbiw r28, 2 | |
| ; 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, 7 | |
| ; CHECK-NEXT: ldi r25, 0 | |
| ; CHECK-NEXT: std Y+2, r25 | |
| ; CHECK-NEXT: std Y+1, r24 | |
| ; CHECK-NEXT: adiw r28, 2 | |
| ; 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 | |
| ; | |
| ; TINY-LABEL: wordalloca: | |
| ; TINY: ; %bb.0: ; %entry | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: ldi r24, 7 | |
| ; TINY-NEXT: ldi r25, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 255 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: st Y+, r24 | |
| ; TINY-NEXT: st Y+, r25 | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 1 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: subi r28, 254 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: out 61, r28 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ; | |
| ; FULL-LABEL: wordalloca: | |
| ; FULL: ; %bb.0: ; %entry | |
| ; FULL-NEXT: push r28 | |
| ; FULL-NEXT: push r29 | |
| ; FULL-NEXT: in r28, 61 | |
| ; FULL-NEXT: clr r29 | |
| ; FULL-NEXT: sbiw r28, 2 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: ldi r24, 7 | |
| ; FULL-NEXT: ldi r25, 0 | |
| ; FULL-NEXT: std Y+2, r25 | |
| ; FULL-NEXT: std Y+1, r24 | |
| ; FULL-NEXT: adiw r28, 2 | |
| ; FULL-NEXT: out 61, r28 | |
| ; FULL-NEXT: pop r29 | |
| ; FULL-NEXT: pop r28 | |
| ; FULL-NEXT: ret | |
| entry: | |
| %a = alloca i16, align 1 | |
| store i16 7, ptr %a, align 1 | |
| ret i16 7 | |
| } |