OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [i386/] [lib/] [checksum.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * INET         An implementation of the TCP/IP protocol suite for the LINUX
3
 *              operating system.  INET is implemented using the  BSD Socket
4
 *              interface as the means of communication with the user level.
5
 *
6
 *              IP/TCP/UDP checksumming routines
7
 *
8
 * Authors:     Jorge Cwik, <jorge@laser.satlink.net>
9
 *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
10
 *              Tom May, <ftom@netcom.com>
11
 *              Lots of code moved from tcp.c and ip.c; see those files
12
 *              for more names.
13
 *
14
 *              This program is free software; you can redistribute it and/or
15
 *              modify it under the terms of the GNU General Public License
16
 *              as published by the Free Software Foundation; either version
17
 *              2 of the License, or (at your option) any later version.
18
 */
19
 
20
#include <net/checksum.h>
21
 
22
/*
23
 * computes a partial checksum, e.g. for TCP/UDP fragments
24
 */
25
 
26
unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) {
27
          /*
28
           * Experiments with ethernet and slip connections show that buff
29
           * is aligned on either a 2-byte or 4-byte boundary.  We get at
30
           * least a 2x speedup on 486 and Pentium if it is 4-byte aligned.
31
           * Fortunately, it is easy to convert 2-byte alignment to 4-byte
32
           * alignment for the unrolled loop.
33
           */
34
        __asm__("
35
            testl $2, %%esi             # Check alignment.
36
            jz 2f                       # Jump if alignment is ok.
37
            subl $2, %%ecx              # Alignment uses up two bytes.
38
            jae 1f                      # Jump if we had at least two bytes.
39
            addl $2, %%ecx              # ecx was < 2.  Deal with it.
40
            jmp 4f
41
1:          movw (%%esi), %%bx
42
            addl $2, %%esi
43
            addw %%bx, %%ax
44
            adcl $0, %%eax
45
2:
46
            movl %%ecx, %%edx
47
            shrl $5, %%ecx
48
            jz 2f
49
            testl %%esi, %%esi
50
1:          movl (%%esi), %%ebx
51
            adcl %%ebx, %%eax
52
            movl 4(%%esi), %%ebx
53
            adcl %%ebx, %%eax
54
            movl 8(%%esi), %%ebx
55
            adcl %%ebx, %%eax
56
            movl 12(%%esi), %%ebx
57
            adcl %%ebx, %%eax
58
            movl 16(%%esi), %%ebx
59
            adcl %%ebx, %%eax
60
            movl 20(%%esi), %%ebx
61
            adcl %%ebx, %%eax
62
            movl 24(%%esi), %%ebx
63
            adcl %%ebx, %%eax
64
            movl 28(%%esi), %%ebx
65
            adcl %%ebx, %%eax
66
            lea 32(%%esi), %%esi
67
            dec %%ecx
68
            jne 1b
69
            adcl $0, %%eax
70
2:          movl %%edx, %%ecx
71
            andl $0x1c, %%edx
72
            je 4f
73
            shrl $2, %%edx
74
            testl %%esi, %%esi
75
3:          adcl (%%esi), %%eax
76
            lea 4(%%esi), %%esi
77
            dec %%edx
78
            jne 3b
79
            adcl $0, %%eax
80
4:          andl $3, %%ecx
81
            jz 7f
82
            cmpl $2, %%ecx
83
            jb 5f
84
            movw (%%esi),%%cx
85
            leal 2(%%esi),%%esi
86
            je 6f
87
            shll $16,%%ecx
88
5:          movb (%%esi),%%cl
89
6:          addl %%ecx,%%eax
90
            adcl $0, %%eax
91
7:          "
92
        : "=a"(sum)
93
        : "0"(sum), "c"(len), "S"(buff)
94
        : "bx", "cx", "dx", "si");
95
        return(sum);
96
}
97
 
98
 
99
 
100
/*
101
 * copy from fs while checksumming, otherwise like csum_partial
102
 */
103
 
