1 /* SPDX-License-Identifier: GPL-2.0+ 2 * 3 * $Id: checksum.S,v 1.10 2001/07/06 13:11:32 4 * 5 * INET An implementation of the TCP/I 6 * operating system. INET is imp 7 * interface as the means of comm 8 * 9 * IP/TCP/UDP checksumming routin 10 * 11 * Authors: Jorge Cwik, <jorge@laser.satlin 12 * Arnt Gulbrandsen, <agulbra@nvg. 13 * Tom May, <ftom@netcom.com> 14 * Pentium Pro/II routines: 15 * Alexander Kjeldaas <astor@guard 16 * Finn Arne Gangstad <finnag@guar 17 * Lots of code moved from tcp.c 18 * for more names. 19 * 20 * Changes: Ingo Molnar, converted csum_pa 21 * handling. 22 * Andi Kleen, add zeroing on er 23 * converted to pure assembl 24 * 25 * SuperH version: Copyright (C) 1999 Niibe 26 */ 27 28 #include <asm/errno.h> 29 #include <linux/linkage.h> 30 31 /* 32 * computes a partial checksum, e.g. for TCP/U 33 */ 34 35 /* 36 * unsigned int csum_partial(const unsigned ch 37 * unsigned int sum) 38 */ 39 40 .text 41 ENTRY(csum_partial) 42 /* 43 * Experiments with Ethernet and SLI 44 * is aligned on either a 2-byte or 45 * least a twofold speedup on 486 an 46 * Fortunately, it is easy to conver 47 * alignment for the unrolled loop. 48 */ 49 mov r5, r1 50 mov r4, r0 51 tst #2, r0 ! Check alignm 52 bt 2f ! Jump if alig 53 ! 54 add #-2, r5 ! Alignment us 55 cmp/pz r5 ! 56 bt/s 1f ! Jump if we h 57 clrt 58 bra 6f 59 add #2, r5 ! r5 was < 2. 60 1: 61 mov r5, r1 ! Save new len 62 mov.w @r4+, r0 63 extu.w r0, r0 64 addc r0, r6 65 bf 2f 66 add #1, r6 67 2: 68 mov #-5, r0 69 shld r0, r5 70 tst r5, r5 71 bt/s 4f ! if it's =0, 72 clrt 73 .align 2 74 3: 75 mov.l @r4+, r0 76 mov.l @r4+, r2 77 mov.l @r4+, r3 78 addc r0, r6 79 mov.l @r4+, r0 80 addc r2, r6 81 mov.l @r4+, r2 82 addc r3, r6 83 mov.l @r4+, r3 84 addc r0, r6 85 mov.l @r4+, r0 86 addc r2, r6 87 mov.l @r4+, r2 88 addc r3, r6 89 addc r0, r6 90 addc r2, r6 91 movt r0 92 dt r5 93 bf/s 3b 94 cmp/eq #1, r0 95 ! here, we know r5==0 96 addc r5, r6 ! add 97 4: 98 mov r1, r0 99 and #0x1c, r0 100 tst r0, r0 101 bt/s 6f 102 mov r0, r5 103 shlr2 r5 104 mov #0, r2 105 5: 106 addc r2, r6 107 mov.l @r4+, r2 108 movt r0 109 dt r5 110 bf/s 5b 111 cmp/eq #1, r0 112 addc r2, r6 113 addc r5, r6 ! r5==0 here, 114 6: 115 mov r1, r5 116 mov #3, r0 117 and r0, r5 118 tst r5, r5 119 bt 9f ! if it's =0 g 120 mov #2, r1 121 cmp/hs r1, r5 122 bf 7f 123 mov.w @r4+, r0 124 extu.w r0, r0 125 cmp/eq r1, r5 126 bt/s 8f 127 clrt 128 shll16 r0 129 addc r0, r6 130 7: 131 mov.b @r4+, r0 132 extu.b r0, r0 133 #ifndef __LITTLE_ENDIAN__ 134 shll8 r0 135 #endif 136 8: 137 addc r0, r6 138 mov #0, r0 139 addc r0, r6 140 9: 141 rts 142 mov r6, r0 143 144 /* 145 unsigned int csum_partial_copy_generic (const 146 */ 147 148 /* 149 * Copy from ds while checksumming, otherwise 150 * sum being ~0U 151 */ 152 153 #define EXC(...) \ 154 9999: __VA_ARGS__ ; \ 155 .section __ex_table, "a"; \ 156 .long 9999b, 6001f ; \ 157 .previous 158 159 ! 160 ! r4: const char *SRC 161 ! r5: char *DST 162 ! r6: int LEN 163 ! 164 ENTRY(csum_partial_copy_generic) 165 mov #-1,r7 166 mov #3,r0 ! Check src an 167 mov r4,r1 168 and r0,r1 169 and r5,r0 170 cmp/eq r1,r0 171 bf 3f ! Different al 172 tst #1,r0 ! Check dest w 173 bf 3f ! If not, do i 174 175 mov #2,r0 176 tst r0,r5 ! Check dest a 177 bt 2f ! Jump if alig 178 add #-2,r6 ! Alignment us 179 cmp/pz r6 ! Jump if we h 180 bt/s 1f 181 clrt 182 add #2,r6 ! r6 was < 2. 183 bra 4f 184 mov r6,r2 185 186 3: ! Handle different src and dest alignm 187 ! This is not common, so simple byte b 188 mov r6,r2 189 shlr r6 190 tst r6,r6 191 bt 4f 192 clrt 193 .align 2 194 5: 195 EXC( mov.b @r4+,r1 ) 196 EXC( mov.b @r4+,r0 ) 197 extu.b r1,r1 198 EXC( mov.b r1,@r5 ) 199 EXC( mov.b r0,@(1,r5) ) 200 extu.b r0,r0 201 add #2,r5 202 203 #ifdef __LITTLE_ENDIAN__ 204 shll8 r0 205 #else 206 shll8 r1 207 #endif 208 or r1,r0 209 210 addc r0,r7 211 movt r0 212 dt r6 213 bf/s 5b 214 cmp/eq #1,r0 215 mov #0,r0 216 addc r0, r7 217 218 mov r2, r0 219 tst #1, r0 220 bt 7f 221 bra 5f 222 clrt 223 224 ! src and dest equally aligned, but to 225 ! Handle first two bytes as a special 226 .align 2 227 1: 228 EXC( mov.w @r4+,r0 ) 229 EXC( mov.w r0,@r5 ) 230 add #2,r5 231 extu.w r0,r0 232 addc r0,r7 233 mov #0,r0 234 addc r0,r7 235 2: 236 mov r6,r2 237 mov #-5,r0 238 shld r0,r6 239 tst r6,r6 240 bt/s 2f 241 clrt 242 .align 2 243 1: 244 EXC( mov.l @r4+,r0 ) 245 EXC( mov.l @r4+,r1 ) 246 addc r0,r7 247 EXC( mov.l r0,@r5 ) 248 EXC( mov.l r1,@(4,r5) ) 249 addc r1,r7 250 251 EXC( mov.l @r4+,r0 ) 252 EXC( mov.l @r4+,r1 ) 253 addc r0,r7 254 EXC( mov.l r0,@(8,r5) ) 255 EXC( mov.l r1,@(12,r5) ) 256 addc r1,r7 257 258 EXC( mov.l @r4+,r0 ) 259 EXC( mov.l @r4+,r1 ) 260 addc r0,r7 261 EXC( mov.l r0,@(16,r5) ) 262 EXC( mov.l r1,@(20,r5) ) 263 addc r1,r7 264 265 EXC( mov.l @r4+,r0 ) 266 EXC( mov.l @r4+,r1 ) 267 addc r0,r7 268 EXC( mov.l r0,@(24,r5) ) 269 EXC( mov.l r1,@(28,r5) ) 270 addc r1,r7 271 add #32,r5 272 movt r0 273 dt r6 274 bf/s 1b 275 cmp/eq #1,r0 276 mov #0,r0 277 addc r0,r7 278 279 2: mov r2,r6 280 mov #0x1c,r0 281 and r0,r6 282 cmp/pl r6 283 bf/s 4f 284 clrt 285 shlr2 r6 286 3: 287 EXC( mov.l @r4+,r0 ) 288 addc r0,r7 289 EXC( mov.l r0,@r5 ) 290 add #4,r5 291 movt r0 292 dt r6 293 bf/s 3b 294 cmp/eq #1,r0 295 mov #0,r0 296 addc r0,r7 297 4: mov r2,r6 298 mov #3,r0 299 and r0,r6 300 cmp/pl r6 301 bf 7f 302 mov #2,r1 303 cmp/hs r1,r6 304 bf 5f 305 EXC( mov.w @r4+,r0 ) 306 EXC( mov.w r0,@r5 ) 307 extu.w r0,r0 308 add #2,r5 309 cmp/eq r1,r6 310 bt/s 6f 311 clrt 312 shll16 r0 313 addc r0,r7 314 5: 315 EXC( mov.b @r4+,r0 ) 316 EXC( mov.b r0,@r5 ) 317 extu.b r0,r0 318 #ifndef __LITTLE_ENDIAN__ 319 shll8 r0 320 #endif 321 6: addc r0,r7 322 mov #0,r0 323 addc r0,r7 324 7: 325 326 # Exception handler: 327 .section .fixup, "ax" 328 329 6001: 330 rts 331 mov #0,r0 332 .previous 333 rts 334 mov r7,r0
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.