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