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