Clang Project

clang_source_code/test/CodeGen/arm_acle.c
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)
11void 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)
18void 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)
25void 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)
33void 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)
40void 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)
47void 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)
54void 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)
61void 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)
68void 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
79void 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)
87void 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)
94void 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)
101void 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)
108void 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)
116void 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
128uint32_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
137unsigned 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
146uint64_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)
152uint32_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)
159long 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)
165uint64_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)
171uint32_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)
178long test_revl(long t) {
179  return __revl(t);
180}
181
182// ARM-LABEL: test_revll
183// ARM: call i64 @llvm.bswap.i64(i64 %t)
184uint64_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
193uint32_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]]
217long 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]]
237uint64_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)
243int16_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
250uint32_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
257long 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
265uint64_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)
274int32_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)
280uint32_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)
289int32_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)
295int32_t test_qsub(int32_t a, int32_t b) {
296  return __qsub(a, b);
297}
298
299extern 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]])
304int32_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
315int32_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
320int32_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
325int32_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
330int32_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
335int32_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
340int32_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)
349int32_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)
354int32_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)
359int32_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)
364int32_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)
369int32_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)
374int32_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
383int16x2_t test_ssat16(int16x2_t a) {
384  return __ssat16(a, 15);
385}
386// AArch32-LABEL: test_usat16
387// AArch32: call i32 @llvm.arm.usat16
388uint16x2_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
397int16x2_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
402int16x2_t test_sxtb16(int8x4_t a) {
403  return __sxtb16(a);
404}
405// AArch32-LABEL: test_uxtab16
406// AArch32: call i32 @llvm.arm.uxtab16
407int16x2_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
412int16x2_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
421uint8x4_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
430int16x2_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
435int8x4_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
440int8x4_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
445int8x4_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
450int8x4_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
455int8x4_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
460uint8x4_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
465uint8x4_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
470uint8x4_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
475uint8x4_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
480uint8x4_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
485uint8x4_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
494uint32_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
499uint32_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
508int16x2_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
513int16x2_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
518int16x2_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
523int16x2_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
528int16x2_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
533int16x2_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
538int16x2_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
543int16x2_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
548int16x2_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
553int16x2_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
558int16x2_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
563int16x2_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
568uint16x2_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
573uint16x2_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
578uint16x2_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
583uint16x2_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
588uint16x2_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
593uint16x2_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
598uint16x2_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
603uint16x2_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
608uint16x2_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
613uint16x2_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
618uint16x2_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
623uint16x2_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
632int32_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
637int32_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
642int64_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
647int64_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
652int32_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
657int32_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
662int64_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
667int64_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
672int32_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
677int32_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
682int32_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
687int32_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
696uint32_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
703uint32_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
710uint32_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
718uint32_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
725uint32_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
732uint32_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
739uint32_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
747uint32_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]]])
755uint32_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]]])
766uint64_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]]])
777void *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 %{{.*}})
784void 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 %{{.*}})
795void 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 %{{.*}})
806void 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