1#ifndef BSWAP_H
2#define BSWAP_H
3
4#include "fpu/softfloat.h"
5
6#ifdef CONFIG_MACHINE_BSWAP_H
7# include <sys/endian.h>
8# include <machine/bswap.h>
9#elif defined(__FreeBSD__)
10# include <sys/endian.h>
11#elif defined(CONFIG_BYTESWAP_H)
12# include <byteswap.h>
13
14static inline uint16_t bswap16(uint16_t x)
15{
16 return bswap_16(x);
17}
18
19static inline uint32_t bswap32(uint32_t x)
20{
21 return bswap_32(x);
22}
23
24static inline uint64_t bswap64(uint64_t x)
25{
26 return bswap_64(x);
27}
28# else
29static inline uint16_t bswap16(uint16_t x)
30{
31 return (((x & 0x00ff) << 8) |
32 ((x & 0xff00) >> 8));
33}
34
35static inline uint32_t bswap32(uint32_t x)
36{
37 return (((x & 0x000000ffU) << 24) |
38 ((x & 0x0000ff00U) << 8) |
39 ((x & 0x00ff0000U) >> 8) |
40 ((x & 0xff000000U) >> 24));
41}
42
43static inline uint64_t bswap64(uint64_t x)
44{
45 return (((x & 0x00000000000000ffULL) << 56) |
46 ((x & 0x000000000000ff00ULL) << 40) |
47 ((x & 0x0000000000ff0000ULL) << 24) |
48 ((x & 0x00000000ff000000ULL) << 8) |
49 ((x & 0x000000ff00000000ULL) >> 8) |
50 ((x & 0x0000ff0000000000ULL) >> 24) |
51 ((x & 0x00ff000000000000ULL) >> 40) |
52 ((x & 0xff00000000000000ULL) >> 56));
53}
54#endif
55
56static inline void bswap16s(uint16_t *s)
57{
58 *s = bswap16(*s);
59}
60
61static inline void bswap32s(uint32_t *s)
62{
63 *s = bswap32(*s);
64}
65
66static inline void bswap64s(uint64_t *s)
67{
68 *s = bswap64(*s);
69}
70
71#if defined(HOST_WORDS_BIGENDIAN)
72#define be_bswap(v, size) (v)
73#define le_bswap(v, size) glue(bswap, size)(v)
74#define be_bswaps(v, size)
75#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
76#else
77#define le_bswap(v, size) (v)
78#define be_bswap(v, size) glue(bswap, size)(v)
79#define le_bswaps(v, size)
80#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
81#endif
82
83#define CPU_CONVERT(endian, size, type)\
84static inline type endian ## size ## _to_cpu(type v)\
85{\
86 return glue(endian, _bswap)(v, size);\
87}\
88\
89static inline type cpu_to_ ## endian ## size(type v)\
90{\
91 return glue(endian, _bswap)(v, size);\
92}\
93\
94static inline void endian ## size ## _to_cpus(type *p)\
95{\
96 glue(endian, _bswaps)(p, size);\
97}\
98\
99static inline void cpu_to_ ## endian ## size ## s(type *p)\
100{\
101 glue(endian, _bswaps)(p, size);\
102}\
103\
104static inline type endian ## size ## _to_cpup(const type *p)\
105{\
106 return glue(glue(endian, size), _to_cpu)(*p);\
107}\
108\
109static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
110{\
111 *p = glue(glue(cpu_to_, endian), size)(v);\
112}
113
114CPU_CONVERT(be, 16, uint16_t)
115CPU_CONVERT(be, 32, uint32_t)
116CPU_CONVERT(be, 64, uint64_t)
117
118CPU_CONVERT(le, 16, uint16_t)
119CPU_CONVERT(le, 32, uint32_t)
120CPU_CONVERT(le, 64, uint64_t)
121
122
123static inline uint32_t qemu_bswap_len(uint32_t value, int len)
124{
125 return bswap32(value) >> (32 - 8 * len);
126}
127
128
129
130
131
132
133#if defined(HOST_WORDS_BIGENDIAN)
134# define const_le32(_x) \
135 ((((_x) & 0x000000ffU) << 24) | \
136 (((_x) & 0x0000ff00U) << 8) | \
137 (((_x) & 0x00ff0000U) >> 8) | \
138 (((_x) & 0xff000000U) >> 24))
139# define const_le16(_x) \
140 ((((_x) & 0x00ff) << 8) | \
141 (((_x) & 0xff00) >> 8))
142#else
143# define const_le32(_x) (_x)
144# define const_le16(_x) (_x)
145#endif
146
147
148
149typedef union {
150 float32 f;
151 uint32_t l;
152} CPU_FloatU;
153
154typedef union {
155 float64 d;
156#if defined(HOST_WORDS_BIGENDIAN)
157 struct {
158 uint32_t upper;
159 uint32_t lower;
160 } l;
161#else
162 struct {
163 uint32_t lower;
164 uint32_t upper;
165 } l;
166#endif
167 uint64_t ll;
168} CPU_DoubleU;
169
170typedef union {
171 floatx80 d;
172 struct {
173 uint64_t lower;
174 uint16_t upper;
175 } l;
176} CPU_LDoubleU;
177
178typedef union {
179 float128 q;
180#if defined(HOST_WORDS_BIGENDIAN)
181 struct {
182 uint32_t upmost;
183 uint32_t upper;
184 uint32_t lower;
185 uint32_t lowest;
186 } l;
187 struct {
188 uint64_t upper;
189 uint64_t lower;
190 } ll;
191#else
192 struct {
193 uint32_t lowest;
194 uint32_t lower;
195 uint32_t upper;
196 uint32_t upmost;
197 } l;
198 struct {
199 uint64_t lower;
200 uint64_t upper;
201 } ll;
202#endif
203} CPU_QuadU;
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247static inline int ldub_p(const void *ptr)
248{
249 return *(uint8_t *)ptr;
250}
251
252static inline int ldsb_p(const void *ptr)
253{
254 return *(int8_t *)ptr;
255}
256
257static inline void stb_p(void *ptr, uint8_t v)
258{
259 *(uint8_t *)ptr = v;
260}
261
262
263
264
265
266static inline int lduw_he_p(const void *ptr)
267{
268 uint16_t r;
269 memcpy(&r, ptr, sizeof(r));
270 return r;
271}
272
273static inline int ldsw_he_p(const void *ptr)
274{
275 int16_t r;
276 memcpy(&r, ptr, sizeof(r));
277 return r;
278}
279
280static inline void stw_he_p(void *ptr, uint16_t v)
281{
282 memcpy(ptr, &v, sizeof(v));
283}
284
285static inline int ldl_he_p(const void *ptr)
286{
287 int32_t r;
288 memcpy(&r, ptr, sizeof(r));
289 return r;
290}
291
292static inline void stl_he_p(void *ptr, uint32_t v)
293{
294 memcpy(ptr, &v, sizeof(v));
295}
296
297static inline uint64_t ldq_he_p(const void *ptr)
298{
299 uint64_t r;
300 memcpy(&r, ptr, sizeof(r));
301 return r;
302}
303
304static inline void stq_he_p(void *ptr, uint64_t v)
305{
306 memcpy(ptr, &v, sizeof(v));
307}
308
309static inline int lduw_le_p(const void *ptr)
310{
311 return (uint16_t)le_bswap(lduw_he_p(ptr), 16);
312}
313
314static inline int ldsw_le_p(const void *ptr)
315{
316 return (int16_t)le_bswap(lduw_he_p(ptr), 16);
317}
318
319static inline int ldl_le_p(const void *ptr)
320{
321 return le_bswap(ldl_he_p(ptr), 32);
322}
323
324static inline uint64_t ldq_le_p(const void *ptr)
325{
326 return le_bswap(ldq_he_p(ptr), 64);
327}
328
329static inline void stw_le_p(void *ptr, uint16_t v)
330{
331 stw_he_p(ptr, le_bswap(v, 16));
332}
333
334static inline void stl_le_p(void *ptr, uint32_t v)
335{
336 stl_he_p(ptr, le_bswap(v, 32));
337}
338
339static inline void stq_le_p(void *ptr, uint64_t v)
340{
341 stq_he_p(ptr, le_bswap(v, 64));
342}
343
344
345
346static inline float32 ldfl_le_p(const void *ptr)
347{
348 CPU_FloatU u;
349 u.l = ldl_le_p(ptr);
350 return u.f;
351}
352
353static inline void stfl_le_p(void *ptr, float32 v)
354{
355 CPU_FloatU u;
356 u.f = v;
357 stl_le_p(ptr, u.l);
358}
359
360static inline float64 ldfq_le_p(const void *ptr)
361{
362 CPU_DoubleU u;
363 u.ll = ldq_le_p(ptr);
364 return u.d;
365}
366
367static inline void stfq_le_p(void *ptr, float64 v)
368{
369 CPU_DoubleU u;
370 u.d = v;
371 stq_le_p(ptr, u.ll);
372}
373
374static inline int lduw_be_p(const void *ptr)
375{
376 return (uint16_t)be_bswap(lduw_he_p(ptr), 16);
377}
378
379static inline int ldsw_be_p(const void *ptr)
380{
381 return (int16_t)be_bswap(lduw_he_p(ptr), 16);
382}
383
384static inline int ldl_be_p(const void *ptr)
385{
386 return be_bswap(ldl_he_p(ptr), 32);
387}
388
389static inline uint64_t ldq_be_p(const void *ptr)
390{
391 return be_bswap(ldq_he_p(ptr), 64);
392}
393
394static inline void stw_be_p(void *ptr, uint16_t v)
395{
396 stw_he_p(ptr, be_bswap(v, 16));
397}
398
399static inline void stl_be_p(void *ptr, uint32_t v)
400{
401 stl_he_p(ptr, be_bswap(v, 32));
402}
403
404static inline void stq_be_p(void *ptr, uint64_t v)
405{
406 stq_he_p(ptr, be_bswap(v, 64));
407}
408
409
410
411static inline float32 ldfl_be_p(const void *ptr)
412{
413 CPU_FloatU u;
414 u.l = ldl_be_p(ptr);
415 return u.f;
416}
417
418static inline void stfl_be_p(void *ptr, float32 v)
419{
420 CPU_FloatU u;
421 u.f = v;
422 stl_be_p(ptr, u.l);
423}
424
425static inline float64 ldfq_be_p(const void *ptr)
426{
427 CPU_DoubleU u;
428 u.ll = ldq_be_p(ptr);
429 return u.d;
430}
431
432static inline void stfq_be_p(void *ptr, float64 v)
433{
434 CPU_DoubleU u;
435 u.d = v;
436 stq_be_p(ptr, u.ll);
437}
438
439static inline unsigned long leul_to_cpu(unsigned long v)
440{
441#if HOST_LONG_BITS == 32
442 return le_bswap(v, 32);
443#elif HOST_LONG_BITS == 64
444 return le_bswap(v, 64);
445#else
446# error Unknown sizeof long
447#endif
448}
449
450#undef le_bswap
451#undef be_bswap
452#undef le_bswaps
453#undef be_bswaps
454
455#endif
456