arm_acle.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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. #ifndef __ARM_ACLE_H
  24. #define __ARM_ACLE_H
  25. #ifndef __ARM_ACLE
  26. #error "ACLE intrinsics support not enabled."
  27. #endif
  28. #include <stdint.h>
  29. #if defined(__cplusplus)
  30. extern "C" {
  31. #endif
  32. /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
  33. /* 8.3 Memory barriers */
  34. #if !defined(_MSC_VER)
  35. #define __dmb(i) __builtin_arm_dmb(i)
  36. #define __dsb(i) __builtin_arm_dsb(i)
  37. #define __isb(i) __builtin_arm_isb(i)
  38. #endif
  39. /* 8.4 Hints */
  40. #if !defined(_MSC_VER)
  41. static __inline__ void __attribute__((__always_inline__, __nodebug__)) __wfi(void) {
  42. __builtin_arm_wfi();
  43. }
  44. static __inline__ void __attribute__((__always_inline__, __nodebug__)) __wfe(void) {
  45. __builtin_arm_wfe();
  46. }
  47. static __inline__ void __attribute__((__always_inline__, __nodebug__)) __sev(void) {
  48. __builtin_arm_sev();
  49. }
  50. static __inline__ void __attribute__((__always_inline__, __nodebug__)) __sevl(void) {
  51. __builtin_arm_sevl();
  52. }
  53. static __inline__ void __attribute__((__always_inline__, __nodebug__)) __yield(void) {
  54. __builtin_arm_yield();
  55. }
  56. #endif
  57. #if __ARM_32BIT_STATE
  58. #define __dbg(t) __builtin_arm_dbg(t)
  59. #endif
  60. /* 8.5 Swap */
  61. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  62. __swp(uint32_t x, volatile uint32_t *p) {
  63. uint32_t v;
  64. do v = __builtin_arm_ldrex(p); while (__builtin_arm_strex(x, p));
  65. return v;
  66. }
  67. /* 8.6 Memory prefetch intrinsics */
  68. /* 8.6.1 Data prefetch */
  69. #define __pld(addr) __pldx(0, 0, 0, addr)
  70. #if __ARM_32BIT_STATE
  71. #define __pldx(access_kind, cache_level, retention_policy, addr) \
  72. __builtin_arm_prefetch(addr, access_kind, 1)
  73. #else
  74. #define __pldx(access_kind, cache_level, retention_policy, addr) \
  75. __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1)
  76. #endif
  77. /* 8.6.2 Instruction prefetch */
  78. #define __pli(addr) __plix(0, 0, addr)
  79. #if __ARM_32BIT_STATE
  80. #define __plix(cache_level, retention_policy, addr) \
  81. __builtin_arm_prefetch(addr, 0, 0)
  82. #else
  83. #define __plix(cache_level, retention_policy, addr) \
  84. __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0)
  85. #endif
  86. /* 8.7 NOP */
  87. static __inline__ void __attribute__((__always_inline__, __nodebug__)) __nop(void) {
  88. __builtin_arm_nop();
  89. }
  90. /* 9 DATA-PROCESSING INTRINSICS */
  91. /* 9.2 Miscellaneous data-processing intrinsics */
  92. /* ROR */
  93. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  94. __ror(uint32_t x, uint32_t y) {
  95. y %= 32;
  96. if (y == 0) return x;
  97. return (x >> y) | (x << (32 - y));
  98. }
  99. static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
  100. __rorll(uint64_t x, uint32_t y) {
  101. y %= 64;
  102. if (y == 0) return x;
  103. return (x >> y) | (x << (64 - y));
  104. }
  105. static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
  106. __rorl(unsigned long x, uint32_t y) {
  107. #if __SIZEOF_LONG__ == 4
  108. return __ror(x, y);
  109. #else
  110. return __rorll(x, y);
  111. #endif
  112. }
  113. /* CLZ */
  114. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  115. __clz(uint32_t t) {
  116. return __builtin_clz(t);
  117. }
  118. static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
  119. __clzl(unsigned long t) {
  120. return __builtin_clzl(t);
  121. }
  122. static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
  123. __clzll(uint64_t t) {
  124. return __builtin_clzll(t);
  125. }
  126. /* REV */
  127. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  128. __rev(uint32_t t) {
  129. return __builtin_bswap32(t);
  130. }
  131. static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
  132. __revl(unsigned long t) {
  133. #if __SIZEOF_LONG__ == 4
  134. return __builtin_bswap32(t);
  135. #else
  136. return __builtin_bswap64(t);
  137. #endif
  138. }
  139. static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
  140. __revll(uint64_t t) {
  141. return __builtin_bswap64(t);
  142. }
  143. /* REV16 */
  144. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  145. __rev16(uint32_t t) {
  146. return __ror(__rev(t), 16);
  147. }
  148. static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
  149. __rev16l(unsigned long t) {
  150. return __rorl(__revl(t), sizeof(long) / 2);
  151. }
  152. static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
  153. __rev16ll(uint64_t t) {
  154. return __rorll(__revll(t), 32);
  155. }
  156. /* REVSH */
  157. static __inline__ int16_t __attribute__((__always_inline__, __nodebug__))
  158. __revsh(int16_t t) {
  159. return __builtin_bswap16(t);
  160. }
  161. /* RBIT */
  162. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  163. __rbit(uint32_t t) {
  164. return __builtin_arm_rbit(t);
  165. }
  166. static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
  167. __rbitll(uint64_t t) {
  168. #if __ARM_32BIT_STATE
  169. return (((uint64_t) __builtin_arm_rbit(t)) << 32) |
  170. __builtin_arm_rbit(t >> 32);
  171. #else
  172. return __builtin_arm_rbit64(t);
  173. #endif
  174. }
  175. static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
  176. __rbitl(unsigned long t) {
  177. #if __SIZEOF_LONG__ == 4
  178. return __rbit(t);
  179. #else
  180. return __rbitll(t);
  181. #endif
  182. }
  183. /*
  184. * 9.4 Saturating intrinsics
  185. *
  186. * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag
  187. * intrinsics are implemented and the flag is enabled.
  188. */
  189. /* 9.4.1 Width-specified saturation intrinsics */
  190. #if __ARM_32BIT_STATE
  191. #define __ssat(x, y) __builtin_arm_ssat(x, y)
  192. #define __usat(x, y) __builtin_arm_usat(x, y)
  193. #endif
  194. /* 9.4.2 Saturating addition and subtraction intrinsics */
  195. #if __ARM_32BIT_STATE
  196. static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
  197. __qadd(int32_t t, int32_t v) {
  198. return __builtin_arm_qadd(t, v);
  199. }
  200. static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
  201. __qsub(int32_t t, int32_t v) {
  202. return __builtin_arm_qsub(t, v);
  203. }
  204. static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
  205. __qdbl(int32_t t) {
  206. return __builtin_arm_qadd(t, t);
  207. }
  208. #endif
  209. /* 9.7 CRC32 intrinsics */
  210. #if __ARM_FEATURE_CRC32
  211. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  212. __crc32b(uint32_t a, uint8_t b) {
  213. return __builtin_arm_crc32b(a, b);
  214. }
  215. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  216. __crc32h(uint32_t a, uint16_t b) {
  217. return __builtin_arm_crc32h(a, b);
  218. }
  219. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  220. __crc32w(uint32_t a, uint32_t b) {
  221. return __builtin_arm_crc32w(a, b);
  222. }
  223. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  224. __crc32d(uint32_t a, uint64_t b) {
  225. return __builtin_arm_crc32d(a, b);
  226. }
  227. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  228. __crc32cb(uint32_t a, uint8_t b) {
  229. return __builtin_arm_crc32cb(a, b);
  230. }
  231. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  232. __crc32ch(uint32_t a, uint16_t b) {
  233. return __builtin_arm_crc32ch(a, b);
  234. }
  235. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  236. __crc32cw(uint32_t a, uint32_t b) {
  237. return __builtin_arm_crc32cw(a, b);
  238. }
  239. static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
  240. __crc32cd(uint32_t a, uint64_t b) {
  241. return __builtin_arm_crc32cd(a, b);
  242. }
  243. #endif
  244. /* 10.1 Special register intrinsics */
  245. #define __arm_rsr(sysreg) __builtin_arm_rsr(sysreg)
  246. #define __arm_rsr64(sysreg) __builtin_arm_rsr64(sysreg)
  247. #define __arm_rsrp(sysreg) __builtin_arm_rsrp(sysreg)
  248. #define __arm_wsr(sysreg, v) __builtin_arm_wsr(sysreg, v)
  249. #define __arm_wsr64(sysreg, v) __builtin_arm_wsr64(sysreg, v)
  250. #define __arm_wsrp(sysreg, v) __builtin_arm_wsrp(sysreg, v)
  251. #if defined(__cplusplus)
  252. }
  253. #endif
  254. #endif /* __ARM_ACLE_H */