aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crc32.c')
-rw-r--r--lib/crc32.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/lib/crc32.c b/lib/crc32.c
index 02e3b31b3a79..4855995fcde9 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -25,16 +25,19 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/compiler.h> 26#include <linux/compiler.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/slab.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <asm/atomic.h> 29#include <asm/atomic.h>
31#include "crc32defs.h" 30#include "crc32defs.h"
32#if CRC_LE_BITS == 8 31#if CRC_LE_BITS == 8
33#define tole(x) __constant_cpu_to_le32(x) 32# define tole(x) __constant_cpu_to_le32(x)
34#define tobe(x) __constant_cpu_to_be32(x)
35#else 33#else
36#define tole(x) (x) 34# define tole(x) (x)
37#define tobe(x) (x) 35#endif
36
37#if CRC_BE_BITS == 8
38# define tobe(x) __constant_cpu_to_be32(x)
39#else
40# define tobe(x) (x)
38#endif 41#endif
39#include "crc32table.h" 42#include "crc32table.h"
40 43
@@ -45,33 +48,37 @@ MODULE_LICENSE("GPL");
45#if CRC_LE_BITS == 8 || CRC_BE_BITS == 8 48#if CRC_LE_BITS == 8 || CRC_BE_BITS == 8
46 49
47static inline u32 50static inline u32
48crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) 51crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
49{ 52{
50# ifdef __LITTLE_ENDIAN 53# ifdef __LITTLE_ENDIAN
51# define DO_CRC(x) crc = tab[(crc ^ (x)) & 255 ] ^ (crc >> 8) 54# define DO_CRC(x) crc = tab[0][(crc ^ (x)) & 255] ^ (crc >> 8)
55# define DO_CRC4 crc = tab[3][(crc) & 255] ^ \
56 tab[2][(crc >> 8) & 255] ^ \
57 tab[1][(crc >> 16) & 255] ^ \
58 tab[0][(crc >> 24) & 255]
52# else 59# else
53# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) 60# define DO_CRC(x) crc = tab[0][((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
61# define DO_CRC4 crc = tab[0][(crc) & 255] ^ \
62 tab[1][(crc >> 8) & 255] ^ \
63 tab[2][(crc >> 16) & 255] ^ \
64 tab[3][(crc >> 24) & 255]
54# endif 65# endif
55 const u32 *b = (const u32 *)buf; 66 const u32 *b;
56 size_t rem_len; 67 size_t rem_len;
57 68
58 /* Align it */ 69 /* Align it */
59 if (unlikely((long)b & 3 && len)) { 70 if (unlikely((long)buf & 3 && len)) {
60 u8 *p = (u8 *)b;
61 do { 71 do {
62 DO_CRC(*p++); 72 DO_CRC(*buf++);
63 } while ((--len) && ((long)p)&3); 73 } while ((--len) && ((long)buf)&3);
64 b = (u32 *)p;
65 } 74 }
66 rem_len = len & 3; 75 rem_len = len & 3;
67 /* load data 32 bits wide, xor data 32 bits wide. */ 76 /* load data 32 bits wide, xor data 32 bits wide. */
68 len = len >> 2; 77 len = len >> 2;
78 b = (const u32 *)buf;
69 for (--b; len; --len) { 79 for (--b; len; --len) {
70 crc ^= *++b; /* use pre increment for speed */ 80 crc ^= *++b; /* use pre increment for speed */
71 DO_CRC(0); 81 DO_CRC4;
72 DO_CRC(0);
73 DO_CRC(0);
74 DO_CRC(0);
75 } 82 }
76 len = rem_len; 83 len = rem_len;
77 /* And the last few bytes */ 84 /* And the last few bytes */
@@ -82,6 +89,8 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
82 } while (--len); 89 } while (--len);
83 } 90 }
84 return crc; 91 return crc;
92#undef DO_CRC
93#undef DO_CRC4
85} 94}
86#endif 95#endif
87/** 96/**
@@ -114,14 +123,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
114u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) 123u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
115{ 124{
116# if CRC_LE_BITS == 8 125# if CRC_LE_BITS == 8
117 const u32 *tab = crc32table_le; 126 const u32 (*tab)[] = crc32table_le;
118 127
119 crc = __cpu_to_le32(crc); 128 crc = __cpu_to_le32(crc);
120 crc = crc32_body(crc, p, len, tab); 129 crc = crc32_body(crc, p, len, tab);
121 return __le32_to_cpu(crc); 130 return __le32_to_cpu(crc);
122#undef ENDIAN_SHIFT
123#undef DO_CRC
124
125# elif CRC_LE_BITS == 4 131# elif CRC_LE_BITS == 4
126 while (len--) { 132 while (len--) {
127 crc ^= *p++; 133 crc ^= *p++;
@@ -174,14 +180,11 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
174u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) 180u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
175{ 181{
176# if CRC_BE_BITS == 8 182# if CRC_BE_BITS == 8
177 const u32 *tab = crc32table_be; 183 const u32 (*tab)[] = crc32table_be;
178 184
179 crc = __cpu_to_be32(crc); 185 crc = __cpu_to_be32(crc);
180 crc = crc32_body(crc, p, len, tab); 186 crc = crc32_body(crc, p, len, tab);
181 return __be32_to_cpu(crc); 187 return __be32_to_cpu(crc);
182#undef ENDIAN_SHIFT
183#undef DO_CRC
184
185# elif CRC_BE_BITS == 4 188# elif CRC_BE_BITS == 4
186 while (len--) { 189 while (len--) {
187 crc ^= *p++ << 24; 190 crc ^= *p++ << 24;