Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
#include "gc.h"
2
 
3
static	int	resvreg[nelem(reg)];
4
 
5
void
6
ginit(void)
7
{
8
	int i;
9
	Type *t;
10
 
11
	thechar = '6';
12
	thestring = "amd64";
13
	exregoffset = REGEXT;
14
	exfregoffset = FREGEXT;
15
	listinit();
16
	nstring = 0;
17
	mnstring = 0;
18
	nrathole = 0;
19
	pc = 0;
20
	breakpc = -1;
21
	continpc = -1;
22
	cases = C;
23
	firstp = P;
24
	lastp = P;
25
	tfield = types[TINT];
26
 
27
	typeword = typechlvp;
28
	typeswitch = typechlv;
29
	typecmplx = typesu;
30
 
31
	/* TO DO */
32
	memmove(typechlpv, typechlp, sizeof(typechlpv));
33
	typechlpv[TVLONG] = 1;
34
	typechlpv[TUVLONG] = 1;
35
 
36
	zprog.link = P;
37
	zprog.as = AGOK;
38
	zprog.from.type = D_NONE;
39
	zprog.from.index = D_NONE;
40
	zprog.from.scale = 0;
41
	zprog.to = zprog.from;
42
 
43
	lregnode.op = OREGISTER;
44
	lregnode.class = CEXREG;
45
	lregnode.reg = REGTMP;
46
	lregnode.complex = 0;
47
	lregnode.addable = 11;
48
	lregnode.type = types[TLONG];
49
 
50
	qregnode = lregnode;
51
	qregnode.type = types[TVLONG];
52
 
53
	constnode.op = OCONST;
54
	constnode.class = CXXX;
55
	constnode.complex = 0;
56
	constnode.addable = 20;
57
	constnode.type = types[TLONG];
58
 
59
	vconstnode = constnode;
60
	vconstnode.type = types[TVLONG];
61
 
62
	fconstnode.op = OCONST;
63
	fconstnode.class = CXXX;
64
	fconstnode.complex = 0;
65
	fconstnode.addable = 20;
66
	fconstnode.type = types[TDOUBLE];
67
 
68
	nodsafe = new(ONAME, Z, Z);
69
	nodsafe->sym = slookup(".safe");
70
	nodsafe->type = types[TINT];
71
	nodsafe->etype = types[TINT]->etype;
72
	nodsafe->class = CAUTO;
73
	complex(nodsafe);
74
 
75
	t = typ(TARRAY, types[TCHAR]);
76
	symrathole = slookup(".rathole");
77
	symrathole->class = CGLOBL;
78
	symrathole->type = t;
79
 
80
	nodrat = new(ONAME, Z, Z);
81
	nodrat->sym = symrathole;
82
	nodrat->type = types[TIND];
83
	nodrat->etype = TVOID;
84
	nodrat->class = CGLOBL;
85
	complex(nodrat);
86
	nodrat->type = t;
87
 
88
	nodret = new(ONAME, Z, Z);
89
	nodret->sym = slookup(".ret");
90
	nodret->type = types[TIND];
91
	nodret->etype = TIND;
92
	nodret->class = CPARAM;
93
	nodret = new(OIND, nodret, Z);
94
	complex(nodret);
95
 
96
	if(0)
97
		com64init();
98
 
99
	memset(reg, 0, sizeof(reg));
100
	for(i=0; i<nelem(reg); i++) {
101
		reg[i] = 1;
102
		if(i >= D_AX && i <= D_R15 && i != D_SP)
103
			reg[i] = 0;
104
		if(i >= D_X0 && i <= D_X7)
105
			reg[i] = 0;
106
	}
107
	/* keep two external registers */
108
	reg[REGEXT] = 1;
109
	reg[REGEXT-1] = 1;
110
	memmove(resvreg, reg, sizeof(resvreg));
111
}
112
 
113
void
114
gclean(void)
115
{
116
	int i;
117
	Sym *s;
118
 
119
	reg[D_SP]--;
120
	for(i=D_AX; i<=D_R15; i++)
121
		if(reg[i] && !resvreg[i])
122
			diag(Z, "reg %R left allocated", i);
123
	for(i=D_X0; i<=D_X7; i++)
124
		if(reg[i] && !resvreg[i])
125
			diag(Z, "reg %R left allocated", i);
126
	while(mnstring)
127
		outstring("", 1L);
128
	symstring->type->width = nstring;
129
	symrathole->type->width = nrathole;
130
	for(i=0; i<NHASH; i++)
131
	for(s = hash[i]; s != S; s = s->link) {
132
		if(s->type == T)
133
			continue;
134
		if(s->type->width == 0)
135
			continue;
136
		if(s->class != CGLOBL && s->class != CSTATIC)
137
			continue;
138
		if(s->type == types[TENUM])
139
			continue;
140
		gpseudo(AGLOBL, s, nodconst(s->type->width));
141
	}
142
	nextpc();
143
	p->as = AEND;
144
	outcode();
145
}
146
 
147
void
148
nextpc(void)
149
{
150
 
151
	p = alloc(sizeof(*p));
152
	*p = zprog;
153
	p->lineno = nearln;
154
	pc++;
155
	if(firstp == P) {
156
		firstp = p;
157
		lastp = p;
158
		return;
159
	}
160
	lastp->link = p;
161
	lastp = p;
162
}
163
 
164
void
165
gargs(Node *n, Node *tn1, Node *tn2)
166
{
167
	long regs;
168
	Node fnxargs[20], *fnxp;
169
 
170
	regs = cursafe;
171
 
172
	fnxp = fnxargs;
173
	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
174
 
175
	curarg = 0;
176
	fnxp = fnxargs;
177
	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
178
 
179
	cursafe = regs;
180
}
181
 
182
int
183
nareg(void)
184
{
185
	int i, n;
186
 
187
	n = 0;
188
	for(i=D_AX; i<=D_R15; i++)
189
		if(reg[i] == 0 && !resvreg[i])
190
			n++;
191
	return n;
192
}
193
 
