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