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)
18C_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
271:
28	be	mzero_scan_word
29	 sethi	%hi(HI_MAGIC), %g2
30
31	ldsb	[%o0], %g3
32mzero_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
401:
41	subcc	%o1, 1, %o1
42	bne,a	1f
43	 andcc	%o0, 3, %g0
44
45	retl
46	 nop
47
481:
49	bne,a	mzero_still_not_word_aligned
50	 ldsb	[%o0], %g3
51
52	sethi	%hi(HI_MAGIC), %g2
53mzero_scan_word:
54	or	%g2, %lo(HI_MAGIC), %o3
55	sethi	%hi(LO_MAGIC), %g3
56	or	%g3, %lo(LO_MAGIC), %o2
57mzero_next_word:
58	ld	[%o0], %g2
59mzero_next_word_preloaded:
60	sub	%g2, %o2, %g2
61mzero_next_word_preloaded_next:
62	andcc	%g2, %o3, %g0
63	bne	mzero_byte_zero
64	 add	%o0, 4, %o0
65
66mzero_check_out_of_fuel:
67	subcc	%o1, 4, %o1
68	bg,a	1f
69	 ld	[%o0], %g2
70
71	retl
72	 nop
73
741:
75	b	mzero_next_word_preloaded_next
76	 sub	%g2, %o2, %g2
77
78	/* Check every byte. */
79mzero_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
88mzero_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
97mzero_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
1051:
106	cmp	%g2, 0
107	bne,a	mzero_next_word_preloaded
108	 ld	[%o0], %g2
109
110	retl
111	 sub	%o0, 1, %o0
112
113mzero_found_it:
114	retl
115	 sub	%o0, 2, %o0
116
117C_LABEL(memscan):
118C_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
1251:
126	ldub	[%o0], %g2
1270:
128	cmp	%g2, %o1
129	be	2f
130	 addcc	%o2, -1, %o2
131	bne	1b
132	 add	%o0, 1, %o0
1332:
134	retl
135	 nop
136