diff options
Diffstat (limited to 'arch/avr32/lib/csum_partial_copy_generic.S')
-rw-r--r-- | arch/avr32/lib/csum_partial_copy_generic.S | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/arch/avr32/lib/csum_partial_copy_generic.S b/arch/avr32/lib/csum_partial_copy_generic.S new file mode 100644 index 000000000000..a3a0f9b8929c --- /dev/null +++ b/arch/avr32/lib/csum_partial_copy_generic.S | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #include <asm/errno.h> | ||
9 | #include <asm/asm.h> | ||
10 | |||
11 | /* | ||
12 | * unsigned int csum_partial_copy_generic(const char *src, char *dst, int len | ||
13 | * int sum, int *src_err_ptr, | ||
14 | * int *dst_err_ptr) | ||
15 | * | ||
16 | * Copy src to dst while checksumming, otherwise like csum_partial. | ||
17 | */ | ||
18 | |||
19 | .macro ld_src size, reg, ptr | ||
20 | 9999: ld.\size \reg, \ptr | ||
21 | .section __ex_table, "a" | ||
22 | .long 9999b, fixup_ld_src | ||
23 | .previous | ||
24 | .endm | ||
25 | |||
26 | .macro st_dst size, ptr, reg | ||
27 | 9999: st.\size \ptr, \reg | ||
28 | .section __ex_table, "a" | ||
29 | .long 9999b, fixup_st_dst | ||
30 | .previous | ||
31 | .endm | ||
32 | |||
33 | .text | ||
34 | .global csum_partial_copy_generic | ||
35 | .type csum_partial_copy_generic,"function" | ||
36 | .align 1 | ||
37 | csum_partial_copy_generic: | ||
38 | pushm r4-r7,lr | ||
39 | |||
40 | /* The inner loop */ | ||
41 | 1: sub r10, 4 | ||
42 | brlt 5f | ||
43 | 2: ld_src w, r5, r12++ | ||
44 | st_dst w, r11++, r5 | ||
45 | add r9, r5 | ||
46 | acr r9 | ||
47 | sub r10, 4 | ||
48 | brge 2b | ||
49 | |||
50 | /* return if we had a whole number of words */ | ||
51 | 5: sub r10, -4 | ||
52 | brne 7f | ||
53 | |||
54 | 6: mov r12, r9 | ||
55 | popm r4-r7,pc | ||
56 | |||
57 | /* handle additional bytes at the tail */ | ||
58 | 7: mov r5, 0 | ||
59 | mov r4, 32 | ||
60 | 8: ld_src ub, r6, r12++ | ||
61 | st_dst b, r11++, r6 | ||
62 | lsl r5, 8 | ||
63 | sub r4, 8 | ||
64 | bfins r5, r6, 0, 8 | ||
65 | sub r10, 1 | ||
66 | brne 8b | ||
67 | |||
68 | lsl r5, r5, r4 | ||
69 | add r9, r5 | ||
70 | acr r9 | ||
71 | rjmp 6b | ||
72 | |||
73 | /* Exception handler */ | ||
74 | .section .fixup,"ax" | ||
75 | .align 1 | ||
76 | fixup_ld_src: | ||
77 | mov r9, -EFAULT | ||
78 | cp.w r8, 0 | ||
79 | breq 1f | ||
80 | st.w r8[0], r9 | ||
81 | |||
82 | 1: /* | ||
83 | * TODO: zero the complete destination - computing the rest | ||
84 | * is too much work | ||
85 | */ | ||
86 | |||
87 | mov r9, 0 | ||
88 | rjmp 6b | ||
89 | |||
90 | fixup_st_dst: | ||
91 | mov r9, -EFAULT | ||
92 | lddsp r8, sp[20] | ||
93 | cp.w r8, 0 | ||
94 | breq 1f | ||
95 | st.w r8[0], r9 | ||
96 | 1: mov r9, 0 | ||
97 | rjmp 6b | ||
98 | |||
99 | .previous | ||