vlrt.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. typedef unsigned long ulong;
  2. typedef unsigned int uint;
  3. typedef unsigned short ushort;
  4. typedef unsigned char uchar;
  5. typedef signed char schar;
  6. #define SIGN(n) (1UL<<(n-1))
  7. typedef struct Vlong Vlong;
  8. struct Vlong
  9. {
  10. union
  11. {
  12. struct
  13. {
  14. ulong lo;
  15. ulong hi;
  16. };
  17. struct
  18. {
  19. ushort lols;
  20. ushort loms;
  21. ushort hils;
  22. ushort hims;
  23. };
  24. };
  25. };
  26. void abort(void);
  27. void
  28. _subv(Vlong *r, Vlong a, Vlong b)
  29. {
  30. ulong lo, hi;
  31. lo = a.lo - b.lo;
  32. hi = a.hi - b.hi;
  33. if(lo > a.lo)
  34. hi--;
  35. r->lo = lo;
  36. r->hi = hi;
  37. }
  38. void
  39. _d2v(Vlong *y, double d)
  40. {
  41. union { double d; struct Vlong; } x;
  42. ulong xhi, xlo, ylo, yhi;
  43. int sh;
  44. x.d = d;
  45. xhi = (x.hi & 0xfffff) | 0x100000;
  46. xlo = x.lo;
  47. sh = 1075 - ((x.hi >> 20) & 0x7ff);
  48. ylo = 0;
  49. yhi = 0;
  50. if(sh >= 0) {
  51. /* v = (hi||lo) >> sh */
  52. if(sh < 32) {
  53. if(sh == 0) {
  54. ylo = xlo;
  55. yhi = xhi;
  56. } else {
  57. ylo = (xlo >> sh) | (xhi << (32-sh));
  58. yhi = xhi >> sh;
  59. }
  60. } else {
  61. if(sh == 32) {
  62. ylo = xhi;
  63. } else
  64. if(sh < 64) {
  65. ylo = xhi >> (sh-32);
  66. }
  67. }
  68. } else {
  69. /* v = (hi||lo) << -sh */
  70. sh = -sh;
  71. if(sh <= 10) {
  72. ylo = xlo << sh;
  73. yhi = (xhi << sh) | (xlo >> (32-sh));
  74. } else {
  75. /* overflow */
  76. yhi = d; /* causes something awful */
  77. }
  78. }
  79. if(x.hi & SIGN(32)) {
  80. if(ylo != 0) {
  81. ylo = -ylo;
  82. yhi = ~yhi;
  83. } else
  84. yhi = -yhi;
  85. }
  86. y->hi = yhi;
  87. y->lo = ylo;
  88. }
  89. void
  90. _f2v(Vlong *y, float f)
  91. {
  92. _d2v(y, f);
  93. }
  94. double
  95. _v2d(Vlong x)
  96. {
  97. if(x.hi & SIGN(32)) {
  98. if(x.lo) {
  99. x.lo = -x.lo;
  100. x.hi = ~x.hi;
  101. } else
  102. x.hi = -x.hi;
  103. return -((long)x.hi*4294967296. + x.lo);
  104. }
  105. return (long)x.hi*4294967296. + x.lo;
  106. }
  107. float
  108. _v2f(Vlong x)
  109. {
  110. return _v2d(x);
  111. }
  112. ulong _div64by32(Vlong, ulong, ulong*);
  113. void _mul64by32(Vlong*, Vlong, ulong);
  114. static void
  115. slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
  116. {
  117. ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
  118. int i;
  119. numhi = num.hi;
  120. numlo = num.lo;
  121. denhi = den.hi;
  122. denlo = den.lo;
  123. /*
  124. * get a divide by zero
  125. */
  126. if(denlo==0 && denhi==0) {
  127. numlo = numlo / denlo;
  128. }
  129. /*
  130. * set up the divisor and find the number of iterations needed
  131. */
  132. if(numhi >= SIGN(32)) {
  133. quohi = SIGN(32);
  134. quolo = 0;
  135. } else {
  136. quohi = numhi;
  137. quolo = numlo;
  138. }
  139. i = 0;
  140. while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
  141. denhi = (denhi<<1) | (denlo>>31);
  142. denlo <<= 1;
  143. i++;
  144. }
  145. quohi = 0;
  146. quolo = 0;
  147. for(; i >= 0; i--) {
  148. quohi = (quohi<<1) | (quolo>>31);
  149. quolo <<= 1;
  150. if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
  151. t = numlo;
  152. numlo -= denlo;
  153. if(numlo > t)
  154. numhi--;
  155. numhi -= denhi;
  156. quolo |= 1;
  157. }
  158. denlo = (denlo>>1) | (denhi<<31);
  159. denhi >>= 1;
  160. }
  161. if(q) {
  162. q->lo = quolo;
  163. q->hi = quohi;
  164. }
  165. if(r) {
  166. r->lo = numlo;
  167. r->hi = numhi;
  168. }
  169. }
  170. static void
  171. dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
  172. {
  173. ulong n;
  174. Vlong x, q, r;
  175. if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){
  176. if(qp) {
  177. qp->hi = 0;
  178. qp->lo = 0;
  179. }
  180. if(rp) {
  181. rp->hi = num.hi;
  182. rp->lo = num.lo;
  183. }
  184. return;
  185. }
  186. if(den.hi != 0){
  187. q.hi = 0;
  188. n = num.hi/den.hi;
  189. _mul64by32(&x, den, n);
  190. if(x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo))
  191. slowdodiv(num, den, &q, &r);
  192. else {
  193. q.lo = n;
  194. _subv(&r, num, x);
  195. }
  196. } else {
  197. if(num.hi >= den.lo){
  198. q.hi = n = num.hi/den.lo;
  199. num.hi -= den.lo*n;
  200. } else {
  201. q.hi = 0;
  202. }
  203. q.lo = _div64by32(num, den.lo, &r.lo);
  204. r.hi = 0;
  205. }
  206. if(qp) {
  207. qp->lo = q.lo;
  208. qp->hi = q.hi;
  209. }
  210. if(rp) {
  211. rp->lo = r.lo;
  212. rp->hi = r.hi;
  213. }
  214. }
  215. void
  216. _divvu(Vlong *q, Vlong n, Vlong d)
  217. {
  218. if(n.hi == 0 && d.hi == 0) {
  219. q->hi = 0;
  220. q->lo = n.lo / d.lo;
  221. return;
  222. }
  223. dodiv(n, d, q, 0);
  224. }
  225. void
  226. _modvu(Vlong *r, Vlong n, Vlong d)
  227. {
  228. if(n.hi == 0 && d.hi == 0) {
  229. r->hi = 0;
  230. r->lo = n.lo % d.lo;
  231. return;
  232. }
  233. dodiv(n, d, 0, r);
  234. }
  235. static void
  236. vneg(Vlong *v)
  237. {
  238. if(v->lo == 0) {
  239. v->hi = -v->hi;
  240. return;
  241. }
  242. v->lo = -v->lo;
  243. v->hi = ~v->hi;
  244. }
  245. void
  246. _divv(Vlong *q, Vlong n, Vlong d)
  247. {
  248. long nneg, dneg;
  249. if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
  250. q->lo = (long)n.lo / (long)d.lo;
  251. q->hi = ((long)q->lo) >> 31;
  252. return;
  253. }
  254. nneg = n.hi >> 31;
  255. if(nneg)
  256. vneg(&n);
  257. dneg = d.hi >> 31;
  258. if(dneg)
  259. vneg(&d);
  260. dodiv(n, d, q, 0);
  261. if(nneg != dneg)
  262. vneg(q);
  263. }
  264. void
  265. _modv(Vlong *r, Vlong n, Vlong d)
  266. {
  267. long nneg, dneg;
  268. if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
  269. r->lo = (long)n.lo % (long)d.lo;
  270. r->hi = ((long)r->lo) >> 31;
  271. return;
  272. }
  273. nneg = n.hi >> 31;
  274. if(nneg)
  275. vneg(&n);
  276. dneg = d.hi >> 31;
  277. if(dneg)
  278. vneg(&d);
  279. dodiv(n, d, 0, r);
  280. if(nneg)
  281. vneg(r);
  282. }
  283. void
  284. _rshav(Vlong *r, Vlong a, int b)
  285. {
  286. long t;
  287. t = a.hi;
  288. if(b >= 32) {
  289. r->hi = t>>31;
  290. if(b >= 64) {
  291. /* this is illegal re C standard */
  292. r->lo = t>>31;
  293. return;
  294. }
  295. r->lo = t >> (b-32);
  296. return;
  297. }
  298. if(b <= 0) {
  299. r->hi = t;
  300. r->lo = a.lo;
  301. return;
  302. }
  303. r->hi = t >> b;
  304. r->lo = (t << (32-b)) | (a.lo >> b);
  305. }
  306. void
  307. _rshlv(Vlong *r, Vlong a, int b)
  308. {
  309. ulong t;
  310. t = a.hi;
  311. if(b >= 32) {
  312. r->hi = 0;
  313. if(b >= 64) {
  314. /* this is illegal re C standard */
  315. r->lo = 0;
  316. return;
  317. }
  318. r->lo = t >> (b-32);
  319. return;
  320. }
  321. if(b <= 0) {
  322. r->hi = t;
  323. r->lo = a.lo;
  324. return;
  325. }
  326. r->hi = t >> b;
  327. r->lo = (t << (32-b)) | (a.lo >> b);
  328. }
  329. void
  330. _lshv(Vlong *r, Vlong a, int b)
  331. {
  332. ulong t;
  333. t = a.lo;
  334. if(b >= 32) {
  335. r->lo = 0;
  336. if(b >= 64) {
  337. /* this is illegal re C standard */
  338. r->hi = 0;
  339. return;
  340. }
  341. r->hi = t << (b-32);
  342. return;
  343. }
  344. if(b <= 0) {
  345. r->lo = t;
  346. r->hi = a.hi;
  347. return;
  348. }
  349. r->lo = t << b;
  350. r->hi = (t >> (32-b)) | (a.hi << b);
  351. }
  352. void
  353. _andv(Vlong *r, Vlong a, Vlong b)
  354. {
  355. r->hi = a.hi & b.hi;
  356. r->lo = a.lo & b.lo;
  357. }
  358. void
  359. _orv(Vlong *r, Vlong a, Vlong b)
  360. {
  361. r->hi = a.hi | b.hi;
  362. r->lo = a.lo | b.lo;
  363. }
  364. void
  365. _xorv(Vlong *r, Vlong a, Vlong b)
  366. {
  367. r->hi = a.hi ^ b.hi;
  368. r->lo = a.lo ^ b.lo;
  369. }
  370. void
  371. _vpp(Vlong *l, Vlong *r)
  372. {
  373. l->hi = r->hi;
  374. l->lo = r->lo;
  375. r->lo++;
  376. if(r->lo == 0)
  377. r->hi++;
  378. }
  379. void
  380. _vmm(Vlong *l, Vlong *r)
  381. {
  382. l->hi = r->hi;
  383. l->lo = r->lo;
  384. if(r->lo == 0)
  385. r->hi--;
  386. r->lo--;
  387. }
  388. void
  389. _ppv(Vlong *l, Vlong *r)
  390. {
  391. r->lo++;
  392. if(r->lo == 0)
  393. r->hi++;
  394. l->hi = r->hi;
  395. l->lo = r->lo;
  396. }
  397. void
  398. _mmv(Vlong *l, Vlong *r)
  399. {
  400. if(r->lo == 0)
  401. r->hi--;
  402. r->lo--;
  403. l->hi = r->hi;
  404. l->lo = r->lo;
  405. }
  406. void
  407. _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
  408. {
  409. Vlong t, u;
  410. u.lo = 0;
  411. u.hi = 0;
  412. switch(type) {
  413. default:
  414. abort();
  415. break;
  416. case 1: /* schar */
  417. t.lo = *(schar*)lv;
  418. t.hi = t.lo >> 31;
  419. fn(&u, t, rv);
  420. *(schar*)lv = u.lo;
  421. break;
  422. case 2: /* uchar */
  423. t.lo = *(uchar*)lv;
  424. t.hi = 0;
  425. fn(&u, t, rv);
  426. *(uchar*)lv = u.lo;
  427. break;
  428. case 3: /* short */
  429. t.lo = *(short*)lv;
  430. t.hi = t.lo >> 31;
  431. fn(&u, t, rv);
  432. *(short*)lv = u.lo;
  433. break;
  434. case 4: /* ushort */
  435. t.lo = *(ushort*)lv;
  436. t.hi = 0;
  437. fn(&u, t, rv);
  438. *(ushort*)lv = u.lo;
  439. break;
  440. case 9: /* int */
  441. t.lo = *(int*)lv;
  442. t.hi = t.lo >> 31;
  443. fn(&u, t, rv);
  444. *(int*)lv = u.lo;
  445. break;
  446. case 10: /* uint */
  447. t.lo = *(uint*)lv;
  448. t.hi = 0;
  449. fn(&u, t, rv);
  450. *(uint*)lv = u.lo;
  451. break;
  452. case 5: /* long */
  453. t.lo = *(long*)lv;
  454. t.hi = t.lo >> 31;
  455. fn(&u, t, rv);
  456. *(long*)lv = u.lo;
  457. break;
  458. case 6: /* ulong */
  459. t.lo = *(ulong*)lv;
  460. t.hi = 0;
  461. fn(&u, t, rv);
  462. *(ulong*)lv = u.lo;
  463. break;
  464. case 7: /* vlong */
  465. case 8: /* uvlong */
  466. fn(&u, *(Vlong*)lv, rv);
  467. *(Vlong*)lv = u;
  468. break;
  469. }
  470. *ret = u;
  471. }
  472. void
  473. _p2v(Vlong *ret, void *p)
  474. {
  475. long t;
  476. t = (ulong)p;
  477. ret->lo = t;
  478. ret->hi = 0;
  479. }
  480. void
  481. _sl2v(Vlong *ret, long sl)
  482. {
  483. long t;
  484. t = sl;
  485. ret->lo = t;
  486. ret->hi = t >> 31;
  487. }
  488. void
  489. _ul2v(Vlong *ret, ulong ul)
  490. {
  491. long t;
  492. t = ul;
  493. ret->lo = t;
  494. ret->hi = 0;
  495. }
  496. void
  497. _si2v(Vlong *ret, int si)
  498. {
  499. long t;
  500. t = si;
  501. ret->lo = t;
  502. ret->hi = t >> 31;
  503. }
  504. void
  505. _ui2v(Vlong *ret, uint ui)
  506. {
  507. long t;
  508. t = ui;
  509. ret->lo = t;
  510. ret->hi = 0;
  511. }
  512. void
  513. _sh2v(Vlong *ret, long sh)
  514. {
  515. long t;
  516. t = (sh << 16) >> 16;
  517. ret->lo = t;
  518. ret->hi = t >> 31;
  519. }
  520. void
  521. _uh2v(Vlong *ret, ulong ul)
  522. {
  523. long t;
  524. t = ul & 0xffff;
  525. ret->lo = t;
  526. ret->hi = 0;
  527. }
  528. void
  529. _sc2v(Vlong *ret, long uc)
  530. {
  531. long t;
  532. t = (uc << 24) >> 24;
  533. ret->lo = t;
  534. ret->hi = t >> 31;
  535. }
  536. void
  537. _uc2v(Vlong *ret, ulong ul)
  538. {
  539. long t;
  540. t = ul & 0xff;
  541. ret->lo = t;
  542. ret->hi = 0;
  543. }
  544. long
  545. _v2sc(Vlong rv)
  546. {
  547. long t;
  548. t = rv.lo & 0xff;
  549. return (t << 24) >> 24;
  550. }
  551. long
  552. _v2uc(Vlong rv)
  553. {
  554. return rv.lo & 0xff;
  555. }
  556. long
  557. _v2sh(Vlong rv)
  558. {
  559. long t;
  560. t = rv.lo & 0xffff;
  561. return (t << 16) >> 16;
  562. }
  563. long
  564. _v2uh(Vlong rv)
  565. {
  566. return rv.lo & 0xffff;
  567. }
  568. long
  569. _v2sl(Vlong rv)
  570. {
  571. return rv.lo;
  572. }
  573. long
  574. _v2ul(Vlong rv)
  575. {
  576. return rv.lo;
  577. }
  578. long
  579. _v2si(Vlong rv)
  580. {
  581. return rv.lo;
  582. }
  583. long
  584. _v2ui(Vlong rv)
  585. {
  586. return rv.lo;
  587. }
  588. int
  589. _testv(Vlong rv)
  590. {
  591. return rv.lo || rv.hi;
  592. }
  593. int
  594. _eqv(Vlong lv, Vlong rv)
  595. {
  596. return lv.lo == rv.lo && lv.hi == rv.hi;
  597. }
  598. int
  599. _nev(Vlong lv, Vlong rv)
  600. {
  601. return lv.lo != rv.lo || lv.hi != rv.hi;
  602. }
  603. int
  604. _ltv(Vlong lv, Vlong rv)
  605. {
  606. return (long)lv.hi < (long)rv.hi ||
  607. (lv.hi == rv.hi && lv.lo < rv.lo);
  608. }
  609. int
  610. _lev(Vlong lv, Vlong rv)
  611. {
  612. return (long)lv.hi < (long)rv.hi ||
  613. (lv.hi == rv.hi && lv.lo <= rv.lo);
  614. }
  615. int
  616. _gtv(Vlong lv, Vlong rv)
  617. {
  618. return (long)lv.hi > (long)rv.hi ||
  619. (lv.hi == rv.hi && lv.lo > rv.lo);
  620. }
  621. int
  622. _gev(Vlong lv, Vlong rv)
  623. {
  624. return (long)lv.hi > (long)rv.hi ||
  625. (lv.hi == rv.hi && lv.lo >= rv.lo);
  626. }
  627. int
  628. _lov(Vlong lv, Vlong rv)
  629. {
  630. return lv.hi < rv.hi ||
  631. (lv.hi == rv.hi && lv.lo < rv.lo);
  632. }
  633. int
  634. _lsv(Vlong lv, Vlong rv)
  635. {
  636. return lv.hi < rv.hi ||
  637. (lv.hi == rv.hi && lv.lo <= rv.lo);
  638. }
  639. int
  640. _hiv(Vlong lv, Vlong rv)
  641. {
  642. return lv.hi > rv.hi ||
  643. (lv.hi == rv.hi && lv.lo > rv.lo);
  644. }
  645. int
  646. _hsv(Vlong lv, Vlong rv)
  647. {
  648. return lv.hi > rv.hi ||
  649. (lv.hi == rv.hi && lv.lo >= rv.lo);
  650. }