• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -march=avr -mattr=avr6 | FileCheck %s
2
3; TODO: test returning byval structs
4
5declare i8 @foo8_1(i8)
6declare i8 @foo8_2(i8, i8, i8)
7declare i8 @foo8_3(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8)
8
9declare i16 @foo16_1(i16, i16)
10declare i16 @foo16_2(i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16)
11
12declare i32 @foo32_1(i32, i32)
13declare i32 @foo32_2(i32, i32, i32, i32, i32)
14
15declare i64 @foo64_1(i64)
16declare i64 @foo64_2(i64, i64, i64)
17
18define i8 @calli8_reg() {
19; CHECK-LABEL: calli8_reg:
20; CHECK: ldi r24, 12
21; CHECK: call foo8_1
22; CHECK: ldi r24, 12
23; CHECK: ldi r22, 13
24; CHECK: ldi r20, 14
25; CHECK: call foo8_2
26    %result1 = call i8 @foo8_1(i8 12)
27    %result2 = call i8 @foo8_2(i8 12, i8 13, i8 14)
28    ret i8 %result2
29}
30
31define i8 @calli8_stack() {
32; CHECK-LABEL: calli8_stack:
33; CHECK: ldi [[REG1:r[0-9]+]], 10
34; CHECK: ldi [[REG2:r[0-9]+]], 11
35; CHECK: push [[REG2]]
36; CHECK: push [[REG1]]
37; CHECK: call foo8_3
38    %result1 = call i8 @foo8_3(i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11)
39    ret i8 %result1
40}
41
42define i16 @calli16_reg() {
43; CHECK-LABEL: calli16_reg:
44; CHECK: ldi r24, 1
45; CHECK: ldi r25, 2
46; CHECK: ldi r22, 2
47; CHECK: ldi r23, 2
48; CHECK: call foo16_1
49    %result1 = call i16 @foo16_1(i16 513, i16 514)
50    ret i16 %result1
51}
52
53define i16 @calli16_stack() {
54; CHECK-LABEL: calli16_stack:
55; CHECK: ldi [[REG1:r[0-9]+]], 9
56; CHECK: ldi [[REG2:r[0-9]+]], 2
57; CHECK: push [[REG2]]
58; CHECK: push [[REG1]]
59; CHECK: ldi [[REG1:r[0-9]+]], 10
60; CHECK: ldi [[REG2:r[0-9]+]], 2
61; CHECK: push [[REG2]]
62; CHECK: push [[REG1]]
63; CHECK: call foo16_2
64    %result1 = call i16 @foo16_2(i16 512, i16 513, i16 514, i16 515, i16 516, i16 517, i16 518, i16 519, i16 520, i16 521, i16 522)
65    ret i16 %result1
66}
67
68define i32 @calli32_reg() {
69; CHECK-LABEL: calli32_reg:
70; CHECK: ldi r22, 64
71; CHECK: ldi r23, 66
72; CHECK: ldi r24, 15
73; CHECK: ldi r25, 2
74; CHECK: ldi r18, 128
75; CHECK: ldi r19, 132
76; CHECK: ldi r20, 30
77; CHECK: ldi r21, 2
78; CHECK: call foo32_1
79    %result1 = call i32 @foo32_1(i32 34554432, i32 35554432)
80    ret i32 %result1
81}
82
83define i32 @calli32_stack() {
84; CHECK-LABEL: calli32_stack:
85; CHECK: ldi [[REG1:r[0-9]+]], 64
86; CHECK: ldi [[REG2:r[0-9]+]], 66
87; CHECK: push [[REG2]]
88; CHECK: push [[REG1]]
89; CHECK: ldi [[REG1:r[0-9]+]], 15
90; CHECK: ldi [[REG2:r[0-9]+]], 2
91; CHECK: push [[REG2]]
92; CHECK: push [[REG1]]
93; CHECK: call foo32_2
94    %result1 = call i32 @foo32_2(i32 1, i32 2, i32 3, i32 4, i32 34554432)
95    ret i32 %result1
96}
97
98define i64 @calli64_reg() {
99; CHECK-LABEL: calli64_reg:
100; CHECK: ldi r18, 255
101; CHECK: ldi r19, 255
102; CHECK: ldi r20, 155
103; CHECK: ldi r21, 88
104; CHECK: ldi r22, 76
105; CHECK: ldi r23, 73
106; CHECK: ldi r24, 31
107; CHECK: ldi r25, 242
108; CHECK: call foo64_1
109    %result1 = call i64 @foo64_1(i64 17446744073709551615)
110    ret i64 %result1
111}
112
113define i64 @calli64_stack() {
114; CHECK-LABEL: calli64_stack:
115
116; CHECK: ldi [[REG1:r[0-9]+]], 76
117; CHECK: ldi [[REG2:r[0-9]+]], 73
118; CHECK: push [[REG2]]
119; CHECK: push [[REG1]]
120; CHECK: ldi [[REG1:r[0-9]+]], 31
121; CHECK: ldi [[REG2:r[0-9]+]], 242
122; CHECK: push [[REG2]]
123; CHECK: push [[REG1]]
124; CHECK: ldi [[REG1:r[0-9]+]], 155
125; CHECK: ldi [[REG2:r[0-9]+]], 88
126; CHECK: push [[REG2]]
127; CHECK: push [[REG1]]
128; CHECK: ldi [[REG1:r[0-9]+]], 255
129; CHECK: ldi [[REG2:r[0-9]+]], 255
130; CHECK: push [[REG2]]
131; CHECK: push [[REG1]]
132; CHECK: call foo64_2
133    %result1 = call i64 @foo64_2(i64 1, i64 2, i64 17446744073709551615)
134    ret i64 %result1
135}
136
137; Test passing arguments through the stack when the call frame is allocated
138; in the prologue.
139declare void @foo64_3(i64, i64, i64, i8, i16*)
140
141define void @testcallprologue() {
142; CHECK-LABEL: testcallprologue:
143; CHECK: push r28
144; CHECK: push r29
145; CHECK: sbiw r28, 27
146; CHECK: ldi [[REG1:r[0-9]+]], 88
147; CHECK: std Y+9, [[REG1]]
148; CHECK: ldi [[REG1:r[0-9]+]], 11
149; CHECK: ldi [[REG2:r[0-9]+]], 10
150; CHECK: std Y+7, [[REG1]]
151; CHECK: std Y+8, [[REG2]]
152; CHECK: ldi [[REG1:r[0-9]+]], 13
153; CHECK: ldi [[REG2:r[0-9]+]], 12
154; CHECK: std Y+5, [[REG1]]
155; CHECK: std Y+6, [[REG2]]
156; CHECK: ldi [[REG1:r[0-9]+]], 15
157; CHECK: ldi [[REG2:r[0-9]+]], 14
158; CHECK: std Y+3, [[REG1]]
159; CHECK: std Y+4, [[REG2]]
160; CHECK: ldi [[REG1:r[0-9]+]], 8
161; CHECK: ldi [[REG2:r[0-9]+]], 9
162; CHECK: std Y+1, [[REG1]]
163; CHECK: std Y+2, [[REG2]]
164; CHECK: pop r29
165; CHECK: pop r28
166  %p = alloca [8 x i16]
167  %arraydecay = getelementptr inbounds [8 x i16], [8 x i16]* %p, i16 0, i16 0
168  call void @foo64_3(i64 723685415333071112, i64 723685415333071112, i64 723685415333071112, i8 88, i16* %arraydecay)
169  ret void
170}
171
172define i32 @icall(i32 (i32)* %foo) {
173; CHECK-LABEL: icall:
174; CHECK: movw [[REG:r[0-9]+]], r24
175; CHECK: ldi r22, 147
176; CHECK: ldi r23, 248
177; CHECK: ldi r24, 214
178; CHECK: ldi r25, 198
179; CHECK: movw r30, [[REG]]
180; CHECK: icall
181; CHECK: subi r22, 251
182; CHECK: sbci r23, 255
183; CHECK: sbci r24, 255
184; CHECK: sbci r25, 255
185  %1 = call i32 %foo(i32 3335977107)
186  %2 = add nsw i32 %1, 5
187  ret i32 %2
188}
189
190; Calling external functions (like __divsf3) require extra processing for
191; arguments and return values in the LowerCall function.
192declare i32 @foofloat(float)
193
194define i32 @externcall(float %a, float %b) {
195; CHECK-LABEL: externcall:
196; CHECK: movw [[REG1:(r[0-9]+|[XYZ])]], r24
197; CHECK: movw [[REG2:(r[0-9]+|[XYZ])]], r22
198; CHECK: movw r22, r18
199; CHECK: movw r24, r20
200; CHECK: movw r18, [[REG2]]
201; CHECK: movw r20, [[REG1]]
202; CHECK: call __divsf3
203; CHECK: call foofloat
204; CHECK: subi r22, 251
205; CHECK: sbci r23, 255
206; CHECK: sbci r24, 255
207; CHECK: sbci r25, 255
208  %1 = fdiv float %b, %a
209  %2 = call i32 @foofloat(float %1)
210  %3 = add nsw i32 %2, 5
211  ret i32 %3
212}
213