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
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 /* This file implements fixed size bitsets stored as an array
30 of words. Any unused bits in the last word must be zero. */
32 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
33 #define ABITSET_WORDS(X) ((X)->a.words)
37 abitset_resize (bitset src
, bitset_bindex size
)
39 /* These bitsets have a fixed size. */
40 if (BITSET_SIZE_ (src
) != size
)
46 /* Find list of up to NUM bits set in BSET starting from and including
47 *NEXT and store in array LIST. Return with actual number of bits
48 found and with *NEXT indicating where search stopped. */
50 abitset_small_list (bitset src
, bitset_bindex
*list
,
51 bitset_bindex num
, bitset_bindex
*next
)
58 word
= ABITSET_WORDS (src
)[0];
60 /* Short circuit common case. */
64 size
= BITSET_SIZE_ (src
);
71 /* If num is 1, we could speed things up with a binary search
72 of the word of interest. */
74 if (num
>= BITSET_WORD_BITS
)
76 for (count
= 0; word
; bitno
++)
79 list
[count
++] = bitno
;
85 for (count
= 0; word
; bitno
++)
89 list
[count
++] = bitno
;
105 /* Set bit BITNO in bitset DST. */
107 abitset_set (bitset dst ATTRIBUTE_UNUSED
, bitset_bindex bitno ATTRIBUTE_UNUSED
)
109 /* This should never occur for abitsets since we should always hit
110 the cache. It is likely someone is trying to access outside the
111 bounds of the bitset. */
116 /* Reset bit BITNO in bitset DST. */
118 abitset_reset (bitset dst ATTRIBUTE_UNUSED
,
119 bitset_bindex bitno ATTRIBUTE_UNUSED
)
121 /* This should never occur for abitsets since we should always hit
122 the cache. It is likely someone is trying to access outside the
123 bounds of the bitset. Since the bit is zero anyway, let it pass. */
127 /* Test bit BITNO in bitset SRC. */
129 abitset_test (bitset src ATTRIBUTE_UNUSED
,
130 bitset_bindex bitno ATTRIBUTE_UNUSED
)
132 /* This should never occur for abitsets since we should always
138 /* Find list of up to NUM bits set in BSET in reverse order, starting
139 from and including NEXT and store in array LIST. Return with
140 actual number of bits found and with *NEXT indicating where search
143 abitset_list_reverse (bitset src
, bitset_bindex
*list
,
144 bitset_bindex num
, bitset_bindex
*next
)
147 bitset_bindex rbitno
;
149 bitset_windex windex
;
151 bitset_bindex bitoff
;
152 bitset_word
*srcp
= ABITSET_WORDS (src
);
153 bitset_bindex n_bits
= BITSET_SIZE_ (src
);
157 /* If num is 1, we could speed things up with a binary search
158 of the word of interest. */
160 if (rbitno
>= n_bits
)
165 bitno
= n_bits
- (rbitno
+ 1);
167 windex
= bitno
/ BITSET_WORD_BITS
;
168 bitcnt
= bitno
% BITSET_WORD_BITS
;
169 bitoff
= windex
* BITSET_WORD_BITS
;
175 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
176 for (; word
; bitcnt
--)
178 if (word
& BITSET_MSB
)
180 list
[count
++] = bitoff
+ bitcnt
;
183 *next
= n_bits
- (bitoff
+ bitcnt
);
189 bitoff
-= BITSET_WORD_BITS
;
190 bitcnt
= BITSET_WORD_BITS
- 1;
194 *next
= n_bits
- (bitoff
+ 1);
199 /* Find list of up to NUM bits set in BSET starting from and including
200 *NEXT and store in array LIST. Return with actual number of bits
201 found and with *NEXT indicating where search stopped. */
203 abitset_list (bitset src
, bitset_bindex
*list
,
204 bitset_bindex num
, bitset_bindex
*next
)
208 bitset_windex windex
;
209 bitset_bindex bitoff
;
210 bitset_windex size
= src
->b
.csize
;
211 bitset_word
*srcp
= ABITSET_WORDS (src
);
219 /* Many bitsets are zero, so make this common case fast. */
220 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
225 /* If num is 1, we could speed things up with a binary search
226 of the current word. */
228 bitoff
= windex
* BITSET_WORD_BITS
;
232 if (bitno
>= BITSET_SIZE_ (src
))
235 windex
= bitno
/ BITSET_WORD_BITS
;
236 bitno
= bitno
% BITSET_WORD_BITS
;
240 /* Handle the case where we start within a word.
241 Most often, this is executed with large bitsets
242 with many set bits where we filled the array
243 on the previous call to this function. */
245 bitoff
= windex
* BITSET_WORD_BITS
;
246 word
= srcp
[windex
] >> bitno
;
247 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
251 list
[count
++] = bitno
;
262 bitoff
= windex
* BITSET_WORD_BITS
;
265 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
267 if (!(word
= srcp
[windex
]))
270 if ((count
+ BITSET_WORD_BITS
) < num
)
272 for (bitno
= bitoff
; word
; bitno
++)
275 list
[count
++] = bitno
;
281 for (bitno
= bitoff
; word
; bitno
++)
285 list
[count
++] = bitno
;
302 /* Ensure that any unused bits within the last word are clear. */
304 abitset_unused_clear (bitset dst
)
306 unsigned int last_bit
;
308 last_bit
= BITSET_SIZE_ (dst
) % BITSET_WORD_BITS
;
310 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
311 ((bitset_word
) 1 << last_bit
) - 1;
316 abitset_ones (bitset dst
)
318 bitset_word
*dstp
= ABITSET_WORDS (dst
);
321 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
323 memset (dstp
, -1, bytes
);
324 abitset_unused_clear (dst
);
329 abitset_zero (bitset dst
)
331 bitset_word
*dstp
= ABITSET_WORDS (dst
);
334 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
336 memset (dstp
, 0, bytes
);
341 abitset_empty_p (bitset dst
)
344 bitset_word
*dstp
= ABITSET_WORDS (dst
);
346 for (i
= 0; i
< dst
->b
.csize
; i
++)
355 abitset_copy1 (bitset dst
, bitset src
)
357 bitset_word
*srcp
= ABITSET_WORDS (src
);
358 bitset_word
*dstp
= ABITSET_WORDS (dst
);
359 bitset_windex size
= dst
->b
.csize
;
363 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
368 abitset_not (bitset dst
, bitset src
)
371 bitset_word
*srcp
= ABITSET_WORDS (src
);
372 bitset_word
*dstp
= ABITSET_WORDS (dst
);
373 bitset_windex size
= dst
->b
.csize
;
375 for (i
= 0; i
< size
; i
++)
376 *dstp
++ = ~(*srcp
++);
377 abitset_unused_clear (dst
);
382 abitset_equal_p (bitset dst
, bitset src
)
385 bitset_word
*srcp
= ABITSET_WORDS (src
);
386 bitset_word
*dstp
= ABITSET_WORDS (dst
);
387 bitset_windex size
= dst
->b
.csize
;
389 for (i
= 0; i
< size
; i
++)
390 if (*srcp
++ != *dstp
++)
397 abitset_subset_p (bitset dst
, bitset src
)
400 bitset_word
*srcp
= ABITSET_WORDS (src
);
401 bitset_word
*dstp
= ABITSET_WORDS (dst
);
402 bitset_windex size
= dst
->b
.csize
;
404 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
405 if (*dstp
!= (*srcp
| *dstp
))
412 abitset_disjoint_p (bitset dst
, bitset src
)
415 bitset_word
*srcp
= ABITSET_WORDS (src
);
416 bitset_word
*dstp
= ABITSET_WORDS (dst
);
417 bitset_windex size
= dst
->b
.csize
;
419 for (i
= 0; i
< size
; i
++)
420 if (*srcp
++ & *dstp
++)
428 abitset_and (bitset dst
, bitset src1
, bitset src2
)
431 bitset_word
*src1p
= ABITSET_WORDS (src1
);
432 bitset_word
*src2p
= ABITSET_WORDS (src2
);
433 bitset_word
*dstp
= ABITSET_WORDS (dst
);
434 bitset_windex size
= dst
->b
.csize
;
436 for (i
= 0; i
< size
; i
++)
437 *dstp
++ = *src1p
++ & *src2p
++;
442 abitset_and_cmp (bitset dst
, bitset src1
, bitset src2
)
445 bool changed
= false;
446 bitset_word
*src1p
= ABITSET_WORDS (src1
);
447 bitset_word
*src2p
= ABITSET_WORDS (src2
);
448 bitset_word
*dstp
= ABITSET_WORDS (dst
);
449 bitset_windex size
= dst
->b
.csize
;
451 for (i
= 0; i
< size
; i
++, dstp
++)
453 bitset_word tmp
= *src1p
++ & *src2p
++;
466 abitset_andn (bitset dst
, bitset src1
, bitset src2
)
469 bitset_word
*src1p
= ABITSET_WORDS (src1
);
470 bitset_word
*src2p
= ABITSET_WORDS (src2
);
471 bitset_word
*dstp
= ABITSET_WORDS (dst
);
472 bitset_windex size
= dst
->b
.csize
;
474 for (i
= 0; i
< size
; i
++)
475 *dstp
++ = *src1p
++ & ~(*src2p
++);
480 abitset_andn_cmp (bitset dst
, bitset src1
, bitset src2
)
483 bool changed
= false;
484 bitset_word
*src1p
= ABITSET_WORDS (src1
);
485 bitset_word
*src2p
= ABITSET_WORDS (src2
);
486 bitset_word
*dstp
= ABITSET_WORDS (dst
);
487 bitset_windex size
= dst
->b
.csize
;
489 for (i
= 0; i
< size
; i
++, dstp
++)
491 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
504 abitset_or (bitset dst
, bitset src1
, bitset src2
)
507 bitset_word
*src1p
= ABITSET_WORDS (src1
);
508 bitset_word
*src2p
= ABITSET_WORDS (src2
);
509 bitset_word
*dstp
= ABITSET_WORDS (dst
);
510 bitset_windex size
= dst
->b
.csize
;
512 for (i
= 0; i
< size
; i
++)
513 *dstp
++ = *src1p
++ | *src2p
++;
518 abitset_or_cmp (bitset dst
, bitset src1
, bitset src2
)
521 bool changed
= false;
522 bitset_word
*src1p
= ABITSET_WORDS (src1
);
523 bitset_word
*src2p
= ABITSET_WORDS (src2
);
524 bitset_word
*dstp
= ABITSET_WORDS (dst
);
525 bitset_windex size
= dst
->b
.csize
;
527 for (i
= 0; i
< size
; i
++, dstp
++)
529 bitset_word tmp
= *src1p
++ | *src2p
++;
542 abitset_xor (bitset dst
, bitset src1
, bitset src2
)
545 bitset_word
*src1p
= ABITSET_WORDS (src1
);
546 bitset_word
*src2p
= ABITSET_WORDS (src2
);
547 bitset_word
*dstp
= ABITSET_WORDS (dst
);
548 bitset_windex size
= dst
->b
.csize
;
550 for (i
= 0; i
< size
; i
++)
551 *dstp
++ = *src1p
++ ^ *src2p
++;
556 abitset_xor_cmp (bitset dst
, bitset src1
, bitset src2
)
559 bool changed
= false;
560 bitset_word
*src1p
= ABITSET_WORDS (src1
);
561 bitset_word
*src2p
= ABITSET_WORDS (src2
);
562 bitset_word
*dstp
= ABITSET_WORDS (dst
);
563 bitset_windex size
= dst
->b
.csize
;
565 for (i
= 0; i
< size
; i
++, dstp
++)
567 bitset_word tmp
= *src1p
++ ^ *src2p
++;
580 abitset_and_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
583 bitset_word
*src1p
= ABITSET_WORDS (src1
);
584 bitset_word
*src2p
= ABITSET_WORDS (src2
);
585 bitset_word
*src3p
= ABITSET_WORDS (src3
);
586 bitset_word
*dstp
= ABITSET_WORDS (dst
);
587 bitset_windex size
= dst
->b
.csize
;
589 for (i
= 0; i
< size
; i
++)
590 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
595 abitset_and_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
598 bool changed
= false;
599 bitset_word
*src1p
= ABITSET_WORDS (src1
);
600 bitset_word
*src2p
= ABITSET_WORDS (src2
);
601 bitset_word
*src3p
= ABITSET_WORDS (src3
);
602 bitset_word
*dstp
= ABITSET_WORDS (dst
);
603 bitset_windex size
= dst
->b
.csize
;
605 for (i
= 0; i
< size
; i
++, dstp
++)
607 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
620 abitset_andn_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
623 bitset_word
*src1p
= ABITSET_WORDS (src1
);
624 bitset_word
*src2p
= ABITSET_WORDS (src2
);
625 bitset_word
*src3p
= ABITSET_WORDS (src3
);
626 bitset_word
*dstp
= ABITSET_WORDS (dst
);
627 bitset_windex size
= dst
->b
.csize
;
629 for (i
= 0; i
< size
; i
++)
630 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
635 abitset_andn_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
638 bool changed
= false;
639 bitset_word
*src1p
= ABITSET_WORDS (src1
);
640 bitset_word
*src2p
= ABITSET_WORDS (src2
);
641 bitset_word
*src3p
= ABITSET_WORDS (src3
);
642 bitset_word
*dstp
= ABITSET_WORDS (dst
);
643 bitset_windex size
= dst
->b
.csize
;
645 for (i
= 0; i
< size
; i
++, dstp
++)
647 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
660 abitset_or_and (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
663 bitset_word
*src1p
= ABITSET_WORDS (src1
);
664 bitset_word
*src2p
= ABITSET_WORDS (src2
);
665 bitset_word
*src3p
= ABITSET_WORDS (src3
);
666 bitset_word
*dstp
= ABITSET_WORDS (dst
);
667 bitset_windex size
= dst
->b
.csize
;
669 for (i
= 0; i
< size
; i
++)
670 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
675 abitset_or_and_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
678 bool changed
= false;
679 bitset_word
*src1p
= ABITSET_WORDS (src1
);
680 bitset_word
*src2p
= ABITSET_WORDS (src2
);
681 bitset_word
*src3p
= ABITSET_WORDS (src3
);
682 bitset_word
*dstp
= ABITSET_WORDS (dst
);
683 bitset_windex size
= dst
->b
.csize
;
685 for (i
= 0; i
< size
; i
++, dstp
++)
687 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
700 abitset_copy (bitset dst
, bitset src
)
702 if (BITSET_COMPATIBLE_ (dst
, src
))
703 abitset_copy1 (dst
, src
);
705 bitset_copy_ (dst
, src
);
709 /* Vector of operations for single word bitsets. */
710 struct bitset_vtable abitset_small_vtable
= {
741 abitset_list_reverse
,
747 /* Vector of operations for multiple word bitsets. */
748 struct bitset_vtable abitset_vtable
= {
779 abitset_list_reverse
,
786 abitset_bytes (bitset_bindex n_bits
)
790 size_t header_size
= offsetof (union bitset_union
, a
.words
);
791 struct bitset_align_struct
{ char a
; union bitset_union b
; };
792 size_t bitset_alignment
= offsetof (struct bitset_align_struct
, b
);
794 size
= ABITSET_N_WORDS (n_bits
);
795 bytes
= header_size
+ size
* sizeof (bitset_word
);
797 /* Align the size properly for a vector of abitset objects. */
798 if (header_size
% bitset_alignment
!= 0
799 || sizeof (bitset_word
) % bitset_alignment
!= 0)
801 bytes
+= bitset_alignment
- 1;
802 bytes
-= bytes
% bitset_alignment
;
810 abitset_init (bitset bset
, bitset_bindex n_bits
)
814 size
= ABITSET_N_WORDS (n_bits
);
815 BITSET_NBITS_ (bset
) = n_bits
;
817 /* Use optimized routines if bitset fits within a single word.
818 There is probably little merit if using caching since
819 the small bitset will always fit in the cache. */
821 bset
->b
.vtable
= &abitset_small_vtable
;
823 bset
->b
.vtable
= &abitset_vtable
;
826 bset
->b
.csize
= size
;
827 bset
->b
.cdata
= ABITSET_WORDS (bset
);