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 bitset_bindex 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 bitset_bindex abitset_small_list
PARAMS ((bitset
, bitset_bindex
*,
51 static void abitset_set
PARAMS ((bitset
, bitset_bindex
));
52 static void abitset_reset
PARAMS ((bitset
, bitset_bindex
));
53 static int abitset_test
PARAMS ((bitset
, bitset_bindex
));
54 static bitset_bindex abitset_size
PARAMS ((bitset
));
55 static bitset_bindex abitset_list
PARAMS ((bitset
, bitset_bindex
*,
56 bitset_bindex
, bitset_bindex
*));
57 static bitset_bindex abitset_list_reverse
58 PARAMS ((bitset
, bitset_bindex
*, bitset_bindex
, bitset_bindex
*));
60 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
61 #define ABITSET_WORDS(X) ((X)->a.words)
62 #define ABITSET_N_BITS(X) ((X)->a.n_bits)
65 /* Return size in bits of bitset SRC. */
70 return ABITSET_N_BITS (src
);
74 /* Find list of up to NUM bits set in BSET starting from and including
75 *NEXT and store in array LIST. Return with actual number of bits
76 found and with *NEXT indicating where search stopped. */
78 abitset_small_list (src
, list
, num
, next
)
89 word
= ABITSET_WORDS (src
)[0];
91 /* Short circuit common case. */
95 size
= ABITSET_N_BITS (src
);
102 /* If num is 1, we could speed things up with a binary search
103 of the word of interest. */
105 if (num
>= BITSET_WORD_BITS
)
107 for (count
= 0; word
; bitno
++)
110 list
[count
++] = bitno
;
116 for (count
= 0; word
; bitno
++)
120 list
[count
++] = bitno
;
136 /* Set bit BITNO in bitset DST. */
138 abitset_set (dst
, bitno
)
139 bitset dst ATTRIBUTE_UNUSED
;
140 bitset_bindex bitno ATTRIBUTE_UNUSED
;
142 /* This should never occur for abitsets since we should always
148 /* Reset bit BITNO in bitset DST. */
150 abitset_reset (dst
, bitno
)
151 bitset dst ATTRIBUTE_UNUSED
;
152 bitset_bindex bitno ATTRIBUTE_UNUSED
;
154 /* This should never occur for abitsets since we should always
160 /* Test bit BITNO in bitset SRC. */
162 abitset_test (src
, bitno
)
163 bitset src ATTRIBUTE_UNUSED
;
164 bitset_bindex bitno ATTRIBUTE_UNUSED
;
166 /* This should never occur for abitsets since we should always
173 /* Find list of up to NUM bits set in BSET in reverse order, starting
174 from and including NEXT and store in array LIST. Return with
175 actual number of bits found and with *NEXT indicating where search
178 abitset_list_reverse (src
, list
, num
, next
)
185 bitset_bindex rbitno
;
187 bitset_windex windex
;
189 bitset_bindex bitoff
;
190 bitset_word
*srcp
= ABITSET_WORDS (src
);
191 bitset_bindex n_bits
= ABITSET_N_BITS (src
);
195 /* If num is 1, we could speed things up with a binary search
196 of the word of interest. */
198 if (rbitno
>= n_bits
)
203 bitno
= n_bits
- (rbitno
+ 1);
205 windex
= bitno
/ BITSET_WORD_BITS
;
206 bitcnt
= bitno
% BITSET_WORD_BITS
;
207 bitoff
= windex
* BITSET_WORD_BITS
;
213 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
214 for (; word
; bitcnt
--)
216 if (word
& BITSET_MSB
)
218 list
[count
++] = bitoff
+ bitcnt
;
221 *next
= n_bits
- (bitoff
+ bitcnt
);
227 bitoff
-= BITSET_WORD_BITS
;
228 bitcnt
= BITSET_WORD_BITS
- 1;
232 *next
= n_bits
- (bitoff
+ 1);
237 /* Find list of up to NUM bits set in BSET starting from and including
238 *NEXT and store in array LIST. Return with actual number of bits
239 found and with *NEXT indicating where search stopped. */
241 abitset_list (src
, list
, num
, next
)
249 bitset_windex windex
;
250 bitset_bindex bitoff
;
251 bitset_windex size
= src
->b
.csize
;
252 bitset_word
*srcp
= ABITSET_WORDS (src
);
260 /* Many bitsets are zero, so make this common case fast. */
261 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
266 /* If num is 1, we could speed things up with a binary search
267 of the current word. */
269 bitoff
= windex
* BITSET_WORD_BITS
;
273 if (bitno
>= ABITSET_N_BITS (src
))
276 windex
= bitno
/ BITSET_WORD_BITS
;
277 bitno
= bitno
% BITSET_WORD_BITS
;
281 /* Handle the case where we start within a word.
282 Most often, this is executed with large bitsets
283 with many set bits where we filled the array
284 on the previous call to this function. */
286 bitoff
= windex
* BITSET_WORD_BITS
;
287 word
= srcp
[windex
] >> bitno
;
288 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
292 list
[count
++] = bitno
;
303 bitoff
= windex
* BITSET_WORD_BITS
;
306 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
308 if (!(word
= srcp
[windex
]))
311 if ((count
+ BITSET_WORD_BITS
) < num
)
313 for (bitno
= bitoff
; word
; bitno
++)
316 list
[count
++] = bitno
;
322 for (bitno
= bitoff
; word
; bitno
++)
326 list
[count
++] = bitno
;
343 /* Ensure that any unused bits within the last word are clear. */
345 abitset_unused_clear (dst
)
348 unsigned int last_bit
;
350 last_bit
= ABITSET_N_BITS (dst
) % BITSET_WORD_BITS
;
352 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
353 ((bitset_word
) 1 << last_bit
) - 1;
361 bitset_word
*dstp
= ABITSET_WORDS (dst
);
364 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
366 memset (dstp
, -1, bytes
);
367 abitset_unused_clear (dst
);
375 bitset_word
*dstp
= ABITSET_WORDS (dst
);
378 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
380 memset (dstp
, 0, bytes
);
385 abitset_empty_p (dst
)
389 bitset_word
*dstp
= ABITSET_WORDS (dst
);
391 for (i
= 0; i
< dst
->b
.csize
; i
++)
400 abitset_copy1 (dst
, src
)
404 bitset_word
*srcp
= ABITSET_WORDS (src
);
405 bitset_word
*dstp
= ABITSET_WORDS (dst
);
406 bitset_windex size
= dst
->b
.csize
;
410 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
415 abitset_not (dst
, src
)
420 bitset_word
*srcp
= ABITSET_WORDS (src
);
421 bitset_word
*dstp
= ABITSET_WORDS (dst
);
422 bitset_windex size
= dst
->b
.csize
;
424 for (i
= 0; i
< size
; i
++)
425 *dstp
++ = ~(*srcp
++);
426 abitset_unused_clear (dst
);
431 abitset_equal_p (dst
, src
)
436 bitset_word
*srcp
= ABITSET_WORDS (src
);
437 bitset_word
*dstp
= ABITSET_WORDS (dst
);
438 bitset_windex size
= dst
->b
.csize
;
440 for (i
= 0; i
< size
; i
++)
441 if (*srcp
++ != *dstp
++)
448 abitset_subset_p (dst
, src
)
453 bitset_word
*srcp
= ABITSET_WORDS (src
);
454 bitset_word
*dstp
= ABITSET_WORDS (dst
);
455 bitset_windex size
= dst
->b
.csize
;
457 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
458 if (*dstp
!= (*srcp
| *dstp
))
465 abitset_disjoint_p (dst
, src
)
470 bitset_word
*srcp
= ABITSET_WORDS (src
);
471 bitset_word
*dstp
= ABITSET_WORDS (dst
);
472 bitset_windex size
= dst
->b
.csize
;
474 for (i
= 0; i
< size
; i
++)
475 if (*srcp
++ & *dstp
++)
483 abitset_and (dst
, src1
, src2
)
489 bitset_word
*src1p
= ABITSET_WORDS (src1
);
490 bitset_word
*src2p
= ABITSET_WORDS (src2
);
491 bitset_word
*dstp
= ABITSET_WORDS (dst
);
492 bitset_windex size
= dst
->b
.csize
;
494 for (i
= 0; i
< size
; i
++)
495 *dstp
++ = *src1p
++ & *src2p
++;
500 abitset_and_cmp (dst
, src1
, 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
++, dstp
++)
514 bitset_word tmp
= *src1p
++ & *src2p
++;
527 abitset_andn (dst
, src1
, src2
)
533 bitset_word
*src1p
= ABITSET_WORDS (src1
);
534 bitset_word
*src2p
= ABITSET_WORDS (src2
);
535 bitset_word
*dstp
= ABITSET_WORDS (dst
);
536 bitset_windex size
= dst
->b
.csize
;
538 for (i
= 0; i
< size
; i
++)
539 *dstp
++ = *src1p
++ & ~(*src2p
++);
544 abitset_andn_cmp (dst
, src1
, src2
)
551 bitset_word
*src1p
= ABITSET_WORDS (src1
);
552 bitset_word
*src2p
= ABITSET_WORDS (src2
);
553 bitset_word
*dstp
= ABITSET_WORDS (dst
);
554 bitset_windex size
= dst
->b
.csize
;
556 for (i
= 0; i
< size
; i
++, dstp
++)
558 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
571 abitset_or (dst
, src1
, src2
)
577 bitset_word
*src1p
= ABITSET_WORDS (src1
);
578 bitset_word
*src2p
= ABITSET_WORDS (src2
);
579 bitset_word
*dstp
= ABITSET_WORDS (dst
);
580 bitset_windex size
= dst
->b
.csize
;
582 for (i
= 0; i
< size
; i
++)
583 *dstp
++ = *src1p
++ | *src2p
++;
588 abitset_or_cmp (dst
, src1
, src2
)
595 bitset_word
*src1p
= ABITSET_WORDS (src1
);
596 bitset_word
*src2p
= ABITSET_WORDS (src2
);
597 bitset_word
*dstp
= ABITSET_WORDS (dst
);
598 bitset_windex size
= dst
->b
.csize
;
600 for (i
= 0; i
< size
; i
++, dstp
++)
602 bitset_word tmp
= *src1p
++ | *src2p
++;
615 abitset_xor (dst
, src1
, src2
)
621 bitset_word
*src1p
= ABITSET_WORDS (src1
);
622 bitset_word
*src2p
= ABITSET_WORDS (src2
);
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
++;
632 abitset_xor_cmp (dst
, src1
, src2
)
639 bitset_word
*src1p
= ABITSET_WORDS (src1
);
640 bitset_word
*src2p
= ABITSET_WORDS (src2
);
641 bitset_word
*dstp
= ABITSET_WORDS (dst
);
642 bitset_windex size
= dst
->b
.csize
;
644 for (i
= 0; i
< size
; i
++, dstp
++)
646 bitset_word tmp
= *src1p
++ ^ *src2p
++;
659 abitset_and_or (dst
, src1
, src2
, src3
)
666 bitset_word
*src1p
= ABITSET_WORDS (src1
);
667 bitset_word
*src2p
= ABITSET_WORDS (src2
);
668 bitset_word
*src3p
= ABITSET_WORDS (src3
);
669 bitset_word
*dstp
= ABITSET_WORDS (dst
);
670 bitset_windex size
= dst
->b
.csize
;
672 for (i
= 0; i
< size
; i
++)
673 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
678 abitset_and_or_cmp (dst
, src1
, src2
, src3
)
686 bitset_word
*src1p
= ABITSET_WORDS (src1
);
687 bitset_word
*src2p
= ABITSET_WORDS (src2
);
688 bitset_word
*src3p
= ABITSET_WORDS (src3
);
689 bitset_word
*dstp
= ABITSET_WORDS (dst
);
690 bitset_windex size
= dst
->b
.csize
;
692 for (i
= 0; i
< size
; i
++, dstp
++)
694 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
707 abitset_andn_or (dst
, src1
, src2
, src3
)
714 bitset_word
*src1p
= ABITSET_WORDS (src1
);
715 bitset_word
*src2p
= ABITSET_WORDS (src2
);
716 bitset_word
*src3p
= ABITSET_WORDS (src3
);
717 bitset_word
*dstp
= ABITSET_WORDS (dst
);
718 bitset_windex size
= dst
->b
.csize
;
720 for (i
= 0; i
< size
; i
++)
721 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
726 abitset_andn_or_cmp (dst
, src1
, src2
, src3
)
734 bitset_word
*src1p
= ABITSET_WORDS (src1
);
735 bitset_word
*src2p
= ABITSET_WORDS (src2
);
736 bitset_word
*src3p
= ABITSET_WORDS (src3
);
737 bitset_word
*dstp
= ABITSET_WORDS (dst
);
738 bitset_windex size
= dst
->b
.csize
;
740 for (i
= 0; i
< size
; i
++, dstp
++)
742 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
755 abitset_or_and (dst
, src1
, src2
, src3
)
762 bitset_word
*src1p
= ABITSET_WORDS (src1
);
763 bitset_word
*src2p
= ABITSET_WORDS (src2
);
764 bitset_word
*src3p
= ABITSET_WORDS (src3
);
765 bitset_word
*dstp
= ABITSET_WORDS (dst
);
766 bitset_windex size
= dst
->b
.csize
;
768 for (i
= 0; i
< size
; i
++)
769 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
774 abitset_or_and_cmp (dst
, src1
, src2
, src3
)
782 bitset_word
*src1p
= ABITSET_WORDS (src1
);
783 bitset_word
*src2p
= ABITSET_WORDS (src2
);
784 bitset_word
*src3p
= ABITSET_WORDS (src3
);
785 bitset_word
*dstp
= ABITSET_WORDS (dst
);
786 bitset_windex size
= dst
->b
.csize
;
788 for (i
= 0; i
< size
; i
++, dstp
++)
790 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
803 abitset_copy (dst
, src
)
807 if (BITSET_COMPATIBLE_ (dst
, src
))
808 abitset_copy1 (dst
, src
);
810 bitset_copy_ (dst
, src
);
814 /* Vector of operations for single word bitsets. */
815 struct bitset_vtable abitset_small_vtable
= {
845 abitset_list_reverse
,
851 /* Vector of operations for multiple word bitsets. */
852 struct bitset_vtable abitset_vtable
= {
882 abitset_list_reverse
,
889 abitset_bytes (n_bits
)
890 bitset_bindex n_bits
;
895 size
= ABITSET_N_WORDS (n_bits
);
896 bytes
= size
* sizeof (bitset_word
);
897 return sizeof (struct bitset_struct
) + bytes
- sizeof (bitset_word
);
902 abitset_init (bset
, n_bits
)
904 bitset_bindex n_bits
;
908 size
= ABITSET_N_WORDS (n_bits
);
909 ABITSET_N_BITS (bset
) = n_bits
;
911 /* Use optimized routines if bitset fits within a single word.
912 There is probably little merit if using caching since
913 the small bitset will always fit in the cache. */
915 bset
->b
.vtable
= &abitset_small_vtable
;
917 bset
->b
.vtable
= &abitset_vtable
;
920 bset
->b
.csize
= size
;
921 bset
->b
.cdata
= ABITSET_WORDS (bset
);