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