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