GNU Linux-libre 4.9.296-gnu1
[releases.git] / arch / sparc / lib / memscan_32.S
1 /*
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/export.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  __memscan_zero, __memscan_generic
17         .globl  memscan
18 EXPORT_SYMBOL(__memscan_zero)
19 EXPORT_SYMBOL(__memscan_generic)
20 __memscan_zero:
21         /* %o0 = addr, %o1 = size */
22         cmp     %o1, 0
23         bne,a   1f
24          andcc  %o0, 3, %g0
25
26         retl
27          nop
28
29 1:
30         be      mzero_scan_word
31          sethi  %hi(HI_MAGIC), %g2
32
33         ldsb    [%o0], %g3
34 mzero_still_not_word_aligned:
35         cmp     %g3, 0
36         bne     1f
37          add    %o0, 1, %o0
38
39         retl
40          sub    %o0, 1, %o0
41
42 1:
43         subcc   %o1, 1, %o1
44         bne,a   1f
45          andcc  %o0, 3, %g0
46
47         retl
48          nop
49
50 1:
51         bne,a   mzero_still_not_word_aligned
52          ldsb   [%o0], %g3
53
54         sethi   %hi(HI_MAGIC), %g2
55 mzero_scan_word:
56         or      %g2, %lo(HI_MAGIC), %o3
57         sethi   %hi(LO_MAGIC), %g3
58         or      %g3, %lo(LO_MAGIC), %o2
59 mzero_next_word:
60         ld      [%o0], %g2
61 mzero_next_word_preloaded:
62         sub     %g2, %o2, %g2
63 mzero_next_word_preloaded_next:
64         andcc   %g2, %o3, %g0
65         bne     mzero_byte_zero
66          add    %o0, 4, %o0
67
68 mzero_check_out_of_fuel:
69         subcc   %o1, 4, %o1
70         bg,a    1f
71          ld     [%o0], %g2
72
73         retl
74          nop
75
76 1:
77         b       mzero_next_word_preloaded_next
78          sub    %g2, %o2, %g2
79
80         /* Check every byte. */
81 mzero_byte_zero:
82         ldsb    [%o0 - 4], %g2
83         cmp     %g2, 0
84         bne     mzero_byte_one
85          sub    %o0, 4, %g3
86
87         retl
88          mov    %g3, %o0
89
90 mzero_byte_one:
91         ldsb    [%o0 - 3], %g2
92         cmp     %g2, 0
93         bne,a   mzero_byte_two_and_three
94          ldsb   [%o0 - 2], %g2
95
96         retl
97          sub    %o0, 3, %o0
98
99 mzero_byte_two_and_three:
100         cmp     %g2, 0
101         bne,a   1f
102          ldsb   [%o0 - 1], %g2
103
104         retl
105          sub    %o0, 2, %o0
106
107 1:
108         cmp     %g2, 0
109         bne,a   mzero_next_word_preloaded
110          ld     [%o0], %g2
111
112         retl
113          sub    %o0, 1, %o0
114
115 mzero_found_it:
116         retl
117          sub    %o0, 2, %o0
118
119 memscan:
120 __memscan_generic:
121         /* %o0 = addr, %o1 = c, %o2 = size */
122         cmp     %o2, 0
123         bne,a   0f
124          ldub   [%o0], %g2
125
126         b,a     2f
127 1:
128         ldub    [%o0], %g2
129 0:
130         cmp     %g2, %o1
131         be      2f
132          addcc  %o2, -1, %o2
133         bne     1b
134          add    %o0, 1, %o0
135 2:
136         retl
137          nop