Statistics
| Branch: | Revision:

root / bswap.h @ 957f1f99

History | View | Annotate | Download (13.9 kB)

1 ab93bbe2 bellard
#ifndef BSWAP_H
2 ab93bbe2 bellard
#define BSWAP_H
3 ab93bbe2 bellard
4 ab93bbe2 bellard
#include "config-host.h"
5 ab93bbe2 bellard
6 ab93bbe2 bellard
#include <inttypes.h>
7 ab93bbe2 bellard
8 5735147e Juan Quintela
#ifdef CONFIG_MACHINE_BSWAP_H
9 1360677c blueswir1
#include <sys/endian.h>
10 1360677c blueswir1
#include <sys/types.h>
11 1360677c blueswir1
#include <machine/bswap.h>
12 1360677c blueswir1
#else
13 1360677c blueswir1
14 cbbab922 Paolo Bonzini
#include "softfloat.h"
15 cbbab922 Paolo Bonzini
16 936dfb80 Juan Quintela
#ifdef CONFIG_BYTESWAP_H
17 ab93bbe2 bellard
#include <byteswap.h>
18 ab93bbe2 bellard
#else
19 ab93bbe2 bellard
20 ab93bbe2 bellard
#define bswap_16(x) \
21 ab93bbe2 bellard
({ \
22 ab93bbe2 bellard
        uint16_t __x = (x); \
23 ab93bbe2 bellard
        ((uint16_t)( \
24 ab93bbe2 bellard
                (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
25 ab93bbe2 bellard
                (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
26 ab93bbe2 bellard
})
27 ab93bbe2 bellard
28 ab93bbe2 bellard
#define bswap_32(x) \
29 ab93bbe2 bellard
({ \
30 ab93bbe2 bellard
        uint32_t __x = (x); \
31 ab93bbe2 bellard
        ((uint32_t)( \
32 ab93bbe2 bellard
                (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
33 ab93bbe2 bellard
                (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
34 ab93bbe2 bellard
                (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
35 ab93bbe2 bellard
                (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
36 ab93bbe2 bellard
})
37 ab93bbe2 bellard
38 ab93bbe2 bellard
#define bswap_64(x) \
39 ab93bbe2 bellard
({ \
40 ab93bbe2 bellard
        uint64_t __x = (x); \
41 ab93bbe2 bellard
        ((uint64_t)( \
42 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
43 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
44 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
45 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) <<  8) | \
46 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >>  8) | \
47 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
48 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
49 ab93bbe2 bellard
                (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
50 ab93bbe2 bellard
})
51 ab93bbe2 bellard
52 936dfb80 Juan Quintela
#endif /* !CONFIG_BYTESWAP_H */
53 ab93bbe2 bellard
54 ab93bbe2 bellard
static inline uint16_t bswap16(uint16_t x)
55 ab93bbe2 bellard
{
56 ab93bbe2 bellard
    return bswap_16(x);
57 ab93bbe2 bellard
}
58 ab93bbe2 bellard
59 5fafdf24 ths
static inline uint32_t bswap32(uint32_t x)
60 ab93bbe2 bellard
{
61 ab93bbe2 bellard
    return bswap_32(x);
62 ab93bbe2 bellard
}
63 ab93bbe2 bellard
64 5fafdf24 ths
static inline uint64_t bswap64(uint64_t x)
65 ab93bbe2 bellard
{
66 ab93bbe2 bellard
    return bswap_64(x);
67 ab93bbe2 bellard
}
68 ab93bbe2 bellard
69 5735147e Juan Quintela
#endif /* ! CONFIG_MACHINE_BSWAP_H */
70 1360677c blueswir1
71 ab93bbe2 bellard
static inline void bswap16s(uint16_t *s)
72 ab93bbe2 bellard
{
73 ab93bbe2 bellard
    *s = bswap16(*s);
74 ab93bbe2 bellard
}
75 ab93bbe2 bellard
76 ab93bbe2 bellard
static inline void bswap32s(uint32_t *s)
77 ab93bbe2 bellard
{
78 ab93bbe2 bellard
    *s = bswap32(*s);
79 ab93bbe2 bellard
}
80 ab93bbe2 bellard
81 ab93bbe2 bellard
static inline void bswap64s(uint64_t *s)
82 ab93bbe2 bellard
{
83 ab93bbe2 bellard
    *s = bswap64(*s);
84 ab93bbe2 bellard
}
85 ab93bbe2 bellard
86 e2542fe2 Juan Quintela
#if defined(HOST_WORDS_BIGENDIAN)
87 af8ffdfd bellard
#define be_bswap(v, size) (v)
88 af8ffdfd bellard
#define le_bswap(v, size) bswap ## size(v)
89 af8ffdfd bellard
#define be_bswaps(v, size)
90 af8ffdfd bellard
#define le_bswaps(p, size) *p = bswap ## size(*p);
91 af8ffdfd bellard
#else
92 af8ffdfd bellard
#define le_bswap(v, size) (v)
93 af8ffdfd bellard
#define be_bswap(v, size) bswap ## size(v)
94 af8ffdfd bellard
#define le_bswaps(v, size)
95 af8ffdfd bellard
#define be_bswaps(p, size) *p = bswap ## size(*p);
96 af8ffdfd bellard
#endif
97 af8ffdfd bellard
98 af8ffdfd bellard
#define CPU_CONVERT(endian, size, type)\
99 af8ffdfd bellard
static inline type endian ## size ## _to_cpu(type v)\
100 af8ffdfd bellard
{\
101 af8ffdfd bellard
    return endian ## _bswap(v, size);\
102 af8ffdfd bellard
}\
103 af8ffdfd bellard
\
104 af8ffdfd bellard
static inline type cpu_to_ ## endian ## size(type v)\
105 af8ffdfd bellard
{\
106 af8ffdfd bellard
    return endian ## _bswap(v, size);\
107 af8ffdfd bellard
}\
108 af8ffdfd bellard
\
109 af8ffdfd bellard
static inline void endian ## size ## _to_cpus(type *p)\
110 af8ffdfd bellard
{\
111 af8ffdfd bellard
    endian ## _bswaps(p, size)\
112 af8ffdfd bellard
}\
113 af8ffdfd bellard
\
114 af8ffdfd bellard
static inline void cpu_to_ ## endian ## size ## s(type *p)\
115 af8ffdfd bellard
{\
116 af8ffdfd bellard
    endian ## _bswaps(p, size)\
117 af8ffdfd bellard
}\
118 af8ffdfd bellard
\
119 af8ffdfd bellard
static inline type endian ## size ## _to_cpup(const type *p)\
120 af8ffdfd bellard
{\
121 af8ffdfd bellard
    return endian ## size ## _to_cpu(*p);\
122 af8ffdfd bellard
}\
123 af8ffdfd bellard
\
124 af8ffdfd bellard
static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
125 af8ffdfd bellard
{\
126 af8ffdfd bellard
     *p = cpu_to_ ## endian ## size(v);\
127 af8ffdfd bellard
}
128 af8ffdfd bellard
129 af8ffdfd bellard
CPU_CONVERT(be, 16, uint16_t)
130 af8ffdfd bellard
CPU_CONVERT(be, 32, uint32_t)
131 af8ffdfd bellard
CPU_CONVERT(be, 64, uint64_t)
132 af8ffdfd bellard
133 af8ffdfd bellard
CPU_CONVERT(le, 16, uint16_t)
134 af8ffdfd bellard
CPU_CONVERT(le, 32, uint32_t)
135 af8ffdfd bellard
CPU_CONVERT(le, 64, uint64_t)
136 af8ffdfd bellard
137 af8ffdfd bellard
/* unaligned versions (optimized for frequent unaligned accesses)*/
138 af8ffdfd bellard
139 e58ffeb3 malc
#if defined(__i386__) || defined(_ARCH_PPC)
140 af8ffdfd bellard
141 af8ffdfd bellard
#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
142 af8ffdfd bellard
#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
143 af8ffdfd bellard
#define le16_to_cpupu(p) le16_to_cpup(p)
144 af8ffdfd bellard
#define le32_to_cpupu(p) le32_to_cpup(p)
145 88738c09 aurel32
#define be32_to_cpupu(p) be32_to_cpup(p)
146 af8ffdfd bellard
147 188d8579 bellard
#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
148 188d8579 bellard
#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
149 102c2976 Aurelien Jarno
#define cpu_to_be64wu(p, v) cpu_to_be64w(p, v)
150 188d8579 bellard
151 af8ffdfd bellard
#else
152 af8ffdfd bellard
153 af8ffdfd bellard
static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
154 af8ffdfd bellard
{
155 af8ffdfd bellard
    uint8_t *p1 = (uint8_t *)p;
156 af8ffdfd bellard
157 9e622b15 blueswir1
    p1[0] = v & 0xff;
158 af8ffdfd bellard
    p1[1] = v >> 8;
159 af8ffdfd bellard
}
160 af8ffdfd bellard
161 af8ffdfd bellard
static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
162 af8ffdfd bellard
{
163 af8ffdfd bellard
    uint8_t *p1 = (uint8_t *)p;
164 af8ffdfd bellard
165 9e622b15 blueswir1
    p1[0] = v & 0xff;
166 af8ffdfd bellard
    p1[1] = v >> 8;
167 af8ffdfd bellard
    p1[2] = v >> 16;
168 af8ffdfd bellard
    p1[3] = v >> 24;
169 af8ffdfd bellard
}
170 af8ffdfd bellard
171 af8ffdfd bellard
static inline uint16_t le16_to_cpupu(const uint16_t *p)
172 af8ffdfd bellard
{
173 af8ffdfd bellard
    const uint8_t *p1 = (const uint8_t *)p;
174 af8ffdfd bellard
    return p1[0] | (p1[1] << 8);
175 af8ffdfd bellard
}
176 af8ffdfd bellard
177 af8ffdfd bellard
static inline uint32_t le32_to_cpupu(const uint32_t *p)
178 af8ffdfd bellard
{
179 af8ffdfd bellard
    const uint8_t *p1 = (const uint8_t *)p;
180 af8ffdfd bellard
    return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
181 af8ffdfd bellard
}
182 af8ffdfd bellard
183 88738c09 aurel32
static inline uint32_t be32_to_cpupu(const uint32_t *p)
184 88738c09 aurel32
{
185 88738c09 aurel32
    const uint8_t *p1 = (const uint8_t *)p;
186 88738c09 aurel32
    return p1[3] | (p1[2] << 8) | (p1[1] << 16) | (p1[0] << 24);
187 88738c09 aurel32
}
188 88738c09 aurel32
189 188d8579 bellard
static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
190 188d8579 bellard
{
191 188d8579 bellard
    uint8_t *p1 = (uint8_t *)p;
192 188d8579 bellard
193 188d8579 bellard
    p1[0] = v >> 8;
194 9e622b15 blueswir1
    p1[1] = v & 0xff;
195 188d8579 bellard
}
196 188d8579 bellard
197 188d8579 bellard
static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
198 188d8579 bellard
{
199 188d8579 bellard
    uint8_t *p1 = (uint8_t *)p;
200 188d8579 bellard
201 188d8579 bellard
    p1[0] = v >> 24;
202 188d8579 bellard
    p1[1] = v >> 16;
203 188d8579 bellard
    p1[2] = v >> 8;
204 9e622b15 blueswir1
    p1[3] = v & 0xff;
205 188d8579 bellard
}
206 188d8579 bellard
207 102c2976 Aurelien Jarno
static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
208 102c2976 Aurelien Jarno
{
209 102c2976 Aurelien Jarno
    uint8_t *p1 = (uint8_t *)p;
210 102c2976 Aurelien Jarno
211 102c2976 Aurelien Jarno
    p1[0] = v >> 56;
212 102c2976 Aurelien Jarno
    p1[1] = v >> 48;
213 102c2976 Aurelien Jarno
    p1[2] = v >> 40;
214 102c2976 Aurelien Jarno
    p1[3] = v >> 32;
215 102c2976 Aurelien Jarno
    p1[4] = v >> 24;
216 102c2976 Aurelien Jarno
    p1[5] = v >> 16;
217 102c2976 Aurelien Jarno
    p1[6] = v >> 8;
218 102c2976 Aurelien Jarno
    p1[7] = v & 0xff;
219 102c2976 Aurelien Jarno
}
220 102c2976 Aurelien Jarno
221 188d8579 bellard
#endif
222 188d8579 bellard
223 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
224 188d8579 bellard
#define cpu_to_32wu cpu_to_be32wu
225 17e6a53f Alexander Graf
#define leul_to_cpu(v) glue(glue(le,HOST_LONG_BITS),_to_cpu)(v)
226 188d8579 bellard
#else
227 188d8579 bellard
#define cpu_to_32wu cpu_to_le32wu
228 213acd2e Marcelo Tosatti
#define leul_to_cpu(v) (v)
229 af8ffdfd bellard
#endif
230 af8ffdfd bellard
231 af8ffdfd bellard
#undef le_bswap
232 af8ffdfd bellard
#undef be_bswap
233 af8ffdfd bellard
#undef le_bswaps
234 af8ffdfd bellard
#undef be_bswaps
235 af8ffdfd bellard
236 e73d6e3a Michael S. Tsirkin
/* len must be one of 1, 2, 4 */
237 e73d6e3a Michael S. Tsirkin
static inline uint32_t qemu_bswap_len(uint32_t value, int len)
238 e73d6e3a Michael S. Tsirkin
{
239 e73d6e3a Michael S. Tsirkin
    return bswap32(value) >> (32 - 8 * len);
240 e73d6e3a Michael S. Tsirkin
}
241 e73d6e3a Michael S. Tsirkin
242 cbbab922 Paolo Bonzini
typedef union {
243 cbbab922 Paolo Bonzini
    float32 f;
244 cbbab922 Paolo Bonzini
    uint32_t l;
245 cbbab922 Paolo Bonzini
} CPU_FloatU;
246 cbbab922 Paolo Bonzini
247 cbbab922 Paolo Bonzini
typedef union {
248 cbbab922 Paolo Bonzini
    float64 d;
249 cbbab922 Paolo Bonzini
#if defined(HOST_WORDS_BIGENDIAN)
250 cbbab922 Paolo Bonzini
    struct {
251 cbbab922 Paolo Bonzini
        uint32_t upper;
252 cbbab922 Paolo Bonzini
        uint32_t lower;
253 cbbab922 Paolo Bonzini
    } l;
254 cbbab922 Paolo Bonzini
#else
255 cbbab922 Paolo Bonzini
    struct {
256 cbbab922 Paolo Bonzini
        uint32_t lower;
257 cbbab922 Paolo Bonzini
        uint32_t upper;
258 cbbab922 Paolo Bonzini
    } l;
259 cbbab922 Paolo Bonzini
#endif
260 cbbab922 Paolo Bonzini
    uint64_t ll;
261 cbbab922 Paolo Bonzini
} CPU_DoubleU;
262 cbbab922 Paolo Bonzini
263 cbbab922 Paolo Bonzini
typedef union {
264 cbbab922 Paolo Bonzini
     floatx80 d;
265 cbbab922 Paolo Bonzini
     struct {
266 cbbab922 Paolo Bonzini
         uint64_t lower;
267 cbbab922 Paolo Bonzini
         uint16_t upper;
268 cbbab922 Paolo Bonzini
     } l;
269 cbbab922 Paolo Bonzini
} CPU_LDoubleU;
270 cbbab922 Paolo Bonzini
271 cbbab922 Paolo Bonzini
typedef union {
272 cbbab922 Paolo Bonzini
    float128 q;
273 cbbab922 Paolo Bonzini
#if defined(HOST_WORDS_BIGENDIAN)
274 cbbab922 Paolo Bonzini
    struct {
275 cbbab922 Paolo Bonzini
        uint32_t upmost;
276 cbbab922 Paolo Bonzini
        uint32_t upper;
277 cbbab922 Paolo Bonzini
        uint32_t lower;
278 cbbab922 Paolo Bonzini
        uint32_t lowest;
279 cbbab922 Paolo Bonzini
    } l;
280 cbbab922 Paolo Bonzini
    struct {
281 cbbab922 Paolo Bonzini
        uint64_t upper;
282 cbbab922 Paolo Bonzini
        uint64_t lower;
283 cbbab922 Paolo Bonzini
    } ll;
284 cbbab922 Paolo Bonzini
#else
285 cbbab922 Paolo Bonzini
    struct {
286 cbbab922 Paolo Bonzini
        uint32_t lowest;
287 cbbab922 Paolo Bonzini
        uint32_t lower;
288 cbbab922 Paolo Bonzini
        uint32_t upper;
289 cbbab922 Paolo Bonzini
        uint32_t upmost;
290 cbbab922 Paolo Bonzini
    } l;
291 cbbab922 Paolo Bonzini
    struct {
292 cbbab922 Paolo Bonzini
        uint64_t lower;
293 cbbab922 Paolo Bonzini
        uint64_t upper;
294 cbbab922 Paolo Bonzini
    } ll;
295 cbbab922 Paolo Bonzini
#endif
296 cbbab922 Paolo Bonzini
} CPU_QuadU;
297 cbbab922 Paolo Bonzini
298 cbbab922 Paolo Bonzini
/* unaligned/endian-independent pointer access */
299 cbbab922 Paolo Bonzini
300 cbbab922 Paolo Bonzini
/*
301 cbbab922 Paolo Bonzini
 * the generic syntax is:
302 cbbab922 Paolo Bonzini
 *
303 cbbab922 Paolo Bonzini
 * load: ld{type}{sign}{size}{endian}_p(ptr)
304 cbbab922 Paolo Bonzini
 *
305 cbbab922 Paolo Bonzini
 * store: st{type}{size}{endian}_p(ptr, val)
306 cbbab922 Paolo Bonzini
 *
307 cbbab922 Paolo Bonzini
 * Note there are small differences with the softmmu access API!
308 cbbab922 Paolo Bonzini
 *
309 cbbab922 Paolo Bonzini
 * type is:
310 cbbab922 Paolo Bonzini
 * (empty): integer access
311 cbbab922 Paolo Bonzini
 *   f    : float access
312 cbbab922 Paolo Bonzini
 *
313 cbbab922 Paolo Bonzini
 * sign is:
314 cbbab922 Paolo Bonzini
 * (empty): for floats or 32 bit size
315 cbbab922 Paolo Bonzini
 *   u    : unsigned
316 cbbab922 Paolo Bonzini
 *   s    : signed
317 cbbab922 Paolo Bonzini
 *
318 cbbab922 Paolo Bonzini
 * size is:
319 cbbab922 Paolo Bonzini
 *   b: 8 bits
320 cbbab922 Paolo Bonzini
 *   w: 16 bits
321 cbbab922 Paolo Bonzini
 *   l: 32 bits
322 cbbab922 Paolo Bonzini
 *   q: 64 bits
323 cbbab922 Paolo Bonzini
 *
324 cbbab922 Paolo Bonzini
 * endian is:
325 cbbab922 Paolo Bonzini
 * (empty): 8 bit access
326 cbbab922 Paolo Bonzini
 *   be   : big endian
327 cbbab922 Paolo Bonzini
 *   le   : little endian
328 cbbab922 Paolo Bonzini
 */
329 cbbab922 Paolo Bonzini
static inline int ldub_p(const void *ptr)
330 cbbab922 Paolo Bonzini
{
331 cbbab922 Paolo Bonzini
    return *(uint8_t *)ptr;
332 cbbab922 Paolo Bonzini
}
333 cbbab922 Paolo Bonzini
334 cbbab922 Paolo Bonzini
static inline int ldsb_p(const void *ptr)
335 cbbab922 Paolo Bonzini
{
336 cbbab922 Paolo Bonzini
    return *(int8_t *)ptr;
337 cbbab922 Paolo Bonzini
}
338 cbbab922 Paolo Bonzini
339 cbbab922 Paolo Bonzini
static inline void stb_p(void *ptr, int v)
340 cbbab922 Paolo Bonzini
{
341 cbbab922 Paolo Bonzini
    *(uint8_t *)ptr = v;
342 cbbab922 Paolo Bonzini
}
343 cbbab922 Paolo Bonzini
344 cbbab922 Paolo Bonzini
/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
345 cbbab922 Paolo Bonzini
   kernel handles unaligned load/stores may give better results, but
346 cbbab922 Paolo Bonzini
   it is a system wide setting : bad */
347 cbbab922 Paolo Bonzini
#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
348 cbbab922 Paolo Bonzini
349 cbbab922 Paolo Bonzini
/* conservative code for little endian unaligned accesses */
350 cbbab922 Paolo Bonzini
static inline int lduw_le_p(const void *ptr)
351 cbbab922 Paolo Bonzini
{
352 cbbab922 Paolo Bonzini
#ifdef _ARCH_PPC
353 cbbab922 Paolo Bonzini
    int val;
354 cbbab922 Paolo Bonzini
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
355 cbbab922 Paolo Bonzini
    return val;
356 cbbab922 Paolo Bonzini
#else
357 cbbab922 Paolo Bonzini
    const uint8_t *p = ptr;
358 cbbab922 Paolo Bonzini
    return p[0] | (p[1] << 8);
359 cbbab922 Paolo Bonzini
#endif
360 cbbab922 Paolo Bonzini
}
361 cbbab922 Paolo Bonzini
362 cbbab922 Paolo Bonzini
static inline int ldsw_le_p(const void *ptr)
363 cbbab922 Paolo Bonzini
{
364 cbbab922 Paolo Bonzini
#ifdef _ARCH_PPC
365 cbbab922 Paolo Bonzini
    int val;
366 cbbab922 Paolo Bonzini
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
367 cbbab922 Paolo Bonzini
    return (int16_t)val;
368 cbbab922 Paolo Bonzini
#else
369 cbbab922 Paolo Bonzini
    const uint8_t *p = ptr;
370 cbbab922 Paolo Bonzini
    return (int16_t)(p[0] | (p[1] << 8));
371 cbbab922 Paolo Bonzini
#endif
372 cbbab922 Paolo Bonzini
}
373 cbbab922 Paolo Bonzini
374 cbbab922 Paolo Bonzini
static inline int ldl_le_p(const void *ptr)
375 cbbab922 Paolo Bonzini
{
376 cbbab922 Paolo Bonzini
#ifdef _ARCH_PPC
377 cbbab922 Paolo Bonzini
    int val;
378 cbbab922 Paolo Bonzini
    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
379 cbbab922 Paolo Bonzini
    return val;
380 cbbab922 Paolo Bonzini
#else
381 cbbab922 Paolo Bonzini
    const uint8_t *p = ptr;
382 cbbab922 Paolo Bonzini
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
383 cbbab922 Paolo Bonzini
#endif
384 cbbab922 Paolo Bonzini
}
385 cbbab922 Paolo Bonzini
386 cbbab922 Paolo Bonzini
static inline uint64_t ldq_le_p(const void *ptr)
387 cbbab922 Paolo Bonzini
{
388 cbbab922 Paolo Bonzini
    const uint8_t *p = ptr;
389 cbbab922 Paolo Bonzini
    uint32_t v1, v2;
390 cbbab922 Paolo Bonzini
    v1 = ldl_le_p(p);
391 cbbab922 Paolo Bonzini
    v2 = ldl_le_p(p + 4);
392 cbbab922 Paolo Bonzini
    return v1 | ((uint64_t)v2 << 32);
393 cbbab922 Paolo Bonzini
}
394 cbbab922 Paolo Bonzini
395 cbbab922 Paolo Bonzini
static inline void stw_le_p(void *ptr, int v)
396 cbbab922 Paolo Bonzini
{
397 cbbab922 Paolo Bonzini
#ifdef _ARCH_PPC
398 cbbab922 Paolo Bonzini
    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
399 cbbab922 Paolo Bonzini
#else
400 cbbab922 Paolo Bonzini
    uint8_t *p = ptr;
401 cbbab922 Paolo Bonzini
    p[0] = v;
402 cbbab922 Paolo Bonzini
    p[1] = v >> 8;
403 cbbab922 Paolo Bonzini
#endif
404 cbbab922 Paolo Bonzini
}
405 cbbab922 Paolo Bonzini
406 cbbab922 Paolo Bonzini
static inline void stl_le_p(void *ptr, int v)
407 cbbab922 Paolo Bonzini
{
408 cbbab922 Paolo Bonzini
#ifdef _ARCH_PPC
409 cbbab922 Paolo Bonzini
    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
410 cbbab922 Paolo Bonzini
#else
411 cbbab922 Paolo Bonzini
    uint8_t *p = ptr;
412 cbbab922 Paolo Bonzini
    p[0] = v;
413 cbbab922 Paolo Bonzini
    p[1] = v >> 8;
414 cbbab922 Paolo Bonzini
    p[2] = v >> 16;
415 cbbab922 Paolo Bonzini
    p[3] = v >> 24;
416 cbbab922 Paolo Bonzini
#endif
417 cbbab922 Paolo Bonzini
}
418 cbbab922 Paolo Bonzini
419 cbbab922 Paolo Bonzini
static inline void stq_le_p(void *ptr, uint64_t v)
420 cbbab922 Paolo Bonzini
{
421 cbbab922 Paolo Bonzini
    uint8_t *p = ptr;
422 cbbab922 Paolo Bonzini
    stl_le_p(p, (uint32_t)v);
423 cbbab922 Paolo Bonzini
    stl_le_p(p + 4, v >> 32);
424 cbbab922 Paolo Bonzini
}
425 cbbab922 Paolo Bonzini
426 cbbab922 Paolo Bonzini
/* float access */
427 cbbab922 Paolo Bonzini
428 cbbab922 Paolo Bonzini
static inline float32 ldfl_le_p(const void *ptr)
429 cbbab922 Paolo Bonzini
{
430 cbbab922 Paolo Bonzini
    union {
431 cbbab922 Paolo Bonzini
        float32 f;
432 cbbab922 Paolo Bonzini
        uint32_t i;
433 cbbab922 Paolo Bonzini
    } u;
434 cbbab922 Paolo Bonzini
    u.i = ldl_le_p(ptr);
435 cbbab922 Paolo Bonzini
    return u.f;
436 cbbab922 Paolo Bonzini
}
437 cbbab922 Paolo Bonzini
438 cbbab922 Paolo Bonzini
static inline void stfl_le_p(void *ptr, float32 v)
439 cbbab922 Paolo Bonzini
{
440 cbbab922 Paolo Bonzini
    union {
441 cbbab922 Paolo Bonzini
        float32 f;
442 cbbab922 Paolo Bonzini
        uint32_t i;
443 cbbab922 Paolo Bonzini
    } u;
444 cbbab922 Paolo Bonzini
    u.f = v;
445 cbbab922 Paolo Bonzini
    stl_le_p(ptr, u.i);
446 cbbab922 Paolo Bonzini
}
447 cbbab922 Paolo Bonzini
448 cbbab922 Paolo Bonzini
static inline float64 ldfq_le_p(const void *ptr)
449 cbbab922 Paolo Bonzini
{
450 cbbab922 Paolo Bonzini
    CPU_DoubleU u;
451 cbbab922 Paolo Bonzini
    u.l.lower = ldl_le_p(ptr);
452 cbbab922 Paolo Bonzini
    u.l.upper = ldl_le_p(ptr + 4);
453 cbbab922 Paolo Bonzini
    return u.d;
454 cbbab922 Paolo Bonzini
}
455 cbbab922 Paolo Bonzini
456 cbbab922 Paolo Bonzini
static inline void stfq_le_p(void *ptr, float64 v)
457 cbbab922 Paolo Bonzini
{
458 cbbab922 Paolo Bonzini
    CPU_DoubleU u;
459 cbbab922 Paolo Bonzini
    u.d = v;
460 cbbab922 Paolo Bonzini
    stl_le_p(ptr, u.l.lower);
461 cbbab922 Paolo Bonzini
    stl_le_p(ptr + 4, u.l.upper);
462 cbbab922 Paolo Bonzini
}
463 cbbab922 Paolo Bonzini
464 cbbab922 Paolo Bonzini
#else
465 cbbab922 Paolo Bonzini
466 cbbab922 Paolo Bonzini
static inline int lduw_le_p(const void *ptr)
467 cbbab922 Paolo Bonzini
{
468 cbbab922 Paolo Bonzini
    return *(uint16_t *)ptr;
469 cbbab922 Paolo Bonzini
}
470 cbbab922 Paolo Bonzini
471 cbbab922 Paolo Bonzini
static inline int ldsw_le_p(const void *ptr)
472 cbbab922 Paolo Bonzini
{
473 cbbab922 Paolo Bonzini
    return *(int16_t *)ptr;
474 cbbab922 Paolo Bonzini
}
475 cbbab922 Paolo Bonzini
476 cbbab922 Paolo Bonzini
static inline int ldl_le_p(const void *ptr)
477 cbbab922 Paolo Bonzini
{
478 cbbab922 Paolo Bonzini
    return *(uint32_t *)ptr;
479 cbbab922 Paolo Bonzini
}
480 cbbab922 Paolo Bonzini
481 cbbab922 Paolo Bonzini
static inline uint64_t ldq_le_p(const void *ptr)
482 cbbab922 Paolo Bonzini
{
483 cbbab922 Paolo Bonzini
    return *(uint64_t *)ptr;
484 cbbab922 Paolo Bonzini
}
485 cbbab922 Paolo Bonzini
486 cbbab922 Paolo Bonzini
static inline void stw_le_p(void *ptr, int v)
487 cbbab922 Paolo Bonzini
{
488 cbbab922 Paolo Bonzini
    *(uint16_t *)ptr = v;
489 cbbab922 Paolo Bonzini
}
490 cbbab922 Paolo Bonzini
491 cbbab922 Paolo Bonzini
static inline void stl_le_p(void *ptr, int v)
492 cbbab922 Paolo Bonzini
{
493 cbbab922 Paolo Bonzini
    *(uint32_t *)ptr = v;
494 cbbab922 Paolo Bonzini
}
495 cbbab922 Paolo Bonzini
496 cbbab922 Paolo Bonzini
static inline void stq_le_p(void *ptr, uint64_t v)
497 cbbab922 Paolo Bonzini
{
498 cbbab922 Paolo Bonzini
    *(uint64_t *)ptr = v;
499 cbbab922 Paolo Bonzini
}
500 cbbab922 Paolo Bonzini
501 cbbab922 Paolo Bonzini
/* float access */
502 cbbab922 Paolo Bonzini
503 cbbab922 Paolo Bonzini
static inline float32 ldfl_le_p(const void *ptr)
504 cbbab922 Paolo Bonzini
{
505 cbbab922 Paolo Bonzini
    return *(float32 *)ptr;
506 cbbab922 Paolo Bonzini
}
507 cbbab922 Paolo Bonzini
508 cbbab922 Paolo Bonzini
static inline float64 ldfq_le_p(const void *ptr)
509 cbbab922 Paolo Bonzini
{
510 cbbab922 Paolo Bonzini
    return *(float64 *)ptr;
511 cbbab922 Paolo Bonzini
}
512 cbbab922 Paolo Bonzini
513 cbbab922 Paolo Bonzini
static inline void stfl_le_p(void *ptr, float32 v)
514 cbbab922 Paolo Bonzini
{
515 cbbab922 Paolo Bonzini
    *(float32 *)ptr = v;
516 cbbab922 Paolo Bonzini
}
517 cbbab922 Paolo Bonzini
518 cbbab922 Paolo Bonzini
static inline void stfq_le_p(void *ptr, float64 v)
519 cbbab922 Paolo Bonzini
{
520 cbbab922 Paolo Bonzini
    *(float64 *)ptr = v;
521 cbbab922 Paolo Bonzini
}
522 cbbab922 Paolo Bonzini
#endif
523 cbbab922 Paolo Bonzini
524 cbbab922 Paolo Bonzini
#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
525 cbbab922 Paolo Bonzini
526 cbbab922 Paolo Bonzini
static inline int lduw_be_p(const void *ptr)
527 cbbab922 Paolo Bonzini
{
528 cbbab922 Paolo Bonzini
#if defined(__i386__)
529 cbbab922 Paolo Bonzini
    int val;
530 cbbab922 Paolo Bonzini
    asm volatile ("movzwl %1, %0\n"
531 cbbab922 Paolo Bonzini
                  "xchgb %b0, %h0\n"
532 cbbab922 Paolo Bonzini
                  : "=q" (val)
533 cbbab922 Paolo Bonzini
                  : "m" (*(uint16_t *)ptr));
534 cbbab922 Paolo Bonzini
    return val;
535 cbbab922 Paolo Bonzini
#else
536 cbbab922 Paolo Bonzini
    const uint8_t *b = ptr;
537 cbbab922 Paolo Bonzini
    return ((b[0] << 8) | b[1]);
538 cbbab922 Paolo Bonzini
#endif
539 cbbab922 Paolo Bonzini
}
540 cbbab922 Paolo Bonzini
541 cbbab922 Paolo Bonzini
static inline int ldsw_be_p(const void *ptr)
542 cbbab922 Paolo Bonzini
{
543 cbbab922 Paolo Bonzini
#if defined(__i386__)
544 cbbab922 Paolo Bonzini
    int val;
545 cbbab922 Paolo Bonzini
    asm volatile ("movzwl %1, %0\n"
546 cbbab922 Paolo Bonzini
                  "xchgb %b0, %h0\n"
547 cbbab922 Paolo Bonzini
                  : "=q" (val)
548 cbbab922 Paolo Bonzini
                  : "m" (*(uint16_t *)ptr));
549 cbbab922 Paolo Bonzini
    return (int16_t)val;
550 cbbab922 Paolo Bonzini
#else
551 cbbab922 Paolo Bonzini
    const uint8_t *b = ptr;
552 cbbab922 Paolo Bonzini
    return (int16_t)((b[0] << 8) | b[1]);
553 cbbab922 Paolo Bonzini
#endif
554 cbbab922 Paolo Bonzini
}
555 cbbab922 Paolo Bonzini
556 cbbab922 Paolo Bonzini
static inline int ldl_be_p(const void *ptr)
557 cbbab922 Paolo Bonzini
{
558 cbbab922 Paolo Bonzini
#if defined(__i386__) || defined(__x86_64__)
559 cbbab922 Paolo Bonzini
    int val;
560 cbbab922 Paolo Bonzini
    asm volatile ("movl %1, %0\n"
561 cbbab922 Paolo Bonzini
                  "bswap %0\n"
562 cbbab922 Paolo Bonzini
                  : "=r" (val)
563 cbbab922 Paolo Bonzini
                  : "m" (*(uint32_t *)ptr));
564 cbbab922 Paolo Bonzini
    return val;
565 cbbab922 Paolo Bonzini
#else
566 cbbab922 Paolo Bonzini
    const uint8_t *b = ptr;
567 cbbab922 Paolo Bonzini
    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
568 cbbab922 Paolo Bonzini
#endif
569 cbbab922 Paolo Bonzini
}
570 cbbab922 Paolo Bonzini
571 cbbab922 Paolo Bonzini
static inline uint64_t ldq_be_p(const void *ptr)
572 cbbab922 Paolo Bonzini
{
573 cbbab922 Paolo Bonzini
    uint32_t a,b;
574 cbbab922 Paolo Bonzini
    a = ldl_be_p(ptr);
575 cbbab922 Paolo Bonzini
    b = ldl_be_p((uint8_t *)ptr + 4);
576 cbbab922 Paolo Bonzini
    return (((uint64_t)a<<32)|b);
577 cbbab922 Paolo Bonzini
}
578 cbbab922 Paolo Bonzini
579 cbbab922 Paolo Bonzini
static inline void stw_be_p(void *ptr, int v)
580 cbbab922 Paolo Bonzini
{
581 cbbab922 Paolo Bonzini
#if defined(__i386__)
582 cbbab922 Paolo Bonzini
    asm volatile ("xchgb %b0, %h0\n"
583 cbbab922 Paolo Bonzini
                  "movw %w0, %1\n"
584 cbbab922 Paolo Bonzini
                  : "=q" (v)
585 cbbab922 Paolo Bonzini
                  : "m" (*(uint16_t *)ptr), "0" (v));
586 cbbab922 Paolo Bonzini
#else
587 cbbab922 Paolo Bonzini
    uint8_t *d = (uint8_t *) ptr;
588 cbbab922 Paolo Bonzini
    d[0] = v >> 8;
589 cbbab922 Paolo Bonzini
    d[1] = v;
590 cbbab922 Paolo Bonzini
#endif
591 cbbab922 Paolo Bonzini
}
592 cbbab922 Paolo Bonzini
593 cbbab922 Paolo Bonzini
static inline void stl_be_p(void *ptr, int v)
594 cbbab922 Paolo Bonzini
{
595 cbbab922 Paolo Bonzini
#if defined(__i386__) || defined(__x86_64__)
596 cbbab922 Paolo Bonzini
    asm volatile ("bswap %0\n"
597 cbbab922 Paolo Bonzini
                  "movl %0, %1\n"
598 cbbab922 Paolo Bonzini
                  : "=r" (v)
599 cbbab922 Paolo Bonzini
                  : "m" (*(uint32_t *)ptr), "0" (v));
600 cbbab922 Paolo Bonzini
#else
601 cbbab922 Paolo Bonzini
    uint8_t *d = (uint8_t *) ptr;
602 cbbab922 Paolo Bonzini
    d[0] = v >> 24;
603 cbbab922 Paolo Bonzini
    d[1] = v >> 16;
604 cbbab922 Paolo Bonzini
    d[2] = v >> 8;
605 cbbab922 Paolo Bonzini
    d[3] = v;
606 cbbab922 Paolo Bonzini
#endif
607 cbbab922 Paolo Bonzini
}
608 cbbab922 Paolo Bonzini
609 cbbab922 Paolo Bonzini
static inline void stq_be_p(void *ptr, uint64_t v)
610 cbbab922 Paolo Bonzini
{
611 cbbab922 Paolo Bonzini
    stl_be_p(ptr, v >> 32);
612 cbbab922 Paolo Bonzini
    stl_be_p((uint8_t *)ptr + 4, v);
613 cbbab922 Paolo Bonzini
}
614 cbbab922 Paolo Bonzini
615 cbbab922 Paolo Bonzini
/* float access */
616 cbbab922 Paolo Bonzini
617 cbbab922 Paolo Bonzini
static inline float32 ldfl_be_p(const void *ptr)
618 cbbab922 Paolo Bonzini
{
619 cbbab922 Paolo Bonzini
    union {
620 cbbab922 Paolo Bonzini
        float32 f;
621 cbbab922 Paolo Bonzini
        uint32_t i;
622 cbbab922 Paolo Bonzini
    } u;
623 cbbab922 Paolo Bonzini
    u.i = ldl_be_p(ptr);
624 cbbab922 Paolo Bonzini
    return u.f;
625 cbbab922 Paolo Bonzini
}
626 cbbab922 Paolo Bonzini
627 cbbab922 Paolo Bonzini
static inline void stfl_be_p(void *ptr, float32 v)
628 cbbab922 Paolo Bonzini
{
629 cbbab922 Paolo Bonzini
    union {
630 cbbab922 Paolo Bonzini
        float32 f;
631 cbbab922 Paolo Bonzini
        uint32_t i;
632 cbbab922 Paolo Bonzini
    } u;
633 cbbab922 Paolo Bonzini
    u.f = v;
634 cbbab922 Paolo Bonzini
    stl_be_p(ptr, u.i);
635 cbbab922 Paolo Bonzini
}
636 cbbab922 Paolo Bonzini
637 cbbab922 Paolo Bonzini
static inline float64 ldfq_be_p(const void *ptr)
638 cbbab922 Paolo Bonzini
{
639 cbbab922 Paolo Bonzini
    CPU_DoubleU u;
640 cbbab922 Paolo Bonzini
    u.l.upper = ldl_be_p(ptr);
641 cbbab922 Paolo Bonzini
    u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
642 cbbab922 Paolo Bonzini
    return u.d;
643 cbbab922 Paolo Bonzini
}
644 cbbab922 Paolo Bonzini
645 cbbab922 Paolo Bonzini
static inline void stfq_be_p(void *ptr, float64 v)
646 cbbab922 Paolo Bonzini
{
647 cbbab922 Paolo Bonzini
    CPU_DoubleU u;
648 cbbab922 Paolo Bonzini
    u.d = v;
649 cbbab922 Paolo Bonzini
    stl_be_p(ptr, u.l.upper);
650 cbbab922 Paolo Bonzini
    stl_be_p((uint8_t *)ptr + 4, u.l.lower);
651 cbbab922 Paolo Bonzini
}
652 cbbab922 Paolo Bonzini
653 cbbab922 Paolo Bonzini
#else
654 cbbab922 Paolo Bonzini
655 cbbab922 Paolo Bonzini
static inline int lduw_be_p(const void *ptr)
656 cbbab922 Paolo Bonzini
{
657 cbbab922 Paolo Bonzini
    return *(uint16_t *)ptr;
658 cbbab922 Paolo Bonzini
}
659 cbbab922 Paolo Bonzini
660 cbbab922 Paolo Bonzini
static inline int ldsw_be_p(const void *ptr)
661 cbbab922 Paolo Bonzini
{
662 cbbab922 Paolo Bonzini
    return *(int16_t *)ptr;
663 cbbab922 Paolo Bonzini
}
664 cbbab922 Paolo Bonzini
665 cbbab922 Paolo Bonzini
static inline int ldl_be_p(const void *ptr)
666 cbbab922 Paolo Bonzini
{
667 cbbab922 Paolo Bonzini
    return *(uint32_t *)ptr;
668 cbbab922 Paolo Bonzini
}
669 cbbab922 Paolo Bonzini
670 cbbab922 Paolo Bonzini
static inline uint64_t ldq_be_p(const void *ptr)
671 cbbab922 Paolo Bonzini
{
672 cbbab922 Paolo Bonzini
    return *(uint64_t *)ptr;
673 cbbab922 Paolo Bonzini
}
674 cbbab922 Paolo Bonzini
675 cbbab922 Paolo Bonzini
static inline void stw_be_p(void *ptr, int v)
676 cbbab922 Paolo Bonzini
{
677 cbbab922 Paolo Bonzini
    *(uint16_t *)ptr = v;
678 cbbab922 Paolo Bonzini
}
679 cbbab922 Paolo Bonzini
680 cbbab922 Paolo Bonzini
static inline void stl_be_p(void *ptr, int v)
681 cbbab922 Paolo Bonzini
{
682 cbbab922 Paolo Bonzini
    *(uint32_t *)ptr = v;
683 cbbab922 Paolo Bonzini
}
684 cbbab922 Paolo Bonzini
685 cbbab922 Paolo Bonzini
static inline void stq_be_p(void *ptr, uint64_t v)
686 cbbab922 Paolo Bonzini
{
687 cbbab922 Paolo Bonzini
    *(uint64_t *)ptr = v;
688 cbbab922 Paolo Bonzini
}
689 cbbab922 Paolo Bonzini
690 cbbab922 Paolo Bonzini
/* float access */
691 cbbab922 Paolo Bonzini
692 cbbab922 Paolo Bonzini
static inline float32 ldfl_be_p(const void *ptr)
693 cbbab922 Paolo Bonzini
{
694 cbbab922 Paolo Bonzini
    return *(float32 *)ptr;
695 cbbab922 Paolo Bonzini
}
696 cbbab922 Paolo Bonzini
697 cbbab922 Paolo Bonzini
static inline float64 ldfq_be_p(const void *ptr)
698 cbbab922 Paolo Bonzini
{
699 cbbab922 Paolo Bonzini
    return *(float64 *)ptr;
700 cbbab922 Paolo Bonzini
}
701 cbbab922 Paolo Bonzini
702 cbbab922 Paolo Bonzini
static inline void stfl_be_p(void *ptr, float32 v)
703 cbbab922 Paolo Bonzini
{
704 cbbab922 Paolo Bonzini
    *(float32 *)ptr = v;
705 cbbab922 Paolo Bonzini
}
706 cbbab922 Paolo Bonzini
707 cbbab922 Paolo Bonzini
static inline void stfq_be_p(void *ptr, float64 v)
708 cbbab922 Paolo Bonzini
{
709 cbbab922 Paolo Bonzini
    *(float64 *)ptr = v;
710 cbbab922 Paolo Bonzini
}
711 cbbab922 Paolo Bonzini
712 cbbab922 Paolo Bonzini
#endif
713 cbbab922 Paolo Bonzini
714 ab93bbe2 bellard
#endif /* BSWAP_H */