xref: /csrg-svn/lib/libc/sparc/string/ffs.s (revision 54401)
1/*
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * %sccs.include.redist.c%
10 *
11 * from: $Header: ffs.s,v 1.1 91/07/07 05:29:48 torek Exp $
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15	.asciz "@(#)ffs.s	5.1 (Berkeley) 06/25/92"
16#endif  /* LIBC_SCCS and not lint */
17
18/*
19 * ffs returns the number of the rightmost bit set in its argument,
20 * i.e., the lowest value such that (x & (ffs(x) - 1)) is nonzero.
21 * If no bits are set, ffs returns 0.
22 *
23 * We use a table lookup, one byte at a time.
24 * Note that the table has a special value in slot 0.
25 */
26
27ffstab:
28	.byte	-24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */
29	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 10-1f */
30	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 20-2f */
31	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 30-3f */
32	.byte	7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 40-4f */
33	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 50-5f */
34	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 60-6f */
35	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 70-7f */
36	.byte	8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 80-8f */
37	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* 10-9f */
38	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* a0-af */
39	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* b0-bf */
40	.byte	7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* c0-cf */
41	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* d0-df */
42	.byte	6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* e0-ef */
43	.byte	5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1	/* f0-ff */
44
45/*
46 * We use a table lookup on each byte.
47 *
48 * In each section below, %o1 is the current byte (0, 1, 2, or 3).
49 * The last byte is handled specially: for the first three,
50 * if that byte is nonzero, we return the table value
51 * (plus 0, 8, or 16 for the byte number), but for the last
52 * one, we just return the table value plus 24.  This means
53 * that ffstab[0] must be -24 so that ffs(0) will return 0.
54 */
55	.global	_ffs
56_ffs:
57	set	ffstab, %o2
58	andcc	%o0, 0xff, %o1	! get low byte
59	be,a	1f		! try again if 0
60	srl	%o0, 8, %o0	! delay slot, get ready for next byte
61
62	retl			! return ffstab[%o1]
63	ldsb	[%o2 + %o1], %o0
64
651:
66	andcc	%o0, 0xff, %o1	! byte 1 like byte 0...
67	be,a	2f
68	srl	%o0, 8, %o0	! (use delay to prepare for byte 2)
69
70	ldsb	[%o2 + %o1], %o0
71	retl			! return ffstab[%o1] + 8
72	add	%o0, 8, %o0
73
742:
75	andcc	%o0, 0xff, %o1
76	be,a	3f
77	srl	%o0, 8, %o0	! (prepare for byte 3)
78
79	ldsb	[%o2 + %o1], %o0
80	retl			! return ffstab[%o1] + 16
81	add	%o0, 16, %o0
82
833:				! just return ffstab[%o0] + 24
84	ldsb	[%o2 + %o0], %o0
85	retl
86	add	%o0, 24, %o0
87