1/*
2 * bit manipulation utility functions
3 *
4 * Copyright 2007, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 * $Id: bitfuncs.h,v 1.1.1.1 2008/10/15 03:25:54 james26_jang Exp $
12 */
13
14#ifndef _BITFUNCS_H
15#define _BITFUNCS_H
16
17#include <typedefs.h>
18
19/* local prototypes */
20static INLINE uint32 find_msbit(uint32 x);
21
22
23/*
24 * find_msbit: returns index of most significant set bit in x, with index
25 *   range defined as 0-31.  NOTE: returns zero if input is zero.
26 */
27
28#if defined(USE_PENTIUM_BSR) && defined(__GNUC__)
29
30/*
31 * Implementation for Pentium processors and gcc.  Note that this
32 * instruction is actually very slow on some processors (e.g., family 5,
33 * model 2, stepping 12, "Pentium 75 - 200"), so we use the generic
34 * implementation instead.
35 */
36static INLINE uint32 find_msbit(uint32 x)
37{
38	uint msbit;
39	__asm__("bsrl %1,%0"
40	        :"=r" (msbit)
41	        :"r" (x));
42	return msbit;
43}
44
45#else	/* !USE_PENTIUM_BSR || !__GNUC__ */
46
47/*
48 * Generic Implementation
49 */
50
51#define DB_POW_MASK16	0xffff0000
52#define DB_POW_MASK8	0x0000ff00
53#define DB_POW_MASK4	0x000000f0
54#define DB_POW_MASK2	0x0000000c
55#define DB_POW_MASK1	0x00000002
56
57static INLINE uint32 find_msbit(uint32 x)
58{
59	uint32 temp_x = x;
60	uint msbit = 0;
61	if (temp_x & DB_POW_MASK16) {
62		temp_x >>= 16;
63		msbit = 16;
64	}
65	if (temp_x & DB_POW_MASK8) {
66		temp_x >>= 8;
67		msbit += 8;
68	}
69	if (temp_x & DB_POW_MASK4) {
70		temp_x >>= 4;
71		msbit += 4;
72	}
73	if (temp_x & DB_POW_MASK2) {
74		temp_x >>= 2;
75		msbit += 2;
76	}
77	if (temp_x & DB_POW_MASK1) {
78		msbit += 1;
79	}
80	return (msbit);
81}
82
83#endif	/* USE_PENTIUM_BSR && __GNUC__ */
84
85#endif /* _BITFUNCS_H */
86