MIPS: Implement __arch_bitrev* using bitswap for MIPSr6
authorPaul Burton <paul.burton@imgtec.com>
Fri, 6 May 2016 12:35:03 +0000 (13:35 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 13 May 2016 12:02:17 +0000 (14:02 +0200)
Release 6 of the MIPS architecture introduced the bitswap instruction,
which reverses the bits within each byte of a word. Make use of this
instruction to implement the __arch_bitrev* functions, which should be
faster for most MIPSr6 CPUs, reduces code size slightly and allows us to
avoid the lookup table used by the generic implementation, saving 256
bytes in the kernel binary by dropping that.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/13204/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/Kconfig
arch/mips/include/asm/bitrev.h [new file with mode: 0644]

index 2b7af90..95f0582 100644 (file)
@@ -2000,6 +2000,7 @@ config CPU_MIPSR2
 config CPU_MIPSR6
        bool
        default y if CPU_MIPS32_R6 || CPU_MIPS64_R6
+       select HAVE_ARCH_BITREVERSE
        select MIPS_SPRAM
 
 config EVA
diff --git a/arch/mips/include/asm/bitrev.h b/arch/mips/include/asm/bitrev.h
new file mode 100644 (file)
index 0000000..bc739a4
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __MIPS_ASM_BITREV_H__
+#define __MIPS_ASM_BITREV_H__
+
+#include <linux/swab.h>
+
+static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
+{
+       u32 ret;
+
+       asm("bitswap    %0, %1" : "=r"(ret) : "r"(__swab32(x)));
+       return ret;
+}
+
+static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
+{
+       u16 ret;
+
+       asm("bitswap    %0, %1" : "=r"(ret) : "r"(__swab16(x)));
+       return ret;
+}
+
+static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
+{
+       u8 ret;
+
+       asm("bitswap    %0, %1" : "=r"(ret) : "r"(x));
+       return ret;
+}
+
+#endif /* __MIPS_ASM_BITREV_H__ */