1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#ident "$Id$"
/* ----------------------------------------------------------------------- *
*
* Copyright 2000-2001 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, Inc.,
* 59 Temple Place Ste 330, Boston MA 02111-1307, USA, version 2.1,
* incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* bitops.h
*
* Internals for LPSM: bitmap operations. Not to be used by applications.
*/
#ifndef LPSM_BITOPS_H
#define LPSM_BITOPS_H
#include <inttypes.h>
#include "system.h" /* System-specific constants */
/* The data type to use for bitfield scanning. Typically should equal
the "natural" size on the machine; defined in system.h. */
#if MACHINE_SIZE_LG2 == 6
typedef uint64_t bitscan_t;
#else
typedef uint32_t bitscan_t;
#endif
#define BITSCAN_SHIFT MACHINE_SIZE_LG2
#define BITSCAN_BITS (1 << BITSCAN_SHIFT)
#define BITSCAN_MASK (BITSCAN_BITS-1)
#define BITSCAN_0 ((bitscan_t)0)
#define BITSCAN_1 ((bitscan_t)1)
/*
* These should be revamped to be thread-safe at some point. That
* may mean doing things that are architecture-specific...
*
* Important: "bit" can be negative, and that needs to be handled
* correctly!
*/
static inline int test_bit(const void *ptr, int bit)
{
#if defined(__GNUC__) && defined(__i386__)
int rv;
asm("xorl %0,%0 ; btl %2,%1 ; adcl %0,%0"
: "=&r" (rv) : "m" (*(const bitscan_t *)ptr), "r" (bit) : "cc");
return rv;
#else
const bitscan_t *cp;
cp = (const bitscan_t *)ptr + (bit >> BITSCAN_SHIFT);
return (int)((*cp >> (bit & BITSCAN_MASK)) & BITSCAN_1);
#endif
}
static inline void set_bit(void *ptr, int bit)
{
#if defined(__GNUC__) && defined(__i386__)
asm volatile("btsl %1,%0" : "=m" (*(bitscan_t *)ptr) : "r" (bit) : "cc");
#else
bitscan_t *cp;
cp = (bitscan_t *)ptr + (bit >> BITSCAN_SHIFT);
*cp |= (BITSCAN_1 << (bit & BITSCAN_MASK));
#endif
}
static inline void clr_bit(void *ptr, int bit)
{
#if defined(__GNUC__) && defined(__i386__)
asm volatile("btcl %1,%0" : "=m" (*(bitscan_t *)ptr) : "r" (bit) : "cc");
#else
bitscan_t *cp;
cp = (bitscan_t *)ptr + (bit >> BITSCAN_SHIFT);
*cp &= ~(BITSCAN_1 << (bit & BITSCAN_MASK));
#endif
}
int lpsm_find_set_bit(const void *ptr, int start, int count, int err);
#endif
|