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