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