xref: /netbsd-src/common/lib/libc/arch/sparc/string/ffs.S (revision 4d12bfcd155352508213ace5ccc59ce930ea2974)
1*4d12bfcdSjoerg/*	$NetBSD: ffs.S,v 1.4 2013/09/12 15:36:14 joerg Exp $	*/
237c9f0a6Schristos
337c9f0a6Schristos/*
437c9f0a6Schristos * Copyright (c) 1992, 1993
537c9f0a6Schristos *	The Regents of the University of California.  All rights reserved.
637c9f0a6Schristos *
737c9f0a6Schristos * This software was developed by the Computer Systems Engineering group
837c9f0a6Schristos * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
937c9f0a6Schristos * contributed to Berkeley.
1037c9f0a6Schristos *
1137c9f0a6Schristos * Redistribution and use in source and binary forms, with or without
1237c9f0a6Schristos * modification, are permitted provided that the following conditions
1337c9f0a6Schristos * are met:
1437c9f0a6Schristos * 1. Redistributions of source code must retain the above copyright
1537c9f0a6Schristos *    notice, this list of conditions and the following disclaimer.
1637c9f0a6Schristos * 2. Redistributions in binary form must reproduce the above copyright
1737c9f0a6Schristos *    notice, this list of conditions and the following disclaimer in the
1837c9f0a6Schristos *    documentation and/or other materials provided with the distribution.
1937c9f0a6Schristos * 3. Neither the name of the University nor the names of its contributors
2037c9f0a6Schristos *    may be used to endorse or promote products derived from this software
2137c9f0a6Schristos *    without specific prior written permission.
2237c9f0a6Schristos *
2337c9f0a6Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2437c9f0a6Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2537c9f0a6Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2637c9f0a6Schristos * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2737c9f0a6Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2837c9f0a6Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2937c9f0a6Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3037c9f0a6Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3137c9f0a6Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3237c9f0a6Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3337c9f0a6Schristos * SUCH DAMAGE.
3437c9f0a6Schristos *
3537c9f0a6Schristos * from: Header: ffs.s,v 1.3 92/07/07 00:23:57 torek Exp
3637c9f0a6Schristos */
3737c9f0a6Schristos
3837c9f0a6Schristos#include <machine/asm.h>
3937c9f0a6Schristos#if defined(LIBC_SCCS) && !defined(lint)
4037c9f0a6Schristos#if 0
4137c9f0a6Schristos	.asciz "@(#)ffs.s	8.1 (Berkeley) 6/4/93"
4237c9f0a6Schristos#else
43*4d12bfcdSjoerg	RCSID("$NetBSD: ffs.S,v 1.4 2013/09/12 15:36:14 joerg Exp $")
4437c9f0a6Schristos#endif
4537c9f0a6Schristos#endif  /* LIBC_SCCS and not lint */
4637c9f0a6Schristos
4737c9f0a6Schristos/*
4837c9f0a6Schristos * ffs returns the number of the rightmost bit set in its argument,
4937c9f0a6Schristos * i.e., the lowest value such that (x & (ffs(x) - 1)) is nonzero.
5037c9f0a6Schristos * If no bits are set, ffs returns 0.
5137c9f0a6Schristos *
5237c9f0a6Schristos * We use a table lookup on each byte.
5337c9f0a6Schristos *
5437c9f0a6Schristos * In each section below, %o1 is the current byte (0, 1, 2, or 3).
5537c9f0a6Schristos * The last byte is handled specially: for the first three,
5637c9f0a6Schristos * if that byte is nonzero, we return the table value
5737c9f0a6Schristos * (plus 0, 8, or 16 for the byte number), but for the last
5837c9f0a6Schristos * one, we just return the table value plus 24.  This means
5937c9f0a6Schristos * that ffstab[0] must be -24 so that ffs(0) will return 0.
6037c9f0a6Schristos */
6188fcb00cSmrgWEAK_ALIAS(__ffssi2,ffs)
6237c9f0a6SchristosENTRY(ffs)
63*4d12bfcdSjoerg#ifdef __PIC__
64817cd315Spooka	PICCY_SET(ffstab, %o2, %o3)
6537c9f0a6Schristos#else
66817cd315Spooka	set	ffstab, %o2
6737c9f0a6Schristos#endif
6837c9f0a6Schristos	andcc	%o0, 0xff, %o1	! get low byte
6937c9f0a6Schristos	be,a	1f		! try again if 0
7037c9f0a6Schristos	 srl	%o0, 8, %o0	! delay slot, get ready for next byte
7137c9f0a6Schristos
7237c9f0a6Schristos	retl			! return ffstab[%o1]
7337c9f0a6Schristos	 ldsb	[%o2 + %o1], %o0
7437c9f0a6Schristos
7537c9f0a6Schristos1:
7637c9f0a6Schristos	andcc	%o0, 0xff, %o1	! byte 1 like byte 0...
7737c9f0a6Schristos	be,a	2f
7837c9f0a6Schristos	 srl	%o0, 8, %o0	! (use delay to prepare for byte 2)
7937c9f0a6Schristos
8037c9f0a6Schristos	ldsb	[%o2 + %o1], %o0
8137c9f0a6Schristos	retl			! return ffstab[%o1] + 8
8237c9f0a6Schristos	 add	%o0, 8, %o0
8337c9f0a6Schristos
8437c9f0a6Schristos2:
8537c9f0a6Schristos	andcc	%o0, 0xff, %o1
8637c9f0a6Schristos	be,a	3f
8737c9f0a6Schristos	 srl	%o0, 8, %o0	! (prepare for byte 3)
8837c9f0a6Schristos
8937c9f0a6Schristos	ldsb	[%o2 + %o1], %o0
9037c9f0a6Schristos	retl			! return ffstab[%o1] + 16
9137c9f0a6Schristos	 add	%o0, 16, %o0
9237c9f0a6Schristos
9337c9f0a6Schristos3:				! just return ffstab[%o0] + 24
9437c9f0a6Schristos	ldsb	[%o2 + %o0], %o0
9537c9f0a6Schristos	retl
9637c9f0a6Schristos	 add	%o0, 24, %o0
9737c9f0a6Schristos
98817cd315Spookaffstab:
9937c9f0a6Schristos	.byte	-24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */
10037c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 10-1f */
10137c9f0a6Schristos	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 20-2f */
10237c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 30-3f */
10337c9f0a6Schristos	.byte	7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 40-4f */
10437c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 50-5f */
10537c9f0a6Schristos	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 60-6f */
10637c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 70-7f */
10737c9f0a6Schristos	.byte	8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 80-8f */
10837c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 10-9f */
10937c9f0a6Schristos	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* a0-af */
11037c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* b0-bf */
11137c9f0a6Schristos	.byte	7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* c0-cf */
11237c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* d0-df */
11337c9f0a6Schristos	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* e0-ef */
11437c9f0a6Schristos	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* f0-ff */
115