fix to allow usb modules to compile
[linux-2.4.21-pre4.git] / arch / ppc / lib / string.S
1 /*
2  * BK Id: SCCS/s.string.S 1.19 08/13/02 21:52:53 paulus
3  */
4 /*
5  * String handling functions for PowerPC.
6  *
7  * Copyright (C) 1996 Paul Mackerras.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version
12  * 2 of the License, or (at your option) any later version.
13  */
14 #include <linux/config.h>
15 #include <asm/processor.h>
16 #include <asm/cache.h>
17 #include <asm/errno.h>
18 #include <asm/ppc_asm.h>
19
20 #define COPY_16_BYTES           \
21         lwz     r7,4(r4);       \
22         lwz     r8,8(r4);       \
23         lwz     r9,12(r4);      \
24         lwzu    r10,16(r4);     \
25         stw     r7,4(r6);       \
26         stw     r8,8(r6);       \
27         stw     r9,12(r6);      \
28         stwu    r10,16(r6)
29
30 #define COPY_16_BYTES_WITHEX(n) \
31 8 ## n ## 0:                    \
32         lwz     r7,4(r4);       \
33 8 ## n ## 1:                    \
34         lwz     r8,8(r4);       \
35 8 ## n ## 2:                    \
36         lwz     r9,12(r4);      \
37 8 ## n ## 3:                    \
38         lwzu    r10,16(r4);     \
39 8 ## n ## 4:                    \
40         stw     r7,4(r6);       \
41 8 ## n ## 5:                    \
42         stw     r8,8(r6);       \
43 8 ## n ## 6:                    \
44         stw     r9,12(r6);      \
45 8 ## n ## 7:                    \
46         stwu    r10,16(r6)
47
48 #define COPY_16_BYTES_EXCODE(n)                 \
49 9 ## n ## 0:                                    \
50         addi    r5,r5,-(16 * n);                \
51         b       104f;                           \
52 9 ## n ## 1:                                    \
53         addi    r5,r5,-(16 * n);                \
54         b       105f;                           \
55 .section __ex_table,"a";                        \
56         .align  2;                              \
57         .long   8 ## n ## 0b,9 ## n ## 0b;      \
58         .long   8 ## n ## 1b,9 ## n ## 0b;      \
59         .long   8 ## n ## 2b,9 ## n ## 0b;      \
60         .long   8 ## n ## 3b,9 ## n ## 0b;      \
61         .long   8 ## n ## 4b,9 ## n ## 1b;      \
62         .long   8 ## n ## 5b,9 ## n ## 1b;      \
63         .long   8 ## n ## 6b,9 ## n ## 1b;      \
64         .long   8 ## n ## 7b,9 ## n ## 1b;      \
65         .text
66
67         .text
68         .stabs  "arch/ppc/lib/",N_SO,0,0,0f
69         .stabs  "string.S",N_SO,0,0,0f
70
71 CACHELINE_BYTES = L1_CACHE_LINE_SIZE
72 LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE
73 CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1)
74
75 _GLOBAL(strcpy)
76         addi    r5,r3,-1
77         addi    r4,r4,-1
78 1:      lbzu    r0,1(r4)
79         cmpwi   0,r0,0
80         stbu    r0,1(r5)
81         bne     1b
82         blr
83
84 _GLOBAL(strncpy)
85         cmpwi   0,r5,0
86         beqlr
87         mtctr   r5
88         addi    r6,r3,-1
89         addi    r4,r4,-1
90 1:      lbzu    r0,1(r4)
91         cmpwi   0,r0,0
92         stbu    r0,1(r6)
93         bdnzf   2,1b            /* dec ctr, branch if ctr != 0 && !cr0.eq */
94         blr
95
96 _GLOBAL(strcat)
97         addi    r5,r3,-1
98         addi    r4,r4,-1
99 1:      lbzu    r0,1(r5)
100         cmpwi   0,r0,0
101         bne     1b
102         addi    r5,r5,-1
103 1:      lbzu    r0,1(r4)
104         cmpwi   0,r0,0
105         stbu    r0,1(r5)
106         bne     1b
107         blr
108
109 _GLOBAL(strcmp)
110         addi    r5,r3,-1
111         addi    r4,r4,-1
112 1:      lbzu    r3,1(r5)
113         cmpwi   1,r3,0
114         lbzu    r0,1(r4)
115         subf.   r3,r0,r3
116         beqlr   1
117         beq     1b
118         blr
119
120 _GLOBAL(strlen)
121         addi    r4,r3,-1
122 1:      lbzu    r0,1(r4)
123         cmpwi   0,r0,0
124         bne     1b
125         subf    r3,r3,r4
126         blr
127
128 /*
129  * Use dcbz on the complete cache lines in the destination
130  * to set them to zero.  This requires that the destination
131  * area is cacheable.  -- paulus
132  */
133 _GLOBAL(cacheable_memzero)
134         mr      r5,r4
135         li      r4,0
136         addi    r6,r3,-4
137         cmplwi  0,r5,4
138         blt     7f
139         stwu    r4,4(r6)
140         beqlr
141         andi.   r0,r6,3
142         add     r5,r0,r5
143         subf    r6,r0,r6
144         clrlwi  r7,r6,32-LG_CACHELINE_BYTES
145         add     r8,r7,r5
146         srwi    r9,r8,LG_CACHELINE_BYTES
147         addic.  r9,r9,-1        /* total number of complete cachelines */
148         ble     2f
149         xori    r0,r7,CACHELINE_MASK & ~3
150         srwi.   r0,r0,2
151         beq     3f
152         mtctr   r0
153 4:      stwu    r4,4(r6)
154         bdnz    4b
155 3:      mtctr   r9
156         li      r7,4
157 #if !defined(CONFIG_8xx)
158 10:     dcbz    r7,r6
159 #else
160 10:     stw     r4, 4(r6)
161         stw     r4, 8(r6)
162         stw     r4, 12(r6)
163         stw     r4, 16(r6)
164 #endif
165         addi    r6,r6,CACHELINE_BYTES
166         bdnz    10b
167         clrlwi  r5,r8,32-LG_CACHELINE_BYTES
168         addi    r5,r5,4
169 2:      srwi    r0,r5,2
170         mtctr   r0
171         bdz     6f
172 1:      stwu    r4,4(r6)
173         bdnz    1b
174 6:      andi.   r5,r5,3
175 7:      cmpwi   0,r5,0
176         beqlr
177         mtctr   r5
178         addi    r6,r6,3
179 8:      stbu    r4,1(r6)
180         bdnz    8b
181         blr
182
183 _GLOBAL(memset)
184         rlwimi  r4,r4,8,16,23
185         rlwimi  r4,r4,16,0,15
186         addi    r6,r3,-4
187         cmplwi  0,r5,4
188         blt     7f
189         stwu    r4,4(r6)
190         beqlr
191         andi.   r0,r6,3
192         add     r5,r0,r5
193         subf    r6,r0,r6
194         srwi    r0,r5,2
195         mtctr   r0
196         bdz     6f
197 1:      stwu    r4,4(r6)
198         bdnz    1b
199 6:      andi.   r5,r5,3
200 7:      cmpwi   0,r5,0
201         beqlr
202         mtctr   r5
203         addi    r6,r6,3
204 8:      stbu    r4,1(r6)
205         bdnz    8b
206         blr
207
208 _GLOBAL(bcopy)
209         mr      r6,r3
210         mr      r3,r4
211         mr      r4,r6
212         b       memcpy
213
214 /*
215  * This version uses dcbz on the complete cache lines in the
216  * destination area to reduce memory traffic.  This requires that
217  * the destination area is cacheable.
218  * We only use this version if the source and dest don't overlap.
219  * -- paulus.
220  */
221 _GLOBAL(cacheable_memcpy)
222         add     r7,r3,r5                /* test if the src & dst overlap */
223         add     r8,r4,r5
224         cmplw   0,r4,r7
225         cmplw   1,r3,r8
226         crand   0,0,4                   /* cr0.lt &= cr1.lt */
227         blt     memcpy                  /* if regions overlap */
228
229         addi    r4,r4,-4
230         addi    r6,r3,-4
231         neg     r0,r3
232         andi.   r0,r0,CACHELINE_MASK    /* # bytes to start of cache line */
233         beq     58f
234
235         cmplw   0,r5,r0                 /* is this more than total to do? */
236         blt     63f                     /* if not much to do */
237         andi.   r8,r0,3                 /* get it word-aligned first */
238         subf    r5,r0,r5
239         mtctr   r8
240         beq+    61f
241 70:     lbz     r9,4(r4)                /* do some bytes */
242         stb     r9,4(r6)
243         addi    r4,r4,1
244         addi    r6,r6,1
245         bdnz    70b
246 61:     srwi.   r0,r0,2
247         mtctr   r0
248         beq     58f
249 72:     lwzu    r9,4(r4)                /* do some words */
250         stwu    r9,4(r6)
251         bdnz    72b
252
253 58:     srwi.   r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
254         clrlwi  r5,r5,32-LG_CACHELINE_BYTES
255         li      r11,4
256         mtctr   r0
257         beq     63f
258 53:
259 #if !defined(CONFIG_8xx)
260         dcbz    r11,r6
261 #endif
262         COPY_16_BYTES
263 #if L1_CACHE_LINE_SIZE >= 32
264         COPY_16_BYTES
265 #if L1_CACHE_LINE_SIZE >= 64
266         COPY_16_BYTES
267         COPY_16_BYTES
268 #if L1_CACHE_LINE_SIZE >= 128
269         COPY_16_BYTES
270         COPY_16_BYTES
271         COPY_16_BYTES
272         COPY_16_BYTES
273 #endif
274 #endif
275 #endif
276         bdnz    53b
277
278 63:     srwi.   r0,r5,2
279         mtctr   r0
280         beq     64f
281 30:     lwzu    r0,4(r4)
282         stwu    r0,4(r6)
283         bdnz    30b
284
285 64:     andi.   r0,r5,3
286         mtctr   r0
287         beq+    65f
288 40:     lbz     r0,4(r4)
289         stb     r0,4(r6)
290         addi    r4,r4,1
291         addi    r6,r6,1
292         bdnz    40b
293 65:     blr
294
295 _GLOBAL(memmove)
296         cmplw   0,r3,r4
297         bgt     backwards_memcpy
298         /* fall through */
299
300 _GLOBAL(memcpy)
301         srwi.   r7,r5,3
302         addi    r6,r3,-4
303         addi    r4,r4,-4
304         beq     2f                      /* if less than 8 bytes to do */
305         andi.   r0,r6,3                 /* get dest word aligned */
306         mtctr   r7
307         bne     5f
308 1:      lwz     r7,4(r4)
309         lwzu    r8,8(r4)
310         stw     r7,4(r6)
311         stwu    r8,8(r6)
312         bdnz    1b
313         andi.   r5,r5,7
314 2:      cmplwi  0,r5,4
315         blt     3f
316         lwzu    r0,4(r4)
317         addi    r5,r5,-4
318         stwu    r0,4(r6)
319 3:      cmpwi   0,r5,0
320         beqlr
321         mtctr   r5
322         addi    r4,r4,3
323         addi    r6,r6,3
324 4:      lbzu    r0,1(r4)
325         stbu    r0,1(r6)
326         bdnz    4b
327         blr
328 5:      subfic  r0,r0,4
329         mtctr   r0
330 6:      lbz     r7,4(r4)
331         addi    r4,r4,1
332         stb     r7,4(r6)
333         addi    r6,r6,1
334         bdnz    6b
335         subf    r5,r0,r5
336         rlwinm. r7,r5,32-3,3,31
337         beq     2b
338         mtctr   r7
339         b       1b
340
341 _GLOBAL(backwards_memcpy)
342         rlwinm. r7,r5,32-3,3,31         /* r0 = r5 >> 3 */
343         add     r6,r3,r5
344         add     r4,r4,r5
345         beq     2f
346         andi.   r0,r6,3
347         mtctr   r7
348         bne     5f
349 1:      lwz     r7,-4(r4)
350         lwzu    r8,-8(r4)
351         stw     r7,-4(r6)
352         stwu    r8,-8(r6)
353         bdnz    1b
354         andi.   r5,r5,7
355 2:      cmplwi  0,r5,4
356         blt     3f
357         lwzu    r0,-4(r4)
358         subi    r5,r5,4
359         stwu    r0,-4(r6)
360 3:      cmpwi   0,r5,0
361         beqlr
362         mtctr   r5
363 4:      lbzu    r0,-1(r4)
364         stbu    r0,-1(r6)
365         bdnz    4b
366         blr
367 5:      mtctr   r0
368 6:      lbzu    r7,-1(r4)
369         stbu    r7,-1(r6)
370         bdnz    6b
371         subf    r5,r0,r5
372         rlwinm. r7,r5,32-3,3,31
373         beq     2b
374         mtctr   r7
375         b       1b
376
377 _GLOBAL(memcmp)
378         cmpwi   0,r5,0
379         ble-    2f
380         mtctr   r5
381         addi    r6,r3,-1
382         addi    r4,r4,-1
383 1:      lbzu    r3,1(r6)
384         lbzu    r0,1(r4)
385         subf.   r3,r0,r3
386         bdnzt   2,1b
387         blr
388 2:      li      r3,0
389         blr
390
391 _GLOBAL(memchr)
392         cmpwi   0,r5,0
393         ble-    2f
394         mtctr   r5
395         addi    r3,r3,-1
396 1:      lbzu    r0,1(r3)
397         cmpw    0,r0,r4
398         bdnzf   2,1b
399         beqlr
400 2:      li      r3,0
401         blr
402
403 _GLOBAL(__copy_tofrom_user)
404         addi    r4,r4,-4
405         addi    r6,r3,-4
406         neg     r0,r3
407         andi.   r0,r0,CACHELINE_MASK    /* # bytes to start of cache line */
408         beq     58f
409
410         cmplw   0,r5,r0                 /* is this more than total to do? */
411         blt     63f                     /* if not much to do */
412         andi.   r8,r0,3                 /* get it word-aligned first */
413         mtctr   r8
414         beq+    61f
415 70:     lbz     r9,4(r4)                /* do some bytes */
416 71:     stb     r9,4(r6)
417         addi    r4,r4,1
418         addi    r6,r6,1
419         bdnz    70b
420 61:     subf    r5,r0,r5
421         srwi.   r0,r0,2
422         mtctr   r0
423         beq     58f
424 72:     lwzu    r9,4(r4)                /* do some words */
425 73:     stwu    r9,4(r6)
426         bdnz    72b
427
428 58:     srwi.   r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
429         clrlwi  r5,r5,32-LG_CACHELINE_BYTES
430         li      r11,4
431         beq     63f
432
433 #if !defined(CONFIG_8xx)
434         /* Here we decide how far ahead to prefetch the source */
435 #if MAX_COPY_PREFETCH > 1
436         /* Heuristically, for large transfers we prefetch
437            MAX_COPY_PREFETCH cachelines ahead.  For small transfers
438            we prefetch 1 cacheline ahead. */
439         cmpwi   r0,MAX_COPY_PREFETCH
440         li      r7,1
441         li      r3,4
442         ble     111f
443         li      r7,MAX_COPY_PREFETCH
444 111:    mtctr   r7
445 112:    dcbt    r3,r4
446         addi    r3,r3,CACHELINE_BYTES
447         bdnz    112b
448 #else /* MAX_COPY_PREFETCH == 1 */
449         li      r3,CACHELINE_BYTES + 4
450         dcbt    r11,r4
451 #endif /* MAX_COPY_PREFETCH */
452 #endif /* CONFIG_8xx */
453
454         mtctr   r0
455 53:
456 #if !defined(CONFIG_8xx)
457         dcbt    r3,r4
458 54:     dcbz    r11,r6
459 #endif
460 /* had to move these to keep extable in order */
461         .section __ex_table,"a"
462         .align  2
463         .long   70b,100f
464         .long   71b,101f
465         .long   72b,102f
466         .long   73b,103f
467 #if !defined(CONFIG_8xx)
468         .long   54b,105f
469 #endif
470         .text
471 /* the main body of the cacheline loop */
472         COPY_16_BYTES_WITHEX(0)
473 #if L1_CACHE_LINE_SIZE >= 32
474         COPY_16_BYTES_WITHEX(1)
475 #if L1_CACHE_LINE_SIZE >= 64
476         COPY_16_BYTES_WITHEX(2)
477         COPY_16_BYTES_WITHEX(3)
478 #if L1_CACHE_LINE_SIZE >= 128
479         COPY_16_BYTES_WITHEX(4)
480         COPY_16_BYTES_WITHEX(5)
481         COPY_16_BYTES_WITHEX(6)
482         COPY_16_BYTES_WITHEX(7)
483 #endif
484 #endif
485 #endif
486         bdnz    53b
487
488 63:     srwi.   r0,r5,2
489         mtctr   r0
490         beq     64f
491 30:     lwzu    r0,4(r4)
492 31:     stwu    r0,4(r6)
493         bdnz    30b
494
495 64:     andi.   r0,r5,3
496         mtctr   r0
497         beq+    65f
498 40:     lbz     r0,4(r4)
499 41:     stb     r0,4(r6)
500         addi    r4,r4,1
501         addi    r6,r6,1
502         bdnz    40b
503 65:     li      r3,0
504         blr
505
506 /* read fault, initial single-byte copy */
507 100:    li      r4,0
508         b       90f
509 /* write fault, initial single-byte copy */
510 101:    li      r4,1
511 90:     subf    r5,r8,r5
512         li      r3,0
513         b       99f
514 /* read fault, initial word copy */
515 102:    li      r4,0
516         b       91f
517 /* write fault, initial word copy */
518 103:    li      r4,1
519 91:     li      r3,2
520         b       99f
521
522 /*
523  * this stuff handles faults in the cacheline loop and branches to either
524  * 104f (if in read part) or 105f (if in write part), after updating r5
525  */
526         COPY_16_BYTES_EXCODE(0)
527 #if L1_CACHE_LINE_SIZE >= 32
528         COPY_16_BYTES_EXCODE(1)
529 #if L1_CACHE_LINE_SIZE >= 64
530         COPY_16_BYTES_EXCODE(2)
531         COPY_16_BYTES_EXCODE(3)
532 #if L1_CACHE_LINE_SIZE >= 128
533         COPY_16_BYTES_EXCODE(4)
534         COPY_16_BYTES_EXCODE(5)
535         COPY_16_BYTES_EXCODE(6)
536         COPY_16_BYTES_EXCODE(7)
537 #endif
538 #endif
539 #endif
540
541 /* read fault in cacheline loop */
542 104:    li      r4,0
543         b       92f
544 /* fault on dcbz (effectively a write fault) */
545 /* or write fault in cacheline loop */
546 105:    li      r4,1
547 92:     li      r3,LG_CACHELINE_BYTES
548         b       99f
549 /* read fault in final word loop */
550 108:    li      r4,0
551         b       93f
552 /* write fault in final word loop */
553 109:    li      r4,1
554 93:     andi.   r5,r5,3
555         li      r3,2
556         b       99f
557 /* read fault in final byte loop */
558 110:    li      r4,0
559         b       94f
560 /* write fault in final byte loop */
561 111:    li      r4,1
562 94:     li      r5,0
563         li      r3,0
564 /*
565  * At this stage the number of bytes not copied is
566  * r5 + (ctr << r3), and r4 is 0 for read or 1 for write.
567  */
568 99:     mfctr   r0
569         slw     r3,r0,r3
570         add     r3,r3,r5
571         cmpwi   0,r4,0
572         bne     120f
573 /* for read fault, clear out the destination: r3 bytes starting at 4(r6) */
574         srwi.   r0,r3,2
575         li      r9,0
576         mtctr   r0
577         beq     113f
578 112:    stwu    r9,4(r6)
579         bdnz    112b
580 113:    andi.   r0,r3,3
581         mtctr   r0
582         beq     120f
583 114:    stb     r9,4(r6)
584         addi    r6,r6,1
585         bdnz    114b
586 120:    blr
587
588         .section __ex_table,"a"
589         .align  2
590         .long   30b,108b
591         .long   31b,109b
592         .long   40b,110b
593         .long   41b,111b
594         .long   112b,120b
595         .long   114b,120b
596         .text
597
598 _GLOBAL(__clear_user)
599         addi    r6,r3,-4
600         li      r3,0
601         li      r5,0
602         cmplwi  0,r4,4
603         blt     7f
604         /* clear a single word */
605 11:     stwu    r5,4(r6)
606         beqlr
607         /* clear word sized chunks */
608         andi.   r0,r6,3
609         add     r4,r0,r4
610         subf    r6,r0,r6
611         srwi    r0,r4,2
612         andi.   r4,r4,3
613         mtctr   r0
614         bdz     7f
615 1:      stwu    r5,4(r6)
616         bdnz    1b
617         /* clear byte sized chunks */
618 7:      cmpwi   0,r4,0
619         beqlr
620         mtctr   r4
621         addi    r6,r6,3
622 8:      stbu    r5,1(r6)
623         bdnz    8b
624         blr
625 90:     mr      r3,r4
626         blr
627 91:     mfctr   r3
628         slwi    r3,r3,2
629         add     r3,r3,r4
630         blr
631 92:     mfctr   r3
632         blr
633
634         .section __ex_table,"a"
635         .align  2
636         .long   11b,90b
637         .long   1b,91b
638         .long   8b,92b
639         .text
640
641 _GLOBAL(__strncpy_from_user)
642         addi    r6,r3,-1
643         addi    r4,r4,-1
644         cmpwi   0,r5,0
645         beq     2f
646         mtctr   r5
647 1:      lbzu    r0,1(r4)
648         cmpwi   0,r0,0
649         stbu    r0,1(r6)
650         bdnzf   2,1b            /* dec ctr, branch if ctr != 0 && !cr0.eq */
651         beq     3f
652 2:      addi    r6,r6,1
653 3:      subf    r3,r3,r6
654         blr
655 99:     li      r3,-EFAULT
656         blr
657
658         .section __ex_table,"a"
659         .align  2
660         .long   1b,99b
661         .text
662
663 /* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
664 _GLOBAL(__strnlen_user)
665         addi    r7,r3,-1
666         subf    r6,r7,r5        /* top+1 - str */
667         cmplw   0,r4,r6
668         bge     0f
669         mr      r6,r4
670 0:      mtctr   r6              /* ctr = min(len, top - str) */
671 1:      lbzu    r0,1(r7)        /* get next byte */
672         cmpwi   0,r0,0
673         bdnzf   2,1b            /* loop if --ctr != 0 && byte != 0 */
674         addi    r7,r7,1
675         subf    r3,r3,r7        /* number of bytes we have looked at */
676         beqlr                   /* return if we found a 0 byte */
677         cmpw    0,r3,r4         /* did we look at all len bytes? */
678         blt     99f             /* if not, must have hit top */
679         addi    r3,r4,1         /* return len + 1 to indicate no null found */
680         blr
681 99:     li      r3,0            /* bad address, return 0 */
682         blr
683
684         .section __ex_table,"a"
685         .align  2
686         .long   1b,99b