xref: /inferno-os/libkern/vlrt-arm.c (revision 7b3bf63c0d3f8b97a41a7022310b70c5d40c6fc6)
137da2899SCharles.Forsyth typedef	unsigned long	ulong;
237da2899SCharles.Forsyth typedef	unsigned int	uint;
337da2899SCharles.Forsyth typedef	unsigned short	ushort;
437da2899SCharles.Forsyth typedef	unsigned char	uchar;
537da2899SCharles.Forsyth typedef	signed char	schar;
637da2899SCharles.Forsyth 
737da2899SCharles.Forsyth #define	SIGN(n)	(1UL<<(n-1))
837da2899SCharles.Forsyth 
937da2899SCharles.Forsyth typedef	struct	Vlong	Vlong;
1037da2899SCharles.Forsyth struct	Vlong
1137da2899SCharles.Forsyth {
1237da2899SCharles.Forsyth 	union
1337da2899SCharles.Forsyth 	{
1437da2899SCharles.Forsyth 		struct
1537da2899SCharles.Forsyth 		{
1637da2899SCharles.Forsyth 			ulong	lo;
17*7b3bf63cSCharles.Forsyth 			ulong	hi;
1837da2899SCharles.Forsyth 		};
1937da2899SCharles.Forsyth 	};
2037da2899SCharles.Forsyth };
2137da2899SCharles.Forsyth 
2237da2899SCharles.Forsyth void	abort(void);
2337da2899SCharles.Forsyth 
2437da2899SCharles.Forsyth void
_addv(Vlong * r,Vlong a,Vlong b)2537da2899SCharles.Forsyth _addv(Vlong *r, Vlong a, Vlong b)
2637da2899SCharles.Forsyth {
2737da2899SCharles.Forsyth 	ulong lo, hi;
2837da2899SCharles.Forsyth 
2937da2899SCharles.Forsyth 	lo = a.lo + b.lo;
3037da2899SCharles.Forsyth 	hi = a.hi + b.hi;
3137da2899SCharles.Forsyth 	if(lo < a.lo)
3237da2899SCharles.Forsyth 		hi++;
3337da2899SCharles.Forsyth 	r->lo = lo;
3437da2899SCharles.Forsyth 	r->hi = hi;
3537da2899SCharles.Forsyth }
3637da2899SCharles.Forsyth 
3737da2899SCharles.Forsyth void
_subv(Vlong * r,Vlong a,Vlong b)3837da2899SCharles.Forsyth _subv(Vlong *r, Vlong a, Vlong b)
3937da2899SCharles.Forsyth {
4037da2899SCharles.Forsyth 	ulong lo, hi;
4137da2899SCharles.Forsyth 
4237da2899SCharles.Forsyth 	lo = a.lo - b.lo;
4337da2899SCharles.Forsyth 	hi = a.hi - b.hi;
4437da2899SCharles.Forsyth 	if(lo > a.lo)
4537da2899SCharles.Forsyth 		hi--;
4637da2899SCharles.Forsyth 	r->lo = lo;
4737da2899SCharles.Forsyth 	r->hi = hi;
4837da2899SCharles.Forsyth }
4937da2899SCharles.Forsyth 
5037da2899SCharles.Forsyth 
5137da2899SCharles.Forsyth void
_d2v(Vlong * y,double d)5237da2899SCharles.Forsyth _d2v(Vlong *y, double d)
5337da2899SCharles.Forsyth {
5437da2899SCharles.Forsyth 	union { double d; struct Vlong; } x;
5537da2899SCharles.Forsyth 	ulong xhi, xlo, ylo, yhi;
5637da2899SCharles.Forsyth 	int sh;
5737da2899SCharles.Forsyth 
5837da2899SCharles.Forsyth 	x.d = d;
5937da2899SCharles.Forsyth 
6037da2899SCharles.Forsyth 	xhi = (x.hi & 0xfffff) | 0x100000;
6137da2899SCharles.Forsyth 	xlo = x.lo;
6237da2899SCharles.Forsyth 	sh = 1075 - ((x.hi >> 20) & 0x7ff);
6337da2899SCharles.Forsyth 
6437da2899SCharles.Forsyth 	ylo = 0;
6537da2899SCharles.Forsyth 	yhi = 0;
6637da2899SCharles.Forsyth 	if(sh >= 0) {
6737da2899SCharles.Forsyth 		/* v = (hi||lo) >> sh */
6837da2899SCharles.Forsyth 		if(sh < 32) {
6937da2899SCharles.Forsyth 			if(sh == 0) {
7037da2899SCharles.Forsyth 				ylo = xlo;
7137da2899SCharles.Forsyth 				yhi = xhi;
7237da2899SCharles.Forsyth 			} else {
7337da2899SCharles.Forsyth 				ylo = (xlo >> sh) | (xhi << (32-sh));
7437da2899SCharles.Forsyth 				yhi = xhi >> sh;
7537da2899SCharles.Forsyth 			}
7637da2899SCharles.Forsyth 		} else {
7737da2899SCharles.Forsyth 			if(sh == 32) {
7837da2899SCharles.Forsyth 				ylo = xhi;
7937da2899SCharles.Forsyth 			} else
8037da2899SCharles.Forsyth 			if(sh < 64) {
8137da2899SCharles.Forsyth 				ylo = xhi >> (sh-32);
8237da2899SCharles.Forsyth 			}
8337da2899SCharles.Forsyth 		}
8437da2899SCharles.Forsyth 	} else {
8537da2899SCharles.Forsyth 		/* v = (hi||lo) << -sh */
8637da2899SCharles.Forsyth 		sh = -sh;
8737da2899SCharles.Forsyth 		if(sh <= 10) {
8837da2899SCharles.Forsyth 			ylo = xlo << sh;
8937da2899SCharles.Forsyth 			yhi = (xhi << sh) | (xlo >> (32-sh));
9037da2899SCharles.Forsyth 		} else {
9137da2899SCharles.Forsyth 			/* overflow */
9237da2899SCharles.Forsyth 			yhi = d;	/* causes something awful */
9337da2899SCharles.Forsyth 		}
9437da2899SCharles.Forsyth 	}
9537da2899SCharles.Forsyth 	if(x.hi & SIGN(32)) {
9637da2899SCharles.Forsyth 		if(ylo != 0) {
9737da2899SCharles.Forsyth 			ylo = -ylo;
9837da2899SCharles.Forsyth 			yhi = ~yhi;
9937da2899SCharles.Forsyth 		} else
10037da2899SCharles.Forsyth 			yhi = -yhi;
10137da2899SCharles.Forsyth 	}
10237da2899SCharles.Forsyth 
10337da2899SCharles.Forsyth 	y->hi = yhi;
10437da2899SCharles.Forsyth 	y->lo = ylo;
10537da2899SCharles.Forsyth }
10637da2899SCharles.Forsyth 
10737da2899SCharles.Forsyth void
_f2v(Vlong * y,float f)10837da2899SCharles.Forsyth _f2v(Vlong *y, float f)
10937da2899SCharles.Forsyth {
11037da2899SCharles.Forsyth 	_d2v(y, f);
11137da2899SCharles.Forsyth }
11237da2899SCharles.Forsyth 
11337da2899SCharles.Forsyth double
_v2d(Vlong x)11437da2899SCharles.Forsyth _v2d(Vlong x)
11537da2899SCharles.Forsyth {
11637da2899SCharles.Forsyth 	if(x.hi & SIGN(32)) {
11737da2899SCharles.Forsyth 		if(x.lo) {
11837da2899SCharles.Forsyth 			x.lo = -x.lo;
11937da2899SCharles.Forsyth 			x.hi = ~x.hi;
12037da2899SCharles.Forsyth 		} else
12137da2899SCharles.Forsyth 			x.hi = -x.hi;
12237da2899SCharles.Forsyth 		return -((long)x.hi*4294967296. + x.lo);
12337da2899SCharles.Forsyth 	}
12437da2899SCharles.Forsyth 	return (long)x.hi*4294967296. + x.lo;
12537da2899SCharles.Forsyth }
12637da2899SCharles.Forsyth 
12737da2899SCharles.Forsyth float
_v2f(Vlong x)12837da2899SCharles.Forsyth _v2f(Vlong x)
12937da2899SCharles.Forsyth {
13037da2899SCharles.Forsyth 	return _v2d(x);
13137da2899SCharles.Forsyth }
13237da2899SCharles.Forsyth 
13337da2899SCharles.Forsyth static void
dodiv(Vlong num,Vlong den,Vlong * q,Vlong * r)13437da2899SCharles.Forsyth dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
13537da2899SCharles.Forsyth {
13637da2899SCharles.Forsyth 	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
13737da2899SCharles.Forsyth 	int i;
13837da2899SCharles.Forsyth 
13937da2899SCharles.Forsyth 	numhi = num.hi;
14037da2899SCharles.Forsyth 	numlo = num.lo;
14137da2899SCharles.Forsyth 	denhi = den.hi;
14237da2899SCharles.Forsyth 	denlo = den.lo;
14337da2899SCharles.Forsyth 
14437da2899SCharles.Forsyth 	/*
14537da2899SCharles.Forsyth 	 * get a divide by zero
14637da2899SCharles.Forsyth 	 */
14737da2899SCharles.Forsyth 	if(denlo==0 && denhi==0) {
14837da2899SCharles.Forsyth 		numlo = numlo / denlo;
14937da2899SCharles.Forsyth 	}
15037da2899SCharles.Forsyth 
15137da2899SCharles.Forsyth 	/*
15237da2899SCharles.Forsyth 	 * set up the divisor and find the number of iterations needed
15337da2899SCharles.Forsyth 	 */
15437da2899SCharles.Forsyth 	if(numhi >= SIGN(32)) {
15537da2899SCharles.Forsyth 		quohi = SIGN(32);
15637da2899SCharles.Forsyth 		quolo = 0;
15737da2899SCharles.Forsyth 	} else {
15837da2899SCharles.Forsyth 		quohi = numhi;
15937da2899SCharles.Forsyth 		quolo = numlo;
16037da2899SCharles.Forsyth 	}
16137da2899SCharles.Forsyth 	i = 0;
16237da2899SCharles.Forsyth 	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
16337da2899SCharles.Forsyth 		denhi = (denhi<<1) | (denlo>>31);
16437da2899SCharles.Forsyth 		denlo <<= 1;
16537da2899SCharles.Forsyth 		i++;
16637da2899SCharles.Forsyth 	}
16737da2899SCharles.Forsyth 
16837da2899SCharles.Forsyth 	quohi = 0;
16937da2899SCharles.Forsyth 	quolo = 0;
17037da2899SCharles.Forsyth 	for(; i >= 0; i--) {
17137da2899SCharles.Forsyth 		quohi = (quohi<<1) | (quolo>>31);
17237da2899SCharles.Forsyth 		quolo <<= 1;
17337da2899SCharles.Forsyth 		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
17437da2899SCharles.Forsyth 			t = numlo;
17537da2899SCharles.Forsyth 			numlo -= denlo;
17637da2899SCharles.Forsyth 			if(numlo > t)
17737da2899SCharles.Forsyth 				numhi--;
17837da2899SCharles.Forsyth 			numhi -= denhi;
17937da2899SCharles.Forsyth 			quolo |= 1;
18037da2899SCharles.Forsyth 		}
18137da2899SCharles.Forsyth 		denlo = (denlo>>1) | (denhi<<31);
18237da2899SCharles.Forsyth 		denhi >>= 1;
18337da2899SCharles.Forsyth 	}
18437da2899SCharles.Forsyth 
18537da2899SCharles.Forsyth 	if(q) {
18637da2899SCharles.Forsyth 		q->lo = quolo;
18737da2899SCharles.Forsyth 		q->hi = quohi;
18837da2899SCharles.Forsyth 	}
18937da2899SCharles.Forsyth 	if(r) {
19037da2899SCharles.Forsyth 		r->lo = numlo;
19137da2899SCharles.Forsyth 		r->hi = numhi;
19237da2899SCharles.Forsyth 	}
19337da2899SCharles.Forsyth }
19437da2899SCharles.Forsyth 
19537da2899SCharles.Forsyth void
_divvu(Vlong * q,Vlong n,Vlong d)19637da2899SCharles.Forsyth _divvu(Vlong *q, Vlong n, Vlong d)
19737da2899SCharles.Forsyth {
19837da2899SCharles.Forsyth 
19937da2899SCharles.Forsyth 	if(n.hi == 0 && d.hi == 0) {
20037da2899SCharles.Forsyth 		q->hi = 0;
20137da2899SCharles.Forsyth 		q->lo = n.lo / d.lo;
20237da2899SCharles.Forsyth 		return;
20337da2899SCharles.Forsyth 	}
20437da2899SCharles.Forsyth 	dodiv(n, d, q, 0);
20537da2899SCharles.Forsyth }
20637da2899SCharles.Forsyth 
20737da2899SCharles.Forsyth void
_modvu(Vlong * r,Vlong n,Vlong d)20837da2899SCharles.Forsyth _modvu(Vlong *r, Vlong n, Vlong d)
20937da2899SCharles.Forsyth {
21037da2899SCharles.Forsyth 
21137da2899SCharles.Forsyth 	if(n.hi == 0 && d.hi == 0) {
21237da2899SCharles.Forsyth 		r->hi = 0;
21337da2899SCharles.Forsyth 		r->lo = n.lo % d.lo;
21437da2899SCharles.Forsyth 		return;
21537da2899SCharles.Forsyth 	}
21637da2899SCharles.Forsyth 	dodiv(n, d, 0, r);
21737da2899SCharles.Forsyth }
21837da2899SCharles.Forsyth 
21937da2899SCharles.Forsyth static void
vneg(Vlong * v)22037da2899SCharles.Forsyth vneg(Vlong *v)
22137da2899SCharles.Forsyth {
22237da2899SCharles.Forsyth 
22337da2899SCharles.Forsyth 	if(v->lo == 0) {
22437da2899SCharles.Forsyth 		v->hi = -v->hi;
22537da2899SCharles.Forsyth 		return;
22637da2899SCharles.Forsyth 	}
22737da2899SCharles.Forsyth 	v->lo = -v->lo;
22837da2899SCharles.Forsyth 	v->hi = ~v->hi;
22937da2899SCharles.Forsyth }
23037da2899SCharles.Forsyth 
23137da2899SCharles.Forsyth void
_divv(Vlong * q,Vlong n,Vlong d)23237da2899SCharles.Forsyth _divv(Vlong *q, Vlong n, Vlong d)
23337da2899SCharles.Forsyth {
23437da2899SCharles.Forsyth 	long nneg, dneg;
23537da2899SCharles.Forsyth 
23637da2899SCharles.Forsyth 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
23737da2899SCharles.Forsyth 		q->lo = (long)n.lo / (long)d.lo;
23837da2899SCharles.Forsyth 		q->hi = ((long)q->lo) >> 31;
23937da2899SCharles.Forsyth 		return;
24037da2899SCharles.Forsyth 	}
24137da2899SCharles.Forsyth 	nneg = n.hi >> 31;
24237da2899SCharles.Forsyth 	if(nneg)
24337da2899SCharles.Forsyth 		vneg(&n);
24437da2899SCharles.Forsyth 	dneg = d.hi >> 31;
24537da2899SCharles.Forsyth 	if(dneg)
24637da2899SCharles.Forsyth 		vneg(&d);
24737da2899SCharles.Forsyth 	dodiv(n, d, q, 0);
24837da2899SCharles.Forsyth 	if(nneg != dneg)
24937da2899SCharles.Forsyth 		vneg(q);
25037da2899SCharles.Forsyth }
25137da2899SCharles.Forsyth 
25237da2899SCharles.Forsyth void
_modv(Vlong * r,Vlong n,Vlong d)25337da2899SCharles.Forsyth _modv(Vlong *r, Vlong n, Vlong d)
25437da2899SCharles.Forsyth {
25537da2899SCharles.Forsyth 	long nneg, dneg;
25637da2899SCharles.Forsyth 
25737da2899SCharles.Forsyth 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
25837da2899SCharles.Forsyth 		r->lo = (long)n.lo % (long)d.lo;
25937da2899SCharles.Forsyth 		r->hi = ((long)r->lo) >> 31;
26037da2899SCharles.Forsyth 		return;
26137da2899SCharles.Forsyth 	}
26237da2899SCharles.Forsyth 	nneg = n.hi >> 31;
26337da2899SCharles.Forsyth 	if(nneg)
26437da2899SCharles.Forsyth 		vneg(&n);
26537da2899SCharles.Forsyth 	dneg = d.hi >> 31;
26637da2899SCharles.Forsyth 	if(dneg)
26737da2899SCharles.Forsyth 		vneg(&d);
26837da2899SCharles.Forsyth 	dodiv(n, d, 0, r);
26937da2899SCharles.Forsyth 	if(nneg)
27037da2899SCharles.Forsyth 		vneg(r);
27137da2899SCharles.Forsyth }
27237da2899SCharles.Forsyth 
27337da2899SCharles.Forsyth void
_rshav(Vlong * r,Vlong a,int b)27437da2899SCharles.Forsyth _rshav(Vlong *r, Vlong a, int b)
27537da2899SCharles.Forsyth {
27637da2899SCharles.Forsyth 	long t;
27737da2899SCharles.Forsyth 
27837da2899SCharles.Forsyth 	t = a.hi;
27937da2899SCharles.Forsyth 	if(b >= 32) {
28037da2899SCharles.Forsyth 		r->hi = t>>31;
28137da2899SCharles.Forsyth 		if(b >= 64) {
28237da2899SCharles.Forsyth 			/* this is illegal re C standard */
28337da2899SCharles.Forsyth 			r->lo = t>>31;
28437da2899SCharles.Forsyth 			return;
28537da2899SCharles.Forsyth 		}
28637da2899SCharles.Forsyth 		r->lo = t >> (b-32);
28737da2899SCharles.Forsyth 		return;
28837da2899SCharles.Forsyth 	}
28937da2899SCharles.Forsyth 	if(b <= 0) {
29037da2899SCharles.Forsyth 		r->hi = t;
29137da2899SCharles.Forsyth 		r->lo = a.lo;
29237da2899SCharles.Forsyth 		return;
29337da2899SCharles.Forsyth 	}
29437da2899SCharles.Forsyth 	r->hi = t >> b;
29537da2899SCharles.Forsyth 	r->lo = (t << (32-b)) | (a.lo >> b);
29637da2899SCharles.Forsyth }
29737da2899SCharles.Forsyth 
29837da2899SCharles.Forsyth void
_rshlv(Vlong * r,Vlong a,int b)29937da2899SCharles.Forsyth _rshlv(Vlong *r, Vlong a, int b)
30037da2899SCharles.Forsyth {
30137da2899SCharles.Forsyth 	ulong t;
30237da2899SCharles.Forsyth 
30337da2899SCharles.Forsyth 	t = a.hi;
30437da2899SCharles.Forsyth 	if(b >= 32) {
30537da2899SCharles.Forsyth 		r->hi = 0;
30637da2899SCharles.Forsyth 		if(b >= 64) {
30737da2899SCharles.Forsyth 			/* this is illegal re C standard */
30837da2899SCharles.Forsyth 			r->lo = 0;
30937da2899SCharles.Forsyth 			return;
31037da2899SCharles.Forsyth 		}
31137da2899SCharles.Forsyth 		r->lo = t >> (b-32);
31237da2899SCharles.Forsyth 		return;
31337da2899SCharles.Forsyth 	}
31437da2899SCharles.Forsyth 	if(b <= 0) {
31537da2899SCharles.Forsyth 		r->hi = t;
31637da2899SCharles.Forsyth 		r->lo = a.lo;
31737da2899SCharles.Forsyth 		return;
31837da2899SCharles.Forsyth 	}
31937da2899SCharles.Forsyth 	r->hi = t >> b;
32037da2899SCharles.Forsyth 	r->lo = (t << (32-b)) | (a.lo >> b);
32137da2899SCharles.Forsyth }
32237da2899SCharles.Forsyth 
32337da2899SCharles.Forsyth void
_lshv(Vlong * r,Vlong a,int b)32437da2899SCharles.Forsyth _lshv(Vlong *r, Vlong a, int b)
32537da2899SCharles.Forsyth {
32637da2899SCharles.Forsyth 	ulong t;
32737da2899SCharles.Forsyth 
32837da2899SCharles.Forsyth 	t = a.lo;
32937da2899SCharles.Forsyth 	if(b >= 32) {
33037da2899SCharles.Forsyth 		r->lo = 0;
33137da2899SCharles.Forsyth 		if(b >= 64) {
33237da2899SCharles.Forsyth 			/* this is illegal re C standard */
33337da2899SCharles.Forsyth 			r->hi = 0;
33437da2899SCharles.Forsyth 			return;
33537da2899SCharles.Forsyth 		}
33637da2899SCharles.Forsyth 		r->hi = t << (b-32);
33737da2899SCharles.Forsyth 		return;
33837da2899SCharles.Forsyth 	}
33937da2899SCharles.Forsyth 	if(b <= 0) {
34037da2899SCharles.Forsyth 		r->lo = t;
34137da2899SCharles.Forsyth 		r->hi = a.hi;
34237da2899SCharles.Forsyth 		return;
34337da2899SCharles.Forsyth 	}
34437da2899SCharles.Forsyth 	r->lo = t << b;
34537da2899SCharles.Forsyth 	r->hi = (t >> (32-b)) | (a.hi << b);
34637da2899SCharles.Forsyth }
34737da2899SCharles.Forsyth 
34837da2899SCharles.Forsyth void
_andv(Vlong * r,Vlong a,Vlong b)34937da2899SCharles.Forsyth _andv(Vlong *r, Vlong a, Vlong b)
35037da2899SCharles.Forsyth {
35137da2899SCharles.Forsyth 	r->hi = a.hi & b.hi;
35237da2899SCharles.Forsyth 	r->lo = a.lo & b.lo;
35337da2899SCharles.Forsyth }
35437da2899SCharles.Forsyth 
35537da2899SCharles.Forsyth void
_orv(Vlong * r,Vlong a,Vlong b)35637da2899SCharles.Forsyth _orv(Vlong *r, Vlong a, Vlong b)
35737da2899SCharles.Forsyth {
35837da2899SCharles.Forsyth 	r->hi = a.hi | b.hi;
35937da2899SCharles.Forsyth 	r->lo = a.lo | b.lo;
36037da2899SCharles.Forsyth }
36137da2899SCharles.Forsyth 
36237da2899SCharles.Forsyth void
_xorv(Vlong * r,Vlong a,Vlong b)36337da2899SCharles.Forsyth _xorv(Vlong *r, Vlong a, Vlong b)
36437da2899SCharles.Forsyth {
36537da2899SCharles.Forsyth 	r->hi = a.hi ^ b.hi;
36637da2899SCharles.Forsyth 	r->lo = a.lo ^ b.lo;
36737da2899SCharles.Forsyth }
36837da2899SCharles.Forsyth 
36937da2899SCharles.Forsyth void
_vpp(Vlong * l,Vlong * r)37037da2899SCharles.Forsyth _vpp(Vlong *l, Vlong *r)
37137da2899SCharles.Forsyth {
37237da2899SCharles.Forsyth 
37337da2899SCharles.Forsyth 	l->hi = r->hi;
37437da2899SCharles.Forsyth 	l->lo = r->lo;
37537da2899SCharles.Forsyth 	r->lo++;
37637da2899SCharles.Forsyth 	if(r->lo == 0)
37737da2899SCharles.Forsyth 		r->hi++;
37837da2899SCharles.Forsyth }
37937da2899SCharles.Forsyth 
38037da2899SCharles.Forsyth void
_vmm(Vlong * l,Vlong * r)38137da2899SCharles.Forsyth _vmm(Vlong *l, Vlong *r)
38237da2899SCharles.Forsyth {
38337da2899SCharles.Forsyth 
38437da2899SCharles.Forsyth 	l->hi = r->hi;
38537da2899SCharles.Forsyth 	l->lo = r->lo;
38637da2899SCharles.Forsyth 	if(r->lo == 0)
38737da2899SCharles.Forsyth 		r->hi--;
38837da2899SCharles.Forsyth 	r->lo--;
38937da2899SCharles.Forsyth }
39037da2899SCharles.Forsyth 
39137da2899SCharles.Forsyth void
_ppv(Vlong * l,Vlong * r)39237da2899SCharles.Forsyth _ppv(Vlong *l, Vlong *r)
39337da2899SCharles.Forsyth {
39437da2899SCharles.Forsyth 
39537da2899SCharles.Forsyth 	r->lo++;
39637da2899SCharles.Forsyth 	if(r->lo == 0)
39737da2899SCharles.Forsyth 		r->hi++;
39837da2899SCharles.Forsyth 	l->hi = r->hi;
39937da2899SCharles.Forsyth 	l->lo = r->lo;
40037da2899SCharles.Forsyth }
40137da2899SCharles.Forsyth 
40237da2899SCharles.Forsyth void
_mmv(Vlong * l,Vlong * r)40337da2899SCharles.Forsyth _mmv(Vlong *l, Vlong *r)
40437da2899SCharles.Forsyth {
40537da2899SCharles.Forsyth 
40637da2899SCharles.Forsyth 	if(r->lo == 0)
40737da2899SCharles.Forsyth 		r->hi--;
40837da2899SCharles.Forsyth 	r->lo--;
40937da2899SCharles.Forsyth 	l->hi = r->hi;
41037da2899SCharles.Forsyth 	l->lo = r->lo;
41137da2899SCharles.Forsyth }
41237da2899SCharles.Forsyth 
41337da2899SCharles.Forsyth void
_vasop(Vlong * ret,void * lv,void fn (Vlong *,Vlong,Vlong),int type,Vlong rv)41437da2899SCharles.Forsyth _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
41537da2899SCharles.Forsyth {
41637da2899SCharles.Forsyth 	Vlong t, u;
41737da2899SCharles.Forsyth 
41837da2899SCharles.Forsyth 	u = *ret;
41937da2899SCharles.Forsyth 	switch(type) {
42037da2899SCharles.Forsyth 	default:
42137da2899SCharles.Forsyth 		abort();
42237da2899SCharles.Forsyth 		break;
42337da2899SCharles.Forsyth 
42437da2899SCharles.Forsyth 	case 1:	/* schar */
42537da2899SCharles.Forsyth 		t.lo = *(schar*)lv;
42637da2899SCharles.Forsyth 		t.hi = t.lo >> 31;
42737da2899SCharles.Forsyth 		fn(&u, t, rv);
42837da2899SCharles.Forsyth 		*(schar*)lv = u.lo;
42937da2899SCharles.Forsyth 		break;
43037da2899SCharles.Forsyth 
43137da2899SCharles.Forsyth 	case 2:	/* uchar */
43237da2899SCharles.Forsyth 		t.lo = *(uchar*)lv;
43337da2899SCharles.Forsyth 		t.hi = 0;
43437da2899SCharles.Forsyth 		fn(&u, t, rv);
43537da2899SCharles.Forsyth 		*(uchar*)lv = u.lo;
43637da2899SCharles.Forsyth 		break;
43737da2899SCharles.Forsyth 
43837da2899SCharles.Forsyth 	case 3:	/* short */
43937da2899SCharles.Forsyth 		t.lo = *(short*)lv;
44037da2899SCharles.Forsyth 		t.hi = t.lo >> 31;
44137da2899SCharles.Forsyth 		fn(&u, t, rv);
44237da2899SCharles.Forsyth 		*(short*)lv = u.lo;
44337da2899SCharles.Forsyth 		break;
44437da2899SCharles.Forsyth 
44537da2899SCharles.Forsyth 	case 4:	/* ushort */
44637da2899SCharles.Forsyth 		t.lo = *(ushort*)lv;
44737da2899SCharles.Forsyth 		t.hi = 0;
44837da2899SCharles.Forsyth 		fn(&u, t, rv);
44937da2899SCharles.Forsyth 		*(ushort*)lv = u.lo;
45037da2899SCharles.Forsyth 		break;
45137da2899SCharles.Forsyth 
45237da2899SCharles.Forsyth 	case 9:	/* int */
45337da2899SCharles.Forsyth 		t.lo = *(int*)lv;
45437da2899SCharles.Forsyth 		t.hi = t.lo >> 31;
45537da2899SCharles.Forsyth 		fn(&u, t, rv);
45637da2899SCharles.Forsyth 		*(int*)lv = u.lo;
45737da2899SCharles.Forsyth 		break;
45837da2899SCharles.Forsyth 
45937da2899SCharles.Forsyth 	case 10:	/* uint */
46037da2899SCharles.Forsyth 		t.lo = *(uint*)lv;
46137da2899SCharles.Forsyth 		t.hi = 0;
46237da2899SCharles.Forsyth 		fn(&u, t, rv);
46337da2899SCharles.Forsyth 		*(uint*)lv = u.lo;
46437da2899SCharles.Forsyth 		break;
46537da2899SCharles.Forsyth 
46637da2899SCharles.Forsyth 	case 5:	/* long */
46737da2899SCharles.Forsyth 		t.lo = *(long*)lv;
46837da2899SCharles.Forsyth 		t.hi = t.lo >> 31;
46937da2899SCharles.Forsyth 		fn(&u, t, rv);
47037da2899SCharles.Forsyth 		*(long*)lv = u.lo;
47137da2899SCharles.Forsyth 		break;
47237da2899SCharles.Forsyth 
47337da2899SCharles.Forsyth 	case 6:	/* ulong */
47437da2899SCharles.Forsyth 		t.lo = *(ulong*)lv;
47537da2899SCharles.Forsyth 		t.hi = 0;
47637da2899SCharles.Forsyth 		fn(&u, t, rv);
47737da2899SCharles.Forsyth 		*(ulong*)lv = u.lo;
47837da2899SCharles.Forsyth 		break;
47937da2899SCharles.Forsyth 
48037da2899SCharles.Forsyth 	case 7:	/* vlong */
48137da2899SCharles.Forsyth 	case 8:	/* uvlong */
48237da2899SCharles.Forsyth 		fn(&u, *(Vlong*)lv, rv);
48337da2899SCharles.Forsyth 		*(Vlong*)lv = u;
48437da2899SCharles.Forsyth 		break;
48537da2899SCharles.Forsyth 	}
48637da2899SCharles.Forsyth 	*ret = u;
48737da2899SCharles.Forsyth }
48837da2899SCharles.Forsyth 
48937da2899SCharles.Forsyth void
_p2v(Vlong * ret,void * p)49037da2899SCharles.Forsyth _p2v(Vlong *ret, void *p)
49137da2899SCharles.Forsyth {
49237da2899SCharles.Forsyth 	long t;
49337da2899SCharles.Forsyth 
49437da2899SCharles.Forsyth 	t = (ulong)p;
49537da2899SCharles.Forsyth 	ret->lo = t;
49637da2899SCharles.Forsyth 	ret->hi = 0;
49737da2899SCharles.Forsyth }
49837da2899SCharles.Forsyth 
49937da2899SCharles.Forsyth void
_sl2v(Vlong * ret,long sl)50037da2899SCharles.Forsyth _sl2v(Vlong *ret, long sl)
50137da2899SCharles.Forsyth {
50237da2899SCharles.Forsyth 	long t;
50337da2899SCharles.Forsyth 
50437da2899SCharles.Forsyth 	t = sl;
50537da2899SCharles.Forsyth 	ret->lo = t;
50637da2899SCharles.Forsyth 	ret->hi = t >> 31;
50737da2899SCharles.Forsyth }
50837da2899SCharles.Forsyth 
50937da2899SCharles.Forsyth void
_ul2v(Vlong * ret,ulong ul)51037da2899SCharles.Forsyth _ul2v(Vlong *ret, ulong ul)
51137da2899SCharles.Forsyth {
51237da2899SCharles.Forsyth 	long t;
51337da2899SCharles.Forsyth 
51437da2899SCharles.Forsyth 	t = ul;
51537da2899SCharles.Forsyth 	ret->lo = t;
51637da2899SCharles.Forsyth 	ret->hi = 0;
51737da2899SCharles.Forsyth }
51837da2899SCharles.Forsyth 
51937da2899SCharles.Forsyth void
_si2v(Vlong * ret,int si)52037da2899SCharles.Forsyth _si2v(Vlong *ret, int si)
52137da2899SCharles.Forsyth {
52237da2899SCharles.Forsyth 	long t;
52337da2899SCharles.Forsyth 
52437da2899SCharles.Forsyth 	t = si;
52537da2899SCharles.Forsyth 	ret->lo = t;
52637da2899SCharles.Forsyth 	ret->hi = t >> 31;
52737da2899SCharles.Forsyth }
52837da2899SCharles.Forsyth 
52937da2899SCharles.Forsyth void
_ui2v(Vlong * ret,uint ui)53037da2899SCharles.Forsyth _ui2v(Vlong *ret, uint ui)
53137da2899SCharles.Forsyth {
53237da2899SCharles.Forsyth 	long t;
53337da2899SCharles.Forsyth 
53437da2899SCharles.Forsyth 	t = ui;
53537da2899SCharles.Forsyth 	ret->lo = t;
53637da2899SCharles.Forsyth 	ret->hi = 0;
53737da2899SCharles.Forsyth }
53837da2899SCharles.Forsyth 
53937da2899SCharles.Forsyth void
_sh2v(Vlong * ret,long sh)54037da2899SCharles.Forsyth _sh2v(Vlong *ret, long sh)
54137da2899SCharles.Forsyth {
54237da2899SCharles.Forsyth 	long t;
54337da2899SCharles.Forsyth 
54437da2899SCharles.Forsyth 	t = (sh << 16) >> 16;
54537da2899SCharles.Forsyth 	ret->lo = t;
54637da2899SCharles.Forsyth 	ret->hi = t >> 31;
54737da2899SCharles.Forsyth }
54837da2899SCharles.Forsyth 
54937da2899SCharles.Forsyth void
_uh2v(Vlong * ret,ulong ul)55037da2899SCharles.Forsyth _uh2v(Vlong *ret, ulong ul)
55137da2899SCharles.Forsyth {
55237da2899SCharles.Forsyth 	long t;
55337da2899SCharles.Forsyth 
55437da2899SCharles.Forsyth 	t = ul & 0xffff;
55537da2899SCharles.Forsyth 	ret->lo = t;
55637da2899SCharles.Forsyth 	ret->hi = 0;
55737da2899SCharles.Forsyth }
55837da2899SCharles.Forsyth 
55937da2899SCharles.Forsyth void
_sc2v(Vlong * ret,long uc)56037da2899SCharles.Forsyth _sc2v(Vlong *ret, long uc)
56137da2899SCharles.Forsyth {
56237da2899SCharles.Forsyth 	long t;
56337da2899SCharles.Forsyth 
56437da2899SCharles.Forsyth 	t = (uc << 24) >> 24;
56537da2899SCharles.Forsyth 	ret->lo = t;
56637da2899SCharles.Forsyth 	ret->hi = t >> 31;
56737da2899SCharles.Forsyth }
56837da2899SCharles.Forsyth 
56937da2899SCharles.Forsyth void
_uc2v(Vlong * ret,ulong ul)57037da2899SCharles.Forsyth _uc2v(Vlong *ret, ulong ul)
57137da2899SCharles.Forsyth {
57237da2899SCharles.Forsyth 	long t;
57337da2899SCharles.Forsyth 
57437da2899SCharles.Forsyth 	t = ul & 0xff;
57537da2899SCharles.Forsyth 	ret->lo = t;
57637da2899SCharles.Forsyth 	ret->hi = 0;
57737da2899SCharles.Forsyth }
57837da2899SCharles.Forsyth 
57937da2899SCharles.Forsyth long
_v2sc(Vlong rv)58037da2899SCharles.Forsyth _v2sc(Vlong rv)
58137da2899SCharles.Forsyth {
58237da2899SCharles.Forsyth 	long t;
58337da2899SCharles.Forsyth 
58437da2899SCharles.Forsyth 	t = rv.lo & 0xff;
58537da2899SCharles.Forsyth 	return (t << 24) >> 24;
58637da2899SCharles.Forsyth }
58737da2899SCharles.Forsyth 
58837da2899SCharles.Forsyth long
_v2uc(Vlong rv)58937da2899SCharles.Forsyth _v2uc(Vlong rv)
59037da2899SCharles.Forsyth {
59137da2899SCharles.Forsyth 
59237da2899SCharles.Forsyth 	return rv.lo & 0xff;
59337da2899SCharles.Forsyth }
59437da2899SCharles.Forsyth 
59537da2899SCharles.Forsyth long
_v2sh(Vlong rv)59637da2899SCharles.Forsyth _v2sh(Vlong rv)
59737da2899SCharles.Forsyth {
59837da2899SCharles.Forsyth 	long t;
59937da2899SCharles.Forsyth 
60037da2899SCharles.Forsyth 	t = rv.lo & 0xffff;
60137da2899SCharles.Forsyth 	return (t << 16) >> 16;
60237da2899SCharles.Forsyth }
60337da2899SCharles.Forsyth 
60437da2899SCharles.Forsyth long
_v2uh(Vlong rv)60537da2899SCharles.Forsyth _v2uh(Vlong rv)
60637da2899SCharles.Forsyth {
60737da2899SCharles.Forsyth 
60837da2899SCharles.Forsyth 	return rv.lo & 0xffff;
60937da2899SCharles.Forsyth }
61037da2899SCharles.Forsyth 
61137da2899SCharles.Forsyth long
_v2sl(Vlong rv)61237da2899SCharles.Forsyth _v2sl(Vlong rv)
61337da2899SCharles.Forsyth {
61437da2899SCharles.Forsyth 
61537da2899SCharles.Forsyth 	return rv.lo;
61637da2899SCharles.Forsyth }
61737da2899SCharles.Forsyth 
61837da2899SCharles.Forsyth long
_v2ul(Vlong rv)61937da2899SCharles.Forsyth _v2ul(Vlong rv)
62037da2899SCharles.Forsyth {
62137da2899SCharles.Forsyth 
62237da2899SCharles.Forsyth 	return rv.lo;
62337da2899SCharles.Forsyth }
62437da2899SCharles.Forsyth 
62537da2899SCharles.Forsyth long
_v2si(Vlong rv)62637da2899SCharles.Forsyth _v2si(Vlong rv)
62737da2899SCharles.Forsyth {
62837da2899SCharles.Forsyth 
62937da2899SCharles.Forsyth 	return rv.lo;
63037da2899SCharles.Forsyth }
63137da2899SCharles.Forsyth 
63237da2899SCharles.Forsyth long
_v2ui(Vlong rv)63337da2899SCharles.Forsyth _v2ui(Vlong rv)
63437da2899SCharles.Forsyth {
63537da2899SCharles.Forsyth 
63637da2899SCharles.Forsyth 	return rv.lo;
63737da2899SCharles.Forsyth }
63837da2899SCharles.Forsyth 
63937da2899SCharles.Forsyth int
_testv(Vlong rv)64037da2899SCharles.Forsyth _testv(Vlong rv)
64137da2899SCharles.Forsyth {
64237da2899SCharles.Forsyth 	return rv.lo || rv.hi;
64337da2899SCharles.Forsyth }
64437da2899SCharles.Forsyth 
64537da2899SCharles.Forsyth int
_eqv(Vlong lv,Vlong rv)64637da2899SCharles.Forsyth _eqv(Vlong lv, Vlong rv)
64737da2899SCharles.Forsyth {
64837da2899SCharles.Forsyth 	return lv.lo == rv.lo && lv.hi == rv.hi;
64937da2899SCharles.Forsyth }
65037da2899SCharles.Forsyth 
65137da2899SCharles.Forsyth int
_nev(Vlong lv,Vlong rv)65237da2899SCharles.Forsyth _nev(Vlong lv, Vlong rv)
65337da2899SCharles.Forsyth {
65437da2899SCharles.Forsyth 	return lv.lo != rv.lo || lv.hi != rv.hi;
65537da2899SCharles.Forsyth }
65637da2899SCharles.Forsyth 
65737da2899SCharles.Forsyth int
_ltv(Vlong lv,Vlong rv)65837da2899SCharles.Forsyth _ltv(Vlong lv, Vlong rv)
65937da2899SCharles.Forsyth {
66037da2899SCharles.Forsyth 	return (long)lv.hi < (long)rv.hi ||
66137da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo < rv.lo);
66237da2899SCharles.Forsyth }
66337da2899SCharles.Forsyth 
66437da2899SCharles.Forsyth int
_lev(Vlong lv,Vlong rv)66537da2899SCharles.Forsyth _lev(Vlong lv, Vlong rv)
66637da2899SCharles.Forsyth {
66737da2899SCharles.Forsyth 	return (long)lv.hi < (long)rv.hi ||
66837da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo <= rv.lo);
66937da2899SCharles.Forsyth }
67037da2899SCharles.Forsyth 
67137da2899SCharles.Forsyth int
_gtv(Vlong lv,Vlong rv)67237da2899SCharles.Forsyth _gtv(Vlong lv, Vlong rv)
67337da2899SCharles.Forsyth {
67437da2899SCharles.Forsyth 	return (long)lv.hi > (long)rv.hi ||
67537da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo > rv.lo);
67637da2899SCharles.Forsyth }
67737da2899SCharles.Forsyth 
67837da2899SCharles.Forsyth int
_gev(Vlong lv,Vlong rv)67937da2899SCharles.Forsyth _gev(Vlong lv, Vlong rv)
68037da2899SCharles.Forsyth {
68137da2899SCharles.Forsyth 	return (long)lv.hi > (long)rv.hi ||
68237da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo >= rv.lo);
68337da2899SCharles.Forsyth }
68437da2899SCharles.Forsyth 
68537da2899SCharles.Forsyth int
_lov(Vlong lv,Vlong rv)68637da2899SCharles.Forsyth _lov(Vlong lv, Vlong rv)
68737da2899SCharles.Forsyth {
68837da2899SCharles.Forsyth 	return lv.hi < rv.hi ||
68937da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo < rv.lo);
69037da2899SCharles.Forsyth }
69137da2899SCharles.Forsyth 
69237da2899SCharles.Forsyth int
_lsv(Vlong lv,Vlong rv)69337da2899SCharles.Forsyth _lsv(Vlong lv, Vlong rv)
69437da2899SCharles.Forsyth {
69537da2899SCharles.Forsyth 	return lv.hi < rv.hi ||
69637da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo <= rv.lo);
69737da2899SCharles.Forsyth }
69837da2899SCharles.Forsyth 
69937da2899SCharles.Forsyth int
_hiv(Vlong lv,Vlong rv)70037da2899SCharles.Forsyth _hiv(Vlong lv, Vlong rv)
70137da2899SCharles.Forsyth {
70237da2899SCharles.Forsyth 	return lv.hi > rv.hi ||
70337da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo > rv.lo);
70437da2899SCharles.Forsyth }
70537da2899SCharles.Forsyth 
70637da2899SCharles.Forsyth int
_hsv(Vlong lv,Vlong rv)70737da2899SCharles.Forsyth _hsv(Vlong lv, Vlong rv)
70837da2899SCharles.Forsyth {
70937da2899SCharles.Forsyth 	return lv.hi > rv.hi ||
71037da2899SCharles.Forsyth 		(lv.hi == rv.hi && lv.lo >= rv.lo);
71137da2899SCharles.Forsyth }
712