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