xref: /plan9/sys/src/ape/lib/ap/arm/vlrt.c (revision 5aa528fabc16cf8efb2814bf4829050e8175d743)
180ee5cbfSDavid du Colombier typedef	unsigned long	ulong;
280ee5cbfSDavid du Colombier typedef	unsigned int	uint;
380ee5cbfSDavid du Colombier typedef	unsigned short	ushort;
480ee5cbfSDavid du Colombier typedef	unsigned char	uchar;
580ee5cbfSDavid du Colombier typedef	signed char	schar;
680ee5cbfSDavid du Colombier 
780ee5cbfSDavid du Colombier #define	SIGN(n)	(1UL<<(n-1))
880ee5cbfSDavid du Colombier 
980ee5cbfSDavid du Colombier typedef	struct	Vlong	Vlong;
1080ee5cbfSDavid du Colombier struct	Vlong
1180ee5cbfSDavid du Colombier {
1280ee5cbfSDavid du Colombier 	ulong	lo;
13*5aa528faSDavid du Colombier 	ulong	hi;
1480ee5cbfSDavid du Colombier };
1580ee5cbfSDavid du Colombier 
1680ee5cbfSDavid du Colombier void	abort(void);
1780ee5cbfSDavid du Colombier 
18*5aa528faSDavid du Colombier /* needed by profiler; can't be profiled */
19*5aa528faSDavid du Colombier #pragma profile off
20*5aa528faSDavid du Colombier 
2180ee5cbfSDavid du Colombier void
_addv(Vlong * r,Vlong a,Vlong b)2280ee5cbfSDavid du Colombier _addv(Vlong *r, Vlong a, Vlong b)
2380ee5cbfSDavid du Colombier {
2480ee5cbfSDavid du Colombier 	ulong lo, hi;
2580ee5cbfSDavid du Colombier 
2680ee5cbfSDavid du Colombier 	lo = a.lo + b.lo;
2780ee5cbfSDavid du Colombier 	hi = a.hi + b.hi;
2880ee5cbfSDavid du Colombier 	if(lo < a.lo)
2980ee5cbfSDavid du Colombier 		hi++;
3080ee5cbfSDavid du Colombier 	r->lo = lo;
3180ee5cbfSDavid du Colombier 	r->hi = hi;
3280ee5cbfSDavid du Colombier }
3380ee5cbfSDavid du Colombier 
3480ee5cbfSDavid du Colombier void
_subv(Vlong * r,Vlong a,Vlong b)3580ee5cbfSDavid du Colombier _subv(Vlong *r, Vlong a, Vlong b)
3680ee5cbfSDavid du Colombier {
3780ee5cbfSDavid du Colombier 	ulong lo, hi;
3880ee5cbfSDavid du Colombier 
3980ee5cbfSDavid du Colombier 	lo = a.lo - b.lo;
4080ee5cbfSDavid du Colombier 	hi = a.hi - b.hi;
4180ee5cbfSDavid du Colombier 	if(lo > a.lo)
4280ee5cbfSDavid du Colombier 		hi--;
4380ee5cbfSDavid du Colombier 	r->lo = lo;
4480ee5cbfSDavid du Colombier 	r->hi = hi;
4580ee5cbfSDavid du Colombier }
4680ee5cbfSDavid du Colombier 
47*5aa528faSDavid du Colombier #pragma profile on
4880ee5cbfSDavid du Colombier 
4980ee5cbfSDavid du Colombier void
_d2v(Vlong * y,double d)5080ee5cbfSDavid du Colombier _d2v(Vlong *y, double d)
5180ee5cbfSDavid du Colombier {
5280ee5cbfSDavid du Colombier 	union { double d; struct Vlong; } x;
5380ee5cbfSDavid du Colombier 	ulong xhi, xlo, ylo, yhi;
5480ee5cbfSDavid du Colombier 	int sh;
5580ee5cbfSDavid du Colombier 
5680ee5cbfSDavid du Colombier 	x.d = d;
5780ee5cbfSDavid du Colombier 
5880ee5cbfSDavid du Colombier 	xhi = (x.hi & 0xfffff) | 0x100000;
5980ee5cbfSDavid du Colombier 	xlo = x.lo;
6080ee5cbfSDavid du Colombier 	sh = 1075 - ((x.hi >> 20) & 0x7ff);
6180ee5cbfSDavid du Colombier 
6280ee5cbfSDavid du Colombier 	ylo = 0;
6380ee5cbfSDavid du Colombier 	yhi = 0;
6480ee5cbfSDavid du Colombier 	if(sh >= 0) {
6580ee5cbfSDavid du Colombier 		/* v = (hi||lo) >> sh */
6680ee5cbfSDavid du Colombier 		if(sh < 32) {
6780ee5cbfSDavid du Colombier 			if(sh == 0) {
6880ee5cbfSDavid du Colombier 				ylo = xlo;
6980ee5cbfSDavid du Colombier 				yhi = xhi;
7080ee5cbfSDavid du Colombier 			} else {
7180ee5cbfSDavid du Colombier 				ylo = (xlo >> sh) | (xhi << (32-sh));
7280ee5cbfSDavid du Colombier 				yhi = xhi >> sh;
7380ee5cbfSDavid du Colombier 			}
7480ee5cbfSDavid du Colombier 		} else {
7580ee5cbfSDavid du Colombier 			if(sh == 32) {
7680ee5cbfSDavid du Colombier 				ylo = xhi;
7780ee5cbfSDavid du Colombier 			} else
7880ee5cbfSDavid du Colombier 			if(sh < 64) {
7980ee5cbfSDavid du Colombier 				ylo = xhi >> (sh-32);
8080ee5cbfSDavid du Colombier 			}
8180ee5cbfSDavid du Colombier 		}
8280ee5cbfSDavid du Colombier 	} else {
8380ee5cbfSDavid du Colombier 		/* v = (hi||lo) << -sh */
8480ee5cbfSDavid du Colombier 		sh = -sh;
8580ee5cbfSDavid du Colombier 		if(sh <= 10) {
8680ee5cbfSDavid du Colombier 			ylo = xlo << sh;
8780ee5cbfSDavid du Colombier 			yhi = (xhi << sh) | (xlo >> (32-sh));
8880ee5cbfSDavid du Colombier 		} else {
8980ee5cbfSDavid du Colombier 			/* overflow */
9080ee5cbfSDavid du Colombier 			yhi = d;	/* causes something awful */
9180ee5cbfSDavid du Colombier 		}
9280ee5cbfSDavid du Colombier 	}
9380ee5cbfSDavid du Colombier 	if(x.hi & SIGN(32)) {
9480ee5cbfSDavid du Colombier 		if(ylo != 0) {
9580ee5cbfSDavid du Colombier 			ylo = -ylo;
9680ee5cbfSDavid du Colombier 			yhi = ~yhi;
9780ee5cbfSDavid du Colombier 		} else
9880ee5cbfSDavid du Colombier 			yhi = -yhi;
9980ee5cbfSDavid du Colombier 	}
10080ee5cbfSDavid du Colombier 
10180ee5cbfSDavid du Colombier 	y->hi = yhi;
10280ee5cbfSDavid du Colombier 	y->lo = ylo;
10380ee5cbfSDavid du Colombier }
10480ee5cbfSDavid du Colombier 
10580ee5cbfSDavid du Colombier void
_f2v(Vlong * y,float f)10680ee5cbfSDavid du Colombier _f2v(Vlong *y, float f)
10780ee5cbfSDavid du Colombier {
10880ee5cbfSDavid du Colombier 	_d2v(y, f);
10980ee5cbfSDavid du Colombier }
11080ee5cbfSDavid du Colombier 
11180ee5cbfSDavid du Colombier double
_v2d(Vlong x)11280ee5cbfSDavid du Colombier _v2d(Vlong x)
11380ee5cbfSDavid du Colombier {
11480ee5cbfSDavid du Colombier 	if(x.hi & SIGN(32)) {
11580ee5cbfSDavid du Colombier 		if(x.lo) {
11680ee5cbfSDavid du Colombier 			x.lo = -x.lo;
11780ee5cbfSDavid du Colombier 			x.hi = ~x.hi;
11880ee5cbfSDavid du Colombier 		} else
11980ee5cbfSDavid du Colombier 			x.hi = -x.hi;
12080ee5cbfSDavid du Colombier 		return -((long)x.hi*4294967296. + x.lo);
12180ee5cbfSDavid du Colombier 	}
12280ee5cbfSDavid du Colombier 	return (long)x.hi*4294967296. + x.lo;
12380ee5cbfSDavid du Colombier }
12480ee5cbfSDavid du Colombier 
12580ee5cbfSDavid du Colombier float
_v2f(Vlong x)12680ee5cbfSDavid du Colombier _v2f(Vlong x)
12780ee5cbfSDavid du Colombier {
12880ee5cbfSDavid du Colombier 	return _v2d(x);
12980ee5cbfSDavid du Colombier }
13080ee5cbfSDavid du Colombier 
13180ee5cbfSDavid du Colombier 
13280ee5cbfSDavid du Colombier static void
dodiv(Vlong num,Vlong den,Vlong * q,Vlong * r)13380ee5cbfSDavid du Colombier dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
13480ee5cbfSDavid du Colombier {
13580ee5cbfSDavid du Colombier 	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
13680ee5cbfSDavid du Colombier 	int i;
13780ee5cbfSDavid du Colombier 
13880ee5cbfSDavid du Colombier 	numhi = num.hi;
13980ee5cbfSDavid du Colombier 	numlo = num.lo;
14080ee5cbfSDavid du Colombier 	denhi = den.hi;
14180ee5cbfSDavid du Colombier 	denlo = den.lo;
14280ee5cbfSDavid du Colombier 	/*
14380ee5cbfSDavid du Colombier 	 * get a divide by zero
14480ee5cbfSDavid du Colombier 	 */
14580ee5cbfSDavid du Colombier 	if(denlo==0 && denhi==0) {
14680ee5cbfSDavid du Colombier 		numlo = numlo / denlo;
14780ee5cbfSDavid du Colombier 	}
14880ee5cbfSDavid du Colombier 
14980ee5cbfSDavid du Colombier 	/*
15080ee5cbfSDavid du Colombier 	 * set up the divisor and find the number of iterations needed
15180ee5cbfSDavid du Colombier 	 */
15280ee5cbfSDavid du Colombier 	if(numhi >= SIGN(32)) {
15380ee5cbfSDavid du Colombier 		quohi = SIGN(32);
15480ee5cbfSDavid du Colombier 		quolo = 0;
15580ee5cbfSDavid du Colombier 	} else {
15680ee5cbfSDavid du Colombier 		quohi = numhi;
15780ee5cbfSDavid du Colombier 		quolo = numlo;
15880ee5cbfSDavid du Colombier 	}
15980ee5cbfSDavid du Colombier 	i = 0;
16080ee5cbfSDavid du Colombier 	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
16180ee5cbfSDavid du Colombier 		denhi = (denhi<<1) | (denlo>>31);
16280ee5cbfSDavid du Colombier 		denlo <<= 1;
16380ee5cbfSDavid du Colombier 		i++;
16480ee5cbfSDavid du Colombier 	}
16580ee5cbfSDavid du Colombier 
16680ee5cbfSDavid du Colombier 	quohi = 0;
16780ee5cbfSDavid du Colombier 	quolo = 0;
16880ee5cbfSDavid du Colombier 	for(; i >= 0; i--) {
16980ee5cbfSDavid du Colombier 		quohi = (quohi<<1) | (quolo>>31);
17080ee5cbfSDavid du Colombier 		quolo <<= 1;
17180ee5cbfSDavid du Colombier 		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
17280ee5cbfSDavid du Colombier 			t = numlo;
17380ee5cbfSDavid du Colombier 			numlo -= denlo;
17480ee5cbfSDavid du Colombier 			if(numlo > t)
17580ee5cbfSDavid du Colombier 				numhi--;
17680ee5cbfSDavid du Colombier 			numhi -= denhi;
17780ee5cbfSDavid du Colombier 			quolo |= 1;
17880ee5cbfSDavid du Colombier 		}
17980ee5cbfSDavid du Colombier 		denlo = (denlo>>1) | (denhi<<31);
18080ee5cbfSDavid du Colombier 		denhi >>= 1;
18180ee5cbfSDavid du Colombier 	}
18280ee5cbfSDavid du Colombier 
18380ee5cbfSDavid du Colombier 	if(q) {
18480ee5cbfSDavid du Colombier 		q->lo = quolo;
18580ee5cbfSDavid du Colombier 		q->hi = quohi;
18680ee5cbfSDavid du Colombier 	}
18780ee5cbfSDavid du Colombier 	if(r) {
18880ee5cbfSDavid du Colombier 		r->lo = numlo;
18980ee5cbfSDavid du Colombier 		r->hi = numhi;
19080ee5cbfSDavid du Colombier 	}
19180ee5cbfSDavid du Colombier }
19280ee5cbfSDavid du Colombier 
19380ee5cbfSDavid du Colombier void
_divvu(Vlong * q,Vlong n,Vlong d)19480ee5cbfSDavid du Colombier _divvu(Vlong *q, Vlong n, Vlong d)
19580ee5cbfSDavid du Colombier {
19680ee5cbfSDavid du Colombier 	if(n.hi == 0 && d.hi == 0) {
19780ee5cbfSDavid du Colombier 		q->hi = 0;
19880ee5cbfSDavid du Colombier 		q->lo = n.lo / d.lo;
19980ee5cbfSDavid du Colombier 		return;
20080ee5cbfSDavid du Colombier 	}
20180ee5cbfSDavid du Colombier 	dodiv(n, d, q, 0);
20280ee5cbfSDavid du Colombier }
20380ee5cbfSDavid du Colombier 
20480ee5cbfSDavid du Colombier void
_modvu(Vlong * r,Vlong n,Vlong d)20580ee5cbfSDavid du Colombier _modvu(Vlong *r, Vlong n, Vlong d)
20680ee5cbfSDavid du Colombier {
20780ee5cbfSDavid du Colombier 
20880ee5cbfSDavid du Colombier 	if(n.hi == 0 && d.hi == 0) {
20980ee5cbfSDavid du Colombier 		r->hi = 0;
21080ee5cbfSDavid du Colombier 		r->lo = n.lo % d.lo;
21180ee5cbfSDavid du Colombier 		return;
21280ee5cbfSDavid du Colombier 	}
21380ee5cbfSDavid du Colombier 	dodiv(n, d, 0, r);
21480ee5cbfSDavid du Colombier }
21580ee5cbfSDavid du Colombier 
21680ee5cbfSDavid du Colombier static void
vneg(Vlong * v)21780ee5cbfSDavid du Colombier vneg(Vlong *v)
21880ee5cbfSDavid du Colombier {
21980ee5cbfSDavid du Colombier 
22080ee5cbfSDavid du Colombier 	if(v->lo == 0) {
22180ee5cbfSDavid du Colombier 		v->hi = -v->hi;
22280ee5cbfSDavid du Colombier 		return;
22380ee5cbfSDavid du Colombier 	}
22480ee5cbfSDavid du Colombier 	v->lo = -v->lo;
22580ee5cbfSDavid du Colombier 	v->hi = ~v->hi;
22680ee5cbfSDavid du Colombier }
22780ee5cbfSDavid du Colombier 
22880ee5cbfSDavid du Colombier void
_divv(Vlong * q,Vlong n,Vlong d)22980ee5cbfSDavid du Colombier _divv(Vlong *q, Vlong n, Vlong d)
23080ee5cbfSDavid du Colombier {
23180ee5cbfSDavid du Colombier 	long nneg, dneg;
23280ee5cbfSDavid du Colombier 
23380ee5cbfSDavid du Colombier 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
23480ee5cbfSDavid du Colombier 		q->lo = (long)n.lo / (long)d.lo;
23580ee5cbfSDavid du Colombier 		q->hi = ((long)q->lo) >> 31;
23680ee5cbfSDavid du Colombier 		return;
23780ee5cbfSDavid du Colombier 	}
23880ee5cbfSDavid du Colombier 	nneg = n.hi >> 31;
23980ee5cbfSDavid du Colombier 	if(nneg)
24080ee5cbfSDavid du Colombier 		vneg(&n);
24180ee5cbfSDavid du Colombier 	dneg = d.hi >> 31;
24280ee5cbfSDavid du Colombier 	if(dneg)
24380ee5cbfSDavid du Colombier 		vneg(&d);
24480ee5cbfSDavid du Colombier 	dodiv(n, d, q, 0);
24580ee5cbfSDavid du Colombier 	if(nneg != dneg)
24680ee5cbfSDavid du Colombier 		vneg(q);
24780ee5cbfSDavid du Colombier }
24880ee5cbfSDavid du Colombier 
24980ee5cbfSDavid du Colombier void
_modv(Vlong * r,Vlong n,Vlong d)25080ee5cbfSDavid du Colombier _modv(Vlong *r, Vlong n, Vlong d)
25180ee5cbfSDavid du Colombier {
25280ee5cbfSDavid du Colombier 	long nneg, dneg;
25380ee5cbfSDavid du Colombier 
25480ee5cbfSDavid du Colombier 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
25580ee5cbfSDavid du Colombier 		r->lo = (long)n.lo % (long)d.lo;
25680ee5cbfSDavid du Colombier 		r->hi = ((long)r->lo) >> 31;
25780ee5cbfSDavid du Colombier 		return;
25880ee5cbfSDavid du Colombier 	}
25980ee5cbfSDavid du Colombier 	nneg = n.hi >> 31;
26080ee5cbfSDavid du Colombier 	if(nneg)
26180ee5cbfSDavid du Colombier 		vneg(&n);
26280ee5cbfSDavid du Colombier 	dneg = d.hi >> 31;
26380ee5cbfSDavid du Colombier 	if(dneg)
26480ee5cbfSDavid du Colombier 		vneg(&d);
26580ee5cbfSDavid du Colombier 	dodiv(n, d, 0, r);
26680ee5cbfSDavid du Colombier 	if(nneg)
26780ee5cbfSDavid du Colombier 		vneg(r);
26880ee5cbfSDavid du Colombier }
26980ee5cbfSDavid du Colombier 
27080ee5cbfSDavid du Colombier void
_rshav(Vlong * r,Vlong a,int b)27180ee5cbfSDavid du Colombier _rshav(Vlong *r, Vlong a, int b)
27280ee5cbfSDavid du Colombier {
27380ee5cbfSDavid du Colombier 	long t;
27480ee5cbfSDavid du Colombier 
27580ee5cbfSDavid du Colombier 	t = a.hi;
27680ee5cbfSDavid du Colombier 	if(b >= 32) {
27780ee5cbfSDavid du Colombier 		r->hi = t>>31;
27880ee5cbfSDavid du Colombier 		if(b >= 64) {
27980ee5cbfSDavid du Colombier 			/* this is illegal re C standard */
28080ee5cbfSDavid du Colombier 			r->lo = t>>31;
28180ee5cbfSDavid du Colombier 			return;
28280ee5cbfSDavid du Colombier 		}
28380ee5cbfSDavid du Colombier 		r->lo = t >> (b-32);
28480ee5cbfSDavid du Colombier 		return;
28580ee5cbfSDavid du Colombier 	}
28680ee5cbfSDavid du Colombier 	if(b <= 0) {
28780ee5cbfSDavid du Colombier 		r->hi = t;
28880ee5cbfSDavid du Colombier 		r->lo = a.lo;
28980ee5cbfSDavid du Colombier 		return;
29080ee5cbfSDavid du Colombier 	}
29180ee5cbfSDavid du Colombier 	r->hi = t >> b;
29280ee5cbfSDavid du Colombier 	r->lo = (t << (32-b)) | (a.lo >> b);
29380ee5cbfSDavid du Colombier }
29480ee5cbfSDavid du Colombier 
29580ee5cbfSDavid du Colombier void
_rshlv(Vlong * r,Vlong a,int b)29680ee5cbfSDavid du Colombier _rshlv(Vlong *r, Vlong a, int b)
29780ee5cbfSDavid du Colombier {
29880ee5cbfSDavid du Colombier 	ulong t;
29980ee5cbfSDavid du Colombier 
30080ee5cbfSDavid du Colombier 	t = a.hi;
30180ee5cbfSDavid du Colombier 	if(b >= 32) {
30280ee5cbfSDavid du Colombier 		r->hi = 0;
30380ee5cbfSDavid du Colombier 		if(b >= 64) {
30480ee5cbfSDavid du Colombier 			/* this is illegal re C standard */
30580ee5cbfSDavid du Colombier 			r->lo = 0;
30680ee5cbfSDavid du Colombier 			return;
30780ee5cbfSDavid du Colombier 		}
30880ee5cbfSDavid du Colombier 		r->lo = t >> (b-32);
30980ee5cbfSDavid du Colombier 		return;
31080ee5cbfSDavid du Colombier 	}
31180ee5cbfSDavid du Colombier 	if(b <= 0) {
31280ee5cbfSDavid du Colombier 		r->hi = t;
31380ee5cbfSDavid du Colombier 		r->lo = a.lo;
31480ee5cbfSDavid du Colombier 		return;
31580ee5cbfSDavid du Colombier 	}
31680ee5cbfSDavid du Colombier 	r->hi = t >> b;
31780ee5cbfSDavid du Colombier 	r->lo = (t << (32-b)) | (a.lo >> b);
31880ee5cbfSDavid du Colombier }
31980ee5cbfSDavid du Colombier 
32080ee5cbfSDavid du Colombier void
_lshv(Vlong * r,Vlong a,int b)32180ee5cbfSDavid du Colombier _lshv(Vlong *r, Vlong a, int b)
32280ee5cbfSDavid du Colombier {
32380ee5cbfSDavid du Colombier 	ulong t;
32480ee5cbfSDavid du Colombier 
32580ee5cbfSDavid du Colombier 	t = a.lo;
32680ee5cbfSDavid du Colombier 	if(b >= 32) {
32780ee5cbfSDavid du Colombier 		r->lo = 0;
32880ee5cbfSDavid du Colombier 		if(b >= 64) {
32980ee5cbfSDavid du Colombier 			/* this is illegal re C standard */
33080ee5cbfSDavid du Colombier 			r->hi = 0;
33180ee5cbfSDavid du Colombier 			return;
33280ee5cbfSDavid du Colombier 		}
33380ee5cbfSDavid du Colombier 		r->hi = t << (b-32);
33480ee5cbfSDavid du Colombier 		return;
33580ee5cbfSDavid du Colombier 	}
33680ee5cbfSDavid du Colombier 	if(b <= 0) {
33780ee5cbfSDavid du Colombier 		r->lo = t;
33880ee5cbfSDavid du Colombier 		r->hi = a.hi;
33980ee5cbfSDavid du Colombier 		return;
34080ee5cbfSDavid du Colombier 	}
34180ee5cbfSDavid du Colombier 	r->lo = t << b;
34280ee5cbfSDavid du Colombier 	r->hi = (t >> (32-b)) | (a.hi << b);
34380ee5cbfSDavid du Colombier }
34480ee5cbfSDavid du Colombier 
34580ee5cbfSDavid du Colombier void
_andv(Vlong * r,Vlong a,Vlong b)34680ee5cbfSDavid du Colombier _andv(Vlong *r, Vlong a, Vlong b)
34780ee5cbfSDavid du Colombier {
34880ee5cbfSDavid du Colombier 	r->hi = a.hi & b.hi;
34980ee5cbfSDavid du Colombier 	r->lo = a.lo & b.lo;
35080ee5cbfSDavid du Colombier }
35180ee5cbfSDavid du Colombier 
35280ee5cbfSDavid du Colombier void
_orv(Vlong * r,Vlong a,Vlong b)35380ee5cbfSDavid du Colombier _orv(Vlong *r, Vlong a, Vlong b)
35480ee5cbfSDavid du Colombier {
35580ee5cbfSDavid du Colombier 	r->hi = a.hi | b.hi;
35680ee5cbfSDavid du Colombier 	r->lo = a.lo | b.lo;
35780ee5cbfSDavid du Colombier }
35880ee5cbfSDavid du Colombier 
35980ee5cbfSDavid du Colombier void
_xorv(Vlong * r,Vlong a,Vlong b)36080ee5cbfSDavid du Colombier _xorv(Vlong *r, Vlong a, Vlong b)
36180ee5cbfSDavid du Colombier {
36280ee5cbfSDavid du Colombier 	r->hi = a.hi ^ b.hi;
36380ee5cbfSDavid du Colombier 	r->lo = a.lo ^ b.lo;
36480ee5cbfSDavid du Colombier }
36580ee5cbfSDavid du Colombier 
36680ee5cbfSDavid du Colombier void
_vpp(Vlong * l,Vlong * r)36780ee5cbfSDavid du Colombier _vpp(Vlong *l, Vlong *r)
36880ee5cbfSDavid du Colombier {
36980ee5cbfSDavid du Colombier 
37080ee5cbfSDavid du Colombier 	l->hi = r->hi;
37180ee5cbfSDavid du Colombier 	l->lo = r->lo;
37280ee5cbfSDavid du Colombier 	r->lo++;
37380ee5cbfSDavid du Colombier 	if(r->lo == 0)
37480ee5cbfSDavid du Colombier 		r->hi++;
37580ee5cbfSDavid du Colombier }
37680ee5cbfSDavid du Colombier 
37780ee5cbfSDavid du Colombier void
_vmm(Vlong * l,Vlong * r)37880ee5cbfSDavid du Colombier _vmm(Vlong *l, Vlong *r)
37980ee5cbfSDavid du Colombier {
38080ee5cbfSDavid du Colombier 
38180ee5cbfSDavid du Colombier 	l->hi = r->hi;
38280ee5cbfSDavid du Colombier 	l->lo = r->lo;
38380ee5cbfSDavid du Colombier 	if(r->lo == 0)
38480ee5cbfSDavid du Colombier 		r->hi--;
38580ee5cbfSDavid du Colombier 	r->lo--;
38680ee5cbfSDavid du Colombier }
38780ee5cbfSDavid du Colombier 
38880ee5cbfSDavid du Colombier void
_ppv(Vlong * l,Vlong * r)38980ee5cbfSDavid du Colombier _ppv(Vlong *l, Vlong *r)
39080ee5cbfSDavid du Colombier {
39180ee5cbfSDavid du Colombier 
39280ee5cbfSDavid du Colombier 	r->lo++;
39380ee5cbfSDavid du Colombier 	if(r->lo == 0)
39480ee5cbfSDavid du Colombier 		r->hi++;
39580ee5cbfSDavid du Colombier 	l->hi = r->hi;
39680ee5cbfSDavid du Colombier 	l->lo = r->lo;
39780ee5cbfSDavid du Colombier }
39880ee5cbfSDavid du Colombier 
39980ee5cbfSDavid du Colombier void
_mmv(Vlong * l,Vlong * r)40080ee5cbfSDavid du Colombier _mmv(Vlong *l, Vlong *r)
40180ee5cbfSDavid du Colombier {
40280ee5cbfSDavid du Colombier 
40380ee5cbfSDavid du Colombier 	if(r->lo == 0)
40480ee5cbfSDavid du Colombier 		r->hi--;
40580ee5cbfSDavid du Colombier 	r->lo--;
40680ee5cbfSDavid du Colombier 	l->hi = r->hi;
40780ee5cbfSDavid du Colombier 	l->lo = r->lo;
40880ee5cbfSDavid du Colombier }
40980ee5cbfSDavid du Colombier 
41080ee5cbfSDavid du Colombier void
_vasop(Vlong * ret,void * lv,void fn (Vlong *,Vlong,Vlong),int type,Vlong rv)41180ee5cbfSDavid du Colombier _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
41280ee5cbfSDavid du Colombier {
41380ee5cbfSDavid du Colombier 	Vlong t, u;
41480ee5cbfSDavid du Colombier 
41580ee5cbfSDavid du Colombier 	u = *ret;
41680ee5cbfSDavid du Colombier 	switch(type) {
41780ee5cbfSDavid du Colombier 	default:
41880ee5cbfSDavid du Colombier 		abort();
41980ee5cbfSDavid du Colombier 		break;
42080ee5cbfSDavid du Colombier 
42180ee5cbfSDavid du Colombier 	case 1:	/* schar */
42280ee5cbfSDavid du Colombier 		t.lo = *(schar*)lv;
42380ee5cbfSDavid du Colombier 		t.hi = t.lo >> 31;
42480ee5cbfSDavid du Colombier 		fn(&u, t, rv);
42580ee5cbfSDavid du Colombier 		*(schar*)lv = u.lo;
42680ee5cbfSDavid du Colombier 		break;
42780ee5cbfSDavid du Colombier 
42880ee5cbfSDavid du Colombier 	case 2:	/* uchar */
42980ee5cbfSDavid du Colombier 		t.lo = *(uchar*)lv;
43080ee5cbfSDavid du Colombier 		t.hi = 0;
43180ee5cbfSDavid du Colombier 		fn(&u, t, rv);
43280ee5cbfSDavid du Colombier 		*(uchar*)lv = u.lo;
43380ee5cbfSDavid du Colombier 		break;
43480ee5cbfSDavid du Colombier 
43580ee5cbfSDavid du Colombier 	case 3:	/* short */
43680ee5cbfSDavid du Colombier 		t.lo = *(short*)lv;
43780ee5cbfSDavid du Colombier 		t.hi = t.lo >> 31;
43880ee5cbfSDavid du Colombier 		fn(&u, t, rv);
43980ee5cbfSDavid du Colombier 		*(short*)lv = u.lo;
44080ee5cbfSDavid du Colombier 		break;
44180ee5cbfSDavid du Colombier 
44280ee5cbfSDavid du Colombier 	case 4:	/* ushort */
44380ee5cbfSDavid du Colombier 		t.lo = *(ushort*)lv;
44480ee5cbfSDavid du Colombier 		t.hi = 0;
44580ee5cbfSDavid du Colombier 		fn(&u, t, rv);
44680ee5cbfSDavid du Colombier 		*(ushort*)lv = u.lo;
44780ee5cbfSDavid du Colombier 		break;
44880ee5cbfSDavid du Colombier 
44980ee5cbfSDavid du Colombier 	case 9:	/* int */
45080ee5cbfSDavid du Colombier 		t.lo = *(int*)lv;
45180ee5cbfSDavid du Colombier 		t.hi = t.lo >> 31;
45280ee5cbfSDavid du Colombier 		fn(&u, t, rv);
45380ee5cbfSDavid du Colombier 		*(int*)lv = u.lo;
45480ee5cbfSDavid du Colombier 		break;
45580ee5cbfSDavid du Colombier 
45680ee5cbfSDavid du Colombier 	case 10:	/* uint */
45780ee5cbfSDavid du Colombier 		t.lo = *(uint*)lv;
45880ee5cbfSDavid du Colombier 		t.hi = 0;
45980ee5cbfSDavid du Colombier 		fn(&u, t, rv);
46080ee5cbfSDavid du Colombier 		*(uint*)lv = u.lo;
46180ee5cbfSDavid du Colombier 		break;
46280ee5cbfSDavid du Colombier 
46380ee5cbfSDavid du Colombier 	case 5:	/* long */
46480ee5cbfSDavid du Colombier 		t.lo = *(long*)lv;
46580ee5cbfSDavid du Colombier 		t.hi = t.lo >> 31;
46680ee5cbfSDavid du Colombier 		fn(&u, t, rv);
46780ee5cbfSDavid du Colombier 		*(long*)lv = u.lo;
46880ee5cbfSDavid du Colombier 		break;
46980ee5cbfSDavid du Colombier 
47080ee5cbfSDavid du Colombier 	case 6:	/* ulong */
47180ee5cbfSDavid du Colombier 		t.lo = *(ulong*)lv;
47280ee5cbfSDavid du Colombier 		t.hi = 0;
47380ee5cbfSDavid du Colombier 		fn(&u, t, rv);
47480ee5cbfSDavid du Colombier 		*(ulong*)lv = u.lo;
47580ee5cbfSDavid du Colombier 		break;
47680ee5cbfSDavid du Colombier 
47780ee5cbfSDavid du Colombier 	case 7:	/* vlong */
47880ee5cbfSDavid du Colombier 	case 8:	/* uvlong */
47980ee5cbfSDavid du Colombier 		fn(&u, *(Vlong*)lv, rv);
48080ee5cbfSDavid du Colombier 		*(Vlong*)lv = u;
48180ee5cbfSDavid du Colombier 		break;
48280ee5cbfSDavid du Colombier 	}
48380ee5cbfSDavid du Colombier 	*ret = u;
48480ee5cbfSDavid du Colombier }
48580ee5cbfSDavid du Colombier 
48680ee5cbfSDavid du Colombier void
_p2v(Vlong * ret,void * p)48780ee5cbfSDavid du Colombier _p2v(Vlong *ret, void *p)
48880ee5cbfSDavid du Colombier {
48980ee5cbfSDavid du Colombier 	long t;
49080ee5cbfSDavid du Colombier 
49180ee5cbfSDavid du Colombier 	t = (ulong)p;
49280ee5cbfSDavid du Colombier 	ret->lo = t;
49380ee5cbfSDavid du Colombier 	ret->hi = 0;
49480ee5cbfSDavid du Colombier }
49580ee5cbfSDavid du Colombier 
49680ee5cbfSDavid du Colombier void
_sl2v(Vlong * ret,long sl)49780ee5cbfSDavid du Colombier _sl2v(Vlong *ret, long sl)
49880ee5cbfSDavid du Colombier {
49980ee5cbfSDavid du Colombier 	long t;
50080ee5cbfSDavid du Colombier 
50180ee5cbfSDavid du Colombier 	t = sl;
50280ee5cbfSDavid du Colombier 	ret->lo = t;
50380ee5cbfSDavid du Colombier 	ret->hi = t >> 31;
50480ee5cbfSDavid du Colombier }
50580ee5cbfSDavid du Colombier 
50680ee5cbfSDavid du Colombier void
_ul2v(Vlong * ret,ulong ul)50780ee5cbfSDavid du Colombier _ul2v(Vlong *ret, ulong ul)
50880ee5cbfSDavid du Colombier {
50980ee5cbfSDavid du Colombier 	long t;
51080ee5cbfSDavid du Colombier 
51180ee5cbfSDavid du Colombier 	t = ul;
51280ee5cbfSDavid du Colombier 	ret->lo = t;
51380ee5cbfSDavid du Colombier 	ret->hi = 0;
51480ee5cbfSDavid du Colombier }
51580ee5cbfSDavid du Colombier 
51680ee5cbfSDavid du Colombier void
_si2v(Vlong * ret,int si)51780ee5cbfSDavid du Colombier _si2v(Vlong *ret, int si)
51880ee5cbfSDavid du Colombier {
51980ee5cbfSDavid du Colombier 	long t;
52080ee5cbfSDavid du Colombier 
52180ee5cbfSDavid du Colombier 	t = si;
52280ee5cbfSDavid du Colombier 	ret->lo = t;
52380ee5cbfSDavid du Colombier 	ret->hi = t >> 31;
52480ee5cbfSDavid du Colombier }
52580ee5cbfSDavid du Colombier 
52680ee5cbfSDavid du Colombier void
_ui2v(Vlong * ret,uint ui)52780ee5cbfSDavid du Colombier _ui2v(Vlong *ret, uint ui)
52880ee5cbfSDavid du Colombier {
52980ee5cbfSDavid du Colombier 	long t;
53080ee5cbfSDavid du Colombier 
53180ee5cbfSDavid du Colombier 	t = ui;
53280ee5cbfSDavid du Colombier 	ret->lo = t;
53380ee5cbfSDavid du Colombier 	ret->hi = 0;
53480ee5cbfSDavid du Colombier }
53580ee5cbfSDavid du Colombier 
53680ee5cbfSDavid du Colombier void
_sh2v(Vlong * ret,long sh)53780ee5cbfSDavid du Colombier _sh2v(Vlong *ret, long sh)
53880ee5cbfSDavid du Colombier {
53980ee5cbfSDavid du Colombier 	long t;
54080ee5cbfSDavid du Colombier 
54180ee5cbfSDavid du Colombier 	t = (sh << 16) >> 16;
54280ee5cbfSDavid du Colombier 	ret->lo = t;
54380ee5cbfSDavid du Colombier 	ret->hi = t >> 31;
54480ee5cbfSDavid du Colombier }
54580ee5cbfSDavid du Colombier 
54680ee5cbfSDavid du Colombier void
_uh2v(Vlong * ret,ulong ul)54780ee5cbfSDavid du Colombier _uh2v(Vlong *ret, ulong ul)
54880ee5cbfSDavid du Colombier {
54980ee5cbfSDavid du Colombier 	long t;
55080ee5cbfSDavid du Colombier 
55180ee5cbfSDavid du Colombier 	t = ul & 0xffff;
55280ee5cbfSDavid du Colombier 	ret->lo = t;
55380ee5cbfSDavid du Colombier 	ret->hi = 0;
55480ee5cbfSDavid du Colombier }
55580ee5cbfSDavid du Colombier 
55680ee5cbfSDavid du Colombier void
_sc2v(Vlong * ret,long uc)55780ee5cbfSDavid du Colombier _sc2v(Vlong *ret, long uc)
55880ee5cbfSDavid du Colombier {
55980ee5cbfSDavid du Colombier 	long t;
56080ee5cbfSDavid du Colombier 
56180ee5cbfSDavid du Colombier 	t = (uc << 24) >> 24;
56280ee5cbfSDavid du Colombier 	ret->lo = t;
56380ee5cbfSDavid du Colombier 	ret->hi = t >> 31;
56480ee5cbfSDavid du Colombier }
56580ee5cbfSDavid du Colombier 
56680ee5cbfSDavid du Colombier void
_uc2v(Vlong * ret,ulong ul)56780ee5cbfSDavid du Colombier _uc2v(Vlong *ret, ulong ul)
56880ee5cbfSDavid du Colombier {
56980ee5cbfSDavid du Colombier 	long t;
57080ee5cbfSDavid du Colombier 
57180ee5cbfSDavid du Colombier 	t = ul & 0xff;
57280ee5cbfSDavid du Colombier 	ret->lo = t;
57380ee5cbfSDavid du Colombier 	ret->hi = 0;
57480ee5cbfSDavid du Colombier }
57580ee5cbfSDavid du Colombier 
57680ee5cbfSDavid du Colombier long
_v2sc(Vlong rv)57780ee5cbfSDavid du Colombier _v2sc(Vlong rv)
57880ee5cbfSDavid du Colombier {
57980ee5cbfSDavid du Colombier 	long t;
58080ee5cbfSDavid du Colombier 
58180ee5cbfSDavid du Colombier 	t = rv.lo & 0xff;
58280ee5cbfSDavid du Colombier 	return (t << 24) >> 24;
58380ee5cbfSDavid du Colombier }
58480ee5cbfSDavid du Colombier 
58580ee5cbfSDavid du Colombier long
_v2uc(Vlong rv)58680ee5cbfSDavid du Colombier _v2uc(Vlong rv)
58780ee5cbfSDavid du Colombier {
58880ee5cbfSDavid du Colombier 
58980ee5cbfSDavid du Colombier 	return rv.lo & 0xff;
59080ee5cbfSDavid du Colombier }
59180ee5cbfSDavid du Colombier 
59280ee5cbfSDavid du Colombier long
_v2sh(Vlong rv)59380ee5cbfSDavid du Colombier _v2sh(Vlong rv)
59480ee5cbfSDavid du Colombier {
59580ee5cbfSDavid du Colombier 	long t;
59680ee5cbfSDavid du Colombier 
59780ee5cbfSDavid du Colombier 	t = rv.lo & 0xffff;
59880ee5cbfSDavid du Colombier 	return (t << 16) >> 16;
59980ee5cbfSDavid du Colombier }
60080ee5cbfSDavid du Colombier 
60180ee5cbfSDavid du Colombier long
_v2uh(Vlong rv)60280ee5cbfSDavid du Colombier _v2uh(Vlong rv)
60380ee5cbfSDavid du Colombier {
60480ee5cbfSDavid du Colombier 
60580ee5cbfSDavid du Colombier 	return rv.lo & 0xffff;
60680ee5cbfSDavid du Colombier }
60780ee5cbfSDavid du Colombier 
60880ee5cbfSDavid du Colombier long
_v2sl(Vlong rv)60980ee5cbfSDavid du Colombier _v2sl(Vlong rv)
61080ee5cbfSDavid du Colombier {
61180ee5cbfSDavid du Colombier 
61280ee5cbfSDavid du Colombier 	return rv.lo;
61380ee5cbfSDavid du Colombier }
61480ee5cbfSDavid du Colombier 
61580ee5cbfSDavid du Colombier long
_v2ul(Vlong rv)61680ee5cbfSDavid du Colombier _v2ul(Vlong rv)
61780ee5cbfSDavid du Colombier {
61880ee5cbfSDavid du Colombier 
61980ee5cbfSDavid du Colombier 	return rv.lo;
62080ee5cbfSDavid du Colombier }
62180ee5cbfSDavid du Colombier 
62280ee5cbfSDavid du Colombier long
_v2si(Vlong rv)62380ee5cbfSDavid du Colombier _v2si(Vlong rv)
62480ee5cbfSDavid du Colombier {
62580ee5cbfSDavid du Colombier 
62680ee5cbfSDavid du Colombier 	return rv.lo;
62780ee5cbfSDavid du Colombier }
62880ee5cbfSDavid du Colombier 
62980ee5cbfSDavid du Colombier long
_v2ui(Vlong rv)63080ee5cbfSDavid du Colombier _v2ui(Vlong rv)
63180ee5cbfSDavid du Colombier {
63280ee5cbfSDavid du Colombier 
63380ee5cbfSDavid du Colombier 	return rv.lo;
63480ee5cbfSDavid du Colombier }
63580ee5cbfSDavid du Colombier 
63680ee5cbfSDavid du Colombier int
_testv(Vlong rv)63780ee5cbfSDavid du Colombier _testv(Vlong rv)
63880ee5cbfSDavid du Colombier {
63980ee5cbfSDavid du Colombier 	return rv.lo || rv.hi;
64080ee5cbfSDavid du Colombier }
64180ee5cbfSDavid du Colombier 
64280ee5cbfSDavid du Colombier int
_eqv(Vlong lv,Vlong rv)64380ee5cbfSDavid du Colombier _eqv(Vlong lv, Vlong rv)
64480ee5cbfSDavid du Colombier {
64580ee5cbfSDavid du Colombier 	return lv.lo == rv.lo && lv.hi == rv.hi;
64680ee5cbfSDavid du Colombier }
64780ee5cbfSDavid du Colombier 
64880ee5cbfSDavid du Colombier int
_nev(Vlong lv,Vlong rv)64980ee5cbfSDavid du Colombier _nev(Vlong lv, Vlong rv)
65080ee5cbfSDavid du Colombier {
65180ee5cbfSDavid du Colombier 	return lv.lo != rv.lo || lv.hi != rv.hi;
65280ee5cbfSDavid du Colombier }
65380ee5cbfSDavid du Colombier 
65480ee5cbfSDavid du Colombier int
_ltv(Vlong lv,Vlong rv)65580ee5cbfSDavid du Colombier _ltv(Vlong lv, Vlong rv)
65680ee5cbfSDavid du Colombier {
65780ee5cbfSDavid du Colombier 	return (long)lv.hi < (long)rv.hi ||
65880ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo < rv.lo);
65980ee5cbfSDavid du Colombier }
66080ee5cbfSDavid du Colombier 
66180ee5cbfSDavid du Colombier int
_lev(Vlong lv,Vlong rv)66280ee5cbfSDavid du Colombier _lev(Vlong lv, Vlong rv)
66380ee5cbfSDavid du Colombier {
66480ee5cbfSDavid du Colombier 	return (long)lv.hi < (long)rv.hi ||
66580ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo <= rv.lo);
66680ee5cbfSDavid du Colombier }
66780ee5cbfSDavid du Colombier 
66880ee5cbfSDavid du Colombier int
_gtv(Vlong lv,Vlong rv)66980ee5cbfSDavid du Colombier _gtv(Vlong lv, Vlong rv)
67080ee5cbfSDavid du Colombier {
67180ee5cbfSDavid du Colombier 	return (long)lv.hi > (long)rv.hi ||
67280ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo > rv.lo);
67380ee5cbfSDavid du Colombier }
67480ee5cbfSDavid du Colombier 
67580ee5cbfSDavid du Colombier int
_gev(Vlong lv,Vlong rv)67680ee5cbfSDavid du Colombier _gev(Vlong lv, Vlong rv)
67780ee5cbfSDavid du Colombier {
67880ee5cbfSDavid du Colombier 	return (long)lv.hi > (long)rv.hi ||
67980ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo >= rv.lo);
68080ee5cbfSDavid du Colombier }
68180ee5cbfSDavid du Colombier 
68280ee5cbfSDavid du Colombier int
_lov(Vlong lv,Vlong rv)68380ee5cbfSDavid du Colombier _lov(Vlong lv, Vlong rv)
68480ee5cbfSDavid du Colombier {
68580ee5cbfSDavid du Colombier 	return lv.hi < rv.hi ||
68680ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo < rv.lo);
68780ee5cbfSDavid du Colombier }
68880ee5cbfSDavid du Colombier 
68980ee5cbfSDavid du Colombier int
_lsv(Vlong lv,Vlong rv)69080ee5cbfSDavid du Colombier _lsv(Vlong lv, Vlong rv)
69180ee5cbfSDavid du Colombier {
69280ee5cbfSDavid du Colombier 	return lv.hi < rv.hi ||
69380ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo <= rv.lo);
69480ee5cbfSDavid du Colombier }
69580ee5cbfSDavid du Colombier 
69680ee5cbfSDavid du Colombier int
_hiv(Vlong lv,Vlong rv)69780ee5cbfSDavid du Colombier _hiv(Vlong lv, Vlong rv)
69880ee5cbfSDavid du Colombier {
69980ee5cbfSDavid du Colombier 	return lv.hi > rv.hi ||
70080ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo > rv.lo);
70180ee5cbfSDavid du Colombier }
70280ee5cbfSDavid du Colombier 
70380ee5cbfSDavid du Colombier int
_hsv(Vlong lv,Vlong rv)70480ee5cbfSDavid du Colombier _hsv(Vlong lv, Vlong rv)
70580ee5cbfSDavid du Colombier {
70680ee5cbfSDavid du Colombier 	return lv.hi > rv.hi ||
70780ee5cbfSDavid du Colombier 		(lv.hi == rv.hi && lv.lo >= rv.lo);
70880ee5cbfSDavid du Colombier }
709