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)
test_dmb(void)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)
test_dsb(void)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)
test_isb(void)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)
test_yield(void)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)
test_wfe(void)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)
test_wfi(void)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)
test_sev(void)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)
test_sevl(void)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)
test_dbg(void)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
test_swp(uint32_t x,volatile void * p)79 uint32_t 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)
test_pld()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)
test_pldx()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)
test_pli()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)
test_plix()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)
test_nop(void)116 void test_nop(void) {
117 __nop();
118 }
119
120 /* 9 DATA-PROCESSING INTRINSICS */
121 /* 9.2 Miscellaneous data-processing intrinsics */
122 // ARM-LABEL: test_ror
123 // ARM: lshr
124 // ARM: sub
125 // ARM: shl
126 // ARM: or
test_ror(uint32_t x,uint32_t y)127 uint32_t test_ror(uint32_t x, uint32_t y) {
128 return __ror(x, y);
129 }
130
131 // ARM-LABEL: test_rorl
132 // ARM: lshr
133 // ARM: sub
134 // ARM: shl
135 // ARM: or
test_rorl(unsigned long x,uint32_t y)136 unsigned long test_rorl(unsigned long x, uint32_t y) {
137 return __rorl(x, y);
138 }
139
140 // ARM-LABEL: test_rorll
141 // ARM: lshr
142 // ARM: sub
143 // ARM: shl
144 // ARM: or
test_rorll(uint64_t x,uint32_t y)145 uint64_t test_rorll(uint64_t x, uint32_t y) {
146 return __rorll(x, y);
147 }
148
149 // ARM-LABEL: test_clz
150 // ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
test_clz(uint32_t t)151 uint32_t test_clz(uint32_t t) {
152 return __clz(t);
153 }
154
155 // ARM-LABEL: test_clzl
156 // AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
157 // AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
test_clzl(long t)158 long test_clzl(long t) {
159 return __clzl(t);
160 }
161
162 // ARM-LABEL: test_clzll
163 // ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
test_clzll(uint64_t t)164 uint64_t test_clzll(uint64_t t) {
165 return __clzll(t);
166 }
167
168 // ARM-LABEL: test_rev
169 // ARM: call i32 @llvm.bswap.i32(i32 %t)
test_rev(uint32_t t)170 uint32_t test_rev(uint32_t t) {
171 return __rev(t);
172 }
173
174 // ARM-LABEL: test_revl
175 // AArch32: call i32 @llvm.bswap.i32(i32 %t)
176 // AArch64: call i64 @llvm.bswap.i64(i64 %t)
test_revl(long t)177 long test_revl(long t) {
178 return __revl(t);
179 }
180
181 // ARM-LABEL: test_revll
182 // ARM: call i64 @llvm.bswap.i64(i64 %t)
test_revll(uint64_t t)183 uint64_t test_revll(uint64_t t) {
184 return __revll(t);
185 }
186
187 // ARM-LABEL: test_rev16
188 // ARM: llvm.bswap
189 // ARM: lshr
190 // ARM: shl
191 // ARM: or
test_rev16(uint32_t t)192 uint32_t test_rev16(uint32_t t) {
193 return __rev16(t);
194 }
195
196 // ARM-LABEL: test_rev16l
197 // ARM: llvm.bswap
198 // ARM: lshr
199 // ARM: shl
200 // ARM: or
test_rev16l(long t)201 long test_rev16l(long t) {
202 return __rev16l(t);
203 }
204
205 // ARM-LABEL: test_rev16ll
206 // ARM: llvm.bswap
207 // ARM: lshr
208 // ARM: shl
209 // ARM: or
test_rev16ll(uint64_t t)210 uint64_t test_rev16ll(uint64_t t) {
211 return __rev16ll(t);
212 }
213
214 // ARM-LABEL: test_revsh
215 // ARM: call i16 @llvm.bswap.i16(i16 %t)
test_revsh(int16_t t)216 int16_t test_revsh(int16_t t) {
217 return __revsh(t);
218 }
219
220 // ARM-LABEL: test_rbit
221 // AArch32: call i32 @llvm.arm.rbit
222 // AArch64: call i32 @llvm.aarch64.rbit.i32
test_rbit(uint32_t t)223 uint32_t test_rbit(uint32_t t) {
224 return __rbit(t);
225 }
226
227 // ARM-LABEL: test_rbitl
228 // AArch32: call i32 @llvm.arm.rbit
229 // AArch64: call i64 @llvm.aarch64.rbit.i64
test_rbitl(long t)230 long test_rbitl(long t) {
231 return __rbitl(t);
232 }
233
234 // ARM-LABEL: test_rbitll
235 // AArch32: call i32 @llvm.arm.rbit
236 // AArch32: call i32 @llvm.arm.rbit
237 // AArch64: call i64 @llvm.aarch64.rbit.i64
test_rbitll(uint64_t t)238 uint64_t test_rbitll(uint64_t t) {
239 return __rbitll(t);
240 }
241
242 /* 9.4 Saturating intrinsics */
243 #ifdef __ARM_32BIT_STATE
244
245 /* 9.4.1 Width-specified saturation intrinsics */
246 // AArch32-LABEL: test_ssat
247 // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
test_ssat(int32_t t)248 int32_t test_ssat(int32_t t) {
249 return __ssat(t, 1);
250 }
251
252 // AArch32-LABEL: test_usat
253 // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
test_usat(int32_t t)254 int32_t test_usat(int32_t t) {
255 return __usat(t, 2);
256 }
257
258 /* 9.4.2 Saturating addition and subtraction intrinsics */
259 // AArch32-LABEL: test_qadd
260 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
test_qadd(int32_t a,int32_t b)261 int32_t test_qadd(int32_t a, int32_t b) {
262 return __qadd(a, b);
263 }
264
265 // AArch32-LABEL: test_qsub
266 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
test_qsub(int32_t a,int32_t b)267 int32_t test_qsub(int32_t a, int32_t b) {
268 return __qsub(a, b);
269 }
270
271 extern int32_t f();
272 // AArch32-LABEL: test_qdbl
273 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
274 // AArch32-NOT: call {{.*}} @f
275 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
test_qdbl()276 int32_t test_qdbl() {
277 return __qdbl(f());
278 }
279 #endif
280
281 /* 9.7 CRC32 intrinsics */
282 // ARM-LABEL: test_crc32b
283 // AArch32: call i32 @llvm.arm.crc32b
284 // AArch64: call i32 @llvm.aarch64.crc32b
test_crc32b(uint32_t a,uint8_t b)285 uint32_t test_crc32b(uint32_t a, uint8_t b) {
286 return __crc32b(a, b);
287 }
288
289 // ARM-LABEL: test_crc32h
290 // AArch32: call i32 @llvm.arm.crc32h
291 // AArch64: call i32 @llvm.aarch64.crc32h
test_crc32h(uint32_t a,uint16_t b)292 uint32_t test_crc32h(uint32_t a, uint16_t b) {
293 return __crc32h(a, b);
294 }
295
296 // ARM-LABEL: test_crc32w
297 // AArch32: call i32 @llvm.arm.crc32w
298 // AArch64: call i32 @llvm.aarch64.crc32w
test_crc32w(uint32_t a,uint32_t b)299 uint32_t test_crc32w(uint32_t a, uint32_t b) {
300 return __crc32w(a, b);
301 }
302
303 // ARM-LABEL: test_crc32d
304 // AArch32: call i32 @llvm.arm.crc32w
305 // AArch32: call i32 @llvm.arm.crc32w
306 // AArch64: call i32 @llvm.aarch64.crc32x
test_crc32d(uint32_t a,uint64_t b)307 uint32_t test_crc32d(uint32_t a, uint64_t b) {
308 return __crc32d(a, b);
309 }
310
311 // ARM-LABEL: test_crc32cb
312 // AArch32: call i32 @llvm.arm.crc32cb
313 // AArch64: call i32 @llvm.aarch64.crc32cb
test_crc32cb(uint32_t a,uint8_t b)314 uint32_t test_crc32cb(uint32_t a, uint8_t b) {
315 return __crc32cb(a, b);
316 }
317
318 // ARM-LABEL: test_crc32ch
319 // AArch32: call i32 @llvm.arm.crc32ch
320 // AArch64: call i32 @llvm.aarch64.crc32ch
test_crc32ch(uint32_t a,uint16_t b)321 uint32_t test_crc32ch(uint32_t a, uint16_t b) {
322 return __crc32ch(a, b);
323 }
324
325 // ARM-LABEL: test_crc32cw
326 // AArch32: call i32 @llvm.arm.crc32cw
327 // AArch64: call i32 @llvm.aarch64.crc32cw
test_crc32cw(uint32_t a,uint32_t b)328 uint32_t test_crc32cw(uint32_t a, uint32_t b) {
329 return __crc32cw(a, b);
330 }
331
332 // ARM-LABEL: test_crc32cd
333 // AArch32: call i32 @llvm.arm.crc32cw
334 // AArch32: call i32 @llvm.arm.crc32cw
335 // AArch64: call i32 @llvm.aarch64.crc32cx
test_crc32cd(uint32_t a,uint64_t b)336 uint32_t test_crc32cd(uint32_t a, uint64_t b) {
337 return __crc32cd(a, b);
338 }
339