104
unsigned int csum_partial_copy_fromuser(const char *src, char *dst,
105
                                  int len, int sum) {
106
    __asm__("
107
        testl $2, %%edi         # Check alignment.
108
        jz 2f                   # Jump if alignment is ok.
109
        subl $2, %%ecx          # Alignment uses up two bytes.
110
        jae 1f                  # Jump if we had at least two bytes.
111
        addl $2, %%ecx          # ecx was < 2.  Deal with it.
112
        jmp 4f
113
1:      movw %%fs:(%%esi), %%bx
114
        addl $2, %%esi
115
        movw %%bx, (%%edi)
116
        addl $2, %%edi
117
        addw %%bx, %%ax
118
        adcl $0, %%eax
119
2:
120
        movl %%ecx, %%edx
121
        shrl $5, %%ecx
122
        jz 2f
123
        testl %%esi, %%esi
124
1:      movl %%fs:(%%esi), %%ebx
125
        adcl %%ebx, %%eax
126
        movl %%ebx, (%%edi)
127
 
128
        movl %%fs:4(%%esi), %%ebx
129
        adcl %%ebx, %%eax
130
        movl %%ebx, 4(%%edi)
131
 
132
        movl %%fs:8(%%esi), %%ebx
133
        adcl %%ebx, %%eax
134
        movl %%ebx, 8(%%edi)
135
 
136
        movl %%fs:12(%%esi), %%ebx
137
        adcl %%ebx, %%eax
138
        movl %%ebx, 12(%%edi)
139
 
140
        movl %%fs:16(%%esi), %%ebx
141
        adcl %%ebx, %%eax
142
        movl %%ebx, 16(%%edi)
143
 
144
        movl %%fs:20(%%esi), %%ebx
145
        adcl %%ebx, %%eax
146
        movl %%ebx, 20(%%edi)
147
 
148
        movl %%fs:24(%%esi), %%ebx
149
        adcl %%ebx, %%eax
150
        movl %%ebx, 24(%%edi)
151
 
152
        movl %%fs:28(%%esi), %%ebx
153
        adcl %%ebx, %%eax
154
        movl %%ebx, 28(%%edi)
155
 
156
        lea 32(%%esi), %%esi
157
        lea 32(%%edi), %%edi
158
        dec %%ecx
159
        jne 1b
160
        adcl $0, %%eax
161
2:      movl %%edx, %%ecx
162
        andl $28, %%edx
163
        je 4f
164
        shrl $2, %%edx
165
        testl %%esi, %%esi
166
3:      movl %%fs:(%%esi), %%ebx
167
        adcl %%ebx, %%eax
168
        movl %%ebx, (%%edi)
169
        lea 4(%%esi), %%esi
170
        lea 4(%%edi), %%edi
171
        dec %%edx
172
        jne 3b
173
        adcl $0, %%eax
174
4:      andl $3, %%ecx
175
        jz 7f
176
        cmpl $2, %%ecx
177
        jb 5f
178
        movw %%fs:(%%esi), %%cx
179
        leal 2(%%esi), %%esi
180
        movw %%cx, (%%edi)
181
        leal 2(%%edi), %%edi
182
        je 6f
183
        shll $16,%%ecx
184
5:      movb %%fs:(%%esi), %%cl
185
        movb %%cl, (%%edi)
186
6:      addl %%ecx, %%eax
187
        adcl $0, %%eax
188
7:
189
        "
190
        : "=a" (sum)
191
        : "0"(sum), "c"(len), "S"(src), "D" (dst)
192
        : "bx", "cx", "dx", "si", "di" );
193
    return(sum);
194
}
195
/*
196
 * copy from ds while checksumming, otherwise like csum_partial
197
 */
198
 
199
unsigned int csum_partial_copy(const char *src, char *dst,
200
                                  int len, int sum) {
201
    __asm__("
202
        testl $2, %%edi         # Check alignment.
203
        jz 2f                   # Jump if alignment is ok.
204
        subl $2, %%ecx          # Alignment uses up two bytes.
205
        jae 1f                  # Jump if we had at least two bytes.
206
        addl $2, %%ecx          # ecx was < 2.  Deal with it.
207
        jmp 4f
208
1:      movw (%%esi), %%bx
209
        addl $2, %%esi
210
        movw %%bx, (%%edi)
211
        addl $2, %%edi
212
        addw %%bx, %%ax
213
        adcl $0, %%eax
214
2:
215
        movl %%ecx, %%edx
216
        shrl $5, %%ecx
217
        jz 2f
218
        testl %%esi, %%esi
219
1:      movl (%%esi), %%ebx
220
        adcl %%ebx, %%eax
221
        movl %%ebx, (%%edi)
222
 
223
        movl 4(%%esi), %%ebx
224
        adcl %%ebx, %%eax
225
        movl %%ebx, 4(%%edi)
226
 
227
        movl 8(%%esi), %%ebx
228
        adcl %%ebx, %%eax
229
        movl %%ebx, 8(%%edi)
230
 
231
        movl 12(%%esi), %%ebx
232
        adcl %%ebx, %%eax
233
        movl %%ebx, 12(%%edi)
234
 
235
        movl 16(%%esi), %%ebx
236
        adcl %%ebx, %%eax
237
        movl %%ebx, 16(%%edi)
238
 
239
        movl 20(%%esi), %%ebx
240
        adcl %%ebx, %%eax
241
        movl %%ebx, 20(%%edi)
242
 
243
        movl 24(%%esi), %%ebx
244
        adcl %%ebx, %%eax
245
        movl %%ebx, 24(%%edi)
246
 
247
        movl 28(%%esi), %%ebx
248
        adcl %%ebx, %%eax
249
        movl %%ebx, 28(%%edi)
250
 
251
        lea 32(%%esi), %%esi
252
        lea 32(%%edi), %%edi
253
        dec %%ecx
254
        jne 1b
255
        adcl $0, %%eax
256
2:      movl %%edx, %%ecx
257
        andl $28, %%edx
258
        je 4f
259
        shrl $2, %%edx
260
        testl %%esi, %%esi
261
3:      movl (%%esi), %%ebx
262
        adcl %%ebx, %%eax
263
        movl %%ebx, (%%edi)
264
        lea 4(%%esi), %%esi
265
        lea 4(%%edi), %%edi
266
        dec %%edx
267
        jne 3b
268
        adcl $0, %%eax
269
4:      andl $3, %%ecx
270
        jz 7f
271
        cmpl $2, %%ecx
272
        jb 5f
273
        movw (%%esi), %%cx
274
        leal 2(%%esi), %%esi
275
        movw %%cx, (%%edi)
276
        leal 2(%%edi), %%edi
277
        je 6f
278
        shll $16,%%ecx
279
5:      movb (%%esi), %%cl
280
        movb %%cl, (%%edi)
281
6:      addl %%ecx, %%eax
282
        adcl $0, %%eax
283
7:
284
        "
285
        : "=a" (sum)
286
        : "0"(sum), "c"(len), "S"(src), "D" (dst)
287
        : "bx", "cx", "dx", "si", "di" );
288
    return(sum);
289
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.