linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / powerpc / lib / memcpy_64.S
1 /*
2  * arch/ppc64/lib/memcpy.S
3  *
4  * Copyright (C) 2002 Paul Mackerras, IBM Corp.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11 #include <asm/processor.h>
12 #include <asm/ppc_asm.h>
13
14         .align  7
15 _GLOBAL(memcpy)
16         std     r3,48(r1)       /* save destination pointer for return value */
17         mtcrf   0x01,r5
18         cmpldi  cr1,r5,16
19         neg     r6,r3           # LS 3 bits = # bytes to 8-byte dest bdry
20         andi.   r6,r6,7
21         dcbt    0,r4
22         blt     cr1,.Lshort_copy
23         bne     .Ldst_unaligned
24 .Ldst_aligned:
25         andi.   r0,r4,7
26         addi    r3,r3,-16
27         bne     .Lsrc_unaligned
28         srdi    r7,r5,4
29         ld      r9,0(r4)
30         addi    r4,r4,-8
31         mtctr   r7
32         andi.   r5,r5,7
33         bf      cr7*4+0,2f
34         addi    r3,r3,8
35         addi    r4,r4,8
36         mr      r8,r9
37         blt     cr1,3f
38 1:      ld      r9,8(r4)
39         std     r8,8(r3)
40 2:      ldu     r8,16(r4)
41         stdu    r9,16(r3)
42         bdnz    1b
43 3:      std     r8,8(r3)
44         beq     3f
45         addi    r3,r3,16
46         ld      r9,8(r4)
47 .Ldo_tail:
48         bf      cr7*4+1,1f
49         rotldi  r9,r9,32
50         stw     r9,0(r3)
51         addi    r3,r3,4
52 1:      bf      cr7*4+2,2f
53         rotldi  r9,r9,16
54         sth     r9,0(r3)
55         addi    r3,r3,2
56 2:      bf      cr7*4+3,3f
57         rotldi  r9,r9,8
58         stb     r9,0(r3)
59 3:      ld      r3,48(r1)       /* return dest pointer */
60         blr
61
62 .Lsrc_unaligned:
63         srdi    r6,r5,3
64         addi    r5,r5,-16
65         subf    r4,r0,r4
66         srdi    r7,r5,4
67         sldi    r10,r0,3
68         cmpdi   cr6,r6,3
69         andi.   r5,r5,7
70         mtctr   r7
71         subfic  r11,r10,64
72         add     r5,r5,r0
73
74         bt      cr7*4+0,0f
75
76         ld      r9,0(r4)        # 3+2n loads, 2+2n stores
77         ld      r0,8(r4)
78         sld     r6,r9,r10
79         ldu     r9,16(r4)
80         srd     r7,r0,r11
81         sld     r8,r0,r10
82         or      r7,r7,r6
83         blt     cr6,4f
84         ld      r0,8(r4)
85         # s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12
86         b       2f
87
88 0:      ld      r0,0(r4)        # 4+2n loads, 3+2n stores
89         ldu     r9,8(r4)
90         sld     r8,r0,r10
91         addi    r3,r3,-8
92         blt     cr6,5f
93         ld      r0,8(r4)
94         srd     r12,r9,r11
95         sld     r6,r9,r10
96         ldu     r9,16(r4)
97         or      r12,r8,r12
98         srd     r7,r0,r11
99         sld     r8,r0,r10
100         addi    r3,r3,16
101         beq     cr6,3f
102
103         # d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9
104 1:      or      r7,r7,r6
105         ld      r0,8(r4)
106         std     r12,8(r3)
107 2:      srd     r12,r9,r11
108         sld     r6,r9,r10
109         ldu     r9,16(r4)
110         or      r12,r8,r12
111         stdu    r7,16(r3)
112         srd     r7,r0,r11
113         sld     r8,r0,r10
114         bdnz    1b
115
116 3:      std     r12,8(r3)
117         or      r7,r7,r6
118 4:      std     r7,16(r3)
119 5:      srd     r12,r9,r11
120         or      r12,r8,r12
121         std     r12,24(r3)
122         beq     4f
123         cmpwi   cr1,r5,8
124         addi    r3,r3,32
125         sld     r9,r9,r10
126         ble     cr1,.Ldo_tail
127         ld      r0,8(r4)
128         srd     r7,r0,r11
129         or      r9,r7,r9
130         b       .Ldo_tail
131
132 .Ldst_unaligned:
133         mtcrf   0x01,r6         # put #bytes to 8B bdry into cr7
134         subf    r5,r6,r5
135         li      r7,0
136         cmpldi  r1,r5,16
137         bf      cr7*4+3,1f
138         lbz     r0,0(r4)
139         stb     r0,0(r3)
140         addi    r7,r7,1
141 1:      bf      cr7*4+2,2f
142         lhzx    r0,r7,r4
143         sthx    r0,r7,r3
144         addi    r7,r7,2
145 2:      bf      cr7*4+1,3f
146         lwzx    r0,r7,r4
147         stwx    r0,r7,r3
148 3:      mtcrf   0x01,r5
149         add     r4,r6,r4
150         add     r3,r6,r3
151         b       .Ldst_aligned
152
153 .Lshort_copy:
154         bf      cr7*4+0,1f
155         lwz     r0,0(r4)
156         lwz     r9,4(r4)
157         addi    r4,r4,8
158         stw     r0,0(r3)
159         stw     r9,4(r3)
160         addi    r3,r3,8
161 1:      bf      cr7*4+1,2f
162         lwz     r0,0(r4)
163         addi    r4,r4,4
164         stw     r0,0(r3)
165         addi    r3,r3,4
166 2:      bf      cr7*4+2,3f
167         lhz     r0,0(r4)
168         addi    r4,r4,2
169         sth     r0,0(r3)
170         addi    r3,r3,2
171 3:      bf      cr7*4+3,4f
172         lbz     r0,0(r4)
173         stb     r0,0(r3)
174 4:      ld      r3,48(r1)       /* return dest pointer */
175         blr