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 3 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, see <http://www.gnu.org/licenses/>. */
25 /* This file implements fixed size bitsets stored as an array
26 of words. Any unused bits in the last word must be zero. */
28 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
29 #define ABITSET_WORDS(X) ((X)->a.words)
33 abitset_resize (bitset src
, bitset_bindex size
)
35 /* These bitsets have a fixed size. */
36 if (BITSET_SIZE_ (src
) != size
)
42 /* Find list of up to NUM bits set in BSET starting from and including
43 *NEXT and store in array LIST. Return with actual number of bits
44 found and with *NEXT indicating where search stopped. */
46 abitset_small_list (bitset src
, bitset_bindex
*list
,
47 bitset_bindex num
, bitset_bindex
*next
)
54 word
= ABITSET_WORDS (src
)[0];
56 /* Short circuit common case. */
60 size
= BITSET_SIZE_ (src
);
67 /* If num is 1, we could speed things up with a binary search
68 of the word of interest. */
70 if (num
>= BITSET_WORD_BITS
)
72 for (count
= 0; word
; bitno
++)
75 list
[count
++] = bitno
;
81 for (count
= 0; word
; bitno
++)
85 list
[count
++] = bitno
;
101 /* Set bit BITNO in bitset DST. */
103 abitset_set (bitset dst ATTRIBUTE_UNUSED
, bitset_bindex bitno ATTRIBUTE_UNUSED
)
105 /* This should never occur for abitsets since we should always hit
106 the cache. It is likely someone is trying to access outside the
107 bounds of the bitset. */
112 /* Reset bit BITNO in bitset DST. */
114 abitset_reset (bitset dst ATTRIBUTE_UNUSED
,
115 bitset_bindex bitno ATTRIBUTE_UNUSED
)
117 /* This should never occur for abitsets since we should always hit
118 the cache. It is likely someone is trying to access outside the
119 bounds of the bitset. Since the bit is zero anyway, let it pass. */
123 /* Test bit BITNO in bitset SRC. */
125 abitset_test (bitset src ATTRIBUTE_UNUSED
,
126 bitset_bindex bitno ATTRIBUTE_UNUSED
)
128 /* This should never occur for abitsets since we should always
134 /* Find list of up to NUM bits set in BSET in reverse order, starting
135 from and including NEXT and store in array LIST. Return with
136 actual number of bits found and with *NEXT indicating where search
139 abitset_list_reverse (bitset src
, bitset_bindex
*list
,
140 bitset_bindex num
, bitset_bindex
*next
)
143 bitset_bindex rbitno
;
145 bitset_windex windex
;
147 bitset_bindex bitoff
;
148 bitset_word
*srcp
= ABITSET_WORDS (src
);
149 bitset_bindex n_bits
= BITSET_SIZE_ (src
);
153 /* If num is 1, we could speed things up with a binary search
154 of the word of interest. */
156 if (rbitno
>= n_bits
)
161 bitno
= n_bits
- (rbitno
+ 1);
163 windex
= bitno
/ BITSET_WORD_BITS
;
164 bitcnt
= bitno
% BITSET_WORD_BITS
;
165 bitoff
= windex
* BITSET_WORD_BITS
;
171 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
172 for (; word
; bitcnt
--)
174 if (word
& BITSET_MSB
)
176 list
[count
++] = bitoff
+ bitcnt
;
179 *next
= n_bits
- (bitoff
+ bitcnt
);
185 bitoff
-= BITSET_WORD_BITS
;
186 bitcnt
= BITSET_WORD_BITS
- 1;
190 *next
= n_bits
- (bitoff
+ 1);
195 /* Find list of up to NUM bits set in BSET starting from and including
196 *NEXT and store in array LIST. Return with actual number of bits
197 found and with *NEXT indicating where search stopped. */
199 abitset_list (bitset src
, bitset_bindex
*list
,
200 bitset_bindex num
, bitset_bindex
*next
)
204 bitset_windex windex
;
205 bitset_bindex bitoff
;
206 bitset_windex size
= src
->b
.csize
;
207 bitset_word
*srcp
= ABITSET_WORDS (src
);
215 /* Many bitsets are zero, so make this common case fast. */
216 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
221 /* If num is 1, we could speed things up with a binary search
222 of the current word. */
224 bitoff
= windex
* BITSET_WORD_BITS
;
228 if (bitno
>= BITSET_SIZE_ (src
))
231 windex
= bitno
/ BITSET_WORD_BITS
;
232 bitno
= bitno
% BITSET_WORD_BITS
;
236 /* Handle the case where we start within a word.
237 Most often, this is executed with large bitsets
238 with many set bits where we filled the array
239 on the previous call to this function. */
241 bitoff
= windex
* BITSET_WORD_BITS
;
242 word
= srcp
[windex
] >> bitno
;
243 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
247 list
[count
++] = bitno
;
258 bitoff
= windex
* BITSET_WORD_BITS
;
261 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
263 if (!(word
= srcp
[windex
]))
266 if ((count
+ BITSET_WORD_BITS
) < num
)
268 for (bitno
= bitoff
; word
; bitno
++)
271 list
[count
++] = bitno
;
277 for (bitno
= bitoff
; word
; bitno
++)
281 list
[count
++] = bitno
;
298 /* Ensure that any unused bits within the last word are clear. */
300 abitset_unused_clear (bitset dst
)
302 unsigned int last_bit
;
304 last_bit
= BITSET_SIZE_ (dst
) % BITSET_WORD_BITS
;
306 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
307 ((bitset_word
) 1 << last_bit
) - 1;
312 abitset_ones (bitset dst
)
314 bitset_word
*dstp
= ABITSET_WORDS (dst
);
317 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
319 memset (dstp
, -1, bytes
);
320 abitset_unused_clear (dst
);
325 abitset_zero (bitset dst
)
327 bitset_word
*dstp
= ABITSET_WORDS (dst
);
330 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
332 memset (dstp
, 0, bytes
);
337 abitset_empty_p (bitset dst
)
340 bitset_word
*dstp
= ABITSET_WORDS (dst
);
342 for (i
= 0; i
< dst
->b
.csize
; i
++)
351 abitset_copy1 (bitset dst
, bitset src
)
353 bitset_word
*srcp
= ABITSET_WORDS (src
);
354 bitset_word
*dstp
= ABITSET_WORDS (dst
);
355 bitset_windex size
= dst
->b
.csize
;
359 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
364 abitset_not (bitset dst
, bitset src
)
367 bitset_word
*srcp
= ABITSET_WORDS (src
);
368 bitset_word
*dstp
= ABITSET_WORDS (dst
);
369 bitset_windex size
= dst
->b
.csize
;
371 for (i
= 0; i
< size
; i
++)
372 *dstp
++ = ~(*srcp
++);
373 abitset_unused_clear (dst
);
378 abitset_equal_p (bitset dst
, bitset src
)
381 bitset_word
*srcp
= ABITSET_WORDS (src
);
382 bitset_word
*dstp
= ABITSET_WORDS (dst
);
383 bitset_windex size
= dst
->b
.csize
;
385 for (i
= 0; i
< size
; i
++)
386 if (*srcp
++ != *dstp
++)
393 abitset_subset_p (bitset dst
, bitset src
)
396 bitset_word
*srcp
= ABITSET_WORDS (src
);
397 bitset_word
*dstp
= ABITSET_WORDS (dst
);
398 bitset_windex size
= dst
->b
.csize
;
400 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
401 if (*dstp
!= (*srcp
| *dstp
))
408 abitset_disjoint_p (bitset dst
, bitset src
)
411 bitset_word
*srcp
= ABITSET_WORDS (src
);
412 bitset_word
*dstp
= ABITSET_WORDS (dst
);
413 bitset_windex size
= dst
->b
.csize
;
415 for (i
= 0; i
< size
; i
++)
416 if (*srcp
++ & *dstp
++)
424 abitset_and (bitset dst
, bitset src1
, bitset src2
)
427 bitset_word
*src1p
= ABITSET_WORDS (src1
);
428 bitset_word
*src2p
= ABITSET_WORDS (src2
);
429 bitset_word
*dstp
= ABITSET_WORDS (dst
);
430 bitset_windex size
= dst
->b
.csize
;
432 for (i
= 0; i
< size
; i
++)
433 *dstp
++ = *src1p
++ & *src2p
++;
438 abitset_and_cmp (bitset dst
, bitset src1
, bitset src2
)
441 bool changed
= false;
442 bitset_word
*src1p
= ABITSET_WORDS (src1
);
443 bitset_word
*src2p
= ABITSET_WORDS (src2
);
444 bitset_word
*dstp
= ABITSET_WORDS (dst
);
445 bitset_windex size
= dst
->b
.csize
;
447 for (i
= 0; i
< size
; i
++, dstp
++)
449 bitset_word tmp
= *src1p
++ & *src2p
++;
462 abitset_andn (bitset dst
, bitset src1
, bitset src2
)
465 bitset_word
*src1p
= ABITSET_WORDS (src1
);
466 bitset_word
*src2p
= ABITSET_WORDS (src2
);
467 bitset_word
*dstp
= ABITSET_WORDS (dst
);
468 bitset_windex size
= dst
->b
.csize
;
470 for (i
= 0; i
< size
; i
++)
471 *dstp
++ = *src1p
++ & ~(*src2p
++);
476 abitset_andn_cmp (bitset dst
, bitset src1
, bitset src2
)
479 bool changed
= false;
480 bitset_word
*src1p
= ABITSET_WORDS (src1
);
481 bitset_word
*src2p
= ABITSET_WORDS (src2
);
482 bitset_word
*dstp
= ABITSET_WORDS (dst
);
483 bitset_windex size
= dst
->b
.csize
;
485 for (i
= 0; i
< size
; i
++, dstp
++)
487 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
500 abitset_or (bitset dst
, bitset src1
, bitset src2
)
503 bitset_word
*src1p
= ABITSET_WORDS (src1
);
504 bitset_word
*src2p
= ABITSET_WORDS (src2
);
505 bitset_word
*dstp
= ABITSET_WORDS (dst
);
506 bitset_windex size
= dst
->b
.csize
;
508 for (i
= 0; i
< size
; i
++)
509 *dstp
++ = *src1p
++ | *src2p
++;
514 abitset_or_cmp (bitset dst
, bitset src1
, bitset src2
)
517 bool changed
= false;
518 bitset_word
*src1p
= ABITSET_WORDS (src1
);
519 bitset_word
*src2p
= ABITSET_WORDS (src2
);
520 bitset_word
*dstp
= ABITSET_WORDS (dst
);
521 bitset_windex size
= dst
->b
.csize
;
523 for (i
= 0; i
< size
; i
++, dstp
++)
525 bitset_word tmp
= *src1p
++ | *src2p
++;
538 abitset_xor (bitset dst
, bitset src1
, bitset src2
)
541 bitset_word
*src1p
= ABITSET_WORDS (src1
);
542 bitset_word
*src2p
= ABITSET_WORDS (src2
);
543 bitset_word
*dstp
= ABITSET_WORDS (dst
);
544 bitset_windex size
= dst
->b
.csize
;
546 for (i
= 0; i
< size
; i
++)
547 *dstp
++ = *src1p
++ ^ *src2p
++;
552 abitset_xor_cmp (bitset dst
, bitset src1
, bitset src2
)
555 bool changed
= false;
556 bitset_word
*src1p
= ABITSET_WORDS (src1
);
557 bitset_word
*src2p
= ABITSET_WORDS (src2
);
558 bitset_word
*dstp
= ABITSET_WORDS (dst
);
559 bitset_windex size
= dst
->b
.csize
;
561 for (i
= 0; i
< size
; i
++, dstp
++)
563 bitset_word tmp
= *src1p
++ ^ *src2p
++;
576 abitset_and_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
579 bitset_word
*src1p
= ABITSET_WORDS (src1
);
580 bitset_word
*src2p
= ABITSET_WORDS (src2
);
581 bitset_word
*src3p
= ABITSET_WORDS (src3
);
582 bitset_word
*dstp
= ABITSET_WORDS (dst
);
583 bitset_windex size
= dst
->b
.csize
;
585 for (i
= 0; i
< size
; i
++)
586 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
591 abitset_and_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
594 bool changed
= false;
595 bitset_word
*src1p
= ABITSET_WORDS (src1
);
596 bitset_word
*src2p
= ABITSET_WORDS (src2
);
597 bitset_word
*src3p
= ABITSET_WORDS (src3
);
598 bitset_word
*dstp
= ABITSET_WORDS (dst
);
599 bitset_windex size
= dst
->b
.csize
;
601 for (i
= 0; i
< size
; i
++, dstp
++)
603 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
616 abitset_andn_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
619 bitset_word
*src1p
= ABITSET_WORDS (src1
);
620 bitset_word
*src2p
= ABITSET_WORDS (src2
);
621 bitset_word
*src3p
= ABITSET_WORDS (src3
);
622 bitset_word
*dstp
= ABITSET_WORDS (dst
);
623 bitset_windex size
= dst
->b
.csize
;
625 for (i
= 0; i
< size
; i
++)
626 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
631 abitset_andn_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
634 bool changed
= false;
635 bitset_word
*src1p
= ABITSET_WORDS (src1
);
636 bitset_word
*src2p
= ABITSET_WORDS (src2
);
637 bitset_word
*src3p
= ABITSET_WORDS (src3
);
638 bitset_word
*dstp
= ABITSET_WORDS (dst
);
639 bitset_windex size
= dst
->b
.csize
;
641 for (i
= 0; i
< size
; i
++, dstp
++)
643 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
656 abitset_or_and (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
659 bitset_word
*src1p
= ABITSET_WORDS (src1
);
660 bitset_word
*src2p
= ABITSET_WORDS (src2
);
661 bitset_word
*src3p
= ABITSET_WORDS (src3
);
662 bitset_word
*dstp
= ABITSET_WORDS (dst
);
663 bitset_windex size
= dst
->b
.csize
;
665 for (i
= 0; i
< size
; i
++)
666 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
671 abitset_or_and_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
674 bool changed
= false;
675 bitset_word
*src1p
= ABITSET_WORDS (src1
);
676 bitset_word
*src2p
= ABITSET_WORDS (src2
);
677 bitset_word
*src3p
= ABITSET_WORDS (src3
);
678 bitset_word
*dstp
= ABITSET_WORDS (dst
);
679 bitset_windex size
= dst
->b
.csize
;
681 for (i
= 0; i
< size
; i
++, dstp
++)
683 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
696 abitset_copy (bitset dst
, bitset src
)
698 if (BITSET_COMPATIBLE_ (dst
, src
))
699 abitset_copy1 (dst
, src
);
701 bitset_copy_ (dst
, src
);
705 /* Vector of operations for single word bitsets. */
706 struct bitset_vtable abitset_small_vtable
= {
737 abitset_list_reverse
,
743 /* Vector of operations for multiple word bitsets. */
744 struct bitset_vtable abitset_vtable
= {
775 abitset_list_reverse
,
782 abitset_bytes (bitset_bindex n_bits
)
786 size_t header_size
= offsetof (union bitset_union
, a
.words
);
787 struct bitset_align_struct
{ char a
; union bitset_union b
; };
788 size_t bitset_alignment
= offsetof (struct bitset_align_struct
, b
);
790 size
= ABITSET_N_WORDS (n_bits
);
791 bytes
= header_size
+ size
* sizeof (bitset_word
);
793 /* Align the size properly for a vector of abitset objects. */
794 if (header_size
% bitset_alignment
!= 0
795 || sizeof (bitset_word
) % bitset_alignment
!= 0)
797 bytes
+= bitset_alignment
- 1;
798 bytes
-= bytes
% bitset_alignment
;
806 abitset_init (bitset bset
, bitset_bindex n_bits
)
810 size
= ABITSET_N_WORDS (n_bits
);
811 BITSET_NBITS_ (bset
) = n_bits
;
813 /* Use optimized routines if bitset fits within a single word.
814 There is probably little merit if using caching since
815 the small bitset will always fit in the cache. */
817 bset
->b
.vtable
= &abitset_small_vtable
;
819 bset
->b
.vtable
= &abitset_vtable
;
822 bset
->b
.csize
= size
;
823 bset
->b
.cdata
= ABITSET_WORDS (bset
);