194
void
195
garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
196
{
197
	Node nod;
198
 
199
	if(n == Z)
200
		return;
201
	if(n->op == OLIST) {
202
		garg1(n->left, tn1, tn2, f, fnxp);
203
		garg1(n->right, tn1, tn2, f, fnxp);
204
		return;
205
	}
206
	if(f == 0) {
207
		if(n->complex >= FNX) {
208
			regsalloc(*fnxp, n);
209
			nod = znode;
210
			nod.op = OAS;
211
			nod.left = *fnxp;
212
			nod.right = n;
213
			nod.type = n->type;
214
			cgen(&nod, Z);
215
			(*fnxp)++;
216
		}
217
		return;
218
	}
219
	if(typesu[n->type->etype]) {
220
		regaalloc(tn2, n);
221
		if(n->complex >= FNX) {
222
			sugen(*fnxp, tn2, n->type->width);
223
			(*fnxp)++;
224
		} else
225
			sugen(n, tn2, n->type->width);
226
		return;
227
	}
228
	if(REGARG && curarg == 0 && typechlpv[n->type->etype]) {
229
		regaalloc1(tn1, n);
230
		if(n->complex >= FNX) {
231
			cgen(*fnxp, tn1);
232
			(*fnxp)++;
233
		} else
234
			cgen(n, tn1);
235
		return;
236
	}
237
	if(vconst(n) == 0) {
238
		regaalloc(tn2, n);
239
		gmove(n, tn2);
240
		return;
241
	}
242
	regalloc(tn1, n, Z);
243
	if(n->complex >= FNX) {
244
		cgen(*fnxp, tn1);
245
		(*fnxp)++;
246
	} else
247
		cgen(n, tn1);
248
	regaalloc(tn2, n);
249
	gmove(tn1, tn2);
250
	regfree(tn1);
251
}
252
 
253
Node*
254
nodgconst(vlong v, Type *t)
255
{
256
	if(!typev[t->etype])
257
		return nodconst((long)v);
258
	vconstnode.vconst = v;
259
	return &vconstnode;
260
}
261
 
262
Node*
263
nodconst(long v)
264
{
265
	constnode.vconst = v;
266
	return &constnode;
267
}
268
 
269
Node*
270
nodfconst(double d)
271
{
272
	fconstnode.fconst = d;
273
	return &fconstnode;
274
}
275
 
276
int
277
isreg(Node *n, int r)
278
{
279
 
280
	if(n->op == OREGISTER)
281
		if(n->reg == r)
282
			return 1;
283
	return 0;
284
}
285
 
286
int
287
nodreg(Node *n, Node *nn, int r)
288
{
289
	int et;
290
 
291
	*n = qregnode;
292
	n->reg = r;
293
	if(nn != Z){
294
		et = nn->type->etype;
295
		if(!typefd[et] && nn->type->width <= SZ_LONG && 0)
296
			n->type = typeu[et]? types[TUINT]: types[TINT];
297
		else
298
			n->type = nn->type;
299
//print("nodreg %s [%s]\n", tnames[et], tnames[n->type->etype]);
300
		n->lineno = nn->lineno;
301
	}
302
	if(reg[r] == 0)
303
		return 0;
304
	if(nn != Z) {
305
		if(nn->op == OREGISTER)
306
		if(nn->reg == r)
307
			return 0;
308
	}
309
	return 1;
310
}
311
 
312
void
313
regret(Node *n, Node *nn)
314
{
315
	int r;
316
 
317
	r = REGRET;
318
	if(typefd[nn->type->etype])
319
		r = FREGRET;
320
	nodreg(n, nn, r);
321
	reg[r]++;
322
}
323
 
324
void
325
regalloc(Node *n, Node *tn, Node *o)
326
{
327
	int i;
328
 
329
	switch(tn->type->etype) {
330
	case TCHAR:
331
	case TUCHAR:
332
	case TSHORT:
333
	case TUSHORT:
334
	case TINT:
335
	case TUINT:
336
	case TLONG:
337
	case TULONG:
338
	case TVLONG:
339
	case TUVLONG:
340
	case TIND:
341
		if(o != Z && o->op == OREGISTER) {
342
			i = o->reg;
343
			if(i >= D_AX && i <= D_R15)
344
				goto out;
345
		}
346
		for(i=D_AX; i<=D_R15; i++)
347
			if(reg[i] == 0 && !resvreg[i])
348
				goto out;
349
		diag(tn, "out of fixed registers");
350
		goto err;
351
 
352
	case TFLOAT:
353
	case TDOUBLE:
354
		if(o != Z && o->op == OREGISTER) {
355
			i = o->reg;
356
			if(i >= D_X0 && i <= D_X7)
357
				goto out;
358
		}
359
		for(i=D_X0; i<=D_X7; i++)
360
			if(reg[i] == 0 && !resvreg[i])
361
				goto out;
362
		diag(tn, "out of float registers");
363
		goto out;
364
	}
365
	diag(tn, "unknown type in regalloc: %T", tn->type);
366
err:
367
	i = 0;
368
out:
369
	if(i)
370
		reg[i]++;
371
	nodreg(n, tn, i);
372
}
373
 
374
void
375
regialloc(Node *n, Node *tn, Node *o)
376
{
377
	Node nod;
378
 
379
	nod = *tn;
380
	nod.type = types[TIND];
381
	regalloc(n, &nod, o);
382
}
383
 
384
void
385
regfree(Node *n)
386
{
387
	int i;
388
 
389
	i = 0;
390
	if(n->op != OREGISTER && n->op != OINDREG)
391
		goto err;
392
	i = n->reg;
393
	if(i < 0 || i >= sizeof(reg))
394
		goto err;
395
	if(reg[i] <= 0)
396
		goto err;
397
	reg[i]--;
398
	return;
399
err:
400
	diag(n, "error in regfree: %R", i);
401
}
402
 
403
void
404
regsalloc(Node *n, Node *nn)
405
{
406
	cursafe = align(cursafe, nn->type, Aaut3);
407
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
408
	*n = *nodsafe;
409
	n->xoffset = -(stkoff + cursafe);
410
	n->type = nn->type;
411
	n->etype = nn->type->etype;
412
	n->lineno = nn->lineno;
413
}
414
 
415
void
416
regaalloc1(Node *n, Node *nn)
417
{
418
	nodreg(n, nn, REGARG);
419
	reg[REGARG]++;
420
	curarg = align(curarg, nn->type, Aarg1);
421
	curarg = align(curarg, nn->type, Aarg2);
422
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
423
}
424
 
425
void
426
regaalloc(Node *n, Node *nn)
427
{
428
	curarg = align(curarg, nn->type, Aarg1);
429
	*n = *nn;
430
	n->op = OINDREG;
431
	n->reg = REGSP;
432
	n->xoffset = curarg;
433
	n->complex = 0;
434
	n->addable = 20;
435
	curarg = align(curarg, nn->type, Aarg2);
436
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
437
}
438
 
