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