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