vlrt.c 8.8 KB

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