2 Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
26 /* This file implements fixed size bitsets stored as an array
27 of words. Any unused bits in the last word must be zero. */
29 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
30 #define ABITSET_WORDS(X) ((X)->a.words)
34 abitset_resize (bitset src
, bitset_bindex size
)
36 /* These bitsets have a fixed size. */
37 if (BITSET_SIZE_ (src
) != size
)
43 /* Find list of up to NUM bits set in BSET starting from and including
44 *NEXT and store in array LIST. Return with actual number of bits
45 found and with *NEXT indicating where search stopped. */
47 abitset_small_list (bitset src
, bitset_bindex
*list
,
48 bitset_bindex num
, bitset_bindex
*next
)
55 word
= ABITSET_WORDS (src
)[0];
57 /* Short circuit common case. */
61 size
= BITSET_SIZE_ (src
);
68 /* If num is 1, we could speed things up with a binary search
69 of the word of interest. */
71 if (num
>= BITSET_WORD_BITS
)
73 for (count
= 0; word
; bitno
++)
76 list
[count
++] = bitno
;
82 for (count
= 0; word
; bitno
++)
86 list
[count
++] = bitno
;
102 /* Set bit BITNO in bitset DST. */
104 abitset_set (bitset dst ATTRIBUTE_UNUSED
, bitset_bindex bitno ATTRIBUTE_UNUSED
)
106 /* This should never occur for abitsets since we should always hit
107 the cache. It is likely someone is trying to access outside the
108 bounds of the bitset. */
113 /* Reset bit BITNO in bitset DST. */
115 abitset_reset (bitset dst ATTRIBUTE_UNUSED
,
116 bitset_bindex bitno ATTRIBUTE_UNUSED
)
118 /* This should never occur for abitsets since we should always hit
119 the cache. It is likely someone is trying to access outside the
120 bounds of the bitset. Since the bit is zero anyway, let it pass. */
124 /* Test bit BITNO in bitset SRC. */
126 abitset_test (bitset src ATTRIBUTE_UNUSED
,
127 bitset_bindex bitno ATTRIBUTE_UNUSED
)
129 /* This should never occur for abitsets since we should always
135 /* Find list of up to NUM bits set in BSET in reverse order, starting
136 from and including NEXT and store in array LIST. Return with
137 actual number of bits found and with *NEXT indicating where search
140 abitset_list_reverse (bitset src
, bitset_bindex
*list
,
141 bitset_bindex num
, bitset_bindex
*next
)
144 bitset_bindex rbitno
;
146 bitset_windex windex
;
148 bitset_bindex bitoff
;
149 bitset_word
*srcp
= ABITSET_WORDS (src
);
150 bitset_bindex n_bits
= BITSET_SIZE_ (src
);
154 /* If num is 1, we could speed things up with a binary search
155 of the word of interest. */
157 if (rbitno
>= n_bits
)
162 bitno
= n_bits
- (rbitno
+ 1);
164 windex
= bitno
/ BITSET_WORD_BITS
;
165 bitcnt
= bitno
% BITSET_WORD_BITS
;
166 bitoff
= windex
* BITSET_WORD_BITS
;
172 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
173 for (; word
; bitcnt
--)
175 if (word
& BITSET_MSB
)
177 list
[count
++] = bitoff
+ bitcnt
;
180 *next
= n_bits
- (bitoff
+ bitcnt
);
186 bitoff
-= BITSET_WORD_BITS
;
187 bitcnt
= BITSET_WORD_BITS
- 1;
191 *next
= n_bits
- (bitoff
+ 1);
196 /* Find list of up to NUM bits set in BSET starting from and including
197 *NEXT and store in array LIST. Return with actual number of bits
198 found and with *NEXT indicating where search stopped. */
200 abitset_list (bitset src
, bitset_bindex
*list
,
201 bitset_bindex num
, bitset_bindex
*next
)
205 bitset_windex windex
;
206 bitset_bindex bitoff
;
207 bitset_windex size
= src
->b
.csize
;
208 bitset_word
*srcp
= ABITSET_WORDS (src
);
216 /* Many bitsets are zero, so make this common case fast. */
217 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
222 /* If num is 1, we could speed things up with a binary search
223 of the current word. */
225 bitoff
= windex
* BITSET_WORD_BITS
;
229 if (bitno
>= BITSET_SIZE_ (src
))
232 windex
= bitno
/ BITSET_WORD_BITS
;
233 bitno
= bitno
% BITSET_WORD_BITS
;
237 /* Handle the case where we start within a word.
238 Most often, this is executed with large bitsets
239 with many set bits where we filled the array
240 on the previous call to this function. */
242 bitoff
= windex
* BITSET_WORD_BITS
;
243 word
= srcp
[windex
] >> bitno
;
244 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
248 list
[count
++] = bitno
;
259 bitoff
= windex
* BITSET_WORD_BITS
;
262 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
264 if (!(word
= srcp
[windex
]))
267 if ((count
+ BITSET_WORD_BITS
) < num
)
269 for (bitno
= bitoff
; word
; bitno
++)
272 list
[count
++] = bitno
;
278 for (bitno
= bitoff
; word
; bitno
++)
282 list
[count
++] = bitno
;
299 /* Ensure that any unused bits within the last word are clear. */
301 abitset_unused_clear (bitset dst
)
303 unsigned int last_bit
;
305 last_bit
= BITSET_SIZE_ (dst
) % BITSET_WORD_BITS
;
307 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
308 ((bitset_word
) 1 << last_bit
) - 1;
313 abitset_ones (bitset dst
)
315 bitset_word
*dstp
= ABITSET_WORDS (dst
);
318 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
320 memset (dstp
, -1, bytes
);
321 abitset_unused_clear (dst
);
326 abitset_zero (bitset dst
)
328 bitset_word
*dstp
= ABITSET_WORDS (dst
);
331 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
333 memset (dstp
, 0, bytes
);
338 abitset_empty_p (bitset dst
)
341 bitset_word
*dstp
= ABITSET_WORDS (dst
);
343 for (i
= 0; i
< dst
->b
.csize
; i
++)
352 abitset_copy1 (bitset dst
, bitset src
)
354 bitset_word
*srcp
= ABITSET_WORDS (src
);
355 bitset_word
*dstp
= ABITSET_WORDS (dst
);
356 bitset_windex size
= dst
->b
.csize
;
360 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
365 abitset_not (bitset dst
, bitset src
)
368 bitset_word
*srcp
= ABITSET_WORDS (src
);
369 bitset_word
*dstp
= ABITSET_WORDS (dst
);
370 bitset_windex size
= dst
->b
.csize
;
372 for (i
= 0; i
< size
; i
++)
373 *dstp
++ = ~(*srcp
++);
374 abitset_unused_clear (dst
);
379 abitset_equal_p (bitset dst
, bitset src
)
382 bitset_word
*srcp
= ABITSET_WORDS (src
);
383 bitset_word
*dstp
= ABITSET_WORDS (dst
);
384 bitset_windex size
= dst
->b
.csize
;
386 for (i
= 0; i
< size
; i
++)
387 if (*srcp
++ != *dstp
++)
394 abitset_subset_p (bitset dst
, bitset src
)
397 bitset_word
*srcp
= ABITSET_WORDS (src
);
398 bitset_word
*dstp
= ABITSET_WORDS (dst
);
399 bitset_windex size
= dst
->b
.csize
;
401 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
402 if (*dstp
!= (*srcp
| *dstp
))
409 abitset_disjoint_p (bitset dst
, bitset src
)
412 bitset_word
*srcp
= ABITSET_WORDS (src
);
413 bitset_word
*dstp
= ABITSET_WORDS (dst
);
414 bitset_windex size
= dst
->b
.csize
;
416 for (i
= 0; i
< size
; i
++)
417 if (*srcp
++ & *dstp
++)
425 abitset_and (bitset dst
, bitset src1
, bitset src2
)
428 bitset_word
*src1p
= ABITSET_WORDS (src1
);
429 bitset_word
*src2p
= ABITSET_WORDS (src2
);
430 bitset_word
*dstp
= ABITSET_WORDS (dst
);
431 bitset_windex size
= dst
->b
.csize
;
433 for (i
= 0; i
< size
; i
++)
434 *dstp
++ = *src1p
++ & *src2p
++;
439 abitset_and_cmp (bitset dst
, bitset src1
, bitset src2
)
442 bool changed
= false;
443 bitset_word
*src1p
= ABITSET_WORDS (src1
);
444 bitset_word
*src2p
= ABITSET_WORDS (src2
);
445 bitset_word
*dstp
= ABITSET_WORDS (dst
);
446 bitset_windex size
= dst
->b
.csize
;
448 for (i
= 0; i
< size
; i
++, dstp
++)
450 bitset_word tmp
= *src1p
++ & *src2p
++;
463 abitset_andn (bitset dst
, bitset src1
, bitset src2
)
466 bitset_word
*src1p
= ABITSET_WORDS (src1
);
467 bitset_word
*src2p
= ABITSET_WORDS (src2
);
468 bitset_word
*dstp
= ABITSET_WORDS (dst
);
469 bitset_windex size
= dst
->b
.csize
;
471 for (i
= 0; i
< size
; i
++)
472 *dstp
++ = *src1p
++ & ~(*src2p
++);
477 abitset_andn_cmp (bitset dst
, bitset src1
, bitset src2
)
480 bool changed
= false;
481 bitset_word
*src1p
= ABITSET_WORDS (src1
);
482 bitset_word
*src2p
= ABITSET_WORDS (src2
);
483 bitset_word
*dstp
= ABITSET_WORDS (dst
);
484 bitset_windex size
= dst
->b
.csize
;
486 for (i
= 0; i
< size
; i
++, dstp
++)
488 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
501 abitset_or (bitset dst
, bitset src1
, bitset src2
)
504 bitset_word
*src1p
= ABITSET_WORDS (src1
);
505 bitset_word
*src2p
= ABITSET_WORDS (src2
);
506 bitset_word
*dstp
= ABITSET_WORDS (dst
);
507 bitset_windex size
= dst
->b
.csize
;
509 for (i
= 0; i
< size
; i
++)
510 *dstp
++ = *src1p
++ | *src2p
++;
515 abitset_or_cmp (bitset dst
, bitset src1
, bitset src2
)
518 bool changed
= false;
519 bitset_word
*src1p
= ABITSET_WORDS (src1
);
520 bitset_word
*src2p
= ABITSET_WORDS (src2
);
521 bitset_word
*dstp
= ABITSET_WORDS (dst
);
522 bitset_windex size
= dst
->b
.csize
;
524 for (i
= 0; i
< size
; i
++, dstp
++)
526 bitset_word tmp
= *src1p
++ | *src2p
++;
539 abitset_xor (bitset dst
, bitset src1
, bitset src2
)
542 bitset_word
*src1p
= ABITSET_WORDS (src1
);
543 bitset_word
*src2p
= ABITSET_WORDS (src2
);
544 bitset_word
*dstp
= ABITSET_WORDS (dst
);
545 bitset_windex size
= dst
->b
.csize
;
547 for (i
= 0; i
< size
; i
++)
548 *dstp
++ = *src1p
++ ^ *src2p
++;
553 abitset_xor_cmp (bitset dst
, bitset src1
, bitset src2
)
556 bool changed
= false;
557 bitset_word
*src1p
= ABITSET_WORDS (src1
);
558 bitset_word
*src2p
= ABITSET_WORDS (src2
);
559 bitset_word
*dstp
= ABITSET_WORDS (dst
);
560 bitset_windex size
= dst
->b
.csize
;
562 for (i
= 0; i
< size
; i
++, dstp
++)
564 bitset_word tmp
= *src1p
++ ^ *src2p
++;
577 abitset_and_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
580 bitset_word
*src1p
= ABITSET_WORDS (src1
);
581 bitset_word
*src2p
= ABITSET_WORDS (src2
);
582 bitset_word
*src3p
= ABITSET_WORDS (src3
);
583 bitset_word
*dstp
= ABITSET_WORDS (dst
);
584 bitset_windex size
= dst
->b
.csize
;
586 for (i
= 0; i
< size
; i
++)
587 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
592 abitset_and_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
595 bool changed
= false;
596 bitset_word
*src1p
= ABITSET_WORDS (src1
);
597 bitset_word
*src2p
= ABITSET_WORDS (src2
);
598 bitset_word
*src3p
= ABITSET_WORDS (src3
);
599 bitset_word
*dstp
= ABITSET_WORDS (dst
);
600 bitset_windex size
= dst
->b
.csize
;
602 for (i
= 0; i
< size
; i
++, dstp
++)
604 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
617 abitset_andn_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
620 bitset_word
*src1p
= ABITSET_WORDS (src1
);
621 bitset_word
*src2p
= ABITSET_WORDS (src2
);
622 bitset_word
*src3p
= ABITSET_WORDS (src3
);
623 bitset_word
*dstp
= ABITSET_WORDS (dst
);
624 bitset_windex size
= dst
->b
.csize
;
626 for (i
= 0; i
< size
; i
++)
627 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
632 abitset_andn_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
635 bool changed
= false;
636 bitset_word
*src1p
= ABITSET_WORDS (src1
);
637 bitset_word
*src2p
= ABITSET_WORDS (src2
);
638 bitset_word
*src3p
= ABITSET_WORDS (src3
);
639 bitset_word
*dstp
= ABITSET_WORDS (dst
);
640 bitset_windex size
= dst
->b
.csize
;
642 for (i
= 0; i
< size
; i
++, dstp
++)
644 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
657 abitset_or_and (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
660 bitset_word
*src1p
= ABITSET_WORDS (src1
);
661 bitset_word
*src2p
= ABITSET_WORDS (src2
);
662 bitset_word
*src3p
= ABITSET_WORDS (src3
);
663 bitset_word
*dstp
= ABITSET_WORDS (dst
);
664 bitset_windex size
= dst
->b
.csize
;
666 for (i
= 0; i
< size
; i
++)
667 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
672 abitset_or_and_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
675 bool changed
= false;
676 bitset_word
*src1p
= ABITSET_WORDS (src1
);
677 bitset_word
*src2p
= ABITSET_WORDS (src2
);
678 bitset_word
*src3p
= ABITSET_WORDS (src3
);
679 bitset_word
*dstp
= ABITSET_WORDS (dst
);
680 bitset_windex size
= dst
->b
.csize
;
682 for (i
= 0; i
< size
; i
++, dstp
++)
684 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
697 abitset_copy (bitset dst
, bitset src
)
699 if (BITSET_COMPATIBLE_ (dst
, src
))
700 abitset_copy1 (dst
, src
);
702 bitset_copy_ (dst
, src
);
706 /* Vector of operations for single word bitsets. */
707 struct bitset_vtable abitset_small_vtable
= {
738 abitset_list_reverse
,
744 /* Vector of operations for multiple word bitsets. */
745 struct bitset_vtable abitset_vtable
= {
776 abitset_list_reverse
,
783 abitset_bytes (bitset_bindex n_bits
)
787 size_t header_size
= offsetof (union bitset_union
, a
.words
);
788 struct bitset_align_struct
{ char a
; union bitset_union b
; };
789 size_t bitset_alignment
= offsetof (struct bitset_align_struct
, b
);
791 size
= ABITSET_N_WORDS (n_bits
);
792 bytes
= header_size
+ size
* sizeof (bitset_word
);
794 /* Align the size properly for a vector of abitset objects. */
795 if (header_size
% bitset_alignment
!= 0
796 || sizeof (bitset_word
) % bitset_alignment
!= 0)
798 bytes
+= bitset_alignment
- 1;
799 bytes
-= bytes
% bitset_alignment
;
807 abitset_init (bitset bset
, bitset_bindex n_bits
)
811 size
= ABITSET_N_WORDS (n_bits
);
812 BITSET_NBITS_ (bset
) = n_bits
;
814 /* Use optimized routines if bitset fits within a single word.
815 There is probably little merit if using caching since
816 the small bitset will always fit in the cache. */
818 bset
->b
.vtable
= &abitset_small_vtable
;
820 bset
->b
.vtable
= &abitset_vtable
;
823 bset
->b
.csize
= size
;
824 bset
->b
.cdata
= ABITSET_WORDS (bset
);