clang API Documentation

arm_acle.h
Go to the documentation of this file.
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 */