439
void
440
regind(Node *n, Node *nn)
441
{
442
 
443
	if(n->op != OREGISTER) {
444
		diag(n, "regind not OREGISTER");
445
		return;
446
	}
447
	n->op = OINDREG;
448
	n->type = nn->type;
449
}
450
 
451
void
452
naddr(Node *n, Adr *a)
453
{
454
	long v;
455
 
456
	a->type = D_NONE;
457
	if(n == Z)
458
		return;
459
	switch(n->op) {
460
	default:
461
	bad:
462
		diag(n, "bad in naddr: %O %D", n->op, a);
463
		break;
464
 
465
	case OREGISTER:
466
		a->type = n->reg;
467
		a->sym = S;
468
		break;
469
 
470
 
471
	case OIND:
472
		naddr(n->left, a);
473
		if(a->type >= D_AX && a->type <= D_R15)
474
			a->type += D_INDIR;
475
		else
476
		if(a->type == D_CONST)
477
			a->type = D_NONE+D_INDIR;
478
		else
479
		if(a->type == D_ADDR) {
480
			a->type = a->index;
481
			a->index = D_NONE;
482
		} else
483
			goto bad;
484
		break;
485
 
486
	case OINDEX:
487
		a->type = idx.ptr;
488
		if(n->left->op == OADDR || n->left->op == OCONST)
489
			naddr(n->left, a);
490
		if(a->type >= D_AX && a->type <= D_R15)
491
			a->type += D_INDIR;
492
		else
493
		if(a->type == D_CONST)
494
			a->type = D_NONE+D_INDIR;
495
		else
496
		if(a->type == D_ADDR) {
497
			a->type = a->index;
498
			a->index = D_NONE;
499
		} else
500
			goto bad;
501
		a->index = idx.reg;
502
		a->scale = n->scale;
503
		a->offset += n->xoffset;
504
		break;
505
 
506
	case OINDREG:
507
		a->type = n->reg+D_INDIR;
508
		a->sym = S;
509
		a->offset = n->xoffset;
510
		break;
511
 
512
	case ONAME:
513
		a->etype = n->etype;
514
		a->type = D_STATIC;
515
		a->sym = n->sym;
516
		a->offset = n->xoffset;
517
		if(n->class == CSTATIC)
518
			break;
519
		if(n->class == CEXTERN || n->class == CGLOBL) {
520
			a->type = D_EXTERN;
521
			break;
522
		}
523
		if(n->class == CAUTO) {
524
			a->type = D_AUTO;
525
			break;
526
		}
527
		if(n->class == CPARAM) {
528
			a->type = D_PARAM;
529
			break;
530
		}
531
		goto bad;
532
 
533
	case OCONST:
534
		if(typefd[n->type->etype]) {
535
			a->type = D_FCONST;
536
			a->dval = n->fconst;
537
			break;
538
		}
539
		a->sym = S;
540
		a->type = D_CONST;
541
		if(typev[n->type->etype] || n->type->etype == TIND)
542
			a->offset = n->vconst;
543
		else
544
			a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
545
		break;
546
 
547
	case OADDR:
548
		naddr(n->left, a);
549
		if(a->type >= D_INDIR) {
550
			a->type -= D_INDIR;
551
			break;
552
		}
553
		if(a->type == D_EXTERN || a->type == D_STATIC ||
554
		   a->type == D_AUTO || a->type == D_PARAM)
555
			if(a->index == D_NONE) {
556
				a->index = a->type;
557
				a->type = D_ADDR;
558
				break;
559
			}
560
		goto bad;
561
 
562
	case OADD:
563
		if(n->right->op == OCONST) {
564
			v = n->right->vconst;
565
			naddr(n->left, a);
566
		} else
567
		if(n->left->op == OCONST) {
568
			v = n->left->vconst;
569
			naddr(n->right, a);
570
		} else
571
			goto bad;
572
		a->offset += v;
573
		break;
574
 
575
	}
576
}
577
 
578
void
579
gcmp(int op, Node *n, vlong val)
580
{
581
	Node *cn, nod;
582
 
583
	cn = nodgconst(val, n->type);
584
	if(!immconst(cn)){
585
		regalloc(&nod, n, Z);
586
		gmove(cn, &nod);
587
		gopcode(op, n->type, n, &nod);
588
		regfree(&nod);
589
	}else
590
		gopcode(op, n->type, n, cn);
591
}
592
 
593
#define	CASE(a,b)	((a<<8)|(b<<0))
594
 
