]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/arm_acle.c
Vendor import of clang release_38 branch r258549:
[FreeBSD/FreeBSD.git] / 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)
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 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)
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 /* 9.2 Miscellaneous data-processing intrinsics */
122 // ARM-LABEL: test_ror
123 // ARM: lshr
124 // ARM: sub
125 // ARM: shl
126 // ARM: or
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
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
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)
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)
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)
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)
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)
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)
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 {{.*}}, 16
190 // ARM: shl {{.*}}, 16
191 // ARM: or
192 uint32_t test_rev16(uint32_t t) {
193   return __rev16(t);
194 }
195
196 // ARM-LABEL: test_rev16l
197 // AArch32: llvm.bswap
198 // AArch32: lshr {{.*}}, 16
199 // AArch32: shl {{.*}}, 16
200 // AArch32: or
201 // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
202 // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32
203 // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
204 // AArch64: [[T4:%.*]] = lshr i32 [[T3]], 16
205 // AArch64: [[T5:%.*]] = shl i32 [[T3]], 16
206 // AArch64: [[T6:%.*]] = or i32 [[T5]], [[T4]]
207 // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64
208 // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32
209 // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32
210 // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
211 // AArch64: [[T11:%.*]] = lshr i32 [[T10]], 16
212 // AArch64: [[T12:%.*]] = shl i32 [[T10]], 16
213 // AArch64: [[T13:%.*]] = or i32 [[T12]], [[T11]]
214 // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64
215 // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]]
216 long test_rev16l(long t) {
217   return __rev16l(t);
218 }
219
220 // ARM-LABEL: test_rev16ll
221 // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
222 // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32
223 // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
224 // ARM: [[T4:%.*]] = lshr i32 [[T3]], 16
225 // ARM: [[T5:%.*]] = shl i32 [[T3]], 16
226 // ARM: [[T6:%.*]] = or i32 [[T5]], [[T4]]
227 // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64
228 // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32
229 // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32
230 // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
231 // ARM: [[T11:%.*]] = lshr i32 [[T10]], 16
232 // ARM: [[T12:%.*]] = shl i32 [[T10]], 16
233 // ARM: [[T13:%.*]] = or i32 [[T12]], [[T11]]
234 // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64
235 // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]]
236 uint64_t test_rev16ll(uint64_t t) {
237   return __rev16ll(t);
238 }
239
240 // ARM-LABEL: test_revsh
241 // ARM: call i16 @llvm.bswap.i16(i16 %t)
242 int16_t test_revsh(int16_t t) {
243   return __revsh(t);
244 }
245
246 // ARM-LABEL: test_rbit
247 // AArch32: call i32 @llvm.arm.rbit
248 // AArch64: call i32 @llvm.aarch64.rbit.i32
249 uint32_t test_rbit(uint32_t t) {
250   return __rbit(t);
251 }
252
253 // ARM-LABEL: test_rbitl
254 // AArch32: call i32 @llvm.arm.rbit
255 // AArch64: call i64 @llvm.aarch64.rbit.i64
256 long test_rbitl(long t) {
257   return __rbitl(t);
258 }
259
260 // ARM-LABEL: test_rbitll
261 // AArch32: call i32 @llvm.arm.rbit
262 // AArch32: call i32 @llvm.arm.rbit
263 // AArch64: call i64 @llvm.aarch64.rbit.i64
264 uint64_t test_rbitll(uint64_t t) {
265   return __rbitll(t);
266 }
267
268 /* 9.4 Saturating intrinsics */
269 #ifdef __ARM_32BIT_STATE
270
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 int32_t test_usat(int32_t t) {
281   return __usat(t, 2);
282 }
283
284 /* 9.4.2 Saturating addition and subtraction intrinsics */
285 // AArch32-LABEL: test_qadd
286 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
287 int32_t test_qadd(int32_t a, int32_t b) {
288   return __qadd(a, b);
289 }
290
291 // AArch32-LABEL: test_qsub
292 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
293 int32_t test_qsub(int32_t a, int32_t b) {
294   return __qsub(a, b);
295 }
296
297 extern int32_t f();
298 // AArch32-LABEL: test_qdbl
299 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
300 // AArch32-NOT: call {{.*}} @f
301 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
302 int32_t test_qdbl() {
303   return __qdbl(f());
304 }
305 #endif
306
307 /* 9.7 CRC32 intrinsics */
308 // ARM-LABEL: test_crc32b
309 // AArch32: call i32 @llvm.arm.crc32b
310 // AArch64: call i32 @llvm.aarch64.crc32b
311 uint32_t test_crc32b(uint32_t a, uint8_t b) {
312   return __crc32b(a, b);
313 }
314
315 // ARM-LABEL: test_crc32h
316 // AArch32: call i32 @llvm.arm.crc32h
317 // AArch64: call i32 @llvm.aarch64.crc32h
318 uint32_t test_crc32h(uint32_t a, uint16_t b) {
319   return __crc32h(a, b);
320 }
321
322 // ARM-LABEL: test_crc32w
323 // AArch32: call i32 @llvm.arm.crc32w
324 // AArch64: call i32 @llvm.aarch64.crc32w
325 uint32_t test_crc32w(uint32_t a, uint32_t b) {
326   return __crc32w(a, b);
327 }
328
329 // ARM-LABEL: test_crc32d
330 // AArch32: call i32 @llvm.arm.crc32w
331 // AArch32: call i32 @llvm.arm.crc32w
332 // AArch64: call i32 @llvm.aarch64.crc32x
333 uint32_t test_crc32d(uint32_t a, uint64_t b) {
334   return __crc32d(a, b);
335 }
336
337 // ARM-LABEL: test_crc32cb
338 // AArch32: call i32 @llvm.arm.crc32cb
339 // AArch64: call i32 @llvm.aarch64.crc32cb
340 uint32_t test_crc32cb(uint32_t a, uint8_t b) {
341   return __crc32cb(a, b);
342 }
343
344 // ARM-LABEL: test_crc32ch
345 // AArch32: call i32 @llvm.arm.crc32ch
346 // AArch64: call i32 @llvm.aarch64.crc32ch
347 uint32_t test_crc32ch(uint32_t a, uint16_t b) {
348   return __crc32ch(a, b);
349 }
350
351 // ARM-LABEL: test_crc32cw
352 // AArch32: call i32 @llvm.arm.crc32cw
353 // AArch64: call i32 @llvm.aarch64.crc32cw
354 uint32_t test_crc32cw(uint32_t a, uint32_t b) {
355   return __crc32cw(a, b);
356 }
357
358 // ARM-LABEL: test_crc32cd
359 // AArch32: call i32 @llvm.arm.crc32cw
360 // AArch32: call i32 @llvm.arm.crc32cw
361 // AArch64: call i32 @llvm.aarch64.crc32cx
362 uint32_t test_crc32cd(uint32_t a, uint64_t b) {
363   return __crc32cd(a, b);
364 }
365
366 /* 10.1 Special register intrinsics */
367 // ARM-LABEL: test_rsr
368 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
369 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]])
370 uint32_t test_rsr() {
371 #ifdef __ARM_32BIT_STATE
372   return __arm_rsr("cp1:2:c3:c4:5");
373 #else
374   return __arm_rsr("1:2:3:4:5");
375 #endif
376 }
377
378 // ARM-LABEL: test_rsr64
379 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
380 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]])
381 uint64_t test_rsr64() {
382 #ifdef __ARM_32BIT_STATE
383   return __arm_rsr64("cp1:2:c3");
384 #else
385   return __arm_rsr64("1:2:3:4:5");
386 #endif
387 }
388
389 // ARM-LABEL: test_rsrp
390 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]])
391 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]])
392 void *test_rsrp() {
393   return __arm_rsrp("sysreg");
394 }
395
396 // ARM-LABEL: test_wsr
397 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
398 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}})
399 void test_wsr(uint32_t v) {
400 #ifdef __ARM_32BIT_STATE
401   __arm_wsr("cp1:2:c3:c4:5", v);
402 #else
403   __arm_wsr("1:2:3:4:5", v);
404 #endif
405 }
406
407 // ARM-LABEL: test_wsr64
408 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
409 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}})
410 void test_wsr64(uint64_t v) {
411 #ifdef __ARM_32BIT_STATE
412   __arm_wsr64("cp1:2:c3", v);
413 #else
414   __arm_wsr64("1:2:3:4:5", v);
415 #endif
416 }
417
418 // ARM-LABEL: test_wsrp
419 // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}})
420 // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}})
421 void test_wsrp(void *v) {
422   __arm_wsrp("sysreg", v);
423 }
424
425 // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"}
426 // AArch32: ![[M3]] = !{!"cp1:2:c3"}
427 // AArch32: ![[M4]] = !{!"sysreg"}
428
429 // AArch64: ![[M0]] = !{!"1:2:3:4:5"}
430 // AArch64: ![[M1]] = !{!"sysreg"}