port more changes to make PCI work
[linux-2.4.git] / 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 #include <asm/cprefix.h>
8
9 /* In essence, this is just a fancy strlen. */
10
11 #define LO_MAGIC 0x01010101
12 #define HI_MAGIC 0x80808080
13
14         .text
15         .align  4
16         .globl  C_LABEL(__memscan_zero), C_LABEL(__memscan_generic)
17         .globl  C_LABEL(memscan)
18 C_LABEL(__memscan_zero):
19         /* %o0 = addr, %o1 = size */
20         cmp     %o1, 0
21         bne,a   1f
22          andcc  %o0, 3, %g0
23
24         retl
25          nop
26
27 1:
28         be      mzero_scan_word
29          sethi  %hi(HI_MAGIC), %g2
30
31         ldsb    [%o0], %g3
32 mzero_still_not_word_aligned:
33         cmp     %g3, 0
34         bne     1f
35          add    %o0, 1, %o0
36
37         retl
38          sub    %o0, 1, %o0
39
40 1:
41         subcc   %o1, 1, %o1
42         bne,a   1f
43          andcc  %o0, 3, %g0
44
45         retl
46          nop
47
48 1:
49         bne,a   mzero_still_not_word_aligned
50          ldsb   [%o0], %g3
51
52         sethi   %hi(HI_MAGIC), %g2
53 mzero_scan_word:
54         or      %g2, %lo(HI_MAGIC), %o3
55         sethi   %hi(LO_MAGIC), %g3
56         or      %g3, %lo(LO_MAGIC), %o2
57 mzero_next_word:
58         ld      [%o0], %g2
59 mzero_next_word_preloaded:
60         sub     %g2, %o2, %g2
61 mzero_next_word_preloaded_next:
62         andcc   %g2, %o3, %g0
63         bne     mzero_byte_zero
64          add    %o0, 4, %o0
65
66 mzero_check_out_of_fuel:
67         subcc   %o1, 4, %o1
68         bg,a    1f
69          ld     [%o0], %g2
70
71         retl
72          nop
73
74 1:
75         b       mzero_next_word_preloaded_next
76          sub    %g2, %o2, %g2
77
78         /* Check every byte. */
79 mzero_byte_zero:
80         ldsb    [%o0 - 4], %g2
81         cmp     %g2, 0
82         bne     mzero_byte_one
83          sub    %o0, 4, %g3
84
85         retl
86          mov    %g3, %o0
87
88 mzero_byte_one:
89         ldsb    [%o0 - 3], %g2
90         cmp     %g2, 0
91         bne,a   mzero_byte_two_and_three
92          ldsb   [%o0 - 2], %g2
93
94         retl
95          sub    %o0, 3, %o0
96
97 mzero_byte_two_and_three:
98         cmp     %g2, 0
99         bne,a   1f
100          ldsb   [%o0 - 1], %g2
101
102         retl
103          sub    %o0, 2, %o0
104
105 1:
106         cmp     %g2, 0
107         bne,a   mzero_next_word_preloaded
108          ld     [%o0], %g2
109
110         retl
111          sub    %o0, 1, %o0
112
113 mzero_found_it:
114         retl
115          sub    %o0, 2, %o0
116
117 C_LABEL(memscan):
118 C_LABEL(__memscan_generic):
119         /* %o0 = addr, %o1 = c, %o2 = size */
120         cmp     %o2, 0
121         bne,a   0f
122          ldub   [%o0], %g2
123
124         b,a     2f
125 1:
126         ldub    [%o0], %g2
127 0:
128         cmp     %g2, %o1
129         be      2f
130          addcc  %o2, -1, %o2
131         bne     1b
132          add    %o0, 1, %o0
133 2:
134         retl
135          nop