xref: /csrg-svn/lib/libc/sparc/string/ffs.s (revision 61174)
154401Storek/*
2*61174Sbostic * Copyright (c) 1992, 1993
3*61174Sbostic *	The Regents of the University of California.  All rights reserved.
454401Storek *
554401Storek * This software was developed by the Computer Systems Engineering group
654401Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
754401Storek * contributed to Berkeley.
854401Storek *
954401Storek * %sccs.include.redist.c%
1054401Storek *
1154729Storek * from: $Header: ffs.s,v 1.3 92/07/07 00:23:57 torek Exp $
1254401Storek */
1354401Storek
1454401Storek#if defined(LIBC_SCCS) && !defined(lint)
15*61174Sbostic	.asciz "@(#)ffs.s	8.1 (Berkeley) 06/04/93"
1654401Storek#endif  /* LIBC_SCCS and not lint */
1754401Storek
1854729Storek#include "DEFS.h"
1954729Storek
2054401Storek/*
2154401Storek * ffs returns the number of the rightmost bit set in its argument,
2254401Storek * i.e., the lowest value such that (x & (ffs(x) - 1)) is nonzero.
2354401Storek * If no bits are set, ffs returns 0.
2454401Storek *
2554401Storek * We use a table lookup on each byte.
2654401Storek *
2754401Storek * In each section below, %o1 is the current byte (0, 1, 2, or 3).
2854401Storek * The last byte is handled specially: for the first three,
2954401Storek * if that byte is nonzero, we return the table value
3054401Storek * (plus 0, 8, or 16 for the byte number), but for the last
3154401Storek * one, we just return the table value plus 24.  This means
3254401Storek * that ffstab[0] must be -24 so that ffs(0) will return 0.
3354401Storek */
3454729StorekENTRY(ffs)
3554401Storek	set	ffstab, %o2
3654401Storek	andcc	%o0, 0xff, %o1	! get low byte
3754401Storek	be,a	1f		! try again if 0
3854729Storek	 srl	%o0, 8, %o0	! delay slot, get ready for next byte
3954401Storek
4054401Storek	retl			! return ffstab[%o1]
4154729Storek	 ldsb	[%o2 + %o1], %o0
4254401Storek
4354401Storek1:
4454401Storek	andcc	%o0, 0xff, %o1	! byte 1 like byte 0...
4554401Storek	be,a	2f
4654729Storek	 srl	%o0, 8, %o0	! (use delay to prepare for byte 2)
4754401Storek
4854401Storek	ldsb	[%o2 + %o1], %o0
4954401Storek	retl			! return ffstab[%o1] + 8
5054729Storek	 add	%o0, 8, %o0
5154401Storek
5254401Storek2:
5354401Storek	andcc	%o0, 0xff, %o1
5454401Storek	be,a	3f
5554729Storek	 srl	%o0, 8, %o0	! (prepare for byte 3)
5654401Storek
5754401Storek	ldsb	[%o2 + %o1], %o0
5854401Storek	retl			! return ffstab[%o1] + 16
5954729Storek	 add	%o0, 16, %o0
6054401Storek
6154401Storek3:				! just return ffstab[%o0] + 24
6254401Storek	ldsb	[%o2 + %o0], %o0
6354401Storek	retl
6454729Storek	 add	%o0, 24, %o0
6554729Storek
6654729Storekffstab:
6754729Storek	.byte	-24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */
6854729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 10-1f */
6954729Storek	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 20-2f */
7054729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 30-3f */
7154729Storek	.byte	7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 40-4f */
7254729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 50-5f */
7354729Storek	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 60-6f */
7454729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 70-7f */
7554729Storek	.byte	8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 80-8f */
7654729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 10-9f */
7754729Storek	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* a0-af */
7854729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* b0-bf */
7954729Storek	.byte	7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* c0-cf */
8054729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* d0-df */
8154729Storek	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* e0-ef */
8254729Storek	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* f0-ff */
83