llvm/llvm/test/CodeGen/AVR/calling-conv/c/tiny.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=avr -mcpu=avrtiny | FileCheck %s

; NOTE: Both %a(i8) and %b(i8) cost two registers.
define i8 @foo0(i8 %a, i8 %b) {
; CHECK-LABEL: foo0:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    sub r24, r22
; CHECK-NEXT:    ret
  %c = sub i8 %a, %b
  ret i8 %c
}

; NOTE: Both %a(i16) and %b(i16) cost two registers.
define i16 @foo1(i16 %a, i16 %b) {
; CHECK-LABEL: foo1:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    sub r24, r22
; CHECK-NEXT:    sbc r25, r23
; CHECK-NEXT:    ret
  %c = sub i16 %a, %b
  ret i16 %c
}

; NOTE: %a(i16), %b(i16) and %c(i16) each costs two registers.
define i16 @foo2(i16 %a, i16 %b, i16 %c) {
; CHECK-LABEL: foo2:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    sub r22, r24
; CHECK-NEXT:    sbc r23, r25
; CHECK-NEXT:    add r22, r20
; CHECK-NEXT:    adc r23, r21
; CHECK-NEXT:    mov r24, r22
; CHECK-NEXT:    mov r25, r23
; CHECK-NEXT:    ret
  %d = sub i16 %a, %b
  %e = sub i16 %c, %d
  ret i16 %e
}

; NOTE:  %a(i16), %b(i16) and %c(i16) each costs two registers,
;        while %d(i16) is passed via the stack.
define i16 @foo3(i16 %a, i16 %b, i16 %c, i16 %d) {
; CHECK-LABEL: foo3:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    in r16, 63
; CHECK-NEXT:    subi r28, 251
; CHECK-NEXT:    sbci r29, 255
; CHECK-NEXT:    ld r30, Y+
; CHECK-NEXT:    ld r31, Y+
; CHECK-NEXT:    subi r28, 2
; CHECK-NEXT:    sbci r29, 0
; CHECK-NEXT:    subi r28, 5
; CHECK-NEXT:    sbci r29, 0
; CHECK-NEXT:    out 63, r16
; CHECK-NEXT:    sub r20, r30
; CHECK-NEXT:    sbc r21, r31
; CHECK-NEXT:    sub r24, r22
; CHECK-NEXT:    sbc r25, r23
; CHECK-NEXT:    add r24, r20
; CHECK-NEXT:    adc r25, r21
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %e = sub i16 %a, %b
  %g = sub i16 %c, %d
  %h = add i16 %e, %g
  ret i16 %h
}

; NOTE: %a(i32) costs four registers, while %b(i32) is passed via the stack.
define i32 @foo4(i32 %a, i32 %b) {
; CHECK-LABEL: foo4:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    in r16, 63
; CHECK-NEXT:    subi r28, 251
; CHECK-NEXT:    sbci r29, 255
; CHECK-NEXT:    ld r20, Y+
; CHECK-NEXT:    ld r21, Y+
; CHECK-NEXT:    subi r28, 2
; CHECK-NEXT:    sbci r29, 0
; CHECK-NEXT:    subi r28, 5
; CHECK-NEXT:    sbci r29, 0
; CHECK-NEXT:    out 63, r16
; CHECK-NEXT:    in r16, 63
; CHECK-NEXT:    subi r28, 249
; CHECK-NEXT:    sbci r29, 255
; CHECK-NEXT:    ld r30, Y+
; CHECK-NEXT:    ld r31, Y+
; CHECK-NEXT:    subi r28, 2
; CHECK-NEXT:    sbci r29, 0
; CHECK-NEXT:    subi r28, 7
; CHECK-NEXT:    sbci r29, 0
; CHECK-NEXT:    out 63, r16
; CHECK-NEXT:    sub r20, r22
; CHECK-NEXT:    sbc r21, r23
; CHECK-NEXT:    sbc r30, r24
; CHECK-NEXT:    sbc r31, r25
; CHECK-NEXT:    mov r22, r20
; CHECK-NEXT:    mov r23, r21
; CHECK-NEXT:    mov r24, r30
; CHECK-NEXT:    mov r25, r31
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %c = sub i32 %b, %a
  ret i32 %c
}

; NOTE: %0 costs six registers, while %1 is passed via the stack.
define i8 @foo5([5 x i8] %0, i8 %1) {
; CHECK-LABEL: foo5:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 251
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r24, X
; CHECK-NEXT:    add r24, r20
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %3 = extractvalue [5 x i8] %0, 0
  %4 = add i8 %3, %1
  ret i8 %4
}

; NOTE: %0 costs two registers and %1 costs four registers.
define i8 @foo6([2 x i8] %0, [4 x i8] %1) {
; CHECK-LABEL: foo6:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    add r24, r20
; CHECK-NEXT:    ret
  %3 = extractvalue [2 x i8] %0, 0
  %4 = extractvalue [4 x i8] %1, 0
  %5 = add i8 %3, %4
  ret i8 %5
}

; NOTE: %0 cost four registers, while %1 is passed via the stack,
;       though there are two vacant registers.
define i8 @foo7([3 x i8] %0, [3 x i8] %1) {
; CHECK-LABEL: foo7:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 251
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r24, X
; CHECK-NEXT:    add r24, r22
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %3 = extractvalue [3 x i8] %0, 0
  %4 = extractvalue [3 x i8] %1, 0
  %5 = add i8 %3, %4
  ret i8 %5
}

; NOTE: %0 costs four registers, and %1 costs two registers, while %2 is
;       passed via the stack, though there is one vacant register.
define i8 @foo8([3 x i8] %0, i8 %1, i8 %2) {
; CHECK-LABEL: foo8:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    add r22, r20
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 251
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r24, X
; CHECK-NEXT:    sub r24, r22
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %4 = extractvalue [3 x i8] %0, 0
  %5 = add i8 %4, %1
  %6 = sub i8 %2, %5
  ret i8 %6
}

; NOTE: %0 is passed via registers, though there are 6 vacant registers.
define i8 @foo9([7 x i8] %0) {
; CHECK-LABEL: foo9:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 250
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r25, X
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 251
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r24, X
; CHECK-NEXT:    add r24, r25
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %2 = extractvalue [7 x i8] %0, 0
  %3 = extractvalue [7 x i8] %0, 1
  %4 = add i8 %2, %3
  ret i8 %4
}

; NOTE: %0 costs six registers, while %1 and %2 are passed via the stack.
define i8 @fooa([6 x i8] %0, i8 %1, i8 %2) {
; CHECK-LABEL: fooa:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r28
; CHECK-NEXT:    push r29
; CHECK-NEXT:    in r28, 61
; CHECK-NEXT:    in r29, 62
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 251
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r25, X
; CHECK-NEXT:    mov r26, r28
; CHECK-NEXT:    mov r27, r29
; CHECK-NEXT:    subi r26, 250
; CHECK-NEXT:    sbci r27, 255
; CHECK-NEXT:    ld r24, X
; CHECK-NEXT:    sub r24, r25
; CHECK-NEXT:    sub r24, r20
; CHECK-NEXT:    pop r29
; CHECK-NEXT:    pop r28
; CHECK-NEXT:    ret
  %4 = extractvalue [6 x i8] %0, 0
  %5 = sub i8 %2, %1
  %6 = sub i8 %5, %4
  ret i8 %6
}