xref: /linux/arch/sparc/lib/memscan_32.S (revision d3867f0483103b8ff7edfdea3ef1981c03d96891)
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
18EXPORT_SYMBOL(__memscan_zero)
19EXPORT_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
291:
30	be	mzero_scan_word
31	 sethi	%hi(HI_MAGIC), %g2
32
33	ldsb	[%o0], %g3
34mzero_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
421:
43	subcc	%o1, 1, %o1
44	bne,a	1f
45	 andcc	%o0, 3, %g0
46
47	retl
48	 nop
49
501:
51	bne,a	mzero_still_not_word_aligned
52	 ldsb	[%o0], %g3
53
54	sethi	%hi(HI_MAGIC), %g2
55mzero_scan_word:
56	or	%g2, %lo(HI_MAGIC), %o3
57	sethi	%hi(LO_MAGIC), %g3
58	or	%g3, %lo(LO_MAGIC), %o2
59mzero_next_word:
60	ld	[%o0], %g2
61mzero_next_word_preloaded:
62	sub	%g2, %o2, %g2
63mzero_next_word_preloaded_next:
64	andcc	%g2, %o3, %g0
65	bne	mzero_byte_zero
66	 add	%o0, 4, %o0
67
68mzero_check_out_of_fuel:
69	subcc	%o1, 4, %o1
70	bg,a	1f
71	 ld	[%o0], %g2
72
73	retl
74	 nop
75
761:
77	b	mzero_next_word_preloaded_next
78	 sub	%g2, %o2, %g2
79
80	/* Check every byte. */
81mzero_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
90mzero_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
99mzero_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
1071:
108	cmp	%g2, 0
109	bne,a	mzero_next_word_preloaded
110	 ld	[%o0], %g2
111
112	retl
113	 sub	%o0, 1, %o0
114
115mzero_found_it:
116	retl
117	 sub	%o0, 2, %o0
118
119memscan:
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
1271:
128	ldub	[%o0], %g2
1290:
130	cmp	%g2, %o1
131	be	2f
132	 addcc	%o2, -1, %o2
133	bne	1b
134	 add	%o0, 1, %o0
1352:
136	retl
137	 nop
138