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
6 @vardouble = global double 0.0
8 define void @arg_longint( i64 %val ) {
9 ; CHECK-LE-LABEL: arg_longint:
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
16 ; CHECK-BE-LABEL: arg_longint:
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, ptr @var32
27 define void @arg_double( double %val ) {
28 ; CHECK-LABEL: arg_double:
30 ; CHECK-NEXT: movw r2, :lower16:vardouble
31 ; CHECK-NEXT: movt r2, :upper16:vardouble
32 ; CHECK-NEXT: strd r0, r1, [r2]
34 store double %val, ptr @vardouble
38 define void @arg_v4i32(<4 x i32> %vec ) {
39 ; CHECK-LE-LABEL: arg_v4i32:
41 ; CHECK-LE-NEXT: vmov d16, r0, r1
42 ; CHECK-LE-NEXT: movw r0, :lower16:var32
43 ; CHECK-LE-NEXT: movt r0, :upper16:var32
44 ; CHECK-LE-NEXT: vst1.32 {d16[0]}, [r0:32]
45 ; CHECK-LE-NEXT: bx lr
47 ; CHECK-BE-LABEL: arg_v4i32:
49 ; CHECK-BE-NEXT: vmov d16, r1, r0
50 ; CHECK-BE-NEXT: movw r0, :lower16:var32
51 ; CHECK-BE-NEXT: movt r0, :upper16:var32
52 ; CHECK-BE-NEXT: vrev64.32 q8, q8
53 ; CHECK-BE-NEXT: vst1.32 {d16[0]}, [r0:32]
54 ; CHECK-BE-NEXT: bx lr
55 %tmp = extractelement <4 x i32> %vec, i32 0
56 store i32 %tmp, ptr @var32
60 define void @arg_v2f64(<2 x double> %vec ) {
61 ; CHECK-LABEL: arg_v2f64:
63 ; CHECK-NEXT: movw r2, :lower16:vardouble
64 ; CHECK-NEXT: movt r2, :upper16:vardouble
65 ; CHECK-NEXT: strd r0, r1, [r2]
67 %tmp = extractelement <2 x double> %vec, i32 0
68 store double %tmp, ptr @vardouble
72 define i64 @return_longint() {
73 ; CHECK-LE-LABEL: return_longint:
75 ; CHECK-LE-NEXT: mov r0, #42
76 ; CHECK-LE-NEXT: mov r1, #0
77 ; CHECK-LE-NEXT: bx lr
79 ; CHECK-BE-LABEL: return_longint:
81 ; CHECK-BE-NEXT: mov r0, #0
82 ; CHECK-BE-NEXT: mov r1, #42
83 ; CHECK-BE-NEXT: bx lr
87 define double @return_double() {
88 ; CHECK-LE-LABEL: return_double:
90 ; CHECK-LE-NEXT: vmov.f64 d16, #1.000000e+00
91 ; CHECK-LE-NEXT: vmov r0, r1, d16
92 ; CHECK-LE-NEXT: bx lr
94 ; CHECK-BE-LABEL: return_double:
96 ; CHECK-BE-NEXT: vmov.f64 d16, #1.000000e+00
97 ; CHECK-BE-NEXT: vmov r1, r0, d16
98 ; CHECK-BE-NEXT: bx lr
102 define <4 x i32> @return_v4i32() {
103 ; CHECK-LABEL: return_v4i32:
105 ; CHECK-NEXT: mov r0, #42
106 ; CHECK-NEXT: mov r1, #43
107 ; CHECK-NEXT: mov r2, #44
108 ; CHECK-NEXT: mov r3, #45
110 ret < 4 x i32> < i32 42, i32 43, i32 44, i32 45 >
113 define <2 x double> @return_v2f64() {
114 ; CHECK-LE-LABEL: return_v2f64:
116 ; CHECK-LE-NEXT: vldr d16, .LCPI7_0
117 ; CHECK-LE-NEXT: vldr d17, .LCPI7_1
118 ; CHECK-LE-NEXT: vmov r0, r1, d16
119 ; CHECK-LE-NEXT: vmov r2, r3, d17
120 ; CHECK-LE-NEXT: bx lr
121 ; CHECK-LE-NEXT: .p2align 3
122 ; CHECK-LE-NEXT: @ %bb.1:
123 ; CHECK-LE-NEXT: .LCPI7_0:
124 ; CHECK-LE-NEXT: .long 1374389535 @ double 3.1400000000000001
125 ; CHECK-LE-NEXT: .long 1074339512
126 ; CHECK-LE-NEXT: .LCPI7_1:
127 ; CHECK-LE-NEXT: .long 1374389535 @ double 6.2800000000000002
128 ; CHECK-LE-NEXT: .long 1075388088
130 ; CHECK-BE-LABEL: return_v2f64:
132 ; CHECK-BE-NEXT: vldr d16, .LCPI7_0
133 ; CHECK-BE-NEXT: vldr d17, .LCPI7_1
134 ; CHECK-BE-NEXT: vmov r1, r0, d16
135 ; CHECK-BE-NEXT: vmov r3, r2, d17
136 ; CHECK-BE-NEXT: bx lr
137 ; CHECK-BE-NEXT: .p2align 3
138 ; CHECK-BE-NEXT: @ %bb.1:
139 ; CHECK-BE-NEXT: .LCPI7_0:
140 ; CHECK-BE-NEXT: .long 1074339512 @ double 3.1400000000000001
141 ; CHECK-BE-NEXT: .long 1374389535
142 ; CHECK-BE-NEXT: .LCPI7_1:
143 ; CHECK-BE-NEXT: .long 1075388088 @ double 6.2800000000000002
144 ; CHECK-BE-NEXT: .long 1374389535
145 ret <2 x double> < double 3.14, double 6.28 >
148 define void @caller_arg_longint() {
149 ; CHECK-LE-LABEL: caller_arg_longint:
151 ; CHECK-LE-NEXT: .save {r11, lr}
152 ; CHECK-LE-NEXT: push {r11, lr}
153 ; CHECK-LE-NEXT: mov r0, #42
154 ; CHECK-LE-NEXT: mov r1, #0
155 ; CHECK-LE-NEXT: bl arg_longint
156 ; CHECK-LE-NEXT: pop {r11, pc}
158 ; CHECK-BE-LABEL: caller_arg_longint:
160 ; CHECK-BE-NEXT: .save {r11, lr}
161 ; CHECK-BE-NEXT: push {r11, lr}
162 ; CHECK-BE-NEXT: mov r0, #0
163 ; CHECK-BE-NEXT: mov r1, #42
164 ; CHECK-BE-NEXT: bl arg_longint
165 ; CHECK-BE-NEXT: pop {r11, pc}
166 call void @arg_longint( i64 42 )
170 define void @caller_arg_double() {
171 ; CHECK-LE-LABEL: caller_arg_double:
173 ; CHECK-LE-NEXT: .save {r11, lr}
174 ; CHECK-LE-NEXT: push {r11, lr}
175 ; CHECK-LE-NEXT: vmov.f64 d16, #1.000000e+00
176 ; CHECK-LE-NEXT: vmov r0, r1, d16
177 ; CHECK-LE-NEXT: bl arg_double
178 ; CHECK-LE-NEXT: pop {r11, pc}
180 ; CHECK-BE-LABEL: caller_arg_double:
182 ; CHECK-BE-NEXT: .save {r11, lr}
183 ; CHECK-BE-NEXT: push {r11, lr}
184 ; CHECK-BE-NEXT: vmov.f64 d16, #1.000000e+00
185 ; CHECK-BE-NEXT: vmov r1, r0, d16
186 ; CHECK-BE-NEXT: bl arg_double
187 ; CHECK-BE-NEXT: pop {r11, pc}
188 call void @arg_double( double 1.0 )
192 define void @caller_return_longint() {
193 ; CHECK-LE-LABEL: caller_return_longint:
195 ; CHECK-LE-NEXT: .save {r11, lr}
196 ; CHECK-LE-NEXT: push {r11, lr}
197 ; CHECK-LE-NEXT: bl return_longint
198 ; CHECK-LE-NEXT: movw r1, :lower16:var32
199 ; CHECK-LE-NEXT: movt r1, :upper16:var32
200 ; CHECK-LE-NEXT: str r0, [r1]
201 ; CHECK-LE-NEXT: pop {r11, pc}
203 ; CHECK-BE-LABEL: caller_return_longint:
205 ; CHECK-BE-NEXT: .save {r11, lr}
206 ; CHECK-BE-NEXT: push {r11, lr}
207 ; CHECK-BE-NEXT: bl return_longint
208 ; CHECK-BE-NEXT: movw r0, :lower16:var32
209 ; CHECK-BE-NEXT: movt r0, :upper16:var32
210 ; CHECK-BE-NEXT: str r1, [r0]
211 ; CHECK-BE-NEXT: pop {r11, pc}
212 %val = call i64 @return_longint()
213 %tmp = trunc i64 %val to i32
214 store i32 %tmp, ptr @var32
218 define void @caller_return_double() {
219 ; CHECK-LE-LABEL: caller_return_double:
221 ; CHECK-LE-NEXT: .save {r11, lr}
222 ; CHECK-LE-NEXT: push {r11, lr}
223 ; CHECK-LE-NEXT: bl return_double
224 ; CHECK-LE-NEXT: vmov d17, r0, r1
225 ; CHECK-LE-NEXT: vldr d16, .LCPI11_0
226 ; CHECK-LE-NEXT: movw r0, :lower16:vardouble
227 ; CHECK-LE-NEXT: vadd.f64 d16, d17, d16
228 ; CHECK-LE-NEXT: movt r0, :upper16:vardouble
229 ; CHECK-LE-NEXT: vstr d16, [r0]
230 ; CHECK-LE-NEXT: pop {r11, pc}
231 ; CHECK-LE-NEXT: .p2align 3
232 ; CHECK-LE-NEXT: @ %bb.1:
233 ; CHECK-LE-NEXT: .LCPI11_0:
234 ; CHECK-LE-NEXT: .long 1374389535 @ double 3.1400000000000001
235 ; CHECK-LE-NEXT: .long 1074339512
237 ; CHECK-BE-LABEL: caller_return_double:
239 ; CHECK-BE-NEXT: .save {r11, lr}
240 ; CHECK-BE-NEXT: push {r11, lr}
241 ; CHECK-BE-NEXT: bl return_double
242 ; CHECK-BE-NEXT: vmov d17, r1, r0
243 ; CHECK-BE-NEXT: vldr d16, .LCPI11_0
244 ; CHECK-BE-NEXT: movw r0, :lower16:vardouble
245 ; CHECK-BE-NEXT: vadd.f64 d16, d17, d16
246 ; CHECK-BE-NEXT: movt r0, :upper16:vardouble
247 ; CHECK-BE-NEXT: vstr d16, [r0]
248 ; CHECK-BE-NEXT: pop {r11, pc}
249 ; CHECK-BE-NEXT: .p2align 3
250 ; CHECK-BE-NEXT: @ %bb.1:
251 ; CHECK-BE-NEXT: .LCPI11_0:
252 ; CHECK-BE-NEXT: .long 1074339512 @ double 3.1400000000000001
253 ; CHECK-BE-NEXT: .long 1374389535
254 %val = call double @return_double( )
255 %tmp = fadd double %val, 3.14
256 store double %tmp, ptr @vardouble
260 define void @caller_return_v2f64() {
261 ; CHECK-LABEL: caller_return_v2f64:
263 ; CHECK-NEXT: .save {r11, lr}
264 ; CHECK-NEXT: push {r11, lr}
265 ; CHECK-NEXT: bl return_v2f64
266 ; CHECK-NEXT: movw r2, :lower16:vardouble
267 ; CHECK-NEXT: movt r2, :upper16:vardouble
268 ; CHECK-NEXT: strd r0, r1, [r2]
269 ; CHECK-NEXT: pop {r11, pc}
270 %val = call <2 x double> @return_v2f64( )
271 %tmp = extractelement <2 x double> %val, i32 0
272 store double %tmp, ptr @vardouble