1 /* Optimised simple memory checksum
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
11 #include <asm/cache.h>
14 .balign L1_CACHE_BYTES
16 ###############################################################################
18 # unsigned int do_csum(const unsigned char *buff, size_t len)
20 ###############################################################################
22 .type do_csum,@function
32 beq do_csum_done # return if zero-length buffer
34 # 4-byte align the buffer pointer
36 beq do_csum_now_4b_aligned
39 beq do_csum_addr_not_odd
49 bcs do_csum_fewer_than_4
51 beq do_csum_now_4b_aligned
57 bcs do_csum_fewer_than_4
59 do_csum_now_4b_aligned:
60 # we want to checksum as much as we can in chunks of 32 bytes
62 bls do_csum_remainder # 4-byte aligned remainder
93 # cut 16-31 bytes down to 0-15
95 bcs do_csum_fewer_than_16
108 do_csum_fewer_than_16:
109 # copy the remaining whole words
111 bcs do_csum_fewer_than_4
115 bcs do_csum_two_words
128 do_csum_fewer_than_4:
132 bcs do_csum_fewer_than_2
134 do_csum_fewer_than_2:
136 beq do_csum_add_last_bit
139 do_csum_add_last_bit:
144 # compress the checksum down to 16 bits
152 # flip the halves of the word result if the buffer was oddly aligned
155 beq do_csum_not_oddly_aligned
156 swaph d0,d0 # exchange bits 15:8 with 7:0
158 do_csum_not_oddly_aligned:
162 .size do_csum, do_csum_end-do_csum