You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
3.8KB

  1. /*
  2. * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This 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. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. /**
  19. * @file bswap.h
  20. * byte swap.
  21. */
  22. #ifndef __BSWAP_H__
  23. #define __BSWAP_H__
  24. #ifdef HAVE_BYTESWAP_H
  25. #include <byteswap.h>
  26. #else
  27. #ifdef ARCH_X86_64
  28. # define LEGACY_REGS "=Q"
  29. #else
  30. # define LEGACY_REGS "=q"
  31. #endif
  32. #if defined(ARCH_X86) || defined(ARCH_X86_64)
  33. static always_inline uint16_t bswap_16(uint16_t x)
  34. {
  35. __asm("rorw $8, %0" :
  36. LEGACY_REGS (x) :
  37. "0" (x));
  38. return x;
  39. }
  40. static always_inline uint32_t bswap_32(uint32_t x)
  41. {
  42. #if __CPU__ != 386
  43. __asm("bswap %0":
  44. "=r" (x) :
  45. #else
  46. __asm("xchgb %b0,%h0\n"
  47. " rorl $16,%0\n"
  48. " xchgb %b0,%h0":
  49. LEGACY_REGS (x) :
  50. #endif
  51. "0" (x));
  52. return x;
  53. }
  54. static inline uint64_t bswap_64(uint64_t x)
  55. {
  56. #ifdef ARCH_X86_64
  57. __asm("bswap %0":
  58. "=r" (x) :
  59. "0" (x));
  60. return x;
  61. #else
  62. union {
  63. uint64_t ll;
  64. struct {
  65. uint32_t l,h;
  66. } l;
  67. } r;
  68. r.l.l = bswap_32 (x);
  69. r.l.h = bswap_32 (x>>32);
  70. return r.ll;
  71. #endif
  72. }
  73. #elif defined(ARCH_SH4)
  74. static always_inline uint16_t bswap_16(uint16_t x) {
  75. __asm__("swap.b %0,%0":"=r"(x):"0"(x));
  76. return x;
  77. }
  78. static always_inline uint32_t bswap_32(uint32_t x) {
  79. __asm__(
  80. "swap.b %0,%0\n"
  81. "swap.w %0,%0\n"
  82. "swap.b %0,%0\n"
  83. :"=r"(x):"0"(x));
  84. return x;
  85. }
  86. static inline uint64_t bswap_64(uint64_t x)
  87. {
  88. union {
  89. uint64_t ll;
  90. struct {
  91. uint32_t l,h;
  92. } l;
  93. } r;
  94. r.l.l = bswap_32 (x);
  95. r.l.h = bswap_32 (x>>32);
  96. return r.ll;
  97. }
  98. #else
  99. static always_inline uint16_t bswap_16(uint16_t x){
  100. return (x>>8) | (x<<8);
  101. }
  102. #ifdef ARCH_ARM
  103. static always_inline uint32_t bswap_32(uint32_t x){
  104. uint32_t t;
  105. __asm__ (
  106. "eor %1, %0, %0, ror #16 \n\t"
  107. "bic %1, %1, #0xFF0000 \n\t"
  108. "mov %0, %0, ror #8 \n\t"
  109. "eor %0, %0, %1, lsr #8 \n\t"
  110. : "+r"(x), "+r"(t));
  111. return x;
  112. }
  113. #else
  114. static always_inline uint32_t bswap_32(uint32_t x){
  115. x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
  116. return (x>>16) | (x<<16);
  117. }
  118. #endif
  119. static inline uint64_t bswap_64(uint64_t x)
  120. {
  121. #if 0
  122. x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL);
  123. x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL);
  124. return (x>>32) | (x<<32);
  125. #else
  126. union {
  127. uint64_t ll;
  128. uint32_t l[2];
  129. } w, r;
  130. w.ll = x;
  131. r.l[0] = bswap_32 (w.l[1]);
  132. r.l[1] = bswap_32 (w.l[0]);
  133. return r.ll;
  134. #endif
  135. }
  136. #endif /* !ARCH_X86 */
  137. #endif /* !HAVE_BYTESWAP_H */
  138. // be2me ... BigEndian to MachineEndian
  139. // le2me ... LittleEndian to MachineEndian
  140. #ifdef WORDS_BIGENDIAN
  141. #define be2me_16(x) (x)
  142. #define be2me_32(x) (x)
  143. #define be2me_64(x) (x)
  144. #define le2me_16(x) bswap_16(x)
  145. #define le2me_32(x) bswap_32(x)
  146. #define le2me_64(x) bswap_64(x)
  147. #else
  148. #define be2me_16(x) bswap_16(x)
  149. #define be2me_32(x) bswap_32(x)
  150. #define be2me_64(x) bswap_64(x)
  151. #define le2me_16(x) (x)
  152. #define le2me_32(x) (x)
  153. #define le2me_64(x) (x)
  154. #endif
  155. #endif /* __BSWAP_H__ */