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