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
139