_endian.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /* $OpenBSD: _endian.h,v 1.1 2014/07/12 16:25:08 guenther Exp $ */
  2. /*-
  3. * Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /*
  26. * Internal endianness macros. This pulls in <machine/endian.h> to
  27. * get the correct setting direction for the platform and sets internal
  28. * ('__' prefix) macros appropriately.
  29. */
  30. #ifndef _SYS__ENDIAN_H_
  31. #define _SYS__ENDIAN_H_
  32. #include <sys/_types.h>
  33. #define __FROM_SYS__ENDIAN
  34. #include <machine/endian.h>
  35. #undef __FROM_SYS__ENDIAN
  36. #define _LITTLE_ENDIAN 1234
  37. #define _BIG_ENDIAN 4321
  38. #define _PDP_ENDIAN 3412
  39. #ifdef __GNUC__
  40. #define __swap16gen(x) __statement({ \
  41. __uint16_t __swap16gen_x = (x); \
  42. \
  43. (__uint16_t)((__swap16gen_x & 0xff) << 8 | \
  44. (__swap16gen_x & 0xff00) >> 8); \
  45. })
  46. #define __swap32gen(x) __statement({ \
  47. __uint32_t __swap32gen_x = (x); \
  48. \
  49. (__uint32_t)((__swap32gen_x & 0xff) << 24 | \
  50. (__swap32gen_x & 0xff00) << 8 | \
  51. (__swap32gen_x & 0xff0000) >> 8 | \
  52. (__swap32gen_x & 0xff000000) >> 24); \
  53. })
  54. #define __swap64gen(x) __statement({ \
  55. __uint64_t __swap64gen_x = (x); \
  56. \
  57. (__uint64_t)((__swap64gen_x & 0xff) << 56 | \
  58. (__swap64gen_x & 0xff00ULL) << 40 | \
  59. (__swap64gen_x & 0xff0000ULL) << 24 | \
  60. (__swap64gen_x & 0xff000000ULL) << 8 | \
  61. (__swap64gen_x & 0xff00000000ULL) >> 8 | \
  62. (__swap64gen_x & 0xff0000000000ULL) >> 24 | \
  63. (__swap64gen_x & 0xff000000000000ULL) >> 40 | \
  64. (__swap64gen_x & 0xff00000000000000ULL) >> 56); \
  65. })
  66. #else /* __GNUC__ */
  67. /* Note that these macros evaluate their arguments several times. */
  68. #define __swap16gen(x) \
  69. (__uint16_t)(((__uint16_t)(x) & 0xffU) << 8 | ((__uint16_t)(x) & 0xff00U) >> 8)
  70. #define __swap32gen(x) \
  71. (__uint32_t)(((__uint32_t)(x) & 0xff) << 24 | \
  72. ((__uint32_t)(x) & 0xff00) << 8 | ((__uint32_t)(x) & 0xff0000) >> 8 |\
  73. ((__uint32_t)(x) & 0xff000000) >> 24)
  74. #define __swap64gen(x) \
  75. (__uint64_t)((((__uint64_t)(x) & 0xff) << 56) | \
  76. ((__uint64_t)(x) & 0xff00ULL) << 40 | \
  77. ((__uint64_t)(x) & 0xff0000ULL) << 24 | \
  78. ((__uint64_t)(x) & 0xff000000ULL) << 8 | \
  79. ((__uint64_t)(x) & 0xff00000000ULL) >> 8 | \
  80. ((__uint64_t)(x) & 0xff0000000000ULL) >> 24 | \
  81. ((__uint64_t)(x) & 0xff000000000000ULL) >> 40 | \
  82. ((__uint64_t)(x) & 0xff00000000000000ULL) >> 56)
  83. #endif /* __GNUC__ */
  84. /*
  85. * Define __HAVE_MD_SWAP if you provide __swap{16,32}md functions/macros
  86. * that are optimized for your architecture, These will be used for
  87. * __swap{16,32} unless the argument is a constant and we are using GCC,
  88. * where we can take advantage of the CSE phase much better by using the
  89. * generic version.
  90. */
  91. #ifdef __HAVE_MD_SWAP
  92. #if __GNUC__
  93. #define __swap16(x) __statement({ \
  94. __uint16_t __swap16_x = (x); \
  95. \
  96. __builtin_constant_p(x) ? __swap16gen(__swap16_x) : \
  97. __swap16md(__swap16_x); \
  98. })
  99. #define __swap32(x) __statement({ \
  100. __uint32_t __swap32_x = (x); \
  101. \
  102. __builtin_constant_p(x) ? __swap32gen(__swap32_x) : \
  103. __swap32md(__swap32_x); \
  104. })
  105. #define __swap64(x) __statement({ \
  106. __uint64_t __swap64_x = (x); \
  107. \
  108. __builtin_constant_p(x) ? __swap64gen(__swap64_x) : \
  109. __swap64md(__swap64_x); \
  110. })
  111. #else
  112. /* have MD macros, but not gcc */
  113. #define __swap16 __swap16md
  114. #define __swap32 __swap32md
  115. #define __swap64 __swap64md
  116. #endif /* __GNUC__ */
  117. #else /* __HAVE_MD_SWAP */
  118. #define __swap16 __swap16gen
  119. #define __swap32 __swap32gen
  120. #define __swap64 __swap64gen
  121. #endif /* __HAVE_MD_SWAP */
  122. #define __swap16_multi(v, n) do { \
  123. __size_t __swap16_multi_n = (n); \
  124. __uint16_t *__swap16_multi_v = (v); \
  125. \
  126. while (__swap16_multi_n) { \
  127. *__swap16_multi_v = swap16(*__swap16_multi_v); \
  128. __swap16_multi_v++; \
  129. __swap16_multi_n--; \
  130. } \
  131. } while (0)
  132. #if _BYTE_ORDER == _LITTLE_ENDIAN
  133. #define _QUAD_HIGHWORD 1
  134. #define _QUAD_LOWWORD 0
  135. #define __htobe16 __swap16
  136. #define __htobe32 __swap32
  137. #define __htobe64 __swap64
  138. #define __htole16(x) ((__uint16_t)(x))
  139. #define __htole32(x) ((__uint32_t)(x))
  140. #define __htole64(x) ((__uint64_t)(x))
  141. #ifdef _KERNEL
  142. #ifdef __HAVE_MD_SWAPIO
  143. #define __bemtoh16(_x) __mswap16(_x)
  144. #define __bemtoh32(_x) __mswap32(_x)
  145. #define __bemtoh64(_x) __mswap64(_x)
  146. #define __htobem16(_x, _v) __swapm16((_x), (_v))
  147. #define __htobem32(_x, _v) __swapm32((_x), (_v))
  148. #define __htobem64(_x, _v) __swapm64((_x), (_v))
  149. #endif /* __HAVE_MD_SWAPIO */
  150. #endif /* _KERNEL */
  151. #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
  152. #if _BYTE_ORDER == _BIG_ENDIAN
  153. #define _QUAD_HIGHWORD 0
  154. #define _QUAD_LOWWORD 1
  155. #define __htobe16(x) ((__uint16_t)(x))
  156. #define __htobe32(x) ((__uint32_t)(x))
  157. #define __htobe64(x) ((__uint64_t)(x))
  158. #define __htole16 __swap16
  159. #define __htole32 __swap32
  160. #define __htole64 __swap64
  161. #ifdef _KERNEL
  162. #ifdef __HAVE_MD_SWAPIO
  163. #define __lemtoh16(_x) __mswap16(_x)
  164. #define __lemtoh32(_x) __mswap32(_x)
  165. #define __lemtoh64(_x) __mswap64(_x)
  166. #define __htolem16(_x, _v) __swapm16((_x), (_v))
  167. #define __htolem32(_x, _v) __swapm32((_x), (_v))
  168. #define __htolem64(_x, _v) __swapm64((_x), (_v))
  169. #endif /* __HAVE_MD_SWAPIO */
  170. #endif /* _KERNEL */
  171. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  172. #ifdef _KERNEL
  173. /*
  174. * Fill in the __hto[bl]em{16,32,64} and __[bl]emtoh{16,32,64} macros
  175. * that haven't been defined yet
  176. */
  177. #ifndef __bemtoh16
  178. #define __bemtoh16(_x) __htobe16(*(__uint16_t *)(_x))
  179. #define __bemtoh32(_x) __htobe32(*(__uint32_t *)(_x))
  180. #define __bemtoh64(_x) __htobe64(*(__uint64_t *)(_x))
  181. #endif
  182. #ifndef __htobem16
  183. #define __htobem16(_x, _v) (*(__uint16_t *)(_x) = __htobe16(_v))
  184. #define __htobem32(_x, _v) (*(__uint32_t *)(_x) = __htobe32(_v))
  185. #define __htobem64(_x, _v) (*(__uint64_t *)(_x) = __htobe64(_v))
  186. #endif
  187. #ifndef __lemtoh16
  188. #define __lemtoh16(_x) __htole16(*(__uint16_t *)(_x))
  189. #define __lemtoh32(_x) __htole32(*(__uint32_t *)(_x))
  190. #define __lemtoh64(_x) __htole64(*(__uint64_t *)(_x))
  191. #endif
  192. #ifndef __htolem16
  193. #define __htolem16(_x, _v) (*(__uint16_t *)(_x) = __htole16(_v))
  194. #define __htolem32(_x, _v) (*(__uint32_t *)(_x) = __htole32(_v))
  195. #define __htolem64(_x, _v) (*(__uint64_t *)(_x) = __htole64(_v))
  196. #endif
  197. #endif /* _KERNEL */
  198. #endif /* _SYS__ENDIAN_H_ */