2 Copyright (C) 2002, 2003 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 #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 ATTRIBUTE_UNUSED
,
38 bitset_bindex size ATTRIBUTE_UNUSED
)
40 if (BITSET_SIZE_ (src
) == size
)
43 /* These bitsets have a fixed size. */
47 /* Find list of up to NUM bits set in BSET starting from and including
48 *NEXT and store in array LIST. Return with actual number of bits
49 found and with *NEXT indicating where search stopped. */
51 abitset_small_list (bitset src
, bitset_bindex
*list
,
52 bitset_bindex num
, bitset_bindex
*next
)
59 word
= ABITSET_WORDS (src
)[0];
61 /* Short circuit common case. */
65 size
= BITSET_SIZE_ (src
);
72 /* If num is 1, we could speed things up with a binary search
73 of the word of interest. */
75 if (num
>= BITSET_WORD_BITS
)
77 for (count
= 0; word
; bitno
++)
80 list
[count
++] = bitno
;
86 for (count
= 0; word
; bitno
++)
90 list
[count
++] = bitno
;
106 /* Set bit BITNO in bitset DST. */
108 abitset_set (bitset dst ATTRIBUTE_UNUSED
, bitset_bindex bitno ATTRIBUTE_UNUSED
)
110 /* This should never occur for abitsets since we should always hit
111 the cache. It is likely someone is trying to access outside the
112 bounds of the bitset. */
117 /* Reset bit BITNO in bitset DST. */
119 abitset_reset (bitset dst ATTRIBUTE_UNUSED
,
120 bitset_bindex bitno ATTRIBUTE_UNUSED
)
122 /* This should never occur for abitsets since we should always hit
123 the cache. It is likely someone is trying to access outside the
124 bounds of the bitset. Since the bit is zero anyway, let it pass. */
128 /* Test bit BITNO in bitset SRC. */
130 abitset_test (bitset src ATTRIBUTE_UNUSED
,
131 bitset_bindex bitno ATTRIBUTE_UNUSED
)
133 /* This should never occur for abitsets since we should always
139 /* Find list of up to NUM bits set in BSET in reverse order, starting
140 from and including NEXT and store in array LIST. Return with
141 actual number of bits found and with *NEXT indicating where search
144 abitset_list_reverse (bitset src
, bitset_bindex
*list
,
145 bitset_bindex num
, bitset_bindex
*next
)
148 bitset_bindex rbitno
;
150 bitset_windex windex
;
152 bitset_bindex bitoff
;
153 bitset_word
*srcp
= ABITSET_WORDS (src
);
154 bitset_bindex n_bits
= BITSET_SIZE_ (src
);
158 /* If num is 1, we could speed things up with a binary search
159 of the word of interest. */
161 if (rbitno
>= n_bits
)
166 bitno
= n_bits
- (rbitno
+ 1);
168 windex
= bitno
/ BITSET_WORD_BITS
;
169 bitcnt
= bitno
% BITSET_WORD_BITS
;
170 bitoff
= windex
* BITSET_WORD_BITS
;
176 word
= srcp
[windex
] << (BITSET_WORD_BITS
- 1 - bitcnt
);
177 for (; word
; bitcnt
--)
179 if (word
& BITSET_MSB
)
181 list
[count
++] = bitoff
+ bitcnt
;
184 *next
= n_bits
- (bitoff
+ bitcnt
);
190 bitoff
-= BITSET_WORD_BITS
;
191 bitcnt
= BITSET_WORD_BITS
- 1;
195 *next
= n_bits
- (bitoff
+ 1);
200 /* Find list of up to NUM bits set in BSET starting from and including
201 *NEXT and store in array LIST. Return with actual number of bits
202 found and with *NEXT indicating where search stopped. */
204 abitset_list (bitset src
, bitset_bindex
*list
,
205 bitset_bindex num
, bitset_bindex
*next
)
209 bitset_windex windex
;
210 bitset_bindex bitoff
;
211 bitset_windex size
= src
->b
.csize
;
212 bitset_word
*srcp
= ABITSET_WORDS (src
);
220 /* Many bitsets are zero, so make this common case fast. */
221 for (windex
= 0; windex
< size
&& !srcp
[windex
]; windex
++)
226 /* If num is 1, we could speed things up with a binary search
227 of the current word. */
229 bitoff
= windex
* BITSET_WORD_BITS
;
233 if (bitno
>= BITSET_SIZE_ (src
))
236 windex
= bitno
/ BITSET_WORD_BITS
;
237 bitno
= bitno
% BITSET_WORD_BITS
;
241 /* Handle the case where we start within a word.
242 Most often, this is executed with large bitsets
243 with many set bits where we filled the array
244 on the previous call to this function. */
246 bitoff
= windex
* BITSET_WORD_BITS
;
247 word
= srcp
[windex
] >> bitno
;
248 for (bitno
= bitoff
+ bitno
; word
; bitno
++)
252 list
[count
++] = bitno
;
263 bitoff
= windex
* BITSET_WORD_BITS
;
266 for (; windex
< size
; windex
++, bitoff
+= BITSET_WORD_BITS
)
268 if (!(word
= srcp
[windex
]))
271 if ((count
+ BITSET_WORD_BITS
) < num
)
273 for (bitno
= bitoff
; word
; bitno
++)
276 list
[count
++] = bitno
;
282 for (bitno
= bitoff
; word
; bitno
++)
286 list
[count
++] = bitno
;
303 /* Ensure that any unused bits within the last word are clear. */
305 abitset_unused_clear (bitset dst
)
307 unsigned int last_bit
;
309 last_bit
= BITSET_SIZE_ (dst
) % BITSET_WORD_BITS
;
311 ABITSET_WORDS (dst
)[dst
->b
.csize
- 1] &=
312 ((bitset_word
) 1 << last_bit
) - 1;
317 abitset_ones (bitset dst
)
319 bitset_word
*dstp
= ABITSET_WORDS (dst
);
322 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
324 memset (dstp
, -1, bytes
);
325 abitset_unused_clear (dst
);
330 abitset_zero (bitset dst
)
332 bitset_word
*dstp
= ABITSET_WORDS (dst
);
335 bytes
= sizeof (bitset_word
) * dst
->b
.csize
;
337 memset (dstp
, 0, bytes
);
342 abitset_empty_p (bitset dst
)
345 bitset_word
*dstp
= ABITSET_WORDS (dst
);
347 for (i
= 0; i
< dst
->b
.csize
; i
++)
356 abitset_copy1 (bitset dst
, bitset src
)
358 bitset_word
*srcp
= ABITSET_WORDS (src
);
359 bitset_word
*dstp
= ABITSET_WORDS (dst
);
360 bitset_windex size
= dst
->b
.csize
;
364 memcpy (dstp
, srcp
, sizeof (bitset_word
) * size
);
369 abitset_not (bitset dst
, bitset src
)
372 bitset_word
*srcp
= ABITSET_WORDS (src
);
373 bitset_word
*dstp
= ABITSET_WORDS (dst
);
374 bitset_windex size
= dst
->b
.csize
;
376 for (i
= 0; i
< size
; i
++)
377 *dstp
++ = ~(*srcp
++);
378 abitset_unused_clear (dst
);
383 abitset_equal_p (bitset dst
, bitset src
)
386 bitset_word
*srcp
= ABITSET_WORDS (src
);
387 bitset_word
*dstp
= ABITSET_WORDS (dst
);
388 bitset_windex size
= dst
->b
.csize
;
390 for (i
= 0; i
< size
; i
++)
391 if (*srcp
++ != *dstp
++)
398 abitset_subset_p (bitset dst
, bitset src
)
401 bitset_word
*srcp
= ABITSET_WORDS (src
);
402 bitset_word
*dstp
= ABITSET_WORDS (dst
);
403 bitset_windex size
= dst
->b
.csize
;
405 for (i
= 0; i
< size
; i
++, dstp
++, srcp
++)
406 if (*dstp
!= (*srcp
| *dstp
))
413 abitset_disjoint_p (bitset dst
, bitset src
)
416 bitset_word
*srcp
= ABITSET_WORDS (src
);
417 bitset_word
*dstp
= ABITSET_WORDS (dst
);
418 bitset_windex size
= dst
->b
.csize
;
420 for (i
= 0; i
< size
; i
++)
421 if (*srcp
++ & *dstp
++)
429 abitset_and (bitset dst
, bitset src1
, bitset src2
)
432 bitset_word
*src1p
= ABITSET_WORDS (src1
);
433 bitset_word
*src2p
= ABITSET_WORDS (src2
);
434 bitset_word
*dstp
= ABITSET_WORDS (dst
);
435 bitset_windex size
= dst
->b
.csize
;
437 for (i
= 0; i
< size
; i
++)
438 *dstp
++ = *src1p
++ & *src2p
++;
443 abitset_and_cmp (bitset dst
, bitset src1
, bitset src2
)
446 bool changed
= false;
447 bitset_word
*src1p
= ABITSET_WORDS (src1
);
448 bitset_word
*src2p
= ABITSET_WORDS (src2
);
449 bitset_word
*dstp
= ABITSET_WORDS (dst
);
450 bitset_windex size
= dst
->b
.csize
;
452 for (i
= 0; i
< size
; i
++, dstp
++)
454 bitset_word tmp
= *src1p
++ & *src2p
++;
467 abitset_andn (bitset dst
, bitset src1
, bitset src2
)
470 bitset_word
*src1p
= ABITSET_WORDS (src1
);
471 bitset_word
*src2p
= ABITSET_WORDS (src2
);
472 bitset_word
*dstp
= ABITSET_WORDS (dst
);
473 bitset_windex size
= dst
->b
.csize
;
475 for (i
= 0; i
< size
; i
++)
476 *dstp
++ = *src1p
++ & ~(*src2p
++);
481 abitset_andn_cmp (bitset dst
, bitset src1
, bitset src2
)
484 bool changed
= false;
485 bitset_word
*src1p
= ABITSET_WORDS (src1
);
486 bitset_word
*src2p
= ABITSET_WORDS (src2
);
487 bitset_word
*dstp
= ABITSET_WORDS (dst
);
488 bitset_windex size
= dst
->b
.csize
;
490 for (i
= 0; i
< size
; i
++, dstp
++)
492 bitset_word tmp
= *src1p
++ & ~(*src2p
++);
505 abitset_or (bitset dst
, bitset src1
, bitset src2
)
508 bitset_word
*src1p
= ABITSET_WORDS (src1
);
509 bitset_word
*src2p
= ABITSET_WORDS (src2
);
510 bitset_word
*dstp
= ABITSET_WORDS (dst
);
511 bitset_windex size
= dst
->b
.csize
;
513 for (i
= 0; i
< size
; i
++)
514 *dstp
++ = *src1p
++ | *src2p
++;
519 abitset_or_cmp (bitset dst
, bitset src1
, bitset src2
)
522 bool changed
= false;
523 bitset_word
*src1p
= ABITSET_WORDS (src1
);
524 bitset_word
*src2p
= ABITSET_WORDS (src2
);
525 bitset_word
*dstp
= ABITSET_WORDS (dst
);
526 bitset_windex size
= dst
->b
.csize
;
528 for (i
= 0; i
< size
; i
++, dstp
++)
530 bitset_word tmp
= *src1p
++ | *src2p
++;
543 abitset_xor (bitset dst
, bitset src1
, bitset src2
)
546 bitset_word
*src1p
= ABITSET_WORDS (src1
);
547 bitset_word
*src2p
= ABITSET_WORDS (src2
);
548 bitset_word
*dstp
= ABITSET_WORDS (dst
);
549 bitset_windex size
= dst
->b
.csize
;
551 for (i
= 0; i
< size
; i
++)
552 *dstp
++ = *src1p
++ ^ *src2p
++;
557 abitset_xor_cmp (bitset dst
, bitset src1
, bitset src2
)
560 bool changed
= false;
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_and_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
584 bitset_word
*src1p
= ABITSET_WORDS (src1
);
585 bitset_word
*src2p
= ABITSET_WORDS (src2
);
586 bitset_word
*src3p
= ABITSET_WORDS (src3
);
587 bitset_word
*dstp
= ABITSET_WORDS (dst
);
588 bitset_windex size
= dst
->b
.csize
;
590 for (i
= 0; i
< size
; i
++)
591 *dstp
++ = (*src1p
++ & *src2p
++) | *src3p
++;
596 abitset_and_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
599 bool changed
= false;
600 bitset_word
*src1p
= ABITSET_WORDS (src1
);
601 bitset_word
*src2p
= ABITSET_WORDS (src2
);
602 bitset_word
*src3p
= ABITSET_WORDS (src3
);
603 bitset_word
*dstp
= ABITSET_WORDS (dst
);
604 bitset_windex size
= dst
->b
.csize
;
606 for (i
= 0; i
< size
; i
++, dstp
++)
608 bitset_word tmp
= (*src1p
++ & *src2p
++) | *src3p
++;
621 abitset_andn_or (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
624 bitset_word
*src1p
= ABITSET_WORDS (src1
);
625 bitset_word
*src2p
= ABITSET_WORDS (src2
);
626 bitset_word
*src3p
= ABITSET_WORDS (src3
);
627 bitset_word
*dstp
= ABITSET_WORDS (dst
);
628 bitset_windex size
= dst
->b
.csize
;
630 for (i
= 0; i
< size
; i
++)
631 *dstp
++ = (*src1p
++ & ~(*src2p
++)) | *src3p
++;
636 abitset_andn_or_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
639 bool changed
= false;
640 bitset_word
*src1p
= ABITSET_WORDS (src1
);
641 bitset_word
*src2p
= ABITSET_WORDS (src2
);
642 bitset_word
*src3p
= ABITSET_WORDS (src3
);
643 bitset_word
*dstp
= ABITSET_WORDS (dst
);
644 bitset_windex size
= dst
->b
.csize
;
646 for (i
= 0; i
< size
; i
++, dstp
++)
648 bitset_word tmp
= (*src1p
++ & ~(*src2p
++)) | *src3p
++;
661 abitset_or_and (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
664 bitset_word
*src1p
= ABITSET_WORDS (src1
);
665 bitset_word
*src2p
= ABITSET_WORDS (src2
);
666 bitset_word
*src3p
= ABITSET_WORDS (src3
);
667 bitset_word
*dstp
= ABITSET_WORDS (dst
);
668 bitset_windex size
= dst
->b
.csize
;
670 for (i
= 0; i
< size
; i
++)
671 *dstp
++ = (*src1p
++ | *src2p
++) & *src3p
++;
676 abitset_or_and_cmp (bitset dst
, bitset src1
, bitset src2
, bitset src3
)
679 bool changed
= false;
680 bitset_word
*src1p
= ABITSET_WORDS (src1
);
681 bitset_word
*src2p
= ABITSET_WORDS (src2
);
682 bitset_word
*src3p
= ABITSET_WORDS (src3
);
683 bitset_word
*dstp
= ABITSET_WORDS (dst
);
684 bitset_windex size
= dst
->b
.csize
;
686 for (i
= 0; i
< size
; i
++, dstp
++)
688 bitset_word tmp
= (*src1p
++ | *src2p
++) & *src3p
++;
701 abitset_copy (bitset dst
, bitset src
)
703 if (BITSET_COMPATIBLE_ (dst
, src
))
704 abitset_copy1 (dst
, src
);
706 bitset_copy_ (dst
, src
);
710 /* Vector of operations for single word bitsets. */
711 struct bitset_vtable abitset_small_vtable
= {
742 abitset_list_reverse
,
748 /* Vector of operations for multiple word bitsets. */
749 struct bitset_vtable abitset_vtable
= {
780 abitset_list_reverse
,
787 abitset_bytes (bitset_bindex n_bits
)
791 size_t header_size
= offsetof (union bitset_union
, a
.words
);
792 struct bitset_align_struct
{ char a
; union bitset_union b
; };
793 size_t bitset_alignment
= offsetof (struct bitset_align_struct
, b
);
795 size
= ABITSET_N_WORDS (n_bits
);
796 bytes
= header_size
+ size
* sizeof (bitset_word
);
798 /* Align the size properly for a vector of abitset objects. */
799 if (header_size
% bitset_alignment
!= 0
800 || sizeof (bitset_word
) % bitset_alignment
!= 0)
802 bytes
+= bitset_alignment
- 1;
803 bytes
-= bytes
% bitset_alignment
;
811 abitset_init (bitset bset
, bitset_bindex n_bits
)
815 size
= ABITSET_N_WORDS (n_bits
);
816 BITSET_NBITS_ (bset
) = n_bits
;
818 /* Use optimized routines if bitset fits within a single word.
819 There is probably little merit if using caching since
820 the small bitset will always fit in the cache. */
822 bset
->b
.vtable
= &abitset_small_vtable
;
824 bset
->b
.vtable
= &abitset_vtable
;
827 bset
->b
.csize
= size
;
828 bset
->b
.cdata
= ABITSET_WORDS (bset
);