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