Assembly version of ffs(3).

Confirmed to return the same value as that of the C version.

The results of a simple benchmark on SH-4 200MHz, is shown below.
I think this shows acceptable performance.

return value	C version	this version	speed
of ffs()	(ns/call)	(ns/call)	ratio
------------	---------	------------	-----
 0		  86		 86		1.00
 1		 110		 86		1.27
 2		 132		 86		1.53
 3		 165		105		1.57
 4		 201		104		1.93
 5		 237		111		2.13
 6		 271		111		2.44
 7		 307		126		2.43
 8		 342		125		2.73
 9		 376		122		3.08
10		 410		121		3.38
11		 446		139		3.20
12		 483		140		3.45
13		 518		146		3.54
14		 551		146		3.77
15		 587		161		3.64
16		 624		162		3.85
17		 658		141		4.66
18		 694		142		4.88
19		 727		160		4.54
20		 764		161		4.74
21		 799		167		4.78
22		 834		167		4.99
23		 868		181		4.79
24		 903		181		4.98
25		 939		146		6.43
26		 974		146		6.67
27		1009		166		6.07
28		1044		165		6.32
29		1080		171		6.31
30		1115		171		6.52
31		1151		185		6.22
32		1185		186		6.37
This commit is contained in:
itohy 2002-08-24 06:30:34 +00:00
parent 41c25cb648
commit 70b5675025
2 changed files with 222 additions and 0 deletions

View File

@ -0,0 +1,111 @@
/* $NetBSD: ffs.S,v 1.1 2002/08/24 06:30:34 itohy Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by ITOH Yasufumi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
#if defined(SYSLIBC_SCCS) && !defined(lint)
RCSID("$NetBSD: ffs.S,v 1.1 2002/08/24 06:30:34 itohy Exp $")
#endif
/*
* ffs - find first bit set
*
* This code makes use of ``test 8bit'' and ``shift 8bit'' instructions.
* The remaining 8bit is tested in every 2bit.
*/
ENTRY(ffs)
mov r4,r0 ! using r0 specific instructions
tst #0xff,r0
bt Lshift8
mov #0+2,r1 ! ret = 1..8
L8bit:
tst #0x0f,r0
bt 4f
tst #0x03,r0
bt 2f
and #1,r0
sub r0,r1
rts
mov r1,r0
2: shlr2 r0
add #2,r1
and #1,r0
sub r0,r1
rts
mov r1,r0
4: shlr2 r0
shlr2 r0
tst #0x03,r0
bt 6f
add #4,r1
and #1,r0
sub r0,r1
rts
mov r1,r0
6: shlr2 r0
add #6,r1
and #1,r0
sub r0,r1
rts
mov r1,r0
Lzero: rts
Lshift8:
tst r0,r0 ! ffs(0) is 0
bt Lzero ! testing here to accelerate ret=1..8 cases
shlr8 r0
tst #0xff,r0
bt Lshift16
bra L8bit
mov #8+2,r1 ! ret = 9..16
Lshift16:
shlr8 r0
tst #0xff,r0
bt Lshift24
bra L8bit
mov #16+2,r1 ! ret = 17..24
Lshift24:
shlr8 r0
bra L8bit
mov #24+2,r1 ! ret = 25..32

View File

@ -0,0 +1,111 @@
/* $NetBSD: ffs.S,v 1.1 2002/08/24 06:30:36 itohy Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by ITOH Yasufumi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
#if defined(SYSLIBC_SCCS) && !defined(lint)
RCSID("$NetBSD: ffs.S,v 1.1 2002/08/24 06:30:36 itohy Exp $")
#endif
/*
* ffs - find first bit set
*
* This code makes use of ``test 8bit'' and ``shift 8bit'' instructions.
* The remaining 8bit is tested in every 2bit.
*/
ENTRY(ffs)
mov r4,r0 ! using r0 specific instructions
tst #0xff,r0
bt Lshift8
mov #0+2,r1 ! ret = 1..8
L8bit:
tst #0x0f,r0
bt 4f
tst #0x03,r0
bt 2f
and #1,r0
sub r0,r1
rts
mov r1,r0
2: shlr2 r0
add #2,r1
and #1,r0
sub r0,r1
rts
mov r1,r0
4: shlr2 r0
shlr2 r0
tst #0x03,r0
bt 6f
add #4,r1
and #1,r0
sub r0,r1
rts
mov r1,r0
6: shlr2 r0
add #6,r1
and #1,r0
sub r0,r1
rts
mov r1,r0
Lzero: rts
Lshift8:
tst r0,r0 ! ffs(0) is 0
bt Lzero ! testing here to accelerate ret=1..8 cases
shlr8 r0
tst #0xff,r0
bt Lshift16
bra L8bit
mov #8+2,r1 ! ret = 9..16
Lshift16:
shlr8 r0
tst #0xff,r0
bt Lshift24
bra L8bit
mov #16+2,r1 ! ret = 17..24
Lshift24:
shlr8 r0
bra L8bit
mov #24+2,r1 ! ret = 25..32