xref: /llvm-project/llvm/test/CodeGen/AVR/calling-conv/c/tiny.ll (revision d1d3005c9fe6a1ded17d4cad373cae85c743e7f3)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=avr -mcpu=avrtiny | FileCheck %s
3
4; NOTE: Both %a(i8) and %b(i8) cost two registers.
5define i8 @foo0(i8 %a, i8 %b) {
6; CHECK-LABEL: foo0:
7; CHECK:       ; %bb.0:
8; CHECK-NEXT:    sub r24, r22
9; CHECK-NEXT:    ret
10  %c = sub i8 %a, %b
11  ret i8 %c
12}
13
14; NOTE: Both %a(i16) and %b(i16) cost two registers.
15define i16 @foo1(i16 %a, i16 %b) {
16; CHECK-LABEL: foo1:
17; CHECK:       ; %bb.0:
18; CHECK-NEXT:    sub r24, r22
19; CHECK-NEXT:    sbc r25, r23
20; CHECK-NEXT:    ret
21  %c = sub i16 %a, %b
22  ret i16 %c
23}
24
25; NOTE: %a(i16), %b(i16) and %c(i16) each costs two registers.
26define i16 @foo2(i16 %a, i16 %b, i16 %c) {
27; CHECK-LABEL: foo2:
28; CHECK:       ; %bb.0:
29; CHECK-NEXT:    sub r22, r24
30; CHECK-NEXT:    sbc r23, r25
31; CHECK-NEXT:    add r22, r20
32; CHECK-NEXT:    adc r23, r21
33; CHECK-NEXT:    mov r24, r22
34; CHECK-NEXT:    mov r25, r23
35; CHECK-NEXT:    ret
36  %d = sub i16 %a, %b
37  %e = sub i16 %c, %d
38  ret i16 %e
39}
40
41; NOTE:  %a(i16), %b(i16) and %c(i16) each costs two registers,
42;        while %d(i16) is passed via the stack.
43define i16 @foo3(i16 %a, i16 %b, i16 %c, i16 %d) {
44; CHECK-LABEL: foo3:
45; CHECK:       ; %bb.0:
46; CHECK-NEXT:    push r28
47; CHECK-NEXT:    push r29
48; CHECK-NEXT:    in r28, 61
49; CHECK-NEXT:    in r29, 62
50; CHECK-NEXT:    in r16, 63
51; CHECK-NEXT:    subi r28, 251
52; CHECK-NEXT:    sbci r29, 255
53; CHECK-NEXT:    ld r30, Y+
54; CHECK-NEXT:    ld r31, Y+
55; CHECK-NEXT:    subi r28, 2
56; CHECK-NEXT:    sbci r29, 0
57; CHECK-NEXT:    subi r28, 5
58; CHECK-NEXT:    sbci r29, 0
59; CHECK-NEXT:    out 63, r16
60; CHECK-NEXT:    sub r20, r30
61; CHECK-NEXT:    sbc r21, r31
62; CHECK-NEXT:    sub r24, r22
63; CHECK-NEXT:    sbc r25, r23
64; CHECK-NEXT:    add r24, r20
65; CHECK-NEXT:    adc r25, r21
66; CHECK-NEXT:    pop r29
67; CHECK-NEXT:    pop r28
68; CHECK-NEXT:    ret
69  %e = sub i16 %a, %b
70  %g = sub i16 %c, %d
71  %h = add i16 %e, %g
72  ret i16 %h
73}
74
75; NOTE: %a(i32) costs four registers, while %b(i32) is passed via the stack.
76define i32 @foo4(i32 %a, i32 %b) {
77; CHECK-LABEL: foo4:
78; CHECK:       ; %bb.0:
79; CHECK-NEXT:    push r28
80; CHECK-NEXT:    push r29
81; CHECK-NEXT:    in r28, 61
82; CHECK-NEXT:    in r29, 62
83; CHECK-NEXT:    in r16, 63
84; CHECK-NEXT:    subi r28, 251
85; CHECK-NEXT:    sbci r29, 255
86; CHECK-NEXT:    ld r20, Y+
87; CHECK-NEXT:    ld r21, Y+
88; CHECK-NEXT:    subi r28, 2
89; CHECK-NEXT:    sbci r29, 0
90; CHECK-NEXT:    subi r28, 5
91; CHECK-NEXT:    sbci r29, 0
92; CHECK-NEXT:    out 63, r16
93; CHECK-NEXT:    in r16, 63
94; CHECK-NEXT:    subi r28, 249
95; CHECK-NEXT:    sbci r29, 255
96; CHECK-NEXT:    ld r30, Y+
97; CHECK-NEXT:    ld r31, Y+
98; CHECK-NEXT:    subi r28, 2
99; CHECK-NEXT:    sbci r29, 0
100; CHECK-NEXT:    subi r28, 7
101; CHECK-NEXT:    sbci r29, 0
102; CHECK-NEXT:    out 63, r16
103; CHECK-NEXT:    sub r20, r22
104; CHECK-NEXT:    sbc r21, r23
105; CHECK-NEXT:    sbc r30, r24
106; CHECK-NEXT:    sbc r31, r25
107; CHECK-NEXT:    mov r22, r20
108; CHECK-NEXT:    mov r23, r21
109; CHECK-NEXT:    mov r24, r30
110; CHECK-NEXT:    mov r25, r31
111; CHECK-NEXT:    pop r29
112; CHECK-NEXT:    pop r28
113; CHECK-NEXT:    ret
114  %c = sub i32 %b, %a
115  ret i32 %c
116}
117
118; NOTE: %0 costs six registers, while %1 is passed via the stack.
119define i8 @foo5([5 x i8] %0, i8 %1) {
120; CHECK-LABEL: foo5:
121; CHECK:       ; %bb.0:
122; CHECK-NEXT:    push r28
123; CHECK-NEXT:    push r29
124; CHECK-NEXT:    in r28, 61
125; CHECK-NEXT:    in r29, 62
126; CHECK-NEXT:    mov r26, r28
127; CHECK-NEXT:    mov r27, r29
128; CHECK-NEXT:    subi r26, 251
129; CHECK-NEXT:    sbci r27, 255
130; CHECK-NEXT:    ld r24, X
131; CHECK-NEXT:    add r24, r20
132; CHECK-NEXT:    pop r29
133; CHECK-NEXT:    pop r28
134; CHECK-NEXT:    ret
135  %3 = extractvalue [5 x i8] %0, 0
136  %4 = add i8 %3, %1
137  ret i8 %4
138}
139
140; NOTE: %0 costs two registers and %1 costs four registers.
141define i8 @foo6([2 x i8] %0, [4 x i8] %1) {
142; CHECK-LABEL: foo6:
143; CHECK:       ; %bb.0:
144; CHECK-NEXT:    add r24, r20
145; CHECK-NEXT:    ret
146  %3 = extractvalue [2 x i8] %0, 0
147  %4 = extractvalue [4 x i8] %1, 0
148  %5 = add i8 %3, %4
149  ret i8 %5
150}
151
152; NOTE: %0 cost four registers, while %1 is passed via the stack,
153;       though there are two vacant registers.
154define i8 @foo7([3 x i8] %0, [3 x i8] %1) {
155; CHECK-LABEL: foo7:
156; CHECK:       ; %bb.0:
157; CHECK-NEXT:    push r28
158; CHECK-NEXT:    push r29
159; CHECK-NEXT:    in r28, 61
160; CHECK-NEXT:    in r29, 62
161; CHECK-NEXT:    mov r26, r28
162; CHECK-NEXT:    mov r27, r29
163; CHECK-NEXT:    subi r26, 251
164; CHECK-NEXT:    sbci r27, 255
165; CHECK-NEXT:    ld r24, X
166; CHECK-NEXT:    add r24, r22
167; CHECK-NEXT:    pop r29
168; CHECK-NEXT:    pop r28
169; CHECK-NEXT:    ret
170  %3 = extractvalue [3 x i8] %0, 0
171  %4 = extractvalue [3 x i8] %1, 0
172  %5 = add i8 %3, %4
173  ret i8 %5
174}
175
176; NOTE: %0 costs four registers, and %1 costs two registers, while %2 is
177;       passed via the stack, though there is one vacant register.
178define i8 @foo8([3 x i8] %0, i8 %1, i8 %2) {
179; CHECK-LABEL: foo8:
180; CHECK:       ; %bb.0:
181; CHECK-NEXT:    push r28
182; CHECK-NEXT:    push r29
183; CHECK-NEXT:    in r28, 61
184; CHECK-NEXT:    in r29, 62
185; CHECK-NEXT:    add r22, r20
186; CHECK-NEXT:    mov r26, r28
187; CHECK-NEXT:    mov r27, r29
188; CHECK-NEXT:    subi r26, 251
189; CHECK-NEXT:    sbci r27, 255
190; CHECK-NEXT:    ld r24, X
191; CHECK-NEXT:    sub r24, r22
192; CHECK-NEXT:    pop r29
193; CHECK-NEXT:    pop r28
194; CHECK-NEXT:    ret
195  %4 = extractvalue [3 x i8] %0, 0
196  %5 = add i8 %4, %1
197  %6 = sub i8 %2, %5
198  ret i8 %6
199}
200
201; NOTE: %0 is passed via registers, though there are 6 vacant registers.
202define i8 @foo9([7 x i8] %0) {
203; CHECK-LABEL: foo9:
204; CHECK:       ; %bb.0:
205; CHECK-NEXT:    push r28
206; CHECK-NEXT:    push r29
207; CHECK-NEXT:    in r28, 61
208; CHECK-NEXT:    in r29, 62
209; CHECK-NEXT:    mov r26, r28
210; CHECK-NEXT:    mov r27, r29
211; CHECK-NEXT:    subi r26, 250
212; CHECK-NEXT:    sbci r27, 255
213; CHECK-NEXT:    ld r25, X
214; CHECK-NEXT:    mov r26, r28
215; CHECK-NEXT:    mov r27, r29
216; CHECK-NEXT:    subi r26, 251
217; CHECK-NEXT:    sbci r27, 255
218; CHECK-NEXT:    ld r24, X
219; CHECK-NEXT:    add r24, r25
220; CHECK-NEXT:    pop r29
221; CHECK-NEXT:    pop r28
222; CHECK-NEXT:    ret
223  %2 = extractvalue [7 x i8] %0, 0
224  %3 = extractvalue [7 x i8] %0, 1
225  %4 = add i8 %2, %3
226  ret i8 %4
227}
228
229; NOTE: %0 costs six registers, while %1 and %2 are passed via the stack.
230define i8 @fooa([6 x i8] %0, i8 %1, i8 %2) {
231; CHECK-LABEL: fooa:
232; CHECK:       ; %bb.0:
233; CHECK-NEXT:    push r28
234; CHECK-NEXT:    push r29
235; CHECK-NEXT:    in r28, 61
236; CHECK-NEXT:    in r29, 62
237; CHECK-NEXT:    mov r26, r28
238; CHECK-NEXT:    mov r27, r29
239; CHECK-NEXT:    subi r26, 251
240; CHECK-NEXT:    sbci r27, 255
241; CHECK-NEXT:    ld r25, X
242; CHECK-NEXT:    mov r26, r28
243; CHECK-NEXT:    mov r27, r29
244; CHECK-NEXT:    subi r26, 250
245; CHECK-NEXT:    sbci r27, 255
246; CHECK-NEXT:    ld r24, X
247; CHECK-NEXT:    sub r24, r25
248; CHECK-NEXT:    sub r24, r20
249; CHECK-NEXT:    pop r29
250; CHECK-NEXT:    pop r28
251; CHECK-NEXT:    ret
252  %4 = extractvalue [6 x i8] %0, 0
253  %5 = sub i8 %2, %1
254  %6 = sub i8 %5, %4
255  ret i8 %6
256}
257