* data/c.m4 (b4_c_function_def): Look at __C99_FUNC__, not at
[bison.git] / lib / vbitset.c
bloba7d9bdec07c6013424eb384b6e539ef36ed7d60c
1 /* Variable array bitsets.
2 Copyright (C) 2002, 2003, 2004, 2005 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.
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "vbitset.h"
25 #include <stdlib.h>
26 #include <string.h>
28 /* This file implements variable size bitsets stored as a variable
29 length array of words. Any unused bits in the last word must be
30 zero.
32 Note that binary or ternary operations assume that each bitset operand
33 has the same size.
36 static void vbitset_unused_clear (bitset);
38 static void vbitset_set (bitset, bitset_bindex);
39 static void vbitset_reset (bitset, bitset_bindex);
40 static bool vbitset_test (bitset, bitset_bindex);
41 static bitset_bindex vbitset_list (bitset, bitset_bindex *,
42 bitset_bindex, bitset_bindex *);
43 static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
44 bitset_bindex, bitset_bindex *);
46 #define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
47 #define VBITSET_WORDS(X) ((X)->b.cdata)
48 #define VBITSET_SIZE(X) ((X)->b.csize)
49 #define VBITSET_ASIZE(X) ((X)->v.size)
51 #undef min
52 #undef max
53 #define min(a, b) ((a) > (b) ? (b) : (a))
54 #define max(a, b) ((a) > (b) ? (a) : (b))
56 static bitset_bindex
57 vbitset_resize (bitset src, bitset_bindex n_bits)
59 bitset_windex oldsize;
60 bitset_windex newsize;
62 if (n_bits == BITSET_NBITS_ (src))
63 return n_bits;
65 oldsize = VBITSET_SIZE (src);
66 newsize = VBITSET_N_WORDS (n_bits);
68 if (oldsize < newsize)
70 bitset_windex size;
72 /* The bitset needs to grow. If we already have enough memory
73 allocated, then just zero what we need. */
74 if (newsize > VBITSET_ASIZE (src))
76 /* We need to allocate more memory. When oldsize is
77 non-zero this means that we are changing the size, so
78 grow the bitset 25% larger than requested to reduce
79 number of reallocations. */
81 if (oldsize == 0)
82 size = newsize;
83 else
84 size = newsize + newsize / 4;
86 VBITSET_WORDS (src)
87 = realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
88 VBITSET_ASIZE (src) = size;
91 memset (VBITSET_WORDS (src) + oldsize, 0,
92 (newsize - oldsize) * sizeof (bitset_word));
93 VBITSET_SIZE (src) = newsize;
95 else
97 /* The bitset needs to shrink. There's no point deallocating
98 the memory unless it is shrinking by a reasonable amount. */
99 if ((oldsize - newsize) >= oldsize / 2)
101 VBITSET_WORDS (src)
102 = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
103 VBITSET_ASIZE (src) = newsize;
106 /* Need to prune any excess bits. FIXME. */
108 VBITSET_SIZE (src) = newsize;
111 BITSET_NBITS_ (src) = n_bits;
112 return n_bits;
116 /* Set bit BITNO in bitset DST. */
117 static void
118 vbitset_set (dst, bitno)
119 bitset dst;
120 bitset_bindex bitno;
122 bitset_windex windex = bitno / BITSET_WORD_BITS;
124 /* Perhaps we should abort. The user should explicitly call
125 bitset_resize since this will not catch the case when we set a
126 bit larger than the current size but smaller than the allocated
127 size. */
128 vbitset_resize (dst, bitno);
130 dst->b.cdata[windex - dst->b.cindex] |=
131 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
135 /* Reset bit BITNO in bitset DST. */
136 static void
137 vbitset_reset (dst, bitno)
138 bitset dst ATTRIBUTE_UNUSED;
139 bitset_bindex bitno ATTRIBUTE_UNUSED;
141 /* We must be accessing outside the cache so the bit is
142 zero anyway. */
146 /* Test bit BITNO in bitset SRC. */
147 static bool
148 vbitset_test (src, bitno)
149 bitset src ATTRIBUTE_UNUSED;
150 bitset_bindex bitno ATTRIBUTE_UNUSED;
152 /* We must be accessing outside the cache so the bit is
153 zero anyway. */
154 return 0;
158 /* Find list of up to NUM bits set in BSET in reverse order, starting
159 from and including NEXT and store in array LIST. Return with
160 actual number of bits found and with *NEXT indicating where search
161 stopped. */
162 static bitset_bindex
163 vbitset_list_reverse (src, list, num, next)
164 bitset src;
165 bitset_bindex *list;
166 bitset_bindex num;
167 bitset_bindex *next;
169 bitset_bindex bitno;
170 bitset_bindex rbitno;
171 bitset_bindex count;
172 bitset_windex windex;
173 unsigned int bitcnt;
174 bitset_bindex bitoff;
175 bitset_word *srcp = VBITSET_WORDS (src);
176 bitset_bindex n_bits = BITSET_SIZE_ (src);
178 rbitno = *next;
180 /* If num is 1, we could speed things up with a binary search
181 of the word of interest. */
183 if (rbitno >= n_bits)
184 return 0;
186 count = 0;
188 bitno = n_bits - (rbitno + 1);
190 windex = bitno / BITSET_WORD_BITS;
191 bitcnt = bitno % BITSET_WORD_BITS;
192 bitoff = windex * BITSET_WORD_BITS;
196 bitset_word word;
198 word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
199 for (; word; bitcnt--)
201 if (word & BITSET_MSB)
203 list[count++] = bitoff + bitcnt;
204 if (count >= num)
206 *next = n_bits - (bitoff + bitcnt);
207 return count;
210 word <<= 1;
212 bitoff -= BITSET_WORD_BITS;
213 bitcnt = BITSET_WORD_BITS - 1;
215 while (windex--);
217 *next = n_bits - (bitoff + 1);
218 return count;
222 /* Find list of up to NUM bits set in BSET starting from and including
223 *NEXT and store in array LIST. Return with actual number of bits
224 found and with *NEXT indicating where search stopped. */
225 static bitset_bindex
226 vbitset_list (src, list, num, next)
227 bitset src;
228 bitset_bindex *list;
229 bitset_bindex num;
230 bitset_bindex *next;
232 bitset_bindex bitno;
233 bitset_bindex count;
234 bitset_windex windex;
235 bitset_bindex bitoff;
236 bitset_windex size = VBITSET_SIZE (src);
237 bitset_word *srcp = VBITSET_WORDS (src);
238 bitset_word word;
240 bitno = *next;
242 count = 0;
243 if (!bitno)
245 /* Many bitsets are zero, so make this common case fast. */
246 for (windex = 0; windex < size && !srcp[windex]; windex++)
247 continue;
248 if (windex >= size)
249 return 0;
251 /* If num is 1, we could speed things up with a binary search
252 of the current word. */
254 bitoff = windex * BITSET_WORD_BITS;
256 else
258 if (bitno >= BITSET_SIZE_ (src))
259 return 0;
261 windex = bitno / BITSET_WORD_BITS;
262 bitno = bitno % BITSET_WORD_BITS;
264 if (bitno)
266 /* Handle the case where we start within a word.
267 Most often, this is executed with large bitsets
268 with many set bits where we filled the array
269 on the previous call to this function. */
271 bitoff = windex * BITSET_WORD_BITS;
272 word = srcp[windex] >> bitno;
273 for (bitno = bitoff + bitno; word; bitno++)
275 if (word & 1)
277 list[count++] = bitno;
278 if (count >= num)
280 *next = bitno + 1;
281 return count;
284 word >>= 1;
286 windex++;
288 bitoff = windex * BITSET_WORD_BITS;
291 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
293 if (!(word = srcp[windex]))
294 continue;
296 if ((count + BITSET_WORD_BITS) < num)
298 for (bitno = bitoff; word; bitno++)
300 if (word & 1)
301 list[count++] = bitno;
302 word >>= 1;
305 else
307 for (bitno = bitoff; word; bitno++)
309 if (word & 1)
311 list[count++] = bitno;
312 if (count >= num)
314 *next = bitno + 1;
315 return count;
318 word >>= 1;
323 *next = bitoff;
324 return count;
328 /* Ensure that any unused bits within the last word are clear. */
329 static inline void
330 vbitset_unused_clear (dst)
331 bitset dst;
333 unsigned int last_bit;
335 last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
336 if (last_bit)
337 VBITSET_WORDS (dst)[VBITSET_SIZE (dst) - 1] &=
338 ((bitset_word) 1 << last_bit) - 1;
342 static void
343 vbitset_ones (bitset dst)
345 bitset_word *dstp = VBITSET_WORDS (dst);
346 unsigned int bytes;
348 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
350 memset (dstp, -1, bytes);
351 vbitset_unused_clear (dst);
355 static void
356 vbitset_zero (bitset dst)
358 bitset_word *dstp = VBITSET_WORDS (dst);
359 unsigned int bytes;
361 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
363 memset (dstp, 0, bytes);
367 static bool
368 vbitset_empty_p (bitset dst)
370 unsigned int i;
371 bitset_word *dstp = VBITSET_WORDS (dst);
373 for (i = 0; i < VBITSET_SIZE (dst); i++)
374 if (dstp[i])
375 return 0;
377 return 1;
381 static void
382 vbitset_copy1 (bitset dst, bitset src)
384 bitset_word *srcp;
385 bitset_word *dstp;
386 bitset_windex ssize;
387 bitset_windex dsize;
389 if (src == dst)
390 return;
392 vbitset_resize (dst, BITSET_SIZE_ (src));
394 srcp = VBITSET_WORDS (src);
395 dstp = VBITSET_WORDS (dst);
396 ssize = VBITSET_SIZE (src);
397 dsize = VBITSET_SIZE (dst);
399 memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
401 memset (dstp + sizeof (bitset_word) * ssize, 0,
402 sizeof (bitset_word) * (dsize - ssize));
406 static void
407 vbitset_not (bitset dst, bitset src)
409 unsigned int i;
410 bitset_word *srcp;
411 bitset_word *dstp;
412 bitset_windex ssize;
413 bitset_windex dsize;
415 vbitset_resize (dst, BITSET_SIZE_ (src));
417 srcp = VBITSET_WORDS (src);
418 dstp = VBITSET_WORDS (dst);
419 ssize = VBITSET_SIZE (src);
420 dsize = VBITSET_SIZE (dst);
422 for (i = 0; i < ssize; i++)
423 *dstp++ = ~(*srcp++);
425 vbitset_unused_clear (dst);
426 memset (dstp + sizeof (bitset_word) * ssize, 0,
427 sizeof (bitset_word) * (dsize - ssize));
431 static bool
432 vbitset_equal_p (bitset dst, bitset src)
434 unsigned int i;
435 bitset_word *srcp = VBITSET_WORDS (src);
436 bitset_word *dstp = VBITSET_WORDS (dst);
437 bitset_windex ssize = VBITSET_SIZE (src);
438 bitset_windex dsize = VBITSET_SIZE (dst);
440 for (i = 0; i < min (ssize, dsize); i++)
441 if (*srcp++ != *dstp++)
442 return 0;
444 if (ssize > dsize)
446 for (; i < ssize; i++)
447 if (*srcp++)
448 return 0;
450 else
452 for (; i < dsize; i++)
453 if (*dstp++)
454 return 0;
457 return 1;
461 static bool
462 vbitset_subset_p (bitset dst, bitset src)
464 unsigned int i;
465 bitset_word *srcp = VBITSET_WORDS (src);
466 bitset_word *dstp = VBITSET_WORDS (dst);
467 bitset_windex ssize = VBITSET_SIZE (src);
468 bitset_windex dsize = VBITSET_SIZE (dst);
470 for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
471 if (*dstp != (*srcp | *dstp))
472 return 0;
474 if (ssize > dsize)
476 for (; i < ssize; i++)
477 if (*srcp++)
478 return 0;
481 return 1;
485 static bool
486 vbitset_disjoint_p (bitset dst, bitset src)
488 unsigned int i;
489 bitset_word *srcp = VBITSET_WORDS (src);
490 bitset_word *dstp = VBITSET_WORDS (dst);
491 bitset_windex ssize = VBITSET_SIZE (src);
492 bitset_windex dsize = VBITSET_SIZE (dst);
494 for (i = 0; i < min (ssize, dsize); i++)
495 if (*srcp++ & *dstp++)
496 return 0;
498 return 1;
502 static void
503 vbitset_and (bitset dst, bitset src1, bitset src2)
505 unsigned int i;
506 bitset_word *src1p;
507 bitset_word *src2p;
508 bitset_word *dstp;
509 bitset_windex ssize1;
510 bitset_windex ssize2;
511 bitset_windex dsize;
513 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
515 dsize = VBITSET_SIZE (dst);
516 ssize1 = VBITSET_SIZE (src1);
517 ssize2 = VBITSET_SIZE (src2);
518 dstp = VBITSET_WORDS (dst);
519 src1p = VBITSET_WORDS (src1);
520 src2p = VBITSET_WORDS (src2);
522 for (i = 0; i < min (ssize1, ssize2); i++)
523 *dstp++ = *src1p++ & *src2p++;
525 memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
529 static bool
530 vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
532 unsigned int i;
533 int changed = 0;
534 bitset_word *src1p;
535 bitset_word *src2p;
536 bitset_word *dstp;
537 bitset_windex ssize1;
538 bitset_windex ssize2;
539 bitset_windex dsize;
541 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
543 dsize = VBITSET_SIZE (dst);
544 ssize1 = VBITSET_SIZE (src1);
545 ssize2 = VBITSET_SIZE (src2);
546 dstp = VBITSET_WORDS (dst);
547 src1p = VBITSET_WORDS (src1);
548 src2p = VBITSET_WORDS (src2);
550 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
552 bitset_word tmp = *src1p++ & *src2p++;
554 if (*dstp != tmp)
556 changed = 1;
557 *dstp = tmp;
561 if (ssize2 > ssize1)
563 src1p = src2p;
564 ssize1 = ssize2;
567 for (; i < ssize1; i++, dstp++)
569 if (*dstp != 0)
571 changed = 1;
572 *dstp = 0;
576 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
578 return changed;
582 static void
583 vbitset_andn (bitset dst, bitset src1, bitset src2)
585 unsigned int i;
586 bitset_word *src1p;
587 bitset_word *src2p;
588 bitset_word *dstp;
589 bitset_windex ssize1;
590 bitset_windex ssize2;
591 bitset_windex dsize;
593 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
595 dsize = VBITSET_SIZE (dst);
596 ssize1 = VBITSET_SIZE (src1);
597 ssize2 = VBITSET_SIZE (src2);
598 dstp = VBITSET_WORDS (dst);
599 src1p = VBITSET_WORDS (src1);
600 src2p = VBITSET_WORDS (src2);
602 for (i = 0; i < min (ssize1, ssize2); i++)
603 *dstp++ = *src1p++ & ~(*src2p++);
605 if (ssize2 > ssize1)
607 for (; i < ssize2; i++)
608 *dstp++ = 0;
610 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
612 else
614 for (; i < ssize1; i++)
615 *dstp++ = *src1p++;
617 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
622 static bool
623 vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
625 unsigned int i;
626 int changed = 0;
627 bitset_word *src1p;
628 bitset_word *src2p;
629 bitset_word *dstp;
630 bitset_windex ssize1;
631 bitset_windex ssize2;
632 bitset_windex dsize;
634 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
636 dsize = VBITSET_SIZE (dst);
637 ssize1 = VBITSET_SIZE (src1);
638 ssize2 = VBITSET_SIZE (src2);
639 dstp = VBITSET_WORDS (dst);
640 src1p = VBITSET_WORDS (src1);
641 src2p = VBITSET_WORDS (src2);
643 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
645 bitset_word tmp = *src1p++ & ~(*src2p++);
647 if (*dstp != tmp)
649 changed = 1;
650 *dstp = tmp;
654 if (ssize2 > ssize1)
656 for (; i < ssize2; i++, dstp++)
658 if (*dstp != 0)
660 changed = 1;
661 *dstp = 0;
665 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
667 else
669 for (; i < ssize1; i++, dstp++)
671 bitset_word tmp = *src1p++;
673 if (*dstp != tmp)
675 changed = 1;
676 *dstp = tmp;
680 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
683 return changed;
687 static void
688 vbitset_or (bitset dst, bitset src1, bitset src2)
690 unsigned int i;
691 bitset_word *src1p;
692 bitset_word *src2p;
693 bitset_word *dstp;
694 bitset_windex ssize1;
695 bitset_windex ssize2;
696 bitset_windex dsize;
698 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
700 dsize = VBITSET_SIZE (dst);
701 ssize1 = VBITSET_SIZE (src1);
702 ssize2 = VBITSET_SIZE (src2);
703 dstp = VBITSET_WORDS (dst);
704 src1p = VBITSET_WORDS (src1);
705 src2p = VBITSET_WORDS (src2);
707 for (i = 0; i < min (ssize1, ssize2); i++)
708 *dstp++ = *src1p++ | *src2p++;
710 if (ssize2 > ssize1)
712 src1p = src2p;
713 ssize1 = ssize2;
716 for (; i < ssize1; i++)
717 *dstp++ = *src1p++;
719 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
723 static bool
724 vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
726 unsigned int i;
727 int changed = 0;
728 bitset_word *src1p;
729 bitset_word *src2p;
730 bitset_word *dstp;
731 bitset_windex ssize1;
732 bitset_windex ssize2;
733 bitset_windex dsize;
735 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
737 dsize = VBITSET_SIZE (dst);
738 ssize1 = VBITSET_SIZE (src1);
739 ssize2 = VBITSET_SIZE (src2);
740 dstp = VBITSET_WORDS (dst);
741 src1p = VBITSET_WORDS (src1);
742 src2p = VBITSET_WORDS (src2);
744 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
746 bitset_word tmp = *src1p++ | *src2p++;
748 if (*dstp != tmp)
750 changed = 1;
751 *dstp = tmp;
755 if (ssize2 > ssize1)
757 src1p = src2p;
758 ssize1 = ssize2;
761 for (; i < ssize1; i++, dstp++)
763 bitset_word tmp = *src1p++;
765 if (*dstp != tmp)
767 changed = 1;
768 *dstp = tmp;
772 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
774 return changed;
778 static void
779 vbitset_xor (bitset dst, bitset src1, bitset src2)
781 unsigned int i;
782 bitset_word *src1p;
783 bitset_word *src2p;
784 bitset_word *dstp;
785 bitset_windex ssize1;
786 bitset_windex ssize2;
787 bitset_windex dsize;
789 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
791 dsize = VBITSET_SIZE (dst);
792 ssize1 = VBITSET_SIZE (src1);
793 ssize2 = VBITSET_SIZE (src2);
794 dstp = VBITSET_WORDS (dst);
795 src1p = VBITSET_WORDS (src1);
796 src2p = VBITSET_WORDS (src2);
798 for (i = 0; i < min (ssize1, ssize2); i++)
799 *dstp++ = *src1p++ ^ *src2p++;
801 if (ssize2 > ssize1)
803 src1p = src2p;
804 ssize1 = ssize2;
807 for (; i < ssize1; i++)
808 *dstp++ = *src1p++;
810 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
814 static bool
815 vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
817 unsigned int i;
818 int changed = 0;
819 bitset_word *src1p;
820 bitset_word *src2p;
821 bitset_word *dstp;
822 bitset_windex ssize1;
823 bitset_windex ssize2;
824 bitset_windex dsize;
826 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
828 dsize = VBITSET_SIZE (dst);
829 ssize1 = VBITSET_SIZE (src1);
830 ssize2 = VBITSET_SIZE (src2);
831 dstp = VBITSET_WORDS (dst);
832 src1p = VBITSET_WORDS (src1);
833 src2p = VBITSET_WORDS (src2);
835 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
837 bitset_word tmp = *src1p++ ^ *src2p++;
839 if (*dstp != tmp)
841 changed = 1;
842 *dstp = tmp;
846 if (ssize2 > ssize1)
848 src1p = src2p;
849 ssize1 = ssize2;
852 for (; i < ssize1; i++, dstp++)
854 bitset_word tmp = *src1p++;
856 if (*dstp != tmp)
858 changed = 1;
859 *dstp = tmp;
863 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
865 return changed;
869 /* FIXME, these operations need fixing for different size
870 bitsets. */
872 static void
873 vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
875 unsigned int i;
876 bitset_word *src1p;
877 bitset_word *src2p;
878 bitset_word *src3p;
879 bitset_word *dstp;
880 bitset_windex size;
882 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
883 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
885 bitset_and_or_ (dst, src1, src2, src3);
886 return;
889 vbitset_resize (dst, BITSET_NBITS_ (src1));
891 src1p = VBITSET_WORDS (src1);
892 src2p = VBITSET_WORDS (src2);
893 src3p = VBITSET_WORDS (src3);
894 dstp = VBITSET_WORDS (dst);
895 size = VBITSET_SIZE (dst);
897 for (i = 0; i < size; i++)
898 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
902 static bool
903 vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
905 unsigned int i;
906 int changed = 0;
907 bitset_word *src1p;
908 bitset_word *src2p;
909 bitset_word *src3p;
910 bitset_word *dstp;
911 bitset_windex size;
913 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
914 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
915 return bitset_and_or_cmp_ (dst, src1, src2, src3);
917 vbitset_resize (dst, BITSET_NBITS_ (src1));
919 src1p = VBITSET_WORDS (src1);
920 src2p = VBITSET_WORDS (src2);
921 src3p = VBITSET_WORDS (src3);
922 dstp = VBITSET_WORDS (dst);
923 size = VBITSET_SIZE (dst);
925 for (i = 0; i < size; i++, dstp++)
927 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
929 if (*dstp != tmp)
931 changed = 1;
932 *dstp = tmp;
935 return changed;
939 static void
940 vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
942 unsigned int i;
943 bitset_word *src1p;
944 bitset_word *src2p;
945 bitset_word *src3p;
946 bitset_word *dstp;
947 bitset_windex size;
949 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
950 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
952 bitset_andn_or_ (dst, src1, src2, src3);
953 return;
956 vbitset_resize (dst, BITSET_NBITS_ (src1));
958 src1p = VBITSET_WORDS (src1);
959 src2p = VBITSET_WORDS (src2);
960 src3p = VBITSET_WORDS (src3);
961 dstp = VBITSET_WORDS (dst);
962 size = VBITSET_SIZE (dst);
964 for (i = 0; i < size; i++)
965 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
969 static bool
970 vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
972 unsigned int i;
973 int changed = 0;
974 bitset_word *src1p;
975 bitset_word *src2p;
976 bitset_word *src3p;
977 bitset_word *dstp;
978 bitset_windex size;
980 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
981 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
982 return bitset_andn_or_cmp_ (dst, src1, src2, src3);
984 vbitset_resize (dst, BITSET_NBITS_ (src1));
986 src1p = VBITSET_WORDS (src1);
987 src2p = VBITSET_WORDS (src2);
988 src3p = VBITSET_WORDS (src3);
989 dstp = VBITSET_WORDS (dst);
990 size = VBITSET_SIZE (dst);
992 for (i = 0; i < size; i++, dstp++)
994 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
996 if (*dstp != tmp)
998 changed = 1;
999 *dstp = tmp;
1002 return changed;
1006 static void
1007 vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
1009 unsigned int i;
1010 bitset_word *src1p;
1011 bitset_word *src2p;
1012 bitset_word *src3p;
1013 bitset_word *dstp;
1014 bitset_windex size;
1016 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1017 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1019 bitset_or_and_ (dst, src1, src2, src3);
1020 return;
1023 vbitset_resize (dst, BITSET_NBITS_ (src1));
1025 src1p = VBITSET_WORDS (src1);
1026 src2p = VBITSET_WORDS (src2);
1027 src3p = VBITSET_WORDS (src3);
1028 dstp = VBITSET_WORDS (dst);
1029 size = VBITSET_SIZE (dst);
1031 for (i = 0; i < size; i++)
1032 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
1036 static bool
1037 vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
1039 unsigned int i;
1040 int changed = 0;
1041 bitset_word *src1p;
1042 bitset_word *src2p;
1043 bitset_word *src3p;
1044 bitset_word *dstp;
1045 bitset_windex size;
1047 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1048 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1049 return bitset_or_and_cmp_ (dst, src1, src2, src3);
1051 vbitset_resize (dst, BITSET_NBITS_ (src1));
1053 src1p = VBITSET_WORDS (src1);
1054 src2p = VBITSET_WORDS (src2);
1055 src3p = VBITSET_WORDS (src3);
1056 dstp = VBITSET_WORDS (dst);
1057 size = VBITSET_SIZE (dst);
1059 for (i = 0; i < size; i++, dstp++)
1061 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
1063 if (*dstp != tmp)
1065 changed = 1;
1066 *dstp = tmp;
1069 return changed;
1073 static void
1074 vbitset_copy (bitset dst, bitset src)
1076 if (BITSET_COMPATIBLE_ (dst, src))
1077 vbitset_copy1 (dst, src);
1078 else
1079 bitset_copy_ (dst, src);
1083 /* Vector of operations for multiple word bitsets. */
1084 struct bitset_vtable vbitset_vtable = {
1085 vbitset_set,
1086 vbitset_reset,
1087 bitset_toggle_,
1088 vbitset_test,
1089 vbitset_resize,
1090 bitset_size_,
1091 bitset_count_,
1092 vbitset_empty_p,
1093 vbitset_ones,
1094 vbitset_zero,
1095 vbitset_copy,
1096 vbitset_disjoint_p,
1097 vbitset_equal_p,
1098 vbitset_not,
1099 vbitset_subset_p,
1100 vbitset_and,
1101 vbitset_and_cmp,
1102 vbitset_andn,
1103 vbitset_andn_cmp,
1104 vbitset_or,
1105 vbitset_or_cmp,
1106 vbitset_xor,
1107 vbitset_xor_cmp,
1108 vbitset_and_or,
1109 vbitset_and_or_cmp,
1110 vbitset_andn_or,
1111 vbitset_andn_or_cmp,
1112 vbitset_or_and,
1113 vbitset_or_and_cmp,
1114 vbitset_list,
1115 vbitset_list_reverse,
1116 NULL,
1117 BITSET_VARRAY
1121 size_t
1122 vbitset_bytes (n_bits)
1123 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1125 return sizeof (struct vbitset_struct);
1129 bitset
1130 vbitset_init (bset, n_bits)
1131 bitset bset;
1132 bitset_bindex n_bits;
1134 bset->b.vtable = &vbitset_vtable;
1136 bset->b.cindex = 0;
1138 VBITSET_SIZE (bset) = 0;
1139 vbitset_resize (bset, n_bits);
1140 return bset;