/root/src/xen/xen/arch/x86/bitops.c
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | #include <xen/bitops.h> |
3 | | #include <xen/lib.h> |
4 | | |
5 | | unsigned int __find_first_bit( |
6 | | const unsigned long *addr, unsigned int size) |
7 | 9.77M | { |
8 | 9.77M | unsigned long d0, d1, res; |
9 | 9.77M | |
10 | 9.77M | asm volatile ( |
11 | 9.77M | "1: xor %%eax,%%eax\n\t" /* also ensures ZF==1 if size==0 */ |
12 | 9.77M | " repe; scas"__OS"\n\t" |
13 | 9.77M | " je 2f\n\t" |
14 | 9.77M | " bsf -"STR(BITS_PER_LONG/8)"(%2),%0\n\t" |
15 | 9.77M | " jz 1b\n\t" |
16 | 9.77M | " lea -"STR(BITS_PER_LONG/8)"(%2),%2\n\t" |
17 | 9.77M | "2: sub %%ebx,%%edi\n\t" |
18 | 9.77M | " shl $3,%%edi\n\t" |
19 | 9.77M | " add %%edi,%%eax" |
20 | 9.77M | : "=&a" (res), "=&c" (d0), "=&D" (d1) |
21 | 9.77M | : "1" (BITS_TO_LONGS(size)), "2" (addr), "b" ((int)(long)addr) |
22 | 9.77M | : "memory" ); |
23 | 9.77M | |
24 | 9.77M | return res; |
25 | 9.77M | } |
26 | | |
27 | | unsigned int __find_next_bit( |
28 | | const unsigned long *addr, unsigned int size, unsigned int offset) |
29 | 18.2M | { |
30 | 18.2M | const unsigned long *p = addr + (offset / BITS_PER_LONG); |
31 | 18.2M | unsigned int set, bit = offset & (BITS_PER_LONG - 1); |
32 | 18.2M | |
33 | 18.2M | ASSERT(offset <= size); |
34 | 18.2M | |
35 | 18.2M | if ( bit != 0 ) |
36 | 18.3M | { |
37 | 18.3M | /* Look for a bit in the first word. */ |
38 | 18.3M | set = __scanbit(*p >> bit, BITS_PER_LONG - bit); |
39 | 18.3M | if ( set < (BITS_PER_LONG - bit) ) |
40 | 13.9M | return (offset + set); |
41 | 4.38M | offset += BITS_PER_LONG - bit; |
42 | 4.38M | p++; |
43 | 4.38M | } |
44 | 18.2M | |
45 | 4.33M | if ( offset >= size ) |
46 | 4.99M | return size; |
47 | 4.33M | |
48 | 4.33M | /* Search remaining full words for a bit. */ |
49 | 18.4E | set = __find_first_bit(p, size - offset); |
50 | 18.4E | return (offset + set); |
51 | 4.33M | } |
52 | | |
53 | | unsigned int __find_first_zero_bit( |
54 | | const unsigned long *addr, unsigned int size) |
55 | 3 | { |
56 | 3 | unsigned long d0, d1, d2, res; |
57 | 3 | |
58 | 3 | asm volatile ( |
59 | 3 | "1: xor %%eax,%%eax ; not %3\n\t" /* rAX == ~0ul */ |
60 | 3 | " xor %%edx,%%edx\n\t" /* also ensures ZF==1 if size==0 */ |
61 | 3 | " repe; scas"__OS"\n\t" |
62 | 3 | " je 2f\n\t" |
63 | 3 | " xor -"STR(BITS_PER_LONG/8)"(%2),%3\n\t" |
64 | 3 | " jz 1b\n\t" |
65 | 3 | " rep; bsf %3,%0\n\t" |
66 | 3 | " lea -"STR(BITS_PER_LONG/8)"(%2),%2\n\t" |
67 | 3 | "2: sub %%ebx,%%edi\n\t" |
68 | 3 | " shl $3,%%edi\n\t" |
69 | 3 | " add %%edi,%%edx" |
70 | 3 | : "=&d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) |
71 | 3 | : "1" (BITS_TO_LONGS(size)), "2" (addr), "b" ((int)(long)addr) |
72 | 3 | : "memory" ); |
73 | 3 | |
74 | 3 | return res; |
75 | 3 | } |
76 | | |
77 | | unsigned int __find_next_zero_bit( |
78 | | const unsigned long *addr, unsigned int size, unsigned int offset) |
79 | 3 | { |
80 | 3 | const unsigned long *p = addr + (offset / BITS_PER_LONG); |
81 | 3 | unsigned int set, bit = offset & (BITS_PER_LONG - 1); |
82 | 3 | |
83 | 3 | ASSERT(offset <= size); |
84 | 3 | |
85 | 3 | if ( bit != 0 ) |
86 | 2 | { |
87 | 2 | /* Look for zero in the first word. */ |
88 | 2 | set = __scanbit(~(*p >> bit), BITS_PER_LONG - bit); |
89 | 2 | if ( set < (BITS_PER_LONG - bit) ) |
90 | 1 | return (offset + set); |
91 | 1 | offset += BITS_PER_LONG - bit; |
92 | 1 | p++; |
93 | 1 | } |
94 | 3 | |
95 | 2 | if ( offset >= size ) |
96 | 0 | return size; |
97 | 2 | |
98 | 2 | /* Search remaining full words for a zero. */ |
99 | 2 | set = __find_first_zero_bit(p, size - offset); |
100 | 2 | return (offset + set); |
101 | 2 | } |