]> git.saurik.com Git - bison.git/blame - lib/abitset.c
(struct abitset_struct.n_bits, abitset_small_list, abitset_size,
[bison.git] / lib / abitset.c
CommitLineData
613f5e1a 1/* Array bitsets.
7086e707
AD
2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
ef017502
AD
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.
7086e707 9
ef017502
AD
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.
7086e707 14
ef017502
AD
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
345cea78
AD
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18*/
7086e707
AD
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
613f5e1a 24#include "abitset.h"
7086e707 25#include <stdlib.h>
ef017502 26#include <string.h>
7086e707
AD
27
28/* This file implements fixed size bitsets stored as an array
29 of words. Any unused bits in the last word must be zero. */
30
613f5e1a 31typedef struct abitset_struct
ef017502 32{
62a34c3e 33 bitset_bindex n_bits; /* Number of bits. */
ef017502
AD
34 bitset_word words[1]; /* The array of bits. */
35}
613f5e1a 36*abitset;
ef017502
AD
37
38
39struct bitset_struct
40{
41 struct bbitset_struct b;
613f5e1a 42 struct abitset_struct a;
ef017502
AD
43};
44
613f5e1a 45static void abitset_unused_clear PARAMS ((bitset));
ef017502 46
62a34c3e
PE
47static bitset_bindex abitset_small_list PARAMS ((bitset, bitset_bindex *,
48 bitset_bindex,
49 bitset_bindex *));
ef017502 50
613f5e1a
AD
51static void abitset_set PARAMS ((bitset, bitset_bindex));
52static void abitset_reset PARAMS ((bitset, bitset_bindex));
53static int abitset_test PARAMS ((bitset, bitset_bindex));
62a34c3e
PE
54static bitset_bindex abitset_size PARAMS ((bitset));
55static bitset_bindex abitset_list PARAMS ((bitset, bitset_bindex *,
56 bitset_bindex, bitset_bindex *));
57static bitset_bindex abitset_list_reverse
ef017502 58PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));
7086e707 59
613f5e1a
AD
60#define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
61#define ABITSET_WORDS(X) ((X)->a.words)
62#define ABITSET_N_BITS(X) ((X)->a.n_bits)
7086e707
AD
63
64
65/* Return size in bits of bitset SRC. */
62a34c3e 66static bitset_bindex
613f5e1a 67abitset_size (src)
7086e707
AD
68 bitset src;
69{
613f5e1a 70 return ABITSET_N_BITS (src);
7086e707
AD
71}
72
73
74/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
75 *NEXT and store in array LIST. Return with actual number of bits
76 found and with *NEXT indicating where search stopped. */
62a34c3e 77static bitset_bindex
613f5e1a 78abitset_small_list (src, list, num, next)
7086e707
AD
79 bitset src;
80 bitset_bindex *list;
81 bitset_bindex num;
82 bitset_bindex *next;
83{
84 bitset_bindex bitno;
85 bitset_bindex count;
86 bitset_windex size;
87 bitset_word word;
88
613f5e1a 89 word = ABITSET_WORDS (src)[0];
7086e707
AD
90
91 /* Short circuit common case. */
92 if (!word)
93 return 0;
94
613f5e1a 95 size = ABITSET_N_BITS (src);
7086e707
AD
96 bitno = *next;
97 if (bitno >= size)
98 return 0;
99
100 word >>= bitno;
101
102 /* If num is 1, we could speed things up with a binary search
103 of the word of interest. */
104
105 if (num >= BITSET_WORD_BITS)
ef017502 106 {
7086e707 107 for (count = 0; word; bitno++)
ef017502 108 {
7086e707 109 if (word & 1)
ef017502 110 list[count++] = bitno;
7086e707 111 word >>= 1;
ef017502
AD
112 }
113 }
7086e707 114 else
ef017502 115 {
7086e707 116 for (count = 0; word; bitno++)
ef017502 117 {
7086e707 118 if (word & 1)
ef017502 119 {
7086e707
AD
120 list[count++] = bitno;
121 if (count >= num)
ef017502 122 {
7086e707
AD
123 bitno++;
124 break;
ef017502
AD
125 }
126 }
7086e707 127 word >>= 1;
ef017502
AD
128 }
129 }
7086e707
AD
130
131 *next = bitno;
132 return count;
133}
134
135
136/* Set bit BITNO in bitset DST. */
137static void
613f5e1a 138abitset_set (dst, bitno)
7086e707
AD
139 bitset dst ATTRIBUTE_UNUSED;
140 bitset_bindex bitno ATTRIBUTE_UNUSED;
141{
6aa452a6
AD
142 /* This should never occur for abitsets since we should always
143 hit the cache. */
ef017502 144 abort ();
7086e707
AD
145}
146
147
148/* Reset bit BITNO in bitset DST. */
149static void
613f5e1a 150abitset_reset (dst, bitno)
7086e707
AD
151 bitset dst ATTRIBUTE_UNUSED;
152 bitset_bindex bitno ATTRIBUTE_UNUSED;
153{
6aa452a6
AD
154 /* This should never occur for abitsets since we should always
155 hit the cache. */
ef017502 156 abort ();
7086e707
AD
157}
158
159
160/* Test bit BITNO in bitset SRC. */
161static int
613f5e1a 162abitset_test (src, bitno)
7086e707
AD
163 bitset src ATTRIBUTE_UNUSED;
164 bitset_bindex bitno ATTRIBUTE_UNUSED;
165{
6aa452a6
AD
166 /* This should never occur for abitsets since we should always
167 hit the cache. */
ef017502
AD
168 abort ();
169 return 0;
7086e707
AD
170}
171
172
173/* Find list of up to NUM bits set in BSET in reverse order, starting
174 from and including NEXT and store in array LIST. Return with
175 actual number of bits found and with *NEXT indicating where search
176 stopped. */
62a34c3e 177static bitset_bindex
6aa452a6 178abitset_list_reverse (src, list, num, next)
7086e707
AD
179 bitset src;
180 bitset_bindex *list;
181 bitset_bindex num;
182 bitset_bindex *next;
183{
184 bitset_bindex bitno;
185 bitset_bindex rbitno;
186 bitset_bindex count;
345cea78 187 bitset_windex windex;
7086e707
AD
188 unsigned int bitcnt;
189 bitset_bindex bitoff;
613f5e1a
AD
190 bitset_word *srcp = ABITSET_WORDS (src);
191 bitset_bindex n_bits = ABITSET_N_BITS (src);
7086e707
AD
192
193 rbitno = *next;
194
195 /* If num is 1, we could speed things up with a binary search
196 of the word of interest. */
197
198 if (rbitno >= n_bits)
ef017502 199 return 0;
7086e707
AD
200
201 count = 0;
202
203 bitno = n_bits - (rbitno + 1);
204
345cea78 205 windex = bitno / BITSET_WORD_BITS;
7086e707 206 bitcnt = bitno % BITSET_WORD_BITS;
345cea78 207 bitoff = windex * BITSET_WORD_BITS;
7086e707 208
d6eba423 209 do
7086e707 210 {
6aa452a6
AD
211 bitset_word word;
212
345cea78 213 word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
7086e707
AD
214 for (; word; bitcnt--)
215 {
216 if (word & BITSET_MSB)
217 {
218 list[count++] = bitoff + bitcnt;
219 if (count >= num)
220 {
221 *next = n_bits - (bitoff + bitcnt);
222 return count;
223 }
224 }
225 word <<= 1;
226 }
d6eba423
PE
227 bitoff -= BITSET_WORD_BITS;
228 bitcnt = BITSET_WORD_BITS - 1;
7086e707 229 }
d6eba423 230 while (windex--);
7086e707
AD
231
232 *next = n_bits - (bitoff + 1);
233 return count;
234}
235
236
237/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
238 *NEXT and store in array LIST. Return with actual number of bits
239 found and with *NEXT indicating where search stopped. */
62a34c3e 240static bitset_bindex
613f5e1a 241abitset_list (src, list, num, next)
7086e707
AD
242 bitset src;
243 bitset_bindex *list;
244 bitset_bindex num;
245 bitset_bindex *next;
246{
247 bitset_bindex bitno;
248 bitset_bindex count;
345cea78 249 bitset_windex windex;
7086e707 250 bitset_bindex bitoff;
ef017502 251 bitset_windex size = src->b.csize;
613f5e1a 252 bitset_word *srcp = ABITSET_WORDS (src);
7086e707
AD
253 bitset_word word;
254
255 bitno = *next;
256
257 count = 0;
ef017502 258 if (!bitno)
7086e707
AD
259 {
260 /* Many bitsets are zero, so make this common case fast. */
345cea78 261 for (windex = 0; windex < size && !srcp[windex]; windex++)
7086e707 262 continue;
345cea78 263 if (windex >= size)
7086e707
AD
264 return 0;
265
266 /* If num is 1, we could speed things up with a binary search
267 of the current word. */
268
345cea78 269 bitoff = windex * BITSET_WORD_BITS;
7086e707
AD
270 }
271 else
272 {
613f5e1a 273 if (bitno >= ABITSET_N_BITS (src))
7086e707
AD
274 return 0;
275
345cea78 276 windex = bitno / BITSET_WORD_BITS;
7086e707
AD
277 bitno = bitno % BITSET_WORD_BITS;
278
279 if (bitno)
280 {
281 /* Handle the case where we start within a word.
282 Most often, this is executed with large bitsets
283 with many set bits where we filled the array
284 on the previous call to this function. */
285
345cea78
AD
286 bitoff = windex * BITSET_WORD_BITS;
287 word = srcp[windex] >> bitno;
7086e707
AD
288 for (bitno = bitoff + bitno; word; bitno++)
289 {
290 if (word & 1)
291 {
292 list[count++] = bitno;
293 if (count >= num)
294 {
295 *next = bitno + 1;
296 return count;
297 }
298 }
299 word >>= 1;
300 }
345cea78 301 windex++;
7086e707 302 }
345cea78 303 bitoff = windex * BITSET_WORD_BITS;
7086e707
AD
304 }
305
345cea78 306 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
7086e707 307 {
345cea78 308 if (!(word = srcp[windex]))
7086e707
AD
309 continue;
310
311 if ((count + BITSET_WORD_BITS) < num)
ef017502
AD
312 {
313 for (bitno = bitoff; word; bitno++)
314 {
315 if (word & 1)
316 list[count++] = bitno;
317 word >>= 1;
318 }
319 }
7086e707
AD
320 else
321 {
322 for (bitno = bitoff; word; bitno++)
323 {
324 if (word & 1)
325 {
326 list[count++] = bitno;
327 if (count >= num)
328 {
329 *next = bitno + 1;
330 return count;
331 }
332 }
333 word >>= 1;
334 }
335 }
336 }
337
338 *next = bitoff;
339 return count;
340}
341
342
343/* Ensure that any unused bits within the last word are clear. */
344static inline void
613f5e1a 345abitset_unused_clear (dst)
7086e707
AD
346 bitset dst;
347{
348 unsigned int last_bit;
349
613f5e1a 350 last_bit = ABITSET_N_BITS (dst) % BITSET_WORD_BITS;
7086e707 351 if (last_bit)
613f5e1a 352 ABITSET_WORDS (dst)[dst->b.csize - 1] &=
d6eba423 353 ((bitset_word) 1 << last_bit) - 1;
7086e707
AD
354}
355
356
6aa452a6
AD
357static void
358abitset_ones (dst)
7086e707 359 bitset dst;
7086e707 360{
613f5e1a 361 bitset_word *dstp = ABITSET_WORDS (dst);
62a34c3e 362 size_t bytes;
7086e707 363
ef017502 364 bytes = sizeof (bitset_word) * dst->b.csize;
7086e707 365
6aa452a6
AD
366 memset (dstp, -1, bytes);
367 abitset_unused_clear (dst);
368}
369
370
371static void
372abitset_zero (dst)
373 bitset dst;
374{
375 bitset_word *dstp = ABITSET_WORDS (dst);
62a34c3e 376 size_t bytes;
6aa452a6
AD
377
378 bytes = sizeof (bitset_word) * dst->b.csize;
379
380 memset (dstp, 0, bytes);
381}
7086e707 382
6aa452a6
AD
383
384static int
385abitset_empty_p (dst)
386 bitset dst;
387{
62a34c3e 388 bitset_windex i;
6aa452a6
AD
389 bitset_word *dstp = ABITSET_WORDS (dst);
390
391 for (i = 0; i < dst->b.csize; i++)
392 if (dstp[i])
393 return 0;
7086e707
AD
394
395 return 1;
396}
397
398
6aa452a6
AD
399static void
400abitset_copy1 (dst, src)
401 bitset dst;
402 bitset src;
403{
404 bitset_word *srcp = ABITSET_WORDS (src);
405 bitset_word *dstp = ABITSET_WORDS (dst);
406 bitset_windex size = dst->b.csize;
407
408 if (srcp == dstp)
409 return;
410 memcpy (dstp, srcp, sizeof (bitset_word) * size);
411}
412
413
414static void
415abitset_not (dst, src)
416 bitset dst;
417 bitset src;
418{
62a34c3e 419 bitset_windex i;
6aa452a6
AD
420 bitset_word *srcp = ABITSET_WORDS (src);
421 bitset_word *dstp = ABITSET_WORDS (dst);
422 bitset_windex size = dst->b.csize;
423
424 for (i = 0; i < size; i++)
425 *dstp++ = ~(*srcp++);
426 abitset_unused_clear (dst);
427}
428
429
7086e707 430static int
6aa452a6 431abitset_equal_p (dst, src)
7086e707
AD
432 bitset dst;
433 bitset src;
7086e707 434{
62a34c3e 435 bitset_windex i;
613f5e1a
AD
436 bitset_word *srcp = ABITSET_WORDS (src);
437 bitset_word *dstp = ABITSET_WORDS (dst);
ef017502 438 bitset_windex size = dst->b.csize;
7086e707 439
6aa452a6
AD
440 for (i = 0; i < size; i++)
441 if (*srcp++ != *dstp++)
7086e707 442 return 0;
6aa452a6
AD
443 return 1;
444}
445
446
447static int
448abitset_subset_p (dst, src)
449 bitset dst;
450 bitset src;
451{
62a34c3e 452 bitset_windex i;
6aa452a6
AD
453 bitset_word *srcp = ABITSET_WORDS (src);
454 bitset_word *dstp = ABITSET_WORDS (dst);
455 bitset_windex size = dst->b.csize;
456
457 for (i = 0; i < size; i++, dstp++, srcp++)
458 if (*dstp != (*srcp | *dstp))
ef017502 459 return 0;
6aa452a6
AD
460 return 1;
461}
462
463
464static int
465abitset_disjoint_p (dst, src)
466 bitset dst;
467 bitset src;
468{
62a34c3e 469 bitset_windex i;
6aa452a6
AD
470 bitset_word *srcp = ABITSET_WORDS (src);
471 bitset_word *dstp = ABITSET_WORDS (dst);
472 bitset_windex size = dst->b.csize;
473
474 for (i = 0; i < size; i++)
475 if (*srcp++ & *dstp++)
ef017502 476 return 0;
7086e707
AD
477
478 return 1;
479}
480
481
6aa452a6
AD
482static void
483abitset_and (dst, src1, src2)
484 bitset dst;
485 bitset src1;
486 bitset src2;
487{
62a34c3e 488 bitset_windex i;
6aa452a6
AD
489 bitset_word *src1p = ABITSET_WORDS (src1);
490 bitset_word *src2p = ABITSET_WORDS (src2);
491 bitset_word *dstp = ABITSET_WORDS (dst);
492 bitset_windex size = dst->b.csize;
493
494 for (i = 0; i < size; i++)
495 *dstp++ = *src1p++ & *src2p++;
496}
497
498
7086e707 499static int
6aa452a6 500abitset_and_cmp (dst, src1, src2)
7086e707
AD
501 bitset dst;
502 bitset src1;
503 bitset src2;
7086e707 504{
62a34c3e 505 bitset_windex i;
7086e707 506 int changed = 0;
613f5e1a
AD
507 bitset_word *src1p = ABITSET_WORDS (src1);
508 bitset_word *src2p = ABITSET_WORDS (src2);
509 bitset_word *dstp = ABITSET_WORDS (dst);
ef017502 510 bitset_windex size = dst->b.csize;
7086e707 511
6aa452a6 512 for (i = 0; i < size; i++, dstp++)
7086e707 513 {
6aa452a6
AD
514 bitset_word tmp = *src1p++ & *src2p++;
515
516 if (*dstp != tmp)
7086e707 517 {
6aa452a6
AD
518 changed = 1;
519 *dstp = tmp;
7086e707 520 }
6aa452a6
AD
521 }
522 return changed;
523}
7086e707 524
7086e707 525
6aa452a6
AD
526static void
527abitset_andn (dst, src1, src2)
528 bitset dst;
529 bitset src1;
530 bitset src2;
531{
62a34c3e 532 bitset_windex i;
6aa452a6
AD
533 bitset_word *src1p = ABITSET_WORDS (src1);
534 bitset_word *src2p = ABITSET_WORDS (src2);
535 bitset_word *dstp = ABITSET_WORDS (dst);
536 bitset_windex size = dst->b.csize;
7086e707 537
6aa452a6
AD
538 for (i = 0; i < size; i++)
539 *dstp++ = *src1p++ & ~(*src2p++);
540}
7086e707 541
7086e707 542
6aa452a6
AD
543static int
544abitset_andn_cmp (dst, src1, src2)
545 bitset dst;
546 bitset src1;
547 bitset src2;
548{
62a34c3e 549 bitset_windex i;
6aa452a6
AD
550 int changed = 0;
551 bitset_word *src1p = ABITSET_WORDS (src1);
552 bitset_word *src2p = ABITSET_WORDS (src2);
553 bitset_word *dstp = ABITSET_WORDS (dst);
554 bitset_windex size = dst->b.csize;
555
556 for (i = 0; i < size; i++, dstp++)
557 {
558 bitset_word tmp = *src1p++ & ~(*src2p++);
559
560 if (*dstp != tmp)
7086e707 561 {
6aa452a6
AD
562 changed = 1;
563 *dstp = tmp;
7086e707 564 }
6aa452a6
AD
565 }
566 return changed;
567}
568
569
570static void
571abitset_or (dst, src1, src2)
572 bitset dst;
573 bitset src1;
574 bitset src2;
575{
62a34c3e 576 bitset_windex i;
6aa452a6
AD
577 bitset_word *src1p = ABITSET_WORDS (src1);
578 bitset_word *src2p = ABITSET_WORDS (src2);
579 bitset_word *dstp = ABITSET_WORDS (dst);
580 bitset_windex size = dst->b.csize;
581
582 for (i = 0; i < size; i++)
583 *dstp++ = *src1p++ | *src2p++;
584}
585
7086e707 586
6aa452a6
AD
587static int
588abitset_or_cmp (dst, src1, src2)
589 bitset dst;
590 bitset src1;
591 bitset src2;
592{
62a34c3e 593 bitset_windex i;
6aa452a6
AD
594 int changed = 0;
595 bitset_word *src1p = ABITSET_WORDS (src1);
596 bitset_word *src2p = ABITSET_WORDS (src2);
597 bitset_word *dstp = ABITSET_WORDS (dst);
598 bitset_windex size = dst->b.csize;
599
600 for (i = 0; i < size; i++, dstp++)
601 {
602 bitset_word tmp = *src1p++ | *src2p++;
603
604 if (*dstp != tmp)
605 {
606 changed = 1;
607 *dstp = tmp;
608 }
7086e707 609 }
6aa452a6
AD
610 return changed;
611}
7086e707 612
6aa452a6
AD
613
614static void
615abitset_xor (dst, src1, src2)
616 bitset dst;
617 bitset src1;
618 bitset src2;
619{
62a34c3e 620 bitset_windex i;
6aa452a6
AD
621 bitset_word *src1p = ABITSET_WORDS (src1);
622 bitset_word *src2p = ABITSET_WORDS (src2);
623 bitset_word *dstp = ABITSET_WORDS (dst);
624 bitset_windex size = dst->b.csize;
625
626 for (i = 0; i < size; i++)
627 *dstp++ = *src1p++ ^ *src2p++;
628}
629
630
631static int
632abitset_xor_cmp (dst, src1, src2)
633 bitset dst;
634 bitset src1;
635 bitset src2;
636{
62a34c3e 637 bitset_windex i;
6aa452a6
AD
638 int changed = 0;
639 bitset_word *src1p = ABITSET_WORDS (src1);
640 bitset_word *src2p = ABITSET_WORDS (src2);
641 bitset_word *dstp = ABITSET_WORDS (dst);
642 bitset_windex size = dst->b.csize;
643
644 for (i = 0; i < size; i++, dstp++)
645 {
646 bitset_word tmp = *src1p++ ^ *src2p++;
647
648 if (*dstp != tmp)
649 {
650 changed = 1;
651 *dstp = tmp;
652 }
653 }
7086e707
AD
654 return changed;
655}
656
657
6aa452a6
AD
658static void
659abitset_and_or (dst, src1, src2, src3)
660 bitset dst;
661 bitset src1;
662 bitset src2;
663 bitset src3;
664{
62a34c3e 665 bitset_windex i;
6aa452a6
AD
666 bitset_word *src1p = ABITSET_WORDS (src1);
667 bitset_word *src2p = ABITSET_WORDS (src2);
668 bitset_word *src3p = ABITSET_WORDS (src3);
669 bitset_word *dstp = ABITSET_WORDS (dst);
670 bitset_windex size = dst->b.csize;
671
672 for (i = 0; i < size; i++)
673 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
674}
675
676
7086e707 677static int
6aa452a6 678abitset_and_or_cmp (dst, src1, src2, src3)
7086e707
AD
679 bitset dst;
680 bitset src1;
681 bitset src2;
682 bitset src3;
7086e707 683{
62a34c3e 684 bitset_windex i;
7086e707 685 int changed = 0;
613f5e1a
AD
686 bitset_word *src1p = ABITSET_WORDS (src1);
687 bitset_word *src2p = ABITSET_WORDS (src2);
688 bitset_word *src3p = ABITSET_WORDS (src3);
689 bitset_word *dstp = ABITSET_WORDS (dst);
ef017502 690 bitset_windex size = dst->b.csize;
6aa452a6
AD
691
692 for (i = 0; i < size; i++, dstp++)
7086e707 693 {
6aa452a6
AD
694 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
695
696 if (*dstp != tmp)
7086e707 697 {
6aa452a6
AD
698 changed = 1;
699 *dstp = tmp;
7086e707 700 }
6aa452a6
AD
701 }
702 return changed;
703}
7086e707 704
7086e707 705
6aa452a6
AD
706static void
707abitset_andn_or (dst, src1, src2, src3)
708 bitset dst;
709 bitset src1;
710 bitset src2;
711 bitset src3;
712{
62a34c3e 713 bitset_windex i;
6aa452a6
AD
714 bitset_word *src1p = ABITSET_WORDS (src1);
715 bitset_word *src2p = ABITSET_WORDS (src2);
716 bitset_word *src3p = ABITSET_WORDS (src3);
717 bitset_word *dstp = ABITSET_WORDS (dst);
718 bitset_windex size = dst->b.csize;
719
720 for (i = 0; i < size; i++)
721 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
722}
7086e707 723
7086e707 724
6aa452a6
AD
725static int
726abitset_andn_or_cmp (dst, src1, src2, src3)
727 bitset dst;
728 bitset src1;
729 bitset src2;
730 bitset src3;
731{
62a34c3e 732 bitset_windex i;
6aa452a6
AD
733 int changed = 0;
734 bitset_word *src1p = ABITSET_WORDS (src1);
735 bitset_word *src2p = ABITSET_WORDS (src2);
736 bitset_word *src3p = ABITSET_WORDS (src3);
737 bitset_word *dstp = ABITSET_WORDS (dst);
738 bitset_windex size = dst->b.csize;
739
740 for (i = 0; i < size; i++, dstp++)
741 {
742 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
743
744 if (*dstp != tmp)
745 {
746 changed = 1;
747 *dstp = tmp;
7086e707 748 }
7086e707 749 }
6aa452a6
AD
750 return changed;
751}
752
753
754static void
755abitset_or_and (dst, src1, src2, src3)
756 bitset dst;
757 bitset src1;
758 bitset src2;
759 bitset src3;
760{
62a34c3e 761 bitset_windex i;
6aa452a6
AD
762 bitset_word *src1p = ABITSET_WORDS (src1);
763 bitset_word *src2p = ABITSET_WORDS (src2);
764 bitset_word *src3p = ABITSET_WORDS (src3);
765 bitset_word *dstp = ABITSET_WORDS (dst);
766 bitset_windex size = dst->b.csize;
767
768 for (i = 0; i < size; i++)
769 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
770}
771
7086e707 772
6aa452a6
AD
773static int
774abitset_or_and_cmp (dst, src1, src2, src3)
775 bitset dst;
776 bitset src1;
777 bitset src2;
778 bitset src3;
779{
62a34c3e 780 bitset_windex i;
6aa452a6
AD
781 int changed = 0;
782 bitset_word *src1p = ABITSET_WORDS (src1);
783 bitset_word *src2p = ABITSET_WORDS (src2);
784 bitset_word *src3p = ABITSET_WORDS (src3);
785 bitset_word *dstp = ABITSET_WORDS (dst);
786 bitset_windex size = dst->b.csize;
787
788 for (i = 0; i < size; i++, dstp++)
789 {
790 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
791
792 if (*dstp != tmp)
793 {
794 changed = 1;
795 *dstp = tmp;
796 }
797 }
7086e707
AD
798 return changed;
799}
800
801
6aa452a6
AD
802void
803abitset_copy (dst, src)
804 bitset dst;
805 bitset src;
806{
807 if (BITSET_COMPATIBLE_ (dst, src))
808 abitset_copy1 (dst, src);
809 else
810 bitset_copy_ (dst, src);
811}
812
813
7086e707 814/* Vector of operations for single word bitsets. */
6aa452a6 815struct bitset_vtable abitset_small_vtable = {
613f5e1a
AD
816 abitset_set,
817 abitset_reset,
6aa452a6 818 bitset_toggle_,
613f5e1a
AD
819 abitset_test,
820 abitset_size,
6aa452a6
AD
821 bitset_count_,
822 abitset_empty_p,
823 abitset_ones,
824 abitset_zero,
825 abitset_copy,
826 abitset_disjoint_p,
827 abitset_equal_p,
828 abitset_not,
829 abitset_subset_p,
830 abitset_and,
831 abitset_and_cmp,
832 abitset_andn,
833 abitset_andn_cmp,
834 abitset_or,
835 abitset_or_cmp,
836 abitset_xor,
837 abitset_xor_cmp,
838 abitset_and_or,
839 abitset_and_or_cmp,
840 abitset_andn_or,
841 abitset_andn_or_cmp,
842 abitset_or_and,
843 abitset_or_and_cmp,
613f5e1a 844 abitset_small_list,
6aa452a6 845 abitset_list_reverse,
ef017502
AD
846 NULL,
847 BITSET_ARRAY
848};
7086e707
AD
849
850
851/* Vector of operations for multiple word bitsets. */
6aa452a6 852struct bitset_vtable abitset_vtable = {
613f5e1a
AD
853 abitset_set,
854 abitset_reset,
6aa452a6 855 bitset_toggle_,
613f5e1a
AD
856 abitset_test,
857 abitset_size,
6aa452a6
AD
858 bitset_count_,
859 abitset_empty_p,
860 abitset_ones,
861 abitset_zero,
862 abitset_copy,
863 abitset_disjoint_p,
864 abitset_equal_p,
865 abitset_not,
866 abitset_subset_p,
867 abitset_and,
868 abitset_and_cmp,
869 abitset_andn,
870 abitset_andn_cmp,
871 abitset_or,
872 abitset_or_cmp,
873 abitset_xor,
874 abitset_xor_cmp,
875 abitset_and_or,
876 abitset_and_or_cmp,
877 abitset_andn_or,
878 abitset_andn_or_cmp,
879 abitset_or_and,
880 abitset_or_and_cmp,
613f5e1a 881 abitset_list,
6aa452a6 882 abitset_list_reverse,
ef017502
AD
883 NULL,
884 BITSET_ARRAY
7086e707
AD
885};
886
887
62a34c3e 888size_t
613f5e1a 889abitset_bytes (n_bits)
7086e707
AD
890 bitset_bindex n_bits;
891{
62a34c3e
PE
892 bitset_windex size;
893 size_t bytes;
7086e707 894
613f5e1a 895 size = ABITSET_N_WORDS (n_bits);
7086e707
AD
896 bytes = size * sizeof (bitset_word);
897 return sizeof (struct bitset_struct) + bytes - sizeof (bitset_word);
898}
899
900
901bitset
613f5e1a 902abitset_init (bset, n_bits)
7086e707
AD
903 bitset bset;
904 bitset_bindex n_bits;
905{
906 bitset_windex size;
907
613f5e1a
AD
908 size = ABITSET_N_WORDS (n_bits);
909 ABITSET_N_BITS (bset) = n_bits;
7086e707
AD
910
911 /* Use optimized routines if bitset fits within a single word.
912 There is probably little merit if using caching since
913 the small bitset will always fit in the cache. */
914 if (size == 1)
6aa452a6 915 bset->b.vtable = &abitset_small_vtable;
7086e707 916 else
6aa452a6 917 bset->b.vtable = &abitset_vtable;
7086e707 918
ef017502
AD
919 bset->b.cindex = 0;
920 bset->b.csize = size;
613f5e1a 921 bset->b.cdata = ABITSET_WORDS (bset);
7086e707
AD
922 return bset;
923}