diff options
author | Bob Pearson <rpearson@systemfabricworks.com> | 2012-03-23 18:02:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:37 -0400 |
commit | 324eb0f17d9dcead3c60c133aa244f6b3631fec9 (patch) | |
tree | 657c564269a0fc1921f4252dbf0184725f5c85fa /lib/crc32.c | |
parent | 9a1dbf6a29694c9d81b498019f103aee0f8b5b6c (diff) |
crc32: add slice-by-8 algorithm to existing code
Add slicing-by-8 algorithm to the existing slicing-by-4 algorithm. This
consists of:
- extend largest BITS size from 32 to 64
- extend tables from tab[4][256] to up to tab[8][256]
- Add code for inner loop.
[djwong@us.ibm.com: Minor changelog tweaks]
Signed-off-by: Bob Pearson <rpearson@systemfabricworks.com>
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/crc32.c')
-rw-r--r-- | lib/crc32.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/lib/crc32.c b/lib/crc32.c index 5971f2ad46d5..826e16352e0e 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
@@ -47,25 +47,28 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | #if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 | 48 | #if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 |
49 | 49 | ||
50 | /* implements slicing-by-4 or slicing-by-8 algorithm */ | ||
50 | static inline u32 | 51 | static inline u32 |
51 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) | 52 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) |
52 | { | 53 | { |
53 | # ifdef __LITTLE_ENDIAN | 54 | # ifdef __LITTLE_ENDIAN |
54 | # define DO_CRC(x) crc = t0[(crc ^ (x)) & 255] ^ (crc >> 8) | 55 | # define DO_CRC(x) crc = t0[(crc ^ (x)) & 255] ^ (crc >> 8) |
55 | # define DO_CRC4 crc = t3[(crc) & 255] ^ \ | 56 | # define DO_CRC4 (t3[(q) & 255] ^ t2[(q >> 8) & 255] ^ \ |
56 | t2[(crc >> 8) & 255] ^ \ | 57 | t1[(q >> 16) & 255] ^ t0[(q >> 24) & 255]) |
57 | t1[(crc >> 16) & 255] ^ \ | 58 | # define DO_CRC8 (t7[(q) & 255] ^ t6[(q >> 8) & 255] ^ \ |
58 | t0[(crc >> 24) & 255] | 59 | t5[(q >> 16) & 255] ^ t4[(q >> 24) & 255]) |
59 | # else | 60 | # else |
60 | # define DO_CRC(x) crc = t0[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) | 61 | # define DO_CRC(x) crc = t0[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) |
61 | # define DO_CRC4 crc = t0[(crc) & 255] ^ \ | 62 | # define DO_CRC4 (t0[(q) & 255] ^ t1[(q >> 8) & 255] ^ \ |
62 | t1[(crc >> 8) & 255] ^ \ | 63 | t2[(q >> 16) & 255] ^ t3[(q >> 24) & 255]) |
63 | t2[(crc >> 16) & 255] ^ \ | 64 | # define DO_CRC8 (t4[(q) & 255] ^ t5[(q >> 8) & 255] ^ \ |
64 | t3[(crc >> 24) & 255] | 65 | t6[(q >> 16) & 255] ^ t7[(q >> 24) & 255]) |
65 | # endif | 66 | # endif |
66 | const u32 *b; | 67 | const u32 *b; |
67 | size_t rem_len; | 68 | size_t rem_len; |
68 | const u32 *t0=tab[0], *t1=tab[1], *t2=tab[2], *t3=tab[3]; | 69 | const u32 *t0=tab[0], *t1=tab[1], *t2=tab[2], *t3=tab[3]; |
70 | const u32 *t4 = tab[4], *t5 = tab[5], *t6 = tab[6], *t7 = tab[7]; | ||
71 | u32 q; | ||
69 | 72 | ||
70 | /* Align it */ | 73 | /* Align it */ |
71 | if (unlikely((long)buf & 3 && len)) { | 74 | if (unlikely((long)buf & 3 && len)) { |
@@ -73,13 +76,25 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) | |||
73 | DO_CRC(*buf++); | 76 | DO_CRC(*buf++); |
74 | } while ((--len) && ((long)buf)&3); | 77 | } while ((--len) && ((long)buf)&3); |
75 | } | 78 | } |
79 | |||
80 | # if CRC_LE_BITS == 32 | ||
76 | rem_len = len & 3; | 81 | rem_len = len & 3; |
77 | /* load data 32 bits wide, xor data 32 bits wide. */ | ||
78 | len = len >> 2; | 82 | len = len >> 2; |
83 | # else | ||
84 | rem_len = len & 7; | ||
85 | len = len >> 3; | ||
86 | # endif | ||
87 | |||
79 | b = (const u32 *)buf; | 88 | b = (const u32 *)buf; |
80 | for (--b; len; --len) { | 89 | for (--b; len; --len) { |
81 | crc ^= *++b; /* use pre increment for speed */ | 90 | q = crc ^ *++b; /* use pre increment for speed */ |
82 | DO_CRC4; | 91 | # if CRC_LE_BITS == 32 |
92 | crc = DO_CRC4; | ||
93 | # else | ||
94 | crc = DO_CRC8; | ||
95 | q = *++b; | ||
96 | crc ^= DO_CRC4; | ||
97 | # endif | ||
83 | } | 98 | } |
84 | len = rem_len; | 99 | len = rem_len; |
85 | /* And the last few bytes */ | 100 | /* And the last few bytes */ |
@@ -92,6 +107,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) | |||
92 | return crc; | 107 | return crc; |
93 | #undef DO_CRC | 108 | #undef DO_CRC |
94 | #undef DO_CRC4 | 109 | #undef DO_CRC4 |
110 | #undef DO_CRC8 | ||
95 | } | 111 | } |
96 | #endif | 112 | #endif |
97 | 113 | ||