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