]> git.saurik.com Git - bison.git/blame - lib/vbitset.c
maint: automate annual package-wide copyright-year update.
[bison.git] / lib / vbitset.c
CommitLineData
cea53247 1/* Variable array bitsets.
02650b7f 2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
cea53247
PE
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
f16b0819 5 This program is free software: you can redistribute it and/or modify
cea53247 6 it under the terms of the GNU General Public License as published by
f16b0819 7 the Free Software Foundation, either version 3 of the License, or
cea53247
PE
8 (at your option) any later version.
9
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.
14
15 You should have received a copy of the GNU General Public License
f16b0819 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
cea53247 17
231ed89a 18#include <config.h>
cea53247
PE
19
20#include "vbitset.h"
231ed89a 21
cea53247
PE
22#include <stdlib.h>
23#include <string.h>
24
25/* This file implements variable size bitsets stored as a variable
26 length array of words. Any unused bits in the last word must be
4d1801f1 27 zero.
cea53247
PE
28
29 Note that binary or ternary operations assume that each bitset operand
30 has the same size.
31*/
32
7d7d6663
PE
33static void vbitset_unused_clear (bitset);
34
35static void vbitset_set (bitset, bitset_bindex);
36static void vbitset_reset (bitset, bitset_bindex);
37static bool vbitset_test (bitset, bitset_bindex);
4d1801f1 38static bitset_bindex vbitset_list (bitset, bitset_bindex *,
7d7d6663
PE
39 bitset_bindex, bitset_bindex *);
40static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
41 bitset_bindex, bitset_bindex *);
cea53247
PE
42
43#define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
44#define VBITSET_WORDS(X) ((X)->b.cdata)
45#define VBITSET_SIZE(X) ((X)->b.csize)
46#define VBITSET_ASIZE(X) ((X)->v.size)
47
4d1801f1
PE
48#undef min
49#undef max
cea53247
PE
50#define min(a, b) ((a) > (b) ? (b) : (a))
51#define max(a, b) ((a) > (b) ? (a) : (b))
52
53static bitset_bindex
88ab880d 54vbitset_resize (bitset src, bitset_bindex n_bits)
cea53247
PE
55{
56 bitset_windex oldsize;
57 bitset_windex newsize;
58
59 if (n_bits == BITSET_NBITS_ (src))
60 return n_bits;
61
62 oldsize = VBITSET_SIZE (src);
63 newsize = VBITSET_N_WORDS (n_bits);
64
65 if (oldsize < newsize)
66 {
67 bitset_windex size;
68
4d1801f1 69 /* The bitset needs to grow. If we already have enough memory
cea53247
PE
70 allocated, then just zero what we need. */
71 if (newsize > VBITSET_ASIZE (src))
72 {
73 /* We need to allocate more memory. When oldsize is
74 non-zero this means that we are changing the size, so
75 grow the bitset 25% larger than requested to reduce
76 number of reallocations. */
77
78 if (oldsize == 0)
79 size = newsize;
80 else
81 size = newsize + newsize / 4;
4d1801f1 82
cea53247
PE
83 VBITSET_WORDS (src)
84 = realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
85 VBITSET_ASIZE (src) = size;
86 }
87
4d1801f1 88 memset (VBITSET_WORDS (src) + oldsize, 0,
cea53247
PE
89 (newsize - oldsize) * sizeof (bitset_word));
90 VBITSET_SIZE (src) = newsize;
91 }
92 else
93 {
94 /* The bitset needs to shrink. There's no point deallocating
95 the memory unless it is shrinking by a reasonable amount. */
96 if ((oldsize - newsize) >= oldsize / 2)
97 {
98 VBITSET_WORDS (src)
99 = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
100 VBITSET_ASIZE (src) = newsize;
101 }
102
103 /* Need to prune any excess bits. FIXME. */
104
105 VBITSET_SIZE (src) = newsize;
106 }
107
108 BITSET_NBITS_ (src) = n_bits;
109 return n_bits;
110}
111
112
113/* Set bit BITNO in bitset DST. */
114static void
115vbitset_set (dst, bitno)
116 bitset dst;
117 bitset_bindex bitno;
118{
119 bitset_windex windex = bitno / BITSET_WORD_BITS;
120
121 /* Perhaps we should abort. The user should explicitly call
122 bitset_resize since this will not catch the case when we set a
123 bit larger than the current size but smaller than the allocated
124 size. */
125 vbitset_resize (dst, bitno);
126
127 dst->b.cdata[windex - dst->b.cindex] |=
128 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
129}
130
131
132/* Reset bit BITNO in bitset DST. */
133static void
134vbitset_reset (dst, bitno)
135 bitset dst ATTRIBUTE_UNUSED;
136 bitset_bindex bitno ATTRIBUTE_UNUSED;
137{
138 /* We must be accessing outside the cache so the bit is
139 zero anyway. */
140}
141
142
143/* Test bit BITNO in bitset SRC. */
144static bool
145vbitset_test (src, bitno)
146 bitset src ATTRIBUTE_UNUSED;
147 bitset_bindex bitno ATTRIBUTE_UNUSED;
148{
149 /* We must be accessing outside the cache so the bit is
150 zero anyway. */
151 return 0;
152}
153
154
155/* Find list of up to NUM bits set in BSET in reverse order, starting
156 from and including NEXT and store in array LIST. Return with
157 actual number of bits found and with *NEXT indicating where search
158 stopped. */
159static bitset_bindex
160vbitset_list_reverse (src, list, num, next)
161 bitset src;
162 bitset_bindex *list;
163 bitset_bindex num;
164 bitset_bindex *next;
165{
166 bitset_bindex bitno;
167 bitset_bindex rbitno;
168 bitset_bindex count;
169 bitset_windex windex;
170 unsigned int bitcnt;
171 bitset_bindex bitoff;
172 bitset_word *srcp = VBITSET_WORDS (src);
173 bitset_bindex n_bits = BITSET_SIZE_ (src);
174
175 rbitno = *next;
176
177 /* If num is 1, we could speed things up with a binary search
178 of the word of interest. */
179
180 if (rbitno >= n_bits)
181 return 0;
182
183 count = 0;
184
185 bitno = n_bits - (rbitno + 1);
186
187 windex = bitno / BITSET_WORD_BITS;
188 bitcnt = bitno % BITSET_WORD_BITS;
189 bitoff = windex * BITSET_WORD_BITS;
190
191 do
192 {
193 bitset_word word;
194
195 word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
196 for (; word; bitcnt--)
197 {
198 if (word & BITSET_MSB)
199 {
200 list[count++] = bitoff + bitcnt;
201 if (count >= num)
202 {
203 *next = n_bits - (bitoff + bitcnt);
204 return count;
205 }
206 }
207 word <<= 1;
208 }
209 bitoff -= BITSET_WORD_BITS;
210 bitcnt = BITSET_WORD_BITS - 1;
211 }
212 while (windex--);
213
214 *next = n_bits - (bitoff + 1);
215 return count;
216}
217
218
219/* Find list of up to NUM bits set in BSET starting from and including
220 *NEXT and store in array LIST. Return with actual number of bits
221 found and with *NEXT indicating where search stopped. */
222static bitset_bindex
223vbitset_list (src, list, num, next)
224 bitset src;
225 bitset_bindex *list;
226 bitset_bindex num;
227 bitset_bindex *next;
228{
229 bitset_bindex bitno;
230 bitset_bindex count;
231 bitset_windex windex;
232 bitset_bindex bitoff;
233 bitset_windex size = VBITSET_SIZE (src);
234 bitset_word *srcp = VBITSET_WORDS (src);
235 bitset_word word;
236
237 bitno = *next;
238
239 count = 0;
240 if (!bitno)
241 {
242 /* Many bitsets are zero, so make this common case fast. */
243 for (windex = 0; windex < size && !srcp[windex]; windex++)
244 continue;
245 if (windex >= size)
246 return 0;
247
248 /* If num is 1, we could speed things up with a binary search
249 of the current word. */
250
251 bitoff = windex * BITSET_WORD_BITS;
252 }
253 else
254 {
255 if (bitno >= BITSET_SIZE_ (src))
256 return 0;
257
258 windex = bitno / BITSET_WORD_BITS;
259 bitno = bitno % BITSET_WORD_BITS;
260
261 if (bitno)
262 {
263 /* Handle the case where we start within a word.
264 Most often, this is executed with large bitsets
265 with many set bits where we filled the array
266 on the previous call to this function. */
267
268 bitoff = windex * BITSET_WORD_BITS;
269 word = srcp[windex] >> bitno;
270 for (bitno = bitoff + bitno; word; bitno++)
271 {
272 if (word & 1)
273 {
274 list[count++] = bitno;
275 if (count >= num)
276 {
277 *next = bitno + 1;
278 return count;
279 }
280 }
281 word >>= 1;
282 }
283 windex++;
284 }
285 bitoff = windex * BITSET_WORD_BITS;
286 }
287
288 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
289 {
290 if (!(word = srcp[windex]))
291 continue;
292
293 if ((count + BITSET_WORD_BITS) < num)
294 {
295 for (bitno = bitoff; word; bitno++)
296 {
297 if (word & 1)
298 list[count++] = bitno;
299 word >>= 1;
300 }
301 }
302 else
303 {
304 for (bitno = bitoff; word; bitno++)
305 {
306 if (word & 1)
307 {
308 list[count++] = bitno;
309 if (count >= num)
310 {
311 *next = bitno + 1;
312 return count;
313 }
314 }
315 word >>= 1;
316 }
317 }
318 }
319
320 *next = bitoff;
321 return count;
322}
323
324
325/* Ensure that any unused bits within the last word are clear. */
326static inline void
327vbitset_unused_clear (dst)
328 bitset dst;
329{
330 unsigned int last_bit;
331
332 last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
333 if (last_bit)
334 VBITSET_WORDS (dst)[VBITSET_SIZE (dst) - 1] &=
335 ((bitset_word) 1 << last_bit) - 1;
336}
337
338
339static void
88ab880d 340vbitset_ones (bitset dst)
cea53247
PE
341{
342 bitset_word *dstp = VBITSET_WORDS (dst);
343 unsigned int bytes;
344
345 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
346
347 memset (dstp, -1, bytes);
348 vbitset_unused_clear (dst);
349}
350
351
352static void
88ab880d 353vbitset_zero (bitset dst)
cea53247
PE
354{
355 bitset_word *dstp = VBITSET_WORDS (dst);
356 unsigned int bytes;
357
358 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
359
360 memset (dstp, 0, bytes);
361}
362
363
364static bool
88ab880d 365vbitset_empty_p (bitset dst)
cea53247
PE
366{
367 unsigned int i;
368 bitset_word *dstp = VBITSET_WORDS (dst);
369
370 for (i = 0; i < VBITSET_SIZE (dst); i++)
371 if (dstp[i])
372 return 0;
373
374 return 1;
375}
376
377
378static void
88ab880d 379vbitset_copy1 (bitset dst, bitset src)
cea53247
PE
380{
381 bitset_word *srcp;
382 bitset_word *dstp;
383 bitset_windex ssize;
384 bitset_windex dsize;
385
386 if (src == dst)
387 return;
388
389 vbitset_resize (dst, BITSET_SIZE_ (src));
390
391 srcp = VBITSET_WORDS (src);
392 dstp = VBITSET_WORDS (dst);
393 ssize = VBITSET_SIZE (src);
394 dsize = VBITSET_SIZE (dst);
395
396 memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
397
398 memset (dstp + sizeof (bitset_word) * ssize, 0,
399 sizeof (bitset_word) * (dsize - ssize));
400}
401
402
403static void
88ab880d 404vbitset_not (bitset dst, bitset src)
cea53247
PE
405{
406 unsigned int i;
407 bitset_word *srcp;
408 bitset_word *dstp;
409 bitset_windex ssize;
410 bitset_windex dsize;
411
412 vbitset_resize (dst, BITSET_SIZE_ (src));
413
414 srcp = VBITSET_WORDS (src);
415 dstp = VBITSET_WORDS (dst);
416 ssize = VBITSET_SIZE (src);
417 dsize = VBITSET_SIZE (dst);
418
419 for (i = 0; i < ssize; i++)
420 *dstp++ = ~(*srcp++);
421
422 vbitset_unused_clear (dst);
423 memset (dstp + sizeof (bitset_word) * ssize, 0,
424 sizeof (bitset_word) * (dsize - ssize));
425}
426
4d1801f1 427
cea53247 428static bool
88ab880d 429vbitset_equal_p (bitset dst, bitset src)
cea53247
PE
430{
431 unsigned int i;
432 bitset_word *srcp = VBITSET_WORDS (src);
433 bitset_word *dstp = VBITSET_WORDS (dst);
434 bitset_windex ssize = VBITSET_SIZE (src);
435 bitset_windex dsize = VBITSET_SIZE (dst);
436
437 for (i = 0; i < min (ssize, dsize); i++)
438 if (*srcp++ != *dstp++)
439 return 0;
440
441 if (ssize > dsize)
442 {
443 for (; i < ssize; i++)
444 if (*srcp++)
445 return 0;
446 }
447 else
448 {
449 for (; i < dsize; i++)
450 if (*dstp++)
451 return 0;
452 }
453
454 return 1;
455}
456
457
458static bool
88ab880d 459vbitset_subset_p (bitset dst, bitset src)
cea53247
PE
460{
461 unsigned int i;
462 bitset_word *srcp = VBITSET_WORDS (src);
463 bitset_word *dstp = VBITSET_WORDS (dst);
464 bitset_windex ssize = VBITSET_SIZE (src);
465 bitset_windex dsize = VBITSET_SIZE (dst);
4d1801f1 466
cea53247
PE
467 for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
468 if (*dstp != (*srcp | *dstp))
469 return 0;
470
471 if (ssize > dsize)
472 {
473 for (; i < ssize; i++)
474 if (*srcp++)
475 return 0;
476 }
477
478 return 1;
479}
480
481
482static bool
88ab880d 483vbitset_disjoint_p (bitset dst, bitset src)
cea53247
PE
484{
485 unsigned int i;
486 bitset_word *srcp = VBITSET_WORDS (src);
487 bitset_word *dstp = VBITSET_WORDS (dst);
488 bitset_windex ssize = VBITSET_SIZE (src);
489 bitset_windex dsize = VBITSET_SIZE (dst);
490
491 for (i = 0; i < min (ssize, dsize); i++)
492 if (*srcp++ & *dstp++)
493 return 0;
494
495 return 1;
496}
497
498
499static void
88ab880d 500vbitset_and (bitset dst, bitset src1, bitset src2)
cea53247
PE
501{
502 unsigned int i;
503 bitset_word *src1p;
504 bitset_word *src2p;
505 bitset_word *dstp;
506 bitset_windex ssize1;
507 bitset_windex ssize2;
508 bitset_windex dsize;
509
510 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
511
512 dsize = VBITSET_SIZE (dst);
513 ssize1 = VBITSET_SIZE (src1);
514 ssize2 = VBITSET_SIZE (src2);
515 dstp = VBITSET_WORDS (dst);
516 src1p = VBITSET_WORDS (src1);
517 src2p = VBITSET_WORDS (src2);
518
519 for (i = 0; i < min (ssize1, ssize2); i++)
520 *dstp++ = *src1p++ & *src2p++;
4d1801f1 521
cea53247
PE
522 memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
523}
524
525
526static bool
88ab880d 527vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
528{
529 unsigned int i;
530 int changed = 0;
531 bitset_word *src1p;
532 bitset_word *src2p;
533 bitset_word *dstp;
534 bitset_windex ssize1;
535 bitset_windex ssize2;
536 bitset_windex dsize;
537
538 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
539
540 dsize = VBITSET_SIZE (dst);
541 ssize1 = VBITSET_SIZE (src1);
542 ssize2 = VBITSET_SIZE (src2);
543 dstp = VBITSET_WORDS (dst);
544 src1p = VBITSET_WORDS (src1);
545 src2p = VBITSET_WORDS (src2);
546
547 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
548 {
549 bitset_word tmp = *src1p++ & *src2p++;
4d1801f1 550
cea53247
PE
551 if (*dstp != tmp)
552 {
553 changed = 1;
554 *dstp = tmp;
555 }
556 }
4d1801f1 557
cea53247
PE
558 if (ssize2 > ssize1)
559 {
560 src1p = src2p;
561 ssize1 = ssize2;
562 }
563
564 for (; i < ssize1; i++, dstp++)
565 {
566 if (*dstp != 0)
567 {
568 changed = 1;
569 *dstp = 0;
570 }
571 }
572
573 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
574
575 return changed;
576}
577
578
579static void
88ab880d 580vbitset_andn (bitset dst, bitset src1, bitset src2)
cea53247
PE
581{
582 unsigned int i;
583 bitset_word *src1p;
584 bitset_word *src2p;
585 bitset_word *dstp;
586 bitset_windex ssize1;
587 bitset_windex ssize2;
588 bitset_windex dsize;
589
590 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
591
592 dsize = VBITSET_SIZE (dst);
593 ssize1 = VBITSET_SIZE (src1);
594 ssize2 = VBITSET_SIZE (src2);
595 dstp = VBITSET_WORDS (dst);
596 src1p = VBITSET_WORDS (src1);
597 src2p = VBITSET_WORDS (src2);
598
599 for (i = 0; i < min (ssize1, ssize2); i++)
600 *dstp++ = *src1p++ & ~(*src2p++);
4d1801f1 601
cea53247
PE
602 if (ssize2 > ssize1)
603 {
604 for (; i < ssize2; i++)
605 *dstp++ = 0;
606
607 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
608 }
609 else
610 {
611 for (; i < ssize1; i++)
612 *dstp++ = *src1p++;
613
614 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
615 }
616}
617
618
619static bool
88ab880d 620vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
621{
622 unsigned int i;
623 int changed = 0;
624 bitset_word *src1p;
625 bitset_word *src2p;
626 bitset_word *dstp;
627 bitset_windex ssize1;
628 bitset_windex ssize2;
629 bitset_windex dsize;
630
631 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
632
633 dsize = VBITSET_SIZE (dst);
634 ssize1 = VBITSET_SIZE (src1);
635 ssize2 = VBITSET_SIZE (src2);
636 dstp = VBITSET_WORDS (dst);
637 src1p = VBITSET_WORDS (src1);
638 src2p = VBITSET_WORDS (src2);
639
640 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
641 {
642 bitset_word tmp = *src1p++ & ~(*src2p++);
4d1801f1 643
cea53247
PE
644 if (*dstp != tmp)
645 {
646 changed = 1;
647 *dstp = tmp;
648 }
649 }
4d1801f1 650
cea53247
PE
651 if (ssize2 > ssize1)
652 {
653 for (; i < ssize2; i++, dstp++)
654 {
655 if (*dstp != 0)
656 {
657 changed = 1;
658 *dstp = 0;
659 }
660 }
661
662 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
663 }
664 else
665 {
666 for (; i < ssize1; i++, dstp++)
667 {
668 bitset_word tmp = *src1p++;
4d1801f1 669
cea53247
PE
670 if (*dstp != tmp)
671 {
672 changed = 1;
673 *dstp = tmp;
674 }
675 }
676
677 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
678 }
679
680 return changed;
681}
682
683
684static void
88ab880d 685vbitset_or (bitset dst, bitset src1, bitset src2)
cea53247
PE
686{
687 unsigned int i;
688 bitset_word *src1p;
689 bitset_word *src2p;
690 bitset_word *dstp;
691 bitset_windex ssize1;
692 bitset_windex ssize2;
693 bitset_windex dsize;
694
695 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
696
697 dsize = VBITSET_SIZE (dst);
698 ssize1 = VBITSET_SIZE (src1);
699 ssize2 = VBITSET_SIZE (src2);
700 dstp = VBITSET_WORDS (dst);
701 src1p = VBITSET_WORDS (src1);
702 src2p = VBITSET_WORDS (src2);
703
704 for (i = 0; i < min (ssize1, ssize2); i++)
705 *dstp++ = *src1p++ | *src2p++;
4d1801f1 706
cea53247
PE
707 if (ssize2 > ssize1)
708 {
709 src1p = src2p;
710 ssize1 = ssize2;
711 }
712
713 for (; i < ssize1; i++)
714 *dstp++ = *src1p++;
715
716 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
717}
718
719
720static bool
88ab880d 721vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
722{
723 unsigned int i;
724 int changed = 0;
725 bitset_word *src1p;
726 bitset_word *src2p;
727 bitset_word *dstp;
728 bitset_windex ssize1;
729 bitset_windex ssize2;
730 bitset_windex dsize;
731
732 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
733
734 dsize = VBITSET_SIZE (dst);
735 ssize1 = VBITSET_SIZE (src1);
736 ssize2 = VBITSET_SIZE (src2);
737 dstp = VBITSET_WORDS (dst);
738 src1p = VBITSET_WORDS (src1);
739 src2p = VBITSET_WORDS (src2);
740
741 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
742 {
743 bitset_word tmp = *src1p++ | *src2p++;
4d1801f1 744
cea53247
PE
745 if (*dstp != tmp)
746 {
747 changed = 1;
748 *dstp = tmp;
749 }
750 }
4d1801f1 751
cea53247
PE
752 if (ssize2 > ssize1)
753 {
754 src1p = src2p;
755 ssize1 = ssize2;
756 }
757
758 for (; i < ssize1; i++, dstp++)
759 {
760 bitset_word tmp = *src1p++;
4d1801f1 761
cea53247
PE
762 if (*dstp != tmp)
763 {
764 changed = 1;
765 *dstp = tmp;
766 }
767 }
768
769 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
770
771 return changed;
772}
773
774
775static void
88ab880d 776vbitset_xor (bitset dst, bitset src1, bitset src2)
cea53247
PE
777{
778 unsigned int i;
779 bitset_word *src1p;
780 bitset_word *src2p;
781 bitset_word *dstp;
782 bitset_windex ssize1;
783 bitset_windex ssize2;
784 bitset_windex dsize;
785
786 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
787
788 dsize = VBITSET_SIZE (dst);
789 ssize1 = VBITSET_SIZE (src1);
790 ssize2 = VBITSET_SIZE (src2);
791 dstp = VBITSET_WORDS (dst);
792 src1p = VBITSET_WORDS (src1);
793 src2p = VBITSET_WORDS (src2);
794
795 for (i = 0; i < min (ssize1, ssize2); i++)
796 *dstp++ = *src1p++ ^ *src2p++;
4d1801f1 797
cea53247
PE
798 if (ssize2 > ssize1)
799 {
800 src1p = src2p;
801 ssize1 = ssize2;
802 }
803
804 for (; i < ssize1; i++)
805 *dstp++ = *src1p++;
806
807 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
808}
809
810
811static bool
88ab880d 812vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
813{
814 unsigned int i;
815 int changed = 0;
816 bitset_word *src1p;
817 bitset_word *src2p;
818 bitset_word *dstp;
819 bitset_windex ssize1;
820 bitset_windex ssize2;
821 bitset_windex dsize;
822
823 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
824
825 dsize = VBITSET_SIZE (dst);
826 ssize1 = VBITSET_SIZE (src1);
827 ssize2 = VBITSET_SIZE (src2);
828 dstp = VBITSET_WORDS (dst);
829 src1p = VBITSET_WORDS (src1);
830 src2p = VBITSET_WORDS (src2);
831
832 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
833 {
834 bitset_word tmp = *src1p++ ^ *src2p++;
4d1801f1 835
cea53247
PE
836 if (*dstp != tmp)
837 {
838 changed = 1;
839 *dstp = tmp;
840 }
841 }
4d1801f1 842
cea53247
PE
843 if (ssize2 > ssize1)
844 {
845 src1p = src2p;
846 ssize1 = ssize2;
847 }
848
849 for (; i < ssize1; i++, dstp++)
850 {
851 bitset_word tmp = *src1p++;
4d1801f1 852
cea53247
PE
853 if (*dstp != tmp)
854 {
855 changed = 1;
856 *dstp = tmp;
857 }
858 }
859
860 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
861
862 return changed;
863}
864
865
866/* FIXME, these operations need fixing for different size
867 bitsets. */
868
869static void
88ab880d 870vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
871{
872 unsigned int i;
873 bitset_word *src1p;
874 bitset_word *src2p;
875 bitset_word *src3p;
876 bitset_word *dstp;
877 bitset_windex size;
4d1801f1 878
cea53247
PE
879 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
880 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
881 {
882 bitset_and_or_ (dst, src1, src2, src3);
883 return;
884 }
885
886 vbitset_resize (dst, BITSET_NBITS_ (src1));
887
888 src1p = VBITSET_WORDS (src1);
889 src2p = VBITSET_WORDS (src2);
890 src3p = VBITSET_WORDS (src3);
891 dstp = VBITSET_WORDS (dst);
892 size = VBITSET_SIZE (dst);
893
894 for (i = 0; i < size; i++)
895 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
896}
897
898
899static bool
88ab880d 900vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
901{
902 unsigned int i;
903 int changed = 0;
904 bitset_word *src1p;
905 bitset_word *src2p;
906 bitset_word *src3p;
907 bitset_word *dstp;
908 bitset_windex size;
4d1801f1 909
cea53247
PE
910 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
911 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
912 return bitset_and_or_cmp_ (dst, src1, src2, src3);
913
914 vbitset_resize (dst, BITSET_NBITS_ (src1));
915
916 src1p = VBITSET_WORDS (src1);
917 src2p = VBITSET_WORDS (src2);
918 src3p = VBITSET_WORDS (src3);
919 dstp = VBITSET_WORDS (dst);
920 size = VBITSET_SIZE (dst);
4d1801f1 921
cea53247
PE
922 for (i = 0; i < size; i++, dstp++)
923 {
924 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
4d1801f1 925
cea53247
PE
926 if (*dstp != tmp)
927 {
928 changed = 1;
929 *dstp = tmp;
930 }
931 }
932 return changed;
933}
934
935
936static void
88ab880d 937vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
938{
939 unsigned int i;
940 bitset_word *src1p;
941 bitset_word *src2p;
942 bitset_word *src3p;
943 bitset_word *dstp;
944 bitset_windex size;
4d1801f1 945
cea53247
PE
946 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
947 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
948 {
949 bitset_andn_or_ (dst, src1, src2, src3);
950 return;
951 }
952
953 vbitset_resize (dst, BITSET_NBITS_ (src1));
954
955 src1p = VBITSET_WORDS (src1);
956 src2p = VBITSET_WORDS (src2);
957 src3p = VBITSET_WORDS (src3);
958 dstp = VBITSET_WORDS (dst);
959 size = VBITSET_SIZE (dst);
960
961 for (i = 0; i < size; i++)
962 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
963}
964
965
966static bool
88ab880d 967vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
968{
969 unsigned int i;
970 int changed = 0;
971 bitset_word *src1p;
972 bitset_word *src2p;
973 bitset_word *src3p;
974 bitset_word *dstp;
975 bitset_windex size;
4d1801f1 976
cea53247
PE
977 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
978 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
979 return bitset_andn_or_cmp_ (dst, src1, src2, src3);
980
981 vbitset_resize (dst, BITSET_NBITS_ (src1));
982
983 src1p = VBITSET_WORDS (src1);
984 src2p = VBITSET_WORDS (src2);
985 src3p = VBITSET_WORDS (src3);
986 dstp = VBITSET_WORDS (dst);
987 size = VBITSET_SIZE (dst);
4d1801f1 988
cea53247
PE
989 for (i = 0; i < size; i++, dstp++)
990 {
991 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
4d1801f1 992
cea53247
PE
993 if (*dstp != tmp)
994 {
995 changed = 1;
996 *dstp = tmp;
997 }
998 }
999 return changed;
1000}
1001
1002
1003static void
88ab880d 1004vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
1005{
1006 unsigned int i;
1007 bitset_word *src1p;
1008 bitset_word *src2p;
1009 bitset_word *src3p;
1010 bitset_word *dstp;
1011 bitset_windex size;
4d1801f1 1012
cea53247
PE
1013 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1014 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1015 {
1016 bitset_or_and_ (dst, src1, src2, src3);
1017 return;
1018 }
1019
1020 vbitset_resize (dst, BITSET_NBITS_ (src1));
1021
1022 src1p = VBITSET_WORDS (src1);
1023 src2p = VBITSET_WORDS (src2);
1024 src3p = VBITSET_WORDS (src3);
1025 dstp = VBITSET_WORDS (dst);
1026 size = VBITSET_SIZE (dst);
4d1801f1 1027
cea53247
PE
1028 for (i = 0; i < size; i++)
1029 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
1030}
1031
1032
1033static bool
88ab880d 1034vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
1035{
1036 unsigned int i;
1037 int changed = 0;
1038 bitset_word *src1p;
1039 bitset_word *src2p;
1040 bitset_word *src3p;
1041 bitset_word *dstp;
1042 bitset_windex size;
4d1801f1 1043
cea53247
PE
1044 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1045 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1046 return bitset_or_and_cmp_ (dst, src1, src2, src3);
1047
1048 vbitset_resize (dst, BITSET_NBITS_ (src1));
1049
1050 src1p = VBITSET_WORDS (src1);
1051 src2p = VBITSET_WORDS (src2);
1052 src3p = VBITSET_WORDS (src3);
1053 dstp = VBITSET_WORDS (dst);
1054 size = VBITSET_SIZE (dst);
4d1801f1 1055
cea53247
PE
1056 for (i = 0; i < size; i++, dstp++)
1057 {
1058 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
4d1801f1 1059
cea53247
PE
1060 if (*dstp != tmp)
1061 {
1062 changed = 1;
1063 *dstp = tmp;
1064 }
1065 }
1066 return changed;
1067}
1068
1069
98bb5428 1070static void
88ab880d 1071vbitset_copy (bitset dst, bitset src)
cea53247
PE
1072{
1073 if (BITSET_COMPATIBLE_ (dst, src))
1074 vbitset_copy1 (dst, src);
1075 else
1076 bitset_copy_ (dst, src);
1077}
1078
1079
1080/* Vector of operations for multiple word bitsets. */
1081struct bitset_vtable vbitset_vtable = {
1082 vbitset_set,
1083 vbitset_reset,
1084 bitset_toggle_,
1085 vbitset_test,
1086 vbitset_resize,
1087 bitset_size_,
1088 bitset_count_,
1089 vbitset_empty_p,
1090 vbitset_ones,
1091 vbitset_zero,
1092 vbitset_copy,
1093 vbitset_disjoint_p,
1094 vbitset_equal_p,
1095 vbitset_not,
1096 vbitset_subset_p,
1097 vbitset_and,
1098 vbitset_and_cmp,
1099 vbitset_andn,
1100 vbitset_andn_cmp,
1101 vbitset_or,
1102 vbitset_or_cmp,
1103 vbitset_xor,
1104 vbitset_xor_cmp,
1105 vbitset_and_or,
1106 vbitset_and_or_cmp,
1107 vbitset_andn_or,
1108 vbitset_andn_or_cmp,
1109 vbitset_or_and,
1110 vbitset_or_and_cmp,
1111 vbitset_list,
1112 vbitset_list_reverse,
1113 NULL,
1114 BITSET_VARRAY
1115};
1116
1117
1118size_t
1119vbitset_bytes (n_bits)
1120 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1121{
1122 return sizeof (struct vbitset_struct);
1123}
1124
1125
1126bitset
1127vbitset_init (bset, n_bits)
1128 bitset bset;
1129 bitset_bindex n_bits;
1130{
1131 bset->b.vtable = &vbitset_vtable;
1132
1133 bset->b.cindex = 0;
1134
1135 VBITSET_SIZE (bset) = 0;
1136 vbitset_resize (bset, n_bits);
1137 return bset;
1138}