diff options
Diffstat (limited to 'arch/sparc/lib/memscan.S')
| -rw-r--r-- | arch/sparc/lib/memscan.S | 133 | 
1 files changed, 133 insertions, 0 deletions
diff --git a/arch/sparc/lib/memscan.S b/arch/sparc/lib/memscan.S new file mode 100644 index 00000000000..28e78ff090a --- /dev/null +++ b/arch/sparc/lib/memscan.S @@ -0,0 +1,133 @@ +/* $Id: memscan.S,v 1.4 1996/09/08 02:01:20 davem Exp $ + * memscan.S: Optimized memscan for the Sparc. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +/* In essence, this is just a fancy strlen. */ + +#define LO_MAGIC 0x01010101 +#define HI_MAGIC 0x80808080 + +	.text +	.align	4 +	.globl	__memscan_zero, __memscan_generic +	.globl	memscan +__memscan_zero: +	/* %o0 = addr, %o1 = size */ +	cmp	%o1, 0 +	bne,a	1f +	 andcc	%o0, 3, %g0 + +	retl +	 nop + +1: +	be	mzero_scan_word +	 sethi	%hi(HI_MAGIC), %g2 + +	ldsb	[%o0], %g3 +mzero_still_not_word_aligned: +	cmp	%g3, 0 +	bne	1f +	 add	%o0, 1, %o0 + +	retl +	 sub	%o0, 1, %o0 + +1: +	subcc	%o1, 1, %o1 +	bne,a	1f +	 andcc	%o0, 3, %g0 + +	retl +	 nop + +1: +	bne,a	mzero_still_not_word_aligned +	 ldsb	[%o0], %g3 + +	sethi	%hi(HI_MAGIC), %g2 +mzero_scan_word: +	or	%g2, %lo(HI_MAGIC), %o3 +	sethi	%hi(LO_MAGIC), %g3 +	or	%g3, %lo(LO_MAGIC), %o2 +mzero_next_word: +	ld	[%o0], %g2 +mzero_next_word_preloaded: +	sub	%g2, %o2, %g2 +mzero_next_word_preloaded_next: +	andcc	%g2, %o3, %g0 +	bne	mzero_byte_zero +	 add	%o0, 4, %o0 + +mzero_check_out_of_fuel: +	subcc	%o1, 4, %o1 +	bg,a	1f +	 ld	[%o0], %g2 + +	retl +	 nop + +1: +	b	mzero_next_word_preloaded_next +	 sub	%g2, %o2, %g2 + +	/* Check every byte. */ +mzero_byte_zero: +	ldsb	[%o0 - 4], %g2 +	cmp	%g2, 0 +	bne	mzero_byte_one +	 sub	%o0, 4, %g3 + +	retl +	 mov	%g3, %o0 + +mzero_byte_one: +	ldsb	[%o0 - 3], %g2 +	cmp	%g2, 0 +	bne,a	mzero_byte_two_and_three +	 ldsb	[%o0 - 2], %g2 + +	retl +	 sub	%o0, 3, %o0 + +mzero_byte_two_and_three: +	cmp	%g2, 0 +	bne,a	1f +	 ldsb	[%o0 - 1], %g2 + +	retl +	 sub	%o0, 2, %o0 + +1: +	cmp	%g2, 0 +	bne,a	mzero_next_word_preloaded +	 ld	[%o0], %g2 + +	retl +	 sub	%o0, 1, %o0 + +mzero_found_it: +	retl +	 sub	%o0, 2, %o0 + +memscan: +__memscan_generic: +	/* %o0 = addr, %o1 = c, %o2 = size */ +	cmp	%o2, 0 +	bne,a	0f +	 ldub	[%o0], %g2 + +	b,a	2f +1: +	ldub	[%o0], %g2 +0: +	cmp	%g2, %o1 +	be	2f +	 addcc	%o2, -1, %o2 +	bne	1b +	 add	%o0, 1, %o0 +2: +	retl +	 nop  |