Fix spelling errors in sysdeps/powerpc files.
[glibc.git] / sysdeps / powerpc / powerpc32 / cell / memcpy.S
blob6d7d4ce5db31f15f27abc42d99afa31571ee0a56
1 /* Optimized memcpy implementation for CELL BE PowerPC.
2    Copyright (C) 2010-2013 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <bp-sym.h>
21 #include <bp-asm.h>
23 #define PREFETCH_AHEAD 6        /* no cache lines SRC prefetching ahead  */
24 #define ZERO_AHEAD 4            /* no cache lines DST zeroing ahead  */
26 /* memcpy routine optimized for CELL-BE-PPC     v2.0
27  *
28  * The CELL PPC core has 1 integer unit and 1 load/store unit
29  * CELL:
30  * 1st level data cache = 32K
31  * 2nd level data cache = 512K
32  * 3rd level data cache = 0K
33  * With 3.2 GHz clockrate the latency to 2nd level cache is >36 clocks,
34  * latency to memory is >400 clocks
35  * To improve copy performance we need to prefetch source data
36  * far ahead to hide this latency
37  * For best performance instruction forms ending in "." like "andi."
38  * should be avoided as the are implemented in microcode on CELL.
39  * The below code is loop unrolled for the CELL cache line of 128 bytes
40  */
42 .align  7
44 EALIGN (BP_SYM (memcpy), 5, 0)
45         CALL_MCOUNT
47         dcbt    0,r4            /* Prefetch ONE SRC cacheline  */
48         cmplwi  cr1,r5,16       /* is size < 16 ?  */
49         mr      r6,r3
50         blt+    cr1,.Lshortcopy
52 .Lbigcopy:
53         neg     r8,r3           /* LS 3 bits = # bytes to 8-byte dest bdry  */
54         clrlwi  r8,r8,32-4      /* aling to 16byte boundary  */
55         sub     r7,r4,r3
56         cmplwi  cr0,r8,0
57         beq+    .Ldst_aligned
59 .Ldst_unaligned:
60         mtcrf   0x01,r8         /* put #bytes to boundary into cr7  */
61         subf    r5,r8,r5
63         bf      cr7*4+3,1f
64         lbzx    r0,r7,r6        /* copy 1 byte  */
65         stb     r0,0(r6)
66         addi    r6,r6,1
67 1:      bf      cr7*4+2,2f
68         lhzx    r0,r7,r6        /* copy 2 byte  */
69         sth     r0,0(r6)
70         addi    r6,r6,2
71 2:      bf      cr7*4+1,4f
72         lwzx    r0,r7,r6        /* copy 4 byte  */
73         stw     r0,0(r6)
74         addi    r6,r6,4
75 4:      bf      cr7*4+0,8f
76         lfdx    fp9,r7,r6       /* copy 8 byte  */
77         stfd    fp9,0(r6)
78         addi    r6,r6,8
80         add     r4,r7,r6
82 .Ldst_aligned:
84         cmpwi   cr5,r5,128-1
86         neg     r7,r6
87         addi    r6,r6,-8        /* prepare for stfdu  */
88         addi    r4,r4,-8        /* prepare for lfdu  */
90         clrlwi  r7,r7,32-7      /* align to cacheline boundary  */
91         ble+    cr5,.Llessthancacheline
93         cmplwi  cr6,r7,0
94         subf    r5,r7,r5
95         srwi    r7,r7,4         /* divide size by 16  */
96         srwi    r10,r5,7        /* number of cache lines to copy  */
98         cmplwi  r10,0
99         li      r11,0           /* number cachelines to copy with prefetch  */
100         beq     .Lnocacheprefetch
102         cmplwi  r10,PREFETCH_AHEAD
103         li      r12,128+8       /* prefetch distance  */
104         ble     .Llessthanmaxprefetch
106         subi    r11,r10,PREFETCH_AHEAD
107         li      r10,PREFETCH_AHEAD
109 .Llessthanmaxprefetch:
110         mtctr   r10
112 .LprefetchSRC:
113         dcbt    r12,r4
114         addi    r12,r12,128
115         bdnz    .LprefetchSRC
117 .Lnocacheprefetch:
118         mtctr   r7
119         cmplwi  cr1,r5,128
120         clrlwi  r5,r5,32-7
121         beq     cr6,.Lcachelinealigned
123 .Laligntocacheline:
124         lfd     fp9,0x08(r4)
125         lfdu    fp10,0x10(r4)
126         stfd    fp9,0x08(r6)
127         stfdu   fp10,0x10(r6)
128         bdnz    .Laligntocacheline
131 .Lcachelinealigned:             /* copy while cache lines  */
133         blt-    cr1,.Llessthancacheline /* size <128  */
135 .Louterloop:
136         cmpwi   r11,0
137         mtctr   r11
138         beq-    .Lendloop
140         li      r11,128*ZERO_AHEAD +8   /* DCBZ dist  */
142 .align  4
143         /* Copy whole cachelines, optimized by prefetching SRC cacheline  */
144 .Lloop:                         /* Copy aligned body  */
145         dcbt    r12,r4          /* PREFETCH SOURCE some cache lines ahead  */
146         lfd     fp9, 0x08(r4)
147         dcbz    r11,r6
148         lfd     fp10, 0x10(r4)  /* 4 register stride copy is optimal  */
149         lfd     fp11, 0x18(r4)  /* to hide 1st level cache latency.  */
150         lfd     fp12, 0x20(r4)
151         stfd    fp9, 0x08(r6)
152         stfd    fp10, 0x10(r6)
153         stfd    fp11, 0x18(r6)
154         stfd    fp12, 0x20(r6)
155         lfd     fp9, 0x28(r4)
156         lfd     fp10, 0x30(r4)
157         lfd     fp11, 0x38(r4)
158         lfd     fp12, 0x40(r4)
159         stfd    fp9, 0x28(r6)
160         stfd    fp10, 0x30(r6)
161         stfd    fp11, 0x38(r6)
162         stfd    fp12, 0x40(r6)
163         lfd     fp9, 0x48(r4)
164         lfd     fp10, 0x50(r4)
165         lfd     fp11, 0x58(r4)
166         lfd     fp12, 0x60(r4)
167         stfd    fp9, 0x48(r6)
168         stfd    fp10, 0x50(r6)
169         stfd    fp11, 0x58(r6)
170         stfd    fp12, 0x60(r6)
171         lfd     fp9, 0x68(r4)
172         lfd     fp10, 0x70(r4)
173         lfd     fp11, 0x78(r4)
174         lfdu    fp12, 0x80(r4)
175         stfd    fp9, 0x68(r6)
176         stfd    fp10, 0x70(r6)
177         stfd    fp11, 0x78(r6)
178         stfdu   fp12, 0x80(r6)
180         bdnz    .Lloop
182 .Lendloop:
183         cmpwi   r10,0
184         slwi    r10,r10,2       /* adjust from 128 to 32 byte stride  */
185         beq-    .Lendloop2
186         mtctr   r10
188 .Lloop2:                        /* Copy aligned body  */
189         lfd     fp9, 0x08(r4)
190         lfd     fp10, 0x10(r4)
191         lfd     fp11, 0x18(r4)
192         lfdu    fp12, 0x20(r4)
193         stfd    fp9, 0x08(r6)
194         stfd    fp10, 0x10(r6)
195         stfd    fp11, 0x18(r6)
196         stfdu   fp12, 0x20(r6)
198         bdnz    .Lloop2
199 .Lendloop2:
201 .Llessthancacheline:            /* less than cache to do ?  */
202         cmplwi  cr0,r5,16
203         srwi    r7,r5,4         /* divide size by 16  */
204         blt-    .Ldo_lt16
205         mtctr   r7
207 .Lcopy_remaining:
208         lfd     fp9,0x08(r4)
209         lfdu    fp10,0x10(r4)
210         stfd    fp9,0x08(r6)
211         stfdu   fp10,0x10(r6)
212         bdnz    .Lcopy_remaining
214 .Ldo_lt16:                      /* less than 16 ?  */
215         cmplwi  cr0,r5,0        /* copy remaining bytes (0-15)  */
216         beqlr+                  /* no rest to copy  */
217         addi    r4,r4,8
218         addi    r6,r6,8
220 .Lshortcopy:                    /* SIMPLE COPY to handle size =< 15 bytes  */
221         mtcrf   0x01,r5
222         sub     r7,r4,r6
223         bf-     cr7*4+0,8f
224         lfdx    fp9,r7,r6       /* copy 8 byte  */
225         stfd    fp9,0(r6)
226         addi    r6,r6,8
228         bf      cr7*4+1,4f
229         lwzx    r0,r7,r6        /* copy 4 byte  */
230         stw     r0,0(r6)
231         addi    r6,r6,4
233         bf      cr7*4+2,2f
234         lhzx    r0,r7,r6        /* copy 2 byte  */
235         sth     r0,0(r6)
236         addi    r6,r6,2
238         bf      cr7*4+3,1f
239         lbzx    r0,r7,r6        /* copy 1 byte  */
240         stb     r0,0(r6)
241 1:      blr
243 END (BP_SYM (memcpy))
244 libc_hidden_builtin_def (memcpy)