1 // RUN: %clang_cc1 -triple avr -target-cpu atmega328 -emit-llvm %s -o - \ 2 // RUN: | FileCheck %s --check-prefix AVR 3 // RUN: %clang_cc1 -triple avr -target-cpu attiny40 -emit-llvm %s -o - \ 4 // RUN: | FileCheck %s --check-prefix TINY 5 6 // NOTE: All arguments are passed via the stack for functions with variable arguments. 7 // AVR: define {{.*}} i8 @foo0(i8 {{.*}}, i8 {{.*}}, ...) 8 // TINY: define {{.*}} i8 @foo0(i8 {{.*}}, i8 {{.*}}, ...) 9 // AVR-NOT: define {{.*}} i8 @foo0(i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}, ...) 10 // TINY-NOT: define {{.*}} i8 @foo0(i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}, ...) 11 char foo0(char a, char b, ...) { 12 return a + b; 13 } 14 15 // NOTE: All arguments are passed via registers on both avr and avrtiny. 16 // AVR: define {{.*}} i8 @foo1(i32 {{.*}}, i8 {{.*}} signext {{.*}}) 17 // TINY: define {{.*}} i8 @foo1(i32 {{.*}}, i8 {{.*}} signext {{.*}}) 18 char foo1(long a, char b) { 19 return a + b; 20 } 21 22 // NOTE: The argument `char c` is passed via registers on avr, while via the stack on avrtiny. 23 // The argument `char b` costs 2 registers, so there is no vacant register left for 24 // `char c` on avrtiny. 25 // AVR: define {{.*}} i8 @foo2(i32 {{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}) 26 // TINY: define {{.*}} i8 @foo2(i32 {{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}}) 27 // TINY-NOT: define {{.*}} i8 @foo2(i32 {{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}) 28 char foo2(long a, char b, char c) { 29 return a + b + c; 30 } 31 32 // NOTE: On avr, the argument `a` costs 16 registers and `b` costs 2 registers, so 33 // `c` has to be passed via the stack. 34 // AVR: define {{.*}} i8 @foo3({{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}}) 35 // AVR-NOT: define {{.*}} i8 @foo3({{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}) 36 // TINY: define {{.*}} i8 @foo3({{.*}}, i8 {{.*}}, i8 {{.*}}) 37 // TINY-NOT: define {{.*}} i8 @foo3({{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}) 38 struct s15 { 39 char arr[15]; 40 }; 41 char foo3(struct s15 a, char b, char c) { 42 return a.arr[b] + a.arr[c]; 43 } 44 45 // NOTE: On avr, `a` only costs 16 registers, though there are 2 vacant registers, 46 // both `b` and `c` have to be passed via the stack. 47 // AVR: define {{.*}} i8 @foo4({{.*}}, i32 {{.*}}, i8 {{.*}}) 48 // AVR-NOT: define {{.*}} i8 @foo4({{.*}}, i32 {{.*}}, i8 {{.*}} signext {{.*}}) 49 // TINY: define {{.*}} i8 @foo4({{.*}}, i32 {{.*}}, i8 {{.*}}) 50 // TINY-NOT: define {{.*}} i8 @foo4({{.*}}, i32 {{.*}}, i8 {{.*}} signext {{.*}}) 51 char foo4(struct s15 a, long b, char c) { 52 return a.arr[c]; 53 } 54 55 // NOTE: On avrtiny, `a` only costs 4 registers, though there are 2 vacant 56 // registers, both `b` and `c` are passed via the stack. 57 // AVR: define {{.*}} i8 @foo5(i32 {{.*}}, i32 {{.*}}, i8 {{.*}} signext {{.*}}) 58 // TINY: define {{.*}} i8 @foo5(i32 {{.*}}, i32 {{.*}}, i8 {{.*}}) 59 // TINY-NOT: define {{.*}} i8 @foo5(i32 {{.*}}, i32 {{.*}}, i8 {{.*}} signext {{.*}}) 60 char foo5(long a, long b, char c) { 61 return c + 1; 62 } 63 64 // NOTE: All arguments are passed via the stack, though all registers are vacant. 65 // AVR: define {{.*}} i8 @foo6({{.*}}, i8 {{.*}}) 66 // AVR-NOT: define {{.*}} i8 @foo6({{.*}}, i8 {{.*}} signext {{.*}}) 67 // TINY: define {{.*}} i8 @foo6({{.*}}, i8 {{.*}}) 68 // TINY-NOT: define {{.*}} i8 @foo6({{.*}}, i8 {{.*}} signext {{.*}}) 69 struct s32 { 70 char arr[32]; 71 }; 72 char foo6(struct s32 a, char b) { 73 return a.arr[b]; 74 } 75 76 // NOTE: All arguments are passed via registers on avr. While all arguments are passed 77 // via the stack on avrtiny, though all registers are vacant. 78 // AVR: define {{.*}} i8 @foo7({{.*}}, i8 {{.*}} signext {{.*}}) 79 // TINY: define {{.*}} i8 @foo7({{.*}}, i8 {{.*}}) 80 // TINY-NOT: define {{.*}} i8 @foo7({{.*}}, i8 {{.*}} signext {{.*}}) 81 char foo7(struct s15 a, char b) { 82 return a.arr[b]; 83 } 84 85 // NOTE: On avr, though `a` only cost 16 registers, `b` has to be passed via the 86 // stack, since there is an implicit pointer argument costs 2 registers. 87 // AVR: define {{.*}} @foo8({{.*}}, {{.*}}, i8 {{.*}}) 88 // AVR-NOT: define {{.*}} @foo8({{.*}}, {{.*}}, i8 {{.*}} signext {{.*}}) 89 // TINY: define {{.*}} @foo8({{.*}}, {{.*}}, i8 {{.*}}) 90 // TINY-NOT: define {{.*}} @foo8({{.*}}, {{.*}}, i8 {{.*}} signext {{.*}}) 91 struct s15 foo8(struct s15 a, char b) { 92 a.arr[0] = b; 93 return a; 94 } 95 96 // NOTE: On avrtiny, `b` has to be passed via the stack, since there is an 97 // implicit pointer argument costs 2 registers. 98 // AVR: define {{.*}} @foo9({{.*}}, i32 {{.*}}, i8 {{.*}} signext {{.*}}) 99 // TINY: define {{.*}} @foo9({{.*}}, i32 {{.*}}, i8 {{.*}}) 100 // TINY-NOT: define {{.*}} @foo9({{.*}}, i32 {{.*}}, i8 {{.*}} signext {{.*}}) 101 struct s15 foo9(long a, char b) { 102 struct s15 x; 103 x.arr[0] = b; 104 return x; 105 } 106 107 // NOTE: All arguments are passed via registers, though there is an implicit 108 // pointer argument costs 2 registers. 109 // AVR: define {{.*}} @fooa({{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}) 110 // TINY: define {{.*}} @fooa({{.*}}, i8 {{.*}} signext {{.*}}, i8 {{.*}} signext {{.*}}) 111 struct s15 fooa(char a, char b) { 112 struct s15 x; 113 x.arr[0] = a; 114 x.arr[1] = b; 115 return x; 116 } 117