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 <linux/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 |
139 | |