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