Skip to content

Commit

Permalink
ARM: 8187/1: add CONFIG_HAVE_ARCH_BITREVERSE to support rbit instruction
Browse files Browse the repository at this point in the history
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: Yalin Wang <[email protected]>
Acked-by: Will Deacon <[email protected]>
Signed-off-by: Russell King <[email protected]>
  • Loading branch information
Yalin Wang authored and Russell King committed Dec 22, 2014
1 parent 97bf6af commit 556d2f0
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 19 deletions.
77 changes: 73 additions & 4 deletions include/linux/bitrev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 9 additions & 0 deletions lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 2 additions & 15 deletions lib/bitrev.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#ifndef CONFIG_HAVE_ARCH_BITREVERSE
#include <linux/types.h>
#include <linux/module.h>
#include <linux/bitrev.h>
Expand Down Expand Up @@ -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 */

0 comments on commit 556d2f0

Please sign in to comment.