xref: /plan9/sys/src/libc/386/vlrt.c (revision 853458f38e7eb3a48cfa3a36aefdb799375e398a)
1219b2ee8SDavid du Colombier typedef	unsigned long	ulong;
27dd7cddfSDavid du Colombier typedef	unsigned int	uint;
3219b2ee8SDavid du Colombier typedef	unsigned short	ushort;
47dd7cddfSDavid du Colombier typedef	unsigned char	uchar;
5219b2ee8SDavid du Colombier typedef	signed char	schar;
6219b2ee8SDavid du Colombier 
7219b2ee8SDavid du Colombier #define	SIGN(n)	(1UL<<(n-1))
8219b2ee8SDavid du Colombier 
9219b2ee8SDavid du Colombier typedef	struct	Vlong	Vlong;
10219b2ee8SDavid du Colombier struct	Vlong
11219b2ee8SDavid du Colombier {
12219b2ee8SDavid du Colombier 	union
13219b2ee8SDavid du Colombier 	{
14219b2ee8SDavid du Colombier 		struct
15219b2ee8SDavid du Colombier 		{
16219b2ee8SDavid du Colombier 			ulong	lo;
17219b2ee8SDavid du Colombier 			ulong	hi;
18219b2ee8SDavid du Colombier 		};
19219b2ee8SDavid du Colombier 		struct
20219b2ee8SDavid du Colombier 		{
21219b2ee8SDavid du Colombier 			ushort	lols;
22219b2ee8SDavid du Colombier 			ushort	loms;
23219b2ee8SDavid du Colombier 			ushort	hils;
24219b2ee8SDavid du Colombier 			ushort	hims;
25219b2ee8SDavid du Colombier 		};
26219b2ee8SDavid du Colombier 	};
27219b2ee8SDavid du Colombier };
28219b2ee8SDavid du Colombier 
29219b2ee8SDavid du Colombier void	abort(void);
30219b2ee8SDavid du Colombier 
31e288d156SDavid du Colombier void _subv(Vlong*, Vlong, Vlong);
32219b2ee8SDavid du Colombier 
33219b2ee8SDavid du Colombier void
_d2v(Vlong * y,double d)34219b2ee8SDavid du Colombier _d2v(Vlong *y, double d)
35219b2ee8SDavid du Colombier {
36219b2ee8SDavid du Colombier 	union { double d; struct Vlong; } x;
37219b2ee8SDavid du Colombier 	ulong xhi, xlo, ylo, yhi;
38219b2ee8SDavid du Colombier 	int sh;
39219b2ee8SDavid du Colombier 
40219b2ee8SDavid du Colombier 	x.d = d;
41219b2ee8SDavid du Colombier 
42219b2ee8SDavid du Colombier 	xhi = (x.hi & 0xfffff) | 0x100000;
43219b2ee8SDavid du Colombier 	xlo = x.lo;
44219b2ee8SDavid du Colombier 	sh = 1075 - ((x.hi >> 20) & 0x7ff);
45219b2ee8SDavid du Colombier 
46219b2ee8SDavid du Colombier 	ylo = 0;
47219b2ee8SDavid du Colombier 	yhi = 0;
48219b2ee8SDavid du Colombier 	if(sh >= 0) {
49219b2ee8SDavid du Colombier 		/* v = (hi||lo) >> sh */
50219b2ee8SDavid du Colombier 		if(sh < 32) {
51219b2ee8SDavid du Colombier 			if(sh == 0) {
52219b2ee8SDavid du Colombier 				ylo = xlo;
53219b2ee8SDavid du Colombier 				yhi = xhi;
54219b2ee8SDavid du Colombier 			} else {
55219b2ee8SDavid du Colombier 				ylo = (xlo >> sh) | (xhi << (32-sh));
56219b2ee8SDavid du Colombier 				yhi = xhi >> sh;
57219b2ee8SDavid du Colombier 			}
58219b2ee8SDavid du Colombier 		} else {
59219b2ee8SDavid du Colombier 			if(sh == 32) {
60219b2ee8SDavid du Colombier 				ylo = xhi;
61219b2ee8SDavid du Colombier 			} else
62219b2ee8SDavid du Colombier 			if(sh < 64) {
63219b2ee8SDavid du Colombier 				ylo = xhi >> (sh-32);
64219b2ee8SDavid du Colombier 			}
65219b2ee8SDavid du Colombier 		}
66219b2ee8SDavid du Colombier 	} else {
67219b2ee8SDavid du Colombier 		/* v = (hi||lo) << -sh */
68219b2ee8SDavid du Colombier 		sh = -sh;
69219b2ee8SDavid du Colombier 		if(sh <= 10) {
70219b2ee8SDavid du Colombier 			ylo = xlo << sh;
71219b2ee8SDavid du Colombier 			yhi = (xhi << sh) | (xlo >> (32-sh));
72219b2ee8SDavid du Colombier 		} else {
73219b2ee8SDavid du Colombier 			/* overflow */
74219b2ee8SDavid du Colombier 			yhi = d;	/* causes something awful */
75219b2ee8SDavid du Colombier 		}
76219b2ee8SDavid du Colombier 	}
777dd7cddfSDavid du Colombier 	if(x.hi & SIGN(32)) {
78219b2ee8SDavid du Colombier 		if(ylo != 0) {
79219b2ee8SDavid du Colombier 			ylo = -ylo;
80219b2ee8SDavid du Colombier 			yhi = ~yhi;
81219b2ee8SDavid du Colombier 		} else
82219b2ee8SDavid du Colombier 			yhi = -yhi;
83219b2ee8SDavid du Colombier 	}
84219b2ee8SDavid du Colombier 
85219b2ee8SDavid du Colombier 	y->hi = yhi;
86219b2ee8SDavid du Colombier 	y->lo = ylo;
87219b2ee8SDavid du Colombier }
88219b2ee8SDavid du Colombier 
89219b2ee8SDavid du Colombier void
_f2v(Vlong * y,float f)90219b2ee8SDavid du Colombier _f2v(Vlong *y, float f)
91219b2ee8SDavid du Colombier {
92219b2ee8SDavid du Colombier 
93219b2ee8SDavid du Colombier 	_d2v(y, f);
94219b2ee8SDavid du Colombier }
95219b2ee8SDavid du Colombier 
96219b2ee8SDavid du Colombier double
_v2d(Vlong x)97219b2ee8SDavid du Colombier _v2d(Vlong x)
98219b2ee8SDavid du Colombier {
997dd7cddfSDavid du Colombier 	if(x.hi & SIGN(32)) {
100219b2ee8SDavid du Colombier 		if(x.lo) {
101219b2ee8SDavid du Colombier 			x.lo = -x.lo;
102219b2ee8SDavid du Colombier 			x.hi = ~x.hi;
103219b2ee8SDavid du Colombier 		} else
104219b2ee8SDavid du Colombier 			x.hi = -x.hi;
105219b2ee8SDavid du Colombier 		return -((long)x.hi*4294967296. + x.lo);
106219b2ee8SDavid du Colombier 	}
107219b2ee8SDavid du Colombier 	return (long)x.hi*4294967296. + x.lo;
108219b2ee8SDavid du Colombier }
109219b2ee8SDavid du Colombier 
110219b2ee8SDavid du Colombier float
_v2f(Vlong x)111219b2ee8SDavid du Colombier _v2f(Vlong x)
112219b2ee8SDavid du Colombier {
113219b2ee8SDavid du Colombier 	return _v2d(x);
114219b2ee8SDavid du Colombier }
115219b2ee8SDavid du Colombier 
1167dd7cddfSDavid du Colombier ulong	_div64by32(Vlong, ulong, ulong*);
117*853458f3SDavid du Colombier int	_mul64by32(Vlong*, Vlong, ulong);
1187dd7cddfSDavid du Colombier 
119219b2ee8SDavid du Colombier static void
slowdodiv(Vlong num,Vlong den,Vlong * q,Vlong * r)1209a747e4fSDavid du Colombier slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
1219a747e4fSDavid du Colombier {
1229a747e4fSDavid du Colombier 	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
1239a747e4fSDavid du Colombier 	int i;
1249a747e4fSDavid du Colombier 
1259a747e4fSDavid du Colombier 	numhi = num.hi;
1269a747e4fSDavid du Colombier 	numlo = num.lo;
1279a747e4fSDavid du Colombier 	denhi = den.hi;
1289a747e4fSDavid du Colombier 	denlo = den.lo;
1299a747e4fSDavid du Colombier 
1309a747e4fSDavid du Colombier 	/*
1319a747e4fSDavid du Colombier 	 * get a divide by zero
1329a747e4fSDavid du Colombier 	 */
1339a747e4fSDavid du Colombier 	if(denlo==0 && denhi==0) {
1349a747e4fSDavid du Colombier 		numlo = numlo / denlo;
1359a747e4fSDavid du Colombier 	}
1369a747e4fSDavid du Colombier 
1379a747e4fSDavid du Colombier 	/*
1389a747e4fSDavid du Colombier 	 * set up the divisor and find the number of iterations needed
1399a747e4fSDavid du Colombier 	 */
1409a747e4fSDavid du Colombier 	if(numhi >= SIGN(32)) {
1419a747e4fSDavid du Colombier 		quohi = SIGN(32);
1429a747e4fSDavid du Colombier 		quolo = 0;
1439a747e4fSDavid du Colombier 	} else {
1449a747e4fSDavid du Colombier 		quohi = numhi;
1459a747e4fSDavid du Colombier 		quolo = numlo;
1469a747e4fSDavid du Colombier 	}
1479a747e4fSDavid du Colombier 	i = 0;
1489a747e4fSDavid du Colombier 	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
1499a747e4fSDavid du Colombier 		denhi = (denhi<<1) | (denlo>>31);
1509a747e4fSDavid du Colombier 		denlo <<= 1;
1519a747e4fSDavid du Colombier 		i++;
1529a747e4fSDavid du Colombier 	}
1539a747e4fSDavid du Colombier 
1549a747e4fSDavid du Colombier 	quohi = 0;
1559a747e4fSDavid du Colombier 	quolo = 0;
1569a747e4fSDavid du Colombier 	for(; i >= 0; i--) {
1579a747e4fSDavid du Colombier 		quohi = (quohi<<1) | (quolo>>31);
1589a747e4fSDavid du Colombier 		quolo <<= 1;
1599a747e4fSDavid du Colombier 		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
1609a747e4fSDavid du Colombier 			t = numlo;
1619a747e4fSDavid du Colombier 			numlo -= denlo;
1629a747e4fSDavid du Colombier 			if(numlo > t)
1639a747e4fSDavid du Colombier 				numhi--;
1649a747e4fSDavid du Colombier 			numhi -= denhi;
1659a747e4fSDavid du Colombier 			quolo |= 1;
1669a747e4fSDavid du Colombier 		}
1679a747e4fSDavid du Colombier 		denlo = (denlo>>1) | (denhi<<31);
1689a747e4fSDavid du Colombier 		denhi >>= 1;
1699a747e4fSDavid du Colombier 	}
1709a747e4fSDavid du Colombier 
1719a747e4fSDavid du Colombier 	if(q) {
1729a747e4fSDavid du Colombier 		q->lo = quolo;
1739a747e4fSDavid du Colombier 		q->hi = quohi;
1749a747e4fSDavid du Colombier 	}
1759a747e4fSDavid du Colombier 	if(r) {
1769a747e4fSDavid du Colombier 		r->lo = numlo;
1779a747e4fSDavid du Colombier 		r->hi = numhi;
1789a747e4fSDavid du Colombier 	}
1799a747e4fSDavid du Colombier }
1809a747e4fSDavid du Colombier 
1819a747e4fSDavid du Colombier static void
dodiv(Vlong num,Vlong den,Vlong * qp,Vlong * rp)1827dd7cddfSDavid du Colombier dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
183219b2ee8SDavid du Colombier {
1847dd7cddfSDavid du Colombier 	ulong n;
1857dd7cddfSDavid du Colombier 	Vlong x, q, r;
186219b2ee8SDavid du Colombier 
1877dd7cddfSDavid du Colombier 	if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){
1887dd7cddfSDavid du Colombier 		if(qp) {
1897dd7cddfSDavid du Colombier 			qp->hi = 0;
1907dd7cddfSDavid du Colombier 			qp->lo = 0;
1917dd7cddfSDavid du Colombier 		}
1927dd7cddfSDavid du Colombier 		if(rp) {
1937dd7cddfSDavid du Colombier 			rp->hi = num.hi;
1947dd7cddfSDavid du Colombier 			rp->lo = num.lo;
1957dd7cddfSDavid du Colombier 		}
1967dd7cddfSDavid du Colombier 		return;
197219b2ee8SDavid du Colombier 	}
198219b2ee8SDavid du Colombier 
1997dd7cddfSDavid du Colombier 	if(den.hi != 0){
2007dd7cddfSDavid du Colombier 		q.hi = 0;
2017dd7cddfSDavid du Colombier 		n = num.hi/den.hi;
202*853458f3SDavid du Colombier 		if(_mul64by32(&x, den, n) || x.hi > num.hi ||
203*853458f3SDavid du Colombier 		    (x.hi == num.hi && x.lo > num.lo))
2049a747e4fSDavid du Colombier 			slowdodiv(num, den, &q, &r);
2059a747e4fSDavid du Colombier 		else {
2067dd7cddfSDavid du Colombier 			q.lo = n;
2077dd7cddfSDavid du Colombier 			_subv(&r, num, x);
2089a747e4fSDavid du Colombier 		}
209219b2ee8SDavid du Colombier 	} else {
2107dd7cddfSDavid du Colombier 		if(num.hi >= den.lo){
2117dd7cddfSDavid du Colombier 			q.hi = n = num.hi/den.lo;
2127dd7cddfSDavid du Colombier 			num.hi -= den.lo*n;
2137dd7cddfSDavid du Colombier 		} else {
2147dd7cddfSDavid du Colombier 			q.hi = 0;
215219b2ee8SDavid du Colombier 		}
2167dd7cddfSDavid du Colombier 		q.lo = _div64by32(num, den.lo, &r.lo);
2177dd7cddfSDavid du Colombier 		r.hi = 0;
218219b2ee8SDavid du Colombier 	}
2197dd7cddfSDavid du Colombier 	if(qp) {
2207dd7cddfSDavid du Colombier 		qp->lo = q.lo;
2217dd7cddfSDavid du Colombier 		qp->hi = q.hi;
222219b2ee8SDavid du Colombier 	}
2237dd7cddfSDavid du Colombier 	if(rp) {
2247dd7cddfSDavid du Colombier 		rp->lo = r.lo;
2257dd7cddfSDavid du Colombier 		rp->hi = r.hi;
226219b2ee8SDavid du Colombier 	}
227219b2ee8SDavid du Colombier }
228219b2ee8SDavid du Colombier 
229219b2ee8SDavid du Colombier void
_divvu(Vlong * q,Vlong n,Vlong d)230219b2ee8SDavid du Colombier _divvu(Vlong *q, Vlong n, Vlong d)
231219b2ee8SDavid du Colombier {
232219b2ee8SDavid du Colombier 
233219b2ee8SDavid du Colombier 	if(n.hi == 0 && d.hi == 0) {
234219b2ee8SDavid du Colombier 		q->hi = 0;
235219b2ee8SDavid du Colombier 		q->lo = n.lo / d.lo;
236219b2ee8SDavid du Colombier 		return;
237219b2ee8SDavid du Colombier 	}
238219b2ee8SDavid du Colombier 	dodiv(n, d, q, 0);
239219b2ee8SDavid du Colombier }
240219b2ee8SDavid du Colombier 
241219b2ee8SDavid du Colombier void
_modvu(Vlong * r,Vlong n,Vlong d)242219b2ee8SDavid du Colombier _modvu(Vlong *r, Vlong n, Vlong d)
243219b2ee8SDavid du Colombier {
244219b2ee8SDavid du Colombier 
245219b2ee8SDavid du Colombier 	if(n.hi == 0 && d.hi == 0) {
246219b2ee8SDavid du Colombier 		r->hi = 0;
247219b2ee8SDavid du Colombier 		r->lo = n.lo % d.lo;
248219b2ee8SDavid du Colombier 		return;
249219b2ee8SDavid du Colombier 	}
250219b2ee8SDavid du Colombier 	dodiv(n, d, 0, r);
251219b2ee8SDavid du Colombier }
252219b2ee8SDavid du Colombier 
253219b2ee8SDavid du Colombier static void
vneg(Vlong * v)254219b2ee8SDavid du Colombier vneg(Vlong *v)
255219b2ee8SDavid du Colombier {
256219b2ee8SDavid du Colombier 
257219b2ee8SDavid du Colombier 	if(v->lo == 0) {
258219b2ee8SDavid du Colombier 		v->hi = -v->hi;
259219b2ee8SDavid du Colombier 		return;
260219b2ee8SDavid du Colombier 	}
261219b2ee8SDavid du Colombier 	v->lo = -v->lo;
262219b2ee8SDavid du Colombier 	v->hi = ~v->hi;
263219b2ee8SDavid du Colombier }
264219b2ee8SDavid du Colombier 
265219b2ee8SDavid du Colombier void
_divv(Vlong * q,Vlong n,Vlong d)266219b2ee8SDavid du Colombier _divv(Vlong *q, Vlong n, Vlong d)
267219b2ee8SDavid du Colombier {
268219b2ee8SDavid du Colombier 	long nneg, dneg;
269219b2ee8SDavid du Colombier 
270219b2ee8SDavid du Colombier 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
271219b2ee8SDavid du Colombier 		q->lo = (long)n.lo / (long)d.lo;
272219b2ee8SDavid du Colombier 		q->hi = ((long)q->lo) >> 31;
273219b2ee8SDavid du Colombier 		return;
274219b2ee8SDavid du Colombier 	}
275219b2ee8SDavid du Colombier 	nneg = n.hi >> 31;
276219b2ee8SDavid du Colombier 	if(nneg)
277219b2ee8SDavid du Colombier 		vneg(&n);
278219b2ee8SDavid du Colombier 	dneg = d.hi >> 31;
279219b2ee8SDavid du Colombier 	if(dneg)
280219b2ee8SDavid du Colombier 		vneg(&d);
281219b2ee8SDavid du Colombier 	dodiv(n, d, q, 0);
282219b2ee8SDavid du Colombier 	if(nneg != dneg)
283219b2ee8SDavid du Colombier 		vneg(q);
284219b2ee8SDavid du Colombier }
285219b2ee8SDavid du Colombier 
286219b2ee8SDavid du Colombier void
_modv(Vlong * r,Vlong n,Vlong d)287219b2ee8SDavid du Colombier _modv(Vlong *r, Vlong n, Vlong d)
288219b2ee8SDavid du Colombier {
289219b2ee8SDavid du Colombier 	long nneg, dneg;
290219b2ee8SDavid du Colombier 
291219b2ee8SDavid du Colombier 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
292219b2ee8SDavid du Colombier 		r->lo = (long)n.lo % (long)d.lo;
293219b2ee8SDavid du Colombier 		r->hi = ((long)r->lo) >> 31;
294219b2ee8SDavid du Colombier 		return;
295219b2ee8SDavid du Colombier 	}
296219b2ee8SDavid du Colombier 	nneg = n.hi >> 31;
297219b2ee8SDavid du Colombier 	if(nneg)
298219b2ee8SDavid du Colombier 		vneg(&n);
299219b2ee8SDavid du Colombier 	dneg = d.hi >> 31;
300219b2ee8SDavid du Colombier 	if(dneg)
301219b2ee8SDavid du Colombier 		vneg(&d);
302219b2ee8SDavid du Colombier 	dodiv(n, d, 0, r);
303219b2ee8SDavid du Colombier 	if(nneg)
304219b2ee8SDavid du Colombier 		vneg(r);
305219b2ee8SDavid du Colombier }
306219b2ee8SDavid du Colombier 
307219b2ee8SDavid du Colombier void
_rshav(Vlong * r,Vlong a,int b)308219b2ee8SDavid du Colombier _rshav(Vlong *r, Vlong a, int b)
309219b2ee8SDavid du Colombier {
310219b2ee8SDavid du Colombier 	long t;
311219b2ee8SDavid du Colombier 
312219b2ee8SDavid du Colombier 	t = a.hi;
313219b2ee8SDavid du Colombier 	if(b >= 32) {
314219b2ee8SDavid du Colombier 		r->hi = t>>31;
315219b2ee8SDavid du Colombier 		if(b >= 64) {
316219b2ee8SDavid du Colombier 			/* this is illegal re C standard */
317219b2ee8SDavid du Colombier 			r->lo = t>>31;
318219b2ee8SDavid du Colombier 			return;
319219b2ee8SDavid du Colombier 		}
320219b2ee8SDavid du Colombier 		r->lo = t >> (b-32);
321219b2ee8SDavid du Colombier 		return;
322219b2ee8SDavid du Colombier 	}
323219b2ee8SDavid du Colombier 	if(b <= 0) {
324219b2ee8SDavid du Colombier 		r->hi = t;
325219b2ee8SDavid du Colombier 		r->lo = a.lo;
326219b2ee8SDavid du Colombier 		return;
327219b2ee8SDavid du Colombier 	}
328219b2ee8SDavid du Colombier 	r->hi = t >> b;
329219b2ee8SDavid du Colombier 	r->lo = (t << (32-b)) | (a.lo >> b);
330219b2ee8SDavid du Colombier }
331219b2ee8SDavid du Colombier 
332219b2ee8SDavid du Colombier void
_rshlv(Vlong * r,Vlong a,int b)333219b2ee8SDavid du Colombier _rshlv(Vlong *r, Vlong a, int b)
334219b2ee8SDavid du Colombier {
335219b2ee8SDavid du Colombier 	ulong t;
336219b2ee8SDavid du Colombier 
337219b2ee8SDavid du Colombier 	t = a.hi;
338219b2ee8SDavid du Colombier 	if(b >= 32) {
339219b2ee8SDavid du Colombier 		r->hi = 0;
340219b2ee8SDavid du Colombier 		if(b >= 64) {
341219b2ee8SDavid du Colombier 			/* this is illegal re C standard */
342219b2ee8SDavid du Colombier 			r->lo = 0;
343219b2ee8SDavid du Colombier 			return;
344219b2ee8SDavid du Colombier 		}
345219b2ee8SDavid du Colombier 		r->lo = t >> (b-32);
346219b2ee8SDavid du Colombier 		return;
347219b2ee8SDavid du Colombier 	}
348219b2ee8SDavid du Colombier 	if(b <= 0) {
349219b2ee8SDavid du Colombier 		r->hi = t;
350219b2ee8SDavid du Colombier 		r->lo = a.lo;
351219b2ee8SDavid du Colombier 		return;
352219b2ee8SDavid du Colombier 	}
353219b2ee8SDavid du Colombier 	r->hi = t >> b;
354219b2ee8SDavid du Colombier 	r->lo = (t << (32-b)) | (a.lo >> b);
355219b2ee8SDavid du Colombier }
356219b2ee8SDavid du Colombier 
357219b2ee8SDavid du Colombier void
_lshv(Vlong * r,Vlong a,int b)358219b2ee8SDavid du Colombier _lshv(Vlong *r, Vlong a, int b)
359219b2ee8SDavid du Colombier {
360219b2ee8SDavid du Colombier 	ulong t;
361219b2ee8SDavid du Colombier 
362219b2ee8SDavid du Colombier 	t = a.lo;
363219b2ee8SDavid du Colombier 	if(b >= 32) {
364219b2ee8SDavid du Colombier 		r->lo = 0;
365219b2ee8SDavid du Colombier 		if(b >= 64) {
366219b2ee8SDavid du Colombier 			/* this is illegal re C standard */
367219b2ee8SDavid du Colombier 			r->hi = 0;
368219b2ee8SDavid du Colombier 			return;
369219b2ee8SDavid du Colombier 		}
370219b2ee8SDavid du Colombier 		r->hi = t << (b-32);
371219b2ee8SDavid du Colombier 		return;
372219b2ee8SDavid du Colombier 	}
373219b2ee8SDavid du Colombier 	if(b <= 0) {
374219b2ee8SDavid du Colombier 		r->lo = t;
375219b2ee8SDavid du Colombier 		r->hi = a.hi;
376219b2ee8SDavid du Colombier 		return;
377219b2ee8SDavid du Colombier 	}
378219b2ee8SDavid du Colombier 	r->lo = t << b;
379219b2ee8SDavid du Colombier 	r->hi = (t >> (32-b)) | (a.hi << b);
380219b2ee8SDavid du Colombier }
381219b2ee8SDavid du Colombier 
382219b2ee8SDavid du Colombier void
_andv(Vlong * r,Vlong a,Vlong b)383219b2ee8SDavid du Colombier _andv(Vlong *r, Vlong a, Vlong b)
384219b2ee8SDavid du Colombier {
385219b2ee8SDavid du Colombier 	r->hi = a.hi & b.hi;
386219b2ee8SDavid du Colombier 	r->lo = a.lo & b.lo;
387219b2ee8SDavid du Colombier }
388219b2ee8SDavid du Colombier 
389219b2ee8SDavid du Colombier void
_orv(Vlong * r,Vlong a,Vlong b)390219b2ee8SDavid du Colombier _orv(Vlong *r, Vlong a, Vlong b)
391219b2ee8SDavid du Colombier {
392219b2ee8SDavid du Colombier 	r->hi = a.hi | b.hi;
393219b2ee8SDavid du Colombier 	r->lo = a.lo | b.lo;
394219b2ee8SDavid du Colombier }
395219b2ee8SDavid du Colombier 
396219b2ee8SDavid du Colombier void
_xorv(Vlong * r,Vlong a,Vlong b)397219b2ee8SDavid du Colombier _xorv(Vlong *r, Vlong a, Vlong b)
398219b2ee8SDavid du Colombier {
399219b2ee8SDavid du Colombier 	r->hi = a.hi ^ b.hi;
400219b2ee8SDavid du Colombier 	r->lo = a.lo ^ b.lo;
401219b2ee8SDavid du Colombier }
402219b2ee8SDavid du Colombier 
403219b2ee8SDavid du Colombier void
_vpp(Vlong * l,Vlong * r)404219b2ee8SDavid du Colombier _vpp(Vlong *l, Vlong *r)
405219b2ee8SDavid du Colombier {
406219b2ee8SDavid du Colombier 
407219b2ee8SDavid du Colombier 	l->hi = r->hi;
408219b2ee8SDavid du Colombier 	l->lo = r->lo;
409219b2ee8SDavid du Colombier 	r->lo++;
410219b2ee8SDavid du Colombier 	if(r->lo == 0)
411219b2ee8SDavid du Colombier 		r->hi++;
412219b2ee8SDavid du Colombier }
413219b2ee8SDavid du Colombier 
414219b2ee8SDavid du Colombier void
_vmm(Vlong * l,Vlong * r)415219b2ee8SDavid du Colombier _vmm(Vlong *l, Vlong *r)
416219b2ee8SDavid du Colombier {
417219b2ee8SDavid du Colombier 
418219b2ee8SDavid du Colombier 	l->hi = r->hi;
419219b2ee8SDavid du Colombier 	l->lo = r->lo;
420219b2ee8SDavid du Colombier 	if(r->lo == 0)
421219b2ee8SDavid du Colombier 		r->hi--;
422219b2ee8SDavid du Colombier 	r->lo--;
423219b2ee8SDavid du Colombier }
424219b2ee8SDavid du Colombier 
425219b2ee8SDavid du Colombier void
_ppv(Vlong * l,Vlong * r)426219b2ee8SDavid du Colombier _ppv(Vlong *l, Vlong *r)
427219b2ee8SDavid du Colombier {
428219b2ee8SDavid du Colombier 
429219b2ee8SDavid du Colombier 	r->lo++;
430219b2ee8SDavid du Colombier 	if(r->lo == 0)
431219b2ee8SDavid du Colombier 		r->hi++;
432219b2ee8SDavid du Colombier 	l->hi = r->hi;
433219b2ee8SDavid du Colombier 	l->lo = r->lo;
434219b2ee8SDavid du Colombier }
435219b2ee8SDavid du Colombier 
436219b2ee8SDavid du Colombier void
_mmv(Vlong * l,Vlong * r)437219b2ee8SDavid du Colombier _mmv(Vlong *l, Vlong *r)
438219b2ee8SDavid du Colombier {
439219b2ee8SDavid du Colombier 
440219b2ee8SDavid du Colombier 	if(r->lo == 0)
441219b2ee8SDavid du Colombier 		r->hi--;
442219b2ee8SDavid du Colombier 	r->lo--;
443219b2ee8SDavid du Colombier 	l->hi = r->hi;
444219b2ee8SDavid du Colombier 	l->lo = r->lo;
445219b2ee8SDavid du Colombier }
446219b2ee8SDavid du Colombier 
447219b2ee8SDavid du Colombier void
_vasop(Vlong * ret,void * lv,void fn (Vlong *,Vlong,Vlong),int type,Vlong rv)448219b2ee8SDavid du Colombier _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
449219b2ee8SDavid du Colombier {
4507dd7cddfSDavid du Colombier 	Vlong t, u;
451219b2ee8SDavid du Colombier 
4527dd7cddfSDavid du Colombier 	u.lo = 0;
4537dd7cddfSDavid du Colombier 	u.hi = 0;
454219b2ee8SDavid du Colombier 	switch(type) {
455219b2ee8SDavid du Colombier 	default:
456219b2ee8SDavid du Colombier 		abort();
457219b2ee8SDavid du Colombier 		break;
458219b2ee8SDavid du Colombier 
459219b2ee8SDavid du Colombier 	case 1:	/* schar */
460219b2ee8SDavid du Colombier 		t.lo = *(schar*)lv;
461219b2ee8SDavid du Colombier 		t.hi = t.lo >> 31;
4627dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4637dd7cddfSDavid du Colombier 		*(schar*)lv = u.lo;
464219b2ee8SDavid du Colombier 		break;
465219b2ee8SDavid du Colombier 
466219b2ee8SDavid du Colombier 	case 2:	/* uchar */
467219b2ee8SDavid du Colombier 		t.lo = *(uchar*)lv;
468219b2ee8SDavid du Colombier 		t.hi = 0;
4697dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4707dd7cddfSDavid du Colombier 		*(uchar*)lv = u.lo;
471219b2ee8SDavid du Colombier 		break;
472219b2ee8SDavid du Colombier 
473219b2ee8SDavid du Colombier 	case 3:	/* short */
474219b2ee8SDavid du Colombier 		t.lo = *(short*)lv;
475219b2ee8SDavid du Colombier 		t.hi = t.lo >> 31;
4767dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4777dd7cddfSDavid du Colombier 		*(short*)lv = u.lo;
478219b2ee8SDavid du Colombier 		break;
479219b2ee8SDavid du Colombier 
480219b2ee8SDavid du Colombier 	case 4:	/* ushort */
481219b2ee8SDavid du Colombier 		t.lo = *(ushort*)lv;
482219b2ee8SDavid du Colombier 		t.hi = 0;
4837dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4847dd7cddfSDavid du Colombier 		*(ushort*)lv = u.lo;
4857dd7cddfSDavid du Colombier 		break;
4867dd7cddfSDavid du Colombier 
4877dd7cddfSDavid du Colombier 	case 9:	/* int */
4887dd7cddfSDavid du Colombier 		t.lo = *(int*)lv;
4897dd7cddfSDavid du Colombier 		t.hi = t.lo >> 31;
4907dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4917dd7cddfSDavid du Colombier 		*(int*)lv = u.lo;
4927dd7cddfSDavid du Colombier 		break;
4937dd7cddfSDavid du Colombier 
4947dd7cddfSDavid du Colombier 	case 10:	/* uint */
4957dd7cddfSDavid du Colombier 		t.lo = *(uint*)lv;
4967dd7cddfSDavid du Colombier 		t.hi = 0;
4977dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4987dd7cddfSDavid du Colombier 		*(uint*)lv = u.lo;
499219b2ee8SDavid du Colombier 		break;
500219b2ee8SDavid du Colombier 
501219b2ee8SDavid du Colombier 	case 5:	/* long */
502219b2ee8SDavid du Colombier 		t.lo = *(long*)lv;
503219b2ee8SDavid du Colombier 		t.hi = t.lo >> 31;
5047dd7cddfSDavid du Colombier 		fn(&u, t, rv);
5057dd7cddfSDavid du Colombier 		*(long*)lv = u.lo;
506219b2ee8SDavid du Colombier 		break;
507219b2ee8SDavid du Colombier 
508219b2ee8SDavid du Colombier 	case 6:	/* ulong */
509219b2ee8SDavid du Colombier 		t.lo = *(ulong*)lv;
510219b2ee8SDavid du Colombier 		t.hi = 0;
5117dd7cddfSDavid du Colombier 		fn(&u, t, rv);
5127dd7cddfSDavid du Colombier 		*(ulong*)lv = u.lo;
513219b2ee8SDavid du Colombier 		break;
514219b2ee8SDavid du Colombier 
515219b2ee8SDavid du Colombier 	case 7:	/* vlong */
516219b2ee8SDavid du Colombier 	case 8:	/* uvlong */
5177dd7cddfSDavid du Colombier 		fn(&u, *(Vlong*)lv, rv);
5187dd7cddfSDavid du Colombier 		*(Vlong*)lv = u;
519219b2ee8SDavid du Colombier 		break;
520219b2ee8SDavid du Colombier 	}
5217dd7cddfSDavid du Colombier 	*ret = u;
5227dd7cddfSDavid du Colombier }
5237dd7cddfSDavid du Colombier 
5247dd7cddfSDavid du Colombier void
_p2v(Vlong * ret,void * p)5257dd7cddfSDavid du Colombier _p2v(Vlong *ret, void *p)
5267dd7cddfSDavid du Colombier {
5277dd7cddfSDavid du Colombier 	long t;
5287dd7cddfSDavid du Colombier 
5297dd7cddfSDavid du Colombier 	t = (ulong)p;
5307dd7cddfSDavid du Colombier 	ret->lo = t;
5317dd7cddfSDavid du Colombier 	ret->hi = 0;
532219b2ee8SDavid du Colombier }
533219b2ee8SDavid du Colombier 
534219b2ee8SDavid du Colombier void
_sl2v(Vlong * ret,long sl)535219b2ee8SDavid du Colombier _sl2v(Vlong *ret, long sl)
536219b2ee8SDavid du Colombier {
537219b2ee8SDavid du Colombier 	long t;
538219b2ee8SDavid du Colombier 
539219b2ee8SDavid du Colombier 	t = sl;
540219b2ee8SDavid du Colombier 	ret->lo = t;
541219b2ee8SDavid du Colombier 	ret->hi = t >> 31;
542219b2ee8SDavid du Colombier }
543219b2ee8SDavid du Colombier 
544219b2ee8SDavid du Colombier void
_ul2v(Vlong * ret,ulong ul)545219b2ee8SDavid du Colombier _ul2v(Vlong *ret, ulong ul)
546219b2ee8SDavid du Colombier {
547219b2ee8SDavid du Colombier 	long t;
548219b2ee8SDavid du Colombier 
549219b2ee8SDavid du Colombier 	t = ul;
550219b2ee8SDavid du Colombier 	ret->lo = t;
551219b2ee8SDavid du Colombier 	ret->hi = 0;
552219b2ee8SDavid du Colombier }
553219b2ee8SDavid du Colombier 
554219b2ee8SDavid du Colombier void
_si2v(Vlong * ret,int si)5557dd7cddfSDavid du Colombier _si2v(Vlong *ret, int si)
5567dd7cddfSDavid du Colombier {
5577dd7cddfSDavid du Colombier 	long t;
5587dd7cddfSDavid du Colombier 
5597dd7cddfSDavid du Colombier 	t = si;
5607dd7cddfSDavid du Colombier 	ret->lo = t;
5617dd7cddfSDavid du Colombier 	ret->hi = t >> 31;
5627dd7cddfSDavid du Colombier }
5637dd7cddfSDavid du Colombier 
5647dd7cddfSDavid du Colombier void
_ui2v(Vlong * ret,uint ui)5657dd7cddfSDavid du Colombier _ui2v(Vlong *ret, uint ui)
5667dd7cddfSDavid du Colombier {
5677dd7cddfSDavid du Colombier 	long t;
5687dd7cddfSDavid du Colombier 
5697dd7cddfSDavid du Colombier 	t = ui;
5707dd7cddfSDavid du Colombier 	ret->lo = t;
5717dd7cddfSDavid du Colombier 	ret->hi = 0;
5727dd7cddfSDavid du Colombier }
5737dd7cddfSDavid du Colombier 
5747dd7cddfSDavid du Colombier void
_sh2v(Vlong * ret,long sh)575219b2ee8SDavid du Colombier _sh2v(Vlong *ret, long sh)
576219b2ee8SDavid du Colombier {
577219b2ee8SDavid du Colombier 	long t;
578219b2ee8SDavid du Colombier 
579219b2ee8SDavid du Colombier 	t = (sh << 16) >> 16;
580219b2ee8SDavid du Colombier 	ret->lo = t;
581219b2ee8SDavid du Colombier 	ret->hi = t >> 31;
582219b2ee8SDavid du Colombier }
583219b2ee8SDavid du Colombier 
584219b2ee8SDavid du Colombier void
_uh2v(Vlong * ret,ulong ul)585219b2ee8SDavid du Colombier _uh2v(Vlong *ret, ulong ul)
586219b2ee8SDavid du Colombier {
587219b2ee8SDavid du Colombier 	long t;
588219b2ee8SDavid du Colombier 
589219b2ee8SDavid du Colombier 	t = ul & 0xffff;
590219b2ee8SDavid du Colombier 	ret->lo = t;
591219b2ee8SDavid du Colombier 	ret->hi = 0;
592219b2ee8SDavid du Colombier }
593219b2ee8SDavid du Colombier 
594219b2ee8SDavid du Colombier void
_sc2v(Vlong * ret,long uc)595219b2ee8SDavid du Colombier _sc2v(Vlong *ret, long uc)
596219b2ee8SDavid du Colombier {
597219b2ee8SDavid du Colombier 	long t;
598219b2ee8SDavid du Colombier 
599219b2ee8SDavid du Colombier 	t = (uc << 24) >> 24;
600219b2ee8SDavid du Colombier 	ret->lo = t;
601219b2ee8SDavid du Colombier 	ret->hi = t >> 31;
602219b2ee8SDavid du Colombier }
603219b2ee8SDavid du Colombier 
604219b2ee8SDavid du Colombier void
_uc2v(Vlong * ret,ulong ul)605219b2ee8SDavid du Colombier _uc2v(Vlong *ret, ulong ul)
606219b2ee8SDavid du Colombier {
607219b2ee8SDavid du Colombier 	long t;
608219b2ee8SDavid du Colombier 
609219b2ee8SDavid du Colombier 	t = ul & 0xff;
610219b2ee8SDavid du Colombier 	ret->lo = t;
611219b2ee8SDavid du Colombier 	ret->hi = 0;
612219b2ee8SDavid du Colombier }
613219b2ee8SDavid du Colombier 
614219b2ee8SDavid du Colombier long
_v2sc(Vlong rv)615219b2ee8SDavid du Colombier _v2sc(Vlong rv)
616219b2ee8SDavid du Colombier {
617219b2ee8SDavid du Colombier 	long t;
618219b2ee8SDavid du Colombier 
619219b2ee8SDavid du Colombier 	t = rv.lo & 0xff;
620219b2ee8SDavid du Colombier 	return (t << 24) >> 24;
621219b2ee8SDavid du Colombier }
622219b2ee8SDavid du Colombier 
623219b2ee8SDavid du Colombier long
_v2uc(Vlong rv)624219b2ee8SDavid du Colombier _v2uc(Vlong rv)
625219b2ee8SDavid du Colombier {
626219b2ee8SDavid du Colombier 
627219b2ee8SDavid du Colombier 	return rv.lo & 0xff;
628219b2ee8SDavid du Colombier }
629219b2ee8SDavid du Colombier 
630219b2ee8SDavid du Colombier long
_v2sh(Vlong rv)631219b2ee8SDavid du Colombier _v2sh(Vlong rv)
632219b2ee8SDavid du Colombier {
633219b2ee8SDavid du Colombier 	long t;
634219b2ee8SDavid du Colombier 
635219b2ee8SDavid du Colombier 	t = rv.lo & 0xffff;
636219b2ee8SDavid du Colombier 	return (t << 16) >> 16;
637219b2ee8SDavid du Colombier }
638219b2ee8SDavid du Colombier 
639219b2ee8SDavid du Colombier long
_v2uh(Vlong rv)640219b2ee8SDavid du Colombier _v2uh(Vlong rv)
641219b2ee8SDavid du Colombier {
642219b2ee8SDavid du Colombier 
643219b2ee8SDavid du Colombier 	return rv.lo & 0xffff;
644219b2ee8SDavid du Colombier }
645219b2ee8SDavid du Colombier 
646219b2ee8SDavid du Colombier long
_v2sl(Vlong rv)647219b2ee8SDavid du Colombier _v2sl(Vlong rv)
648219b2ee8SDavid du Colombier {
649219b2ee8SDavid du Colombier 
650219b2ee8SDavid du Colombier 	return rv.lo;
651219b2ee8SDavid du Colombier }
652219b2ee8SDavid du Colombier 
653219b2ee8SDavid du Colombier long
_v2ul(Vlong rv)654219b2ee8SDavid du Colombier _v2ul(Vlong rv)
655219b2ee8SDavid du Colombier {
656219b2ee8SDavid du Colombier 
657219b2ee8SDavid du Colombier 	return rv.lo;
658219b2ee8SDavid du Colombier }
659219b2ee8SDavid du Colombier 
6607dd7cddfSDavid du Colombier long
_v2si(Vlong rv)6617dd7cddfSDavid du Colombier _v2si(Vlong rv)
6627dd7cddfSDavid du Colombier {
6637dd7cddfSDavid du Colombier 
6647dd7cddfSDavid du Colombier 	return rv.lo;
6657dd7cddfSDavid du Colombier }
6667dd7cddfSDavid du Colombier 
6677dd7cddfSDavid du Colombier long
_v2ui(Vlong rv)6687dd7cddfSDavid du Colombier _v2ui(Vlong rv)
6697dd7cddfSDavid du Colombier {
6707dd7cddfSDavid du Colombier 
6717dd7cddfSDavid du Colombier 	return rv.lo;
6727dd7cddfSDavid du Colombier }
6737dd7cddfSDavid du Colombier 
674219b2ee8SDavid du Colombier int
_testv(Vlong rv)675219b2ee8SDavid du Colombier _testv(Vlong rv)
676219b2ee8SDavid du Colombier {
677219b2ee8SDavid du Colombier 	return rv.lo || rv.hi;
678219b2ee8SDavid du Colombier }
679219b2ee8SDavid du Colombier 
680219b2ee8SDavid du Colombier int
_eqv(Vlong lv,Vlong rv)681219b2ee8SDavid du Colombier _eqv(Vlong lv, Vlong rv)
682219b2ee8SDavid du Colombier {
683219b2ee8SDavid du Colombier 	return lv.lo == rv.lo && lv.hi == rv.hi;
684219b2ee8SDavid du Colombier }
685219b2ee8SDavid du Colombier 
686219b2ee8SDavid du Colombier int
_nev(Vlong lv,Vlong rv)687219b2ee8SDavid du Colombier _nev(Vlong lv, Vlong rv)
688219b2ee8SDavid du Colombier {
689219b2ee8SDavid du Colombier 	return lv.lo != rv.lo || lv.hi != rv.hi;
690219b2ee8SDavid du Colombier }
691219b2ee8SDavid du Colombier 
692219b2ee8SDavid du Colombier int
_ltv(Vlong lv,Vlong rv)693219b2ee8SDavid du Colombier _ltv(Vlong lv, Vlong rv)
694219b2ee8SDavid du Colombier {
695219b2ee8SDavid du Colombier 	return (long)lv.hi < (long)rv.hi ||
696219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo < rv.lo);
697219b2ee8SDavid du Colombier }
698219b2ee8SDavid du Colombier 
699219b2ee8SDavid du Colombier int
_lev(Vlong lv,Vlong rv)700219b2ee8SDavid du Colombier _lev(Vlong lv, Vlong rv)
701219b2ee8SDavid du Colombier {
702219b2ee8SDavid du Colombier 	return (long)lv.hi < (long)rv.hi ||
703219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo <= rv.lo);
704219b2ee8SDavid du Colombier }
705219b2ee8SDavid du Colombier 
706219b2ee8SDavid du Colombier int
_gtv(Vlong lv,Vlong rv)707219b2ee8SDavid du Colombier _gtv(Vlong lv, Vlong rv)
708219b2ee8SDavid du Colombier {
709219b2ee8SDavid du Colombier 	return (long)lv.hi > (long)rv.hi ||
710219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo > rv.lo);
711219b2ee8SDavid du Colombier }
712219b2ee8SDavid du Colombier 
713219b2ee8SDavid du Colombier int
_gev(Vlong lv,Vlong rv)714219b2ee8SDavid du Colombier _gev(Vlong lv, Vlong rv)
715219b2ee8SDavid du Colombier {
716219b2ee8SDavid du Colombier 	return (long)lv.hi > (long)rv.hi ||
717219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo >= rv.lo);
718219b2ee8SDavid du Colombier }
719219b2ee8SDavid du Colombier 
720219b2ee8SDavid du Colombier int
_lov(Vlong lv,Vlong rv)721219b2ee8SDavid du Colombier _lov(Vlong lv, Vlong rv)
722219b2ee8SDavid du Colombier {
723219b2ee8SDavid du Colombier 	return lv.hi < rv.hi ||
724219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo < rv.lo);
725219b2ee8SDavid du Colombier }
726219b2ee8SDavid du Colombier 
727219b2ee8SDavid du Colombier int
_lsv(Vlong lv,Vlong rv)728219b2ee8SDavid du Colombier _lsv(Vlong lv, Vlong rv)
729219b2ee8SDavid du Colombier {
730219b2ee8SDavid du Colombier 	return lv.hi < rv.hi ||
731219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo <= rv.lo);
732219b2ee8SDavid du Colombier }
733219b2ee8SDavid du Colombier 
734219b2ee8SDavid du Colombier int
_hiv(Vlong lv,Vlong rv)735219b2ee8SDavid du Colombier _hiv(Vlong lv, Vlong rv)
736219b2ee8SDavid du Colombier {
737219b2ee8SDavid du Colombier 	return lv.hi > rv.hi ||
738219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo > rv.lo);
739219b2ee8SDavid du Colombier }
740219b2ee8SDavid du Colombier 
741219b2ee8SDavid du Colombier int
_hsv(Vlong lv,Vlong rv)742219b2ee8SDavid du Colombier _hsv(Vlong lv, Vlong rv)
743219b2ee8SDavid du Colombier {
744219b2ee8SDavid du Colombier 	return lv.hi > rv.hi ||
745219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo >= rv.lo);
746219b2ee8SDavid du Colombier }
747