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