595
void
596
gmove(Node *f, Node *t)
597
{
598
	int ft, tt, t64, a;
599
	Node nod, nod1, nod2, nod3;
600
	Prog *p1, *p2;
601
 
602
	ft = f->type->etype;
603
	tt = t->type->etype;
604
	t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
605
	if(debug['M'])
606
		print("gop: %O %O[%s],%O[%s]\n", OAS,
607
			f->op, tnames[ft], t->op, tnames[tt]);
608
	if(typefd[ft] && f->op == OCONST) {
609
		/* TO DO: pick up special constants, possibly preloaded */
610
		if(f->fconst == 0.0){
611
			regalloc(&nod, t, t);
612
			gins(AXORPD, &nod, &nod);
613
			gmove(&nod, t);
614
			regfree(&nod);
615
			return;
616
		}
617
	}
618
/*
619
 * load
620
 */
621
	if(f->op == ONAME || f->op == OINDREG ||
622
	   f->op == OIND || f->op == OINDEX)
623
	switch(ft) {
624
	case TCHAR:
625
		a = AMOVBLSX;
626
		if(t64)
627
			a = AMOVBQSX;
628
		goto ld;
629
	case TUCHAR:
630
		a = AMOVBLZX;
631
		if(t64)
632
			a = AMOVBQZX;
633
		goto ld;
634
	case TSHORT:
635
		a = AMOVWLSX;
636
		if(t64)
637
			a = AMOVWQSX;
638
		goto ld;
639
	case TUSHORT:
640
		a = AMOVWLZX;
641
		if(t64)
642
			a = AMOVWQZX;
643
		goto ld;
644
	case TINT:
645
	case TLONG:
646
		if(typefd[tt]) {
647
			regalloc(&nod, t, t);
648
			if(tt == TDOUBLE)
649
				a = ACVTSL2SD;
650
			else
651
				a = ACVTSL2SS;
652
			gins(a, f, &nod);
653
			gmove(&nod, t);
654
			regfree(&nod);
655
			return;
656
		}
657
		a = AMOVL;
658
		if(t64)
659
			a = AMOVLQSX;
660
		goto ld;
661
	case TUINT:
662
	case TULONG:
663
		a = AMOVL;
664
		if(t64)
665
			a = AMOVLQZX;	/* could probably use plain MOVL */
666
		goto ld;
667
	case TVLONG:
668
		if(typefd[tt]) {
669
			regalloc(&nod, t, t);
670
			if(tt == TDOUBLE)
671
				a = ACVTSQ2SD;
672
			else
673
				a = ACVTSQ2SS;
674
			gins(a, f, &nod);
675
			gmove(&nod, t);
676
			regfree(&nod);
677
			return;
678
		}
679
	case TUVLONG:
680
		a = AMOVQ;
681
		goto ld;
682
	case TIND:
683
		a = AMOVQ;
684
 
685
	ld:
686
		regalloc(&nod, f, t);
687
		nod.type = t64? types[TVLONG]: types[TINT];
688
		gins(a, f, &nod);
689
		gmove(&nod, t);
690
		regfree(&nod);
691
		return;
692
 
693
	case TFLOAT:
694
		a = AMOVSS;
695
		goto fld;
696
	case TDOUBLE:
697
		a = AMOVSD;
698
	fld:
699
		regalloc(&nod, f, t);
700
		if(tt != TDOUBLE && tt != TFLOAT){	/* TO DO: why is this here */
701
			prtree(f, "odd tree");
702
			nod.type = t64? types[TVLONG]: types[TINT];
703
		}
704
		gins(a, f, &nod);
705
		gmove(&nod, t);
706
		regfree(&nod);
707
		return;
708
	}
709
 
710
/*
711
 * store
712
 */
713
	if(t->op == ONAME || t->op == OINDREG ||
714
	   t->op == OIND || t->op == OINDEX)
715
	switch(tt) {
716
	case TCHAR:
717
	case TUCHAR:
718
		a = AMOVB;	goto st;
719
	case TSHORT:
720
	case TUSHORT:
721
		a = AMOVW;	goto st;
722
	case TINT:
723
	case TUINT:
724
	case TLONG:
725
	case TULONG:
726
		a = AMOVL;	goto st;
727
	case TVLONG:
728
	case TUVLONG:
729
	case TIND:
730
		a = AMOVQ;	goto st;
731
 
732
	st:
733
		if(f->op == OCONST) {
734
			gins(a, f, t);
735
			return;
736
		}
737
	fst:
738
		regalloc(&nod, t, f);
739
		gmove(f, &nod);
740
		gins(a, &nod, t);
741
		regfree(&nod);
742
		return;
743
 
744
	case TFLOAT:
745
		a = AMOVSS;
746
		goto fst;
747
	case TDOUBLE:
748
		a = AMOVSD;
749
		goto fst;
750
	}
751
 
752
/*
753
 * convert
754
 */
755
	switch(CASE(ft,tt)) {
756
	default:
757
/*
758
 * integer to integer
759
 ********
760
		a = AGOK;	break;
761
 
762
	case CASE(	TCHAR,	TCHAR):
763
	case CASE(	TUCHAR,	TCHAR):
764
	case CASE(	TSHORT,	TCHAR):
765
	case CASE(	TUSHORT,TCHAR):
766
	case CASE(	TINT,	TCHAR):
767
	case CASE(	TUINT,	TCHAR):
768
	case CASE(	TLONG,	TCHAR):
769
	case CASE(	TULONG,	TCHAR):
770
	case CASE(	TIND,	TCHAR):
771
 
772
	case CASE(	TCHAR,	TUCHAR):
773
	case CASE(	TUCHAR,	TUCHAR):
774
	case CASE(	TSHORT,	TUCHAR):
775
	case CASE(	TUSHORT,TUCHAR):
776
	case CASE(	TINT,	TUCHAR):
777
	case CASE(	TUINT,	TUCHAR):
778
	case CASE(	TLONG,	TUCHAR):
779
	case CASE(	TULONG,	TUCHAR):
780
	case CASE(	TIND,	TUCHAR):
781
 
782
	case CASE(	TSHORT,	TSHORT):
783
	case CASE(	TUSHORT,TSHORT):
784
	case CASE(	TINT,	TSHORT):
785
	case CASE(	TUINT,	TSHORT):
786
	case CASE(	TLONG,	TSHORT):
787
	case CASE(	TULONG,	TSHORT):
788
	case CASE(	TIND,	TSHORT):
789
 
790
	case CASE(	TSHORT,	TUSHORT):
791
	case CASE(	TUSHORT,TUSHORT):
792
	case CASE(	TINT,	TUSHORT):
793
	case CASE(	TUINT,	TUSHORT):
794
	case CASE(	TLONG,	TUSHORT):
795
	case CASE(	TULONG,	TUSHORT):
796
	case CASE(	TIND,	TUSHORT):
797
 
798
	case CASE(	TINT,	TINT):
799
	case CASE(	TUINT,	TINT):
800
	case CASE(	TLONG,	TINT):
801
	case CASE(	TULONG,	TINT):
802
	case CASE(	TIND,	TINT):
803
 
804
	case CASE(	TINT,	TUINT):
805
	case CASE(	TUINT,	TUINT):
806
	case CASE(	TLONG,	TUINT):
807
	case CASE(	TULONG,	TUINT):
808
	case CASE(	TIND,	TUINT):
809
 
810
	case CASE(	TUINT,	TIND):
811
	case CASE(	TVLONG,	TUINT):
812
	case CASE(	TVLONG,	TULONG):
813
	case CASE(	TUVLONG, TUINT):
814
	case CASE(	TUVLONG, TULONG):
815
 *****/
816
		a = AMOVL;
817
		break;
818
 
819
	case CASE(	TVLONG,	TCHAR):
820
	case	CASE(	TVLONG,	TSHORT):
821
	case CASE(	TVLONG,	TINT):
822
	case CASE(	TVLONG,	TLONG):
823
	case CASE(	TUVLONG, TCHAR):
824
	case	CASE(	TUVLONG, TSHORT):
825
	case CASE(	TUVLONG, TINT):
826
	case CASE(	TUVLONG, TLONG):
827
	case CASE(	TINT,	TVLONG):
828
	case CASE(	TINT,	TUVLONG):
829
	case CASE(	TLONG,	TVLONG):
830
	case CASE(	TINT,	TIND):
831
	case CASE(	TLONG,	TIND):
832
		a = AMOVLQSX;
833
		if(f->op == OCONST) {
834
			f->vconst &= (uvlong)0xffffffffU;
835
			if(f->vconst & 0x80000000)
836
				f->vconst |= (vlong)0xffffffff << 32;
837
			a = AMOVQ;
838
		}
839
		break;
840
 
841
	case CASE(	TUINT,	TIND):
842
	case CASE(	TUINT,	TVLONG):
843
	case CASE(	TUINT,	TUVLONG):
844
	case CASE(	TULONG,	TVLONG):
845
	case CASE(	TULONG,	TUVLONG):
846
	case CASE(	TULONG,	TIND):
847
		a = AMOVL;	/* same effect as AMOVLQZX */
848
		if(f->op == OCONST) {
849
			f->vconst &= (uvlong)0xffffffffU;
850
			a = AMOVQ;
851
		}
852
		break;
853
 
854
	case CASE(	TIND,	TVLONG):
855
	case CASE(	TVLONG,	TVLONG):
856
	case CASE(	TUVLONG,	TVLONG):
857
	case CASE(	TVLONG,	TUVLONG):
858
	case CASE(	TUVLONG,	TUVLONG):
859
	case CASE(	TIND,	TUVLONG):
860
	case CASE(	TVLONG,	TIND):
861
	case CASE(	TUVLONG,	TIND):
862
	case CASE(	TIND,	TIND):
863
		a = AMOVQ;
864
		break;
865
 
866
	case CASE(	TSHORT,	TINT):
867
	case CASE(	TSHORT,	TUINT):
868
	case CASE(	TSHORT,	TLONG):
869
	case CASE(	TSHORT,	TULONG):
870
		a = AMOVWLSX;
871
		if(f->op == OCONST) {
872
			f->vconst &= 0xffff;
873
			if(f->vconst & 0x8000)
874
				f->vconst |= 0xffff0000;
875
			a = AMOVL;
876
		}
877
		break;
878
 
879
	case CASE(	TSHORT,	TVLONG):
880
	case CASE(	TSHORT,	TUVLONG):
881
	case CASE(	TSHORT,	TIND):
882
		a = AMOVWQSX;
883
		if(f->op == OCONST) {
884
			f->vconst &= 0xffff;
885
			if(f->vconst & 0x8000){
886
				f->vconst |= 0xffff0000;
887
				f->vconst |= (vlong)~0 << 32;
888
			}
889
			a = AMOVL;
890
		}
891
		break;
892
 
893
	case CASE(	TUSHORT,TINT):
894
	case CASE(	TUSHORT,TUINT):
895
	case CASE(	TUSHORT,TLONG):
896
	case CASE(	TUSHORT,TULONG):
897
		a = AMOVWLZX;
898
		if(f->op == OCONST) {
899
			f->vconst &= 0xffff;
900
			a = AMOVL;
901
		}
902
		break;
903
 
904
	case CASE(	TUSHORT,TVLONG):
905
	case CASE(	TUSHORT,TUVLONG):
906
	case CASE(	TUSHORT,TIND):
907
		a = AMOVWQZX;
908
		if(f->op == OCONST) {
909
			f->vconst &= 0xffff;
910
			a = AMOVL;	/* MOVL also zero-extends to 64 bits */
911
		}
912
		break;
913
 
914
	case CASE(	TCHAR,	TSHORT):
915
	case CASE(	TCHAR,	TUSHORT):
916
	case CASE(	TCHAR,	TINT):
917
	case CASE(	TCHAR,	TUINT):
918
	case CASE(	TCHAR,	TLONG):
919
	case CASE(	TCHAR,	TULONG):
920
		a = AMOVBLSX;
921
		if(f->op == OCONST) {
922
			f->vconst &= 0xff;
923
			if(f->vconst & 0x80)
924
				f->vconst |= 0xffffff00;
925
			a = AMOVL;
926
		}
927
		break;
928
 
929
	case CASE(	TCHAR,	TVLONG):
930
	case CASE(	TCHAR,	TUVLONG):
931
	case CASE(	TCHAR,	TIND):
932
		a = AMOVBQSX;
933
		if(f->op == OCONST) {
934
			f->vconst &= 0xff;
935
			if(f->vconst & 0x80){
936
				f->vconst |= 0xffffff00;
937
				f->vconst |= (vlong)~0 << 32;
938
			}
939
			a = AMOVQ;
940
		}
941
		break;
942
 
943
	case CASE(	TUCHAR,	TSHORT):
944
	case CASE(	TUCHAR,	TUSHORT):
945
	case CASE(	TUCHAR,	TINT):
946
	case CASE(	TUCHAR,	TUINT):
947
	case CASE(	TUCHAR,	TLONG):
948
	case CASE(	TUCHAR,	TULONG):
949
		a = AMOVBLZX;
950
		if(f->op == OCONST) {
951
			f->vconst &= 0xff;
952
			a = AMOVL;
953
		}
954
		break;
955
 
956
	case CASE(	TUCHAR,	TVLONG):
957
	case CASE(	TUCHAR,	TUVLONG):
958
	case CASE(	TUCHAR,	TIND):
959
		a = AMOVBQZX;
960
		if(f->op == OCONST) {
961
			f->vconst &= 0xff;
962
			a = AMOVL;	/* zero-extends to 64-bits */
963
		}
964
		break;
965
 
966
/*
967
 * float to fix
968
 */
969
	case CASE(	TFLOAT,	TCHAR):
970
	case CASE(	TFLOAT,	TUCHAR):
971
	case CASE(	TFLOAT,	TSHORT):
972
	case CASE(	TFLOAT,	TUSHORT):
973
	case CASE(	TFLOAT,	TINT):
974
	case CASE(	TFLOAT,	TUINT):
975
	case CASE(	TFLOAT,	TLONG):
976
	case CASE(	TFLOAT,	TULONG):
977
	case CASE(	TFLOAT,	TVLONG):
978
	case CASE(	TFLOAT,	TUVLONG):
979
	case CASE(	TFLOAT,	TIND):
980
 
981
	case CASE(	TDOUBLE,TCHAR):
982
	case CASE(	TDOUBLE,TUCHAR):
983
	case CASE(	TDOUBLE,TSHORT):
984
	case CASE(	TDOUBLE,TUSHORT):
985
	case CASE(	TDOUBLE,TINT):
986
	case CASE(	TDOUBLE,TUINT):
987
	case CASE(	TDOUBLE,TLONG):
988
	case CASE(	TDOUBLE,TULONG):
989
	case CASE(	TDOUBLE,TVLONG):
990
	case CASE(	TDOUBLE,TUVLONG):
991
	case CASE(	TDOUBLE,TIND):
992
		regalloc(&nod, t, Z);
993
		if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){
994
			if(ft == TFLOAT)
995
				a = ACVTTSS2SQ;
996
			else
997
				a = ACVTTSD2SQ;
998
		}else{
999
			if(ft == TFLOAT)
1000
				a = ACVTTSS2SL;
1001
			else
1002
				a = ACVTTSD2SL;
1003
		}
1004
		gins(a, f, &nod);
1005
		gmove(&nod, t);
1006
		regfree(&nod);
1007
		return;
1008
 
1009
/*
1010
 * ulong to float
1011
 */
1012
	case CASE(	TUVLONG,	TDOUBLE):
1013
	case CASE(	TUVLONG,	TFLOAT):
1014
		a = ACVTSQ2SS;
1015
		if(tt == TDOUBLE)
1016
			a = ACVTSQ2SD;
1017
		regalloc(&nod, f, f);
1018
		gmove(f, &nod);
1019
		regalloc(&nod1, t, t);
1020
		gins(ACMPQ, &nod, nodconst(0));
1021
		gins(AJLT, Z, Z);
1022
		p1 = p;
1023
		gins(a, &nod, &nod1);
1024
		gins(AJMP, Z, Z);
1025
		p2 = p;
1026
		patch(p1, pc);
1027
		regalloc(&nod2, f, Z);
1028
		regalloc(&nod3, f, Z);
1029
		gmove(&nod, &nod2);
1030
		gins(ASHRQ, nodconst(1), &nod2);
1031
		gmove(&nod, &nod3);
1032
		gins(AANDL, nodconst(1), &nod3);
1033
		gins(AORQ, &nod3, &nod2);
1034
		gins(a, &nod2, &nod1);
1035
		gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1);
