1#ifndef _BYTESWAP_H 2#define _BYTESWAP_H 3 4#include <stdint.h> 5#include <klibc/endian.h> 6#include <klibc/compiler.h> 7 8/* This assumes an i386 platform */ 9 10#define __bswap_16_macro(v) ((uint16_t) \ 11 (((uint16_t)(v) << 8) | \ 12 ((uint16_t)(v) >> 8))) 13 14static inline __constfunc uint16_t __bswap_16(uint16_t v) 15{ 16 return __bswap_16_macro(v); 17} 18 19#define bswap_16(x) (__builtin_constant_p(x) ? \ 20 __bswap_16_macro(x) : __bswap_16(x)) 21 22#define __bswap_32_macro(v) ((uint32_t) \ 23 ((((uint32_t)(v) & 0x000000ff) << 24) | \ 24 (((uint32_t)(v) & 0x0000ff00) << 8) | \ 25 (((uint32_t)(v) & 0x00ff0000) >> 8) | \ 26 (((uint32_t)(v) & 0xff000000) >> 24))) 27 28static inline __constfunc uint32_t __bswap_32(uint32_t v) 29{ 30#if defined(__x86_64__) 31 asm("bswap %0" : "+r" (v)); 32#elif defined(__i386__) 33 asm("xchgb %h0,%b0 ; roll $16,%0 ; xchgb %h0,%b0" 34 : "+q" (v)); 35#else 36 v = __bswap_32_macro(v); 37#endif 38 return v; 39} 40 41#define bswap_32(x) (__builtin_constant_p(x) ? \ 42 __bswap_32_macro(x) : __bswap_32(x)) 43 44 45#define __bswap_64_macro(v) ((uint64_t) \ 46 (((uint64_t)__bswap_32_macro((uint32_t)(v)) << 32) | \ 47 (__bswap_32_macro((uint32_t)((uint64_t)(v) >> 32))))) 48 49static inline __constfunc uint64_t __bswap_64(uint64_t v) 50{ 51#if defined(__x86_64__) 52 asm("bswap %0" : "+r" (v)); 53#else 54 v = ((uint64_t)__bswap_32(v) << 32) | __bswap_32(v >> 32); 55#endif 56 return v; 57} 58 59#define bswap_64(x) (__builtin_constant_p(x) ? \ 60 __bswap_64_macro(x) : __bswap_64(x)) 61 62/* This is generic */ 63 64#if __BYTE_ORDER == __LITTLE_ENDIAN 65 66#define be16_to_cpu(x) bswap_16(x) 67#define cpu_to_be16(x) bswap_16(x) 68#define be32_to_cpu(x) bswap_32(x) 69#define cpu_to_be32(x) bswap_32(x) 70#define be64_to_cpu(x) bswap_64(x) 71#define cpu_to_be64(x) bswap_64(x) 72 73#define le16_to_cpu(x) (x) 74#define cpu_to_le16(x) (x) 75#define le32_to_cpu(x) (x) 76#define cpu_to_le32(x) (x) 77#define le64_to_cpu(x) (x) 78#define cpu_to_le64(x) (x) 79 80#elif __BYTE_ORDER == __BIG_ENDIAN 81 82#define le16_to_cpu(x) bswap_16(x) 83#define cpu_to_le16(x) bswap_16(x) 84#define le32_to_cpu(x) bswap_32(x) 85#define cpu_to_le32(x) bswap_32(x) 86#define le64_to_cpu(x) bswap_64(x) 87#define cpu_to_le64(x) bswap_64(x) 88 89#define be16_to_cpu(x) (x) 90#define cpu_to_be16(x) (x) 91#define be32_to_cpu(x) (x) 92#define cpu_to_be32(x) (x) 93#define be64_to_cpu(x) (x) 94#define cpu_to_be64(x) (x) 95 96#else 97 98#error "Unknown byte order!" 99 100#endif 101 102typedef struct { uint16_t x; } __attribute__((packed)) __ua_uint16_t; 103typedef struct { uint32_t x; } __attribute__((packed)) __ua_uint32_t; 104typedef struct { uint64_t x; } __attribute__((packed)) __ua_uint64_t; 105 106/* These are guaranteed to support unaligned accesses */ 107static inline uint16_t get_le16(const uint16_t *p) 108{ 109 const __ua_uint16_t *up = (const __ua_uint16_t *)p; 110 return le16_to_cpu(up->x); 111} 112 113static inline uint32_t get_le32(const uint32_t *p) 114{ 115 const __ua_uint32_t *up = (const __ua_uint32_t *)p; 116 return le32_to_cpu(up->x); 117} 118 119static inline uint64_t get_le64(const uint64_t *p) 120{ 121 const __ua_uint64_t *up = (const __ua_uint64_t *)p; 122 return le64_to_cpu(up->x); 123} 124 125static inline uint16_t get_be16(const uint16_t *p) 126{ 127 const __ua_uint16_t *up = (const __ua_uint16_t *)p; 128 return be16_to_cpu(up->x); 129} 130 131static inline uint32_t get_be32(const uint32_t *p) 132{ 133 const __ua_uint32_t *up = (const __ua_uint32_t *)p; 134 return be32_to_cpu(up->x); 135} 136 137static inline uint64_t get_be64(const uint64_t *p) 138{ 139 const __ua_uint64_t *up = (const __ua_uint64_t *)p; 140 return be64_to_cpu(up->x); 141} 142 143static inline void put_le16(uint16_t v, uint16_t *p) 144{ 145 __ua_uint16_t *up = (__ua_uint16_t *)p; 146 up->x = cpu_to_le16(v); 147} 148 149static inline void put_le32(uint32_t v, uint32_t *p) 150{ 151 __ua_uint32_t *up = (__ua_uint32_t *)p; 152 up->x = cpu_to_le32(v); 153} 154 155static inline void put_le64(uint64_t v, uint64_t *p) 156{ 157 __ua_uint64_t *up = (__ua_uint64_t *)p; 158 up->x = cpu_to_le64(v); 159} 160 161static inline void put_be16(uint16_t v, uint16_t *p) 162{ 163 __ua_uint16_t *up = (__ua_uint16_t *)p; 164 up->x = cpu_to_be16(v); 165} 166 167static inline void put_be32(uint32_t v, uint32_t *p) 168{ 169 __ua_uint32_t *up = (__ua_uint32_t *)p; 170 up->x = cpu_to_be32(v); 171} 172 173static inline void put_be64(uint64_t v, uint64_t *p) 174{ 175 __ua_uint64_t *up = (__ua_uint64_t *)p; 176 up->x = cpu_to_be64(v); 177} 178 179#endif /* _BYTESWAP_H */ 180 181