Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 556d2f05 authored by Yalin Wang's avatar Yalin Wang Committed by Russell King
Browse files

ARM: 8187/1: add CONFIG_HAVE_ARCH_BITREVERSE to support rbit instruction



this change add CONFIG_HAVE_ARCH_BITREVERSE config option,
so that we can use some architecture's bitrev hardware instruction
to do bitrev operation.

Introduce __constant_bitrev* macro for constant bitrev operation.

Change __bitrev16() __bitrev32() to be inline function,
don't need export symbol for these tiny functions.

Signed-off-by: default avatarYalin Wang <yalin.wang@sonymobile.com>
Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 97bf6af1
Loading
Loading
Loading
Loading
+73 −4
Original line number Diff line number Diff line
@@ -3,14 +3,83 @@

#include <linux/types.h>

extern u8 const byte_rev_table[256];
#ifdef CONFIG_HAVE_ARCH_BITREVERSE
#include <asm/bitrev.h>

#define __bitrev32 __arch_bitrev32
#define __bitrev16 __arch_bitrev16
#define __bitrev8 __arch_bitrev8

static inline u8 bitrev8(u8 byte)
#else
extern u8 const byte_rev_table[256];
static inline u8 __bitrev8(u8 byte)
{
	return byte_rev_table[byte];
}

extern u16 bitrev16(u16 in);
extern u32 bitrev32(u32 in);
static inline u16 __bitrev16(u16 x)
{
	return (__bitrev8(x & 0xff) << 8) | __bitrev8(x >> 8);
}

static inline u32 __bitrev32(u32 x)
{
	return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16);
}

#endif /* CONFIG_HAVE_ARCH_BITREVERSE */

#define __constant_bitrev32(x)	\
({					\
	u32 __x = x;			\
	__x = (__x >> 16) | (__x << 16);	\
	__x = ((__x & (u32)0xFF00FF00UL) >> 8) | ((__x & (u32)0x00FF00FFUL) << 8);	\
	__x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4);	\
	__x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2);	\
	__x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1);	\
	__x;								\
})

#define __constant_bitrev16(x)	\
({					\
	u16 __x = x;			\
	__x = (__x >> 8) | (__x << 8);	\
	__x = ((__x & (u16)0xF0F0U) >> 4) | ((__x & (u16)0x0F0FU) << 4);	\
	__x = ((__x & (u16)0xCCCCU) >> 2) | ((__x & (u16)0x3333U) << 2);	\
	__x = ((__x & (u16)0xAAAAU) >> 1) | ((__x & (u16)0x5555U) << 1);	\
	__x;								\
})

#define __constant_bitrev8(x)	\
({					\
	u8 __x = x;			\
	__x = (__x >> 4) | (__x << 4);	\
	__x = ((__x & (u8)0xCCU) >> 2) | ((__x & (u8)0x33U) << 2);	\
	__x = ((__x & (u8)0xAAU) >> 1) | ((__x & (u8)0x55U) << 1);	\
	__x;								\
})

#define bitrev32(x) \
({			\
	u32 __x = x;	\
	__builtin_constant_p(__x) ?	\
	__constant_bitrev32(__x) :			\
	__bitrev32(__x);				\
})

#define bitrev16(x) \
({			\
	u16 __x = x;	\
	__builtin_constant_p(__x) ?	\
	__constant_bitrev16(__x) :			\
	__bitrev16(__x);				\
 })

#define bitrev8(x) \
({			\
	u8 __x = x;	\
	__builtin_constant_p(__x) ?	\
	__constant_bitrev8(__x) :			\
	__bitrev8(__x)	;			\
 })
#endif /* _LINUX_BITREV_H */
+9 −0
Original line number Diff line number Diff line
@@ -13,6 +13,15 @@ config RAID6_PQ
config BITREVERSE
	tristate

config HAVE_ARCH_BITREVERSE
	boolean
	default n
	depends on BITREVERSE
	help
	  This option provides an config for the architecture which have instruction
	  can do bitreverse operation, we use the hardware instruction if the architecture
	  have this capability.

config RATIONAL
	boolean

+2 −15
Original line number Diff line number Diff line
#ifndef CONFIG_HAVE_ARCH_BITREVERSE
#include <linux/types.h>
#include <linux/module.h>
#include <linux/bitrev.h>
@@ -42,18 +43,4 @@ const u8 byte_rev_table[256] = {
};
EXPORT_SYMBOL_GPL(byte_rev_table);

u16 bitrev16(u16 x)
{
	return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
}
EXPORT_SYMBOL(bitrev16);

/**
 * bitrev32 - reverse the order of bits in a u32 value
 * @x: value to be bit-reversed
 */
u32 bitrev32(u32 x)
{
	return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
}
EXPORT_SYMBOL(bitrev32);
#endif /* CONFIG_HAVE_ARCH_BITREVERSE */