xref: /llvm-project/llvm/test/CodeGen/ARM/func-argpassing-endian.ll (revision a39389ebffd096dcf16ab1d9580e2d34d6ab37ad)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs < %s -mtriple=arm-eabi -mattr=v7,neon | FileCheck %s --check-prefixes=CHECK,CHECK-LE
3; RUN: llc -verify-machineinstrs < %s -mtriple=armeb-eabi -mattr=v7,neon | FileCheck %s --check-prefixes=CHECK,CHECK-BE
4
5@var32 = global i32 0
6@vardouble = global double 0.0
7
8define void @arg_longint( i64 %val ) {
9; CHECK-LE-LABEL: arg_longint:
10; CHECK-LE:       @ %bb.0:
11; CHECK-LE-NEXT:    movw r1, :lower16:var32
12; CHECK-LE-NEXT:    movt r1, :upper16:var32
13; CHECK-LE-NEXT:    str r0, [r1]
14; CHECK-LE-NEXT:    bx lr
15;
16; CHECK-BE-LABEL: arg_longint:
17; CHECK-BE:       @ %bb.0:
18; CHECK-BE-NEXT:    movw r0, :lower16:var32
19; CHECK-BE-NEXT:    movt r0, :upper16:var32
20; CHECK-BE-NEXT:    str r1, [r0]
21; CHECK-BE-NEXT:    bx lr
22   %tmp = trunc i64 %val to i32
23   store i32 %tmp, i32* @var32
24   ret void
25}
26
27define void @arg_double( double %val ) {
28; CHECK-LABEL: arg_double:
29; CHECK:       @ %bb.0:
30; CHECK-NEXT:    movw r2, :lower16:vardouble
31; CHECK-NEXT:    movt r2, :upper16:vardouble
32; CHECK-NEXT:    strd r0, r1, [r2]
33; CHECK-NEXT:    bx lr
34    store double  %val, double* @vardouble
35    ret void
36}
37
38define void @arg_v4i32(<4 x i32> %vec ) {
39; CHECK-LE-LABEL: arg_v4i32:
40; CHECK-LE:       @ %bb.0:
41; CHECK-LE-NEXT:    vmov d17, r2, r3
42; CHECK-LE-NEXT:    vmov d16, r0, r1
43; CHECK-LE-NEXT:    movw r0, :lower16:var32
44; CHECK-LE-NEXT:    movt r0, :upper16:var32
45; CHECK-LE-NEXT:    vst1.32 {d16[0]}, [r0:32]
46; CHECK-LE-NEXT:    bx lr
47;
48; CHECK-BE-LABEL: arg_v4i32:
49; CHECK-BE:       @ %bb.0:
50; CHECK-BE-NEXT:    vmov d17, r3, r2
51; CHECK-BE-NEXT:    vmov d16, r1, r0
52; CHECK-BE-NEXT:    movw r0, :lower16:var32
53; CHECK-BE-NEXT:    movt r0, :upper16:var32
54; CHECK-BE-NEXT:    vrev64.32 q8, q8
55; CHECK-BE-NEXT:    vst1.32 {d16[0]}, [r0:32]
56; CHECK-BE-NEXT:    bx lr
57    %tmp = extractelement <4 x i32> %vec, i32 0
58    store i32 %tmp, i32* @var32
59    ret void
60}
61
62define void @arg_v2f64(<2 x double> %vec ) {
63; CHECK-LABEL: arg_v2f64:
64; CHECK:       @ %bb.0:
65; CHECK-NEXT:    movw r2, :lower16:vardouble
66; CHECK-NEXT:    movt r2, :upper16:vardouble
67; CHECK-NEXT:    strd r0, r1, [r2]
68; CHECK-NEXT:    bx lr
69    %tmp = extractelement <2 x double> %vec, i32 0
70    store double %tmp, double* @vardouble
71    ret void
72}
73
74define i64 @return_longint() {
75; CHECK-LE-LABEL: return_longint:
76; CHECK-LE:       @ %bb.0:
77; CHECK-LE-NEXT:    mov r0, #42
78; CHECK-LE-NEXT:    mov r1, #0
79; CHECK-LE-NEXT:    bx lr
80;
81; CHECK-BE-LABEL: return_longint:
82; CHECK-BE:       @ %bb.0:
83; CHECK-BE-NEXT:    mov r0, #0
84; CHECK-BE-NEXT:    mov r1, #42
85; CHECK-BE-NEXT:    bx lr
86    ret i64 42
87}
88
89define double @return_double() {
90; CHECK-LE-LABEL: return_double:
91; CHECK-LE:       @ %bb.0:
92; CHECK-LE-NEXT:    vmov.f64 d16, #1.000000e+00
93; CHECK-LE-NEXT:    vmov r0, r1, d16
94; CHECK-LE-NEXT:    bx lr
95;
96; CHECK-BE-LABEL: return_double:
97; CHECK-BE:       @ %bb.0:
98; CHECK-BE-NEXT:    vmov.f64 d16, #1.000000e+00
99; CHECK-BE-NEXT:    vmov r1, r0, d16
100; CHECK-BE-NEXT:    bx lr
101    ret double 1.0
102}
103
104define <4 x i32> @return_v4i32() {
105; CHECK-LE-LABEL: return_v4i32:
106; CHECK-LE:       @ %bb.0:
107; CHECK-LE-NEXT:    adr r0, .LCPI6_0
108; CHECK-LE-NEXT:    vld1.64 {d16, d17}, [r0:128]
109; CHECK-LE-NEXT:    vmov r0, r1, d16
110; CHECK-LE-NEXT:    vmov r2, r3, d17
111; CHECK-LE-NEXT:    bx lr
112; CHECK-LE-NEXT:    .p2align 4
113; CHECK-LE-NEXT:  @ %bb.1:
114; CHECK-LE-NEXT:  .LCPI6_0:
115; CHECK-LE-NEXT:    .long 42 @ double 9.1245819032257467E-313
116; CHECK-LE-NEXT:    .long 43
117; CHECK-LE-NEXT:    .long 44 @ double 9.5489810615176143E-313
118; CHECK-LE-NEXT:    .long 45
119;
120; CHECK-BE-LABEL: return_v4i32:
121; CHECK-BE:       @ %bb.0:
122; CHECK-BE-NEXT:    adr r0, .LCPI6_0
123; CHECK-BE-NEXT:    vld1.64 {d16, d17}, [r0:128]
124; CHECK-BE-NEXT:    vmov r1, r0, d16
125; CHECK-BE-NEXT:    vmov r3, r2, d17
126; CHECK-BE-NEXT:    bx lr
127; CHECK-BE-NEXT:    .p2align 4
128; CHECK-BE-NEXT:  @ %bb.1:
129; CHECK-BE-NEXT:  .LCPI6_0:
130; CHECK-BE-NEXT:    .long 42 @ double 8.912382324178626E-313
131; CHECK-BE-NEXT:    .long 43
132; CHECK-BE-NEXT:    .long 44 @ double 9.3367814824704935E-313
133; CHECK-BE-NEXT:    .long 45
134   ret < 4 x i32> < i32 42, i32 43, i32 44, i32 45 >
135}
136
137define <2 x double> @return_v2f64() {
138; CHECK-LE-LABEL: return_v2f64:
139; CHECK-LE:       @ %bb.0:
140; CHECK-LE-NEXT:    vldr d16, .LCPI7_0
141; CHECK-LE-NEXT:    vldr d17, .LCPI7_1
142; CHECK-LE-NEXT:    vmov r0, r1, d16
143; CHECK-LE-NEXT:    vmov r2, r3, d17
144; CHECK-LE-NEXT:    bx lr
145; CHECK-LE-NEXT:    .p2align 3
146; CHECK-LE-NEXT:  @ %bb.1:
147; CHECK-LE-NEXT:  .LCPI7_0:
148; CHECK-LE-NEXT:    .long 1374389535 @ double 3.1400000000000001
149; CHECK-LE-NEXT:    .long 1074339512
150; CHECK-LE-NEXT:  .LCPI7_1:
151; CHECK-LE-NEXT:    .long 1374389535 @ double 6.2800000000000002
152; CHECK-LE-NEXT:    .long 1075388088
153;
154; CHECK-BE-LABEL: return_v2f64:
155; CHECK-BE:       @ %bb.0:
156; CHECK-BE-NEXT:    vldr d16, .LCPI7_0
157; CHECK-BE-NEXT:    vldr d17, .LCPI7_1
158; CHECK-BE-NEXT:    vmov r1, r0, d16
159; CHECK-BE-NEXT:    vmov r3, r2, d17
160; CHECK-BE-NEXT:    bx lr
161; CHECK-BE-NEXT:    .p2align 3
162; CHECK-BE-NEXT:  @ %bb.1:
163; CHECK-BE-NEXT:  .LCPI7_0:
164; CHECK-BE-NEXT:    .long 1074339512 @ double 3.1400000000000001
165; CHECK-BE-NEXT:    .long 1374389535
166; CHECK-BE-NEXT:  .LCPI7_1:
167; CHECK-BE-NEXT:    .long 1075388088 @ double 6.2800000000000002
168; CHECK-BE-NEXT:    .long 1374389535
169   ret <2 x double> < double 3.14, double 6.28 >
170}
171
172define void @caller_arg_longint() {
173; CHECK-LE-LABEL: caller_arg_longint:
174; CHECK-LE:       @ %bb.0:
175; CHECK-LE-NEXT:    .save {r11, lr}
176; CHECK-LE-NEXT:    push {r11, lr}
177; CHECK-LE-NEXT:    mov r0, #42
178; CHECK-LE-NEXT:    mov r1, #0
179; CHECK-LE-NEXT:    bl arg_longint
180; CHECK-LE-NEXT:    pop {r11, pc}
181;
182; CHECK-BE-LABEL: caller_arg_longint:
183; CHECK-BE:       @ %bb.0:
184; CHECK-BE-NEXT:    .save {r11, lr}
185; CHECK-BE-NEXT:    push {r11, lr}
186; CHECK-BE-NEXT:    mov r0, #0
187; CHECK-BE-NEXT:    mov r1, #42
188; CHECK-BE-NEXT:    bl arg_longint
189; CHECK-BE-NEXT:    pop {r11, pc}
190   call void @arg_longint( i64 42 )
191   ret void
192}
193
194define void @caller_arg_double() {
195; CHECK-LE-LABEL: caller_arg_double:
196; CHECK-LE:       @ %bb.0:
197; CHECK-LE-NEXT:    .save {r11, lr}
198; CHECK-LE-NEXT:    push {r11, lr}
199; CHECK-LE-NEXT:    vmov.f64 d16, #1.000000e+00
200; CHECK-LE-NEXT:    vmov r0, r1, d16
201; CHECK-LE-NEXT:    bl arg_double
202; CHECK-LE-NEXT:    pop {r11, pc}
203;
204; CHECK-BE-LABEL: caller_arg_double:
205; CHECK-BE:       @ %bb.0:
206; CHECK-BE-NEXT:    .save {r11, lr}
207; CHECK-BE-NEXT:    push {r11, lr}
208; CHECK-BE-NEXT:    vmov.f64 d16, #1.000000e+00
209; CHECK-BE-NEXT:    vmov r1, r0, d16
210; CHECK-BE-NEXT:    bl arg_double
211; CHECK-BE-NEXT:    pop {r11, pc}
212   call void @arg_double( double 1.0 )
213   ret void
214}
215
216define void @caller_return_longint() {
217; CHECK-LE-LABEL: caller_return_longint:
218; CHECK-LE:       @ %bb.0:
219; CHECK-LE-NEXT:    .save {r11, lr}
220; CHECK-LE-NEXT:    push {r11, lr}
221; CHECK-LE-NEXT:    bl return_longint
222; CHECK-LE-NEXT:    movw r1, :lower16:var32
223; CHECK-LE-NEXT:    movt r1, :upper16:var32
224; CHECK-LE-NEXT:    str r0, [r1]
225; CHECK-LE-NEXT:    pop {r11, pc}
226;
227; CHECK-BE-LABEL: caller_return_longint:
228; CHECK-BE:       @ %bb.0:
229; CHECK-BE-NEXT:    .save {r11, lr}
230; CHECK-BE-NEXT:    push {r11, lr}
231; CHECK-BE-NEXT:    bl return_longint
232; CHECK-BE-NEXT:    movw r0, :lower16:var32
233; CHECK-BE-NEXT:    movt r0, :upper16:var32
234; CHECK-BE-NEXT:    str r1, [r0]
235; CHECK-BE-NEXT:    pop {r11, pc}
236   %val = call i64 @return_longint()
237   %tmp = trunc i64 %val to i32
238   store i32 %tmp, i32* @var32
239   ret void
240}
241
242define void @caller_return_double() {
243; CHECK-LE-LABEL: caller_return_double:
244; CHECK-LE:       @ %bb.0:
245; CHECK-LE-NEXT:    .save {r11, lr}
246; CHECK-LE-NEXT:    push {r11, lr}
247; CHECK-LE-NEXT:    bl return_double
248; CHECK-LE-NEXT:    vmov d17, r0, r1
249; CHECK-LE-NEXT:    vldr d16, .LCPI11_0
250; CHECK-LE-NEXT:    movw r0, :lower16:vardouble
251; CHECK-LE-NEXT:    vadd.f64 d16, d17, d16
252; CHECK-LE-NEXT:    movt r0, :upper16:vardouble
253; CHECK-LE-NEXT:    vstr d16, [r0]
254; CHECK-LE-NEXT:    pop {r11, pc}
255; CHECK-LE-NEXT:    .p2align 3
256; CHECK-LE-NEXT:  @ %bb.1:
257; CHECK-LE-NEXT:  .LCPI11_0:
258; CHECK-LE-NEXT:    .long 1374389535 @ double 3.1400000000000001
259; CHECK-LE-NEXT:    .long 1074339512
260;
261; CHECK-BE-LABEL: caller_return_double:
262; CHECK-BE:       @ %bb.0:
263; CHECK-BE-NEXT:    .save {r11, lr}
264; CHECK-BE-NEXT:    push {r11, lr}
265; CHECK-BE-NEXT:    bl return_double
266; CHECK-BE-NEXT:    vmov d17, r1, r0
267; CHECK-BE-NEXT:    vldr d16, .LCPI11_0
268; CHECK-BE-NEXT:    movw r0, :lower16:vardouble
269; CHECK-BE-NEXT:    vadd.f64 d16, d17, d16
270; CHECK-BE-NEXT:    movt r0, :upper16:vardouble
271; CHECK-BE-NEXT:    vstr d16, [r0]
272; CHECK-BE-NEXT:    pop {r11, pc}
273; CHECK-BE-NEXT:    .p2align 3
274; CHECK-BE-NEXT:  @ %bb.1:
275; CHECK-BE-NEXT:  .LCPI11_0:
276; CHECK-BE-NEXT:    .long 1074339512 @ double 3.1400000000000001
277; CHECK-BE-NEXT:    .long 1374389535
278  %val = call double @return_double( )
279  %tmp = fadd double %val, 3.14
280  store double  %tmp, double* @vardouble
281  ret void
282}
283
284define void @caller_return_v2f64() {
285; CHECK-LABEL: caller_return_v2f64:
286; CHECK:       @ %bb.0:
287; CHECK-NEXT:    .save {r11, lr}
288; CHECK-NEXT:    push {r11, lr}
289; CHECK-NEXT:    bl return_v2f64
290; CHECK-NEXT:    movw r2, :lower16:vardouble
291; CHECK-NEXT:    movt r2, :upper16:vardouble
292; CHECK-NEXT:    strd r0, r1, [r2]
293; CHECK-NEXT:    pop {r11, pc}
294   %val = call <2 x double> @return_v2f64( )
295   %tmp = extractelement <2 x double> %val, i32 0
296    store double %tmp, double* @vardouble
297    ret void
298}
299