1 | // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 |
2 | // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 |
3 | |
4 | #include <arm_acle.h> |
5 | |
6 | /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ |
7 | /* 8.3 Memory Barriers */ |
8 | // ARM-LABEL: test_dmb |
9 | // AArch32: call void @llvm.arm.dmb(i32 1) |
10 | // AArch64: call void @llvm.aarch64.dmb(i32 1) |
11 | void test_dmb(void) { |
12 | __dmb(1); |
13 | } |
14 | |
15 | // ARM-LABEL: test_dsb |
16 | // AArch32: call void @llvm.arm.dsb(i32 2) |
17 | // AArch64: call void @llvm.aarch64.dsb(i32 2) |
18 | void test_dsb(void) { |
19 | __dsb(2); |
20 | } |
21 | |
22 | // ARM-LABEL: test_isb |
23 | // AArch32: call void @llvm.arm.isb(i32 3) |
24 | // AArch64: call void @llvm.aarch64.isb(i32 3) |
25 | void test_isb(void) { |
26 | __isb(3); |
27 | } |
28 | |
29 | /* 8.4 Hints */ |
30 | // ARM-LABEL: test_yield |
31 | // AArch32: call void @llvm.arm.hint(i32 1) |
32 | // AArch64: call void @llvm.aarch64.hint(i32 1) |
33 | void test_yield(void) { |
34 | __yield(); |
35 | } |
36 | |
37 | // ARM-LABEL: test_wfe |
38 | // AArch32: call void @llvm.arm.hint(i32 2) |
39 | // AArch64: call void @llvm.aarch64.hint(i32 2) |
40 | void test_wfe(void) { |
41 | __wfe(); |
42 | } |
43 | |
44 | // ARM-LABEL: test_wfi |
45 | // AArch32: call void @llvm.arm.hint(i32 3) |
46 | // AArch64: call void @llvm.aarch64.hint(i32 3) |
47 | void test_wfi(void) { |
48 | __wfi(); |
49 | } |
50 | |
51 | // ARM-LABEL: test_sev |
52 | // AArch32: call void @llvm.arm.hint(i32 4) |
53 | // AArch64: call void @llvm.aarch64.hint(i32 4) |
54 | void test_sev(void) { |
55 | __sev(); |
56 | } |
57 | |
58 | // ARM-LABEL: test_sevl |
59 | // AArch32: call void @llvm.arm.hint(i32 5) |
60 | // AArch64: call void @llvm.aarch64.hint(i32 5) |
61 | void test_sevl(void) { |
62 | __sevl(); |
63 | } |
64 | |
65 | #if __ARM_32BIT_STATE |
66 | // AArch32-LABEL: test_dbg |
67 | // AArch32: call void @llvm.arm.dbg(i32 0) |
68 | void test_dbg(void) { |
69 | __dbg(0); |
70 | } |
71 | #endif |
72 | |
73 | /* 8.5 Swap */ |
74 | // ARM-LABEL: test_swp |
75 | // AArch32: call i32 @llvm.arm.ldrex |
76 | // AArch32: call i32 @llvm.arm.strex |
77 | // AArch64: call i64 @llvm.aarch64.ldxr |
78 | // AArch64: call i32 @llvm.aarch64.stxr |
79 | void test_swp(uint32_t x, volatile void *p) { |
80 | __swp(x, p); |
81 | } |
82 | |
83 | /* 8.6 Memory prefetch intrinsics */ |
84 | /* 8.6.1 Data prefetch */ |
85 | // ARM-LABEL: test_pld |
86 | // ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 1) |
87 | void test_pld() { |
88 | __pld(0); |
89 | } |
90 | |
91 | // ARM-LABEL: test_pldx |
92 | // AArch32: call void @llvm.prefetch(i8* null, i32 1, i32 3, i32 1) |
93 | // AArch64: call void @llvm.prefetch(i8* null, i32 1, i32 1, i32 1) |
94 | void test_pldx() { |
95 | __pldx(1, 2, 0, 0); |
96 | } |
97 | |
98 | /* 8.6.2 Instruction prefetch */ |
99 | // ARM-LABEL: test_pli |
100 | // ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0) |
101 | void test_pli() { |
102 | __pli(0); |
103 | } |
104 | |
105 | // ARM-LABEL: test_plix |
106 | // AArch32: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0) |
107 | // AArch64: call void @llvm.prefetch(i8* null, i32 0, i32 1, i32 0) |
108 | void test_plix() { |
109 | __plix(2, 0, 0); |
110 | } |
111 | |
112 | /* 8.7 NOP */ |
113 | // ARM-LABEL: test_nop |
114 | // AArch32: call void @llvm.arm.hint(i32 0) |
115 | // AArch64: call void @llvm.aarch64.hint(i32 0) |
116 | void test_nop(void) { |
117 | __nop(); |
118 | } |
119 | |
120 | /* 9 DATA-PROCESSING INTRINSICS */ |
121 | |
122 | /* 9.2 Miscellaneous data-processing intrinsics */ |
123 | // ARM-LABEL: test_ror |
124 | // ARM: lshr |
125 | // ARM: sub |
126 | // ARM: shl |
127 | // ARM: or |
128 | uint32_t test_ror(uint32_t x, uint32_t y) { |
129 | return __ror(x, y); |
130 | } |
131 | |
132 | // ARM-LABEL: test_rorl |
133 | // ARM: lshr |
134 | // ARM: sub |
135 | // ARM: shl |
136 | // ARM: or |
137 | unsigned long test_rorl(unsigned long x, uint32_t y) { |
138 | return __rorl(x, y); |
139 | } |
140 | |
141 | // ARM-LABEL: test_rorll |
142 | // ARM: lshr |
143 | // ARM: sub |
144 | // ARM: shl |
145 | // ARM: or |
146 | uint64_t test_rorll(uint64_t x, uint32_t y) { |
147 | return __rorll(x, y); |
148 | } |
149 | |
150 | // ARM-LABEL: test_clz |
151 | // ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false) |
152 | uint32_t test_clz(uint32_t t) { |
153 | return __clz(t); |
154 | } |
155 | |
156 | // ARM-LABEL: test_clzl |
157 | // AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false) |
158 | // AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false) |
159 | long test_clzl(long t) { |
160 | return __clzl(t); |
161 | } |
162 | |
163 | // ARM-LABEL: test_clzll |
164 | // ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false) |
165 | uint64_t test_clzll(uint64_t t) { |
166 | return __clzll(t); |
167 | } |
168 | |
169 | // ARM-LABEL: test_rev |
170 | // ARM: call i32 @llvm.bswap.i32(i32 %t) |
171 | uint32_t test_rev(uint32_t t) { |
172 | return __rev(t); |
173 | } |
174 | |
175 | // ARM-LABEL: test_revl |
176 | // AArch32: call i32 @llvm.bswap.i32(i32 %t) |
177 | // AArch64: call i64 @llvm.bswap.i64(i64 %t) |
178 | long test_revl(long t) { |
179 | return __revl(t); |
180 | } |
181 | |
182 | // ARM-LABEL: test_revll |
183 | // ARM: call i64 @llvm.bswap.i64(i64 %t) |
184 | uint64_t test_revll(uint64_t t) { |
185 | return __revll(t); |
186 | } |
187 | |
188 | // ARM-LABEL: test_rev16 |
189 | // ARM: llvm.bswap |
190 | // ARM: lshr {{.*}}, 16 |
191 | // ARM: shl {{.*}}, 16 |
192 | // ARM: or |
193 | uint32_t test_rev16(uint32_t t) { |
194 | return __rev16(t); |
195 | } |
196 | |
197 | // ARM-LABEL: test_rev16l |
198 | // AArch32: llvm.bswap |
199 | // AArch32: lshr {{.*}}, 16 |
200 | // AArch32: shl {{.*}}, 16 |
201 | // AArch32: or |
202 | // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 |
203 | // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32 |
204 | // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) |
205 | // AArch64: [[T4:%.*]] = lshr i32 [[T3]], 16 |
206 | // AArch64: [[T5:%.*]] = shl i32 [[T3]], 16 |
207 | // AArch64: [[T6:%.*]] = or i32 [[T5]], [[T4]] |
208 | // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64 |
209 | // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32 |
210 | // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32 |
211 | // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) |
212 | // AArch64: [[T11:%.*]] = lshr i32 [[T10]], 16 |
213 | // AArch64: [[T12:%.*]] = shl i32 [[T10]], 16 |
214 | // AArch64: [[T13:%.*]] = or i32 [[T12]], [[T11]] |
215 | // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64 |
216 | // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]] |
217 | long test_rev16l(long t) { |
218 | return __rev16l(t); |
219 | } |
220 | |
221 | // ARM-LABEL: test_rev16ll |
222 | // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 |
223 | // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32 |
224 | // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) |
225 | // ARM: [[T4:%.*]] = lshr i32 [[T3]], 16 |
226 | // ARM: [[T5:%.*]] = shl i32 [[T3]], 16 |
227 | // ARM: [[T6:%.*]] = or i32 [[T5]], [[T4]] |
228 | // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64 |
229 | // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32 |
230 | // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32 |
231 | // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) |
232 | // ARM: [[T11:%.*]] = lshr i32 [[T10]], 16 |
233 | // ARM: [[T12:%.*]] = shl i32 [[T10]], 16 |
234 | // ARM: [[T13:%.*]] = or i32 [[T12]], [[T11]] |
235 | // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64 |
236 | // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]] |
237 | uint64_t test_rev16ll(uint64_t t) { |
238 | return __rev16ll(t); |
239 | } |
240 | |
241 | // ARM-LABEL: test_revsh |
242 | // ARM: call i16 @llvm.bswap.i16(i16 %t) |
243 | int16_t test_revsh(int16_t t) { |
244 | return __revsh(t); |
245 | } |
246 | |
247 | // ARM-LABEL: test_rbit |
248 | // AArch32: call i32 @llvm.bitreverse.i32 |
249 | // AArch64: call i32 @llvm.bitreverse.i32 |
250 | uint32_t test_rbit(uint32_t t) { |
251 | return __rbit(t); |
252 | } |
253 | |
254 | // ARM-LABEL: test_rbitl |
255 | // AArch32: call i32 @llvm.bitreverse.i32 |
256 | // AArch64: call i64 @llvm.bitreverse.i64 |
257 | long test_rbitl(long t) { |
258 | return __rbitl(t); |
259 | } |
260 | |
261 | // ARM-LABEL: test_rbitll |
262 | // AArch32: call i32 @llvm.bitreverse.i32 |
263 | // AArch32: call i32 @llvm.bitreverse.i32 |
264 | // AArch64: call i64 @llvm.bitreverse.i64 |
265 | uint64_t test_rbitll(uint64_t t) { |
266 | return __rbitll(t); |
267 | } |
268 | |
269 | /* 9.4 Saturating intrinsics */ |
270 | #ifdef __ARM_FEATURE_SAT |
271 | /* 9.4.1 Width-specified saturation intrinsics */ |
272 | // AArch32-LABEL: test_ssat |
273 | // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1) |
274 | int32_t test_ssat(int32_t t) { |
275 | return __ssat(t, 1); |
276 | } |
277 | |
278 | // AArch32-LABEL: test_usat |
279 | // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2) |
280 | uint32_t test_usat(int32_t t) { |
281 | return __usat(t, 2); |
282 | } |
283 | #endif |
284 | |
285 | /* 9.4.2 Saturating addition and subtraction intrinsics */ |
286 | #ifdef __ARM_FEATURE_DSP |
287 | // AArch32-LABEL: test_qadd |
288 | // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b) |
289 | int32_t test_qadd(int32_t a, int32_t b) { |
290 | return __qadd(a, b); |
291 | } |
292 | |
293 | // AArch32-LABEL: test_qsub |
294 | // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b) |
295 | int32_t test_qsub(int32_t a, int32_t b) { |
296 | return __qsub(a, b); |
297 | } |
298 | |
299 | extern int32_t f(); |
300 | // AArch32-LABEL: test_qdbl |
301 | // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f |
302 | // AArch32-NOT: call {{.*}} @f |
303 | // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]]) |
304 | int32_t test_qdbl() { |
305 | return __qdbl(f()); |
306 | } |
307 | #endif |
308 | |
309 | /* |
310 | * 9.3 16-bit multiplications |
311 | */ |
312 | #if __ARM_FEATURE_DSP |
313 | // AArch32-LABEL: test_smulbb |
314 | // AArch32: call i32 @llvm.arm.smulbb |
315 | int32_t test_smulbb(int32_t a, int32_t b) { |
316 | return __smulbb(a, b); |
317 | } |
318 | // AArch32-LABEL: test_smulbt |
319 | // AArch32: call i32 @llvm.arm.smulbt |
320 | int32_t test_smulbt(int32_t a, int32_t b) { |
321 | return __smulbt(a, b); |
322 | } |
323 | // AArch32-LABEL: test_smultb |
324 | // AArch32: call i32 @llvm.arm.smultb |
325 | int32_t test_smultb(int32_t a, int32_t b) { |
326 | return __smultb(a, b); |
327 | } |
328 | // AArch32-LABEL: test_smultt |
329 | // AArch32: call i32 @llvm.arm.smultt |
330 | int32_t test_smultt(int32_t a, int32_t b) { |
331 | return __smultt(a, b); |
332 | } |
333 | // AArch32-LABEL: test_smulwb |
334 | // AArch32: call i32 @llvm.arm.smulwb |
335 | int32_t test_smulwb(int32_t a, int32_t b) { |
336 | return __smulwb(a, b); |
337 | } |
338 | // AArch32-LABEL: test_smulwt |
339 | // AArch32: call i32 @llvm.arm.smulwt |
340 | int32_t test_smulwt(int32_t a, int32_t b) { |
341 | return __smulwt(a, b); |
342 | } |
343 | #endif |
344 | |
345 | /* 9.4.3 Accumultating multiplications */ |
346 | #if __ARM_FEATURE_DSP |
347 | // AArch32-LABEL: test_smlabb |
348 | // AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c) |
349 | int32_t test_smlabb(int32_t a, int32_t b, int32_t c) { |
350 | return __smlabb(a, b, c); |
351 | } |
352 | // AArch32-LABEL: test_smlabt |
353 | // AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c) |
354 | int32_t test_smlabt(int32_t a, int32_t b, int32_t c) { |
355 | return __smlabt(a, b, c); |
356 | } |
357 | // AArch32-LABEL: test_smlatb |
358 | // AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c) |
359 | int32_t test_smlatb(int32_t a, int32_t b, int32_t c) { |
360 | return __smlatb(a, b, c); |
361 | } |
362 | // AArch32-LABEL: test_smlatt |
363 | // AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c) |
364 | int32_t test_smlatt(int32_t a, int32_t b, int32_t c) { |
365 | return __smlatt(a, b, c); |
366 | } |
367 | // AArch32-LABEL: test_smlawb |
368 | // AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c) |
369 | int32_t test_smlawb(int32_t a, int32_t b, int32_t c) { |
370 | return __smlawb(a, b, c); |
371 | } |
372 | // AArch32-LABEL: test_smlawt |
373 | // AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c) |
374 | int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { |
375 | return __smlawt(a, b, c); |
376 | } |
377 | #endif |
378 | |
379 | /* 9.5.4 Parallel 16-bit saturation */ |
380 | #if __ARM_FEATURE_SIMD32 |
381 | // AArch32-LABEL: test_ssat16 |
382 | // AArch32: call i32 @llvm.arm.ssat16 |
383 | int16x2_t test_ssat16(int16x2_t a) { |
384 | return __ssat16(a, 15); |
385 | } |
386 | // AArch32-LABEL: test_usat16 |
387 | // AArch32: call i32 @llvm.arm.usat16 |
388 | uint16x2_t test_usat16(int16x2_t a) { |
389 | return __usat16(a, 15); |
390 | } |
391 | #endif |
392 | |
393 | /* 9.5.5 Packing and unpacking */ |
394 | #if __ARM_FEATURE_SIMD32 |
395 | // AArch32-LABEL: test_sxtab16 |
396 | // AArch32: call i32 @llvm.arm.sxtab16 |
397 | int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) { |
398 | return __sxtab16(a, b); |
399 | } |
400 | // AArch32-LABEL: test_sxtb16 |
401 | // AArch32: call i32 @llvm.arm.sxtb16 |
402 | int16x2_t test_sxtb16(int8x4_t a) { |
403 | return __sxtb16(a); |
404 | } |
405 | // AArch32-LABEL: test_uxtab16 |
406 | // AArch32: call i32 @llvm.arm.uxtab16 |
407 | int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) { |
408 | return __uxtab16(a, b); |
409 | } |
410 | // AArch32-LABEL: test_uxtb16 |
411 | // AArch32: call i32 @llvm.arm.uxtb16 |
412 | int16x2_t test_uxtb16(int8x4_t a) { |
413 | return __uxtb16(a); |
414 | } |
415 | #endif |
416 | |
417 | /* 9.5.6 Parallel selection */ |
418 | #if __ARM_FEATURE_SIMD32 |
419 | // AArch32-LABEL: test_sel |
420 | // AArch32: call i32 @llvm.arm.sel |
421 | uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { |
422 | return __sel(a, b); |
423 | } |
424 | #endif |
425 | |
426 | /* 9.5.7 Parallel 8-bit addition and subtraction */ |
427 | #if __ARM_FEATURE_SIMD32 |
428 | // AArch32-LABEL: test_qadd8 |
429 | // AArch32: call i32 @llvm.arm.qadd8 |
430 | int16x2_t test_qadd8(int8x4_t a, int8x4_t b) { |
431 | return __qadd8(a, b); |
432 | } |
433 | // AArch32-LABEL: test_qsub8 |
434 | // AArch32: call i32 @llvm.arm.qsub8 |
435 | int8x4_t test_qsub8(int8x4_t a, int8x4_t b) { |
436 | return __qsub8(a, b); |
437 | } |
438 | // AArch32-LABEL: test_sadd8 |
439 | // AArch32: call i32 @llvm.arm.sadd8 |
440 | int8x4_t test_sadd8(int8x4_t a, int8x4_t b) { |
441 | return __sadd8(a, b); |
442 | } |
443 | // AArch32-LABEL: test_shadd8 |
444 | // AArch32: call i32 @llvm.arm.shadd8 |
445 | int8x4_t test_shadd8(int8x4_t a, int8x4_t b) { |
446 | return __shadd8(a, b); |
447 | } |
448 | // AArch32-LABEL: test_shsub8 |
449 | // AArch32: call i32 @llvm.arm.shsub8 |
450 | int8x4_t test_shsub8(int8x4_t a, int8x4_t b) { |
451 | return __shsub8(a, b); |
452 | } |
453 | // AArch32-LABEL: test_ssub8 |
454 | // AArch32: call i32 @llvm.arm.ssub8 |
455 | int8x4_t test_ssub8(int8x4_t a, int8x4_t b) { |
456 | return __ssub8(a, b); |
457 | } |
458 | // AArch32-LABEL: test_uadd8 |
459 | // AArch32: call i32 @llvm.arm.uadd8 |
460 | uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) { |
461 | return __uadd8(a, b); |
462 | } |
463 | // AArch32-LABEL: test_uhadd8 |
464 | // AArch32: call i32 @llvm.arm.uhadd8 |
465 | uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) { |
466 | return __uhadd8(a, b); |
467 | } |
468 | // AArch32-LABEL: test_uhsub8 |
469 | // AArch32: call i32 @llvm.arm.uhsub8 |
470 | uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) { |
471 | return __uhsub8(a, b); |
472 | } |
473 | // AArch32-LABEL: test_uqadd8 |
474 | // AArch32: call i32 @llvm.arm.uqadd8 |
475 | uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) { |
476 | return __uqadd8(a, b); |
477 | } |
478 | // AArch32-LABEL: test_uqsub8 |
479 | // AArch32: call i32 @llvm.arm.uqsub8 |
480 | uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) { |
481 | return __uqsub8(a, b); |
482 | } |
483 | // AArch32-LABEL: test_usub8 |
484 | // AArch32: call i32 @llvm.arm.usub8 |
485 | uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { |
486 | return __usub8(a, b); |
487 | } |
488 | #endif |
489 | |
490 | /* 9.5.8 Sum of 8-bit absolute differences */ |
491 | #if __ARM_FEATURE_SIMD32 |
492 | // AArch32-LABEL: test_usad8 |
493 | // AArch32: call i32 @llvm.arm.usad8 |
494 | uint32_t test_usad8(uint8x4_t a, uint8x4_t b) { |
495 | return __usad8(a, b); |
496 | } |
497 | // AArch32-LABEL: test_usada8 |
498 | // AArch32: call i32 @llvm.arm.usada8 |
499 | uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { |
500 | return __usada8(a, b, c); |
501 | } |
502 | #endif |
503 | |
504 | /* 9.5.9 Parallel 16-bit addition and subtraction */ |
505 | #if __ARM_FEATURE_SIMD32 |
506 | // AArch32-LABEL: test_qadd16 |
507 | // AArch32: call i32 @llvm.arm.qadd16 |
508 | int16x2_t test_qadd16(int16x2_t a, int16x2_t b) { |
509 | return __qadd16(a, b); |
510 | } |
511 | // AArch32-LABEL: test_qasx |
512 | // AArch32: call i32 @llvm.arm.qasx |
513 | int16x2_t test_qasx(int16x2_t a, int16x2_t b) { |
514 | return __qasx(a, b); |
515 | } |
516 | // AArch32-LABEL: test_qsax |
517 | // AArch32: call i32 @llvm.arm.qsax |
518 | int16x2_t test_qsax(int16x2_t a, int16x2_t b) { |
519 | return __qsax(a, b); |
520 | } |
521 | // AArch32-LABEL: test_qsub16 |
522 | // AArch32: call i32 @llvm.arm.qsub16 |
523 | int16x2_t test_qsub16(int16x2_t a, int16x2_t b) { |
524 | return __qsub16(a, b); |
525 | } |
526 | // AArch32-LABEL: test_sadd16 |
527 | // AArch32: call i32 @llvm.arm.sadd16 |
528 | int16x2_t test_sadd16(int16x2_t a, int16x2_t b) { |
529 | return __sadd16(a, b); |
530 | } |
531 | // AArch32-LABEL: test_sasx |
532 | // AArch32: call i32 @llvm.arm.sasx |
533 | int16x2_t test_sasx(int16x2_t a, int16x2_t b) { |
534 | return __sasx(a, b); |
535 | } |
536 | // AArch32-LABEL: test_shadd16 |
537 | // AArch32: call i32 @llvm.arm.shadd16 |
538 | int16x2_t test_shadd16(int16x2_t a, int16x2_t b) { |
539 | return __shadd16(a, b); |
540 | } |
541 | // AArch32-LABEL: test_shasx |
542 | // AArch32: call i32 @llvm.arm.shasx |
543 | int16x2_t test_shasx(int16x2_t a, int16x2_t b) { |
544 | return __shasx(a, b); |
545 | } |
546 | // AArch32-LABEL: test_shsax |
547 | // AArch32: call i32 @llvm.arm.shsax |
548 | int16x2_t test_shsax(int16x2_t a, int16x2_t b) { |
549 | return __shsax(a, b); |
550 | } |
551 | // AArch32-LABEL: test_shsub16 |
552 | // AArch32: call i32 @llvm.arm.shsub16 |
553 | int16x2_t test_shsub16(int16x2_t a, int16x2_t b) { |
554 | return __shsub16(a, b); |
555 | } |
556 | // AArch32-LABEL: test_ssax |
557 | // AArch32: call i32 @llvm.arm.ssax |
558 | int16x2_t test_ssax(int16x2_t a, int16x2_t b) { |
559 | return __ssax(a, b); |
560 | } |
561 | // AArch32-LABEL: test_ssub16 |
562 | // AArch32: call i32 @llvm.arm.ssub16 |
563 | int16x2_t test_ssub16(int16x2_t a, int16x2_t b) { |
564 | return __ssub16(a, b); |
565 | } |
566 | // AArch32-LABEL: test_uadd16 |
567 | // AArch32: call i32 @llvm.arm.uadd16 |
568 | uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) { |
569 | return __uadd16(a, b); |
570 | } |
571 | // AArch32-LABEL: test_uasx |
572 | // AArch32: call i32 @llvm.arm.uasx |
573 | uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) { |
574 | return __uasx(a, b); |
575 | } |
576 | // AArch32-LABEL: test_uhadd16 |
577 | // AArch32: call i32 @llvm.arm.uhadd16 |
578 | uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) { |
579 | return __uhadd16(a, b); |
580 | } |
581 | // AArch32-LABEL: test_uhasx |
582 | // AArch32: call i32 @llvm.arm.uhasx |
583 | uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) { |
584 | return __uhasx(a, b); |
585 | } |
586 | // AArch32-LABEL: test_uhsax |
587 | // AArch32: call i32 @llvm.arm.uhsax |
588 | uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) { |
589 | return __uhsax(a, b); |
590 | } |
591 | // AArch32-LABEL: test_uhsub16 |
592 | // AArch32: call i32 @llvm.arm.uhsub16 |
593 | uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) { |
594 | return __uhsub16(a, b); |
595 | } |
596 | // AArch32-LABEL: test_uqadd16 |
597 | // AArch32: call i32 @llvm.arm.uqadd16 |
598 | uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) { |
599 | return __uqadd16(a, b); |
600 | } |
601 | // AArch32-LABEL: test_uqasx |
602 | // AArch32: call i32 @llvm.arm.uqasx |
603 | uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) { |
604 | return __uqasx(a, b); |
605 | } |
606 | // AArch32-LABEL: test_uqsax |
607 | // AArch32: call i32 @llvm.arm.uqsax |
608 | uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) { |
609 | return __uqsax(a, b); |
610 | } |
611 | // AArch32-LABEL: test_uqsub16 |
612 | // AArch32: call i32 @llvm.arm.uqsub16 |
613 | uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) { |
614 | return __uqsub16(a, b); |
615 | } |
616 | // AArch32-LABEL: test_usax |
617 | // AArch32: call i32 @llvm.arm.usax |
618 | uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) { |
619 | return __usax(a, b); |
620 | } |
621 | // AArch32-LABEL: test_usub16 |
622 | // AArch32: call i32 @llvm.arm.usub16 |
623 | uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { |
624 | return __usub16(a, b); |
625 | } |
626 | #endif |
627 | |
628 | /* 9.5.10 Parallel 16-bit multiplications */ |
629 | #if __ARM_FEATURE_SIMD32 |
630 | // AArch32-LABEL: test_smlad |
631 | // AArch32: call i32 @llvm.arm.smlad |
632 | int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) { |
633 | return __smlad(a, b, c); |
634 | } |
635 | // AArch32-LABEL: test_smladx |
636 | // AArch32: call i32 @llvm.arm.smladx |
637 | int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) { |
638 | return __smladx(a, b, c); |
639 | } |
640 | // AArch32-LABEL: test_smlald |
641 | // AArch32: call i64 @llvm.arm.smlald |
642 | int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) { |
643 | return __smlald(a, b, c); |
644 | } |
645 | // AArch32-LABEL: test_smlaldx |
646 | // AArch32: call i64 @llvm.arm.smlaldx |
647 | int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) { |
648 | return __smlaldx(a, b, c); |
649 | } |
650 | // AArch32-LABEL: test_smlsd |
651 | // AArch32: call i32 @llvm.arm.smlsd |
652 | int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) { |
653 | return __smlsd(a, b, c); |
654 | } |
655 | // AArch32-LABEL: test_smlsdx |
656 | // AArch32: call i32 @llvm.arm.smlsdx |
657 | int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) { |
658 | return __smlsdx(a, b, c); |
659 | } |
660 | // AArch32-LABEL: test_smlsld |
661 | // AArch32: call i64 @llvm.arm.smlsld |
662 | int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) { |
663 | return __smlsld(a, b, c); |
664 | } |
665 | // AArch32-LABEL: test_smlsldx |
666 | // AArch32: call i64 @llvm.arm.smlsldx |
667 | int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) { |
668 | return __smlsldx(a, b, c); |
669 | } |
670 | // AArch32-LABEL: test_smuad |
671 | // AArch32: call i32 @llvm.arm.smuad |
672 | int32_t test_smuad(int16x2_t a, int16x2_t b) { |
673 | return __smuad(a, b); |
674 | } |
675 | // AArch32-LABEL: test_smuadx |
676 | // AArch32: call i32 @llvm.arm.smuadx |
677 | int32_t test_smuadx(int16x2_t a, int16x2_t b) { |
678 | return __smuadx(a, b); |
679 | } |
680 | // AArch32-LABEL: test_smusd |
681 | // AArch32: call i32 @llvm.arm.smusd |
682 | int32_t test_smusd(int16x2_t a, int16x2_t b) { |
683 | return __smusd(a, b); |
684 | } |
685 | // AArch32-LABEL: test_smusdx |
686 | // AArch32: call i32 @llvm.arm.smusdx |
687 | int32_t test_smusdx(int16x2_t a, int16x2_t b) { |
688 | return __smusdx(a, b); |
689 | } |
690 | #endif |
691 | |
692 | /* 9.7 CRC32 intrinsics */ |
693 | // ARM-LABEL: test_crc32b |
694 | // AArch32: call i32 @llvm.arm.crc32b |
695 | // AArch64: call i32 @llvm.aarch64.crc32b |
696 | uint32_t test_crc32b(uint32_t a, uint8_t b) { |
697 | return __crc32b(a, b); |
698 | } |
699 | |
700 | // ARM-LABEL: test_crc32h |
701 | // AArch32: call i32 @llvm.arm.crc32h |
702 | // AArch64: call i32 @llvm.aarch64.crc32h |
703 | uint32_t test_crc32h(uint32_t a, uint16_t b) { |
704 | return __crc32h(a, b); |
705 | } |
706 | |
707 | // ARM-LABEL: test_crc32w |
708 | // AArch32: call i32 @llvm.arm.crc32w |
709 | // AArch64: call i32 @llvm.aarch64.crc32w |
710 | uint32_t test_crc32w(uint32_t a, uint32_t b) { |
711 | return __crc32w(a, b); |
712 | } |
713 | |
714 | // ARM-LABEL: test_crc32d |
715 | // AArch32: call i32 @llvm.arm.crc32w |
716 | // AArch32: call i32 @llvm.arm.crc32w |
717 | // AArch64: call i32 @llvm.aarch64.crc32x |
718 | uint32_t test_crc32d(uint32_t a, uint64_t b) { |
719 | return __crc32d(a, b); |
720 | } |
721 | |
722 | // ARM-LABEL: test_crc32cb |
723 | // AArch32: call i32 @llvm.arm.crc32cb |
724 | // AArch64: call i32 @llvm.aarch64.crc32cb |
725 | uint32_t test_crc32cb(uint32_t a, uint8_t b) { |
726 | return __crc32cb(a, b); |
727 | } |
728 | |
729 | // ARM-LABEL: test_crc32ch |
730 | // AArch32: call i32 @llvm.arm.crc32ch |
731 | // AArch64: call i32 @llvm.aarch64.crc32ch |
732 | uint32_t test_crc32ch(uint32_t a, uint16_t b) { |
733 | return __crc32ch(a, b); |
734 | } |
735 | |
736 | // ARM-LABEL: test_crc32cw |
737 | // AArch32: call i32 @llvm.arm.crc32cw |
738 | // AArch64: call i32 @llvm.aarch64.crc32cw |
739 | uint32_t test_crc32cw(uint32_t a, uint32_t b) { |
740 | return __crc32cw(a, b); |
741 | } |
742 | |
743 | // ARM-LABEL: test_crc32cd |
744 | // AArch32: call i32 @llvm.arm.crc32cw |
745 | // AArch32: call i32 @llvm.arm.crc32cw |
746 | // AArch64: call i32 @llvm.aarch64.crc32cx |
747 | uint32_t test_crc32cd(uint32_t a, uint64_t b) { |
748 | return __crc32cd(a, b); |
749 | } |
750 | |
751 | /* 10.1 Special register intrinsics */ |
752 | // ARM-LABEL: test_rsr |
753 | // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) |
754 | // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]]) |
755 | uint32_t test_rsr() { |
756 | #ifdef __ARM_32BIT_STATE |
757 | return __arm_rsr("cp1:2:c3:c4:5"); |
758 | #else |
759 | return __arm_rsr("1:2:3:4:5"); |
760 | #endif |
761 | } |
762 | |
763 | // ARM-LABEL: test_rsr64 |
764 | // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) |
765 | // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]]) |
766 | uint64_t test_rsr64() { |
767 | #ifdef __ARM_32BIT_STATE |
768 | return __arm_rsr64("cp1:2:c3"); |
769 | #else |
770 | return __arm_rsr64("1:2:3:4:5"); |
771 | #endif |
772 | } |
773 | |
774 | // ARM-LABEL: test_rsrp |
775 | // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]]) |
776 | // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]]) |
777 | void *test_rsrp() { |
778 | return __arm_rsrp("sysreg"); |
779 | } |
780 | |
781 | // ARM-LABEL: test_wsr |
782 | // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) |
783 | // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}}) |
784 | void test_wsr(uint32_t v) { |
785 | #ifdef __ARM_32BIT_STATE |
786 | __arm_wsr("cp1:2:c3:c4:5", v); |
787 | #else |
788 | __arm_wsr("1:2:3:4:5", v); |
789 | #endif |
790 | } |
791 | |
792 | // ARM-LABEL: test_wsr64 |
793 | // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) |
794 | // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}}) |
795 | void test_wsr64(uint64_t v) { |
796 | #ifdef __ARM_32BIT_STATE |
797 | __arm_wsr64("cp1:2:c3", v); |
798 | #else |
799 | __arm_wsr64("1:2:3:4:5", v); |
800 | #endif |
801 | } |
802 | |
803 | // ARM-LABEL: test_wsrp |
804 | // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}}) |
805 | // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}}) |
806 | void test_wsrp(void *v) { |
807 | __arm_wsrp("sysreg", v); |
808 | } |
809 | |
810 | // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"} |
811 | // AArch32: ![[M3]] = !{!"cp1:2:c3"} |
812 | // AArch32: ![[M4]] = !{!"sysreg"} |
813 | |
814 | // AArch64: ![[M0]] = !{!"1:2:3:4:5"} |
815 | // AArch64: ![[M1]] = !{!"sysreg"} |
816 | |