| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | |
| ; RUN: llc -mattr=avr6,sram -mtriple=avr < %s | FileCheck %s --check-prefix=AVR | |
| ; RUN: llc -mcpu=attiny10 -mtriple=avr < %s | FileCheck %s --check-prefix=TINY | |
| ;TODO: test returning byval structs | |
| ; TODO: test naked functions | |
| define void @return_void() { | |
| ; AVR-LABEL: return_void: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return_void: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ret | |
| ret void | |
| } | |
| define i8 @return8_imm() { | |
| ; AVR-LABEL: return8_imm: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ldi r24, 5 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return8_imm: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ldi r24, 5 | |
| ; TINY-NEXT: ret | |
| ret i8 5 | |
| } | |
| define i8 @return8_arg(i8 %x) { | |
| ; AVR-LABEL: return8_arg: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return8_arg: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ret | |
| ret i8 %x | |
| } | |
| define i8 @return8_arg2(i8 %x, i8 %y, i8 %z) { | |
| ; AVR-LABEL: return8_arg2: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: mov r24, r20 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return8_arg2: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: mov r24, r20 | |
| ; TINY-NEXT: ret | |
| ret i8 %z | |
| } | |
| define i16 @return16_imm() { | |
| ; AVR-LABEL: return16_imm: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ldi r24, 57 | |
| ; AVR-NEXT: ldi r25, 48 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return16_imm: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ldi r24, 57 | |
| ; TINY-NEXT: ldi r25, 48 | |
| ; TINY-NEXT: ret | |
| ret i16 12345 | |
| } | |
| define i16 @return16_arg(i16 %x) { | |
| ; AVR-LABEL: return16_arg: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return16_arg: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ret | |
| ret i16 %x | |
| } | |
| define i16 @return16_arg2(i16 %x, i16 %y, i16 %z) { | |
| ; AVR-LABEL: return16_arg2: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: movw r24, r20 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return16_arg2: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: mov r24, r20 | |
| ; TINY-NEXT: mov r25, r21 | |
| ; TINY-NEXT: ret | |
| ret i16 %z | |
| } | |
| define i32 @return32_imm() { | |
| ; AVR-LABEL: return32_imm: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ldi r22, 21 | |
| ; AVR-NEXT: ldi r23, 205 | |
| ; AVR-NEXT: ldi r24, 91 | |
| ; AVR-NEXT: ldi r25, 7 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return32_imm: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ldi r22, 21 | |
| ; TINY-NEXT: ldi r23, 205 | |
| ; TINY-NEXT: ldi r24, 91 | |
| ; TINY-NEXT: ldi r25, 7 | |
| ; TINY-NEXT: ret | |
| ret i32 123456789 | |
| } | |
| define i32 @return32_arg(i32 %x) { | |
| ; AVR-LABEL: return32_arg: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return32_arg: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ret | |
| ret i32 %x | |
| } | |
| define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) { | |
| ; AVR-LABEL: return32_arg2: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: movw r24, r16 | |
| ; AVR-NEXT: movw r22, r14 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return32_arg2: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 247 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r22, Y+ | |
| ; TINY-NEXT: ld r23, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 9 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 245 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r24, Y+ | |
| ; TINY-NEXT: ld r25, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 11 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ret i32 %z | |
| } | |
| define i64 @return64_imm() { | |
| ; AVR-LABEL: return64_imm: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ldi r18, 204 | |
| ; AVR-NEXT: ldi r19, 204 | |
| ; AVR-NEXT: ldi r20, 104 | |
| ; AVR-NEXT: ldi r21, 37 | |
| ; AVR-NEXT: ldi r22, 25 | |
| ; AVR-NEXT: ldi r23, 22 | |
| ; AVR-NEXT: ldi r24, 236 | |
| ; AVR-NEXT: ldi r25, 190 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return64_imm: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: ldi r20, 236 | |
| ; TINY-NEXT: ldi r21, 190 | |
| ; TINY-NEXT: mov r30, r24 | |
| ; TINY-NEXT: mov r31, r25 | |
| ; TINY-NEXT: subi r30, 250 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 8 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: ldi r20, 25 | |
| ; TINY-NEXT: ldi r21, 22 | |
| ; TINY-NEXT: subi r30, 252 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 6 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: ldi r20, 104 | |
| ; TINY-NEXT: ldi r21, 37 | |
| ; TINY-NEXT: subi r30, 254 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 4 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: ldi r20, 204 | |
| ; TINY-NEXT: ldi r21, 204 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: ret | |
| ret i64 13757395258967641292 | |
| } | |
| define i64 @return64_arg(i64 %x) { | |
| ; AVR-LABEL: return64_arg: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return64_arg: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 245 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 11 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: mov r30, r24 | |
| ; TINY-NEXT: mov r31, r25 | |
| ; TINY-NEXT: subi r30, 250 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 8 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 247 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 9 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: subi r30, 252 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 6 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 249 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 7 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: subi r30, 254 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 4 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 251 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 5 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ret i64 %x | |
| } | |
| define i64 @return64_arg2(i64 %x, i64 %y, i64 %z) { | |
| ; AVR-LABEL: return64_arg2: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: push r28 | |
| ; AVR-NEXT: push r29 | |
| ; AVR-NEXT: in r28, 61 | |
| ; AVR-NEXT: in r29, 62 | |
| ; AVR-NEXT: ldd r18, Y+5 | |
| ; AVR-NEXT: ldd r19, Y+6 | |
| ; AVR-NEXT: ldd r20, Y+7 | |
| ; AVR-NEXT: ldd r21, Y+8 | |
| ; AVR-NEXT: ldd r22, Y+9 | |
| ; AVR-NEXT: ldd r23, Y+10 | |
| ; AVR-NEXT: ldd r24, Y+11 | |
| ; AVR-NEXT: ldd r25, Y+12 | |
| ; AVR-NEXT: pop r29 | |
| ; AVR-NEXT: pop r28 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return64_arg2: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 229 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 27 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: mov r30, r24 | |
| ; TINY-NEXT: mov r31, r25 | |
| ; TINY-NEXT: subi r30, 250 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 8 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 231 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 25 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: subi r30, 252 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 6 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 233 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; 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: subi r30, 254 | |
| ; TINY-NEXT: sbci r31, 255 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: subi r30, 4 | |
| ; TINY-NEXT: sbci r31, 0 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 235 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r20, Y+ | |
| ; TINY-NEXT: ld r21, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 21 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: st Z+, r20 | |
| ; TINY-NEXT: st Z+, r21 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| ret i64 %z | |
| } | |
| define i32 @return64_trunc(i32 %a, i32 %b, i32 %c, i64 %d) { | |
| ; AVR-LABEL: return64_trunc: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: push r28 | |
| ; AVR-NEXT: push r29 | |
| ; AVR-NEXT: in r28, 61 | |
| ; AVR-NEXT: in r29, 62 | |
| ; AVR-NEXT: ldd r22, Y+5 | |
| ; AVR-NEXT: ldd r23, Y+6 | |
| ; AVR-NEXT: ldd r24, Y+7 | |
| ; AVR-NEXT: ldd r25, Y+8 | |
| ; AVR-NEXT: pop r29 | |
| ; AVR-NEXT: pop r28 | |
| ; AVR-NEXT: ret | |
| ; | |
| ; TINY-LABEL: return64_trunc: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: push r28 | |
| ; TINY-NEXT: push r29 | |
| ; TINY-NEXT: in r28, 61 | |
| ; TINY-NEXT: clr r29 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 243 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r22, Y+ | |
| ; TINY-NEXT: ld r23, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 13 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: subi r28, 241 | |
| ; TINY-NEXT: sbci r29, 255 | |
| ; TINY-NEXT: ld r24, Y+ | |
| ; TINY-NEXT: ld r25, Y+ | |
| ; TINY-NEXT: subi r28, 2 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: subi r28, 15 | |
| ; TINY-NEXT: sbci r29, 0 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: pop r29 | |
| ; TINY-NEXT: pop r28 | |
| ; TINY-NEXT: ret | |
| %result = trunc i64 %d to i32 | |
| ret i32 %result | |
| } | |
| define avr_intrcc void @interrupt_handler() { | |
| ; AVR-LABEL: interrupt_handler: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: sei | |
| ; AVR-NEXT: push r0 | |
| ; AVR-NEXT: in r0, 63 | |
| ; AVR-NEXT: push r0 | |
| ; AVR-NEXT: pop r0 | |
| ; AVR-NEXT: out 63, r0 | |
| ; AVR-NEXT: pop r0 | |
| ; AVR-NEXT: reti | |
| ; | |
| ; TINY-LABEL: interrupt_handler: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: sei | |
| ; TINY-NEXT: push r16 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: push r16 | |
| ; TINY-NEXT: pop r16 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: pop r16 | |
| ; TINY-NEXT: reti | |
| ret void | |
| } | |
| define avr_signalcc void @signal_handler() { | |
| ; AVR-LABEL: signal_handler: | |
| ; AVR: ; %bb.0: | |
| ; AVR-NEXT: push r0 | |
| ; AVR-NEXT: in r0, 63 | |
| ; AVR-NEXT: push r0 | |
| ; AVR-NEXT: pop r0 | |
| ; AVR-NEXT: out 63, r0 | |
| ; AVR-NEXT: pop r0 | |
| ; AVR-NEXT: reti | |
| ; | |
| ; TINY-LABEL: signal_handler: | |
| ; TINY: ; %bb.0: | |
| ; TINY-NEXT: push r16 | |
| ; TINY-NEXT: in r16, 63 | |
| ; TINY-NEXT: push r16 | |
| ; TINY-NEXT: pop r16 | |
| ; TINY-NEXT: out 63, r16 | |
| ; TINY-NEXT: pop r16 | |
| ; TINY-NEXT: reti | |
| ret void | |
| } |