1 #ifndef BSWAP_H
2 #define BSWAP_H
3
4 //#include "config-host.h"
5
6 #include <inttypes.h>
7
8 #if defined(__NetBSD__)
9 #include <sys/endian.h>
10 #include <sys/types.h>
11 #elif defined(__OpenBSD__)
12 #include <machine/endian.h>
13 #define bswap_16(x) swap16(x)
14 #define bswap_32(x) swap32(x)
15 #define bswap_64(x) swap64(x)
16 #elif defined(__linux__)
17
18 #include <endian.h>
19 #include <byteswap.h>
20
bswap16(uint16_t x)21 static inline uint16_t bswap16(uint16_t x)
22 {
23 return bswap_16(x);
24 }
25
bswap32(uint32_t x)26 static inline uint32_t bswap32(uint32_t x)
27 {
28 return bswap_32(x);
29 }
30
bswap64(uint64_t x)31 static inline uint64_t bswap64(uint64_t x)
32 {
33 return bswap_64(x);
34 }
35
bswap16s(uint16_t * s)36 static inline void bswap16s(uint16_t *s)
37 {
38 *s = bswap16(*s);
39 }
40
bswap32s(uint32_t * s)41 static inline void bswap32s(uint32_t *s)
42 {
43 *s = bswap32(*s);
44 }
45
bswap64s(uint64_t * s)46 static inline void bswap64s(uint64_t *s)
47 {
48 *s = bswap64(*s);
49 }
50
51 #endif
52
53 #if defined(WORDS_BIGENDIAN)
54 #define be_bswap(v, size) (v)
55 #define le_bswap(v, size) bswap ## size(v)
56 #define be_bswaps(v, size)
57 #define le_bswaps(p, size) *p = bswap ## size(*p);
58 #else
59 #define le_bswap(v, size) (v)
60 #define be_bswap(v, size) bswap ## size(v)
61 #define le_bswaps(v, size)
62 #define be_bswaps(p, size) *p = bswap ## size(*p);
63 #endif
64
65 #define CPU_CONVERT(endian, size, type)\
66 static inline type endian ## size ## _to_cpu(type v)\
67 {\
68 return endian ## _bswap(v, size);\
69 }\
70 \
71 static inline type cpu_to_ ## endian ## size(type v)\
72 {\
73 return endian ## _bswap(v, size);\
74 }\
75 \
76 static inline void endian ## size ## _to_cpus(type *p)\
77 {\
78 endian ## _bswaps(p, size)\
79 }\
80 \
81 static inline void cpu_to_ ## endian ## size ## s(type *p)\
82 {\
83 endian ## _bswaps(p, size)\
84 }\
85 \
86 static inline type endian ## size ## _to_cpup(const type *p)\
87 {\
88 return endian ## size ## _to_cpu(*p);\
89 }\
90 \
91 static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
92 {\
93 *p = cpu_to_ ## endian ## size(v);\
94 }
95
96 CPU_CONVERT(be, 16, uint16_t)
97 CPU_CONVERT(be, 32, uint32_t)
98 CPU_CONVERT(be, 64, uint64_t)
99
100 CPU_CONVERT(le, 16, uint16_t)
101 CPU_CONVERT(le, 32, uint32_t)
102 CPU_CONVERT(le, 64, uint64_t)
103
104 /* unaligned versions (optimized for frequent unaligned accesses)*/
105
106 #if defined(__i386__) || defined(__powerpc__)
107
108 #define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
109 #define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
110 #define le16_to_cpupu(p) le16_to_cpup(p)
111 #define le32_to_cpupu(p) le32_to_cpup(p)
112
113 #define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
114 #define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
115
116 #else
117
118 static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
119 {
120 uint8_t *p1 = (uint8_t *)p;
121
122 p1[0] = v;
123 p1[1] = v >> 8;
124 }
125
126 static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
127 {
128 uint8_t *p1 = (uint8_t *)p;
129
130 p1[0] = v;
131 p1[1] = v >> 8;
132 p1[2] = v >> 16;
133 p1[3] = v >> 24;
134 }
135
136 static inline uint16_t le16_to_cpupu(const uint16_t *p)
137 {
138 const uint8_t *p1 = (const uint8_t *)p;
139 return p1[0] | (p1[1] << 8);
140 }
141
142 static inline uint32_t le32_to_cpupu(const uint32_t *p)
143 {
144 const uint8_t *p1 = (const uint8_t *)p;
145 return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
146 }
147
148 static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
149 {
150 uint8_t *p1 = (uint8_t *)p;
151
152 p1[0] = v >> 8;
153 p1[1] = v;
154 }
155
156 static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
157 {
158 uint8_t *p1 = (uint8_t *)p;
159
160 p1[0] = v >> 24;
161 p1[1] = v >> 16;
162 p1[2] = v >> 8;
163 p1[3] = v;
164 }
165
166 #endif
167
168 #ifdef WORDS_BIGENDIAN
169 #define cpu_to_32wu cpu_to_be32wu
170 #else
171 #define cpu_to_32wu cpu_to_le32wu
172 #endif
173
174 #undef le_bswap
175 #undef be_bswap
176 #undef le_bswaps
177 #undef be_bswaps
178
179 #endif /* BSWAP_H */
180