1 /*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 *
21 *===-----------------------------------------------------------------------===
22 */
23
24 #ifndef __ARM_ACLE_H
25 #define __ARM_ACLE_H
26
27 #ifndef __ARM_ACLE
28 #error "ACLE intrinsics support not enabled."
29 #endif
30
31 #include <stdint.h>
32
33 #if defined(__cplusplus)
34 extern "C" {
35 #endif
36
37 /* Miscellaneous data-processing intrinsics */
38
39 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__clz(uint32_t t)40 __clz(uint32_t t) {
41 return __builtin_clz(t);
42 }
43
44 static __inline__ unsigned long __attribute__((always_inline, nodebug))
__clzl(unsigned long t)45 __clzl(unsigned long t) {
46 return __builtin_clzl(t);
47 }
48
49 static __inline__ uint64_t __attribute__((always_inline, nodebug))
__clzll(uint64_t t)50 __clzll(uint64_t t) {
51 #if __SIZEOF_LONG_LONG__ == 8
52 return __builtin_clzll(t);
53 #else
54 return __builtin_clzl(t);
55 #endif
56 }
57
58 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__rev(uint32_t t)59 __rev(uint32_t t) {
60 return __builtin_bswap32(t);
61 }
62
63 static __inline__ unsigned long __attribute__((always_inline, nodebug))
__revl(unsigned long t)64 __revl(unsigned long t) {
65 #if __SIZEOF_LONG__ == 4
66 return __builtin_bswap32(t);
67 #else
68 return __builtin_bswap64(t);
69 #endif
70 }
71
72 static __inline__ uint64_t __attribute__((always_inline, nodebug))
__revll(uint64_t t)73 __revll(uint64_t t) {
74 return __builtin_bswap64(t);
75 }
76
77
78 /*
79 * Saturating intrinsics
80 *
81 * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag
82 * intrinsics are implemented and the flag is enabled.
83 */
84 #if __ARM_32BIT_STATE
85 #define __ssat(x, y) __builtin_arm_ssat(x, y)
86 #define __usat(x, y) __builtin_arm_usat(x, y)
87
88 static __inline__ int32_t __attribute__((always_inline, nodebug))
__qadd(int32_t t,int32_t v)89 __qadd(int32_t t, int32_t v) {
90 return __builtin_arm_qadd(t, v);
91 }
92
93 static __inline__ int32_t __attribute__((always_inline, nodebug))
__qsub(int32_t t,int32_t v)94 __qsub(int32_t t, int32_t v) {
95 return __builtin_arm_qsub(t, v);
96 }
97
98 static __inline__ int32_t __attribute__((always_inline, nodebug))
__qdbl(int32_t t)99 __qdbl(int32_t t) {
100 return __builtin_arm_qadd(t, t);
101 }
102 #endif
103
104 /* CRC32 intrinsics */
105 #if __ARM_FEATURE_CRC32
106 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32b(uint32_t a,uint8_t b)107 __crc32b(uint32_t a, uint8_t b) {
108 return __builtin_arm_crc32b(a, b);
109 }
110
111 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32h(uint32_t a,uint16_t b)112 __crc32h(uint32_t a, uint16_t b) {
113 return __builtin_arm_crc32h(a, b);
114 }
115
116 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32w(uint32_t a,uint32_t b)117 __crc32w(uint32_t a, uint32_t b) {
118 return __builtin_arm_crc32w(a, b);
119 }
120
121 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32d(uint32_t a,uint64_t b)122 __crc32d(uint32_t a, uint64_t b) {
123 return __builtin_arm_crc32d(a, b);
124 }
125
126 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32cb(uint32_t a,uint8_t b)127 __crc32cb(uint32_t a, uint8_t b) {
128 return __builtin_arm_crc32cb(a, b);
129 }
130
131 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32ch(uint32_t a,uint16_t b)132 __crc32ch(uint32_t a, uint16_t b) {
133 return __builtin_arm_crc32ch(a, b);
134 }
135
136 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32cw(uint32_t a,uint32_t b)137 __crc32cw(uint32_t a, uint32_t b) {
138 return __builtin_arm_crc32cw(a, b);
139 }
140
141 static __inline__ uint32_t __attribute__((always_inline, nodebug))
__crc32cd(uint32_t a,uint64_t b)142 __crc32cd(uint32_t a, uint64_t b) {
143 return __builtin_arm_crc32cd(a, b);
144 }
145 #endif
146
147 #if defined(__cplusplus)
148 }
149 #endif
150
151 #endif /* __ARM_ACLE_H */
152