/src/tk/vec.c

https://bitbucket.org/olioengr/dmd · C · 655 lines · 490 code · 79 blank · 86 comment · 114 complexity · 00c45a771ad936aab3c90e0f7e9b6cc8 MD5 · raw file

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