]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libc/arm/vlrt.c
pool: do poolcheck when free nodes get corrupted instead of assert
[plan9front.git] / sys / src / libc / arm / 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         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
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
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
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
106 _f2v(Vlong *y, float f)
107 {
108         _d2v(y, f);
109 }
110
111 double
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
580 _v2sc(Vlong rv)
581 {
582         long t;
583
584         t = rv.lo & 0xff;
585         return (t << 24) >> 24;
586 }
587
588 long
589 _v2uc(Vlong rv)
590 {
591
592         return rv.lo & 0xff;
593 }
594
595 long
596 _v2sh(Vlong rv)
597 {
598         long t;
599
600         t = rv.lo & 0xffff;
601         return (t << 16) >> 16;
602 }
603
604 long
605 _v2uh(Vlong rv)
606 {
607
608         return rv.lo & 0xffff;
609 }
610
611 long
612 _v2sl(Vlong rv)
613 {
614
615         return rv.lo;
616 }
617
618 long
619 _v2ul(Vlong rv)
620 {
621
622         return rv.lo;
623 }
624
625 long
626 _v2si(Vlong rv)
627 {
628
629         return rv.lo;
630 }
631
632 long
633 _v2ui(Vlong rv)
634 {
635
636         return rv.lo;
637 }
638
639 int
640 _testv(Vlong rv)
641 {
642         return rv.lo || rv.hi;
643 }
644
645 int
646 _eqv(Vlong lv, Vlong rv)
647 {
648         return lv.lo == rv.lo && lv.hi == rv.hi;
649 }
650
651 int
652 _nev(Vlong lv, Vlong rv)
653 {
654         return lv.lo != rv.lo || lv.hi != rv.hi;
655 }
656
657 int
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
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
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
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
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
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
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
707 _hsv(Vlong lv, Vlong rv)
708 {
709         return lv.hi > rv.hi || 
710                 (lv.hi == rv.hi && lv.lo >= rv.lo);
711 }