2 Copyright (C) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 /* This file implements fixed size bitsets stored as an array
29 of words. Any unused bits in the last word must be zero. */
31 typedef struct abitset_struct
33 unsigned int n_bits
; /* Number of bits. */
34 bitset_word words
[1]; /* The array of bits. */
41 struct bbitset_struct b
;
42 struct abitset_struct a
;
45 static void abitset_unused_clear
PARAMS ((bitset
));
47 static int abitset_small_list
PARAMS ((bitset
, bitset_bindex
*, bitset_bindex
,
50 static void abitset_set
PARAMS ((bitset
, bitset_bindex
));
51 static void abitset_reset
PARAMS ((bitset
, bitset_bindex
));
52 static int abitset_test
PARAMS ((bitset
, bitset_bindex
));
53 static int abitset_size
PARAMS ((bitset
));
54 static int abitset_list
PARAMS ((bitset
, bitset_bindex
*, bitset_bindex
,
56 static int abitset_list_reverse
57 PARAMS ((bitset
, bitset_bindex
*, bitset_bindex
, bitset_bindex
*));
59 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
60 #define ABITSET_WORDS(X) ((X)->a.words)
61 #define ABITSET_N_BITS(X) ((X)->a.n_bits)
64 /* Return size in bits of bitset SRC. */
69 return ABITSET_N_BITS (src
);
73 /* Find list of up to NUM bits set in BSET starting from and including
74 *NEXT and store in array LIST. Return with actual number of bits
75 found and with *NEXT indicating where search stopped. */
77 abitset_small_list (src
, list
, num
, next
)
88 word
= ABITSET_WORDS (src
)[0];
90 /* Short circuit common case. */
94 size
= ABITSET_N_BITS (src
);
101 /* If num is 1, we could speed things up with a binary search
102 of the word of interest. */
104 if (num
>= BITSET_WORD_BITS
)
106 for (count
= 0; word
; bitno
++)
109 list
[count
++] = bitno
;
115 for (count
= 0; word
; bitno
++)
119 list
[count
++] = bitno
;
135 /* Set bit BITNO in bitset DST. */
137 abitset_set (dst
, bitno
)
138 bitset dst ATTRIBUTE_UNUSED
;
139 bitset_bindex bitno ATTRIBUTE_UNUSED
;
141 /* This should never occur for abitsets since we should always
147 /* Reset bit BITNO in bitset DST. */
149 abitset_reset (dst
, bitno
)
150 bitset dst ATTRIBUTE_UNUSED
;
151 bitset_bindex bitno ATTRIBUTE_UNUSED
;
153 /* This should never occur for abitsets since we should always
159 /* Test bit BITNO in bitset SRC. */
161 abitset_test (src
, bitno
)
162 bitset src ATTRIBUTE_UNUSED
;
163 bitset_bindex bitno ATTRIBUTE_UNUSED
;
165 /* This should never occur for abitsets since we should always
172 /* Find list of up to NUM bits set in BSET in reverse order, starting
173 from and including NEXT and store in array LIST. Return with
174 actual number of bits found and with *NEXT indicating where search
177 abitset_list_reverse (src
, list
, num
, next
)
184 bitset_bindex rbitno
;
186 bitset_windex windex
;
188 bitset_bindex bitoff
;
189 bitset_word
*srcp
= ABITSET_WORDS (src
);
190 bitset_bindex n_bits
= ABITSET_N_BITS (src
);
194 /* If num is 1, we could speed things up with a binary search
195 of the word of interest. */
197 if (rbitno
>= n_bits
)
202 bitno
= n_bits
- (rbitno
+ 1);
204 windex
= bitno
/ BITSET_WORD_BITS
;
205 bitcnt
= bitno
% BITSET_WORD_BITS
;
206 bitoff
= windex
* BITSET_WORD_BITS
;
212 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
213 for (; word
; bitcnt
--)
215 if (word
& BITSET_MSB
)
217 list
[count
++] = bitoff
+ bitcnt
;
220 *next
= n_bits
- (bitoff
+ bitcnt
);
226 bitoff
-= BITSET_WORD_BITS
;
227 bitcnt
= BITSET_WORD_BITS
- 1;
231 *next
= n_bits
- (bitoff
+ 1);
236 /* Find list of up to NUM bits set in BSET starting from and including
237 *NEXT and store in array LIST. Return with actual number of bits
238 found and with *NEXT indicating where search stopped. */
240 abitset_list (src
, list
, num
, next
)
248 bitset_windex windex
;
249 bitset_bindex bitoff
;
250 bitset_windex size
= src
->b
.csize
;
251 bitset_word
*srcp
= ABITSET_WORDS (src
);
259 /* Many bitsets are zero, so make this common case fast. */
260 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
265 /* If num is 1, we could speed things up with a binary search
266 of the current word. */
268 bitoff
= windex
* BITSET_WORD_BITS
;
272 if (bitno
>= ABITSET_N_BITS (src
))
275 windex
= bitno
/ BITSET_WORD_BITS
;
276 bitno
= bitno
% BITSET_WORD_BITS
;
280 /* Handle the case where we start within a word.
281 Most often, this is executed with large bitsets
282 with many set bits where we filled the array
283 on the previous call to this function. */
285 bitoff
= windex
* BITSET_WORD_BITS
;
286 word
= srcp
[windex
] >> bitno
;
287 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
291 list
[count
++] = bitno
;
302 bitoff
= windex
* BITSET_WORD_BITS
;
305 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
307 if (!(word
= srcp
[windex
]))
310 if ((count
+ BITSET_WORD_BITS
) < num
)
312 for (bitno
= bitoff
; word
; bitno
++)
315 list
[count
++] = bitno
;
321 for (bitno
= bitoff
; word
; bitno
++)
325 list
[count
++] = bitno
;
342 /* Ensure that any unused bits within the last word are clear. */
344 abitset_unused_clear (dst
)
347 unsigned int last_bit
;
349 last_bit
= ABITSET_N_BITS (dst
) % BITSET_WORD_BITS
;
351 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
352 ((bitset_word
) 1 << last_bit
) - 1;
360 bitset_word
*dstp
= ABITSET_WORDS (dst
);
363 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
365 memset (dstp
, -1, bytes
);
366 abitset_unused_clear (dst
);
374 bitset_word
*dstp
= ABITSET_WORDS (dst
);
377 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
379 memset (dstp
, 0, bytes
);
384 abitset_empty_p (dst
)
388 bitset_word
*dstp
= ABITSET_WORDS (dst
);
390 for (i
= 0; i
< dst
->b
.csize
; i
++)
399 abitset_copy1 (dst
, src
)
403 bitset_word
*srcp
= ABITSET_WORDS (src
);
404 bitset_word
*dstp
= ABITSET_WORDS (dst
);
405 bitset_windex size
= dst
->b
.csize
;
409 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
414 abitset_not (dst
, src
)
419 bitset_word
*srcp
= ABITSET_WORDS (src
);
420 bitset_word
*dstp
= ABITSET_WORDS (dst
);
421 bitset_windex size
= dst
->b
.csize
;
423 for (i
= 0; i
< size
; i
++)
424 *dstp
++ = ~(*srcp
++);
425 abitset_unused_clear (dst
);
430 abitset_equal_p (dst
, src
)
435 bitset_word
*srcp
= ABITSET_WORDS (src
);
436 bitset_word
*dstp
= ABITSET_WORDS (dst
);
437 bitset_windex size
= dst
->b
.csize
;
439 for (i
= 0; i
< size
; i
++)
440 if (*srcp
++ != *dstp
++)
447 abitset_subset_p (dst
, src
)
452 bitset_word
*srcp
= ABITSET_WORDS (src
);
453 bitset_word
*dstp
= ABITSET_WORDS (dst
);
454 bitset_windex size
= dst
->b
.csize
;
456 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
457 if (*dstp
!= (*srcp
| *dstp
))
464 abitset_disjoint_p (dst
, src
)
469 bitset_word
*srcp
= ABITSET_WORDS (src
);
470 bitset_word
*dstp
= ABITSET_WORDS (dst
);
471 bitset_windex size
= dst
->b
.csize
;
473 for (i
= 0; i
< size
; i
++)
474 if (*srcp
++ & *dstp
++)
482 abitset_and (dst
, src1
, src2
)
488 bitset_word
*src1p
= ABITSET_WORDS (src1
);
489 bitset_word
*src2p
= ABITSET_WORDS (src2
);
490 bitset_word
*dstp
= ABITSET_WORDS (dst
);
491 bitset_windex size
= dst
->b
.csize
;
493 for (i
= 0; i
< size
; i
++)
494 *dstp
++ = *src1p
++ & *src2p
++;
499 abitset_and_cmp (dst
, src1
, src2
)
506 bitset_word
*src1p
= ABITSET_WORDS (src1
);
507 bitset_word
*src2p
= ABITSET_WORDS (src2
);
508 bitset_word
*dstp
= ABITSET_WORDS (dst
);
509 bitset_windex size
= dst
->b
.csize
;
511 for (i
= 0; i
< size
; i
++, dstp
++)
513 bitset_word tmp
= *src1p
++ & *src2p
++;
526 abitset_andn (dst
, src1
, src2
)
532 bitset_word
*src1p
= ABITSET_WORDS (src1
);
533 bitset_word
*src2p
= ABITSET_WORDS (src2
);
534 bitset_word
*dstp
= ABITSET_WORDS (dst
);
535 bitset_windex size
= dst
->b
.csize
;
537 for (i
= 0; i
< size
; i
++)
538 *dstp
++ = *src1p
++ & ~(*src2p
++);
543 abitset_andn_cmp (dst
, src1
, src2
)
550 bitset_word
*src1p
= ABITSET_WORDS (src1
);
551 bitset_word
*src2p
= ABITSET_WORDS (src2
);
552 bitset_word
*dstp
= ABITSET_WORDS (dst
);
553 bitset_windex size
= dst
->b
.csize
;
555 for (i
= 0; i
< size
; i
++, dstp
++)
557 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
570 abitset_or (dst
, src1
, src2
)
576 bitset_word
*src1p
= ABITSET_WORDS (src1
);
577 bitset_word
*src2p
= ABITSET_WORDS (src2
);
578 bitset_word
*dstp
= ABITSET_WORDS (dst
);
579 bitset_windex size
= dst
->b
.csize
;
581 for (i
= 0; i
< size
; i
++)
582 *dstp
++ = *src1p
++ | *src2p
++;
587 abitset_or_cmp (dst
, src1
, src2
)
594 bitset_word
*src1p
= ABITSET_WORDS (src1
);
595 bitset_word
*src2p
= ABITSET_WORDS (src2
);
596 bitset_word
*dstp
= ABITSET_WORDS (dst
);
597 bitset_windex size
= dst
->b
.csize
;
599 for (i
= 0; i
< size
; i
++, dstp
++)
601 bitset_word tmp
= *src1p
++ | *src2p
++;
614 abitset_xor (dst
, src1
, src2
)
620 bitset_word
*src1p
= ABITSET_WORDS (src1
);
621 bitset_word
*src2p
= ABITSET_WORDS (src2
);
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
++;
631 abitset_xor_cmp (dst
, src1
, src2
)
638 bitset_word
*src1p
= ABITSET_WORDS (src1
);
639 bitset_word
*src2p
= ABITSET_WORDS (src2
);
640 bitset_word
*dstp
= ABITSET_WORDS (dst
);
641 bitset_windex size
= dst
->b
.csize
;
643 for (i
= 0; i
< size
; i
++, dstp
++)
645 bitset_word tmp
= *src1p
++ ^ *src2p
++;
658 abitset_and_or (dst
, src1
, src2
, src3
)
665 bitset_word
*src1p
= ABITSET_WORDS (src1
);
666 bitset_word
*src2p
= ABITSET_WORDS (src2
);
667 bitset_word
*src3p
= ABITSET_WORDS (src3
);
668 bitset_word
*dstp
= ABITSET_WORDS (dst
);
669 bitset_windex size
= dst
->b
.csize
;
671 for (i
= 0; i
< size
; i
++)
672 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
677 abitset_and_or_cmp (dst
, src1
, src2
, src3
)
685 bitset_word
*src1p
= ABITSET_WORDS (src1
);
686 bitset_word
*src2p
= ABITSET_WORDS (src2
);
687 bitset_word
*src3p
= ABITSET_WORDS (src3
);
688 bitset_word
*dstp
= ABITSET_WORDS (dst
);
689 bitset_windex size
= dst
->b
.csize
;
691 for (i
= 0; i
< size
; i
++, dstp
++)
693 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
706 abitset_andn_or (dst
, src1
, src2
, src3
)
713 bitset_word
*src1p
= ABITSET_WORDS (src1
);
714 bitset_word
*src2p
= ABITSET_WORDS (src2
);
715 bitset_word
*src3p
= ABITSET_WORDS (src3
);
716 bitset_word
*dstp
= ABITSET_WORDS (dst
);
717 bitset_windex size
= dst
->b
.csize
;
719 for (i
= 0; i
< size
; i
++)
720 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
725 abitset_andn_or_cmp (dst
, src1
, src2
, src3
)
733 bitset_word
*src1p
= ABITSET_WORDS (src1
);
734 bitset_word
*src2p
= ABITSET_WORDS (src2
);
735 bitset_word
*src3p
= ABITSET_WORDS (src3
);
736 bitset_word
*dstp
= ABITSET_WORDS (dst
);
737 bitset_windex size
= dst
->b
.csize
;
739 for (i
= 0; i
< size
; i
++, dstp
++)
741 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
754 abitset_or_and (dst
, src1
, src2
, src3
)
761 bitset_word
*src1p
= ABITSET_WORDS (src1
);
762 bitset_word
*src2p
= ABITSET_WORDS (src2
);
763 bitset_word
*src3p
= ABITSET_WORDS (src3
);
764 bitset_word
*dstp
= ABITSET_WORDS (dst
);
765 bitset_windex size
= dst
->b
.csize
;
767 for (i
= 0; i
< size
; i
++)
768 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
773 abitset_or_and_cmp (dst
, src1
, src2
, src3
)
781 bitset_word
*src1p
= ABITSET_WORDS (src1
);
782 bitset_word
*src2p
= ABITSET_WORDS (src2
);
783 bitset_word
*src3p
= ABITSET_WORDS (src3
);
784 bitset_word
*dstp
= ABITSET_WORDS (dst
);
785 bitset_windex size
= dst
->b
.csize
;
787 for (i
= 0; i
< size
; i
++, dstp
++)
789 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
802 abitset_copy (dst
, src
)
806 if (BITSET_COMPATIBLE_ (dst
, src
))
807 abitset_copy1 (dst
, src
);
809 bitset_copy_ (dst
, src
);
813 /* Vector of operations for single word bitsets. */
814 struct bitset_vtable abitset_small_vtable
= {
844 abitset_list_reverse
,
850 /* Vector of operations for multiple word bitsets. */
851 struct bitset_vtable abitset_vtable
= {
881 abitset_list_reverse
,
888 abitset_bytes (n_bits
)
889 bitset_bindex n_bits
;
891 unsigned int bytes
, size
;
893 size
= ABITSET_N_WORDS (n_bits
);
894 bytes
= size
* sizeof (bitset_word
);
895 return sizeof (struct bitset_struct
) + bytes
- sizeof (bitset_word
);
900 abitset_init (bset
, n_bits
)
902 bitset_bindex n_bits
;
906 size
= ABITSET_N_WORDS (n_bits
);
907 ABITSET_N_BITS (bset
) = n_bits
;
909 /* Use optimized routines if bitset fits within a single word.
910 There is probably little merit if using caching since
911 the small bitset will always fit in the cache. */
913 bset
->b
.vtable
= &abitset_small_vtable
;
915 bset
->b
.vtable
= &abitset_vtable
;
918 bset
->b
.csize
= size
;
919 bset
->b
.cdata
= ABITSET_WORDS (bset
);