1*cc2294d3SIgnacio Encinas /* SPDX-License-Identifier: GPL-2.0-only */ 2*cc2294d3SIgnacio Encinas #ifndef _ASM_RISCV_SWAB_H 3*cc2294d3SIgnacio Encinas #define _ASM_RISCV_SWAB_H 4*cc2294d3SIgnacio Encinas 5*cc2294d3SIgnacio Encinas #include <linux/types.h> 6*cc2294d3SIgnacio Encinas #include <linux/compiler.h> 7*cc2294d3SIgnacio Encinas #include <asm/cpufeature-macros.h> 8*cc2294d3SIgnacio Encinas #include <asm/hwcap.h> 9*cc2294d3SIgnacio Encinas #include <asm-generic/swab.h> 10*cc2294d3SIgnacio Encinas 11*cc2294d3SIgnacio Encinas #if defined(CONFIG_TOOLCHAIN_HAS_ZBB) && defined(CONFIG_RISCV_ISA_ZBB) && !defined(NO_ALTERNATIVE) 12*cc2294d3SIgnacio Encinas 13*cc2294d3SIgnacio Encinas // Duplicated from include/uapi/linux/swab.h 14*cc2294d3SIgnacio Encinas #define ___constant_swab16(x) ((__u16)( \ 15*cc2294d3SIgnacio Encinas (((__u16)(x) & (__u16)0x00ffU) << 8) | \ 16*cc2294d3SIgnacio Encinas (((__u16)(x) & (__u16)0xff00U) >> 8))) 17*cc2294d3SIgnacio Encinas 18*cc2294d3SIgnacio Encinas #define ___constant_swab32(x) ((__u32)( \ 19*cc2294d3SIgnacio Encinas (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ 20*cc2294d3SIgnacio Encinas (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ 21*cc2294d3SIgnacio Encinas (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ 22*cc2294d3SIgnacio Encinas (((__u32)(x) & (__u32)0xff000000UL) >> 24))) 23*cc2294d3SIgnacio Encinas 24*cc2294d3SIgnacio Encinas #define ___constant_swab64(x) ((__u64)( \ 25*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ 26*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ 27*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ 28*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ 29*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ 30*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ 31*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ 32*cc2294d3SIgnacio Encinas (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56))) 33*cc2294d3SIgnacio Encinas 34*cc2294d3SIgnacio Encinas #define ARCH_SWAB(size, value) \ 35*cc2294d3SIgnacio Encinas ({ \ 36*cc2294d3SIgnacio Encinas unsigned long x = value; \ 37*cc2294d3SIgnacio Encinas \ 38*cc2294d3SIgnacio Encinas if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) { \ 39*cc2294d3SIgnacio Encinas asm volatile (".option push\n" \ 40*cc2294d3SIgnacio Encinas ".option arch,+zbb\n" \ 41*cc2294d3SIgnacio Encinas "rev8 %0, %1\n" \ 42*cc2294d3SIgnacio Encinas ".option pop\n" \ 43*cc2294d3SIgnacio Encinas : "=r" (x) : "r" (x)); \ 44*cc2294d3SIgnacio Encinas x = x >> (BITS_PER_LONG - size); \ 45*cc2294d3SIgnacio Encinas } else { \ 46*cc2294d3SIgnacio Encinas x = ___constant_swab##size(value); \ 47*cc2294d3SIgnacio Encinas } \ 48*cc2294d3SIgnacio Encinas x; \ 49*cc2294d3SIgnacio Encinas }) 50*cc2294d3SIgnacio Encinas __arch_swab16(__u16 value)51*cc2294d3SIgnacio Encinasstatic __always_inline __u16 __arch_swab16(__u16 value) 52*cc2294d3SIgnacio Encinas { 53*cc2294d3SIgnacio Encinas return ARCH_SWAB(16, value); 54*cc2294d3SIgnacio Encinas } 55*cc2294d3SIgnacio Encinas __arch_swab32(__u32 value)56*cc2294d3SIgnacio Encinasstatic __always_inline __u32 __arch_swab32(__u32 value) 57*cc2294d3SIgnacio Encinas { 58*cc2294d3SIgnacio Encinas return ARCH_SWAB(32, value); 59*cc2294d3SIgnacio Encinas } 60*cc2294d3SIgnacio Encinas 61*cc2294d3SIgnacio Encinas #ifdef CONFIG_64BIT __arch_swab64(__u64 value)62*cc2294d3SIgnacio Encinasstatic __always_inline __u64 __arch_swab64(__u64 value) 63*cc2294d3SIgnacio Encinas { 64*cc2294d3SIgnacio Encinas return ARCH_SWAB(64, value); 65*cc2294d3SIgnacio Encinas } 66*cc2294d3SIgnacio Encinas #else __arch_swab64(__u64 value)67*cc2294d3SIgnacio Encinasstatic __always_inline __u64 __arch_swab64(__u64 value) 68*cc2294d3SIgnacio Encinas { 69*cc2294d3SIgnacio Encinas __u32 h = value >> 32; 70*cc2294d3SIgnacio Encinas __u32 l = value & ((1ULL << 32) - 1); 71*cc2294d3SIgnacio Encinas 72*cc2294d3SIgnacio Encinas return ((__u64)(__arch_swab32(l)) << 32) | ((__u64)(__arch_swab32(h))); 73*cc2294d3SIgnacio Encinas } 74*cc2294d3SIgnacio Encinas #endif 75*cc2294d3SIgnacio Encinas 76*cc2294d3SIgnacio Encinas #define __arch_swab64 __arch_swab64 77*cc2294d3SIgnacio Encinas #define __arch_swab32 __arch_swab32 78*cc2294d3SIgnacio Encinas #define __arch_swab16 __arch_swab16 79*cc2294d3SIgnacio Encinas 80*cc2294d3SIgnacio Encinas #undef ___constant_swab16 81*cc2294d3SIgnacio Encinas #undef ___constant_swab32 82*cc2294d3SIgnacio Encinas #undef ___constant_swab64 83*cc2294d3SIgnacio Encinas 84*cc2294d3SIgnacio Encinas #undef ARCH_SWAB 85*cc2294d3SIgnacio Encinas 86*cc2294d3SIgnacio Encinas #endif /* defined(CONFIG_TOOLCHAIN_HAS_ZBB) && defined(CONFIG_RISCV_ISA_ZBB) && !defined(NO_ALTERNATIVE) */ 87*cc2294d3SIgnacio Encinas #endif /* _ASM_RISCV_SWAB_H */ 88