1036
		regfree(&nod2);
1037
		regfree(&nod3);
1038
		patch(p2, pc);
1039
		regfree(&nod);
1040
		regfree(&nod1);
1041
		return;
1042
 
1043
	case CASE(	TULONG,	TDOUBLE):
1044
	case CASE(	TUINT,	TDOUBLE):
1045
	case CASE(	TULONG,	TFLOAT):
1046
	case CASE(	TUINT,	TFLOAT):
1047
		a = ACVTSQ2SS;
1048
		if(tt == TDOUBLE)
1049
			a = ACVTSQ2SD;
1050
		regalloc(&nod, f, f);
1051
		gins(AMOVLQZX, f, &nod);
1052
		regalloc(&nod1, t, t);
1053
		gins(a, &nod, &nod1);
1054
		gmove(&nod1, t);
1055
		regfree(&nod);
1056
		regfree(&nod1);
1057
		return;
1058
 
1059
/*
1060
 * fix to float
1061
 */
1062
	case CASE(	TCHAR,	TFLOAT):
1063
	case CASE(	TUCHAR,	TFLOAT):
1064
	case CASE(	TSHORT,	TFLOAT):
1065
	case CASE(	TUSHORT,TFLOAT):
1066
	case CASE(	TINT,	TFLOAT):
