xref: /plan9/sys/src/libc/mips/vlrt.c (revision 76a51bbfeb38f900d220158ac11ead554452ed25)
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	hi;
17219b2ee8SDavid du Colombier 			ulong	lo;
18219b2ee8SDavid du Colombier 		};
19219b2ee8SDavid du Colombier 		struct
20219b2ee8SDavid du Colombier 		{
21219b2ee8SDavid du Colombier 			ushort	hims;
22219b2ee8SDavid du Colombier 			ushort	hils;
23219b2ee8SDavid du Colombier 			ushort	loms;
24219b2ee8SDavid du Colombier 			ushort	lols;
25219b2ee8SDavid du Colombier 		};
26219b2ee8SDavid du Colombier 	};
27219b2ee8SDavid du Colombier };
28219b2ee8SDavid du Colombier 
29219b2ee8SDavid du Colombier void	abort(void);
30219b2ee8SDavid du Colombier 
31e288d156SDavid du Colombier /* needed by profiler; can't be profiled. */
32e288d156SDavid du Colombier #pragma profile off
33*76a51bbfSDavid du Colombier 
34219b2ee8SDavid du Colombier void
_addv(Vlong * r,Vlong a,Vlong b)35219b2ee8SDavid du Colombier _addv(Vlong *r, Vlong a, Vlong b)
36219b2ee8SDavid du Colombier {
37219b2ee8SDavid du Colombier 	ulong lo, hi;
38219b2ee8SDavid du Colombier 
39219b2ee8SDavid du Colombier 	lo = a.lo + b.lo;
40219b2ee8SDavid du Colombier 	hi = a.hi + b.hi;
41219b2ee8SDavid du Colombier 	if(lo < a.lo)
42219b2ee8SDavid du Colombier 		hi++;
43219b2ee8SDavid du Colombier 	r->lo = lo;
44219b2ee8SDavid du Colombier 	r->hi = hi;
45219b2ee8SDavid du Colombier }
46219b2ee8SDavid du Colombier 
47219b2ee8SDavid du Colombier void
_subv(Vlong * r,Vlong a,Vlong b)48219b2ee8SDavid du Colombier _subv(Vlong *r, Vlong a, Vlong b)
49219b2ee8SDavid du Colombier {
50219b2ee8SDavid du Colombier 	ulong lo, hi;
51219b2ee8SDavid du Colombier 
52219b2ee8SDavid du Colombier 	lo = a.lo - b.lo;
53219b2ee8SDavid du Colombier 	hi = a.hi - b.hi;
54219b2ee8SDavid du Colombier 	if(lo > a.lo)
55219b2ee8SDavid du Colombier 		hi--;
56219b2ee8SDavid du Colombier 	r->lo = lo;
57219b2ee8SDavid du Colombier 	r->hi = hi;
58219b2ee8SDavid du Colombier }
59219b2ee8SDavid du Colombier 
60219b2ee8SDavid du Colombier void
_d2v(Vlong * y,double d)61219b2ee8SDavid du Colombier _d2v(Vlong *y, double d)
62219b2ee8SDavid du Colombier {
63219b2ee8SDavid du Colombier 	union { double d; struct Vlong; } x;
64219b2ee8SDavid du Colombier 	ulong xhi, xlo, ylo, yhi;
65219b2ee8SDavid du Colombier 	int sh;
66219b2ee8SDavid du Colombier 
67219b2ee8SDavid du Colombier 	x.d = d;
68219b2ee8SDavid du Colombier 
69219b2ee8SDavid du Colombier 	xhi = (x.hi & 0xfffff) | 0x100000;
70219b2ee8SDavid du Colombier 	xlo = x.lo;
71219b2ee8SDavid du Colombier 	sh = 1075 - ((x.hi >> 20) & 0x7ff);
72219b2ee8SDavid du Colombier 
73219b2ee8SDavid du Colombier 	ylo = 0;
74219b2ee8SDavid du Colombier 	yhi = 0;
75219b2ee8SDavid du Colombier 	if(sh >= 0) {
76219b2ee8SDavid du Colombier 		/* v = (hi||lo) >> sh */
77219b2ee8SDavid du Colombier 		if(sh < 32) {
78219b2ee8SDavid du Colombier 			if(sh == 0) {
79219b2ee8SDavid du Colombier 				ylo = xlo;
80219b2ee8SDavid du Colombier 				yhi = xhi;
81219b2ee8SDavid du Colombier 			} else {
82219b2ee8SDavid du Colombier 				ylo = (xlo >> sh) | (xhi << (32-sh));
83219b2ee8SDavid du Colombier 				yhi = xhi >> sh;
84219b2ee8SDavid du Colombier 			}
85219b2ee8SDavid du Colombier 		} else {
86219b2ee8SDavid du Colombier 			if(sh == 32) {
87219b2ee8SDavid du Colombier 				ylo = xhi;
88219b2ee8SDavid du Colombier 			} else
89219b2ee8SDavid du Colombier 			if(sh < 64) {
90219b2ee8SDavid du Colombier 				ylo = xhi >> (sh-32);
91219b2ee8SDavid du Colombier 			}
92219b2ee8SDavid du Colombier 		}
93219b2ee8SDavid du Colombier 	} else {
94219b2ee8SDavid du Colombier 		/* v = (hi||lo) << -sh */
95219b2ee8SDavid du Colombier 		sh = -sh;
96219b2ee8SDavid du Colombier 		if(sh <= 10) {
97219b2ee8SDavid du Colombier 			ylo = xlo << sh;
98219b2ee8SDavid du Colombier 			yhi = (xhi << sh) | (xlo >> (32-sh));
99219b2ee8SDavid du Colombier 		} else {
100219b2ee8SDavid du Colombier 			/* overflow */
101219b2ee8SDavid du Colombier 			yhi = d;	/* causes something awful */
102219b2ee8SDavid du Colombier 		}
103219b2ee8SDavid du Colombier 	}
104219b2ee8SDavid du Colombier 	if(x.hi & SIGN(32)) {
105219b2ee8SDavid du Colombier 		if(ylo != 0) {
106219b2ee8SDavid du Colombier 			ylo = -ylo;
107219b2ee8SDavid du Colombier 			yhi = ~yhi;
108219b2ee8SDavid du Colombier 		} else
109219b2ee8SDavid du Colombier 			yhi = -yhi;
110219b2ee8SDavid du Colombier 	}
111219b2ee8SDavid du Colombier 
112219b2ee8SDavid du Colombier 	y->hi = yhi;
113219b2ee8SDavid du Colombier 	y->lo = ylo;
114219b2ee8SDavid du Colombier }
115219b2ee8SDavid du Colombier 
116219b2ee8SDavid du Colombier void
_f2v(Vlong * y,float f)117219b2ee8SDavid du Colombier _f2v(Vlong *y, float f)
118219b2ee8SDavid du Colombier {
119219b2ee8SDavid du Colombier 
120219b2ee8SDavid du Colombier 	_d2v(y, f);
121219b2ee8SDavid du Colombier }
122219b2ee8SDavid du Colombier 
123219b2ee8SDavid du Colombier double
_v2d(Vlong x)124219b2ee8SDavid du Colombier _v2d(Vlong x)
125219b2ee8SDavid du Colombier {
126219b2ee8SDavid du Colombier 	if(x.hi & SIGN(32)) {
127219b2ee8SDavid du Colombier 		if(x.lo) {
128219b2ee8SDavid du Colombier 			x.lo = -x.lo;
129219b2ee8SDavid du Colombier 			x.hi = ~x.hi;
130219b2ee8SDavid du Colombier 		} else
131219b2ee8SDavid du Colombier 			x.hi = -x.hi;
132219b2ee8SDavid du Colombier 		return -((long)x.hi*4294967296. + x.lo);
133219b2ee8SDavid du Colombier 	}
134219b2ee8SDavid du Colombier 	return (long)x.hi*4294967296. + x.lo;
135219b2ee8SDavid du Colombier }
136219b2ee8SDavid du Colombier 
137219b2ee8SDavid du Colombier float
_v2f(Vlong x)138219b2ee8SDavid du Colombier _v2f(Vlong x)
139219b2ee8SDavid du Colombier {
140219b2ee8SDavid du Colombier 	return _v2d(x);
141219b2ee8SDavid du Colombier }
142219b2ee8SDavid du Colombier 
143219b2ee8SDavid du Colombier static void
dodiv(Vlong num,Vlong den,Vlong * qp,Vlong * rp)1447dd7cddfSDavid du Colombier dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
145219b2ee8SDavid du Colombier {
146219b2ee8SDavid du Colombier 	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
147219b2ee8SDavid du Colombier 	int i;
148219b2ee8SDavid du Colombier 
149219b2ee8SDavid du Colombier 	numhi = num.hi;
150219b2ee8SDavid du Colombier 	numlo = num.lo;
151219b2ee8SDavid du Colombier 	denhi = den.hi;
152219b2ee8SDavid du Colombier 	denlo = den.lo;
153219b2ee8SDavid du Colombier 
154219b2ee8SDavid du Colombier 	/*
155219b2ee8SDavid du Colombier 	 * get a divide by zero
156219b2ee8SDavid du Colombier 	 */
157219b2ee8SDavid du Colombier 	if(denlo==0 && denhi==0) {
158219b2ee8SDavid du Colombier 		numlo = numlo / denlo;
159219b2ee8SDavid du Colombier 	}
160219b2ee8SDavid du Colombier 
161219b2ee8SDavid du Colombier 	/*
162219b2ee8SDavid du Colombier 	 * set up the divisor and find the number of iterations needed
163219b2ee8SDavid du Colombier 	 */
164219b2ee8SDavid du Colombier 	if(numhi >= SIGN(32)) {
165219b2ee8SDavid du Colombier 		quohi = SIGN(32);
166219b2ee8SDavid du Colombier 		quolo = 0;
167219b2ee8SDavid du Colombier 	} else {
168219b2ee8SDavid du Colombier 		quohi = numhi;
169219b2ee8SDavid du Colombier 		quolo = numlo;
170219b2ee8SDavid du Colombier 	}
171219b2ee8SDavid du Colombier 	i = 0;
172219b2ee8SDavid du Colombier 	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
173219b2ee8SDavid du Colombier 		denhi = (denhi<<1) | (denlo>>31);
174219b2ee8SDavid du Colombier 		denlo <<= 1;
175219b2ee8SDavid du Colombier 		i++;
176219b2ee8SDavid du Colombier 	}
177219b2ee8SDavid du Colombier 
178219b2ee8SDavid du Colombier 	quohi = 0;
179219b2ee8SDavid du Colombier 	quolo = 0;
180219b2ee8SDavid du Colombier 	for(; i >= 0; i--) {
181219b2ee8SDavid du Colombier 		quohi = (quohi<<1) | (quolo>>31);
182219b2ee8SDavid du Colombier 		quolo <<= 1;
183219b2ee8SDavid du Colombier 		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
184219b2ee8SDavid du Colombier 			t = numlo;
185219b2ee8SDavid du Colombier 			numlo -= denlo;
186219b2ee8SDavid du Colombier 			if(numlo > t)
187219b2ee8SDavid du Colombier 				numhi--;
188219b2ee8SDavid du Colombier 			numhi -= denhi;
189219b2ee8SDavid du Colombier 			quolo |= 1;
190219b2ee8SDavid du Colombier 		}
191219b2ee8SDavid du Colombier 		denlo = (denlo>>1) | (denhi<<31);
192219b2ee8SDavid du Colombier 		denhi >>= 1;
193219b2ee8SDavid du Colombier 	}
194219b2ee8SDavid du Colombier 
1957dd7cddfSDavid du Colombier 	if(qp) {
1967dd7cddfSDavid du Colombier 		qp->lo = quolo;
1977dd7cddfSDavid du Colombier 		qp->hi = quohi;
198219b2ee8SDavid du Colombier 	}
1997dd7cddfSDavid du Colombier 	if(rp) {
2007dd7cddfSDavid du Colombier 		rp->lo = numlo;
2017dd7cddfSDavid du Colombier 		rp->hi = numhi;
202219b2ee8SDavid du Colombier 	}
203219b2ee8SDavid du Colombier }
204219b2ee8SDavid du Colombier 
205219b2ee8SDavid du Colombier void
_divvu(Vlong * q,Vlong n,Vlong d)206219b2ee8SDavid du Colombier _divvu(Vlong *q, Vlong n, Vlong d)
207219b2ee8SDavid du Colombier {
208219b2ee8SDavid du Colombier 
209219b2ee8SDavid du Colombier 	if(n.hi == 0 && d.hi == 0) {
210219b2ee8SDavid du Colombier 		q->hi = 0;
211219b2ee8SDavid du Colombier 		q->lo = n.lo / d.lo;
212219b2ee8SDavid du Colombier 		return;
213219b2ee8SDavid du Colombier 	}
214219b2ee8SDavid du Colombier 	dodiv(n, d, q, 0);
215219b2ee8SDavid du Colombier }
216219b2ee8SDavid du Colombier 
217219b2ee8SDavid du Colombier void
_modvu(Vlong * r,Vlong n,Vlong d)218219b2ee8SDavid du Colombier _modvu(Vlong *r, Vlong n, Vlong d)
219219b2ee8SDavid du Colombier {
220219b2ee8SDavid du Colombier 
221219b2ee8SDavid du Colombier 	if(n.hi == 0 && d.hi == 0) {
222219b2ee8SDavid du Colombier 		r->hi = 0;
223219b2ee8SDavid du Colombier 		r->lo = n.lo % d.lo;
224219b2ee8SDavid du Colombier 		return;
225219b2ee8SDavid du Colombier 	}
226219b2ee8SDavid du Colombier 	dodiv(n, d, 0, r);
227219b2ee8SDavid du Colombier }
228219b2ee8SDavid du Colombier 
229219b2ee8SDavid du Colombier static void
vneg(Vlong * v)230219b2ee8SDavid du Colombier vneg(Vlong *v)
231219b2ee8SDavid du Colombier {
232219b2ee8SDavid du Colombier 
233219b2ee8SDavid du Colombier 	if(v->lo == 0) {
234219b2ee8SDavid du Colombier 		v->hi = -v->hi;
235219b2ee8SDavid du Colombier 		return;
236219b2ee8SDavid du Colombier 	}
237219b2ee8SDavid du Colombier 	v->lo = -v->lo;
238219b2ee8SDavid du Colombier 	v->hi = ~v->hi;
239219b2ee8SDavid du Colombier }
240219b2ee8SDavid du Colombier 
241219b2ee8SDavid du Colombier void
_divv(Vlong * q,Vlong n,Vlong d)242219b2ee8SDavid du Colombier _divv(Vlong *q, Vlong n, Vlong d)
243219b2ee8SDavid du Colombier {
244219b2ee8SDavid du Colombier 	long nneg, dneg;
245219b2ee8SDavid du Colombier 
246219b2ee8SDavid du Colombier 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
247219b2ee8SDavid du Colombier 		q->lo = (long)n.lo / (long)d.lo;
248219b2ee8SDavid du Colombier 		q->hi = ((long)q->lo) >> 31;
249219b2ee8SDavid du Colombier 		return;
250219b2ee8SDavid du Colombier 	}
251219b2ee8SDavid du Colombier 	nneg = n.hi >> 31;
252219b2ee8SDavid du Colombier 	if(nneg)
253219b2ee8SDavid du Colombier 		vneg(&n);
254219b2ee8SDavid du Colombier 	dneg = d.hi >> 31;
255219b2ee8SDavid du Colombier 	if(dneg)
256219b2ee8SDavid du Colombier 		vneg(&d);
257219b2ee8SDavid du Colombier 	dodiv(n, d, q, 0);
258219b2ee8SDavid du Colombier 	if(nneg != dneg)
259219b2ee8SDavid du Colombier 		vneg(q);
260219b2ee8SDavid du Colombier }
261219b2ee8SDavid du Colombier 
262219b2ee8SDavid du Colombier void
_modv(Vlong * r,Vlong n,Vlong d)263219b2ee8SDavid du Colombier _modv(Vlong *r, Vlong n, Vlong d)
264219b2ee8SDavid du Colombier {
265219b2ee8SDavid du Colombier 	long nneg, dneg;
266219b2ee8SDavid du Colombier 
267219b2ee8SDavid du Colombier 	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
268219b2ee8SDavid du Colombier 		r->lo = (long)n.lo % (long)d.lo;
269219b2ee8SDavid du Colombier 		r->hi = ((long)r->lo) >> 31;
270219b2ee8SDavid du Colombier 		return;
271219b2ee8SDavid du Colombier 	}
272219b2ee8SDavid du Colombier 	nneg = n.hi >> 31;
273219b2ee8SDavid du Colombier 	if(nneg)
274219b2ee8SDavid du Colombier 		vneg(&n);
275219b2ee8SDavid du Colombier 	dneg = d.hi >> 31;
276219b2ee8SDavid du Colombier 	if(dneg)
277219b2ee8SDavid du Colombier 		vneg(&d);
278219b2ee8SDavid du Colombier 	dodiv(n, d, 0, r);
279219b2ee8SDavid du Colombier 	if(nneg)
280219b2ee8SDavid du Colombier 		vneg(r);
281219b2ee8SDavid du Colombier }
282219b2ee8SDavid du Colombier 
283219b2ee8SDavid du Colombier void
_rshav(Vlong * r,Vlong a,int b)284219b2ee8SDavid du Colombier _rshav(Vlong *r, Vlong a, int b)
285219b2ee8SDavid du Colombier {
286219b2ee8SDavid du Colombier 	long t;
287219b2ee8SDavid du Colombier 
288219b2ee8SDavid du Colombier 	t = a.hi;
289219b2ee8SDavid du Colombier 	if(b >= 32) {
290219b2ee8SDavid du Colombier 		r->hi = t>>31;
291219b2ee8SDavid du Colombier 		if(b >= 64) {
292219b2ee8SDavid du Colombier 			/* this is illegal re C standard */
293219b2ee8SDavid du Colombier 			r->lo = t>>31;
294219b2ee8SDavid du Colombier 			return;
295219b2ee8SDavid du Colombier 		}
296219b2ee8SDavid du Colombier 		r->lo = t >> (b-32);
297219b2ee8SDavid du Colombier 		return;
298219b2ee8SDavid du Colombier 	}
299219b2ee8SDavid du Colombier 	if(b <= 0) {
300219b2ee8SDavid du Colombier 		r->hi = t;
301219b2ee8SDavid du Colombier 		r->lo = a.lo;
302219b2ee8SDavid du Colombier 		return;
303219b2ee8SDavid du Colombier 	}
304219b2ee8SDavid du Colombier 	r->hi = t >> b;
305219b2ee8SDavid du Colombier 	r->lo = (t << (32-b)) | (a.lo >> b);
306219b2ee8SDavid du Colombier }
307219b2ee8SDavid du Colombier 
308219b2ee8SDavid du Colombier void
_rshlv(Vlong * r,Vlong a,int b)309219b2ee8SDavid du Colombier _rshlv(Vlong *r, Vlong a, int b)
310219b2ee8SDavid du Colombier {
311219b2ee8SDavid du Colombier 	ulong t;
312219b2ee8SDavid du Colombier 
313219b2ee8SDavid du Colombier 	t = a.hi;
314219b2ee8SDavid du Colombier 	if(b >= 32) {
315219b2ee8SDavid du Colombier 		r->hi = 0;
316219b2ee8SDavid du Colombier 		if(b >= 64) {
317219b2ee8SDavid du Colombier 			/* this is illegal re C standard */
318219b2ee8SDavid du Colombier 			r->lo = 0;
319219b2ee8SDavid du Colombier 			return;
320219b2ee8SDavid du Colombier 		}
321219b2ee8SDavid du Colombier 		r->lo = t >> (b-32);
322219b2ee8SDavid du Colombier 		return;
323219b2ee8SDavid du Colombier 	}
324219b2ee8SDavid du Colombier 	if(b <= 0) {
325219b2ee8SDavid du Colombier 		r->hi = t;
326219b2ee8SDavid du Colombier 		r->lo = a.lo;
327219b2ee8SDavid du Colombier 		return;
328219b2ee8SDavid du Colombier 	}
329219b2ee8SDavid du Colombier 	r->hi = t >> b;
330219b2ee8SDavid du Colombier 	r->lo = (t << (32-b)) | (a.lo >> b);
331219b2ee8SDavid du Colombier }
332219b2ee8SDavid du Colombier 
333219b2ee8SDavid du Colombier void
_lshv(Vlong * r,Vlong a,int b)334219b2ee8SDavid du Colombier _lshv(Vlong *r, Vlong a, int b)
335219b2ee8SDavid du Colombier {
336219b2ee8SDavid du Colombier 	ulong t;
337219b2ee8SDavid du Colombier 
338219b2ee8SDavid du Colombier 	t = a.lo;
339219b2ee8SDavid du Colombier 	if(b >= 32) {
340219b2ee8SDavid du Colombier 		r->lo = 0;
341219b2ee8SDavid du Colombier 		if(b >= 64) {
342219b2ee8SDavid du Colombier 			/* this is illegal re C standard */
343219b2ee8SDavid du Colombier 			r->hi = 0;
344219b2ee8SDavid du Colombier 			return;
345219b2ee8SDavid du Colombier 		}
346219b2ee8SDavid du Colombier 		r->hi = t << (b-32);
347219b2ee8SDavid du Colombier 		return;
348219b2ee8SDavid du Colombier 	}
349219b2ee8SDavid du Colombier 	if(b <= 0) {
350219b2ee8SDavid du Colombier 		r->lo = t;
351219b2ee8SDavid du Colombier 		r->hi = a.hi;
352219b2ee8SDavid du Colombier 		return;
353219b2ee8SDavid du Colombier 	}
354219b2ee8SDavid du Colombier 	r->lo = t << b;
355219b2ee8SDavid du Colombier 	r->hi = (t >> (32-b)) | (a.hi << b);
356219b2ee8SDavid du Colombier }
357219b2ee8SDavid du Colombier 
358219b2ee8SDavid du Colombier void
_andv(Vlong * r,Vlong a,Vlong b)359219b2ee8SDavid du Colombier _andv(Vlong *r, Vlong a, Vlong b)
360219b2ee8SDavid du Colombier {
361219b2ee8SDavid du Colombier 	r->hi = a.hi & b.hi;
362219b2ee8SDavid du Colombier 	r->lo = a.lo & b.lo;
363219b2ee8SDavid du Colombier }
364219b2ee8SDavid du Colombier 
365219b2ee8SDavid du Colombier void
_orv(Vlong * r,Vlong a,Vlong b)366219b2ee8SDavid du Colombier _orv(Vlong *r, Vlong a, Vlong b)
367219b2ee8SDavid du Colombier {
368219b2ee8SDavid du Colombier 	r->hi = a.hi | b.hi;
369219b2ee8SDavid du Colombier 	r->lo = a.lo | b.lo;
370219b2ee8SDavid du Colombier }
371219b2ee8SDavid du Colombier 
372219b2ee8SDavid du Colombier void
_xorv(Vlong * r,Vlong a,Vlong b)373219b2ee8SDavid du Colombier _xorv(Vlong *r, Vlong a, Vlong b)
374219b2ee8SDavid du Colombier {
375219b2ee8SDavid du Colombier 	r->hi = a.hi ^ b.hi;
376219b2ee8SDavid du Colombier 	r->lo = a.lo ^ b.lo;
377219b2ee8SDavid du Colombier }
378219b2ee8SDavid du Colombier 
379219b2ee8SDavid du Colombier void
_vpp(Vlong * l,Vlong * r)380219b2ee8SDavid du Colombier _vpp(Vlong *l, Vlong *r)
381219b2ee8SDavid du Colombier {
382219b2ee8SDavid du Colombier 
383219b2ee8SDavid du Colombier 	l->hi = r->hi;
384219b2ee8SDavid du Colombier 	l->lo = r->lo;
385219b2ee8SDavid du Colombier 	r->lo++;
386219b2ee8SDavid du Colombier 	if(r->lo == 0)
387219b2ee8SDavid du Colombier 		r->hi++;
388219b2ee8SDavid du Colombier }
389219b2ee8SDavid du Colombier 
390219b2ee8SDavid du Colombier void
_vmm(Vlong * l,Vlong * r)391219b2ee8SDavid du Colombier _vmm(Vlong *l, Vlong *r)
392219b2ee8SDavid du Colombier {
393219b2ee8SDavid du Colombier 
394219b2ee8SDavid du Colombier 	l->hi = r->hi;
395219b2ee8SDavid du Colombier 	l->lo = r->lo;
396219b2ee8SDavid du Colombier 	if(r->lo == 0)
397219b2ee8SDavid du Colombier 		r->hi--;
398219b2ee8SDavid du Colombier 	r->lo--;
399219b2ee8SDavid du Colombier }
400219b2ee8SDavid du Colombier 
401219b2ee8SDavid du Colombier void
_ppv(Vlong * l,Vlong * r)402219b2ee8SDavid du Colombier _ppv(Vlong *l, Vlong *r)
403219b2ee8SDavid du Colombier {
404219b2ee8SDavid du Colombier 
405219b2ee8SDavid du Colombier 	r->lo++;
406219b2ee8SDavid du Colombier 	if(r->lo == 0)
407219b2ee8SDavid du Colombier 		r->hi++;
408219b2ee8SDavid du Colombier 	l->hi = r->hi;
409219b2ee8SDavid du Colombier 	l->lo = r->lo;
410219b2ee8SDavid du Colombier }
411219b2ee8SDavid du Colombier 
412219b2ee8SDavid du Colombier void
_mmv(Vlong * l,Vlong * r)413219b2ee8SDavid du Colombier _mmv(Vlong *l, Vlong *r)
414219b2ee8SDavid du Colombier {
415219b2ee8SDavid du Colombier 
416219b2ee8SDavid du Colombier 	if(r->lo == 0)
417219b2ee8SDavid du Colombier 		r->hi--;
418219b2ee8SDavid du Colombier 	r->lo--;
419219b2ee8SDavid du Colombier 	l->hi = r->hi;
420219b2ee8SDavid du Colombier 	l->lo = r->lo;
421219b2ee8SDavid du Colombier }
422219b2ee8SDavid du Colombier 
423219b2ee8SDavid du Colombier void
_vasop(Vlong * ret,void * lv,void fn (Vlong *,Vlong,Vlong),int type,Vlong rv)424219b2ee8SDavid du Colombier _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
425219b2ee8SDavid du Colombier {
4267dd7cddfSDavid du Colombier 	Vlong t, u;
427219b2ee8SDavid du Colombier 
4287dd7cddfSDavid du Colombier 	u.lo = 0;
4297dd7cddfSDavid du Colombier 	u.hi = 0;
430219b2ee8SDavid du Colombier 	switch(type) {
431219b2ee8SDavid du Colombier 	default:
432219b2ee8SDavid du Colombier 		abort();
433219b2ee8SDavid du Colombier 		break;
434219b2ee8SDavid du Colombier 
435219b2ee8SDavid du Colombier 	case 1:	/* schar */
436219b2ee8SDavid du Colombier 		t.lo = *(schar*)lv;
437219b2ee8SDavid du Colombier 		t.hi = t.lo >> 31;
4387dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4397dd7cddfSDavid du Colombier 		*(schar*)lv = u.lo;
440219b2ee8SDavid du Colombier 		break;
441219b2ee8SDavid du Colombier 
442219b2ee8SDavid du Colombier 	case 2:	/* uchar */
443219b2ee8SDavid du Colombier 		t.lo = *(uchar*)lv;
444219b2ee8SDavid du Colombier 		t.hi = 0;
4457dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4467dd7cddfSDavid du Colombier 		*(uchar*)lv = u.lo;
447219b2ee8SDavid du Colombier 		break;
448219b2ee8SDavid du Colombier 
449219b2ee8SDavid du Colombier 	case 3:	/* short */
450219b2ee8SDavid du Colombier 		t.lo = *(short*)lv;
451219b2ee8SDavid du Colombier 		t.hi = t.lo >> 31;
4527dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4537dd7cddfSDavid du Colombier 		*(short*)lv = u.lo;
454219b2ee8SDavid du Colombier 		break;
455219b2ee8SDavid du Colombier 
456219b2ee8SDavid du Colombier 	case 4:	/* ushort */
457219b2ee8SDavid du Colombier 		t.lo = *(ushort*)lv;
458219b2ee8SDavid du Colombier 		t.hi = 0;
4597dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4607dd7cddfSDavid du Colombier 		*(ushort*)lv = u.lo;
4617dd7cddfSDavid du Colombier 		break;
4627dd7cddfSDavid du Colombier 
4637dd7cddfSDavid du Colombier 	case 9:	/* int */
4647dd7cddfSDavid du Colombier 		t.lo = *(int*)lv;
4657dd7cddfSDavid du Colombier 		t.hi = t.lo >> 31;
4667dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4677dd7cddfSDavid du Colombier 		*(int*)lv = u.lo;
4687dd7cddfSDavid du Colombier 		break;
4697dd7cddfSDavid du Colombier 
4707dd7cddfSDavid du Colombier 	case 10:	/* uint */
4717dd7cddfSDavid du Colombier 		t.lo = *(uint*)lv;
4727dd7cddfSDavid du Colombier 		t.hi = 0;
4737dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4747dd7cddfSDavid du Colombier 		*(uint*)lv = u.lo;
475219b2ee8SDavid du Colombier 		break;
476219b2ee8SDavid du Colombier 
477219b2ee8SDavid du Colombier 	case 5:	/* long */
478219b2ee8SDavid du Colombier 		t.lo = *(long*)lv;
479219b2ee8SDavid du Colombier 		t.hi = t.lo >> 31;
4807dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4817dd7cddfSDavid du Colombier 		*(long*)lv = u.lo;
482219b2ee8SDavid du Colombier 		break;
483219b2ee8SDavid du Colombier 
484219b2ee8SDavid du Colombier 	case 6:	/* ulong */
485219b2ee8SDavid du Colombier 		t.lo = *(ulong*)lv;
486219b2ee8SDavid du Colombier 		t.hi = 0;
4877dd7cddfSDavid du Colombier 		fn(&u, t, rv);
4887dd7cddfSDavid du Colombier 		*(ulong*)lv = u.lo;
489219b2ee8SDavid du Colombier 		break;
490219b2ee8SDavid du Colombier 
491219b2ee8SDavid du Colombier 	case 7:	/* vlong */
492219b2ee8SDavid du Colombier 	case 8:	/* uvlong */
4937dd7cddfSDavid du Colombier 		fn(&u, *(Vlong*)lv, rv);
4947dd7cddfSDavid du Colombier 		*(Vlong*)lv = u;
495219b2ee8SDavid du Colombier 		break;
496219b2ee8SDavid du Colombier 	}
4977dd7cddfSDavid du Colombier 	*ret = u;
4987dd7cddfSDavid du Colombier }
4997dd7cddfSDavid du Colombier 
5007dd7cddfSDavid du Colombier void
_p2v(Vlong * ret,void * p)5017dd7cddfSDavid du Colombier _p2v(Vlong *ret, void *p)
5027dd7cddfSDavid du Colombier {
5037dd7cddfSDavid du Colombier 	long t;
5047dd7cddfSDavid du Colombier 
5057dd7cddfSDavid du Colombier 	t = (ulong)p;
5067dd7cddfSDavid du Colombier 	ret->lo = t;
5077dd7cddfSDavid du Colombier 	ret->hi = 0;
508219b2ee8SDavid du Colombier }
509219b2ee8SDavid du Colombier 
510219b2ee8SDavid du Colombier void
_sl2v(Vlong * ret,long sl)511219b2ee8SDavid du Colombier _sl2v(Vlong *ret, long sl)
512219b2ee8SDavid du Colombier {
513219b2ee8SDavid du Colombier 	long t;
514219b2ee8SDavid du Colombier 
515219b2ee8SDavid du Colombier 	t = sl;
516219b2ee8SDavid du Colombier 	ret->lo = t;
517219b2ee8SDavid du Colombier 	ret->hi = t >> 31;
518219b2ee8SDavid du Colombier }
519219b2ee8SDavid du Colombier 
520219b2ee8SDavid du Colombier void
_ul2v(Vlong * ret,ulong ul)521219b2ee8SDavid du Colombier _ul2v(Vlong *ret, ulong ul)
522219b2ee8SDavid du Colombier {
523219b2ee8SDavid du Colombier 	long t;
524219b2ee8SDavid du Colombier 
525219b2ee8SDavid du Colombier 	t = ul;
526219b2ee8SDavid du Colombier 	ret->lo = t;
527219b2ee8SDavid du Colombier 	ret->hi = 0;
528219b2ee8SDavid du Colombier }
529219b2ee8SDavid du Colombier 
530219b2ee8SDavid du Colombier void
_si2v(Vlong * ret,int si)5317dd7cddfSDavid du Colombier _si2v(Vlong *ret, int si)
5327dd7cddfSDavid du Colombier {
5337dd7cddfSDavid du Colombier 	long t;
5347dd7cddfSDavid du Colombier 
5357dd7cddfSDavid du Colombier 	t = si;
5367dd7cddfSDavid du Colombier 	ret->lo = t;
5377dd7cddfSDavid du Colombier 	ret->hi = t >> 31;
5387dd7cddfSDavid du Colombier }
5397dd7cddfSDavid du Colombier 
5407dd7cddfSDavid du Colombier void
_ui2v(Vlong * ret,uint ui)5417dd7cddfSDavid du Colombier _ui2v(Vlong *ret, uint ui)
5427dd7cddfSDavid du Colombier {
5437dd7cddfSDavid du Colombier 	long t;
5447dd7cddfSDavid du Colombier 
5457dd7cddfSDavid du Colombier 	t = ui;
5467dd7cddfSDavid du Colombier 	ret->lo = t;
5477dd7cddfSDavid du Colombier 	ret->hi = 0;
5487dd7cddfSDavid du Colombier }
5497dd7cddfSDavid du Colombier 
5507dd7cddfSDavid du Colombier void
_sh2v(Vlong * ret,long sh)551219b2ee8SDavid du Colombier _sh2v(Vlong *ret, long sh)
552219b2ee8SDavid du Colombier {
553219b2ee8SDavid du Colombier 	long t;
554219b2ee8SDavid du Colombier 
555219b2ee8SDavid du Colombier 	t = (sh << 16) >> 16;
556219b2ee8SDavid du Colombier 	ret->lo = t;
557219b2ee8SDavid du Colombier 	ret->hi = t >> 31;
558219b2ee8SDavid du Colombier }
559219b2ee8SDavid du Colombier 
560219b2ee8SDavid du Colombier void
_uh2v(Vlong * ret,ulong ul)561219b2ee8SDavid du Colombier _uh2v(Vlong *ret, ulong ul)
562219b2ee8SDavid du Colombier {
563219b2ee8SDavid du Colombier 	long t;
564219b2ee8SDavid du Colombier 
565219b2ee8SDavid du Colombier 	t = ul & 0xffff;
566219b2ee8SDavid du Colombier 	ret->lo = t;
567219b2ee8SDavid du Colombier 	ret->hi = 0;
568219b2ee8SDavid du Colombier }
569219b2ee8SDavid du Colombier 
570219b2ee8SDavid du Colombier void
_sc2v(Vlong * ret,long uc)571219b2ee8SDavid du Colombier _sc2v(Vlong *ret, long uc)
572219b2ee8SDavid du Colombier {
573219b2ee8SDavid du Colombier 	long t;
574219b2ee8SDavid du Colombier 
575219b2ee8SDavid du Colombier 	t = (uc << 24) >> 24;
576219b2ee8SDavid du Colombier 	ret->lo = t;
577219b2ee8SDavid du Colombier 	ret->hi = t >> 31;
578219b2ee8SDavid du Colombier }
579219b2ee8SDavid du Colombier 
580219b2ee8SDavid du Colombier void
_uc2v(Vlong * ret,ulong ul)581219b2ee8SDavid du Colombier _uc2v(Vlong *ret, ulong ul)
582219b2ee8SDavid du Colombier {
583219b2ee8SDavid du Colombier 	long t;
584219b2ee8SDavid du Colombier 
585219b2ee8SDavid du Colombier 	t = ul & 0xff;
586219b2ee8SDavid du Colombier 	ret->lo = t;
587219b2ee8SDavid du Colombier 	ret->hi = 0;
588219b2ee8SDavid du Colombier }
589219b2ee8SDavid du Colombier 
590219b2ee8SDavid du Colombier long
_v2sc(Vlong rv)591219b2ee8SDavid du Colombier _v2sc(Vlong rv)
592219b2ee8SDavid du Colombier {
593219b2ee8SDavid du Colombier 	long t;
594219b2ee8SDavid du Colombier 
595219b2ee8SDavid du Colombier 	t = rv.lo & 0xff;
596219b2ee8SDavid du Colombier 	return (t << 24) >> 24;
597219b2ee8SDavid du Colombier }
598219b2ee8SDavid du Colombier 
599219b2ee8SDavid du Colombier long
_v2uc(Vlong rv)600219b2ee8SDavid du Colombier _v2uc(Vlong rv)
601219b2ee8SDavid du Colombier {
602219b2ee8SDavid du Colombier 
603219b2ee8SDavid du Colombier 	return rv.lo & 0xff;
604219b2ee8SDavid du Colombier }
605219b2ee8SDavid du Colombier 
606219b2ee8SDavid du Colombier long
_v2sh(Vlong rv)607219b2ee8SDavid du Colombier _v2sh(Vlong rv)
608219b2ee8SDavid du Colombier {
609219b2ee8SDavid du Colombier 	long t;
610219b2ee8SDavid du Colombier 
611219b2ee8SDavid du Colombier 	t = rv.lo & 0xffff;
612219b2ee8SDavid du Colombier 	return (t << 16) >> 16;
613219b2ee8SDavid du Colombier }
614219b2ee8SDavid du Colombier 
615219b2ee8SDavid du Colombier long
_v2uh(Vlong rv)616219b2ee8SDavid du Colombier _v2uh(Vlong rv)
617219b2ee8SDavid du Colombier {
618219b2ee8SDavid du Colombier 
619219b2ee8SDavid du Colombier 	return rv.lo & 0xffff;
620219b2ee8SDavid du Colombier }
621219b2ee8SDavid du Colombier 
622219b2ee8SDavid du Colombier long
_v2sl(Vlong rv)623219b2ee8SDavid du Colombier _v2sl(Vlong rv)
624219b2ee8SDavid du Colombier {
625219b2ee8SDavid du Colombier 
626219b2ee8SDavid du Colombier 	return rv.lo;
627219b2ee8SDavid du Colombier }
628219b2ee8SDavid du Colombier 
629219b2ee8SDavid du Colombier long
_v2ul(Vlong rv)630219b2ee8SDavid du Colombier _v2ul(Vlong rv)
631219b2ee8SDavid du Colombier {
632219b2ee8SDavid du Colombier 
633219b2ee8SDavid du Colombier 	return rv.lo;
634219b2ee8SDavid du Colombier }
635219b2ee8SDavid du Colombier 
6367dd7cddfSDavid du Colombier long
_v2si(Vlong rv)6377dd7cddfSDavid du Colombier _v2si(Vlong rv)
6387dd7cddfSDavid du Colombier {
6397dd7cddfSDavid du Colombier 
6407dd7cddfSDavid du Colombier 	return rv.lo;
6417dd7cddfSDavid du Colombier }
6427dd7cddfSDavid du Colombier 
6437dd7cddfSDavid du Colombier long
_v2ui(Vlong rv)6447dd7cddfSDavid du Colombier _v2ui(Vlong rv)
6457dd7cddfSDavid du Colombier {
6467dd7cddfSDavid du Colombier 
6477dd7cddfSDavid du Colombier 	return rv.lo;
6487dd7cddfSDavid du Colombier }
6497dd7cddfSDavid du Colombier 
650219b2ee8SDavid du Colombier int
_testv(Vlong rv)651219b2ee8SDavid du Colombier _testv(Vlong rv)
652219b2ee8SDavid du Colombier {
653219b2ee8SDavid du Colombier 	return rv.lo || rv.hi;
654219b2ee8SDavid du Colombier }
655219b2ee8SDavid du Colombier 
656219b2ee8SDavid du Colombier int
_eqv(Vlong lv,Vlong rv)657219b2ee8SDavid du Colombier _eqv(Vlong lv, Vlong rv)
658219b2ee8SDavid du Colombier {
659219b2ee8SDavid du Colombier 	return lv.lo == rv.lo && lv.hi == rv.hi;
660219b2ee8SDavid du Colombier }
661219b2ee8SDavid du Colombier 
662219b2ee8SDavid du Colombier int
_nev(Vlong lv,Vlong rv)663219b2ee8SDavid du Colombier _nev(Vlong lv, Vlong rv)
664219b2ee8SDavid du Colombier {
665219b2ee8SDavid du Colombier 	return lv.lo != rv.lo || lv.hi != rv.hi;
666219b2ee8SDavid du Colombier }
667219b2ee8SDavid du Colombier 
668219b2ee8SDavid du Colombier int
_ltv(Vlong lv,Vlong rv)669219b2ee8SDavid du Colombier _ltv(Vlong lv, Vlong rv)
670219b2ee8SDavid du Colombier {
671219b2ee8SDavid du Colombier 	return (long)lv.hi < (long)rv.hi ||
672219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo < rv.lo);
673219b2ee8SDavid du Colombier }
674219b2ee8SDavid du Colombier 
675219b2ee8SDavid du Colombier int
_lev(Vlong lv,Vlong rv)676219b2ee8SDavid du Colombier _lev(Vlong lv, Vlong rv)
677219b2ee8SDavid du Colombier {
678219b2ee8SDavid du Colombier 	return (long)lv.hi < (long)rv.hi ||
679219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo <= rv.lo);
680219b2ee8SDavid du Colombier }
681219b2ee8SDavid du Colombier 
682219b2ee8SDavid du Colombier int
_gtv(Vlong lv,Vlong rv)683219b2ee8SDavid du Colombier _gtv(Vlong lv, Vlong rv)
684219b2ee8SDavid du Colombier {
685219b2ee8SDavid du Colombier 	return (long)lv.hi > (long)rv.hi ||
686219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo > rv.lo);
687219b2ee8SDavid du Colombier }
688219b2ee8SDavid du Colombier 
689219b2ee8SDavid du Colombier int
_gev(Vlong lv,Vlong rv)690219b2ee8SDavid du Colombier _gev(Vlong lv, Vlong rv)
691219b2ee8SDavid du Colombier {
692219b2ee8SDavid du Colombier 	return (long)lv.hi > (long)rv.hi ||
693219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo >= rv.lo);
694219b2ee8SDavid du Colombier }
695219b2ee8SDavid du Colombier 
696219b2ee8SDavid du Colombier int
_lov(Vlong lv,Vlong rv)697219b2ee8SDavid du Colombier _lov(Vlong lv, Vlong rv)
698219b2ee8SDavid du Colombier {
699219b2ee8SDavid du Colombier 	return lv.hi < rv.hi ||
700219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo < rv.lo);
701219b2ee8SDavid du Colombier }
702219b2ee8SDavid du Colombier 
703219b2ee8SDavid du Colombier int
_lsv(Vlong lv,Vlong rv)704219b2ee8SDavid du Colombier _lsv(Vlong lv, Vlong rv)
705219b2ee8SDavid du Colombier {
706219b2ee8SDavid du Colombier 	return lv.hi < rv.hi ||
707219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo <= rv.lo);
708219b2ee8SDavid du Colombier }
709219b2ee8SDavid du Colombier 
710219b2ee8SDavid du Colombier int
_hiv(Vlong lv,Vlong rv)711219b2ee8SDavid du Colombier _hiv(Vlong lv, Vlong rv)
712219b2ee8SDavid du Colombier {
713219b2ee8SDavid du Colombier 	return lv.hi > rv.hi ||
714219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo > rv.lo);
715219b2ee8SDavid du Colombier }
716219b2ee8SDavid du Colombier 
717219b2ee8SDavid du Colombier int
_hsv(Vlong lv,Vlong rv)718219b2ee8SDavid du Colombier _hsv(Vlong lv, Vlong rv)
719219b2ee8SDavid du Colombier {
720219b2ee8SDavid du Colombier 	return lv.hi > rv.hi ||
721219b2ee8SDavid du Colombier 		(lv.hi == rv.hi && lv.lo >= rv.lo);
722219b2ee8SDavid du Colombier }
723