]>
Commit | Line | Data |
---|---|---|
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 | 36 | static bitset_bindex |
eaef5507 PE |
37 | abitset_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 | 50 | static bitset_bindex |
a911db9c PE |
51 | abitset_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. */ | |
107 | static void | |
a911db9c | 108 | abitset_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. */ | |
118 | static void | |
a911db9c PE |
119 | abitset_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 | 129 | static bool |
a911db9c PE |
130 | abitset_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 | 143 | static bitset_bindex |
a911db9c PE |
144 | abitset_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 | 203 | static bitset_bindex |
a911db9c PE |
204 | abitset_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. */ | |
304 | static inline void | |
a911db9c | 305 | abitset_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 | 316 | static void |
a911db9c | 317 | abitset_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 | ||
329 | static void | |
a911db9c | 330 | abitset_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 | 341 | static bool |
a911db9c | 342 | abitset_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 | 355 | static void |
a911db9c | 356 | abitset_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 | ||
368 | static void | |
a911db9c | 369 | abitset_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 | 382 | static bool |
a911db9c | 383 | abitset_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 | 397 | static bool |
a911db9c | 398 | abitset_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 | 412 | static bool |
a911db9c | 413 | abitset_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 | 428 | static void |
a911db9c | 429 | abitset_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 | 442 | static bool |
a911db9c | 443 | abitset_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 | 466 | static void |
a911db9c | 467 | abitset_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 | 480 | static bool |
a911db9c | 481 | abitset_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 | ||
504 | static void | |
a911db9c | 505 | abitset_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 | 518 | static bool |
a911db9c | 519 | abitset_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 | |
542 | static void | |
a911db9c | 543 | abitset_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 | 556 | static bool |
a911db9c | 557 | abitset_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 | 580 | static void |
a911db9c | 581 | abitset_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 | 595 | static bool |
a911db9c | 596 | abitset_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 | 620 | static void |
a911db9c | 621 | abitset_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 | 635 | static bool |
a911db9c | 636 | abitset_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 | ||
660 | static void | |
a911db9c | 661 | abitset_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 | 675 | static bool |
a911db9c | 676 | abitset_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 | 700 | static void |
a911db9c | 701 | abitset_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 | 711 | struct 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 | 749 | struct 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 | 786 | size_t |
a911db9c | 787 | abitset_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 | ||
810 | bitset | |
a911db9c | 811 | abitset_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 | } |