1067
	case CASE(	TLONG,	TFLOAT):
1068
	case	CASE(	TVLONG,	TFLOAT):
1069
	case CASE(	TIND,	TFLOAT):
1070
 
1071
	case CASE(	TCHAR,	TDOUBLE):
1072
	case CASE(	TUCHAR,	TDOUBLE):
1073
	case CASE(	TSHORT,	TDOUBLE):
1074
	case CASE(	TUSHORT,TDOUBLE):
1075
	case CASE(	TINT,	TDOUBLE):
1076
	case CASE(	TLONG,	TDOUBLE):
1077
	case CASE(	TVLONG,	TDOUBLE):
1078
	case CASE(	TIND,	TDOUBLE):
1079
		regalloc(&nod, t, t);
1080
		if(ewidth[ft] == SZ_VLONG){
1081
			if(tt == TFLOAT)
1082
				a = ACVTSQ2SS;
1083
			else
1084
				a = ACVTSQ2SD;
1085
		}else{
1086
			if(tt == TFLOAT)
1087
				a = ACVTSL2SS;
1088
			else
1089
				a = ACVTSL2SD;
1090
		}
1091
		gins(a, f, &nod);
1092
		gmove(&nod, t);
1093
		regfree(&nod);
1094
		return;
1095
 
1096
/*
1097
 * float to float
1098
 */
1099
	case CASE(	TFLOAT,	TFLOAT):
1100
		a = AMOVSS;
1101
		break;
1102
	case CASE(	TDOUBLE,TFLOAT):
1103
		a = ACVTSD2SS;
1104
		break;
1105
	case CASE(	TFLOAT,	TDOUBLE):
1106
		a = ACVTSS2SD;
1107
		break;
1108
	case CASE(	TDOUBLE,TDOUBLE):
1109
		a = AMOVSD;
1110
		break;
1111
	}
1112
	if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt])	/* TO DO: check AMOVL */
1113
	if(samaddr(f, t))
1114
		return;
1115
	gins(a, f, t);
1116
}
1117
 
1118
void
1119
doindex(Node *n)
1120
{
1121
	Node nod, nod1;
1122
	long v;
1123
 
1124
if(debug['Y'])
1125
prtree(n, "index");
1126
 
1127
if(n->left->complex >= FNX)
1128
print("botch in doindex\n");
1129
 
1130
	regalloc(&nod, &qregnode, Z);
1131
	v = constnode.vconst;
1132
	cgen(n->right, &nod);
1133
	idx.ptr = D_NONE;
1134
	if(n->left->op == OCONST)
1135
		idx.ptr = D_CONST;
1136
	else if(n->left->op == OREGISTER)
1137
		idx.ptr = n->left->reg;
1138
	else if(n->left->op != OADDR) {
1139
		reg[D_BP]++;	// cant be used as a base
1140
		regalloc(&nod1, &qregnode, Z);
1141
		cgen(n->left, &nod1);
1142
		idx.ptr = nod1.reg;
1143
		regfree(&nod1);
1144
		reg[D_BP]--;
1145
	}
1146
	idx.reg = nod.reg;
1147
	regfree(&nod);
1148
	constnode.vconst = v;
1149
}
1150
 
1151
void
1152
gins(int a, Node *f, Node *t)
1153
{
1154
 
1155
	if(f != Z && f->op == OINDEX)
1156
		doindex(f);
1157
	if(t != Z && t->op == OINDEX)
1158
		doindex(t);
1159
	nextpc();
1160
	p->as = a;
1161
	if(f != Z)
1162
		naddr(f, &p->from);
1163
	if(t != Z)
1164
		naddr(t, &p->to);
1165
	if(debug['g'])
1166
		print("%P\n", p);
1167
}
1168
 
