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.
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 static void abitset_unused_clear
PARAMS ((bitset
));
33 static void abitset_ones
PARAMS ((bitset
));
34 static void abitset_zero
PARAMS ((bitset
));
35 static int abitset_empty_p
PARAMS ((bitset
));
36 static void abitset_copy1
PARAMS ((bitset
, bitset
));
37 static void abitset_not
PARAMS ((bitset
, bitset
));
38 static int abitset_equal_p
PARAMS ((bitset
, bitset
));
39 static int abitset_subset_p
PARAMS ((bitset
, bitset
));
40 static int abitset_disjoint_p
PARAMS ((bitset
, bitset
));
41 static void abitset_and
PARAMS ((bitset
, bitset
, bitset
));
42 static int abitset_and_cmp
PARAMS ((bitset
, bitset
, bitset
));
43 static void abitset_andn
PARAMS ((bitset
, bitset
, bitset
));
44 static int abitset_andn_cmp
PARAMS ((bitset
, bitset
, bitset
));
45 static void abitset_or
PARAMS ((bitset
, bitset
, bitset
));
46 static int abitset_or_cmp
PARAMS ((bitset
, bitset
, bitset
));
47 static void abitset_xor
PARAMS ((bitset
, bitset
, bitset
));
48 static int abitset_xor_cmp
PARAMS ((bitset
, bitset
, bitset
));
49 static void abitset_and_or
PARAMS ((bitset
, bitset
, bitset
, bitset
));
50 static int abitset_and_or_cmp
PARAMS ((bitset
, bitset
, bitset
, bitset
));
51 static void abitset_andn_or
PARAMS ((bitset
, bitset
, bitset
, bitset
));
52 static int abitset_andn_or_cmp
PARAMS ((bitset
, bitset
, bitset
, bitset
));
53 static void abitset_or_and
PARAMS ((bitset
, bitset
, bitset
, bitset
));
54 static int abitset_or_and_cmp
PARAMS ((bitset
, bitset
, bitset
, bitset
));
55 static void abitset_copy
PARAMS ((bitset
, bitset
));
57 static bitset_bindex abitset_small_list
PARAMS ((bitset
, bitset_bindex
*,
61 static void abitset_set
PARAMS ((bitset
, bitset_bindex
));
62 static void abitset_reset
PARAMS ((bitset
, bitset_bindex
));
63 static int abitset_test
PARAMS ((bitset
, bitset_bindex
));
64 static bitset_bindex abitset_size
PARAMS ((bitset
));
65 static bitset_bindex abitset_list
PARAMS ((bitset
, bitset_bindex
*,
66 bitset_bindex
, bitset_bindex
*));
67 static bitset_bindex abitset_list_reverse
68 PARAMS ((bitset
, bitset_bindex
*, bitset_bindex
, bitset_bindex
*));
70 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
71 #define ABITSET_WORDS(X) ((X)->a.words)
72 #define ABITSET_N_BITS(X) ((X)->a.n_bits)
75 /* Return size in bits of bitset SRC. */
80 return ABITSET_N_BITS (src
);
84 /* Find list of up to NUM bits set in BSET starting from and including
85 *NEXT and store in array LIST. Return with actual number of bits
86 found and with *NEXT indicating where search stopped. */
88 abitset_small_list (src
, list
, num
, next
)
99 word
= ABITSET_WORDS (src
)[0];
101 /* Short circuit common case. */
105 size
= ABITSET_N_BITS (src
);
112 /* If num is 1, we could speed things up with a binary search
113 of the word of interest. */
115 if (num
>= BITSET_WORD_BITS
)
117 for (count
= 0; word
; bitno
++)
120 list
[count
++] = bitno
;
126 for (count
= 0; word
; bitno
++)
130 list
[count
++] = bitno
;
146 /* Set bit BITNO in bitset DST. */
148 abitset_set (dst
, bitno
)
149 bitset dst ATTRIBUTE_UNUSED
;
150 bitset_bindex bitno ATTRIBUTE_UNUSED
;
152 /* This should never occur for abitsets since we should always
158 /* Reset bit BITNO in bitset DST. */
160 abitset_reset (dst
, bitno
)
161 bitset dst ATTRIBUTE_UNUSED
;
162 bitset_bindex bitno ATTRIBUTE_UNUSED
;
164 /* This should never occur for abitsets since we should always
170 /* Test bit BITNO in bitset SRC. */
172 abitset_test (src
, bitno
)
173 bitset src ATTRIBUTE_UNUSED
;
174 bitset_bindex bitno ATTRIBUTE_UNUSED
;
176 /* This should never occur for abitsets since we should always
183 /* Find list of up to NUM bits set in BSET in reverse order, starting
184 from and including NEXT and store in array LIST. Return with
185 actual number of bits found and with *NEXT indicating where search
188 abitset_list_reverse (src
, list
, num
, next
)
195 bitset_bindex rbitno
;
197 bitset_windex windex
;
199 bitset_bindex bitoff
;
200 bitset_word
*srcp
= ABITSET_WORDS (src
);
201 bitset_bindex n_bits
= ABITSET_N_BITS (src
);
205 /* If num is 1, we could speed things up with a binary search
206 of the word of interest. */
208 if (rbitno
>= n_bits
)
213 bitno
= n_bits
- (rbitno
+ 1);
215 windex
= bitno
/ BITSET_WORD_BITS
;
216 bitcnt
= bitno
% BITSET_WORD_BITS
;
217 bitoff
= windex
* BITSET_WORD_BITS
;
223 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
224 for (; word
; bitcnt
--)
226 if (word
& BITSET_MSB
)
228 list
[count
++] = bitoff
+ bitcnt
;
231 *next
= n_bits
- (bitoff
+ bitcnt
);
237 bitoff
-= BITSET_WORD_BITS
;
238 bitcnt
= BITSET_WORD_BITS
- 1;
242 *next
= n_bits
- (bitoff
+ 1);
247 /* Find list of up to NUM bits set in BSET starting from and including
248 *NEXT and store in array LIST. Return with actual number of bits
249 found and with *NEXT indicating where search stopped. */
251 abitset_list (src
, list
, num
, next
)
259 bitset_windex windex
;
260 bitset_bindex bitoff
;
261 bitset_windex size
= src
->b
.csize
;
262 bitset_word
*srcp
= ABITSET_WORDS (src
);
270 /* Many bitsets are zero, so make this common case fast. */
271 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
276 /* If num is 1, we could speed things up with a binary search
277 of the current word. */
279 bitoff
= windex
* BITSET_WORD_BITS
;
283 if (bitno
>= ABITSET_N_BITS (src
))
286 windex
= bitno
/ BITSET_WORD_BITS
;
287 bitno
= bitno
% BITSET_WORD_BITS
;
291 /* Handle the case where we start within a word.
292 Most often, this is executed with large bitsets
293 with many set bits where we filled the array
294 on the previous call to this function. */
296 bitoff
= windex
* BITSET_WORD_BITS
;
297 word
= srcp
[windex
] >> bitno
;
298 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
302 list
[count
++] = bitno
;
313 bitoff
= windex
* BITSET_WORD_BITS
;
316 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
318 if (!(word
= srcp
[windex
]))
321 if ((count
+ BITSET_WORD_BITS
) < num
)
323 for (bitno
= bitoff
; word
; bitno
++)
326 list
[count
++] = bitno
;
332 for (bitno
= bitoff
; word
; bitno
++)
336 list
[count
++] = bitno
;
353 /* Ensure that any unused bits within the last word are clear. */
355 abitset_unused_clear (dst
)
358 unsigned int last_bit
;
360 last_bit
= ABITSET_N_BITS (dst
) % BITSET_WORD_BITS
;
362 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
363 ((bitset_word
) 1 << last_bit
) - 1;
371 bitset_word
*dstp
= ABITSET_WORDS (dst
);
374 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
376 memset (dstp
, -1, bytes
);
377 abitset_unused_clear (dst
);
385 bitset_word
*dstp
= ABITSET_WORDS (dst
);
388 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
390 memset (dstp
, 0, bytes
);
395 abitset_empty_p (dst
)
399 bitset_word
*dstp
= ABITSET_WORDS (dst
);
401 for (i
= 0; i
< dst
->b
.csize
; i
++)
410 abitset_copy1 (dst
, src
)
414 bitset_word
*srcp
= ABITSET_WORDS (src
);
415 bitset_word
*dstp
= ABITSET_WORDS (dst
);
416 bitset_windex size
= dst
->b
.csize
;
420 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
425 abitset_not (dst
, src
)
430 bitset_word
*srcp
= ABITSET_WORDS (src
);
431 bitset_word
*dstp
= ABITSET_WORDS (dst
);
432 bitset_windex size
= dst
->b
.csize
;
434 for (i
= 0; i
< size
; i
++)
435 *dstp
++ = ~(*srcp
++);
436 abitset_unused_clear (dst
);
441 abitset_equal_p (dst
, src
)
446 bitset_word
*srcp
= ABITSET_WORDS (src
);
447 bitset_word
*dstp
= ABITSET_WORDS (dst
);
448 bitset_windex size
= dst
->b
.csize
;
450 for (i
= 0; i
< size
; i
++)
451 if (*srcp
++ != *dstp
++)
458 abitset_subset_p (dst
, src
)
463 bitset_word
*srcp
= ABITSET_WORDS (src
);
464 bitset_word
*dstp
= ABITSET_WORDS (dst
);
465 bitset_windex size
= dst
->b
.csize
;
467 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
468 if (*dstp
!= (*srcp
| *dstp
))
475 abitset_disjoint_p (dst
, src
)
480 bitset_word
*srcp
= ABITSET_WORDS (src
);
481 bitset_word
*dstp
= ABITSET_WORDS (dst
);
482 bitset_windex size
= dst
->b
.csize
;
484 for (i
= 0; i
< size
; i
++)
485 if (*srcp
++ & *dstp
++)
493 abitset_and (dst
, src1
, src2
)
499 bitset_word
*src1p
= ABITSET_WORDS (src1
);
500 bitset_word
*src2p
= ABITSET_WORDS (src2
);
501 bitset_word
*dstp
= ABITSET_WORDS (dst
);
502 bitset_windex size
= dst
->b
.csize
;
504 for (i
= 0; i
< size
; i
++)
505 *dstp
++ = *src1p
++ & *src2p
++;
510 abitset_and_cmp (dst
, src1
, src2
)
517 bitset_word
*src1p
= ABITSET_WORDS (src1
);
518 bitset_word
*src2p
= ABITSET_WORDS (src2
);
519 bitset_word
*dstp
= ABITSET_WORDS (dst
);
520 bitset_windex size
= dst
->b
.csize
;
522 for (i
= 0; i
< size
; i
++, dstp
++)
524 bitset_word tmp
= *src1p
++ & *src2p
++;
537 abitset_andn (dst
, src1
, src2
)
543 bitset_word
*src1p
= ABITSET_WORDS (src1
);
544 bitset_word
*src2p
= ABITSET_WORDS (src2
);
545 bitset_word
*dstp
= ABITSET_WORDS (dst
);
546 bitset_windex size
= dst
->b
.csize
;
548 for (i
= 0; i
< size
; i
++)
549 *dstp
++ = *src1p
++ & ~(*src2p
++);
554 abitset_andn_cmp (dst
, src1
, src2
)
561 bitset_word
*src1p
= ABITSET_WORDS (src1
);
562 bitset_word
*src2p
= ABITSET_WORDS (src2
);
563 bitset_word
*dstp
= ABITSET_WORDS (dst
);
564 bitset_windex size
= dst
->b
.csize
;
566 for (i
= 0; i
< size
; i
++, dstp
++)
568 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
581 abitset_or (dst
, src1
, src2
)
587 bitset_word
*src1p
= ABITSET_WORDS (src1
);
588 bitset_word
*src2p
= ABITSET_WORDS (src2
);
589 bitset_word
*dstp
= ABITSET_WORDS (dst
);
590 bitset_windex size
= dst
->b
.csize
;
592 for (i
= 0; i
< size
; i
++)
593 *dstp
++ = *src1p
++ | *src2p
++;
598 abitset_or_cmp (dst
, src1
, src2
)
605 bitset_word
*src1p
= ABITSET_WORDS (src1
);
606 bitset_word
*src2p
= ABITSET_WORDS (src2
);
607 bitset_word
*dstp
= ABITSET_WORDS (dst
);
608 bitset_windex size
= dst
->b
.csize
;
610 for (i
= 0; i
< size
; i
++, dstp
++)
612 bitset_word tmp
= *src1p
++ | *src2p
++;
625 abitset_xor (dst
, src1
, src2
)
631 bitset_word
*src1p
= ABITSET_WORDS (src1
);
632 bitset_word
*src2p
= ABITSET_WORDS (src2
);
633 bitset_word
*dstp
= ABITSET_WORDS (dst
);
634 bitset_windex size
= dst
->b
.csize
;
636 for (i
= 0; i
< size
; i
++)
637 *dstp
++ = *src1p
++ ^ *src2p
++;
642 abitset_xor_cmp (dst
, src1
, src2
)
649 bitset_word
*src1p
= ABITSET_WORDS (src1
);
650 bitset_word
*src2p
= ABITSET_WORDS (src2
);
651 bitset_word
*dstp
= ABITSET_WORDS (dst
);
652 bitset_windex size
= dst
->b
.csize
;
654 for (i
= 0; i
< size
; i
++, dstp
++)
656 bitset_word tmp
= *src1p
++ ^ *src2p
++;
669 abitset_and_or (dst
, src1
, src2
, src3
)
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
++)
683 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
688 abitset_and_or_cmp (dst
, src1
, src2
, src3
)
696 bitset_word
*src1p
= ABITSET_WORDS (src1
);
697 bitset_word
*src2p
= ABITSET_WORDS (src2
);
698 bitset_word
*src3p
= ABITSET_WORDS (src3
);
699 bitset_word
*dstp
= ABITSET_WORDS (dst
);
700 bitset_windex size
= dst
->b
.csize
;
702 for (i
= 0; i
< size
; i
++, dstp
++)
704 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
717 abitset_andn_or (dst
, src1
, src2
, src3
)
724 bitset_word
*src1p
= ABITSET_WORDS (src1
);
725 bitset_word
*src2p
= ABITSET_WORDS (src2
);
726 bitset_word
*src3p
= ABITSET_WORDS (src3
);
727 bitset_word
*dstp
= ABITSET_WORDS (dst
);
728 bitset_windex size
= dst
->b
.csize
;
730 for (i
= 0; i
< size
; i
++)
731 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
736 abitset_andn_or_cmp (dst
, src1
, src2
, src3
)
744 bitset_word
*src1p
= ABITSET_WORDS (src1
);
745 bitset_word
*src2p
= ABITSET_WORDS (src2
);
746 bitset_word
*src3p
= ABITSET_WORDS (src3
);
747 bitset_word
*dstp
= ABITSET_WORDS (dst
);
748 bitset_windex size
= dst
->b
.csize
;
750 for (i
= 0; i
< size
; i
++, dstp
++)
752 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
765 abitset_or_and (dst
, src1
, src2
, src3
)
772 bitset_word
*src1p
= ABITSET_WORDS (src1
);
773 bitset_word
*src2p
= ABITSET_WORDS (src2
);
774 bitset_word
*src3p
= ABITSET_WORDS (src3
);
775 bitset_word
*dstp
= ABITSET_WORDS (dst
);
776 bitset_windex size
= dst
->b
.csize
;
778 for (i
= 0; i
< size
; i
++)
779 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
784 abitset_or_and_cmp (dst
, src1
, src2
, src3
)
792 bitset_word
*src1p
= ABITSET_WORDS (src1
);
793 bitset_word
*src2p
= ABITSET_WORDS (src2
);
794 bitset_word
*src3p
= ABITSET_WORDS (src3
);
795 bitset_word
*dstp
= ABITSET_WORDS (dst
);
796 bitset_windex size
= dst
->b
.csize
;
798 for (i
= 0; i
< size
; i
++, dstp
++)
800 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
813 abitset_copy (dst
, src
)
817 if (BITSET_COMPATIBLE_ (dst
, src
))
818 abitset_copy1 (dst
, src
);
820 bitset_copy_ (dst
, src
);
824 /* Vector of operations for single word bitsets. */
825 struct bitset_vtable abitset_small_vtable
= {
855 abitset_list_reverse
,
861 /* Vector of operations for multiple word bitsets. */
862 struct bitset_vtable abitset_vtable
= {
892 abitset_list_reverse
,
899 abitset_bytes (n_bits
)
900 bitset_bindex n_bits
;
904 size_t header_size
= offsetof (union bitset_union
, a
.words
);
905 struct bitset_align_struct
{ char a
; union bitset_union b
; };
906 size_t bitset_alignment
= offsetof (struct bitset_align_struct
, b
);
908 size
= ABITSET_N_WORDS (n_bits
);
909 bytes
= header_size
+ size
* sizeof (bitset_word
);
911 /* Align the size properly for a vector of abitset objects. */
912 if (header_size
% bitset_alignment
!= 0
913 || sizeof (bitset_word
) % bitset_alignment
!= 0)
915 bytes
+= bitset_alignment
- 1;
916 bytes
-= bytes
% bitset_alignment
;
924 abitset_init (bset
, n_bits
)
926 bitset_bindex n_bits
;
930 size
= ABITSET_N_WORDS (n_bits
);
931 ABITSET_N_BITS (bset
) = n_bits
;
933 /* Use optimized routines if bitset fits within a single word.
934 There is probably little merit if using caching since
935 the small bitset will always fit in the cache. */
937 bset
->b
.vtable
= &abitset_small_vtable
;
939 bset
->b
.vtable
= &abitset_vtable
;
942 bset
->b
.csize
= size
;
943 bset
->b
.cdata
= ABITSET_WORDS (bset
);