clang 24.0.0git
arm_acle.h
Go to the documentation of this file.
1/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 * The Arm C Language Extensions specifications can be found in the following
8 * link: https://github.com/ARM-software/acle/releases
9 *
10 * The ACLE section numbers are subject to change. When consulting the
11 * specifications, it is recommended to search using section titles if
12 * the section numbers look outdated.
13 *
14 *===-----------------------------------------------------------------------===
15 */
16
17#ifndef __ARM_ACLE_H
18#define __ARM_ACLE_H
19
20#ifndef __ARM_ACLE
21#error "ACLE intrinsics support not enabled."
22#endif
23
24#include <stdint.h>
25
26#if defined(__cplusplus)
27extern "C" {
28#endif
29
30/* 7 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
31/* 7.3 Memory barriers */
32void __dmb(unsigned int);
33void __dsb(unsigned int);
34void __isb(unsigned int);
35
36/* 7.4 Hints */
37void __wfi(void);
38void __wfe(void);
39void __sev(void);
40void __sevl(void);
41void __yield(void);
42
43#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
44#define __dbg(t) __builtin_arm_dbg(t)
45#endif
46
47#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
48#define _CHKFEAT_GCS 1
49static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
50__chkfeat(uint64_t __features) {
51 return __builtin_arm_chkfeat(__features) ^ __features;
52}
53#endif
54
55/* 7.5 Swap */
56static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
57__swp(uint32_t __x, volatile uint32_t *__p) {
59#if (__ARM_FEATURE_LDREX & 4) || __ARM_ARCH_6M__ || __linux__
60 /*
61 * Using this clang builtin is sensible in most situations. Where
62 * LDREX and STREX are available, it will compile to a loop using
63 * them. Otherwise it will compile to a libcall, requiring the
64 * runtime to provide that library function.
65 *
66 * That's unavoidable on Armv6-M, which has no atomic instructions
67 * at all (not even SWP), so in that situation the user will just
68 * have to provide an implementation of __atomic_exchange_4 (perhaps
69 * it would temporarily disable interrupts, and then do a separate
70 * load and store).
71 *
72 * We also use the libcall strategy on pre-Armv7 Linux targets, on
73 * the theory that Linux's runtime support library _will_ provide a
74 * suitable libcall, and it's better to use that than the SWP
75 * instruction because then when the same binary is run on a later
76 * Linux system the libcall implementation will use LDREX instead.
77 */
78 __v = __atomic_exchange_n(__p, __x, __ATOMIC_RELAXED);
79#else
80 /*
81 * But for older Arm architectures when the target is not Linux, we
82 * fall back to using the SWP instruction via inline assembler. ACLE
83 * is clear that we're allowed to do this, but shouldn't do it if we
84 * have a better alternative.
85 */
86 __asm__("swp %0, %1, [%2]" : "=r"(__v) : "r"(__x), "r"(__p) : "memory");
87#endif
88 return __v;
89}
90
91/* 7.6 Memory prefetch intrinsics */
92/* 7.6.1 Data prefetch */
93#define __pld(addr) __pldx(0, 0, 0, addr)
94
95#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
96#define __pldx(access_kind, cache_level, retention_policy, addr) \
97 __builtin_arm_prefetch(addr, access_kind, 1)
98#else
99#define __pldx(access_kind, cache_level, retention_policy, addr) \
100 __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1)
101#define __pldx_range(access_kind, retention_policy, length, count, stride, \
102 reuse_distance, addr) \
103 __builtin_arm_range_prefetch_x(addr, access_kind, retention_policy, length, \
104 count, stride, reuse_distance)
105#define __pld_range(access_kind, retention_policy, metadata, addr) \
106 __builtin_arm_range_prefetch(addr, access_kind, retention_policy, metadata)
107#endif
108
109/* 7.6.2 Instruction prefetch */
110#define __pli(addr) __plix(0, 0, addr)
111
112#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
113#define __plix(cache_level, retention_policy, addr) \
114 __builtin_arm_prefetch(addr, 0, 0)
115#else
116#define __plix(cache_level, retention_policy, addr) \
117 __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0)
118#define __pldir(addr) __builtin_arm_prefetch_ir(addr)
119#endif
120
121/* 7.7 NOP */
122#if !defined(_MSC_VER) || (!defined(__aarch64__) && !defined(__arm64ec__))
123static __inline__ void __attribute__((__always_inline__, __nodebug__)) __nop(void) {
124 __builtin_arm_nop();
125}
126#endif
127
128/* 8 DATA-PROCESSING INTRINSICS */
129/* 8.2 Miscellaneous data-processing intrinsics */
130/* ROR */
131static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
132__ror(uint32_t __x, uint32_t __y) {
133 __y %= 32;
134 if (__y == 0)
135 return __x;
136 return (__x >> __y) | (__x << (32 - __y));
137}
138
139static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
140__rorll(uint64_t __x, uint32_t __y) {
141 __y %= 64;
142 if (__y == 0)
143 return __x;
144 return (__x >> __y) | (__x << (64 - __y));
145}
146
147static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
148__rorl(unsigned long __x, uint32_t __y) {
149#if __SIZEOF_LONG__ == 4
150 return __ror(__x, __y);
151#else
152 return __rorll(__x, __y);
153#endif
154}
155
156
157/* CLZ */
158static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
159__clz(uint32_t __t) {
160 return __builtin_arm_clz(__t);
161}
162
163static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
164__clzl(unsigned long __t) {
165#if __SIZEOF_LONG__ == 4
166 return __builtin_arm_clz(__t);
167#else
168 return __builtin_arm_clz64(__t);
169#endif
170}
171
172static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
173__clzll(uint64_t __t) {
174 return __builtin_arm_clz64(__t);
175}
176
177/* CLS */
178static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
179__cls(uint32_t __t) {
180 return __builtin_arm_cls(__t);
181}
182
183static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
184__clsl(unsigned long __t) {
185#if __SIZEOF_LONG__ == 4
186 return __builtin_arm_cls(__t);
187#else
188 return __builtin_arm_cls64(__t);
189#endif
190}
191
192static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
193__clsll(uint64_t __t) {
194 return __builtin_arm_cls64(__t);
195}
196
197/* REV */
198static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
199__rev(uint32_t __t) {
200 return __builtin_bswap32(__t);
201}
202
203static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
204__revl(unsigned long __t) {
205#if __SIZEOF_LONG__ == 4
206 return __builtin_bswap32(__t);
207#else
208 return __builtin_bswap64(__t);
209#endif
210}
211
212static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
213__revll(uint64_t __t) {
214 return __builtin_bswap64(__t);
215}
216
217/* REV16 */
218static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
219__rev16(uint32_t __t) {
220 return __ror(__rev(__t), 16);
221}
222
223static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
224__rev16ll(uint64_t __t) {
225 return (((__t >> 8) & 0x00ff00ff00ff00ff) |
226 ((__t << 8) & 0xff00ff00ff00ff00));
227}
228
229static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
230__rev16l(unsigned long __t) {
231#if __SIZEOF_LONG__ == 4
232 return __rev16(__t);
233#else
234 return __rev16ll(__t);
235#endif
236}
237
238/* REVSH */
239static __inline__ int16_t __attribute__((__always_inline__, __nodebug__))
240__revsh(int16_t __t) {
241 return (int16_t)__builtin_bswap16((uint16_t)__t);
242}
243
244/* RBIT */
245static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
246__rbit(uint32_t __t) {
247 return __builtin_arm_rbit(__t);
248}
249
250static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
251__rbitll(uint64_t __t) {
252#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
253 return (((uint64_t)__builtin_arm_rbit(__t)) << 32) |
254 __builtin_arm_rbit(__t >> 32);
255#else
256 return __builtin_arm_rbit64(__t);
257#endif
258}
259
260static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
261__rbitl(unsigned long __t) {
262#if __SIZEOF_LONG__ == 4
263 return __rbit(__t);
264#else
265 return __rbitll(__t);
266#endif
267}
268
269/* 8.3 16-bit multiplications */
270#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
271static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
272__smulbb(int32_t __a, int32_t __b) {
273 return __builtin_arm_smulbb(__a, __b);
274}
275static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
276__smulbt(int32_t __a, int32_t __b) {
277 return __builtin_arm_smulbt(__a, __b);
278}
279static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
280__smultb(int32_t __a, int32_t __b) {
281 return __builtin_arm_smultb(__a, __b);
282}
283static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
284__smultt(int32_t __a, int32_t __b) {
285 return __builtin_arm_smultt(__a, __b);
286}
287static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
288__smulwb(int32_t __a, int32_t __b) {
289 return __builtin_arm_smulwb(__a, __b);
290}
291static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
292__smulwt(int32_t __a, int32_t __b) {
293 return __builtin_arm_smulwt(__a, __b);
294}
295#endif
296
297/*
298 * 8.4 Saturating intrinsics
299 *
300 * FIXME: Change guard to their corresponding __ARM_FEATURE flag when Q flag
301 * intrinsics are implemented and the flag is enabled.
302 */
303/* 8.4.1 Width-specified saturation intrinsics */
304#if defined(__ARM_FEATURE_SAT) && __ARM_FEATURE_SAT
305#define __ssat(x, y) __builtin_arm_ssat(x, y)
306#define __usat(x, y) __builtin_arm_usat(x, y)
307#endif
308
309/* 8.4.2 Saturating addition and subtraction intrinsics */
310#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
311static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
312__qadd(int32_t __t, int32_t __v) {
313 return __builtin_arm_qadd(__t, __v);
314}
315
316static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
317__qsub(int32_t __t, int32_t __v) {
318 return __builtin_arm_qsub(__t, __v);
319}
320
321static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
322__qdbl(int32_t __t) {
323 return __builtin_arm_qadd(__t, __t);
324}
325#endif
326
327/* 8.4.3 Accumulating multiplications */
328#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
329static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
330__smlabb(int32_t __a, int32_t __b, int32_t __c) {
331 return __builtin_arm_smlabb(__a, __b, __c);
332}
333static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
334__smlabt(int32_t __a, int32_t __b, int32_t __c) {
335 return __builtin_arm_smlabt(__a, __b, __c);
336}
337static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
338__smlatb(int32_t __a, int32_t __b, int32_t __c) {
339 return __builtin_arm_smlatb(__a, __b, __c);
340}
341static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
342__smlatt(int32_t __a, int32_t __b, int32_t __c) {
343 return __builtin_arm_smlatt(__a, __b, __c);
344}
345static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
346__smlawb(int32_t __a, int32_t __b, int32_t __c) {
347 return __builtin_arm_smlawb(__a, __b, __c);
348}
349static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
350__smlawt(int32_t __a, int32_t __b, int32_t __c) {
351 return __builtin_arm_smlawt(__a, __b, __c);
352}
353#endif
354
355
356/* 8.5.4 Parallel 16-bit saturation */
357#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
358#define __ssat16(x, y) __builtin_arm_ssat16(x, y)
359#define __usat16(x, y) __builtin_arm_usat16(x, y)
360#endif
361
362/* 8.5.5 Packing and unpacking */
363#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
364typedef int32_t int8x4_t;
365typedef int32_t int16x2_t;
366typedef uint32_t uint8x4_t;
367typedef uint32_t uint16x2_t;
368
369static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
370__sxtab16(int16x2_t __a, int8x4_t __b) {
371 return __builtin_arm_sxtab16(__a, __b);
372}
373static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
374__sxtb16(int8x4_t __a) {
375 return __builtin_arm_sxtb16(__a);
376}
377static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
378__uxtab16(int16x2_t __a, int8x4_t __b) {
379 return __builtin_arm_uxtab16(__a, __b);
380}
381static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
382__uxtb16(int8x4_t __a) {
383 return __builtin_arm_uxtb16(__a);
384}
385#endif
386
387/* 8.5.6 Parallel selection */
388#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
389static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
390__sel(uint8x4_t __a, uint8x4_t __b) {
391 return __builtin_arm_sel(__a, __b);
392}
393#endif
394
395/* 8.5.7 Parallel 8-bit addition and subtraction */
396#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
397static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
398__qadd8(int8x4_t __a, int8x4_t __b) {
399 return __builtin_arm_qadd8(__a, __b);
400}
401static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
402__qsub8(int8x4_t __a, int8x4_t __b) {
403 return __builtin_arm_qsub8(__a, __b);
404}
405static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
406__sadd8(int8x4_t __a, int8x4_t __b) {
407 return __builtin_arm_sadd8(__a, __b);
408}
409static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
410__shadd8(int8x4_t __a, int8x4_t __b) {
411 return __builtin_arm_shadd8(__a, __b);
412}
413static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
414__shsub8(int8x4_t __a, int8x4_t __b) {
415 return __builtin_arm_shsub8(__a, __b);
416}
417static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
418__ssub8(int8x4_t __a, int8x4_t __b) {
419 return __builtin_arm_ssub8(__a, __b);
420}
421static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
422__uadd8(uint8x4_t __a, uint8x4_t __b) {
423 return __builtin_arm_uadd8(__a, __b);
424}
425static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
426__uhadd8(uint8x4_t __a, uint8x4_t __b) {
427 return __builtin_arm_uhadd8(__a, __b);
428}
429static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
430__uhsub8(uint8x4_t __a, uint8x4_t __b) {
431 return __builtin_arm_uhsub8(__a, __b);
432}
433static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
434__uqadd8(uint8x4_t __a, uint8x4_t __b) {
435 return __builtin_arm_uqadd8(__a, __b);
436}
437static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
438__uqsub8(uint8x4_t __a, uint8x4_t __b) {
439 return __builtin_arm_uqsub8(__a, __b);
440}
441static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
442__usub8(uint8x4_t __a, uint8x4_t __b) {
443 return __builtin_arm_usub8(__a, __b);
444}
445#endif
446
447/* 8.5.8 Sum of 8-bit absolute differences */
448#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
449static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
450__usad8(uint8x4_t __a, uint8x4_t __b) {
451 return __builtin_arm_usad8(__a, __b);
452}
453static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
455 return __builtin_arm_usada8(__a, __b, __c);
456}
457#endif
458
459/* 8.5.9 Parallel 16-bit addition and subtraction */
460#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
461static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
462__qadd16(int16x2_t __a, int16x2_t __b) {
463 return __builtin_arm_qadd16(__a, __b);
464}
465static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
466__qasx(int16x2_t __a, int16x2_t __b) {
467 return __builtin_arm_qasx(__a, __b);
468}
469static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
470__qsax(int16x2_t __a, int16x2_t __b) {
471 return __builtin_arm_qsax(__a, __b);
472}
473static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
474__qsub16(int16x2_t __a, int16x2_t __b) {
475 return __builtin_arm_qsub16(__a, __b);
476}
477static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
478__sadd16(int16x2_t __a, int16x2_t __b) {
479 return __builtin_arm_sadd16(__a, __b);
480}
481static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
482__sasx(int16x2_t __a, int16x2_t __b) {
483 return __builtin_arm_sasx(__a, __b);
484}
485static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
486__shadd16(int16x2_t __a, int16x2_t __b) {
487 return __builtin_arm_shadd16(__a, __b);
488}
489static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
490__shasx(int16x2_t __a, int16x2_t __b) {
491 return __builtin_arm_shasx(__a, __b);
492}
493static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
494__shsax(int16x2_t __a, int16x2_t __b) {
495 return __builtin_arm_shsax(__a, __b);
496}
497static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
498__shsub16(int16x2_t __a, int16x2_t __b) {
499 return __builtin_arm_shsub16(__a, __b);
500}
501static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
502__ssax(int16x2_t __a, int16x2_t __b) {
503 return __builtin_arm_ssax(__a, __b);
504}
505static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
506__ssub16(int16x2_t __a, int16x2_t __b) {
507 return __builtin_arm_ssub16(__a, __b);
508}
509static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
510__uadd16(uint16x2_t __a, uint16x2_t __b) {
511 return __builtin_arm_uadd16(__a, __b);
512}
513static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
514__uasx(uint16x2_t __a, uint16x2_t __b) {
515 return __builtin_arm_uasx(__a, __b);
516}
517static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
518__uhadd16(uint16x2_t __a, uint16x2_t __b) {
519 return __builtin_arm_uhadd16(__a, __b);
520}
521static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
522__uhasx(uint16x2_t __a, uint16x2_t __b) {
523 return __builtin_arm_uhasx(__a, __b);
524}
525static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
526__uhsax(uint16x2_t __a, uint16x2_t __b) {
527 return __builtin_arm_uhsax(__a, __b);
528}
529static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
530__uhsub16(uint16x2_t __a, uint16x2_t __b) {
531 return __builtin_arm_uhsub16(__a, __b);
532}
533static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
534__uqadd16(uint16x2_t __a, uint16x2_t __b) {
535 return __builtin_arm_uqadd16(__a, __b);
536}
537static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
538__uqasx(uint16x2_t __a, uint16x2_t __b) {
539 return __builtin_arm_uqasx(__a, __b);
540}
541static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
542__uqsax(uint16x2_t __a, uint16x2_t __b) {
543 return __builtin_arm_uqsax(__a, __b);
544}
545static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
546__uqsub16(uint16x2_t __a, uint16x2_t __b) {
547 return __builtin_arm_uqsub16(__a, __b);
548}
549static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
550__usax(uint16x2_t __a, uint16x2_t __b) {
551 return __builtin_arm_usax(__a, __b);
552}
553static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
554__usub16(uint16x2_t __a, uint16x2_t __b) {
555 return __builtin_arm_usub16(__a, __b);
556}
557#endif
558
559/* 8.5.10 Parallel 16-bit multiplication */
560#if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
561static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
563 return __builtin_arm_smlad(__a, __b, __c);
564}
565static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
566__smladx(int16x2_t __a, int16x2_t __b, int32_t __c) {
567 return __builtin_arm_smladx(__a, __b, __c);
568}
569static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
570__smlald(int16x2_t __a, int16x2_t __b, int64_t __c) {
571 return __builtin_arm_smlald(__a, __b, __c);
572}
573static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
574__smlaldx(int16x2_t __a, int16x2_t __b, int64_t __c) {
575 return __builtin_arm_smlaldx(__a, __b, __c);
576}
577static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
579 return __builtin_arm_smlsd(__a, __b, __c);
580}
581static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
582__smlsdx(int16x2_t __a, int16x2_t __b, int32_t __c) {
583 return __builtin_arm_smlsdx(__a, __b, __c);
584}
585static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
586__smlsld(int16x2_t __a, int16x2_t __b, int64_t __c) {
587 return __builtin_arm_smlsld(__a, __b, __c);
588}
589static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
590__smlsldx(int16x2_t __a, int16x2_t __b, int64_t __c) {
591 return __builtin_arm_smlsldx(__a, __b, __c);
592}
593static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
594__smuad(int16x2_t __a, int16x2_t __b) {
595 return __builtin_arm_smuad(__a, __b);
596}
597static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
598__smuadx(int16x2_t __a, int16x2_t __b) {
599 return __builtin_arm_smuadx(__a, __b);
600}
601static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
602__smusd(int16x2_t __a, int16x2_t __b) {
603 return __builtin_arm_smusd(__a, __b);
604}
605static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
606__smusdx(int16x2_t __a, int16x2_t __b) {
607 return __builtin_arm_smusdx(__a, __b);
608}
609#endif
610
611/* 8.6 Floating-point data-processing intrinsics */
612#if (defined(__ARM_FEATURE_DIRECTED_ROUNDING) && \
613 (__ARM_FEATURE_DIRECTED_ROUNDING)) && \
614 (defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE)
615static __inline__ double __attribute__((__always_inline__, __nodebug__))
616__rintn(double __a) {
617 return __builtin_roundeven(__a);
618}
619
620static __inline__ float __attribute__((__always_inline__, __nodebug__))
621__rintnf(float __a) {
622 return __builtin_roundevenf(__a);
623}
624#endif
625
626/* 8.8 CRC32 intrinsics */
627static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
629 return __builtin_arm_crc32b(__a, __b);
630}
631
632static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
633__crc32h(uint32_t __a, uint16_t __b) {
634 return __builtin_arm_crc32h(__a, __b);
635}
636
637static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
639 return __builtin_arm_crc32w(__a, __b);
640}
641
642static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
643__crc32d(uint32_t __a, uint64_t __b) {
644 return __builtin_arm_crc32d(__a, __b);
645}
646
647static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
648__crc32cb(uint32_t __a, uint8_t __b) {
649 return __builtin_arm_crc32cb(__a, __b);
650}
651
652static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
653__crc32ch(uint32_t __a, uint16_t __b) {
654 return __builtin_arm_crc32ch(__a, __b);
655}
656
657static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
658__crc32cw(uint32_t __a, uint32_t __b) {
659 return __builtin_arm_crc32cw(__a, __b);
660}
661
662static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
663__crc32cd(uint32_t __a, uint64_t __b) {
664 return __builtin_arm_crc32cd(__a, __b);
665}
666
667/* 8.6 Floating-point data-processing intrinsics */
668/* Armv8.3-A Javascript conversion intrinsic */
669#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
670static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("v8.3a")))
671__jcvt(double __a) {
672 return __builtin_arm_jcvt(__a);
673}
674#endif
675
676/* Armv8.5-A FP rounding intrinsics */
677#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
678static __inline__ float __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
679__rint32zf(float __a) {
680 return __builtin_arm_rint32zf(__a);
681}
682
683static __inline__ double __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
684__rint32z(double __a) {
685 return __builtin_arm_rint32z(__a);
686}
687
688static __inline__ float __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
689__rint64zf(float __a) {
690 return __builtin_arm_rint64zf(__a);
691}
692
693static __inline__ double __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
694__rint64z(double __a) {
695 return __builtin_arm_rint64z(__a);
696}
697
698static __inline__ float __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
699__rint32xf(float __a) {
700 return __builtin_arm_rint32xf(__a);
701}
702
703static __inline__ double __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
704__rint32x(double __a) {
705 return __builtin_arm_rint32x(__a);
706}
707
708static __inline__ float __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
709__rint64xf(float __a) {
710 return __builtin_arm_rint64xf(__a);
711}
712
713static __inline__ double __attribute__((__always_inline__, __nodebug__, target("v8.5a")))
714__rint64x(double __a) {
715 return __builtin_arm_rint64x(__a);
716}
717#endif
718
719/* 8.9 Armv8.7-A load/store 64-byte intrinsics */
720#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
721typedef struct {
722 uint64_t val[8];
723} data512_t;
724
725static __inline__ data512_t __attribute__((__always_inline__, __nodebug__, target("ls64")))
726__arm_ld64b(const void *__addr) {
727 data512_t __value;
728 __builtin_arm_ld64b(__addr, __value.val);
729 return __value;
730}
731static __inline__ void __attribute__((__always_inline__, __nodebug__, target("ls64")))
732__arm_st64b(void *__addr, data512_t __value) {
733 __builtin_arm_st64b(__addr, __value.val);
734}
735static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__, target("ls64")))
736__arm_st64bv(void *__addr, data512_t __value) {
737 return __builtin_arm_st64bv(__addr, __value.val);
738}
739static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__, target("ls64")))
740__arm_st64bv0(void *__addr, data512_t __value) {
741 return __builtin_arm_st64bv0(__addr, __value.val);
742}
743#endif
744
745/* 11.1 Special register intrinsics */
746#define __arm_rsr(sysreg) __builtin_arm_rsr(sysreg)
747#define __arm_rsr64(sysreg) __builtin_arm_rsr64(sysreg)
748#define __arm_rsr128(sysreg) __builtin_arm_rsr128(sysreg)
749#define __arm_rsrp(sysreg) __builtin_arm_rsrp(sysreg)
750#define __arm_rsrf(sysreg) __builtin_bit_cast(float, __arm_rsr(sysreg))
751#define __arm_rsrf64(sysreg) __builtin_bit_cast(double, __arm_rsr64(sysreg))
752#define __arm_wsr(sysreg, v) __builtin_arm_wsr(sysreg, v)
753#define __arm_wsr64(sysreg, v) __builtin_arm_wsr64(sysreg, v)
754#define __arm_wsr128(sysreg, v) __builtin_arm_wsr128(sysreg, v)
755#define __arm_wsrp(sysreg, v) __builtin_arm_wsrp(sysreg, v)
756#define __arm_wsrf(sysreg, v) __arm_wsr(sysreg, __builtin_bit_cast(uint32_t, v))
757#define __arm_wsrf64(sysreg, v) __arm_wsr64(sysreg, __builtin_bit_cast(uint64_t, v))
758
759/* 10.3 MTE intrinsics */
760#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
761#define __arm_mte_create_random_tag(__ptr, __mask) __builtin_arm_irg(__ptr, __mask)
762#define __arm_mte_increment_tag(__ptr, __tag_offset) __builtin_arm_addg(__ptr, __tag_offset)
763#define __arm_mte_exclude_tag(__ptr, __excluded) __builtin_arm_gmi(__ptr, __excluded)
764#define __arm_mte_get_tag(__ptr) __builtin_arm_ldg(__ptr)
765#define __arm_mte_set_tag(__ptr) __builtin_arm_stg(__ptr)
766#define __arm_mte_ptrdiff(__ptra, __ptrb) __builtin_arm_subp(__ptra, __ptrb)
767
768/* 18 memcpy family of operations intrinsics - MOPS */
769#define __arm_mops_memset_tag(__tagged_address, __value, __size) \
770 __builtin_arm_mops_memset_tag(__tagged_address, __value, __size)
771#endif
772
773/* 11.3 Coprocessor Intrinsics */
774#if defined(__ARM_FEATURE_COPROC)
775
776#if (__ARM_FEATURE_COPROC & 0x1)
777
778#if (__ARM_ARCH < 8)
779#define __arm_cdp(coproc, opc1, CRd, CRn, CRm, opc2) \
780 __builtin_arm_cdp(coproc, opc1, CRd, CRn, CRm, opc2)
781#endif /* __ARM_ARCH < 8 */
782
783#define __arm_ldc(coproc, CRd, p) __builtin_arm_ldc(coproc, CRd, p)
784#define __arm_stc(coproc, CRd, p) __builtin_arm_stc(coproc, CRd, p)
785
786#define __arm_mcr(coproc, opc1, value, CRn, CRm, opc2) \
787 __builtin_arm_mcr(coproc, opc1, value, CRn, CRm, opc2)
788#define __arm_mrc(coproc, opc1, CRn, CRm, opc2) \
789 __builtin_arm_mrc(coproc, opc1, CRn, CRm, opc2)
790
791#if (__ARM_ARCH != 4) && (__ARM_ARCH < 8)
792#define __arm_ldcl(coproc, CRd, p) __builtin_arm_ldcl(coproc, CRd, p)
793#define __arm_stcl(coproc, CRd, p) __builtin_arm_stcl(coproc, CRd, p)
794#endif /* (__ARM_ARCH != 4) && (__ARM_ARCH != 8) */
795
796#if (__ARM_ARCH_8M_MAIN__) || (__ARM_ARCH_8_1M_MAIN__)
797#define __arm_cdp(coproc, opc1, CRd, CRn, CRm, opc2) \
798 __builtin_arm_cdp(coproc, opc1, CRd, CRn, CRm, opc2)
799#define __arm_ldcl(coproc, CRd, p) __builtin_arm_ldcl(coproc, CRd, p)
800#define __arm_stcl(coproc, CRd, p) __builtin_arm_stcl(coproc, CRd, p)
801#endif /* ___ARM_ARCH_8M_MAIN__ */
802
803#endif /* __ARM_FEATURE_COPROC & 0x1 */
804
805#if (__ARM_FEATURE_COPROC & 0x2)
806#define __arm_cdp2(coproc, opc1, CRd, CRn, CRm, opc2) \
807 __builtin_arm_cdp2(coproc, opc1, CRd, CRn, CRm, opc2)
808#define __arm_ldc2(coproc, CRd, p) __builtin_arm_ldc2(coproc, CRd, p)
809#define __arm_stc2(coproc, CRd, p) __builtin_arm_stc2(coproc, CRd, p)
810#define __arm_ldc2l(coproc, CRd, p) __builtin_arm_ldc2l(coproc, CRd, p)
811#define __arm_stc2l(coproc, CRd, p) __builtin_arm_stc2l(coproc, CRd, p)
812#define __arm_mcr2(coproc, opc1, value, CRn, CRm, opc2) \
813 __builtin_arm_mcr2(coproc, opc1, value, CRn, CRm, opc2)
814#define __arm_mrc2(coproc, opc1, CRn, CRm, opc2) \
815 __builtin_arm_mrc2(coproc, opc1, CRn, CRm, opc2)
816#endif
817
818#if (__ARM_FEATURE_COPROC & 0x4)
819#define __arm_mcrr(coproc, opc1, value, CRm) \
820 __builtin_arm_mcrr(coproc, opc1, value, CRm)
821#define __arm_mrrc(coproc, opc1, CRm) __builtin_arm_mrrc(coproc, opc1, CRm)
822#endif
823
824#if (__ARM_FEATURE_COPROC & 0x8)
825#define __arm_mcrr2(coproc, opc1, value, CRm) \
826 __builtin_arm_mcrr2(coproc, opc1, value, CRm)
827#define __arm_mrrc2(coproc, opc1, CRm) __builtin_arm_mrrc2(coproc, opc1, CRm)
828#endif
829
830#endif // __ARM_FEATURE_COPROC
831
832/* 8.7 Armv8.5-A Random number generation intrinsics */
833#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
834static __inline__ int __attribute__((__always_inline__, __nodebug__, target("rand")))
835__rndr(uint64_t *__p) {
836 return __builtin_arm_rndr(__p);
837}
838static __inline__ int __attribute__((__always_inline__, __nodebug__, target("rand")))
839__rndrrs(uint64_t *__p) {
840 return __builtin_arm_rndrrs(__p);
841}
842#endif
843
844/* 11.2 Guarded Control Stack intrinsics */
845#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
846static __inline__ void * __attribute__((__always_inline__, __nodebug__))
847__gcspr() {
848 return (void *)__builtin_arm_rsr64("gcspr_el0");
849}
850
851static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__, target("gcs")))
852__gcspopm() {
853 return __builtin_arm_gcspopm(0);
854}
855
856static __inline__ void *__attribute__((__always_inline__, __nodebug__,
857 target("gcs")))
858__gcsss(void *__stack) {
859 return __builtin_arm_gcsss(__stack);
860}
861#endif
862
863#if defined(__cplusplus)
864}
865#endif
866
867#endif /* __ARM_ACLE_H */
__DEVICE__ int __clzll(long long __a)
__DEVICE__ int __clz(int __a)
_Float16 __2f16 __attribute__((ext_vector_type(2)))
Zeroes the upper 128 bits (bits 255:128) of all YMM registers.
static __inline__ vector float vector float vector float __c
Definition altivec.h:4800
static __inline__ vector float vector float __b
Definition altivec.h:578
static __inline__ uint32_t volatile uint32_t * __p
Definition arm_acle.h:57
void __yield(void)
void __wfi(void)
void __sev(void)
void __dmb(unsigned int)
void __sevl(void)
return __v
Definition arm_acle.h:88
void __isb(unsigned int)
__asm__("swp %0, %1, [%2]" :"=r"(__v) :"r"(__x), "r"(__p) :"memory")
static __inline__ uint32_t uint32_t __y
Definition arm_acle.h:132
void __dsb(unsigned int)
void __wfe(void)
static __inline__ void int __a
Definition emmintrin.h:4086
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32 __crc32d(unsigned int __C, unsigned int __D)
Adds the unsigned integer operand to the CRC-32C checksum of the second unsigned integer operand.
Definition ia32intrin.h:446
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32 __crc32b(unsigned int __C, unsigned char __D)
Adds the unsigned integer operand to the CRC-32C checksum of the unsigned char operand.
Definition ia32intrin.h:406
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32 __crc32w(unsigned int __C, unsigned short __D)
Adds the unsigned integer operand to the CRC-32C checksum of the unsigned short operand.
Definition ia32intrin.h:426
static __inline__ void unsigned int __value
__packed_splat4 int16x2_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 int16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint16x2_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8x4_t