Merge branch 'for_linus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc
[linux-2.6] / arch / sparc / lib / memscan.S
1 /* $Id: memscan.S,v 1.4 1996/09/08 02:01:20 davem Exp $
2  * memscan.S: Optimized memscan for the Sparc.
3  *
4  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5  */
6
7 /* In essence, this is just a fancy strlen. */
8
9 #define LO_MAGIC 0x01010101
10 #define HI_MAGIC 0x80808080
11
12         .text
13         .align  4
14         .globl  __memscan_zero, __memscan_generic
15         .globl  memscan
16 __memscan_zero:
17         /* %o0 = addr, %o1 = size */
18         cmp     %o1, 0
19         bne,a   1f
20          andcc  %o0, 3, %g0
21
22         retl
23          nop
24
25 1:
26         be      mzero_scan_word
27          sethi  %hi(HI_MAGIC), %g2
28
29         ldsb    [%o0], %g3
30 mzero_still_not_word_aligned:
31         cmp     %g3, 0
32         bne     1f
33          add    %o0, 1, %o0
34
35         retl
36          sub    %o0, 1, %o0
37
38 1:
39         subcc   %o1, 1, %o1
40         bne,a   1f
41          andcc  %o0, 3, %g0
42
43         retl
44          nop
45
46 1:
47         bne,a   mzero_still_not_word_aligned
48          ldsb   [%o0], %g3
49
50         sethi   %hi(HI_MAGIC), %g2
51 mzero_scan_word:
52         or      %g2, %lo(HI_MAGIC), %o3
53         sethi   %hi(LO_MAGIC), %g3
54         or      %g3, %lo(LO_MAGIC), %o2
55 mzero_next_word:
56         ld      [%o0], %g2
57 mzero_next_word_preloaded:
58         sub     %g2, %o2, %g2
59 mzero_next_word_preloaded_next:
60         andcc   %g2, %o3, %g0
61         bne     mzero_byte_zero
62          add    %o0, 4, %o0
63
64 mzero_check_out_of_fuel:
65         subcc   %o1, 4, %o1
66         bg,a    1f
67          ld     [%o0], %g2
68
69         retl
70          nop
71
72 1:
73         b       mzero_next_word_preloaded_next
74          sub    %g2, %o2, %g2
75
76         /* Check every byte. */
77 mzero_byte_zero:
78         ldsb    [%o0 - 4], %g2
79         cmp     %g2, 0
80         bne     mzero_byte_one
81          sub    %o0, 4, %g3
82
83         retl
84          mov    %g3, %o0
85
86 mzero_byte_one:
87         ldsb    [%o0 - 3], %g2
88         cmp     %g2, 0
89         bne,a   mzero_byte_two_and_three
90          ldsb   [%o0 - 2], %g2
91
92         retl
93          sub    %o0, 3, %o0
94
95 mzero_byte_two_and_three:
96         cmp     %g2, 0
97         bne,a   1f
98          ldsb   [%o0 - 1], %g2
99
100         retl
101          sub    %o0, 2, %o0
102
103 1:
104         cmp     %g2, 0
105         bne,a   mzero_next_word_preloaded
106          ld     [%o0], %g2
107
108         retl
109          sub    %o0, 1, %o0
110
111 mzero_found_it:
112         retl
113          sub    %o0, 2, %o0
114
115 memscan:
116 __memscan_generic:
117         /* %o0 = addr, %o1 = c, %o2 = size */
118         cmp     %o2, 0
119         bne,a   0f
120          ldub   [%o0], %g2
121
122         b,a     2f
123 1:
124         ldub    [%o0], %g2
125 0:
126         cmp     %g2, %o1
127         be      2f
128          addcc  %o2, -1, %o2
129         bne     1b
130          add    %o0, 1, %o0
131 2:
132         retl
133          nop