byteswap.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* Macros to swap the order of bytes in integer values.
  2. Copyright (C) 1997, 1998, 2000, 2002, 2003, 2007, 2008, 2010
  3. Free Software Foundation, Inc.
  4. This file is part of the GNU C Library.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, write to the Free
  15. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  16. 02111-1307 USA. */
  17. #if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H
  18. # error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
  19. #endif
  20. #ifndef _BITS_BYTESWAP_H
  21. #define _BITS_BYTESWAP_H 1
  22. #include <bits/wordsize.h>
  23. /* Swap bytes in 16 bit value. */
  24. #define __bswap_constant_16(x) \
  25. ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
  26. #if defined __GNUC__ && __GNUC__ >= 2
  27. # define __bswap_16(x) \
  28. (__extension__ \
  29. ({ register unsigned short int __v, __x = (unsigned short int) (x); \
  30. if (__builtin_constant_p (__x)) \
  31. __v = __bswap_constant_16 (__x); \
  32. else \
  33. __asm__ ("rorw $8, %w0" \
  34. : "=r" (__v) \
  35. : "0" (__x) \
  36. : "cc"); \
  37. __v; }))
  38. #else
  39. /* This is better than nothing. */
  40. # define __bswap_16(x) \
  41. (__extension__ \
  42. ({ register unsigned short int __x = (unsigned short int) (x); \
  43. __bswap_constant_16 (__x); }))
  44. #endif
  45. /* Swap bytes in 32 bit value. */
  46. #define __bswap_constant_32(x) \
  47. ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
  48. (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
  49. #if defined __GNUC__ && __GNUC__ >= 2
  50. # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \
  51. || defined __pentiumpro__ || defined __pentium4__ \
  52. || defined __k8__ || defined __athlon__ \
  53. || defined __k6__ || defined __nocona__ \
  54. || defined __core2__ || defined __geode__ \
  55. || defined __amdfam10__)
  56. /* To swap the bytes in a word the i486 processors and up provide the
  57. `bswap' opcode. On i386 we have to use three instructions. */
  58. # define __bswap_32(x) \
  59. (__extension__ \
  60. ({ register unsigned int __v, __x = (x); \
  61. if (__builtin_constant_p (__x)) \
  62. __v = __bswap_constant_32 (__x); \
  63. else \
  64. __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
  65. __v; }))
  66. # else
  67. # define __bswap_32(x) \
  68. (__extension__ \
  69. ({ register unsigned int __v, __x = (x); \
  70. if (__builtin_constant_p (__x)) \
  71. __v = __bswap_constant_32 (__x); \
  72. else \
  73. __asm__ ("rorw $8, %w0;" \
  74. "rorl $16, %0;" \
  75. "rorw $8, %w0" \
  76. : "=r" (__v) \
  77. : "0" (__x) \
  78. : "cc"); \
  79. __v; }))
  80. # endif
  81. #else
  82. # define __bswap_32(x) \
  83. (__extension__ \
  84. ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
  85. #endif
  86. #if defined __GNUC__ && __GNUC__ >= 2
  87. /* Swap bytes in 64 bit value. */
  88. # define __bswap_constant_64(x) \
  89. ((((x) & 0xff00000000000000ull) >> 56) \
  90. | (((x) & 0x00ff000000000000ull) >> 40) \
  91. | (((x) & 0x0000ff0000000000ull) >> 24) \
  92. | (((x) & 0x000000ff00000000ull) >> 8) \
  93. | (((x) & 0x00000000ff000000ull) << 8) \
  94. | (((x) & 0x0000000000ff0000ull) << 24) \
  95. | (((x) & 0x000000000000ff00ull) << 40) \
  96. | (((x) & 0x00000000000000ffull) << 56))
  97. # if __WORDSIZE == 64
  98. # define __bswap_64(x) \
  99. (__extension__ \
  100. ({ register unsigned long __v, __x = (x); \
  101. if (__builtin_constant_p (__x)) \
  102. __v = __bswap_constant_64 (__x); \
  103. else \
  104. __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); \
  105. __v; }))
  106. # else
  107. # define __bswap_64(x) \
  108. (__extension__ \
  109. ({ union { __extension__ unsigned long long int __ll; \
  110. unsigned int __l[2]; } __w, __r; \
  111. if (__builtin_constant_p (x)) \
  112. __r.__ll = __bswap_constant_64 (x); \
  113. else \
  114. { \
  115. __w.__ll = (x); \
  116. __r.__l[0] = __bswap_32 (__w.__l[1]); \
  117. __r.__l[1] = __bswap_32 (__w.__l[0]); \
  118. } \
  119. __r.__ll; }))
  120. # endif
  121. #endif
  122. #endif /* _BITS_BYTESWAP_H */