more debug output
[linux-2.4.git] / arch / x86_64 / lib / csum-copy.S
1 /*
2  * Copyright 2002,2003 Andi Kleen, SuSE Labs.
3  *      
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file COPYING in the main directory of this archive
6  * for more details. No warranty for anything given at all.
7  */
8         #include <linux/linkage.h>
9         #include <asm/errno.h>
10
11 /*
12  * Checksum copy with exception handling.
13  * On exceptions src_err_ptr or dst_err_ptr is set to -EFAULT and the 
14  * destination is zeroed.
15  * 
16  * Input
17  * rdi  source
18  * rsi  destination
19  * edx  len (32bit)
20  * ecx  sum (32bit) 
21  * r8   src_err_ptr (int)
22  * r9   dst_err_ptr (int)
23  *
24  * Output
25  * eax  64bit sum. undefined in case of exception.
26  * 
27  * Wrappers need to take care of valid exception sum and zeroing.                
28  * They also should align source or destination to 8 bytes.
29  */
30
31         .macro source
32 10:
33         .section __ex_table,"a"
34         .align 8
35         .quad 10b,.Lbad_source
36         .previous
37         .endm
38                 
39         .macro dest
40 20:
41         .section __ex_table,"a"
42         .align 8
43         .quad 20b,.Lbad_dest
44         .previous
45         .endm
46                         
47         .globl csum_partial_copy_generic
48         .p2align 4
49 csum_partial_copy_generic:
50         subq  $7*8,%rsp
51         movq  %rbx,2*8(%rsp)
52         movq  %r12,3*8(%rsp)
53         movq  %r14,4*8(%rsp)
54         movq  %r13,5*8(%rsp)
55         movq  %rbp,6*8(%rsp)
56
57         movq  %r8,(%rsp)
58         movq  %r9,1*8(%rsp)
59         
60         movl  %ecx,%eax
61         movl  %edx,%ecx
62
63         xorl  %r9d,%r9d
64         movq  %rcx,%r12
65
66         shrq  $6,%r12
67         jz    .Lhandle_tail       /* < 64 */
68
69         clc
70         
71         /* main loop. clear in 64 byte blocks */
72         /* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
73         /* r11: temp3, rdx: temp4, r12 loopcnt */
74         /* r10: temp5, rbp: temp6, r14 temp7, r13 temp8 */
75         .p2align 4
76 .Lloop:
77         source
78         movq  (%rdi),%rbx
79         source
80         movq  8(%rdi),%r8
81         source
82         movq  16(%rdi),%r11
83         source
84         movq  24(%rdi),%rdx
85
86         source
87         movq  32(%rdi),%r10
88         source
89         movq  40(%rdi),%rbp
90         source
91         movq  48(%rdi),%r14
92         source
93         movq  56(%rdi),%r13
94                 
95         adcq  %rbx,%rax
96         adcq  %r8,%rax
97         adcq  %r11,%rax
98         adcq  %rdx,%rax
99         adcq  %r10,%rax
100         adcq  %rbp,%rax
101         adcq  %r14,%rax
102         adcq  %r13,%rax
103
104         decl %r12d
105         
106         dest
107         movq %rbx,(%rsi)
108         dest
109         movq %r8,8(%rsi)
110         dest
111         movq %r11,16(%rsi)
112         dest
113         movq %rdx,24(%rsi)
114
115         dest
116         movq %r10,32(%rsi)
117         dest
118         movq %rbp,40(%rsi)
119         dest
120         movq %r14,48(%rsi)
121         dest
122         movq %r13,56(%rsi)
123         
124         leaq 64(%rdi),%rdi
125         leaq 64(%rsi),%rsi
126
127         jnz   .Lloop
128
129         adcq  %r9,%rax
130
131         /* do last upto 56 bytes */
132 .Lhandle_tail:
133         /* ecx: count */
134         movl %ecx,%r10d
135         andl $63,%ecx
136         shrl $3,%ecx
137         jz       .Lfold
138         clc
139         .p2align 4
140 .Lloop_8:       
141         source
142         movq (%rdi),%rbx
143         adcq %rbx,%rax
144         decl %ecx
145         dest
146         movq %rbx,(%rsi)
147         leaq 8(%rsi),%rsi /* preserve carry */
148         leaq 8(%rdi),%rdi
149         jnz     .Lloop_8
150         adcq %r9,%rax   /* add in carry */
151
152 .Lfold:
153         /* reduce checksum to 32bits */
154         movl %eax,%ebx
155         shrq $32,%rax
156         addl %ebx,%eax
157         adcl %r9d,%eax
158
159         /* do last upto 6 bytes */      
160 .Lhandle_7:
161         movl %r10d,%ecx
162         andl $7,%ecx
163         shrl $1,%ecx
164         jz   .Lhandle_1
165         movl $2,%edx
166         xorl %ebx,%ebx
167         clc  
168         .p2align 4
169 .Lloop_1:       
170         source
171         movw (%rdi),%bx
172         adcl %ebx,%eax
173         dest
174         decl %ecx
175         movw %bx,(%rsi)
176         leaq 2(%rdi),%rdi
177         leaq 2(%rsi),%rsi
178         jnz .Lloop_1
179         adcl %r9d,%eax  /* add in carry */
180         
181         /* handle last odd byte */
182 .Lhandle_1:
183         testl $1,%r10d
184         jz    .Lende
185         xorl  %ebx,%ebx
186         source
187         movb (%rdi),%bl
188         dest
189         movb %bl,(%rsi)
190         addl %ebx,%eax
191         adcl %r9d,%eax          /* carry */
192                         
193 .Lende:
194         movq 2*8(%rsp),%rbx
195         movq 3*8(%rsp),%r12
196         movq 4*8(%rsp),%r14
197         movq 5*8(%rsp),%r13
198         movq 6*8(%rsp),%rbp
199         addq $7*8,%rsp
200         ret
201
202         /* Exception handlers. Very simple, zeroing is done in the wrappers */
203 .Lbad_source:
204         movq (%rsp),%rax
205         movl $-EFAULT,(%rax)
206         jmp  .Lende
207         
208 .Lbad_dest:
209         movq 8(%rsp),%rax
210         movl $-EFAULT,(%rax)
211         jmp .Lende