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