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