]>
Commit | Line | Data |
---|---|---|
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 | 31 | typedef 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 | ||
39 | struct bitset_struct | |
40 | { | |
41 | struct bbitset_struct b; | |
613f5e1a | 42 | struct abitset_struct a; |
ef017502 AD |
43 | }; |
44 | ||
613f5e1a | 45 | static void abitset_unused_clear PARAMS ((bitset)); |
ef017502 | 46 | |
62a34c3e PE |
47 | static bitset_bindex abitset_small_list PARAMS ((bitset, bitset_bindex *, |
48 | bitset_bindex, | |
49 | bitset_bindex *)); | |
ef017502 | 50 | |
613f5e1a AD |
51 | static void abitset_set PARAMS ((bitset, bitset_bindex)); |
52 | static void abitset_reset PARAMS ((bitset, bitset_bindex)); | |
53 | static int abitset_test PARAMS ((bitset, bitset_bindex)); | |
62a34c3e PE |
54 | static bitset_bindex abitset_size PARAMS ((bitset)); |
55 | static bitset_bindex abitset_list PARAMS ((bitset, bitset_bindex *, | |
56 | bitset_bindex, bitset_bindex *)); | |
57 | static bitset_bindex abitset_list_reverse | |
ef017502 | 58 | PARAMS ((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 | 66 | static bitset_bindex |
613f5e1a | 67 | abitset_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 | 77 | static bitset_bindex |
613f5e1a | 78 | abitset_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. */ | |
137 | static void | |
613f5e1a | 138 | abitset_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. */ | |
149 | static void | |
613f5e1a | 150 | abitset_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. */ | |
161 | static int | |
613f5e1a | 162 | abitset_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 | 177 | static bitset_bindex |
6aa452a6 | 178 | abitset_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 | 240 | static bitset_bindex |
613f5e1a | 241 | abitset_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. */ | |
344 | static inline void | |
613f5e1a | 345 | abitset_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 |
357 | static void |
358 | abitset_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 | ||
371 | static void | |
372 | abitset_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 | |
384 | static int | |
385 | abitset_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 |
399 | static void |
400 | abitset_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 | ||
414 | static void | |
415 | abitset_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 | 430 | static int |
6aa452a6 | 431 | abitset_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 | ||
447 | static int | |
448 | abitset_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 | ||
464 | static int | |
465 | abitset_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 |
482 | static void |
483 | abitset_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 | 499 | static int |
6aa452a6 | 500 | abitset_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 |
526 | static void |
527 | abitset_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 |
543 | static int |
544 | abitset_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 | ||
570 | static void | |
571 | abitset_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 |
587 | static int |
588 | abitset_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 | |
614 | static void | |
615 | abitset_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 | ||
631 | static int | |
632 | abitset_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 |
658 | static void |
659 | abitset_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 | 677 | static int |
6aa452a6 | 678 | abitset_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 |
706 | static void |
707 | abitset_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 |
725 | static int |
726 | abitset_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 | ||
754 | static void | |
755 | abitset_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 |
773 | static int |
774 | abitset_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 |
802 | void |
803 | abitset_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 | 815 | struct 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 | 852 | struct 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 | 888 | size_t |
613f5e1a | 889 | abitset_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 | ||
901 | bitset | |
613f5e1a | 902 | abitset_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 | } |