summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);