1169
void
1170
gopcode(int o, Type *ty, Node *f, Node *t)
1171
{
1172
	int a, et;
1173
 
1174
	et = TLONG;
1175
	if(ty != T)
1176
		et = ty->etype;
1177
	if(debug['M']) {
1178
		if(f != Z && f->type != T)
1179
			print("gop: %O %O[%s],", o, f->op, tnames[et]);
1180
		else
1181
			print("gop: %O Z,", o);
1182
		if(t != Z && t->type != T)
1183
			print("%O[%s]\n", t->op, tnames[t->type->etype]);
1184
		else
1185
			print("Z\n");
1186
	}
1187
	a = AGOK;
1188
	switch(o) {
1189
	case OCOM:
1190
		a = ANOTL;
1191
		if(et == TCHAR || et == TUCHAR)
1192
			a = ANOTB;
1193
		if(et == TSHORT || et == TUSHORT)
1194
			a = ANOTW;
1195
		if(et == TVLONG || et == TUVLONG || et == TIND)
1196
			a = ANOTQ;
1197
		break;
1198
 
1199
	case ONEG:
1200
		a = ANEGL;
1201
		if(et == TCHAR || et == TUCHAR)
1202
			a = ANEGB;
1203
		if(et == TSHORT || et == TUSHORT)
1204
			a = ANEGW;
1205
		if(et == TVLONG || et == TUVLONG || et == TIND)
1206
			a = ANEGQ;
1207
		break;
1208
 
1209
	case OADDR:
1210
		a = ALEAQ;
1211
		break;
1212
 
1213
	case OASADD:
1214
	case OADD:
1215
		a = AADDL;
1216
		if(et == TCHAR || et == TUCHAR)
1217
			a = AADDB;
1218
		if(et == TSHORT || et == TUSHORT)
1219
			a = AADDW;
1220
		if(et == TVLONG || et == TUVLONG || et == TIND)
1221
			a = AADDQ;
1222
		if(et == TFLOAT)
1223
			a = AADDSS;
1224
		if(et == TDOUBLE)
1225
			a = AADDSD;
1226
		break;
1227
 
1228
	case OASSUB:
1229
	case OSUB:
1230
		a = ASUBL;
1231
		if(et == TCHAR || et == TUCHAR)
1232
			a = ASUBB;
1233
		if(et == TSHORT || et == TUSHORT)
1234
			a = ASUBW;
1235
		if(et == TVLONG || et == TUVLONG || et == TIND)
1236
			a = ASUBQ;
1237
		if(et == TFLOAT)
1238
			a = ASUBSS;
1239
		if(et == TDOUBLE)
1240
			a = ASUBSD;
1241
		break;
1242
 
1243
	case OASOR:
1244
	case OOR:
1245
		a = AORL;
1246
		if(et == TCHAR || et == TUCHAR)
1247
			a = AORB;
1248
		if(et == TSHORT || et == TUSHORT)
1249
			a = AORW;
1250
		if(et == TVLONG || et == TUVLONG || et == TIND)
1251
			a = AORQ;
1252
		break;
1253
 
1254
	case OASAND:
1255
	case OAND:
1256
		a = AANDL;
1257
		if(et == TCHAR || et == TUCHAR)
1258
			a = AANDB;
1259
		if(et == TSHORT || et == TUSHORT)
1260
			a = AANDW;
1261
		if(et == TVLONG || et == TUVLONG || et == TIND)
1262
			a = AANDQ;
1263
		break;
1264
 
1265
	case OASXOR:
1266
	case OXOR:
1267
		a = AXORL;
1268
		if(et == TCHAR || et == TUCHAR)
1269
			a = AXORB;
1270
		if(et == TSHORT || et == TUSHORT)
1271
			a = AXORW;
1272
		if(et == TVLONG || et == TUVLONG || et == TIND)
1273
			a = AXORQ;
1274
		break;
1275
 
1276
	case OASLSHR:
1277
	case OLSHR:
1278
		a = ASHRL;
1279
		if(et == TCHAR || et == TUCHAR)
1280
			a = ASHRB;
1281
		if(et == TSHORT || et == TUSHORT)
1282
			a = ASHRW;
1283
		if(et == TVLONG || et == TUVLONG || et == TIND)
1284
			a = ASHRQ;
1285
		break;
1286
 
1287
	case OASASHR:
1288
	case OASHR:
1289
		a = ASARL;
1290
		if(et == TCHAR || et == TUCHAR)
1291
			a = ASARB;
1292
		if(et == TSHORT || et == TUSHORT)
1293
			a = ASARW;
1294
		if(et == TVLONG || et == TUVLONG || et == TIND)
1295
			a = ASARQ;
1296
		break;
1297
 
1298
	case OASASHL:
1299
	case OASHL:
1300
		a = ASALL;
1301
		if(et == TCHAR || et == TUCHAR)
1302
			a = ASALB;
1303
		if(et == TSHORT || et == TUSHORT)
1304
			a = ASALW;
1305
		if(et == TVLONG || et == TUVLONG || et == TIND)
1306
			a = ASALQ;
1307
		break;
1308
 
1309
	case OFUNC:
1310
		a = ACALL;
1311
		break;
1312
 
1313
	case OASMUL:
1314
	case OMUL:
1315
		if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1316
			t = Z;
1317
		a = AIMULL;
1318
		if(et == TVLONG || et == TUVLONG || et == TIND)
1319
			a = AIMULQ;
1320
		if(et == TFLOAT)
1321
			a = AMULSS;
1322
		if(et == TDOUBLE)
1323
			a = AMULSD;
1324
		break;
1325
 
1326
	case OASMOD:
1327
	case OMOD:
1328
	case OASDIV:
1329
	case ODIV:
1330
		a = AIDIVL;
1331
		if(et == TVLONG || et == TUVLONG || et == TIND)
1332
			a = AIDIVQ;
1333
		if(et == TFLOAT)
1334
			a = ADIVSS;
1335
		if(et == TDOUBLE)
1336
			a = ADIVSD;
1337
		break;
1338
 
1339
	case OASLMUL:
1340
	case OLMUL:
1341
		a = AMULL;
1342
		if(et == TVLONG || et == TUVLONG || et == TIND)
1343
			a = AMULQ;
1344
		break;
1345
 
1346
	case OASLMOD:
1347
	case OLMOD:
1348
	case OASLDIV:
1349
	case OLDIV:
1350
		a = ADIVL;
1351
		if(et == TVLONG || et == TUVLONG || et == TIND)
1352
			a = ADIVQ;
1353
		break;
1354
 
1355
	case OEQ:
1356
	case ONE:
1357
	case OLT:
1358
	case OLE:
1359
	case OGE:
1360
	case OGT:
1361
	case OLO:
1362
	case OLS:
1363
	case OHS:
1364
	case OHI:
1365
		a = ACMPL;
1366
		if(et == TCHAR || et == TUCHAR)
1367
			a = ACMPB;
1368
		if(et == TSHORT || et == TUSHORT)
1369
			a = ACMPW;
1370
		if(et == TVLONG || et == TUVLONG || et == TIND)
1371
			a = ACMPQ;
1372
		if(et == TFLOAT)
1373
			a = AUCOMISS;
1374
		if(et == TDOUBLE)
1375
			a = AUCOMISD;
1376
		gins(a, f, t);
1377
		switch(o) {
1378
		case OEQ:	a = AJEQ; break;
1379
		case ONE:	a = AJNE; break;
1380
		case OLT:	a = AJLT; break;
1381
		case OLE:	a = AJLE; break;
1382
		case OGE:	a = AJGE; break;
1383
		case OGT:	a = AJGT; break;
1384
		case OLO:	a = AJCS; break;
1385
		case OLS:	a = AJLS; break;
1386
		case OHS:	a = AJCC; break;
1387
		case OHI:	a = AJHI; break;
1388
		}
1389
		gins(a, Z, Z);
1390
		return;
1391
	}
1392
	if(a == AGOK)
1393
		diag(Z, "bad in gopcode %O", o);
1394
	gins(a, f, t);
1395
}
1396
 
