clang API Documentation
00001 /*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------=== 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy 00004 * of this software and associated documentation files (the "Software"), to deal 00005 * in the Software without restriction, including without limitation the rights 00006 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00007 * copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in 00011 * all copies or substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00014 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00015 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00016 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00017 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00019 * THE SOFTWARE. 00020 * 00021 *===-----------------------------------------------------------------------=== 00022 */ 00023 00024 #ifndef __ARM_ACLE_H 00025 #define __ARM_ACLE_H 00026 00027 #ifndef __ARM_ACLE 00028 #error "ACLE intrinsics support not enabled." 00029 #endif 00030 00031 #include <stdint.h> 00032 00033 #if defined(__cplusplus) 00034 extern "C" { 00035 #endif 00036 00037 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ 00038 /* 8.3 Memory barriers */ 00039 #if !defined(_MSC_VER) 00040 #define __dmb(i) __builtin_arm_dmb(i) 00041 #define __dsb(i) __builtin_arm_dsb(i) 00042 #define __isb(i) __builtin_arm_isb(i) 00043 #endif 00044 00045 /* 8.4 Hints */ 00046 00047 #if !defined(_MSC_VER) 00048 static __inline__ void __attribute__((always_inline, nodebug)) __wfi(void) { 00049 __builtin_arm_wfi(); 00050 } 00051 00052 static __inline__ void __attribute__((always_inline, nodebug)) __wfe(void) { 00053 __builtin_arm_wfe(); 00054 } 00055 00056 static __inline__ void __attribute__((always_inline, nodebug)) __sev(void) { 00057 __builtin_arm_sev(); 00058 } 00059 00060 static __inline__ void __attribute__((always_inline, nodebug)) __sevl(void) { 00061 __builtin_arm_sevl(); 00062 } 00063 00064 static __inline__ void __attribute__((always_inline, nodebug)) __yield(void) { 00065 __builtin_arm_yield(); 00066 } 00067 #endif 00068 00069 #if __ARM_32BIT_STATE 00070 #define __dbg(t) __builtin_arm_dbg(t) 00071 #endif 00072 00073 /* 8.5 Swap */ 00074 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00075 __swp(uint32_t x, volatile uint32_t *p) { 00076 uint32_t v; 00077 do v = __builtin_arm_ldrex(p); while (__builtin_arm_strex(x, p)); 00078 return v; 00079 } 00080 00081 /* 8.6 Memory prefetch intrinsics */ 00082 /* 8.6.1 Data prefetch */ 00083 #define __pld(addr) __pldx(0, 0, 0, addr) 00084 00085 #if __ARM_32BIT_STATE 00086 #define __pldx(access_kind, cache_level, retention_policy, addr) \ 00087 __builtin_arm_prefetch(addr, access_kind, 1) 00088 #else 00089 #define __pldx(access_kind, cache_level, retention_policy, addr) \ 00090 __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1) 00091 #endif 00092 00093 /* 8.6.2 Instruction prefetch */ 00094 #define __pli(addr) __plix(0, 0, addr) 00095 00096 #if __ARM_32BIT_STATE 00097 #define __plix(cache_level, retention_policy, addr) \ 00098 __builtin_arm_prefetch(addr, 0, 0) 00099 #else 00100 #define __plix(cache_level, retention_policy, addr) \ 00101 __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0) 00102 #endif 00103 00104 /* 8.7 NOP */ 00105 static __inline__ void __attribute__((always_inline, nodebug)) __nop(void) { 00106 __builtin_arm_nop(); 00107 } 00108 00109 /* 9 DATA-PROCESSING INTRINSICS */ 00110 /* 9.2 Miscellaneous data-processing intrinsics */ 00111 /* ROR */ 00112 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00113 __ror(uint32_t x, uint32_t y) { 00114 y %= 32; 00115 if (y == 0) return x; 00116 return (x >> y) | (x << (32 - y)); 00117 } 00118 00119 static __inline__ uint64_t __attribute__((always_inline, nodebug)) 00120 __rorll(uint64_t x, uint32_t y) { 00121 y %= 64; 00122 if (y == 0) return x; 00123 return (x >> y) | (x << (64 - y)); 00124 } 00125 00126 static __inline__ unsigned long __attribute__((always_inline, nodebug)) 00127 __rorl(unsigned long x, uint32_t y) { 00128 #if __SIZEOF_LONG__ == 4 00129 return __ror(x, y); 00130 #else 00131 return __rorll(x, y); 00132 #endif 00133 } 00134 00135 00136 /* CLZ */ 00137 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00138 __clz(uint32_t t) { 00139 return __builtin_clz(t); 00140 } 00141 00142 static __inline__ unsigned long __attribute__((always_inline, nodebug)) 00143 __clzl(unsigned long t) { 00144 return __builtin_clzl(t); 00145 } 00146 00147 static __inline__ uint64_t __attribute__((always_inline, nodebug)) 00148 __clzll(uint64_t t) { 00149 return __builtin_clzll(t); 00150 } 00151 00152 /* REV */ 00153 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00154 __rev(uint32_t t) { 00155 return __builtin_bswap32(t); 00156 } 00157 00158 static __inline__ unsigned long __attribute__((always_inline, nodebug)) 00159 __revl(unsigned long t) { 00160 #if __SIZEOF_LONG__ == 4 00161 return __builtin_bswap32(t); 00162 #else 00163 return __builtin_bswap64(t); 00164 #endif 00165 } 00166 00167 static __inline__ uint64_t __attribute__((always_inline, nodebug)) 00168 __revll(uint64_t t) { 00169 return __builtin_bswap64(t); 00170 } 00171 00172 /* REV16 */ 00173 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00174 __rev16(uint32_t t) { 00175 return __ror(__rev(t), 16); 00176 } 00177 00178 static __inline__ unsigned long __attribute__((always_inline, nodebug)) 00179 __rev16l(unsigned long t) { 00180 return __rorl(__revl(t), sizeof(long) / 2); 00181 } 00182 00183 static __inline__ uint64_t __attribute__((always_inline, nodebug)) 00184 __rev16ll(uint64_t t) { 00185 return __rorll(__revll(t), 32); 00186 } 00187 00188 /* REVSH */ 00189 static __inline__ int16_t __attribute__((always_inline, nodebug)) 00190 __revsh(int16_t t) { 00191 return __builtin_bswap16(t); 00192 } 00193 00194 /* RBIT */ 00195 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00196 __rbit(uint32_t t) { 00197 return __builtin_arm_rbit(t); 00198 } 00199 00200 static __inline__ uint64_t __attribute__((always_inline, nodebug)) 00201 __rbitll(uint64_t t) { 00202 #if __ARM_32BIT_STATE 00203 return (((uint64_t) __builtin_arm_rbit(t)) << 32) | 00204 __builtin_arm_rbit(t >> 32); 00205 #else 00206 return __builtin_arm_rbit64(t); 00207 #endif 00208 } 00209 00210 static __inline__ unsigned long __attribute__((always_inline, nodebug)) 00211 __rbitl(unsigned long t) { 00212 #if __SIZEOF_LONG__ == 4 00213 return __rbit(t); 00214 #else 00215 return __rbitll(t); 00216 #endif 00217 } 00218 00219 /* 00220 * 9.4 Saturating intrinsics 00221 * 00222 * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag 00223 * intrinsics are implemented and the flag is enabled. 00224 */ 00225 /* 9.4.1 Width-specified saturation intrinsics */ 00226 #if __ARM_32BIT_STATE 00227 #define __ssat(x, y) __builtin_arm_ssat(x, y) 00228 #define __usat(x, y) __builtin_arm_usat(x, y) 00229 #endif 00230 00231 /* 9.4.2 Saturating addition and subtraction intrinsics */ 00232 #if __ARM_32BIT_STATE 00233 static __inline__ int32_t __attribute__((always_inline, nodebug)) 00234 __qadd(int32_t t, int32_t v) { 00235 return __builtin_arm_qadd(t, v); 00236 } 00237 00238 static __inline__ int32_t __attribute__((always_inline, nodebug)) 00239 __qsub(int32_t t, int32_t v) { 00240 return __builtin_arm_qsub(t, v); 00241 } 00242 00243 static __inline__ int32_t __attribute__((always_inline, nodebug)) 00244 __qdbl(int32_t t) { 00245 return __builtin_arm_qadd(t, t); 00246 } 00247 #endif 00248 00249 /* 9.7 CRC32 intrinsics */ 00250 #if __ARM_FEATURE_CRC32 00251 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00252 __crc32b(uint32_t a, uint8_t b) { 00253 return __builtin_arm_crc32b(a, b); 00254 } 00255 00256 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00257 __crc32h(uint32_t a, uint16_t b) { 00258 return __builtin_arm_crc32h(a, b); 00259 } 00260 00261 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00262 __crc32w(uint32_t a, uint32_t b) { 00263 return __builtin_arm_crc32w(a, b); 00264 } 00265 00266 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00267 __crc32d(uint32_t a, uint64_t b) { 00268 return __builtin_arm_crc32d(a, b); 00269 } 00270 00271 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00272 __crc32cb(uint32_t a, uint8_t b) { 00273 return __builtin_arm_crc32cb(a, b); 00274 } 00275 00276 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00277 __crc32ch(uint32_t a, uint16_t b) { 00278 return __builtin_arm_crc32ch(a, b); 00279 } 00280 00281 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00282 __crc32cw(uint32_t a, uint32_t b) { 00283 return __builtin_arm_crc32cw(a, b); 00284 } 00285 00286 static __inline__ uint32_t __attribute__((always_inline, nodebug)) 00287 __crc32cd(uint32_t a, uint64_t b) { 00288 return __builtin_arm_crc32cd(a, b); 00289 } 00290 #endif 00291 00292 #if defined(__cplusplus) 00293 } 00294 #endif 00295 00296 #endif /* __ARM_ACLE_H */