Statistics
| Branch: | Revision:

root / bswap.h @ c09015dd

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