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, int len)
20 ###############################################################################
22 .type do_csum,@function
31 ble do_csum_done # check for zero length or negative
33 # 4-byte align the buffer pointer
35 beq do_csum_now_4b_aligned
38 beq do_csum_addr_not_odd
47 bcs do_csum_fewer_than_4
49 beq do_csum_now_4b_aligned
54 bcs do_csum_fewer_than_4
56 do_csum_now_4b_aligned:
57 # we want to checksum as much as we can in chunks of 32 bytes
59 bls do_csum_remainder # 4-byte aligned remainder
90 # cut 16-31 bytes down to 0-15
92 bcs do_csum_fewer_than_16
105 do_csum_fewer_than_16:
106 # copy the remaining whole words
108 bcs do_csum_fewer_than_4
112 bcs do_csum_two_words
125 do_csum_fewer_than_4:
129 bcs do_csum_fewer_than_2
132 beq do_csum_add_last_bit
133 do_csum_fewer_than_2:
136 do_csum_add_last_bit:
141 # compress the checksum down to 16 bits
149 # flip the halves of the word result if the buffer was oddly aligned
151 beq do_csum_not_oddly_aligned
152 swaph d0,d0 # exchange bits 15:8 with 7:0
154 do_csum_not_oddly_aligned:
157 .size do_csum, .-do_csum