aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYalin Wang <Yalin.Wang@sonymobile.com>2014-11-02 21:01:03 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-12-22 11:43:06 -0500
commit556d2f055bf6d79ce81587dfe774d4dd10da473f (patch)
tree3b1eaeda540d1592936691f953607a377668f90f
parent97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff)
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: Yalin Wang <yalin.wang@sonymobile.com> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--include/linux/bitrev.h77
-rw-r--r--lib/Kconfig9
-rw-r--r--lib/bitrev.c17
3 files changed, 84 insertions, 19 deletions
diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h
index 7ffe03f4693d..fb790b8449c1 100644
--- a/include/linux/bitrev.h
+++ b/include/linux/bitrev.h
@@ -3,14 +3,83 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6extern u8 const byte_rev_table[256]; 6#ifdef CONFIG_HAVE_ARCH_BITREVERSE
7#include <asm/bitrev.h>
8
9#define __bitrev32 __arch_bitrev32
10#define __bitrev16 __arch_bitrev16
11#define __bitrev8 __arch_bitrev8
7 12
8static inline u8 bitrev8(u8 byte) 13#else
14extern u8 const byte_rev_table[256];
15static inline u8 __bitrev8(u8 byte)
9{ 16{
10 return byte_rev_table[byte]; 17 return byte_rev_table[byte];
11} 18}
12 19
13extern u16 bitrev16(u16 in); 20static inline u16 __bitrev16(u16 x)
14extern u32 bitrev32(u32 in); 21{
22 return (__bitrev8(x & 0xff) << 8) | __bitrev8(x >> 8);
23}
24
25static inline u32 __bitrev32(u32 x)
26{
27 return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16);
28}
29
30#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
31
32#define __constant_bitrev32(x) \
33({ \
34 u32 __x = x; \
35 __x = (__x >> 16) | (__x << 16); \
36 __x = ((__x & (u32)0xFF00FF00UL) >> 8) | ((__x & (u32)0x00FF00FFUL) << 8); \
37 __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \
38 __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \
39 __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \
40 __x; \
41})
42
43#define __constant_bitrev16(x) \
44({ \
45 u16 __x = x; \
46 __x = (__x >> 8) | (__x << 8); \
47 __x = ((__x & (u16)0xF0F0U) >> 4) | ((__x & (u16)0x0F0FU) << 4); \
48 __x = ((__x & (u16)0xCCCCU) >> 2) | ((__x & (u16)0x3333U) << 2); \
49 __x = ((__x & (u16)0xAAAAU) >> 1) | ((__x & (u16)0x5555U) << 1); \
50 __x; \
51})
52
53#define __constant_bitrev8(x) \
54({ \
55 u8 __x = x; \
56 __x = (__x >> 4) | (__x << 4); \
57 __x = ((__x & (u8)0xCCU) >> 2) | ((__x & (u8)0x33U) << 2); \
58 __x = ((__x & (u8)0xAAU) >> 1) | ((__x & (u8)0x55U) << 1); \
59 __x; \
60})
61
62#define bitrev32(x) \
63({ \
64 u32 __x = x; \
65 __builtin_constant_p(__x) ? \
66 __constant_bitrev32(__x) : \
67 __bitrev32(__x); \
68})
69
70#define bitrev16(x) \
71({ \
72 u16 __x = x; \
73 __builtin_constant_p(__x) ? \
74 __constant_bitrev16(__x) : \
75 __bitrev16(__x); \
76 })
15 77
78#define bitrev8(x) \
79({ \
80 u8 __x = x; \
81 __builtin_constant_p(__x) ? \
82 __constant_bitrev8(__x) : \
83 __bitrev8(__x) ; \
84 })
16#endif /* _LINUX_BITREV_H */ 85#endif /* _LINUX_BITREV_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 54cf309a92a5..cd177caf3876 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -13,6 +13,15 @@ config RAID6_PQ
13config BITREVERSE 13config BITREVERSE
14 tristate 14 tristate
15 15
16config HAVE_ARCH_BITREVERSE
17 boolean
18 default n
19 depends on BITREVERSE
20 help
21 This option provides an config for the architecture which have instruction
22 can do bitreverse operation, we use the hardware instruction if the architecture
23 have this capability.
24
16config RATIONAL 25config RATIONAL
17 boolean 26 boolean
18 27
diff --git a/lib/bitrev.c b/lib/bitrev.c
index 3956203456d4..40ffda94cc5d 100644
--- a/lib/bitrev.c
+++ b/lib/bitrev.c
@@ -1,3 +1,4 @@
1#ifndef CONFIG_HAVE_ARCH_BITREVERSE
1#include <linux/types.h> 2#include <linux/types.h>
2#include <linux/module.h> 3#include <linux/module.h>
3#include <linux/bitrev.h> 4#include <linux/bitrev.h>
@@ -42,18 +43,4 @@ const u8 byte_rev_table[256] = {
42}; 43};
43EXPORT_SYMBOL_GPL(byte_rev_table); 44EXPORT_SYMBOL_GPL(byte_rev_table);
44 45
45u16 bitrev16(u16 x) 46#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
46{
47 return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
48}
49EXPORT_SYMBOL(bitrev16);
50
51/**
52 * bitrev32 - reverse the order of bits in a u32 value
53 * @x: value to be bit-reversed
54 */
55u32 bitrev32(u32 x)
56{
57 return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
58}
59EXPORT_SYMBOL(bitrev32);