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