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