arm_acle.h revision 296417
1274958Sdim/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
2274958Sdim *
3274958Sdim * Permission is hereby granted, free of charge, to any person obtaining a copy
4274958Sdim * of this software and associated documentation files (the "Software"), to deal
5274958Sdim * in the Software without restriction, including without limitation the rights
6274958Sdim * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7274958Sdim * copies of the Software, and to permit persons to whom the Software is
8274958Sdim * furnished to do so, subject to the following conditions:
9274958Sdim *
10274958Sdim * The above copyright notice and this permission notice shall be included in
11274958Sdim * all copies or substantial portions of the Software.
12274958Sdim *
13274958Sdim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14274958Sdim * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15274958Sdim * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16274958Sdim * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17274958Sdim * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18274958Sdim * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19274958Sdim * THE SOFTWARE.
20274958Sdim *
21274958Sdim *===-----------------------------------------------------------------------===
22274958Sdim */
23274958Sdim
24274958Sdim#ifndef __ARM_ACLE_H
25274958Sdim#define __ARM_ACLE_H
26274958Sdim
27274958Sdim#ifndef __ARM_ACLE
28274958Sdim#error "ACLE intrinsics support not enabled."
29274958Sdim#endif
30274958Sdim
31274958Sdim#include <stdint.h>
32274958Sdim
33274958Sdim#if defined(__cplusplus)
34274958Sdimextern "C" {
35274958Sdim#endif
36274958Sdim
37274958Sdim/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
38274958Sdim/* 8.3 Memory barriers */
39274958Sdim#if !defined(_MSC_VER)
40274958Sdim#define __dmb(i) __builtin_arm_dmb(i)
41274958Sdim#define __dsb(i) __builtin_arm_dsb(i)
42274958Sdim#define __isb(i) __builtin_arm_isb(i)
43274958Sdim#endif
44274958Sdim
45274958Sdim/* 8.4 Hints */
46274958Sdim
47274958Sdim#if !defined(_MSC_VER)
48288943Sdimstatic __inline__ void __attribute__((__always_inline__, __nodebug__)) __wfi(void) {
49274958Sdim  __builtin_arm_wfi();
50274958Sdim}
51274958Sdim
52288943Sdimstatic __inline__ void __attribute__((__always_inline__, __nodebug__)) __wfe(void) {
53274958Sdim  __builtin_arm_wfe();
54274958Sdim}
55274958Sdim
56288943Sdimstatic __inline__ void __attribute__((__always_inline__, __nodebug__)) __sev(void) {
57274958Sdim  __builtin_arm_sev();
58274958Sdim}
59274958Sdim
60288943Sdimstatic __inline__ void __attribute__((__always_inline__, __nodebug__)) __sevl(void) {
61274958Sdim  __builtin_arm_sevl();
62274958Sdim}
63274958Sdim
64288943Sdimstatic __inline__ void __attribute__((__always_inline__, __nodebug__)) __yield(void) {
65274958Sdim  __builtin_arm_yield();
66274958Sdim}
67274958Sdim#endif
68274958Sdim
69280031Sdim#if __ARM_32BIT_STATE
70280031Sdim#define __dbg(t) __builtin_arm_dbg(t)
71280031Sdim#endif
72280031Sdim
73280031Sdim/* 8.5 Swap */
74288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
75280031Sdim  __swp(uint32_t x, volatile uint32_t *p) {
76280031Sdim  uint32_t v;
77280031Sdim  do v = __builtin_arm_ldrex(p); while (__builtin_arm_strex(x, p));
78280031Sdim  return v;
79280031Sdim}
80280031Sdim
81280031Sdim/* 8.6 Memory prefetch intrinsics */
82280031Sdim/* 8.6.1 Data prefetch */
83280031Sdim#define __pld(addr) __pldx(0, 0, 0, addr)
84280031Sdim
85280031Sdim#if __ARM_32BIT_STATE
86280031Sdim#define __pldx(access_kind, cache_level, retention_policy, addr) \
87280031Sdim  __builtin_arm_prefetch(addr, access_kind, 1)
88280031Sdim#else
89280031Sdim#define __pldx(access_kind, cache_level, retention_policy, addr) \
90280031Sdim  __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1)
91280031Sdim#endif
92280031Sdim
93280031Sdim/* 8.6.2 Instruction prefetch */
94280031Sdim#define __pli(addr) __plix(0, 0, addr)
95280031Sdim
96280031Sdim#if __ARM_32BIT_STATE
97280031Sdim#define __plix(cache_level, retention_policy, addr) \
98280031Sdim  __builtin_arm_prefetch(addr, 0, 0)
99280031Sdim#else
100280031Sdim#define __plix(cache_level, retention_policy, addr) \
101280031Sdim  __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0)
102280031Sdim#endif
103280031Sdim
104274958Sdim/* 8.7 NOP */
105288943Sdimstatic __inline__ void __attribute__((__always_inline__, __nodebug__)) __nop(void) {
106274958Sdim  __builtin_arm_nop();
107274958Sdim}
108274958Sdim
109274958Sdim/* 9 DATA-PROCESSING INTRINSICS */
110274958Sdim/* 9.2 Miscellaneous data-processing intrinsics */
111280031Sdim/* ROR */
112288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
113280031Sdim  __ror(uint32_t x, uint32_t y) {
114280031Sdim  y %= 32;
115280031Sdim  if (y == 0)  return x;
116280031Sdim  return (x >> y) | (x << (32 - y));
117280031Sdim}
118280031Sdim
119288943Sdimstatic __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
120280031Sdim  __rorll(uint64_t x, uint32_t y) {
121280031Sdim  y %= 64;
122280031Sdim  if (y == 0)  return x;
123280031Sdim  return (x >> y) | (x << (64 - y));
124280031Sdim}
125280031Sdim
126288943Sdimstatic __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
127280031Sdim  __rorl(unsigned long x, uint32_t y) {
128280031Sdim#if __SIZEOF_LONG__ == 4
129280031Sdim  return __ror(x, y);
130280031Sdim#else
131280031Sdim  return __rorll(x, y);
132280031Sdim#endif
133280031Sdim}
134280031Sdim
135280031Sdim
136280031Sdim/* CLZ */
137288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
138274958Sdim  __clz(uint32_t t) {
139274958Sdim  return __builtin_clz(t);
140274958Sdim}
141274958Sdim
142288943Sdimstatic __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
143274958Sdim  __clzl(unsigned long t) {
144274958Sdim  return __builtin_clzl(t);
145274958Sdim}
146274958Sdim
147288943Sdimstatic __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
148274958Sdim  __clzll(uint64_t t) {
149274958Sdim  return __builtin_clzll(t);
150274958Sdim}
151274958Sdim
152280031Sdim/* REV */
153288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
154274958Sdim  __rev(uint32_t t) {
155274958Sdim  return __builtin_bswap32(t);
156274958Sdim}
157274958Sdim
158288943Sdimstatic __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
159274958Sdim  __revl(unsigned long t) {
160274958Sdim#if __SIZEOF_LONG__ == 4
161274958Sdim  return __builtin_bswap32(t);
162274958Sdim#else
163274958Sdim  return __builtin_bswap64(t);
164274958Sdim#endif
165274958Sdim}
166274958Sdim
167288943Sdimstatic __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
168274958Sdim  __revll(uint64_t t) {
169274958Sdim  return __builtin_bswap64(t);
170274958Sdim}
171274958Sdim
172280031Sdim/* REV16 */
173288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
174280031Sdim  __rev16(uint32_t t) {
175280031Sdim  return __ror(__rev(t), 16);
176280031Sdim}
177280031Sdim
178296417Sdimstatic __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
179296417Sdim  __rev16ll(uint64_t t) {
180296417Sdim  return (((uint64_t)__rev16(t >> 32)) << 32) | __rev16(t);
181296417Sdim}
182296417Sdim
183288943Sdimstatic __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
184280031Sdim  __rev16l(unsigned long t) {
185296417Sdim#if __SIZEOF_LONG__ == 4
186296417Sdim    return __rev16(t);
187296417Sdim#else
188296417Sdim    return __rev16ll(t);
189296417Sdim#endif
190280031Sdim}
191280031Sdim
192280031Sdim/* REVSH */
193288943Sdimstatic __inline__ int16_t __attribute__((__always_inline__, __nodebug__))
194280031Sdim  __revsh(int16_t t) {
195280031Sdim  return __builtin_bswap16(t);
196280031Sdim}
197280031Sdim
198280031Sdim/* RBIT */
199288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
200280031Sdim  __rbit(uint32_t t) {
201280031Sdim  return __builtin_arm_rbit(t);
202280031Sdim}
203280031Sdim
204288943Sdimstatic __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
205280031Sdim  __rbitll(uint64_t t) {
206280031Sdim#if __ARM_32BIT_STATE
207280031Sdim  return (((uint64_t) __builtin_arm_rbit(t)) << 32) |
208280031Sdim    __builtin_arm_rbit(t >> 32);
209280031Sdim#else
210280031Sdim  return __builtin_arm_rbit64(t);
211280031Sdim#endif
212280031Sdim}
213280031Sdim
214288943Sdimstatic __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
215280031Sdim  __rbitl(unsigned long t) {
216280031Sdim#if __SIZEOF_LONG__ == 4
217280031Sdim  return __rbit(t);
218280031Sdim#else
219280031Sdim  return __rbitll(t);
220280031Sdim#endif
221280031Sdim}
222280031Sdim
223274958Sdim/*
224274958Sdim * 9.4 Saturating intrinsics
225274958Sdim *
226274958Sdim * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag
227274958Sdim * intrinsics are implemented and the flag is enabled.
228274958Sdim */
229274958Sdim/* 9.4.1 Width-specified saturation intrinsics */
230274958Sdim#if __ARM_32BIT_STATE
231274958Sdim#define __ssat(x, y) __builtin_arm_ssat(x, y)
232274958Sdim#define __usat(x, y) __builtin_arm_usat(x, y)
233274958Sdim#endif
234274958Sdim
235274958Sdim/* 9.4.2 Saturating addition and subtraction intrinsics */
236274958Sdim#if __ARM_32BIT_STATE
237288943Sdimstatic __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
238274958Sdim  __qadd(int32_t t, int32_t v) {
239274958Sdim  return __builtin_arm_qadd(t, v);
240274958Sdim}
241274958Sdim
242288943Sdimstatic __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
243274958Sdim  __qsub(int32_t t, int32_t v) {
244274958Sdim  return __builtin_arm_qsub(t, v);
245274958Sdim}
246274958Sdim
247288943Sdimstatic __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
248274958Sdim__qdbl(int32_t t) {
249274958Sdim  return __builtin_arm_qadd(t, t);
250274958Sdim}
251274958Sdim#endif
252274958Sdim
253274958Sdim/* 9.7 CRC32 intrinsics */
254274958Sdim#if __ARM_FEATURE_CRC32
255288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
256274958Sdim  __crc32b(uint32_t a, uint8_t b) {
257274958Sdim  return __builtin_arm_crc32b(a, b);
258274958Sdim}
259274958Sdim
260288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
261274958Sdim  __crc32h(uint32_t a, uint16_t b) {
262274958Sdim  return __builtin_arm_crc32h(a, b);
263274958Sdim}
264274958Sdim
265288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
266274958Sdim  __crc32w(uint32_t a, uint32_t b) {
267274958Sdim  return __builtin_arm_crc32w(a, b);
268274958Sdim}
269274958Sdim
270288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
271274958Sdim  __crc32d(uint32_t a, uint64_t b) {
272274958Sdim  return __builtin_arm_crc32d(a, b);
273274958Sdim}
274274958Sdim
275288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
276274958Sdim  __crc32cb(uint32_t a, uint8_t b) {
277274958Sdim  return __builtin_arm_crc32cb(a, b);
278274958Sdim}
279274958Sdim
280288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
281274958Sdim  __crc32ch(uint32_t a, uint16_t b) {
282274958Sdim  return __builtin_arm_crc32ch(a, b);
283274958Sdim}
284274958Sdim
285288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
286274958Sdim  __crc32cw(uint32_t a, uint32_t b) {
287274958Sdim  return __builtin_arm_crc32cw(a, b);
288274958Sdim}
289274958Sdim
290288943Sdimstatic __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
291274958Sdim  __crc32cd(uint32_t a, uint64_t b) {
292274958Sdim  return __builtin_arm_crc32cd(a, b);
293274958Sdim}
294274958Sdim#endif
295274958Sdim
296288943Sdim/* 10.1 Special register intrinsics */
297288943Sdim#define __arm_rsr(sysreg) __builtin_arm_rsr(sysreg)
298288943Sdim#define __arm_rsr64(sysreg) __builtin_arm_rsr64(sysreg)
299288943Sdim#define __arm_rsrp(sysreg) __builtin_arm_rsrp(sysreg)
300288943Sdim#define __arm_wsr(sysreg, v) __builtin_arm_wsr(sysreg, v)
301288943Sdim#define __arm_wsr64(sysreg, v) __builtin_arm_wsr64(sysreg, v)
302288943Sdim#define __arm_wsrp(sysreg, v) __builtin_arm_wsrp(sysreg, v)
303288943Sdim
304274958Sdim#if defined(__cplusplus)
305274958Sdim}
306274958Sdim#endif
307274958Sdim
308274958Sdim#endif /* __ARM_ACLE_H */
309