00001
00006 #ifndef __BSWAP_H__
00007 #define __BSWAP_H__
00008
00009 #ifdef HAVE_BYTESWAP_H
00010 #include <byteswap.h>
00011 #else
00012
00013 #ifdef ARCH_X86_64
00014 # define LEGACY_REGS "=Q"
00015 #else
00016 # define LEGACY_REGS "=q"
00017 #endif
00018
00019 #if defined(ARCH_X86) || defined(ARCH_X86_64)
00020 static always_inline uint16_t bswap_16(uint16_t x)
00021 {
00022 __asm("rorw $8, %0" :
00023 LEGACY_REGS (x) :
00024 "0" (x));
00025 return x;
00026 }
00027
00028 static always_inline uint32_t bswap_32(uint32_t x)
00029 {
00030 #if __CPU__ > 386
00031 __asm("bswap %0":
00032 "=r" (x) :
00033 #else
00034 __asm("xchgb %b0,%h0\n"
00035 " rorl $16,%0\n"
00036 " xchgb %b0,%h0":
00037 LEGACY_REGS (x) :
00038 #endif
00039 "0" (x));
00040 return x;
00041 }
00042
00043 static inline uint64_t bswap_64(uint64_t x)
00044 {
00045 #ifdef ARCH_X86_64
00046 __asm("bswap %0":
00047 "=r" (x) :
00048 "0" (x));
00049 return x;
00050 #else
00051 union {
00052 uint64_t ll;
00053 struct {
00054 uint32_t l,h;
00055 } l;
00056 } r;
00057 r.l.l = bswap_32 (x);
00058 r.l.h = bswap_32 (x>>32);
00059 return r.ll;
00060 #endif
00061 }
00062
00063 #elif defined(ARCH_SH4)
00064
00065 static always_inline uint16_t bswap_16(uint16_t x) {
00066 __asm__("swap.b %0,%0":"=r"(x):"0"(x));
00067 return x;
00068 }
00069
00070 static always_inline uint32_t bswap_32(uint32_t x) {
00071 __asm__(
00072 "swap.b %0,%0\n"
00073 "swap.w %0,%0\n"
00074 "swap.b %0,%0\n"
00075 :"=r"(x):"0"(x));
00076 return x;
00077 }
00078
00079 static inline uint64_t bswap_64(uint64_t x)
00080 {
00081 union {
00082 uint64_t ll;
00083 struct {
00084 uint32_t l,h;
00085 } l;
00086 } r;
00087 r.l.l = bswap_32 (x);
00088 r.l.h = bswap_32 (x>>32);
00089 return r.ll;
00090 }
00091 #else
00092
00093 static always_inline uint16_t bswap_16(uint16_t x){
00094 return (x>>8) | (x<<8);
00095 }
00096
00097 #ifdef ARCH_ARM
00098 static always_inline uint32_t bswap_32(uint32_t x){
00099 uint32_t t;
00100 __asm__ (
00101 "eor %1, %0, %0, ror #16 \n\t"
00102 "bic %1, %1, #0xFF0000 \n\t"
00103 "mov %0, %0, ror #8 \n\t"
00104 "eor %0, %0, %1, lsr #8 \n\t"
00105 : "+r"(x), "+r"(t));
00106 return x;
00107 }
00108 #else
00109 static always_inline uint32_t bswap_32(uint32_t x){
00110 x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
00111 return (x>>16) | (x<<16);
00112 }
00113 #endif
00114
00115 static inline uint64_t bswap_64(uint64_t x)
00116 {
00117 #if 0
00118 x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL);
00119 x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL);
00120 return (x>>32) | (x<<32);
00121 #else
00122 union {
00123 uint64_t ll;
00124 uint32_t l[2];
00125 } w, r;
00126 w.ll = x;
00127 r.l[0] = bswap_32 (w.l[1]);
00128 r.l[1] = bswap_32 (w.l[0]);
00129 return r.ll;
00130 #endif
00131 }
00132 #endif
00133
00134 #endif
00135
00136
00137
00138
00139 #ifdef WORDS_BIGENDIAN
00140 #define be2me_16(x) (x)
00141 #define be2me_32(x) (x)
00142 #define be2me_64(x) (x)
00143 #define le2me_16(x) bswap_16(x)
00144 #define le2me_32(x) bswap_32(x)
00145 #define le2me_64(x) bswap_64(x)
00146 #else
00147 #define be2me_16(x) bswap_16(x)
00148 #define be2me_32(x) bswap_32(x)
00149 #define be2me_64(x) bswap_64(x)
00150 #define le2me_16(x) (x)
00151 #define le2me_32(x) (x)
00152 #define le2me_64(x) (x)
00153 #endif
00154
00155 #endif