xref: /qemu/include/qemu/bswap.h (revision a976a99a)
1 #ifndef BSWAP_H
2 #define BSWAP_H
3 
4 #ifdef CONFIG_MACHINE_BSWAP_H
5 # include <sys/endian.h>
6 # include <machine/bswap.h>
7 #elif defined(__FreeBSD__)
8 # include <sys/endian.h>
9 #elif defined(__HAIKU__)
10 # include <endian.h>
11 #elif defined(CONFIG_BYTESWAP_H)
12 # include <byteswap.h>
13 #define BSWAP_FROM_BYTESWAP
14 # else
15 #define BSWAP_FROM_FALLBACKS
16 #endif /* ! CONFIG_MACHINE_BSWAP_H */
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #ifdef BSWAP_FROM_BYTESWAP
23 static inline uint16_t bswap16(uint16_t x)
24 {
25     return bswap_16(x);
26 }
27 
28 static inline uint32_t bswap32(uint32_t x)
29 {
30     return bswap_32(x);
31 }
32 
33 static inline uint64_t bswap64(uint64_t x)
34 {
35     return bswap_64(x);
36 }
37 #endif
38 
39 #ifdef BSWAP_FROM_FALLBACKS
40 static inline uint16_t bswap16(uint16_t x)
41 {
42     return (((x & 0x00ff) << 8) |
43             ((x & 0xff00) >> 8));
44 }
45 
46 static inline uint32_t bswap32(uint32_t x)
47 {
48     return (((x & 0x000000ffU) << 24) |
49             ((x & 0x0000ff00U) <<  8) |
50             ((x & 0x00ff0000U) >>  8) |
51             ((x & 0xff000000U) >> 24));
52 }
53 
54 static inline uint64_t bswap64(uint64_t x)
55 {
56     return (((x & 0x00000000000000ffULL) << 56) |
57             ((x & 0x000000000000ff00ULL) << 40) |
58             ((x & 0x0000000000ff0000ULL) << 24) |
59             ((x & 0x00000000ff000000ULL) <<  8) |
60             ((x & 0x000000ff00000000ULL) >>  8) |
61             ((x & 0x0000ff0000000000ULL) >> 24) |
62             ((x & 0x00ff000000000000ULL) >> 40) |
63             ((x & 0xff00000000000000ULL) >> 56));
64 }
65 #endif
66 
67 #undef BSWAP_FROM_BYTESWAP
68 #undef BSWAP_FROM_FALLBACKS
69 
70 static inline void bswap16s(uint16_t *s)
71 {
72     *s = bswap16(*s);
73 }
74 
75 static inline void bswap32s(uint32_t *s)
76 {
77     *s = bswap32(*s);
78 }
79 
80 static inline void bswap64s(uint64_t *s)
81 {
82     *s = bswap64(*s);
83 }
84 
85 #if HOST_BIG_ENDIAN
86 #define be_bswap(v, size) (v)
87 #define le_bswap(v, size) glue(bswap, size)(v)
88 #define be_bswaps(v, size)
89 #define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
90 #else
91 #define le_bswap(v, size) (v)
92 #define be_bswap(v, size) glue(bswap, size)(v)
93 #define le_bswaps(v, size)
94 #define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
95 #endif
96 
97 /**
98  * Endianness conversion functions between host cpu and specified endianness.
99  * (We list the complete set of prototypes produced by the macros below
100  * to assist people who search the headers to find their definitions.)
101  *
102  * uint16_t le16_to_cpu(uint16_t v);
103  * uint32_t le32_to_cpu(uint32_t v);
104  * uint64_t le64_to_cpu(uint64_t v);
105  * uint16_t be16_to_cpu(uint16_t v);
106  * uint32_t be32_to_cpu(uint32_t v);
107  * uint64_t be64_to_cpu(uint64_t v);
108  *
109  * Convert the value @v from the specified format to the native
110  * endianness of the host CPU by byteswapping if necessary, and
111  * return the converted value.
112  *
113  * uint16_t cpu_to_le16(uint16_t v);
114  * uint32_t cpu_to_le32(uint32_t v);
115  * uint64_t cpu_to_le64(uint64_t v);
116  * uint16_t cpu_to_be16(uint16_t v);
117  * uint32_t cpu_to_be32(uint32_t v);
118  * uint64_t cpu_to_be64(uint64_t v);
119  *
120  * Convert the value @v from the native endianness of the host CPU to
121  * the specified format by byteswapping if necessary, and return
122  * the converted value.
123  *
124  * void le16_to_cpus(uint16_t *v);
125  * void le32_to_cpus(uint32_t *v);
126  * void le64_to_cpus(uint64_t *v);
127  * void be16_to_cpus(uint16_t *v);
128  * void be32_to_cpus(uint32_t *v);
129  * void be64_to_cpus(uint64_t *v);
130  *
131  * Do an in-place conversion of the value pointed to by @v from the
132  * specified format to the native endianness of the host CPU.
133  *
134  * void cpu_to_le16s(uint16_t *v);
135  * void cpu_to_le32s(uint32_t *v);
136  * void cpu_to_le64s(uint64_t *v);
137  * void cpu_to_be16s(uint16_t *v);
138  * void cpu_to_be32s(uint32_t *v);
139  * void cpu_to_be64s(uint64_t *v);
140  *
141  * Do an in-place conversion of the value pointed to by @v from the
142  * native endianness of the host CPU to the specified format.
143  *
144  * Both X_to_cpu() and cpu_to_X() perform the same operation; you
145  * should use whichever one is better documenting of the function your
146  * code is performing.
147  *
148  * Do not use these functions for conversion of values which are in guest
149  * memory, since the data may not be sufficiently aligned for the host CPU's
150  * load and store instructions. Instead you should use the ld*_p() and
151  * st*_p() functions, which perform loads and stores of data of any
152  * required size and endianness and handle possible misalignment.
153  */
154 
155 #define CPU_CONVERT(endian, size, type)\
156 static inline type endian ## size ## _to_cpu(type v)\
157 {\
158     return glue(endian, _bswap)(v, size);\
159 }\
160 \
161 static inline type cpu_to_ ## endian ## size(type v)\
162 {\
163     return glue(endian, _bswap)(v, size);\
164 }\
165 \
166 static inline void endian ## size ## _to_cpus(type *p)\
167 {\
168     glue(endian, _bswaps)(p, size);\
169 }\
170 \
171 static inline void cpu_to_ ## endian ## size ## s(type *p)\
172 {\
173     glue(endian, _bswaps)(p, size);\
174 }
175 
176 CPU_CONVERT(be, 16, uint16_t)
177 CPU_CONVERT(be, 32, uint32_t)
178 CPU_CONVERT(be, 64, uint64_t)
179 
180 CPU_CONVERT(le, 16, uint16_t)
181 CPU_CONVERT(le, 32, uint32_t)
182 CPU_CONVERT(le, 64, uint64_t)
183 
184 /*
185  * Same as cpu_to_le{16,32}, except that gcc will figure the result is
186  * a compile-time constant if you pass in a constant.  So this can be
187  * used to initialize static variables.
188  */
189 #if HOST_BIG_ENDIAN
190 # define const_le32(_x)                          \
191     ((((_x) & 0x000000ffU) << 24) |              \
192      (((_x) & 0x0000ff00U) <<  8) |              \
193      (((_x) & 0x00ff0000U) >>  8) |              \
194      (((_x) & 0xff000000U) >> 24))
195 # define const_le16(_x)                          \
196     ((((_x) & 0x00ff) << 8) |                    \
197      (((_x) & 0xff00) >> 8))
198 #else
199 # define const_le32(_x) (_x)
200 # define const_le16(_x) (_x)
201 #endif
202 
203 /* unaligned/endian-independent pointer access */
204 
205 /*
206  * the generic syntax is:
207  *
208  * load: ld{type}{sign}{size}_{endian}_p(ptr)
209  *
210  * store: st{type}{size}_{endian}_p(ptr, val)
211  *
212  * Note there are small differences with the softmmu access API!
213  *
214  * type is:
215  * (empty): integer access
216  *   f    : float access
217  *
218  * sign is:
219  * (empty): for 32 or 64 bit sizes (including floats and doubles)
220  *   u    : unsigned
221  *   s    : signed
222  *
223  * size is:
224  *   b: 8 bits
225  *   w: 16 bits
226  *   l: 32 bits
227  *   q: 64 bits
228  *
229  * endian is:
230  *   he   : host endian
231  *   be   : big endian
232  *   le   : little endian
233  *   te   : target endian
234  * (except for byte accesses, which have no endian infix).
235  *
236  * The target endian accessors are obviously only available to source
237  * files which are built per-target; they are defined in cpu-all.h.
238  *
239  * In all cases these functions take a host pointer.
240  * For accessors that take a guest address rather than a
241  * host address, see the cpu_{ld,st}_* accessors defined in
242  * cpu_ldst.h.
243  *
244  * For cases where the size to be used is not fixed at compile time,
245  * there are
246  *  stn_{endian}_p(ptr, sz, val)
247  * which stores @val to @ptr as an @endian-order number @sz bytes in size
248  * and
249  *  ldn_{endian}_p(ptr, sz)
250  * which loads @sz bytes from @ptr as an unsigned @endian-order number
251  * and returns it in a uint64_t.
252  */
253 
254 static inline int ldub_p(const void *ptr)
255 {
256     return *(uint8_t *)ptr;
257 }
258 
259 static inline int ldsb_p(const void *ptr)
260 {
261     return *(int8_t *)ptr;
262 }
263 
264 static inline void stb_p(void *ptr, uint8_t v)
265 {
266     *(uint8_t *)ptr = v;
267 }
268 
269 /*
270  * Any compiler worth its salt will turn these memcpy into native unaligned
271  * operations.  Thus we don't need to play games with packed attributes, or
272  * inline byte-by-byte stores.
273  * Some compilation environments (eg some fortify-source implementations)
274  * may intercept memcpy() in a way that defeats the compiler optimization,
275  * though, so we use __builtin_memcpy() to give ourselves the best chance
276  * of good performance.
277  */
278 
279 static inline int lduw_he_p(const void *ptr)
280 {
281     uint16_t r;
282     __builtin_memcpy(&r, ptr, sizeof(r));
283     return r;
284 }
285 
286 static inline int ldsw_he_p(const void *ptr)
287 {
288     int16_t r;
289     __builtin_memcpy(&r, ptr, sizeof(r));
290     return r;
291 }
292 
293 static inline void stw_he_p(void *ptr, uint16_t v)
294 {
295     __builtin_memcpy(ptr, &v, sizeof(v));
296 }
297 
298 static inline int ldl_he_p(const void *ptr)
299 {
300     int32_t r;
301     __builtin_memcpy(&r, ptr, sizeof(r));
302     return r;
303 }
304 
305 static inline void stl_he_p(void *ptr, uint32_t v)
306 {
307     __builtin_memcpy(ptr, &v, sizeof(v));
308 }
309 
310 static inline uint64_t ldq_he_p(const void *ptr)
311 {
312     uint64_t r;
313     __builtin_memcpy(&r, ptr, sizeof(r));
314     return r;
315 }
316 
317 static inline void stq_he_p(void *ptr, uint64_t v)
318 {
319     __builtin_memcpy(ptr, &v, sizeof(v));
320 }
321 
322 static inline int lduw_le_p(const void *ptr)
323 {
324     return (uint16_t)le_bswap(lduw_he_p(ptr), 16);
325 }
326 
327 static inline int ldsw_le_p(const void *ptr)
328 {
329     return (int16_t)le_bswap(lduw_he_p(ptr), 16);
330 }
331 
332 static inline int ldl_le_p(const void *ptr)
333 {
334     return le_bswap(ldl_he_p(ptr), 32);
335 }
336 
337 static inline uint64_t ldq_le_p(const void *ptr)
338 {
339     return le_bswap(ldq_he_p(ptr), 64);
340 }
341 
342 static inline void stw_le_p(void *ptr, uint16_t v)
343 {
344     stw_he_p(ptr, le_bswap(v, 16));
345 }
346 
347 static inline void stl_le_p(void *ptr, uint32_t v)
348 {
349     stl_he_p(ptr, le_bswap(v, 32));
350 }
351 
352 static inline void stq_le_p(void *ptr, uint64_t v)
353 {
354     stq_he_p(ptr, le_bswap(v, 64));
355 }
356 
357 static inline int lduw_be_p(const void *ptr)
358 {
359     return (uint16_t)be_bswap(lduw_he_p(ptr), 16);
360 }
361 
362 static inline int ldsw_be_p(const void *ptr)
363 {
364     return (int16_t)be_bswap(lduw_he_p(ptr), 16);
365 }
366 
367 static inline int ldl_be_p(const void *ptr)
368 {
369     return be_bswap(ldl_he_p(ptr), 32);
370 }
371 
372 static inline uint64_t ldq_be_p(const void *ptr)
373 {
374     return be_bswap(ldq_he_p(ptr), 64);
375 }
376 
377 static inline void stw_be_p(void *ptr, uint16_t v)
378 {
379     stw_he_p(ptr, be_bswap(v, 16));
380 }
381 
382 static inline void stl_be_p(void *ptr, uint32_t v)
383 {
384     stl_he_p(ptr, be_bswap(v, 32));
385 }
386 
387 static inline void stq_be_p(void *ptr, uint64_t v)
388 {
389     stq_he_p(ptr, be_bswap(v, 64));
390 }
391 
392 static inline unsigned long leul_to_cpu(unsigned long v)
393 {
394 #if HOST_LONG_BITS == 32
395     return le_bswap(v, 32);
396 #elif HOST_LONG_BITS == 64
397     return le_bswap(v, 64);
398 #else
399 # error Unknown sizeof long
400 #endif
401 }
402 
403 /* Store v to p as a sz byte value in host order */
404 #define DO_STN_LDN_P(END) \
405     static inline void stn_## END ## _p(void *ptr, int sz, uint64_t v)  \
406     {                                                                   \
407         switch (sz) {                                                   \
408         case 1:                                                         \
409             stb_p(ptr, v);                                              \
410             break;                                                      \
411         case 2:                                                         \
412             stw_ ## END ## _p(ptr, v);                                  \
413             break;                                                      \
414         case 4:                                                         \
415             stl_ ## END ## _p(ptr, v);                                  \
416             break;                                                      \
417         case 8:                                                         \
418             stq_ ## END ## _p(ptr, v);                                  \
419             break;                                                      \
420         default:                                                        \
421             g_assert_not_reached();                                     \
422         }                                                               \
423     }                                                                   \
424     static inline uint64_t ldn_## END ## _p(const void *ptr, int sz)    \
425     {                                                                   \
426         switch (sz) {                                                   \
427         case 1:                                                         \
428             return ldub_p(ptr);                                         \
429         case 2:                                                         \
430             return lduw_ ## END ## _p(ptr);                             \
431         case 4:                                                         \
432             return (uint32_t)ldl_ ## END ## _p(ptr);                    \
433         case 8:                                                         \
434             return ldq_ ## END ## _p(ptr);                              \
435         default:                                                        \
436             g_assert_not_reached();                                     \
437         }                                                               \
438     }
439 
440 DO_STN_LDN_P(he)
441 DO_STN_LDN_P(le)
442 DO_STN_LDN_P(be)
443 
444 #undef DO_STN_LDN_P
445 
446 #undef le_bswap
447 #undef be_bswap
448 #undef le_bswaps
449 #undef be_bswaps
450 
451 #ifdef __cplusplus
452 }
453 #endif
454 
455 #endif /* BSWAP_H */
456