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