bswap.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /**
  2. * @file bswap.h
  3. * byte swap.
  4. */
  5. #ifndef __BSWAP_H__
  6. #define __BSWAP_H__
  7. #ifdef HAVE_BYTESWAP_H
  8. #include <byteswap.h>
  9. #else
  10. #ifdef ARCH_X86_64
  11. # define LEGACY_REGS "=Q"
  12. #else
  13. # define LEGACY_REGS "=q"
  14. #endif
  15. #if defined(ARCH_X86) || defined(ARCH_X86_64)
  16. static always_inline uint16_t bswap_16(uint16_t x)
  17. {
  18. __asm("rorw $8, %0" :
  19. LEGACY_REGS (x) :
  20. "0" (x));
  21. return x;
  22. }
  23. static always_inline uint32_t bswap_32(uint32_t x)
  24. {
  25. #if __CPU__ != 386
  26. __asm("bswap %0":
  27. "=r" (x) :
  28. #else
  29. __asm("xchgb %b0,%h0\n"
  30. " rorl $16,%0\n"
  31. " xchgb %b0,%h0":
  32. LEGACY_REGS (x) :
  33. #endif
  34. "0" (x));
  35. return x;
  36. }
  37. static inline uint64_t bswap_64(uint64_t x)
  38. {
  39. #ifdef ARCH_X86_64
  40. __asm("bswap %0":
  41. "=r" (x) :
  42. "0" (x));
  43. return x;
  44. #else
  45. union {
  46. uint64_t ll;
  47. struct {
  48. uint32_t l,h;
  49. } l;
  50. } r;
  51. r.l.l = bswap_32 (x);
  52. r.l.h = bswap_32 (x>>32);
  53. return r.ll;
  54. #endif
  55. }
  56. #elif defined(ARCH_SH4)
  57. static always_inline uint16_t bswap_16(uint16_t x) {
  58. __asm__("swap.b %0,%0":"=r"(x):"0"(x));
  59. return x;
  60. }
  61. static always_inline uint32_t bswap_32(uint32_t x) {
  62. __asm__(
  63. "swap.b %0,%0\n"
  64. "swap.w %0,%0\n"
  65. "swap.b %0,%0\n"
  66. :"=r"(x):"0"(x));
  67. return x;
  68. }
  69. static inline uint64_t bswap_64(uint64_t x)
  70. {
  71. union {
  72. uint64_t ll;
  73. struct {
  74. uint32_t l,h;
  75. } l;
  76. } r;
  77. r.l.l = bswap_32 (x);
  78. r.l.h = bswap_32 (x>>32);
  79. return r.ll;
  80. }
  81. #else
  82. static always_inline uint16_t bswap_16(uint16_t x){
  83. return (x>>8) | (x<<8);
  84. }
  85. #ifdef ARCH_ARM
  86. static always_inline uint32_t bswap_32(uint32_t x){
  87. uint32_t t;
  88. __asm__ (
  89. "eor %1, %0, %0, ror #16 \n\t"
  90. "bic %1, %1, #0xFF0000 \n\t"
  91. "mov %0, %0, ror #8 \n\t"
  92. "eor %0, %0, %1, lsr #8 \n\t"
  93. : "+r"(x), "+r"(t));
  94. return x;
  95. }
  96. #else
  97. static always_inline uint32_t bswap_32(uint32_t x){
  98. x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
  99. return (x>>16) | (x<<16);
  100. }
  101. #endif
  102. static inline uint64_t bswap_64(uint64_t x)
  103. {
  104. #if 0
  105. x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL);
  106. x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL);
  107. return (x>>32) | (x<<32);
  108. #else
  109. union {
  110. uint64_t ll;
  111. uint32_t l[2];
  112. } w, r;
  113. w.ll = x;
  114. r.l[0] = bswap_32 (w.l[1]);
  115. r.l[1] = bswap_32 (w.l[0]);
  116. return r.ll;
  117. #endif
  118. }
  119. #endif /* !ARCH_X86 */
  120. #endif /* !HAVE_BYTESWAP_H */
  121. // be2me ... BigEndian to MachineEndian
  122. // le2me ... LittleEndian to MachineEndian
  123. #ifdef WORDS_BIGENDIAN
  124. #define be2me_16(x) (x)
  125. #define be2me_32(x) (x)
  126. #define be2me_64(x) (x)
  127. #define le2me_16(x) bswap_16(x)
  128. #define le2me_32(x) bswap_32(x)
  129. #define le2me_64(x) bswap_64(x)
  130. #else
  131. #define be2me_16(x) bswap_16(x)
  132. #define be2me_32(x) bswap_32(x)
  133. #define be2me_64(x) bswap_64(x)
  134. #define le2me_16(x) (x)
  135. #define le2me_32(x) (x)
  136. #define le2me_64(x) (x)
  137. #endif
  138. #endif /* __BSWAP_H__ */