xref: /llvm-project/llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll (revision 7bdc80f35c325d148b1ddbdfce7dea8c6ba7af84)
1; RUN: llc -mtriple=avr < %s | FileCheck %s
2
3; CHECK-LABEL: ret_void_args_struct_i8_i32
4define void @ret_void_args_struct_i8_i32({ i8, i32 } %a) {
5start:
6  ; CHECK:      sts     4, r20
7  %0 = extractvalue { i8, i32 } %a, 0
8  store volatile i8 %0, ptr inttoptr (i64 4 to ptr)
9
10  ; CHECK-NEXT: sts     8, r24
11  ; CHECK-NEXT: sts     7, r23
12  ; CHECK-NEXT: sts     6, r22
13  ; CHECK-NEXT: sts     5, r21
14  %1 = extractvalue { i8, i32 } %a, 1
15  store volatile i32 %1, ptr inttoptr (i64 5 to ptr)
16  ret void
17}
18
19; CHECK-LABEL: ret_void_args_struct_i8_i8_i8_i8
20define void @ret_void_args_struct_i8_i8_i8_i8({ i8, i8, i8, i8 } %a) {
21start:
22  ; CHECK:      sts     4, r22
23  %0 = extractvalue { i8, i8, i8, i8 } %a, 0
24  store volatile i8 %0, ptr inttoptr (i64 4 to ptr)
25  ; CHECK-NEXT: sts     5, r23
26  %1 = extractvalue { i8, i8, i8, i8 } %a, 1
27  store volatile i8 %1, ptr inttoptr (i64 5 to ptr)
28  ; CHECK-NEXT: sts     6, r24
29  %2 = extractvalue { i8, i8, i8, i8 } %a, 2
30  store volatile i8 %2, ptr inttoptr (i64 6 to ptr)
31  ; CHECK-NEXT: sts     7, r25
32  %3 = extractvalue { i8, i8, i8, i8 } %a, 3
33  store volatile i8 %3, ptr inttoptr (i64 7 to ptr)
34  ret void
35}
36
37; CHECK-LABEL: ret_void_args_struct_i32_16_i8
38define void @ret_void_args_struct_i32_16_i8({ i32, i16, i8} %a) {
39start:
40  ; CHECK:      sts     7, r21
41  ; CHECK-NEXT: sts     6, r20
42  ; CHECK-NEXT: sts     5, r19
43  ; CHECK-NEXT: sts     4, r18
44  %0 = extractvalue { i32, i16, i8 } %a, 0
45  store volatile i32 %0, ptr inttoptr (i64 4 to ptr)
46
47  ; CHECK-NEXT: sts     5, r23
48  ; CHECK-NEXT: sts     4, r22
49  %1 = extractvalue { i32, i16, i8 } %a, 1
50  store volatile i16 %1, ptr inttoptr (i64 4 to ptr)
51
52  ; CHECK-NEXT: sts     4, r24
53  %2 = extractvalue { i32, i16, i8 } %a, 2
54  store volatile i8 %2, ptr inttoptr (i64 4 to ptr)
55  ret void
56}
57
58; CHECK-LABEL: ret_void_args_struct_i8_i32_struct_i32_i8
59define void @ret_void_args_struct_i8_i32_struct_i32_i8({ i8, i32 } %a, { i32, i8 } %b) {
60start:
61  ; CHECK:      sts     4, r20
62  %0 = extractvalue { i8, i32 } %a, 0
63  store volatile i8 %0, ptr inttoptr (i64 4 to ptr)
64
65  ; CHECK-NEXT: sts     8, r24
66  ; CHECK-NEXT: sts     7, r23
67  ; CHECK-NEXT: sts     6, r22
68  ; CHECK-NEXT: sts     5, r21
69  %1 = extractvalue { i8, i32 } %a, 1
70  store volatile i32 %1, ptr inttoptr (i64 5 to ptr)
71
72  ; CHECK-NEXT:      sts     9, r17
73  ; CHECK-NEXT:      sts     8, r16
74  ; CHECK-NEXT:      sts     7, r15
75  ; CHECK-NEXT:      sts     6, r14
76  %2 = extractvalue { i32, i8 } %b, 0
77  store volatile i32 %2, ptr inttoptr (i64 6 to ptr)
78
79  ; CHECK-NEXT: sts     7, r18
80  %3 = extractvalue { i32, i8 } %b, 1
81  store volatile i8 %3, ptr inttoptr (i64 7 to ptr)
82  ret void
83}
84
85; NOTE: The %0 (8-byte array) costs 8 registers and %1 (10-byte array)
86; NOTE: costs 10 registers.
87define i8 @foo0([8 x i8] %0, [10 x i8] %1) {
88; CHECK-LABEL: foo0:
89; CHECK:       ; %bb.0:
90; CHECK-NEXT:    sub r18, r8
91; CHECK-NEXT:    mov r24, r18
92; CHECK-NEXT:    ret
93  %3 = extractvalue [8 x i8] %0, 0
94  %4 = extractvalue [10 x i8] %1, 0
95  %5 = sub i8 %3, %4
96  ret i8 %5
97}
98
99; NOTE: The %0 (7-byte array) costs 8 registers and %1 (9-byte array)
100; NOTE: costs 10 registers.
101define i8 @foo1([7 x i8] %0, [9 x i8] %1) {
102; CHECK-LABEL: foo1:
103; CHECK:       ; %bb.0:
104; CHECK-NEXT:    sub r18, r8
105; CHECK-NEXT:    mov r24, r18
106; CHECK-NEXT:    ret
107  %3 = extractvalue [7 x i8] %0, 0
108  %4 = extractvalue [9 x i8] %1, 0
109  %5 = sub i8 %3, %4
110  ret i8 %5
111}
112
113; NOTE: Each argument (6-byte array) costs 6 registers.
114define i8 @foo2([6 x i8] %0, [6 x i8] %1, [6 x i8] %2) {
115; CHECK-LABEL: foo2:
116; CHECK:       ; %bb.0:
117; CHECK-NEXT:    sub r20, r14
118; CHECK-NEXT:    add r20, r8
119; CHECK-NEXT:    mov r24, r20
120; CHECK-NEXT:    ret
121  %4 = extractvalue [6 x i8] %0, 0
122  %5 = extractvalue [6 x i8] %1, 0
123  %6 = extractvalue [6 x i8] %2, 0
124  %7 = sub i8 %4, %5
125  %8 = add i8 %7, %6
126  ret i8 %8
127}
128
129; NOTE: The %0 (9-byte array) costs 10 registers. Though there are
130; NOTE: 8 registers are vacant, the %b (9-byte array) has to be dropped
131; NOTE: to the stack.
132define i8 @foo3([9 x i8] %0, [9 x i8] %1) {
133; CHECK-LABEL: foo3:
134; CHECK:       ; %bb.0:
135; CHECK-NEXT:    push r16
136; CHECK-NEXT:    push r28
137; CHECK-NEXT:    push r29
138; CHECK-NEXT:    in r28, 61
139; CHECK-NEXT:    in r29, 62
140; CHECK-NEXT:    ldd r24, Y+6
141; CHECK-NEXT:    sub r16, r24
142; CHECK-NEXT:    mov r24, r16
143; CHECK-NEXT:    pop r29
144; CHECK-NEXT:    pop r28
145; CHECK-NEXT:    pop r16
146; CHECK-NEXT:    ret
147  %3 = extractvalue [9 x i8] %0, 0
148  %4 = extractvalue [9 x i8] %1, 0
149  %5 = sub i8 %3, %4
150  ret i8 %5
151}
152
153; NOTE: Both %0 and %1 are 7-byte arrays, and cost total 16 registers.
154; NOTE: Though there are 2 registers are vacant, the %2 (7-byte array) has to
155; NOTE: be dropped to the stack.
156define i8 @foo4([7 x i8] %0, [7 x i8] %1, [7 x i8] %2) {
157; CHECK-LABEL: foo4:
158; CHECK:       ; %bb.0:
159; CHECK-NEXT:    push r28
160; CHECK-NEXT:    push r29
161; CHECK-NEXT:    in r28, 61
162; CHECK-NEXT:    in r29, 62
163; CHECK-NEXT:    sub r18, r10
164; CHECK-NEXT:    ldd r24, Y+5
165; CHECK-NEXT:    add r24, r18
166; CHECK-NEXT:    pop r29
167; CHECK-NEXT:    pop r28
168; CHECK-NEXT:    ret
169  %4 = extractvalue [7 x i8] %0, 0
170  %5 = extractvalue [7 x i8] %1, 0
171  %6 = extractvalue [7 x i8] %2, 0
172  %7 = sub i8 %4, %5
173  %8 = add i8 %7, %6
174  ret i8 %8
175}
176