; 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 r22, r14
; AVR-NEXT: movw r24, r16
; 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: in r29, 62
; 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 r24, 25
; TINY-NEXT: ldi r25, 22
; TINY-NEXT: subi r30, 252
; TINY-NEXT: sbci r31, 255
; TINY-NEXT: st Z+, r24
; TINY-NEXT: st Z+, r25
; TINY-NEXT: subi r30, 6
; TINY-NEXT: sbci r31, 0
; TINY-NEXT: ldi r24, 104
; TINY-NEXT: ldi r25, 37
; TINY-NEXT: subi r30, 254
; TINY-NEXT: sbci r31, 255
; TINY-NEXT: st Z+, r24
; TINY-NEXT: st Z+, r25
; TINY-NEXT: subi r30, 4
; TINY-NEXT: sbci r31, 0
; TINY-NEXT: ldi r24, 204
; TINY-NEXT: ldi r25, 204
; TINY-NEXT: st Z+, r24
; TINY-NEXT: st Z+, r25
; 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: in r29, 62
; 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 r24, Y+
; TINY-NEXT: ld r25, 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+, r24
; TINY-NEXT: st Z+, r25
; 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 r24, Y+
; TINY-NEXT: ld r25, 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+, r24
; TINY-NEXT: st Z+, r25
; 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 r24, Y+
; TINY-NEXT: ld r25, 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+, r24
; TINY-NEXT: st Z+, r25
; 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: in r29, 62
; 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 r24, Y+
; TINY-NEXT: ld r25, 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+, r24
; TINY-NEXT: st Z+, r25
; 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 r24, Y+
; TINY-NEXT: ld r25, 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+, r24
; TINY-NEXT: st Z+, r25
; 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 r24, Y+
; TINY-NEXT: ld r25, 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+, r24
; TINY-NEXT: st Z+, r25
; 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: in r29, 62
; 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
}