]> Git Repo - qemu.git/blobdiff - include/qemu/bswap.h
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-10-25' into staging
[qemu.git] / include / qemu / bswap.h
index 78c1ced4e7a79bcabb5ab23f1b3e0436bc22dd48..09c78fd28a6ec5c1a5ef9ad3570b22f78b245ee5 100644 (file)
@@ -1,15 +1,10 @@
 #ifndef BSWAP_H
 #define BSWAP_H
 
-#include "config-host.h"
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
 #include "fpu/softfloat.h"
 
 #ifdef CONFIG_MACHINE_BSWAP_H
 # include <sys/endian.h>
-# include <sys/types.h>
 # include <machine/bswap.h>
 #elif defined(__FreeBSD__)
 # include <sys/endian.h>
@@ -85,6 +80,64 @@ static inline void bswap64s(uint64_t *s)
 #define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
 #endif
 
+/**
+ * Endianness conversion functions between host cpu and specified endianness.
+ * (We list the complete set of prototypes produced by the macros below
+ * to assist people who search the headers to find their definitions.)
+ *
+ * uint16_t le16_to_cpu(uint16_t v);
+ * uint32_t le32_to_cpu(uint32_t v);
+ * uint64_t le64_to_cpu(uint64_t v);
+ * uint16_t be16_to_cpu(uint16_t v);
+ * uint32_t be32_to_cpu(uint32_t v);
+ * uint64_t be64_to_cpu(uint64_t v);
+ *
+ * Convert the value @v from the specified format to the native
+ * endianness of the host CPU by byteswapping if necessary, and
+ * return the converted value.
+ *
+ * uint16_t cpu_to_le16(uint16_t v);
+ * uint32_t cpu_to_le32(uint32_t v);
+ * uint64_t cpu_to_le64(uint64_t v);
+ * uint16_t cpu_to_be16(uint16_t v);
+ * uint32_t cpu_to_be32(uint32_t v);
+ * uint64_t cpu_to_be64(uint64_t v);
+ *
+ * Convert the value @v from the native endianness of the host CPU to
+ * the specified format by byteswapping if necessary, and return
+ * the converted value.
+ *
+ * void le16_to_cpus(uint16_t *v);
+ * void le32_to_cpus(uint32_t *v);
+ * void le64_to_cpus(uint64_t *v);
+ * void be16_to_cpus(uint16_t *v);
+ * void be32_to_cpus(uint32_t *v);
+ * void be64_to_cpus(uint64_t *v);
+ *
+ * Do an in-place conversion of the value pointed to by @v from the
+ * specified format to the native endianness of the host CPU.
+ *
+ * void cpu_to_le16s(uint16_t *v);
+ * void cpu_to_le32s(uint32_t *v);
+ * void cpu_to_le64s(uint64_t *v);
+ * void cpu_to_be16s(uint16_t *v);
+ * void cpu_to_be32s(uint32_t *v);
+ * void cpu_to_be64s(uint64_t *v);
+ *
+ * Do an in-place conversion of the value pointed to by @v from the
+ * native endianness of the host CPU to the specified format.
+ *
+ * Both X_to_cpu() and cpu_to_X() perform the same operation; you
+ * should use whichever one is better documenting of the function your
+ * code is performing.
+ *
+ * Do not use these functions for conversion of values which are in guest
+ * memory, since the data may not be sufficiently aligned for the host CPU's
+ * load and store instructions. Instead you should use the ld*_p() and
+ * st*_p() functions, which perform loads and stores of data of any
+ * required size and endianness and handle possible misalignment.
+ */
+
 #define CPU_CONVERT(endian, size, type)\
 static inline type endian ## size ## _to_cpu(type v)\
 {\
@@ -104,16 +157,6 @@ static inline void endian ## size ## _to_cpus(type *p)\
 static inline void cpu_to_ ## endian ## size ## s(type *p)\
 {\
     glue(endian, _bswaps)(p, size);\
-}\
-\
-static inline type endian ## size ## _to_cpup(const type *p)\
-{\
-    return glue(glue(endian, size), _to_cpu)(*p);\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
-{\
-    *p = glue(glue(cpu_to_, endian), size)(v);\
 }
 
 CPU_CONVERT(be, 16, uint16_t)
@@ -130,6 +173,25 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len)
     return bswap32(value) >> (32 - 8 * len);
 }
 
+/*
+ * Same as cpu_to_le{16,32}, except that gcc will figure the result is
+ * a compile-time constant if you pass in a constant.  So this can be
+ * used to initialize static variables.
+ */
+#if defined(HOST_WORDS_BIGENDIAN)
+# define const_le32(_x)                          \
+    ((((_x) & 0x000000ffU) << 24) |              \
+     (((_x) & 0x0000ff00U) <<  8) |              \
+     (((_x) & 0x00ff0000U) >>  8) |              \
+     (((_x) & 0xff000000U) >> 24))
+# define const_le16(_x)                          \
+    ((((_x) & 0x00ff) << 8) |                    \
+     (((_x) & 0xff00) >> 8))
+#else
+# define const_le32(_x) (_x)
+# define const_le16(_x) (_x)
+#endif
+
 /* Unions for reinterpreting between floats and integers.  */
 
 typedef union {
@@ -204,7 +266,7 @@ typedef union {
  *   f    : float access
  *
  * sign is:
- * (empty): for floats or 32 bit size
+ * (empty): for 32 or 64 bit sizes (including floats and doubles)
  *   u    : unsigned
  *   s    : signed
  *
@@ -218,7 +280,16 @@ typedef union {
  *   he   : host endian
  *   be   : big endian
  *   le   : little endian
+ *   te   : target endian
  * (except for byte accesses, which have no endian infix).
+ *
+ * The target endian accessors are obviously only available to source
+ * files which are built per-target; they are defined in cpu-all.h.
+ *
+ * In all cases these functions take a host pointer.
+ * For accessors that take a guest address rather than a
+ * host address, see the cpu_{ld,st}_* accessors defined in
+ * cpu_ldst.h.
  */
 
 static inline int ldub_p(const void *ptr)
@@ -415,11 +486,9 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 static inline unsigned long leul_to_cpu(unsigned long v)
 {
-    /* In order to break an include loop between here and
-       qemu-common.h, don't rely on HOST_LONG_BITS.  */
-#if ULONG_MAX == UINT32_MAX
+#if HOST_LONG_BITS == 32
     return le_bswap(v, 32);
-#elif ULONG_MAX == UINT64_MAX
+#elif HOST_LONG_BITS == 64
     return le_bswap(v, 64);
 #else
 # error Unknown sizeof long
This page took 0.0285 seconds and 4 git commands to generate.