/src/tk/vec.c

https://github.com/llucax/dmd · C · 656 lines · 492 code · 79 blank · 85 comment · 117 complexity · 784fd438f1302b6a0c1a808929e9f97c MD5 · raw file

  1. /* Copyright (C) 1986-2012 by Digital Mars */
  2. /* Written by Walter Bright */
  3. /* Bit vector package */
  4. #include <stdio.h>
  5. #include <string.h>
  6. #ifndef assert
  7. #include <assert.h>
  8. #endif
  9. #include "vec.h"
  10. #include "mem.h"
  11. static int vec_count; /* # of vectors allocated */
  12. static int vec_initcount = 0; /* # of times package is initialized */
  13. #define VECMAX 20
  14. static vec_t vecfreelist[VECMAX];
  15. #if 1
  16. #define MASK(b) ((vec_base_t)1 << ((b) & VECMASK))
  17. #else
  18. #define MASK(b) bmask[(b) & VECMASK]
  19. static vec_base_t bmask[VECMASK + 1] =
  20. {
  21. 1,2,4,8,0x10,0x20,0x40,0x80,
  22. 0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000,0x8000,
  23. #if __INTSIZE == 4
  24. 0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000,0x800000,
  25. 0x1000000,0x2000000,0x4000000,0x8000000,
  26. 0x10000000,0x20000000,0x40000000,0x80000000
  27. #endif
  28. };
  29. #endif
  30. /**************************
  31. * Initialize package.
  32. */
  33. void vec_init()
  34. {
  35. assert(sizeof(vec_base_t)==2 && VECSHIFT==4 ||
  36. sizeof(vec_base_t)==4 && VECSHIFT==5 ||
  37. sizeof(vec_base_t)==8 && VECSHIFT==6);
  38. if (vec_initcount++ == 0)
  39. vec_count = 0;
  40. }
  41. /**************************
  42. * Terminate package.
  43. */
  44. void vec_term()
  45. {
  46. if (--vec_initcount == 0)
  47. {
  48. #ifdef DEBUG
  49. if (vec_count != 0)
  50. {
  51. printf("vec_count = %d\n",vec_count);
  52. assert(0);
  53. }
  54. #else
  55. assert(vec_count == 0);
  56. #endif
  57. #if TERMCODE
  58. size_t i;
  59. for (i = 0; i < VECMAX; i++)
  60. { void **v;
  61. void **vn;
  62. for (v = (void **)vecfreelist[i]; v; v = vn)
  63. {
  64. vn = (void **)(*v);
  65. mem_free(v);
  66. }
  67. vecfreelist[i] = NULL;
  68. }
  69. #endif
  70. }
  71. }
  72. /********************************
  73. * Allocate a vector given # of bits in it.
  74. * Clear the vector.
  75. */
  76. vec_t vec_calloc(size_t numbits)
  77. { vec_t v;
  78. size_t dim;
  79. if (numbits == 0)
  80. return (vec_t) NULL;
  81. dim = (numbits + (VECBITS - 1)) >> VECSHIFT;
  82. if (dim < VECMAX && (v = vecfreelist[dim]) != NULL)
  83. {
  84. vecfreelist[dim] = *(vec_t *)v;
  85. v += 2;
  86. switch (dim)
  87. {
  88. case 5: v[4] = 0;
  89. case 4: v[3] = 0;
  90. case 3: v[2] = 0;
  91. case 2: v[1] = 0;
  92. case 1: v[0] = 0;
  93. break;
  94. default: memset(v,0,dim * sizeof(vec_base_t));
  95. break;
  96. }
  97. goto L1;
  98. }
  99. else
  100. {
  101. v = (vec_t) mem_calloc((dim + 2) * sizeof(vec_base_t));
  102. }
  103. if (v)
  104. {
  105. v += 2;
  106. L1:
  107. vec_dim(v) = dim;
  108. vec_numbits(v) = numbits;
  109. /*printf("vec_calloc(%d): v = %p vec_numbits = %d vec_dim = %d\n",
  110. numbits,v,vec_numbits(v),vec_dim(v));*/
  111. vec_count++;
  112. }
  113. return v;
  114. }
  115. /********************************
  116. * Allocate copy of existing vector.
  117. */
  118. vec_t vec_clone(vec_t v)
  119. { vec_t vc;
  120. size_t dim;
  121. size_t nbytes;
  122. if (v)
  123. { dim = vec_dim(v);
  124. nbytes = (dim + 2) * sizeof(vec_base_t);
  125. if (dim < VECMAX && (vc = vecfreelist[dim]) != NULL)
  126. {
  127. vecfreelist[dim] = *(vec_t *)vc;
  128. goto L1;
  129. }
  130. else
  131. {
  132. vc = (vec_t) mem_calloc(nbytes);
  133. }
  134. if (vc)
  135. {
  136. L1:
  137. memcpy(vc,v - 2,nbytes);
  138. vec_count++;
  139. v = vc + 2;
  140. }
  141. else
  142. v = NULL;
  143. }
  144. return v;
  145. }
  146. /**************************
  147. * Free a vector.
  148. */
  149. void vec_free(vec_t v)
  150. {
  151. /*printf("vec_free(%p)\n",v);*/
  152. if (v)
  153. { size_t dim = vec_dim(v);
  154. v -= 2;
  155. if (dim < VECMAX)
  156. {
  157. *(vec_t *)v = vecfreelist[dim];
  158. vecfreelist[dim] = v;
  159. }
  160. else
  161. mem_free(v);
  162. vec_count--;
  163. }
  164. }
  165. /**************************
  166. * Realloc a vector to have numbits bits in it.
  167. * Extra bits are set to 0.
  168. */
  169. vec_t vec_realloc(vec_t v, size_t numbits)
  170. { vec_t newv;
  171. size_t vbits;
  172. /*printf("vec_realloc(%p,%d)\n",v,numbits);*/
  173. if (!v)
  174. return vec_calloc(numbits);
  175. if (!numbits)
  176. { vec_free(v);
  177. return NULL;
  178. }
  179. vbits = vec_numbits(v);
  180. if (numbits == vbits)
  181. return v;
  182. newv = vec_calloc(numbits);
  183. if (newv)
  184. { size_t nbytes;
  185. nbytes = (vec_dim(v) < vec_dim(newv)) ? vec_dim(v) : vec_dim(newv);
  186. memcpy(newv,v,nbytes * sizeof(vec_base_t));
  187. vec_clearextrabits(newv);
  188. }
  189. vec_free(v);
  190. return newv;
  191. }
  192. /**************************
  193. * Set bit b in vector v.
  194. */
  195. #ifndef vec_setbit
  196. #if _M_I86 && __INTSIZE == 4 && __SC__
  197. __declspec(naked) void __pascal vec_setbit(size_t b,vec_t v)
  198. {
  199. _asm
  200. {
  201. mov EAX,b-4[ESP]
  202. mov ECX,v-4[ESP]
  203. bts [ECX],EAX
  204. ret 8
  205. }
  206. }
  207. #else
  208. void vec_setbit(size_t b,vec_t v)
  209. {
  210. #ifdef DEBUG
  211. if (!(v && b < vec_numbits(v)))
  212. printf("vec_setbit(v = %p,b = %d): numbits = %d dim = %d\n",
  213. v,b,v ? vec_numbits(v) : 0, v ? vec_dim(v) : 0);
  214. #endif
  215. assert(v && b < vec_numbits(v));
  216. *(v + (b >> VECSHIFT)) |= MASK(b);
  217. }
  218. #endif
  219. #endif
  220. /**************************
  221. * Clear bit b in vector v.
  222. */
  223. #ifndef vec_clearbit
  224. #if _M_I86 && __INTSIZE == 4 && __SC__
  225. __declspec(naked) void __pascal vec_clearbit(size_t b,vec_t v)
  226. {
  227. _asm
  228. {
  229. mov EAX,b-4[ESP]
  230. mov ECX,v-4[ESP]
  231. btr [ECX],EAX
  232. ret 8
  233. }
  234. }
  235. #else
  236. void vec_clearbit(size_t b,vec_t v)
  237. {
  238. assert(v && b < vec_numbits(v));
  239. *(v + (b >> VECSHIFT)) &= ~MASK(b);
  240. }
  241. #endif
  242. #endif
  243. /**************************
  244. * Test bit b in vector v.
  245. */
  246. #ifndef vec_testbit
  247. #if _M_I86 && __INTSIZE == 4 && __SC__
  248. __declspec(naked) size_t __pascal vec_testbit(size_t b,vec_t v)
  249. {
  250. _asm
  251. {
  252. mov EAX,v-4[ESP]
  253. mov ECX,b-4[ESP]
  254. test EAX,EAX
  255. jz L1
  256. bt [EAX],ECX
  257. sbb EAX,EAX
  258. L1: ret 8
  259. }
  260. }
  261. #else
  262. size_t vec_testbit(size_t b,vec_t v)
  263. {
  264. if (!v)
  265. return 0;
  266. #ifdef DEBUG
  267. if (b >= vec_numbits(v))
  268. { printf("vec_testbit(v = %p,b = %d): numbits = %d dim = %d\n",
  269. v,b,vec_numbits(v),vec_dim(v));
  270. b = (size_t)-1;
  271. }
  272. #endif
  273. assert(b < vec_numbits(v));
  274. #if __I86__ >= 3 && __SC__
  275. _asm
  276. {
  277. #if __INTSIZE == 4
  278. mov EAX,b
  279. mov ECX,v
  280. bt [ECX],EAX
  281. sbb EAX,EAX
  282. #elif __COMPACT__ || __LARGE__ || __VCM__
  283. mov AX,b
  284. les BX,v
  285. bt ES:[BX],AX
  286. sbb AX,AX
  287. #else
  288. mov AX,b
  289. mov CX,v
  290. bt [CX],AX
  291. sbb AX,AX
  292. #endif
  293. }
  294. #ifdef DEBUG
  295. { int x = _AX;
  296. assert((x != 0) == ((*(v + (b >> VECSHIFT)) & MASK(b)) != 0));
  297. }
  298. #endif
  299. #else
  300. return *(v + (b >> VECSHIFT)) & MASK(b);
  301. #endif
  302. }
  303. #endif
  304. #endif
  305. /********************************
  306. * Find first set bit starting from b in vector v.
  307. * If no bit is found, return vec_numbits(v).
  308. */
  309. size_t vec_index(size_t b,vec_t vec)
  310. { register size_t starv;
  311. register vec_t v,vtop;
  312. size_t bit;
  313. if (!vec)
  314. return 0;
  315. v = vec;
  316. if (b < vec_numbits(v))
  317. { vtop = &vec[vec_dim(v)];
  318. bit = b & VECMASK;
  319. if (bit != b) /* if not starting in first word */
  320. v += b >> VECSHIFT;
  321. starv = *v >> bit;
  322. while (1)
  323. {
  324. while (starv)
  325. { if (starv & 1)
  326. return b;
  327. b++;
  328. starv >>= 1;
  329. }
  330. b = (b + VECBITS) & ~VECMASK; /* round up to next word */
  331. if (++v >= vtop)
  332. break;
  333. starv = *v;
  334. }
  335. }
  336. return vec_numbits(vec);
  337. }
  338. /********************************
  339. * Compute v1 &= v2.
  340. */
  341. void vec_andass(vec_t v1,vec_t v2)
  342. { vec_t vtop;
  343. if (v1)
  344. {
  345. assert(v2);
  346. assert(vec_numbits(v1)==vec_numbits(v2));
  347. vtop = &v1[vec_dim(v1)];
  348. for (; v1 < vtop; v1++,v2++)
  349. *v1 &= *v2;
  350. }
  351. else
  352. assert(!v2);
  353. }
  354. /********************************
  355. * Compute v1 = v2 & v3.
  356. */
  357. void vec_and(vec_t v1,vec_t v2,vec_t v3)
  358. { vec_t vtop;
  359. if (v1)
  360. {
  361. assert(v2 && v3);
  362. assert(vec_numbits(v1)==vec_numbits(v2) && vec_numbits(v1)==vec_numbits(v3));
  363. vtop = &v1[vec_dim(v1)];
  364. for (; v1 < vtop; v1++,v2++,v3++)
  365. *v1 = *v2 & *v3;
  366. }
  367. else
  368. assert(!v2 && !v3);
  369. }
  370. /********************************
  371. * Compute v1 ^= v2.
  372. */
  373. void vec_xorass(vec_t v1,vec_t v2)
  374. { vec_t vtop;
  375. if (v1)
  376. {
  377. assert(v2);
  378. assert(vec_numbits(v1)==vec_numbits(v2));
  379. vtop = &v1[vec_dim(v1)];
  380. for (; v1 < vtop; v1++,v2++)
  381. *v1 ^= *v2;
  382. }
  383. else
  384. assert(!v2);
  385. }
  386. /********************************
  387. * Compute v1 = v2 ^ v3.
  388. */
  389. void vec_xor(vec_t v1,vec_t v2,vec_t v3)
  390. { vec_t vtop;
  391. if (v1)
  392. {
  393. assert(v2 && v3);
  394. assert(vec_numbits(v1)==vec_numbits(v2) && vec_numbits(v1)==vec_numbits(v3));
  395. vtop = &v1[vec_dim(v1)];
  396. for (; v1 < vtop; v1++,v2++,v3++)
  397. *v1 = *v2 ^ *v3;
  398. }
  399. else
  400. assert(!v2 && !v3);
  401. }
  402. /********************************
  403. * Compute v1 |= v2.
  404. */
  405. void vec_orass(vec_t v1,vec_t v2)
  406. { vec_t vtop;
  407. if (v1)
  408. {
  409. #ifdef DEBUG
  410. assert(v2);
  411. assert(vec_numbits(v1)==vec_numbits(v2));
  412. #endif
  413. vtop = &v1[vec_dim(v1)];
  414. #if __INTSIZE == 2 && __I86__ && (__COMPACT__ || __LARGE__ || __VCM__)
  415. _asm
  416. {
  417. push DS
  418. lds SI,v2
  419. les DI,v1
  420. mov CX,word ptr vtop
  421. cmp CX,DI
  422. jz L1
  423. L2: mov AX,[SI]
  424. add SI,2
  425. or ES:[DI],AX
  426. add DI,2
  427. cmp DI,CX
  428. jb L2
  429. L1: pop DS
  430. #if __SC__ <= 0x610
  431. jmp Lret
  432. #endif
  433. }
  434. #else
  435. for (; v1 < vtop; v1++,v2++)
  436. *v1 |= *v2;
  437. #endif
  438. }
  439. else
  440. assert(!v2);
  441. }
  442. /********************************
  443. * Compute v1 = v2 | v3.
  444. */
  445. void vec_or(vec_t v1,vec_t v2,vec_t v3)
  446. { vec_t vtop;
  447. if (v1)
  448. {
  449. assert(v2 && v3);
  450. assert(vec_numbits(v1)==vec_numbits(v2) && vec_numbits(v1)==vec_numbits(v3));
  451. vtop = &v1[vec_dim(v1)];
  452. for (; v1 < vtop; v1++,v2++,v3++)
  453. *v1 = *v2 | *v3;
  454. }
  455. else
  456. assert(!v2 && !v3);
  457. }
  458. /********************************
  459. * Compute v1 -= v2.
  460. */
  461. void vec_subass(vec_t v1,vec_t v2)
  462. { vec_t vtop;
  463. if (v1)
  464. {
  465. assert(v2);
  466. assert(vec_numbits(v1)==vec_numbits(v2));
  467. vtop = &v1[vec_dim(v1)];
  468. for (; v1 < vtop; v1++,v2++)
  469. *v1 &= ~*v2;
  470. }
  471. else
  472. assert(!v2);
  473. }
  474. /********************************
  475. * Compute v1 = v2 - v3.
  476. */
  477. void vec_sub(vec_t v1,vec_t v2,vec_t v3)
  478. { vec_t vtop;
  479. if (v1)
  480. {
  481. assert(v2 && v3);
  482. assert(vec_numbits(v1)==vec_numbits(v2) && vec_numbits(v1)==vec_numbits(v3));
  483. vtop = &v1[vec_dim(v1)];
  484. for (; v1 < vtop; v1++,v2++,v3++)
  485. *v1 = *v2 & ~*v3;
  486. }
  487. else
  488. assert(!v2 && !v3);
  489. }
  490. /****************
  491. * Clear vector.
  492. */
  493. void vec_clear(vec_t v)
  494. {
  495. if (v)
  496. memset(v,0,sizeof(v[0]) * vec_dim(v));
  497. }
  498. /****************
  499. * Set vector.
  500. */
  501. void vec_set(vec_t v)
  502. {
  503. if (v)
  504. { memset(v,~0,sizeof(v[0]) * vec_dim(v));
  505. vec_clearextrabits(v);
  506. }
  507. }
  508. /***************
  509. * Copy vector.
  510. */
  511. void vec_copy(vec_t to,vec_t from)
  512. {
  513. if (to != from)
  514. {
  515. #ifdef DEBUG
  516. if (!(to && from && vec_numbits(to) == vec_numbits(from)))
  517. printf("to = x%lx, from = x%lx, numbits(to) = %d, numbits(from) = %d\n",
  518. (long)to,(long)from,to ? vec_numbits(to) : 0, from ? vec_numbits(from): 0);
  519. #endif
  520. assert(to && from && vec_numbits(to) == vec_numbits(from));
  521. memcpy(to,from,sizeof(to[0]) * vec_dim(to));
  522. }
  523. }
  524. /****************
  525. * Return 1 if vectors are equal.
  526. */
  527. int vec_equal(vec_t v1,vec_t v2)
  528. {
  529. if (v1 == v2)
  530. return 1;
  531. assert(v1 && v2 && vec_numbits(v1) == vec_numbits(v2));
  532. return !memcmp(v1,v2,sizeof(v1[0]) * vec_dim(v1));
  533. }
  534. /********************************
  535. * Return 1 if (v1 & v2) == 0
  536. */
  537. int vec_disjoint(vec_t v1,vec_t v2)
  538. { vec_t vtop;
  539. assert(v1 && v2);
  540. assert(vec_numbits(v1)==vec_numbits(v2));
  541. vtop = &v1[vec_dim(v1)];
  542. for (; v1 < vtop; v1++,v2++)
  543. if (*v1 & *v2)
  544. return 0;
  545. return 1;
  546. }
  547. /*********************
  548. * Clear any extra bits in vector.
  549. */
  550. void vec_clearextrabits(vec_t v)
  551. { size_t n;
  552. assert(v);
  553. n = vec_numbits(v);
  554. if (n & VECMASK)
  555. v[vec_dim(v) - 1] &= MASK(n) - 1;
  556. }
  557. /******************
  558. * Write out vector.
  559. */
  560. void vec_println(vec_t v)
  561. {
  562. #ifdef DEBUG
  563. vec_print(v);
  564. fputc('\n',stdout);
  565. #endif
  566. }
  567. void vec_print(vec_t v)
  568. {
  569. #ifdef DEBUG
  570. printf(" Vec %p, numbits %d dim %d",v,vec_numbits(v),vec_dim(v));
  571. if (v)
  572. { fputc('\t',stdout);
  573. for (size_t i = 0; i < vec_numbits(v); i++)
  574. fputc((vec_testbit(i,v)) ? '1' : '0',stdout);
  575. }
  576. #endif
  577. }