[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v5 1/6] xen: implement byteswap
swab() is massively over complicated and can be simplified by re-implementing using compiler builtins. The compilers provide builtin function to swap bytes. * gcc: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html * clang: https://clang.llvm.org/docs/LanguageExtensions.html This patch introduces a new byteswapping infrastructure in terms of compiler builtins and bswapXX(), so the swab() infrastructure can be retired. Signed-off-by: Lin Liu <lin.liu@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx> Cc: Julien Grall <julien@xxxxxxx> Cc: Bertrand Marquis <bertrand.marquis@xxxxxxx> Cc: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Cc: George Dunlap <george.dunlap@xxxxxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Wei Liu <wl@xxxxxxx> Cc: "Roger Pau Monné" <roger.pau@xxxxxxxxxx> Changes in v5: - Move `PASTE` back to xen/lib.h - Define `PASTE` for tools in xen-tools/libs.h Changes in v4: - Move `PASTE` definition to xen/compiler.h to support tools - Revert emacs magics Changes in v3: - Check __has_builtin instead of GNUC version Changes in v2: - Add fallback for compilers without __builtin_bswap - Implement with plain C instead of macros --- tools/include/xen-tools/libs.h | 4 ++ xen/arch/arm/include/asm/byteorder.h | 6 ++- xen/arch/x86/include/asm/byteorder.h | 34 ++--------------- xen/include/xen/byteorder.h | 56 ++++++++++++++++++++++++++++ xen/include/xen/byteswap.h | 44 ++++++++++++++++++++++ xen/include/xen/compiler.h | 20 ++++++++++ 6 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 xen/include/xen/byteorder.h create mode 100644 xen/include/xen/byteswap.h diff --git a/tools/include/xen-tools/libs.h b/tools/include/xen-tools/libs.h index a16e0c3807..fc12ac84c6 100644 --- a/tools/include/xen-tools/libs.h +++ b/tools/include/xen-tools/libs.h @@ -63,4 +63,8 @@ #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1)) #endif +/* Indirect macros required for expanded argument pasting. */ +#define PASTE_(a, b) a ## b +#define PASTE(a, b) PASTE_(a, b) + #endif /* __XEN_TOOLS_LIBS__ */ diff --git a/xen/arch/arm/include/asm/byteorder.h b/xen/arch/arm/include/asm/byteorder.h index 9c712c4788..b6a33b23c0 100644 --- a/xen/arch/arm/include/asm/byteorder.h +++ b/xen/arch/arm/include/asm/byteorder.h @@ -1,9 +1,11 @@ #ifndef __ASM_ARM_BYTEORDER_H__ #define __ASM_ARM_BYTEORDER_H__ -#define __BYTEORDER_HAS_U64__ +#ifndef __BYTE_ORDER__ + #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif -#include <xen/byteorder/little_endian.h> +#include <xen/byteorder.h> #endif /* __ASM_ARM_BYTEORDER_H__ */ /* diff --git a/xen/arch/x86/include/asm/byteorder.h b/xen/arch/x86/include/asm/byteorder.h index 1f77e502a5..82aadee7bd 100644 --- a/xen/arch/x86/include/asm/byteorder.h +++ b/xen/arch/x86/include/asm/byteorder.h @@ -1,36 +1,10 @@ #ifndef __ASM_X86_BYTEORDER_H__ #define __ASM_X86_BYTEORDER_H__ -#include <asm/types.h> -#include <xen/compiler.h> +#ifndef __BYTE_ORDER__ + #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif -static inline __attribute_const__ __u32 ___arch__swab32(__u32 x) -{ - asm("bswap %0" : "=r" (x) : "0" (x)); - return x; -} - -static inline __attribute_const__ __u64 ___arch__swab64(__u64 val) -{ - union { - struct { __u32 a,b; } s; - __u64 u; - } v; - v.u = val; - asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" - : "=r" (v.s.a), "=r" (v.s.b) - : "0" (v.s.a), "1" (v.s.b)); - return v.u; -} - -/* Do not define swab16. Gcc is smart enough to recognize "C" version and - convert it into rotation or exhange. */ - -#define __arch__swab64(x) ___arch__swab64(x) -#define __arch__swab32(x) ___arch__swab32(x) - -#define __BYTEORDER_HAS_U64__ - -#include <xen/byteorder/little_endian.h> +#include <xen/byteorder.h> #endif /* __ASM_X86_BYTEORDER_H__ */ diff --git a/xen/include/xen/byteorder.h b/xen/include/xen/byteorder.h new file mode 100644 index 0000000000..2ec434e6a6 --- /dev/null +++ b/xen/include/xen/byteorder.h @@ -0,0 +1,56 @@ +#ifndef __XEN_BYTEORDER_H__ +#define __XEN_BYTEORDER_H__ + +#include <xen/byteswap.h> + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +# ifndef __LITTLE_ENDIAN +# define __LITTLE_ENDIAN 1234 +# endif + +# ifndef __LITTLE_ENDIAN_BITFIELD +# define __LITTLE_ENDIAN_BITFIELD +# endif + +# define cpu_to_le64(x) (x) +# define le64_to_cpu(x) (x) +# define cpu_to_le32(x) (x) +# define le32_to_cpu(x) (x) +# define cpu_to_le16(x) (x) +# define le16_to_cpu(x) (x) +# define cpu_to_be64(x) bswap64(x) +# define be64_to_cpu(x) bswap64(x) +# define cpu_to_be32(x) bswap32(x) +# define be32_to_cpu(x) bswap32(x) +# define cpu_to_be16(x) bswap16(x) +# define be16_to_cpu(x) bswap16(x) + +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +# ifndef __BIG_ENDIAN +# define __BIG_ENDIAN 4321 +# endif + +# ifndef __BIG_ENDIAN_BITFIELD +# define __BIG_ENDIAN_BITFIELD +# endif + +# define cpu_to_le64(x) bswap64(x) +# define le64_to_cpu(x) bswap64(x) +# define cpu_to_le32(x) bswap32(x) +# define le32_to_cpu(x) bswap32(x) +# define cpu_to_le16(x) bswap16(x) +# define le16_to_cpu(x) bswap16(x) +# define cpu_to_be64(x) (x) +# define be64_to_cpu(x) (x) +# define cpu_to_be32(x) (x) +# define be32_to_cpu(x) (x) +# define cpu_to_be16(x) (x) +# define be16_to_cpu(x) (x) + +#else +# error "Unknown Endianness" +#endif /* __BYTE_ORDER__ */ + +#endif /* __XEN_BYTEORDER_H__ */ diff --git a/xen/include/xen/byteswap.h b/xen/include/xen/byteswap.h new file mode 100644 index 0000000000..d2e371fbe7 --- /dev/null +++ b/xen/include/xen/byteswap.h @@ -0,0 +1,44 @@ +#ifndef __XEN_BYTESWAP_H__ +#define __XEN_BYTESWAP_H__ + +#include <xen/types.h> +#include <xen/compiler.h> + +#if !__has_builtin(__builtin_bswap16) +static always_inline uint16_t __builtin_bswap16(uint16_t val) +{ + return ((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8); +} +#endif + +#if !__has_builtin(__builtin_bswap32) +static always_inline uint32_t __builtin_bswap32(uint32_t val) +{ + return ((val & 0x000000FF) << 24) | + ((val & 0x0000FF00) << 8) | + ((val & 0x00FF0000) >> 8) | + ((val & 0xFF000000) >> 24); +} +#endif + +#if !__has_builtin(__builtin_bswap64) +static always_inline uint64_t __builtin_bswap64(uint64_t val) +{ + return ((val & 0x00000000000000FF) << 56) | + ((val & 0x000000000000FF00) << 40) | + ((val & 0x0000000000FF0000) << 24) | + ((val & 0x00000000FF000000) << 8) | + ((val & 0x000000FF00000000) >> 8) | + ((val & 0x0000FF0000000000) >> 24) | + ((val & 0x00FF000000000000) >> 40) | + ((val & 0xFF00000000000000) >> 56); +} +#endif + +#define bswap16(x) __builtin_bswap16(x) +#define bswap32(x) __builtin_bswap32(x) +#define bswap64(x) __builtin_bswap64(x) + +#define bswap_ul(x) PASTE(bswap,BITS_PER_LONG)(x) + +#endif /* __XEN_BYTESWAP_H__ */ diff --git a/xen/include/xen/compiler.h b/xen/include/xen/compiler.h index 933aec09a9..6d77da8a68 100644 --- a/xen/include/xen/compiler.h +++ b/xen/include/xen/compiler.h @@ -185,4 +185,24 @@ # define CLANG_DISABLE_WARN_GCC_COMPAT_END #endif +#ifndef __has_builtin +/* + * Backwards compatibility for GCC < 10. + * All supported versions of Clang support __has_builtin + * */ +#define __has_builtin(x) GCC_has ## x + +#define GCC_has__builtin_bswap16 (CONFIG_GCC_VERSION >= 40800) +#define GCC_has__builtin_bswap32 (CONFIG_GCC_VERSION >= 40400) +#define GCC_has__builtin_bswap64 (CONFIG_GCC_VERSION >= 40400) +#endif + +#ifndef __ORDER_LITTLE_ENDIAN__ +# define __ORDER_LITTLE_ENDIAN__ 1234 +#endif + +#ifndef __ORDER_BIG_ENDIAN__ +# define __ORDER_BIG_ENDIAN__ 4321 +#endif + #endif /* __LINUX_COMPILER_H */ -- 2.27.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |