/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef _ASM_RISCV_SWAB_H #define _ASM_RISCV_SWAB_H #include #include #include #include #include #if defined(CONFIG_TOOLCHAIN_HAS_ZBB) && defined(CONFIG_RISCV_ISA_ZBB) && !defined(NO_ALTERNATIVE) // Duplicated from include/uapi/linux/swab.h #define ___constant_swab16(x) ((__u16)( \ (((__u16)(x) & (__u16)0x00ffU) << 8) | \ (((__u16)(x) & (__u16)0xff00U) >> 8))) #define ___constant_swab32(x) ((__u32)( \ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ (((__u32)(x) & (__u32)0xff000000UL) >> 24))) #define ___constant_swab64(x) ((__u64)( \ (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56))) #define ARCH_SWAB(size, value) \ ({ \ unsigned long x = value; \ \ if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) { \ asm volatile (".option push\n" \ ".option arch,+zbb\n" \ "rev8 %0, %1\n" \ ".option pop\n" \ : "=r" (x) : "r" (x)); \ x = x >> (BITS_PER_LONG - size); \ } else { \ x = ___constant_swab##size(value); \ } \ x; \ }) static __always_inline __u16 __arch_swab16(__u16 value) { return ARCH_SWAB(16, value); } static __always_inline __u32 __arch_swab32(__u32 value) { return ARCH_SWAB(32, value); } #ifdef CONFIG_64BIT static __always_inline __u64 __arch_swab64(__u64 value) { return ARCH_SWAB(64, value); } #else static __always_inline __u64 __arch_swab64(__u64 value) { __u32 h = value >> 32; __u32 l = value & ((1ULL << 32) - 1); return ((__u64)(__arch_swab32(l)) << 32) | ((__u64)(__arch_swab32(h))); } #endif #define __arch_swab64 __arch_swab64 #define __arch_swab32 __arch_swab32 #define __arch_swab16 __arch_swab16 #undef ___constant_swab16 #undef ___constant_swab32 #undef ___constant_swab64 #undef ARCH_SWAB #endif /* defined(CONFIG_TOOLCHAIN_HAS_ZBB) && defined(CONFIG_RISCV_ISA_ZBB) && !defined(NO_ALTERNATIVE) */ #endif /* _ASM_RISCV_SWAB_H */