00001 #ifndef BSWAP_H
00002 #define BSWAP_H
00003
00004 #include "config-host.h"
00005
00006 #include <inttypes.h>
00007
00008 #ifdef HAVE_MACHINE_BSWAP_H
00009 #include <sys/endian.h>
00010 #include <sys/types.h>
00011 #include <machine/bswap.h>
00012 #else
00013
00014 #ifdef HAVE_BYTESWAP_H
00015 #include <byteswap.h>
00016 #else
00017
00018 #define bswap_16(x) \
00019 ({ \
00020 uint16_t __x = (x); \
00021 ((uint16_t)( \
00022 (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
00023 (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
00024 })
00025
00026 #define bswap_32(x) \
00027 ({ \
00028 uint32_t __x = (x); \
00029 ((uint32_t)( \
00030 (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
00031 (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
00032 (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
00033 (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
00034 })
00035
00036 #define bswap_64(x) \
00037 ({ \
00038 uint64_t __x = (x); \
00039 ((uint64_t)( \
00040 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
00041 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
00042 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
00043 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
00044 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
00045 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
00046 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
00047 (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
00048 })
00049
00050 #endif
00051
00052 static inline uint16_t bswap16(uint16_t x)
00053 {
00054 return bswap_16(x);
00055 }
00056
00057 static inline uint32_t bswap32(uint32_t x)
00058 {
00059 return bswap_32(x);
00060 }
00061
00062 static inline uint64_t bswap64(uint64_t x)
00063 {
00064 return bswap_64(x);
00065 }
00066
00067 #endif
00068
00069 static inline void bswap16s(uint16_t *s)
00070 {
00071 *s = bswap16(*s);
00072 }
00073
00074 static inline void bswap32s(uint32_t *s)
00075 {
00076 *s = bswap32(*s);
00077 }
00078
00079 static inline void bswap64s(uint64_t *s)
00080 {
00081 *s = bswap64(*s);
00082 }
00083
00084 #if defined(WORDS_BIGENDIAN)
00085 #define be_bswap(v, size) (v)
00086 #define le_bswap(v, size) bswap ## size(v)
00087 #define be_bswaps(v, size)
00088 #define le_bswaps(p, size) *p = bswap ## size(*p);
00089 #else
00090 #define le_bswap(v, size) (v)
00091 #define be_bswap(v, size) bswap ## size(v)
00092 #define le_bswaps(v, size)
00093 #define be_bswaps(p, size) *p = bswap ## size(*p);
00094 #endif
00095
00096 #define CPU_CONVERT(endian, size, type)\
00097 static inline type endian ## size ## _to_cpu(type v)\
00098 {\
00099 return endian ## _bswap(v, size);\
00100 }\
00101 \
00102 static inline type cpu_to_ ## endian ## size(type v)\
00103 {\
00104 return endian ## _bswap(v, size);\
00105 }\
00106 \
00107 static inline void endian ## size ## _to_cpus(type *p)\
00108 {\
00109 endian ## _bswaps(p, size)\
00110 }\
00111 \
00112 static inline void cpu_to_ ## endian ## size ## s(type *p)\
00113 {\
00114 endian ## _bswaps(p, size)\
00115 }\
00116 \
00117 static inline type endian ## size ## _to_cpup(const type *p)\
00118 {\
00119 return endian ## size ## _to_cpu(*p);\
00120 }\
00121 \
00122 static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
00123 {\
00124 *p = cpu_to_ ## endian ## size(v);\
00125 }
00126
00127 CPU_CONVERT(be, 16, uint16_t)
00128 CPU_CONVERT(be, 32, uint32_t)
00129 CPU_CONVERT(be, 64, uint64_t)
00130
00131 CPU_CONVERT(le, 16, uint16_t)
00132 CPU_CONVERT(le, 32, uint32_t)
00133 CPU_CONVERT(le, 64, uint64_t)
00134
00135
00136
00137 #if defined(__i386__) || defined(_ARCH_PPC)
00138
00139 #define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
00140 #define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
00141 #define le16_to_cpupu(p) le16_to_cpup(p)
00142 #define le32_to_cpupu(p) le32_to_cpup(p)
00143 #define be32_to_cpupu(p) be32_to_cpup(p)
00144
00145 #define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
00146 #define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
00147
00148 #else
00149
00150 static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
00151 {
00152 uint8_t *p1 = (uint8_t *)p;
00153
00154 p1[0] = v;
00155 p1[1] = v >> 8;
00156 }
00157
00158 static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
00159 {
00160 uint8_t *p1 = (uint8_t *)p;
00161
00162 p1[0] = v;
00163 p1[1] = v >> 8;
00164 p1[2] = v >> 16;
00165 p1[3] = v >> 24;
00166 }
00167
00168 static inline uint16_t le16_to_cpupu(const uint16_t *p)
00169 {
00170 const uint8_t *p1 = (const uint8_t *)p;
00171 return p1[0] | (p1[1] << 8);
00172 }
00173
00174 static inline uint32_t le32_to_cpupu(const uint32_t *p)
00175 {
00176 const uint8_t *p1 = (const uint8_t *)p;
00177 return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
00178 }
00179
00180 static inline uint32_t be32_to_cpupu(const uint32_t *p)
00181 {
00182 const uint8_t *p1 = (const uint8_t *)p;
00183 return p1[3] | (p1[2] << 8) | (p1[1] << 16) | (p1[0] << 24);
00184 }
00185
00186 static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
00187 {
00188 uint8_t *p1 = (uint8_t *)p;
00189
00190 p1[0] = v >> 8;
00191 p1[1] = v;
00192 }
00193
00194 static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
00195 {
00196 uint8_t *p1 = (uint8_t *)p;
00197
00198 p1[0] = v >> 24;
00199 p1[1] = v >> 16;
00200 p1[2] = v >> 8;
00201 p1[3] = v;
00202 }
00203
00204 #endif
00205
00206 #ifdef WORDS_BIGENDIAN
00207 #define cpu_to_32wu cpu_to_be32wu
00208 #else
00209 #define cpu_to_32wu cpu_to_le32wu
00210 #endif
00211
00212 #undef le_bswap
00213 #undef be_bswap
00214 #undef le_bswaps
00215 #undef be_bswaps
00216
00217 #endif