diff options
author | Ian Abbott <abbotti@mev.co.uk> | 2011-07-06 21:18:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-07 07:52:24 -0400 |
commit | be0e1e788b0973147b6b83cc940676cc26009eb7 (patch) | |
tree | 75083bdb5b5d9e266b0c632406d67f69505d527c /lib/checksum.c | |
parent | 97bc3633bec7ed0fdfbda6b9cf86c51e4f58f8e2 (diff) |
lib/checksum.c: optimize do_csum a bit
Reduce the number of variables modified by the loop in do_csum() by 1,
which seems like a good idea. On Nios II (a RISC CPU with 3-operand
instruction set) it reduces the loop from 7 to 6 instructions, including
the conditional branch.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib/checksum.c')
-rw-r--r-- | lib/checksum.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/lib/checksum.c b/lib/checksum.c index 097508732f34..8df2f91e6d98 100644 --- a/lib/checksum.c +++ b/lib/checksum.c | |||
@@ -49,7 +49,7 @@ static inline unsigned short from32to16(unsigned int x) | |||
49 | 49 | ||
50 | static unsigned int do_csum(const unsigned char *buff, int len) | 50 | static unsigned int do_csum(const unsigned char *buff, int len) |
51 | { | 51 | { |
52 | int odd, count; | 52 | int odd; |
53 | unsigned int result = 0; | 53 | unsigned int result = 0; |
54 | 54 | ||
55 | if (len <= 0) | 55 | if (len <= 0) |
@@ -64,25 +64,22 @@ static unsigned int do_csum(const unsigned char *buff, int len) | |||
64 | len--; | 64 | len--; |
65 | buff++; | 65 | buff++; |
66 | } | 66 | } |
67 | count = len >> 1; /* nr of 16-bit words.. */ | 67 | if (len >= 2) { |
68 | if (count) { | ||
69 | if (2 & (unsigned long) buff) { | 68 | if (2 & (unsigned long) buff) { |
70 | result += *(unsigned short *) buff; | 69 | result += *(unsigned short *) buff; |
71 | count--; | ||
72 | len -= 2; | 70 | len -= 2; |
73 | buff += 2; | 71 | buff += 2; |
74 | } | 72 | } |
75 | count >>= 1; /* nr of 32-bit words.. */ | 73 | if (len >= 4) { |
76 | if (count) { | 74 | const unsigned char *end = buff + ((unsigned)len & ~3); |
77 | unsigned int carry = 0; | 75 | unsigned int carry = 0; |
78 | do { | 76 | do { |
79 | unsigned int w = *(unsigned int *) buff; | 77 | unsigned int w = *(unsigned int *) buff; |
80 | count--; | ||
81 | buff += 4; | 78 | buff += 4; |
82 | result += carry; | 79 | result += carry; |
83 | result += w; | 80 | result += w; |
84 | carry = (w > result); | 81 | carry = (w > result); |
85 | } while (count); | 82 | } while (buff < end); |
86 | result += carry; | 83 | result += carry; |
87 | result = (result & 0xffff) + (result >> 16); | 84 | result = (result & 0xffff) + (result >> 16); |
88 | } | 85 | } |