bswap.h
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:3k
源码类别:

Windows CE

开发平台:

C/C++

  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,%h0n"
  30.       " rorl $16,%0n"
  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,%0n"
  64. "swap.w %0,%0n"
  65. "swap.b %0,%0n"
  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 (uint16_t)((x>>8) | (x<<8)); //Picard
  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 nt"
  90.       "bic %1, %1, #0xFF0000   nt"
  91.       "mov %0, %0, ror #8      nt"
  92.       "eor %0, %0, %1, lsr #8  nt"
  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__ */