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