vbitset.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. /* Variable array bitsets.
  2. Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc.
  3. Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #include <config.h>
  15. #include "vbitset.h"
  16. #include <stdlib.h>
  17. #include <string.h>
  18. /* This file implements variable size bitsets stored as a variable
  19. length array of words. Any unused bits in the last word must be
  20. zero.
  21. Note that binary or ternary operations assume that each bitset operand
  22. has the same size.
  23. */
  24. static void vbitset_unused_clear (bitset);
  25. static void vbitset_set (bitset, bitset_bindex);
  26. static void vbitset_reset (bitset, bitset_bindex);
  27. static bool vbitset_test (bitset, bitset_bindex);
  28. static bitset_bindex vbitset_list (bitset, bitset_bindex *,
  29. bitset_bindex, bitset_bindex *);
  30. static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
  31. bitset_bindex, bitset_bindex *);
  32. #define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
  33. #define VBITSET_WORDS(X) ((X)->b.cdata)
  34. #define VBITSET_SIZE(X) ((X)->b.csize)
  35. #define VBITSET_ASIZE(X) ((X)->v.size)
  36. #undef min
  37. #undef max
  38. #define min(a, b) ((a) > (b) ? (b) : (a))
  39. #define max(a, b) ((a) > (b) ? (a) : (b))
  40. static bitset_bindex
  41. vbitset_resize (bitset src, bitset_bindex n_bits)
  42. {
  43. bitset_windex oldsize;
  44. bitset_windex newsize;
  45. if (n_bits == BITSET_NBITS_ (src))
  46. return n_bits;
  47. oldsize = VBITSET_SIZE (src);
  48. newsize = VBITSET_N_WORDS (n_bits);
  49. if (oldsize < newsize)
  50. {
  51. bitset_windex size;
  52. /* The bitset needs to grow. If we already have enough memory
  53. allocated, then just zero what we need. */
  54. if (newsize > VBITSET_ASIZE (src))
  55. {
  56. /* We need to allocate more memory. When oldsize is
  57. non-zero this means that we are changing the size, so
  58. grow the bitset 25% larger than requested to reduce
  59. number of reallocations. */
  60. if (oldsize == 0)
  61. size = newsize;
  62. else
  63. size = newsize + newsize / 4;
  64. VBITSET_WORDS (src)
  65. = realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
  66. VBITSET_ASIZE (src) = size;
  67. }
  68. memset (VBITSET_WORDS (src) + oldsize, 0,
  69. (newsize - oldsize) * sizeof (bitset_word));
  70. VBITSET_SIZE (src) = newsize;
  71. }
  72. else
  73. {
  74. /* The bitset needs to shrink. There's no point deallocating
  75. the memory unless it is shrinking by a reasonable amount. */
  76. if ((oldsize - newsize) >= oldsize / 2)
  77. {
  78. VBITSET_WORDS (src)
  79. = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
  80. VBITSET_ASIZE (src) = newsize;
  81. }
  82. /* Need to prune any excess bits. FIXME. */
  83. VBITSET_SIZE (src) = newsize;
  84. }
  85. BITSET_NBITS_ (src) = n_bits;
  86. return n_bits;
  87. }
  88. /* Set bit BITNO in bitset DST. */
  89. static void
  90. vbitset_set (dst, bitno)
  91. bitset dst;
  92. bitset_bindex bitno;
  93. {
  94. bitset_windex windex = bitno / BITSET_WORD_BITS;
  95. /* Perhaps we should abort. The user should explicitly call
  96. bitset_resize since this will not catch the case when we set a
  97. bit larger than the current size but smaller than the allocated
  98. size. */
  99. vbitset_resize (dst, bitno);
  100. dst->b.cdata[windex - dst->b.cindex] |=
  101. (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
  102. }
  103. /* Reset bit BITNO in bitset DST. */
  104. static void
  105. vbitset_reset (dst, bitno)
  106. bitset dst ATTRIBUTE_UNUSED;
  107. bitset_bindex bitno ATTRIBUTE_UNUSED;
  108. {
  109. /* We must be accessing outside the cache so the bit is
  110. zero anyway. */
  111. }
  112. /* Test bit BITNO in bitset SRC. */
  113. static bool
  114. vbitset_test (src, bitno)
  115. bitset src ATTRIBUTE_UNUSED;
  116. bitset_bindex bitno ATTRIBUTE_UNUSED;
  117. {
  118. /* We must be accessing outside the cache so the bit is
  119. zero anyway. */
  120. return 0;
  121. }
  122. /* Find list of up to NUM bits set in BSET in reverse order, starting
  123. from and including NEXT and store in array LIST. Return with
  124. actual number of bits found and with *NEXT indicating where search
  125. stopped. */
  126. static bitset_bindex
  127. vbitset_list_reverse (src, list, num, next)
  128. bitset src;
  129. bitset_bindex *list;
  130. bitset_bindex num;
  131. bitset_bindex *next;
  132. {
  133. bitset_bindex bitno;
  134. bitset_bindex rbitno;
  135. bitset_bindex count;
  136. bitset_windex windex;
  137. unsigned int bitcnt;
  138. bitset_bindex bitoff;
  139. bitset_word *srcp = VBITSET_WORDS (src);
  140. bitset_bindex n_bits = BITSET_SIZE_ (src);
  141. rbitno = *next;
  142. /* If num is 1, we could speed things up with a binary search
  143. of the word of interest. */
  144. if (rbitno >= n_bits)
  145. return 0;
  146. count = 0;
  147. bitno = n_bits - (rbitno + 1);
  148. windex = bitno / BITSET_WORD_BITS;
  149. bitcnt = bitno % BITSET_WORD_BITS;
  150. bitoff = windex * BITSET_WORD_BITS;
  151. do
  152. {
  153. bitset_word word;
  154. word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
  155. for (; word; bitcnt--)
  156. {
  157. if (word & BITSET_MSB)
  158. {
  159. list[count++] = bitoff + bitcnt;
  160. if (count >= num)
  161. {
  162. *next = n_bits - (bitoff + bitcnt);
  163. return count;
  164. }
  165. }
  166. word <<= 1;
  167. }
  168. bitoff -= BITSET_WORD_BITS;
  169. bitcnt = BITSET_WORD_BITS - 1;
  170. }
  171. while (windex--);
  172. *next = n_bits - (bitoff + 1);
  173. return count;
  174. }
  175. /* Find list of up to NUM bits set in BSET starting from and including
  176. *NEXT and store in array LIST. Return with actual number of bits
  177. found and with *NEXT indicating where search stopped. */
  178. static bitset_bindex
  179. vbitset_list (src, list, num, next)
  180. bitset src;
  181. bitset_bindex *list;
  182. bitset_bindex num;
  183. bitset_bindex *next;
  184. {
  185. bitset_bindex bitno;
  186. bitset_bindex count;
  187. bitset_windex windex;
  188. bitset_bindex bitoff;
  189. bitset_windex size = VBITSET_SIZE (src);
  190. bitset_word *srcp = VBITSET_WORDS (src);
  191. bitset_word word;
  192. bitno = *next;
  193. count = 0;
  194. if (!bitno)
  195. {
  196. /* Many bitsets are zero, so make this common case fast. */
  197. for (windex = 0; windex < size && !srcp[windex]; windex++)
  198. continue;
  199. if (windex >= size)
  200. return 0;
  201. /* If num is 1, we could speed things up with a binary search
  202. of the current word. */
  203. bitoff = windex * BITSET_WORD_BITS;
  204. }
  205. else
  206. {
  207. if (bitno >= BITSET_SIZE_ (src))
  208. return 0;
  209. windex = bitno / BITSET_WORD_BITS;
  210. bitno = bitno % BITSET_WORD_BITS;
  211. if (bitno)
  212. {
  213. /* Handle the case where we start within a word.
  214. Most often, this is executed with large bitsets
  215. with many set bits where we filled the array
  216. on the previous call to this function. */
  217. bitoff = windex * BITSET_WORD_BITS;
  218. word = srcp[windex] >> bitno;
  219. for (bitno = bitoff + bitno; word; bitno++)
  220. {
  221. if (word & 1)
  222. {
  223. list[count++] = bitno;
  224. if (count >= num)
  225. {
  226. *next = bitno + 1;
  227. return count;
  228. }
  229. }
  230. word >>= 1;
  231. }
  232. windex++;
  233. }
  234. bitoff = windex * BITSET_WORD_BITS;
  235. }
  236. for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
  237. {
  238. if (!(word = srcp[windex]))
  239. continue;
  240. if ((count + BITSET_WORD_BITS) < num)
  241. {
  242. for (bitno = bitoff; word; bitno++)
  243. {
  244. if (word & 1)
  245. list[count++] = bitno;
  246. word >>= 1;
  247. }
  248. }
  249. else
  250. {
  251. for (bitno = bitoff; word; bitno++)
  252. {
  253. if (word & 1)
  254. {
  255. list[count++] = bitno;
  256. if (count >= num)
  257. {
  258. *next = bitno + 1;
  259. return count;
  260. }
  261. }
  262. word >>= 1;
  263. }
  264. }
  265. }
  266. *next = bitoff;
  267. return count;
  268. }
  269. /* Ensure that any unused bits within the last word are clear. */
  270. static inline void
  271. vbitset_unused_clear (dst)
  272. bitset dst;
  273. {
  274. unsigned int last_bit;
  275. last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
  276. if (last_bit)
  277. VBITSET_WORDS (dst)[VBITSET_SIZE (dst) - 1] &=
  278. ((bitset_word) 1 << last_bit) - 1;
  279. }
  280. static void
  281. vbitset_ones (bitset dst)
  282. {
  283. bitset_word *dstp = VBITSET_WORDS (dst);
  284. unsigned int bytes;
  285. bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
  286. memset (dstp, -1, bytes);
  287. vbitset_unused_clear (dst);
  288. }
  289. static void
  290. vbitset_zero (bitset dst)
  291. {
  292. bitset_word *dstp = VBITSET_WORDS (dst);
  293. unsigned int bytes;
  294. bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
  295. memset (dstp, 0, bytes);
  296. }
  297. static bool
  298. vbitset_empty_p (bitset dst)
  299. {
  300. unsigned int i;
  301. bitset_word *dstp = VBITSET_WORDS (dst);
  302. for (i = 0; i < VBITSET_SIZE (dst); i++)
  303. if (dstp[i])
  304. return 0;
  305. return 1;
  306. }
  307. static void
  308. vbitset_copy1 (bitset dst, bitset src)
  309. {
  310. bitset_word *srcp;
  311. bitset_word *dstp;
  312. bitset_windex ssize;
  313. bitset_windex dsize;
  314. if (src == dst)
  315. return;
  316. vbitset_resize (dst, BITSET_SIZE_ (src));
  317. srcp = VBITSET_WORDS (src);
  318. dstp = VBITSET_WORDS (dst);
  319. ssize = VBITSET_SIZE (src);
  320. dsize = VBITSET_SIZE (dst);
  321. memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
  322. memset (dstp + sizeof (bitset_word) * ssize, 0,
  323. sizeof (bitset_word) * (dsize - ssize));
  324. }
  325. static void
  326. vbitset_not (bitset dst, bitset src)
  327. {
  328. unsigned int i;
  329. bitset_word *srcp;
  330. bitset_word *dstp;
  331. bitset_windex ssize;
  332. bitset_windex dsize;
  333. vbitset_resize (dst, BITSET_SIZE_ (src));
  334. srcp = VBITSET_WORDS (src);
  335. dstp = VBITSET_WORDS (dst);
  336. ssize = VBITSET_SIZE (src);
  337. dsize = VBITSET_SIZE (dst);
  338. for (i = 0; i < ssize; i++)
  339. *dstp++ = ~(*srcp++);
  340. vbitset_unused_clear (dst);
  341. memset (dstp + sizeof (bitset_word) * ssize, 0,
  342. sizeof (bitset_word) * (dsize - ssize));
  343. }
  344. static bool
  345. vbitset_equal_p (bitset dst, bitset src)
  346. {
  347. unsigned int i;
  348. bitset_word *srcp = VBITSET_WORDS (src);
  349. bitset_word *dstp = VBITSET_WORDS (dst);
  350. bitset_windex ssize = VBITSET_SIZE (src);
  351. bitset_windex dsize = VBITSET_SIZE (dst);
  352. for (i = 0; i < min (ssize, dsize); i++)
  353. if (*srcp++ != *dstp++)
  354. return 0;
  355. if (ssize > dsize)
  356. {
  357. for (; i < ssize; i++)
  358. if (*srcp++)
  359. return 0;
  360. }
  361. else
  362. {
  363. for (; i < dsize; i++)
  364. if (*dstp++)
  365. return 0;
  366. }
  367. return 1;
  368. }
  369. static bool
  370. vbitset_subset_p (bitset dst, bitset src)
  371. {
  372. unsigned int i;
  373. bitset_word *srcp = VBITSET_WORDS (src);
  374. bitset_word *dstp = VBITSET_WORDS (dst);
  375. bitset_windex ssize = VBITSET_SIZE (src);
  376. bitset_windex dsize = VBITSET_SIZE (dst);
  377. for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
  378. if (*dstp != (*srcp | *dstp))
  379. return 0;
  380. if (ssize > dsize)
  381. {
  382. for (; i < ssize; i++)
  383. if (*srcp++)
  384. return 0;
  385. }
  386. return 1;
  387. }
  388. static bool
  389. vbitset_disjoint_p (bitset dst, bitset src)
  390. {
  391. unsigned int i;
  392. bitset_word *srcp = VBITSET_WORDS (src);
  393. bitset_word *dstp = VBITSET_WORDS (dst);
  394. bitset_windex ssize = VBITSET_SIZE (src);
  395. bitset_windex dsize = VBITSET_SIZE (dst);
  396. for (i = 0; i < min (ssize, dsize); i++)
  397. if (*srcp++ & *dstp++)
  398. return 0;
  399. return 1;
  400. }
  401. static void
  402. vbitset_and (bitset dst, bitset src1, bitset src2)
  403. {
  404. unsigned int i;
  405. bitset_word *src1p;
  406. bitset_word *src2p;
  407. bitset_word *dstp;
  408. bitset_windex ssize1;
  409. bitset_windex ssize2;
  410. bitset_windex dsize;
  411. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  412. dsize = VBITSET_SIZE (dst);
  413. ssize1 = VBITSET_SIZE (src1);
  414. ssize2 = VBITSET_SIZE (src2);
  415. dstp = VBITSET_WORDS (dst);
  416. src1p = VBITSET_WORDS (src1);
  417. src2p = VBITSET_WORDS (src2);
  418. for (i = 0; i < min (ssize1, ssize2); i++)
  419. *dstp++ = *src1p++ & *src2p++;
  420. memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
  421. }
  422. static bool
  423. vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
  424. {
  425. unsigned int i;
  426. int changed = 0;
  427. bitset_word *src1p;
  428. bitset_word *src2p;
  429. bitset_word *dstp;
  430. bitset_windex ssize1;
  431. bitset_windex ssize2;
  432. bitset_windex dsize;
  433. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  434. dsize = VBITSET_SIZE (dst);
  435. ssize1 = VBITSET_SIZE (src1);
  436. ssize2 = VBITSET_SIZE (src2);
  437. dstp = VBITSET_WORDS (dst);
  438. src1p = VBITSET_WORDS (src1);
  439. src2p = VBITSET_WORDS (src2);
  440. for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
  441. {
  442. bitset_word tmp = *src1p++ & *src2p++;
  443. if (*dstp != tmp)
  444. {
  445. changed = 1;
  446. *dstp = tmp;
  447. }
  448. }
  449. if (ssize2 > ssize1)
  450. {
  451. src1p = src2p;
  452. ssize1 = ssize2;
  453. }
  454. for (; i < ssize1; i++, dstp++)
  455. {
  456. if (*dstp != 0)
  457. {
  458. changed = 1;
  459. *dstp = 0;
  460. }
  461. }
  462. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  463. return changed;
  464. }
  465. static void
  466. vbitset_andn (bitset dst, bitset src1, bitset src2)
  467. {
  468. unsigned int i;
  469. bitset_word *src1p;
  470. bitset_word *src2p;
  471. bitset_word *dstp;
  472. bitset_windex ssize1;
  473. bitset_windex ssize2;
  474. bitset_windex dsize;
  475. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  476. dsize = VBITSET_SIZE (dst);
  477. ssize1 = VBITSET_SIZE (src1);
  478. ssize2 = VBITSET_SIZE (src2);
  479. dstp = VBITSET_WORDS (dst);
  480. src1p = VBITSET_WORDS (src1);
  481. src2p = VBITSET_WORDS (src2);
  482. for (i = 0; i < min (ssize1, ssize2); i++)
  483. *dstp++ = *src1p++ & ~(*src2p++);
  484. if (ssize2 > ssize1)
  485. {
  486. for (; i < ssize2; i++)
  487. *dstp++ = 0;
  488. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
  489. }
  490. else
  491. {
  492. for (; i < ssize1; i++)
  493. *dstp++ = *src1p++;
  494. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  495. }
  496. }
  497. static bool
  498. vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
  499. {
  500. unsigned int i;
  501. int changed = 0;
  502. bitset_word *src1p;
  503. bitset_word *src2p;
  504. bitset_word *dstp;
  505. bitset_windex ssize1;
  506. bitset_windex ssize2;
  507. bitset_windex dsize;
  508. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  509. dsize = VBITSET_SIZE (dst);
  510. ssize1 = VBITSET_SIZE (src1);
  511. ssize2 = VBITSET_SIZE (src2);
  512. dstp = VBITSET_WORDS (dst);
  513. src1p = VBITSET_WORDS (src1);
  514. src2p = VBITSET_WORDS (src2);
  515. for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
  516. {
  517. bitset_word tmp = *src1p++ & ~(*src2p++);
  518. if (*dstp != tmp)
  519. {
  520. changed = 1;
  521. *dstp = tmp;
  522. }
  523. }
  524. if (ssize2 > ssize1)
  525. {
  526. for (; i < ssize2; i++, dstp++)
  527. {
  528. if (*dstp != 0)
  529. {
  530. changed = 1;
  531. *dstp = 0;
  532. }
  533. }
  534. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
  535. }
  536. else
  537. {
  538. for (; i < ssize1; i++, dstp++)
  539. {
  540. bitset_word tmp = *src1p++;
  541. if (*dstp != tmp)
  542. {
  543. changed = 1;
  544. *dstp = tmp;
  545. }
  546. }
  547. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  548. }
  549. return changed;
  550. }
  551. static void
  552. vbitset_or (bitset dst, bitset src1, bitset src2)
  553. {
  554. unsigned int i;
  555. bitset_word *src1p;
  556. bitset_word *src2p;
  557. bitset_word *dstp;
  558. bitset_windex ssize1;
  559. bitset_windex ssize2;
  560. bitset_windex dsize;
  561. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  562. dsize = VBITSET_SIZE (dst);
  563. ssize1 = VBITSET_SIZE (src1);
  564. ssize2 = VBITSET_SIZE (src2);
  565. dstp = VBITSET_WORDS (dst);
  566. src1p = VBITSET_WORDS (src1);
  567. src2p = VBITSET_WORDS (src2);
  568. for (i = 0; i < min (ssize1, ssize2); i++)
  569. *dstp++ = *src1p++ | *src2p++;
  570. if (ssize2 > ssize1)
  571. {
  572. src1p = src2p;
  573. ssize1 = ssize2;
  574. }
  575. for (; i < ssize1; i++)
  576. *dstp++ = *src1p++;
  577. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  578. }
  579. static bool
  580. vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
  581. {
  582. unsigned int i;
  583. int changed = 0;
  584. bitset_word *src1p;
  585. bitset_word *src2p;
  586. bitset_word *dstp;
  587. bitset_windex ssize1;
  588. bitset_windex ssize2;
  589. bitset_windex dsize;
  590. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  591. dsize = VBITSET_SIZE (dst);
  592. ssize1 = VBITSET_SIZE (src1);
  593. ssize2 = VBITSET_SIZE (src2);
  594. dstp = VBITSET_WORDS (dst);
  595. src1p = VBITSET_WORDS (src1);
  596. src2p = VBITSET_WORDS (src2);
  597. for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
  598. {
  599. bitset_word tmp = *src1p++ | *src2p++;
  600. if (*dstp != tmp)
  601. {
  602. changed = 1;
  603. *dstp = tmp;
  604. }
  605. }
  606. if (ssize2 > ssize1)
  607. {
  608. src1p = src2p;
  609. ssize1 = ssize2;
  610. }
  611. for (; i < ssize1; i++, dstp++)
  612. {
  613. bitset_word tmp = *src1p++;
  614. if (*dstp != tmp)
  615. {
  616. changed = 1;
  617. *dstp = tmp;
  618. }
  619. }
  620. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  621. return changed;
  622. }
  623. static void
  624. vbitset_xor (bitset dst, bitset src1, bitset src2)
  625. {
  626. unsigned int i;
  627. bitset_word *src1p;
  628. bitset_word *src2p;
  629. bitset_word *dstp;
  630. bitset_windex ssize1;
  631. bitset_windex ssize2;
  632. bitset_windex dsize;
  633. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  634. dsize = VBITSET_SIZE (dst);
  635. ssize1 = VBITSET_SIZE (src1);
  636. ssize2 = VBITSET_SIZE (src2);
  637. dstp = VBITSET_WORDS (dst);
  638. src1p = VBITSET_WORDS (src1);
  639. src2p = VBITSET_WORDS (src2);
  640. for (i = 0; i < min (ssize1, ssize2); i++)
  641. *dstp++ = *src1p++ ^ *src2p++;
  642. if (ssize2 > ssize1)
  643. {
  644. src1p = src2p;
  645. ssize1 = ssize2;
  646. }
  647. for (; i < ssize1; i++)
  648. *dstp++ = *src1p++;
  649. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  650. }
  651. static bool
  652. vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
  653. {
  654. unsigned int i;
  655. int changed = 0;
  656. bitset_word *src1p;
  657. bitset_word *src2p;
  658. bitset_word *dstp;
  659. bitset_windex ssize1;
  660. bitset_windex ssize2;
  661. bitset_windex dsize;
  662. vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
  663. dsize = VBITSET_SIZE (dst);
  664. ssize1 = VBITSET_SIZE (src1);
  665. ssize2 = VBITSET_SIZE (src2);
  666. dstp = VBITSET_WORDS (dst);
  667. src1p = VBITSET_WORDS (src1);
  668. src2p = VBITSET_WORDS (src2);
  669. for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
  670. {
  671. bitset_word tmp = *src1p++ ^ *src2p++;
  672. if (*dstp != tmp)
  673. {
  674. changed = 1;
  675. *dstp = tmp;
  676. }
  677. }
  678. if (ssize2 > ssize1)
  679. {
  680. src1p = src2p;
  681. ssize1 = ssize2;
  682. }
  683. for (; i < ssize1; i++, dstp++)
  684. {
  685. bitset_word tmp = *src1p++;
  686. if (*dstp != tmp)
  687. {
  688. changed = 1;
  689. *dstp = tmp;
  690. }
  691. }
  692. memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
  693. return changed;
  694. }
  695. /* FIXME, these operations need fixing for different size
  696. bitsets. */
  697. static void
  698. vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
  699. {
  700. unsigned int i;
  701. bitset_word *src1p;
  702. bitset_word *src2p;
  703. bitset_word *src3p;
  704. bitset_word *dstp;
  705. bitset_windex size;
  706. if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
  707. || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
  708. {
  709. bitset_and_or_ (dst, src1, src2, src3);
  710. return;
  711. }
  712. vbitset_resize (dst, BITSET_NBITS_ (src1));
  713. src1p = VBITSET_WORDS (src1);
  714. src2p = VBITSET_WORDS (src2);
  715. src3p = VBITSET_WORDS (src3);
  716. dstp = VBITSET_WORDS (dst);
  717. size = VBITSET_SIZE (dst);
  718. for (i = 0; i < size; i++)
  719. *dstp++ = (*src1p++ & *src2p++) | *src3p++;
  720. }
  721. static bool
  722. vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
  723. {
  724. unsigned int i;
  725. int changed = 0;
  726. bitset_word *src1p;
  727. bitset_word *src2p;
  728. bitset_word *src3p;
  729. bitset_word *dstp;
  730. bitset_windex size;
  731. if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
  732. || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
  733. return bitset_and_or_cmp_ (dst, src1, src2, src3);
  734. vbitset_resize (dst, BITSET_NBITS_ (src1));
  735. src1p = VBITSET_WORDS (src1);
  736. src2p = VBITSET_WORDS (src2);
  737. src3p = VBITSET_WORDS (src3);
  738. dstp = VBITSET_WORDS (dst);
  739. size = VBITSET_SIZE (dst);
  740. for (i = 0; i < size; i++, dstp++)
  741. {
  742. bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
  743. if (*dstp != tmp)
  744. {
  745. changed = 1;
  746. *dstp = tmp;
  747. }
  748. }
  749. return changed;
  750. }
  751. static void
  752. vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
  753. {
  754. unsigned int i;
  755. bitset_word *src1p;
  756. bitset_word *src2p;
  757. bitset_word *src3p;
  758. bitset_word *dstp;
  759. bitset_windex size;
  760. if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
  761. || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
  762. {
  763. bitset_andn_or_ (dst, src1, src2, src3);
  764. return;
  765. }
  766. vbitset_resize (dst, BITSET_NBITS_ (src1));
  767. src1p = VBITSET_WORDS (src1);
  768. src2p = VBITSET_WORDS (src2);
  769. src3p = VBITSET_WORDS (src3);
  770. dstp = VBITSET_WORDS (dst);
  771. size = VBITSET_SIZE (dst);
  772. for (i = 0; i < size; i++)
  773. *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
  774. }
  775. static bool
  776. vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
  777. {
  778. unsigned int i;
  779. int changed = 0;
  780. bitset_word *src1p;
  781. bitset_word *src2p;
  782. bitset_word *src3p;
  783. bitset_word *dstp;
  784. bitset_windex size;
  785. if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
  786. || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
  787. return bitset_andn_or_cmp_ (dst, src1, src2, src3);
  788. vbitset_resize (dst, BITSET_NBITS_ (src1));
  789. src1p = VBITSET_WORDS (src1);
  790. src2p = VBITSET_WORDS (src2);
  791. src3p = VBITSET_WORDS (src3);
  792. dstp = VBITSET_WORDS (dst);
  793. size = VBITSET_SIZE (dst);
  794. for (i = 0; i < size; i++, dstp++)
  795. {
  796. bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
  797. if (*dstp != tmp)
  798. {
  799. changed = 1;
  800. *dstp = tmp;
  801. }
  802. }
  803. return changed;
  804. }
  805. static void
  806. vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
  807. {
  808. unsigned int i;
  809. bitset_word *src1p;
  810. bitset_word *src2p;
  811. bitset_word *src3p;
  812. bitset_word *dstp;
  813. bitset_windex size;
  814. if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
  815. || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
  816. {
  817. bitset_or_and_ (dst, src1, src2, src3);
  818. return;
  819. }
  820. vbitset_resize (dst, BITSET_NBITS_ (src1));
  821. src1p = VBITSET_WORDS (src1);
  822. src2p = VBITSET_WORDS (src2);
  823. src3p = VBITSET_WORDS (src3);
  824. dstp = VBITSET_WORDS (dst);
  825. size = VBITSET_SIZE (dst);
  826. for (i = 0; i < size; i++)
  827. *dstp++ = (*src1p++ | *src2p++) & *src3p++;
  828. }
  829. static bool
  830. vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
  831. {
  832. unsigned int i;
  833. int changed = 0;
  834. bitset_word *src1p;
  835. bitset_word *src2p;
  836. bitset_word *src3p;
  837. bitset_word *dstp;
  838. bitset_windex size;
  839. if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
  840. || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
  841. return bitset_or_and_cmp_ (dst, src1, src2, src3);
  842. vbitset_resize (dst, BITSET_NBITS_ (src1));
  843. src1p = VBITSET_WORDS (src1);
  844. src2p = VBITSET_WORDS (src2);
  845. src3p = VBITSET_WORDS (src3);
  846. dstp = VBITSET_WORDS (dst);
  847. size = VBITSET_SIZE (dst);
  848. for (i = 0; i < size; i++, dstp++)
  849. {
  850. bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
  851. if (*dstp != tmp)
  852. {
  853. changed = 1;
  854. *dstp = tmp;
  855. }
  856. }
  857. return changed;
  858. }
  859. static void
  860. vbitset_copy (bitset dst, bitset src)
  861. {
  862. if (BITSET_COMPATIBLE_ (dst, src))
  863. vbitset_copy1 (dst, src);
  864. else
  865. bitset_copy_ (dst, src);
  866. }
  867. /* Vector of operations for multiple word bitsets. */
  868. struct bitset_vtable vbitset_vtable = {
  869. vbitset_set,
  870. vbitset_reset,
  871. bitset_toggle_,
  872. vbitset_test,
  873. vbitset_resize,
  874. bitset_size_,
  875. bitset_count_,
  876. vbitset_empty_p,
  877. vbitset_ones,
  878. vbitset_zero,
  879. vbitset_copy,
  880. vbitset_disjoint_p,
  881. vbitset_equal_p,
  882. vbitset_not,
  883. vbitset_subset_p,
  884. vbitset_and,
  885. vbitset_and_cmp,
  886. vbitset_andn,
  887. vbitset_andn_cmp,
  888. vbitset_or,
  889. vbitset_or_cmp,
  890. vbitset_xor,
  891. vbitset_xor_cmp,
  892. vbitset_and_or,
  893. vbitset_and_or_cmp,
  894. vbitset_andn_or,
  895. vbitset_andn_or_cmp,
  896. vbitset_or_and,
  897. vbitset_or_and_cmp,
  898. vbitset_list,
  899. vbitset_list_reverse,
  900. NULL,
  901. BITSET_VARRAY
  902. };
  903. size_t
  904. vbitset_bytes (n_bits)
  905. bitset_bindex n_bits ATTRIBUTE_UNUSED;
  906. {
  907. return sizeof (struct vbitset_struct);
  908. }
  909. bitset
  910. vbitset_init (bset, n_bits)
  911. bitset bset;
  912. bitset_bindex n_bits;
  913. {
  914. bset->b.vtable = &vbitset_vtable;
  915. bset->b.cindex = 0;
  916. VBITSET_SIZE (bset) = 0;
  917. vbitset_resize (bset, n_bits);
  918. return bset;
  919. }