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