2 * arch/score/lib/csum_partial.S
4 * Score Processor version.
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <linux/linkage.h>
27 #define ADDC(sum,reg) \
34 #define CSUM_BIGCHUNK(src, offset, sum) \
35 lw r8, [src, offset + 0x00]; \
36 lw r9, [src, offset + 0x04]; \
37 lw r10, [src, offset + 0x08]; \
38 lw r11, [src, offset + 0x0c]; \
43 lw r8, [src, offset + 0x10]; \
44 lw r9, [src, offset + 0x14]; \
45 lw r10, [src, offset + 0x18]; \
46 lw r11, [src, offset + 0x1c]; \
57 /* unknown src alignment and < 8 bytes to go */
62 beq pass_small_set_t7 /*already set, jump to pass_small_set_t7*/
63 andri.c r25,r4 , 0x1 /*Is src 2 bytes aligned?*/
70 slli r9,r9, 0x8 /*Little endian*/
75 /*len still a full word */
77 andri.c r8, r5, 0x4 /*Len >= 4?*/
80 /* Still a full word (4byte) to go,and the src is word aligned.*/
81 andri.c r8, src, 0x3 /*src is 4bytes aligned, so use LW!!*/
91 four_byte_aligned: /* Len >=4 and four byte aligned */
96 len_less_4bytes: /* 2 byte aligned aligned and length<4B */
100 addi src, 0x2 /* src+=2 */
103 len_less_2bytes: /* len = 1 */
105 beq fold /* less than 2 and not equal 1--> len=0 -> fold */
116 bleu 1f /* if r26<=sum */
117 addi sum, 0x1 /* r26>sum */
119 /* odd buffer alignment? r25 was set in csum_partial */
128 /* Add the passed partial csum. */
140 blt small_csumcpy /* < 8(singed) bytes to copy */
143 andri.c r25, src, 0x1 /* odd buffer? */
146 hword_align: /* 1 byte */
153 word_align: /* 2 bytes */
154 andri.c r8, src, 0x2 /* 4bytes(dword)_aligned? */
155 beq dword_align /* not, maybe dword_align */
161 dword_align: /* 4bytes */
162 mv r26, r5 /* maybe useless when len >=56 */
165 bgtu do_end_words /* if a1(len)<t0(56) ,unsigned */
166 andri.c r26, src, 0x4
173 qword_align: /* 8 bytes */
174 andri.c r26, src, 0x8
178 subi r5, 0x8 /* len-=0x8 */
183 oword_align: /* 16bytes */
184 andri.c r26, src, 0x10
198 srli.c r26, r5, 0x7 /* len>=128? */
201 /* r26 is the result that computed in oword_align */
203 CSUM_BIGCHUNK(src, 0x00, sum)
204 CSUM_BIGCHUNK(src, 0x20, sum)
205 CSUM_BIGCHUNK(src, 0x40, sum)
206 CSUM_BIGCHUNK(src, 0x60, sum)
207 subi.c r26, 0x01 /* r26 equals len/128 */
211 1: /* len<128,we process 64byte here */
212 andri.c r10, r5, 0x40
216 CSUM_BIGCHUNK(src, 0x00, sum)
217 CSUM_BIGCHUNK(src, 0x20, sum)
221 andri r26, r5, 0x1c /* 0x1c=28 */
222 andri.c r10, r5, 0x20
223 beq do_end_words /* decided by andri */
226 CSUM_BIGCHUNK(src, 0x00, sum)
230 do_end_words: /* len<32 */
231 /* r26 was set already in dword_align */
233 beq maybe_end_cruft /* len<28 or len<56 */
238 subi.c r26, 0x1 /* unit is 4 byte */
242 bne end_words /* r26!=0 */
244 maybe_end_cruft: /* len<4 */