1397
int
1398
samaddr(Node *f, Node *t)
1399
{
1400
	return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
1401
}
1402
 
1403
void
1404
gbranch(int o)
1405
{
1406
	int a;
1407
 
1408
	a = AGOK;
1409
	switch(o) {
1410
	case ORETURN:
1411
		a = ARET;
1412
		break;
1413
	case OGOTO:
1414
		a = AJMP;
1415
		break;
1416
	}
1417
	nextpc();
1418
	if(a == AGOK) {
1419
		diag(Z, "bad in gbranch %O",  o);
1420
		nextpc();
1421
	}
1422
	p->as = a;
1423
}
1424
 
1425
void
1426
patch(Prog *op, long pc)
1427
{
1428
 
1429
	op->to.offset = pc;
1430
	op->to.type = D_BRANCH;
1431
}
1432
 
1433
void
1434
gpseudo(int a, Sym *s, Node *n)
1435
{
1436
 
1437
	nextpc();
1438
	p->as = a;
1439
	p->from.type = D_EXTERN;
1440
	p->from.sym = s;
1441
	p->from.scale = (profileflg ? 0 : NOPROF);
1442
	if(s->class == CSTATIC)
1443
		p->from.type = D_STATIC;
1444
	naddr(n, &p->to);
1445
	if(a == ADATA || a == AGLOBL)
1446
		pc--;
1447
}
1448
 
1449
int
1450
sconst(Node *n)
1451
{
1452
	long v;
1453
 
1454
	if(n->op == OCONST && !typefd[n->type->etype]) {
1455
		v = n->vconst;
1456
		if(v >= -32766L && v < 32766L)
1457
			return 1;
1458
	}
1459
	return 0;
1460
}
1461
 
1462
long
1463
exreg(Type *t)
1464
{
1465
	long o;
1466
 
1467
	if(typechlpv[t->etype]) {
1468
		if(exregoffset <= REGEXT-4)
1469
			return 0;
1470
		o = exregoffset;
1471
		exregoffset--;
1472
		return o;
1473
	}
1474
	return 0;
1475
}
1476
 
1477
schar	ewidth[NTYPE] =
1478
{
1479
	-1,		/*[TXXX]*/	
1480
	SZ_CHAR,	/*[TCHAR]*/	
1481
	SZ_CHAR,	/*[TUCHAR]*/
1482
	SZ_SHORT,	/*[TSHORT]*/
1483
	SZ_SHORT,	/*[TUSHORT]*/
1484
	SZ_INT,		/*[TINT]*/
1485
	SZ_INT,		/*[TUINT]*/
1486
	SZ_LONG,	/*[TLONG]*/
1487
	SZ_LONG,	/*[TULONG]*/
1488
	SZ_VLONG,	/*[TVLONG]*/
1489
	SZ_VLONG,	/*[TUVLONG]*/
1490
	SZ_FLOAT,	/*[TFLOAT]*/
1491
	SZ_DOUBLE,	/*[TDOUBLE]*/
1492
	SZ_IND,		/*[TIND]*/
1493
	0,		/*[TFUNC]*/
1494
	-1,		/*[TARRAY]*/
1495
	0,		/*[TVOID]*/
1496
	-1,		/*[TSTRUCT]*/
1497
	-1,		/*[TUNION]*/
1498
	SZ_INT,		/*[TENUM]*/
1499
};
1500
long	ncast[NTYPE] =
1501
{
1502
	0,				/*[TXXX]*/
1503
	BCHAR|BUCHAR,			/*[TCHAR]*/
1504
	BCHAR|BUCHAR,			/*[TUCHAR]*/	
1505
	BSHORT|BUSHORT,			/*[TSHORT]*/
1506
	BSHORT|BUSHORT,			/*[TUSHORT]*/
1507
	BINT|BUINT|BLONG|BULONG,	/*[TINT]*/		
1508
	BINT|BUINT|BLONG|BULONG,	/*[TUINT]*/
1509
	BINT|BUINT|BLONG|BULONG,	/*[TLONG]*/
1510
	BINT|BUINT|BLONG|BULONG,	/*[TULONG]*/
1511
	BVLONG|BUVLONG|BIND,			/*[TVLONG]*/
1512
	BVLONG|BUVLONG|BIND,			/*[TUVLONG]*/
1513
	BFLOAT,				/*[TFLOAT]*/
1514
	BDOUBLE,			/*[TDOUBLE]*/
1515
	BVLONG|BUVLONG|BIND,		/*[TIND]*/
1516
	0,				/*[TFUNC]*/
1517
	0,				/*[TARRAY]*/
1518
	0,				/*[TVOID]*/
1519
	BSTRUCT,			/*[TSTRUCT]*/
1520
	BUNION,				/*[TUNION]*/
1521
	0,				/*[TENUM]*/
1522
};