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