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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141#define CPU_CONVERT(endian, size, type)\
142static inline type endian ## size ## _to_cpu(type v)\
143{\
144 return glue(endian, _bswap)(v, size);\
145}\
146\
147static inline type cpu_to_ ## endian ## size(type v)\
148{\
149 return glue(endian, _bswap)(v, size);\
150}\
151\
152static inline void endian ## size ## _to_cpus(type *p)\
153{\
154 glue(endian, _bswaps)(p, size);\
155}\
156\
157static inline void cpu_to_ ## endian ## size ## s(type *p)\
158{\
159 glue(endian, _bswaps)(p, size);\
160}
161
162CPU_CONVERT(be, 16, uint16_t)
163CPU_CONVERT(be, 32, uint32_t)
164CPU_CONVERT(be, 64, uint64_t)
165
166CPU_CONVERT(le, 16, uint16_t)
167CPU_CONVERT(le, 32, uint32_t)
168CPU_CONVERT(le, 64, uint64_t)
169
170
171static inline uint32_t qemu_bswap_len(uint32_t value, int len)
172{
173 return bswap32(value) >> (32 - 8 * len);
174}
175
176
177
178
179
180
181#if defined(HOST_WORDS_BIGENDIAN)
182# define const_le32(_x) \
183 ((((_x) & 0x000000ffU) << 24) | \
184 (((_x) & 0x0000ff00U) << 8) | \
185 (((_x) & 0x00ff0000U) >> 8) | \
186 (((_x) & 0xff000000U) >> 24))
187# define const_le16(_x) \
188 ((((_x) & 0x00ff) << 8) | \
189 (((_x) & 0xff00) >> 8))
190#else
191# define const_le32(_x) (_x)
192# define const_le16(_x) (_x)
193#endif
194
195
196
197typedef union {
198 float32 f;
199 uint32_t l;
200} CPU_FloatU;
201
202typedef union {
203 float64 d;
204#if defined(HOST_WORDS_BIGENDIAN)
205 struct {
206 uint32_t upper;
207 uint32_t lower;
208 } l;
209#else
210 struct {
211 uint32_t lower;
212 uint32_t upper;
213 } l;
214#endif
215 uint64_t ll;
216} CPU_DoubleU;
217
218typedef union {
219 floatx80 d;
220 struct {
221 uint64_t lower;
222 uint16_t upper;
223 } l;
224} CPU_LDoubleU;
225
226typedef union {
227 float128 q;
228#if defined(HOST_WORDS_BIGENDIAN)
229 struct {
230 uint32_t upmost;
231 uint32_t upper;
232 uint32_t lower;
233 uint32_t lowest;
234 } l;
235 struct {
236 uint64_t upper;
237 uint64_t lower;
238 } ll;
239#else
240 struct {
241 uint32_t lowest;
242 uint32_t lower;
243 uint32_t upper;
244 uint32_t upmost;
245 } l;
246 struct {
247 uint64_t lower;
248 uint64_t upper;
249 } ll;
250#endif
251} CPU_QuadU;
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295static inline int ldub_p(const void *ptr)
296{
297 return *(uint8_t *)ptr;
298}
299
300static inline int ldsb_p(const void *ptr)
301{
302 return *(int8_t *)ptr;
303}
304
305static inline void stb_p(void *ptr, uint8_t v)
306{
307 *(uint8_t *)ptr = v;
308}
309
310
311
312
313
314static inline int lduw_he_p(const void *ptr)
315{
316 uint16_t r;
317 memcpy(&r, ptr, sizeof(r));
318 return r;
319}
320
321static inline int ldsw_he_p(const void *ptr)
322{
323 int16_t r;
324 memcpy(&r, ptr, sizeof(r));
325 return r;
326}
327
328static inline void stw_he_p(void *ptr, uint16_t v)
329{
330 memcpy(ptr, &v, sizeof(v));
331}
332
333static inline int ldl_he_p(const void *ptr)
334{
335 int32_t r;
336 memcpy(&r, ptr, sizeof(r));
337 return r;
338}
339
340static inline void stl_he_p(void *ptr, uint32_t v)
341{
342 memcpy(ptr, &v, sizeof(v));
343}
344
345static inline uint64_t ldq_he_p(const void *ptr)
346{
347 uint64_t r;
348 memcpy(&r, ptr, sizeof(r));
349 return r;
350}
351
352static inline void stq_he_p(void *ptr, uint64_t v)
353{
354 memcpy(ptr, &v, sizeof(v));
355}
356
357static inline int lduw_le_p(const void *ptr)
358{
359 return (uint16_t)le_bswap(lduw_he_p(ptr), 16);
360}
361
362static inline int ldsw_le_p(const void *ptr)
363{
364 return (int16_t)le_bswap(lduw_he_p(ptr), 16);
365}
366
367static inline int ldl_le_p(const void *ptr)
368{
369 return le_bswap(ldl_he_p(ptr), 32);
370}
371
372static inline uint64_t ldq_le_p(const void *ptr)
373{
374 return le_bswap(ldq_he_p(ptr), 64);
375}
376
377static inline void stw_le_p(void *ptr, uint16_t v)
378{
379 stw_he_p(ptr, le_bswap(v, 16));
380}
381
382static inline void stl_le_p(void *ptr, uint32_t v)
383{
384 stl_he_p(ptr, le_bswap(v, 32));
385}
386
387static inline void stq_le_p(void *ptr, uint64_t v)
388{
389 stq_he_p(ptr, le_bswap(v, 64));
390}
391
392
393
394static inline float32 ldfl_le_p(const void *ptr)
395{
396 CPU_FloatU u;
397 u.l = ldl_le_p(ptr);
398 return u.f;
399}
400
401static inline void stfl_le_p(void *ptr, float32 v)
402{
403 CPU_FloatU u;
404 u.f = v;
405 stl_le_p(ptr, u.l);
406}
407
408static inline float64 ldfq_le_p(const void *ptr)
409{
410 CPU_DoubleU u;
411 u.ll = ldq_le_p(ptr);
412 return u.d;
413}
414
415static inline void stfq_le_p(void *ptr, float64 v)
416{
417 CPU_DoubleU u;
418 u.d = v;
419 stq_le_p(ptr, u.ll);
420}
421
422static inline int lduw_be_p(const void *ptr)
423{
424 return (uint16_t)be_bswap(lduw_he_p(ptr), 16);
425}
426
427static inline int ldsw_be_p(const void *ptr)
428{
429 return (int16_t)be_bswap(lduw_he_p(ptr), 16);
430}
431
432static inline int ldl_be_p(const void *ptr)
433{
434 return be_bswap(ldl_he_p(ptr), 32);
435}
436
437static inline uint64_t ldq_be_p(const void *ptr)
438{
439 return be_bswap(ldq_he_p(ptr), 64);
440}
441
442static inline void stw_be_p(void *ptr, uint16_t v)
443{
444 stw_he_p(ptr, be_bswap(v, 16));
445}
446
447static inline void stl_be_p(void *ptr, uint32_t v)
448{
449 stl_he_p(ptr, be_bswap(v, 32));
450}
451
452static inline void stq_be_p(void *ptr, uint64_t v)
453{
454 stq_he_p(ptr, be_bswap(v, 64));
455}
456
457
458
459static inline float32 ldfl_be_p(const void *ptr)
460{
461 CPU_FloatU u;
462 u.l = ldl_be_p(ptr);
463 return u.f;
464}
465
466static inline void stfl_be_p(void *ptr, float32 v)
467{
468 CPU_FloatU u;
469 u.f = v;
470 stl_be_p(ptr, u.l);
471}
472
473static inline float64 ldfq_be_p(const void *ptr)
474{
475 CPU_DoubleU u;
476 u.ll = ldq_be_p(ptr);
477 return u.d;
478}
479
480static inline void stfq_be_p(void *ptr, float64 v)
481{
482 CPU_DoubleU u;
483 u.d = v;
484 stq_be_p(ptr, u.ll);
485}
486
487static inline unsigned long leul_to_cpu(unsigned long v)
488{
489#if HOST_LONG_BITS == 32
490 return le_bswap(v, 32);
491#elif HOST_LONG_BITS == 64
492 return le_bswap(v, 64);
493#else
494# error Unknown sizeof long
495#endif
496}
497
498#undef le_bswap
499#undef be_bswap
500#undef le_bswaps
501#undef be_bswaps
502
503#endif
504