Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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