Subversion Repositories planix.SVN

Rev

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