xref: /plan9/sys/src/cmd/8c/swt.c (revision 178702b161d3fe3e021aa6cb2f305be898e56ca0)
13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
swit1(C1 * q,int nc,long def,Node * n)43e12c5d1SDavid du Colombier swit1(C1 *q, int nc, long def, Node *n)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	C1 *r;
73e12c5d1SDavid du Colombier 	int i;
83e12c5d1SDavid du Colombier 	Prog *sp;
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier 	if(nc < 5) {
113e12c5d1SDavid du Colombier 		for(i=0; i<nc; i++) {
12*178702b1SDavid du Colombier 			if(debug['K'])
133a276d32SDavid du Colombier 				print("case = %.8llux\n", q->val);
143e12c5d1SDavid du Colombier 			gopcode(OEQ, n->type, n, nodconst(q->val));
153e12c5d1SDavid du Colombier 			patch(p, q->label);
163e12c5d1SDavid du Colombier 			q++;
173e12c5d1SDavid du Colombier 		}
183e12c5d1SDavid du Colombier 		gbranch(OGOTO);
193e12c5d1SDavid du Colombier 		patch(p, def);
203e12c5d1SDavid du Colombier 		return;
213e12c5d1SDavid du Colombier 	}
223e12c5d1SDavid du Colombier 	i = nc / 2;
233e12c5d1SDavid du Colombier 	r = q+i;
24*178702b1SDavid du Colombier 	if(debug['K'])
253a276d32SDavid du Colombier 		print("case > %.8llux\n", r->val);
263e12c5d1SDavid du Colombier 	gopcode(OGT, n->type, n, nodconst(r->val));
273e12c5d1SDavid du Colombier 	sp = p;
283e12c5d1SDavid du Colombier 	gbranch(OGOTO);
293e12c5d1SDavid du Colombier 	p->as = AJEQ;
303e12c5d1SDavid du Colombier 	patch(p, r->label);
313e12c5d1SDavid du Colombier 	swit1(q, i, def, n);
323e12c5d1SDavid du Colombier 
33*178702b1SDavid du Colombier 	if(debug['K'])
343a276d32SDavid du Colombier 		print("case < %.8llux\n", r->val);
353e12c5d1SDavid du Colombier 	patch(sp, pc);
363e12c5d1SDavid du Colombier 	swit1(r+1, nc-i-1, def, n);
373e12c5d1SDavid du Colombier }
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)403e12c5d1SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
413e12c5d1SDavid du Colombier {
423e12c5d1SDavid du Colombier 	int sh;
433e12c5d1SDavid du Colombier 	long v;
443e12c5d1SDavid du Colombier 	Node *l;
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	/*
473e12c5d1SDavid du Colombier 	 * n1 gets adjusted/masked value
483e12c5d1SDavid du Colombier 	 * n2 gets address of cell
493e12c5d1SDavid du Colombier 	 * n3 gets contents of cell
503e12c5d1SDavid du Colombier 	 */
513e12c5d1SDavid du Colombier 	l = b->left;
523e12c5d1SDavid du Colombier 	if(n2 != Z) {
533e12c5d1SDavid du Colombier 		regalloc(n1, l, nn);
543e12c5d1SDavid du Colombier 		reglcgen(n2, l, Z);
553e12c5d1SDavid du Colombier 		regalloc(n3, l, Z);
563e12c5d1SDavid du Colombier 		gmove(n2, n3);
573e12c5d1SDavid du Colombier 		gmove(n3, n1);
583e12c5d1SDavid du Colombier 	} else {
593e12c5d1SDavid du Colombier 		regalloc(n1, l, nn);
603e12c5d1SDavid du Colombier 		cgen(l, n1);
613e12c5d1SDavid du Colombier 	}
623e12c5d1SDavid du Colombier 	if(b->type->shift == 0 && typeu[b->type->etype]) {
633e12c5d1SDavid du Colombier 		v = ~0 + (1L << b->type->nbits);
643e12c5d1SDavid du Colombier 		gopcode(OAND, types[TLONG], nodconst(v), n1);
653e12c5d1SDavid du Colombier 	} else {
663e12c5d1SDavid du Colombier 		sh = 32 - b->type->shift - b->type->nbits;
673e12c5d1SDavid du Colombier 		if(sh > 0)
683e12c5d1SDavid du Colombier 			gopcode(OASHL, types[TLONG], nodconst(sh), n1);
693e12c5d1SDavid du Colombier 		sh += b->type->shift;
703e12c5d1SDavid du Colombier 		if(sh > 0)
713e12c5d1SDavid du Colombier 			if(typeu[b->type->etype])
723e12c5d1SDavid du Colombier 				gopcode(OLSHR, types[TLONG], nodconst(sh), n1);
733e12c5d1SDavid du Colombier 			else
743e12c5d1SDavid du Colombier 				gopcode(OASHR, types[TLONG], nodconst(sh), n1);
753e12c5d1SDavid du Colombier 	}
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)793e12c5d1SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
803e12c5d1SDavid du Colombier {
813e12c5d1SDavid du Colombier 	long v;
823e12c5d1SDavid du Colombier 	Node nod;
833e12c5d1SDavid du Colombier 	int sh;
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier 	regalloc(&nod, b->left, Z);
863e12c5d1SDavid du Colombier 	v = ~0 + (1L << b->type->nbits);
873e12c5d1SDavid du Colombier 	gopcode(OAND, types[TLONG], nodconst(v), n1);
883e12c5d1SDavid du Colombier 	gmove(n1, &nod);
893e12c5d1SDavid du Colombier 	if(nn != Z)
903e12c5d1SDavid du Colombier 		gmove(n1, nn);
913e12c5d1SDavid du Colombier 	sh = b->type->shift;
923e12c5d1SDavid du Colombier 	if(sh > 0)
933e12c5d1SDavid du Colombier 		gopcode(OASHL, types[TLONG], nodconst(sh), &nod);
943e12c5d1SDavid du Colombier 	v <<= sh;
953e12c5d1SDavid du Colombier 	gopcode(OAND, types[TLONG], nodconst(~v), n3);
963e12c5d1SDavid du Colombier 	gopcode(OOR, types[TLONG], n3, &nod);
973e12c5d1SDavid du Colombier 	gmove(&nod, n2);
983e12c5d1SDavid du Colombier 
993e12c5d1SDavid du Colombier 	regfree(&nod);
1003e12c5d1SDavid du Colombier 	regfree(n1);
1013e12c5d1SDavid du Colombier 	regfree(n2);
1023e12c5d1SDavid du Colombier 	regfree(n3);
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier 
1053e12c5d1SDavid du Colombier long
outstring(char * s,long n)1063e12c5d1SDavid du Colombier outstring(char *s, long n)
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier 	long r;
1093e12c5d1SDavid du Colombier 
1109a747e4fSDavid du Colombier 	if(suppress)
1119a747e4fSDavid du Colombier 		return nstring;
1123e12c5d1SDavid du Colombier 	r = nstring;
1133e12c5d1SDavid du Colombier 	while(n) {
1143e12c5d1SDavid du Colombier 		string[mnstring] = *s++;
1153e12c5d1SDavid du Colombier 		mnstring++;
1163e12c5d1SDavid du Colombier 		nstring++;
1173e12c5d1SDavid du Colombier 		if(mnstring >= NSNAME) {
1183e12c5d1SDavid du Colombier 			gpseudo(ADATA, symstring, nodconst(0L));
1193e12c5d1SDavid du Colombier 			p->from.offset += nstring - NSNAME;
1203e12c5d1SDavid du Colombier 			p->from.scale = NSNAME;
1213e12c5d1SDavid du Colombier 			p->to.type = D_SCONST;
1223e12c5d1SDavid du Colombier 			memmove(p->to.sval, string, NSNAME);
1233e12c5d1SDavid du Colombier 			mnstring = 0;
1243e12c5d1SDavid du Colombier 		}
1253e12c5d1SDavid du Colombier 		n--;
1263e12c5d1SDavid du Colombier 	}
1273e12c5d1SDavid du Colombier 	return r;
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier void
gextern(Sym * s,Node * a,long o,long w)1313e12c5d1SDavid du Colombier gextern(Sym *s, Node *a, long o, long w)
1323e12c5d1SDavid du Colombier {
133219b2ee8SDavid du Colombier 	if(a->op == OCONST && typev[a->type->etype]) {
134375daca8SDavid du Colombier 		gpseudo(ADATA, s, lo64(a));
135219b2ee8SDavid du Colombier 		p->from.offset += o;
136219b2ee8SDavid du Colombier 		p->from.scale = 4;
137375daca8SDavid du Colombier 		gpseudo(ADATA, s, hi64(a));
138219b2ee8SDavid du Colombier 		p->from.offset += o + 4;
139219b2ee8SDavid du Colombier 		p->from.scale = 4;
140219b2ee8SDavid du Colombier 		return;
141219b2ee8SDavid du Colombier 	}
1423e12c5d1SDavid du Colombier 	gpseudo(ADATA, s, a);
1433e12c5d1SDavid du Colombier 	p->from.offset += o;
1443e12c5d1SDavid du Colombier 	p->from.scale = w;
1453e12c5d1SDavid du Colombier 	switch(p->to.type) {
1463e12c5d1SDavid du Colombier 	default:
1473e12c5d1SDavid du Colombier 		p->to.index = p->to.type;
1483e12c5d1SDavid du Colombier 		p->to.type = D_ADDR;
1493e12c5d1SDavid du Colombier 	case D_CONST:
1503e12c5d1SDavid du Colombier 	case D_FCONST:
1513e12c5d1SDavid du Colombier 	case D_ADDR:
1523e12c5d1SDavid du Colombier 		break;
1533e12c5d1SDavid du Colombier 	}
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier 
156375daca8SDavid du Colombier void	zname(Biobuf*, Sym*, int);
1573e12c5d1SDavid du Colombier void	zaddr(Biobuf*, Adr*, int);
1583e12c5d1SDavid du Colombier void	outhist(Biobuf*);
1593e12c5d1SDavid du Colombier 
1603e12c5d1SDavid du Colombier void
outcode(void)1613e12c5d1SDavid du Colombier outcode(void)
1623e12c5d1SDavid du Colombier {
1633e12c5d1SDavid du Colombier 	struct { Sym *sym; short type; } h[NSYM];
1643e12c5d1SDavid du Colombier 	Prog *p;
1653e12c5d1SDavid du Colombier 	Sym *s;
1663e12c5d1SDavid du Colombier 	int f, sf, st, t, sym;
1673e12c5d1SDavid du Colombier 	Biobuf b;
1683e12c5d1SDavid du Colombier 
1693e12c5d1SDavid du Colombier 	if(debug['S']) {
1703e12c5d1SDavid du Colombier 		for(p = firstp; p != P; p = p->link)
1713e12c5d1SDavid du Colombier 			if(p->as != ADATA && p->as != AGLOBL)
1723e12c5d1SDavid du Colombier 				pc--;
1733e12c5d1SDavid du Colombier 		for(p = firstp; p != P; p = p->link) {
1743e12c5d1SDavid du Colombier 			print("%P\n", p);
1753e12c5d1SDavid du Colombier 			if(p->as != ADATA && p->as != AGLOBL)
1763e12c5d1SDavid du Colombier 				pc++;
1773e12c5d1SDavid du Colombier 		}
1783e12c5d1SDavid du Colombier 	}
1793e12c5d1SDavid du Colombier 	f = open(outfile, OWRITE);
1803e12c5d1SDavid du Colombier 	if(f < 0) {
1813e12c5d1SDavid du Colombier 		diag(Z, "cannot open %s", outfile);
1823e12c5d1SDavid du Colombier 		return;
1833e12c5d1SDavid du Colombier 	}
1843e12c5d1SDavid du Colombier 	Binit(&b, f, OWRITE);
1853e12c5d1SDavid du Colombier 	Bseek(&b, 0L, 2);
1863e12c5d1SDavid du Colombier 	outhist(&b);
1873e12c5d1SDavid du Colombier 	for(sym=0; sym<NSYM; sym++) {
1883e12c5d1SDavid du Colombier 		h[sym].sym = S;
1893e12c5d1SDavid du Colombier 		h[sym].type = 0;
1903e12c5d1SDavid du Colombier 	}
1913e12c5d1SDavid du Colombier 	sym = 1;
1923e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
1933e12c5d1SDavid du Colombier 	jackpot:
1943e12c5d1SDavid du Colombier 		sf = 0;
1953e12c5d1SDavid du Colombier 		s = p->from.sym;
1963e12c5d1SDavid du Colombier 		while(s != S) {
1973e12c5d1SDavid du Colombier 			sf = s->sym;
1983e12c5d1SDavid du Colombier 			if(sf < 0 || sf >= NSYM)
1993e12c5d1SDavid du Colombier 				sf = 0;
2003e12c5d1SDavid du Colombier 			t = p->from.type;
2013e12c5d1SDavid du Colombier 			if(t == D_ADDR)
2023e12c5d1SDavid du Colombier 				t = p->from.index;
2033e12c5d1SDavid du Colombier 			if(h[sf].type == t)
2043e12c5d1SDavid du Colombier 			if(h[sf].sym == s)
2053e12c5d1SDavid du Colombier 				break;
2063e12c5d1SDavid du Colombier 			s->sym = sym;
207375daca8SDavid du Colombier 			zname(&b, s, t);
2083e12c5d1SDavid du Colombier 			h[sym].sym = s;
2093e12c5d1SDavid du Colombier 			h[sym].type = t;
2103e12c5d1SDavid du Colombier 			sf = sym;
2113e12c5d1SDavid du Colombier 			sym++;
2123e12c5d1SDavid du Colombier 			if(sym >= NSYM)
2133e12c5d1SDavid du Colombier 				sym = 1;
2143e12c5d1SDavid du Colombier 			break;
2153e12c5d1SDavid du Colombier 		}
2163e12c5d1SDavid du Colombier 		st = 0;
2173e12c5d1SDavid du Colombier 		s = p->to.sym;
2183e12c5d1SDavid du Colombier 		while(s != S) {
2193e12c5d1SDavid du Colombier 			st = s->sym;
2203e12c5d1SDavid du Colombier 			if(st < 0 || st >= NSYM)
2213e12c5d1SDavid du Colombier 				st = 0;
2223e12c5d1SDavid du Colombier 			t = p->to.type;
2233e12c5d1SDavid du Colombier 			if(t == D_ADDR)
2243e12c5d1SDavid du Colombier 				t = p->to.index;
2253e12c5d1SDavid du Colombier 			if(h[st].type == t)
2263e12c5d1SDavid du Colombier 			if(h[st].sym == s)
2273e12c5d1SDavid du Colombier 				break;
2283e12c5d1SDavid du Colombier 			s->sym = sym;
229375daca8SDavid du Colombier 			zname(&b, s, t);
2303e12c5d1SDavid du Colombier 			h[sym].sym = s;
2313e12c5d1SDavid du Colombier 			h[sym].type = t;
2323e12c5d1SDavid du Colombier 			st = sym;
2333e12c5d1SDavid du Colombier 			sym++;
2343e12c5d1SDavid du Colombier 			if(sym >= NSYM)
2353e12c5d1SDavid du Colombier 				sym = 1;
2363e12c5d1SDavid du Colombier 			if(st == sf)
2373e12c5d1SDavid du Colombier 				goto jackpot;
2383e12c5d1SDavid du Colombier 			break;
2393e12c5d1SDavid du Colombier 		}
2403e12c5d1SDavid du Colombier 		Bputc(&b, p->as);
2413e12c5d1SDavid du Colombier 		Bputc(&b, p->as>>8);
2423e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno);
2433e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno>>8);
2443e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno>>16);
2453e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno>>24);
2463e12c5d1SDavid du Colombier 		zaddr(&b, &p->from, sf);
2473e12c5d1SDavid du Colombier 		zaddr(&b, &p->to, st);
2483e12c5d1SDavid du Colombier 	}
2493e12c5d1SDavid du Colombier 	Bflush(&b);
2503e12c5d1SDavid du Colombier 	close(f);
2513e12c5d1SDavid du Colombier 	firstp = P;
2523e12c5d1SDavid du Colombier 	lastp = P;
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier 
2553e12c5d1SDavid du Colombier void
outhist(Biobuf * b)2563e12c5d1SDavid du Colombier outhist(Biobuf *b)
2573e12c5d1SDavid du Colombier {
2583e12c5d1SDavid du Colombier 	Hist *h;
2597dd7cddfSDavid du Colombier 	char *p, *q, *op, c;
2603e12c5d1SDavid du Colombier 	Prog pg;
2613e12c5d1SDavid du Colombier 	int n;
2623e12c5d1SDavid du Colombier 
2633e12c5d1SDavid du Colombier 	pg = zprog;
2643e12c5d1SDavid du Colombier 	pg.as = AHISTORY;
2657dd7cddfSDavid du Colombier 	c = pathchar();
2663e12c5d1SDavid du Colombier 	for(h = hist; h != H; h = h->link) {
2673e12c5d1SDavid du Colombier 		p = h->name;
268219b2ee8SDavid du Colombier 		op = 0;
269375daca8SDavid du Colombier 		/* on windows skip drive specifier in pathname */
270375daca8SDavid du Colombier 		if(systemtype(Windows) && p && p[1] == ':'){
271375daca8SDavid du Colombier 			p += 2;
272375daca8SDavid du Colombier 			c = *p;
273375daca8SDavid du Colombier 		}
2747dd7cddfSDavid du Colombier 		if(p && p[0] != c && h->offset == 0 && pathname){
2757dd7cddfSDavid du Colombier 			/* on windows skip drive specifier in pathname */
276375daca8SDavid du Colombier 			if(systemtype(Windows) && pathname[1] == ':') {
2777dd7cddfSDavid du Colombier 				op = p;
2787dd7cddfSDavid du Colombier 				p = pathname+2;
279375daca8SDavid du Colombier 				c = *p;
2807dd7cddfSDavid du Colombier 			} else if(pathname[0] == c){
281219b2ee8SDavid du Colombier 				op = p;
282219b2ee8SDavid du Colombier 				p = pathname;
283219b2ee8SDavid du Colombier 			}
2847dd7cddfSDavid du Colombier 		}
2853e12c5d1SDavid du Colombier 		while(p) {
2867dd7cddfSDavid du Colombier 			q = utfrune(p, c);
2873e12c5d1SDavid du Colombier 			if(q) {
2883e12c5d1SDavid du Colombier 				n = q-p;
289375daca8SDavid du Colombier 				if(n == 0){
2903e12c5d1SDavid du Colombier 					n = 1;	/* leading "/" */
291375daca8SDavid du Colombier 					*p = '/';	/* don't emit "\" on windows */
292375daca8SDavid du Colombier 				}
2933e12c5d1SDavid du Colombier 				q++;
2943e12c5d1SDavid du Colombier 			} else {
2953e12c5d1SDavid du Colombier 				n = strlen(p);
2963e12c5d1SDavid du Colombier 				q = 0;
2973e12c5d1SDavid du Colombier 			}
2983e12c5d1SDavid du Colombier 			if(n) {
299219b2ee8SDavid du Colombier 				Bputc(b, ANAME);
300219b2ee8SDavid du Colombier 				Bputc(b, ANAME>>8);
301219b2ee8SDavid du Colombier 				Bputc(b, D_FILE);
302219b2ee8SDavid du Colombier 				Bputc(b, 1);
303219b2ee8SDavid du Colombier 				Bputc(b, '<');
304219b2ee8SDavid du Colombier 				Bwrite(b, p, n);
305219b2ee8SDavid du Colombier 				Bputc(b, 0);
3063e12c5d1SDavid du Colombier 			}
3073e12c5d1SDavid du Colombier 			p = q;
308219b2ee8SDavid du Colombier 			if(p == 0 && op) {
309219b2ee8SDavid du Colombier 				p = op;
310219b2ee8SDavid du Colombier 				op = 0;
311219b2ee8SDavid du Colombier 			}
3123e12c5d1SDavid du Colombier 		}
3133e12c5d1SDavid du Colombier 		pg.lineno = h->line;
3143e12c5d1SDavid du Colombier 		pg.to.type = zprog.to.type;
3153e12c5d1SDavid du Colombier 		pg.to.offset = h->offset;
3163e12c5d1SDavid du Colombier 		if(h->offset)
3173e12c5d1SDavid du Colombier 			pg.to.type = D_CONST;
3183e12c5d1SDavid du Colombier 
3193e12c5d1SDavid du Colombier 		Bputc(b, pg.as);
3203e12c5d1SDavid du Colombier 		Bputc(b, pg.as>>8);
3213e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno);
3223e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno>>8);
3233e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno>>16);
3243e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno>>24);
3253e12c5d1SDavid du Colombier 		zaddr(b, &pg.from, 0);
3263e12c5d1SDavid du Colombier 		zaddr(b, &pg.to, 0);
3273e12c5d1SDavid du Colombier 	}
3283e12c5d1SDavid du Colombier }
3293e12c5d1SDavid du Colombier 
3303e12c5d1SDavid du Colombier void
zname(Biobuf * b,Sym * s,int t)331375daca8SDavid du Colombier zname(Biobuf *b, Sym *s, int t)
3323e12c5d1SDavid du Colombier {
333375daca8SDavid du Colombier 	char *n;
334375daca8SDavid du Colombier 	ulong sig;
3353e12c5d1SDavid du Colombier 
336375daca8SDavid du Colombier 	if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
337375daca8SDavid du Colombier 		sig = sign(s);
338375daca8SDavid du Colombier 		Bputc(b, ASIGNAME);
339375daca8SDavid du Colombier 		Bputc(b, ASIGNAME>>8);
340375daca8SDavid du Colombier 		Bputc(b, sig);
341375daca8SDavid du Colombier 		Bputc(b, sig>>8);
342375daca8SDavid du Colombier 		Bputc(b, sig>>16);
343375daca8SDavid du Colombier 		Bputc(b, sig>>24);
344375daca8SDavid du Colombier 		s->sig = SIGDONE;
345375daca8SDavid du Colombier 	}
346375daca8SDavid du Colombier 	else{
3473e12c5d1SDavid du Colombier 		Bputc(b, ANAME);	/* as */
3483e12c5d1SDavid du Colombier 		Bputc(b, ANAME>>8);	/* as */
349375daca8SDavid du Colombier 	}
3503e12c5d1SDavid du Colombier 	Bputc(b, t);			/* type */
351375daca8SDavid du Colombier 	Bputc(b, s->sym);		/* sym */
352375daca8SDavid du Colombier 	n = s->name;
3533e12c5d1SDavid du Colombier 	while(*n) {
3543e12c5d1SDavid du Colombier 		Bputc(b, *n);
3553e12c5d1SDavid du Colombier 		n++;
3563e12c5d1SDavid du Colombier 	}
3573e12c5d1SDavid du Colombier 	Bputc(b, 0);
3583e12c5d1SDavid du Colombier }
3593e12c5d1SDavid du Colombier 
3603e12c5d1SDavid du Colombier void
zaddr(Biobuf * b,Adr * a,int s)3613e12c5d1SDavid du Colombier zaddr(Biobuf *b, Adr *a, int s)
3623e12c5d1SDavid du Colombier {
3633e12c5d1SDavid du Colombier 	long l;
3643e12c5d1SDavid du Colombier 	int i, t;
3653e12c5d1SDavid du Colombier 	char *n;
3663e12c5d1SDavid du Colombier 	Ieee e;
3673e12c5d1SDavid du Colombier 
3683e12c5d1SDavid du Colombier 	t = 0;
3693e12c5d1SDavid du Colombier 	if(a->index != D_NONE || a->scale != 0)
3703e12c5d1SDavid du Colombier 		t |= T_INDEX;
3713e12c5d1SDavid du Colombier 	if(s != 0)
3723e12c5d1SDavid du Colombier 		t |= T_SYM;
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier 	switch(a->type) {
3753e12c5d1SDavid du Colombier 	default:
3763e12c5d1SDavid du Colombier 		t |= T_TYPE;
3773e12c5d1SDavid du Colombier 	case D_NONE:
3783e12c5d1SDavid du Colombier 		if(a->offset != 0)
3793e12c5d1SDavid du Colombier 			t |= T_OFFSET;
3803e12c5d1SDavid du Colombier 		break;
3813e12c5d1SDavid du Colombier 	case D_FCONST:
3823e12c5d1SDavid du Colombier 		t |= T_FCONST;
3833e12c5d1SDavid du Colombier 		break;
3843e12c5d1SDavid du Colombier 	case D_SCONST:
3853e12c5d1SDavid du Colombier 		t |= T_SCONST;
3863e12c5d1SDavid du Colombier 		break;
3873e12c5d1SDavid du Colombier 	}
3883e12c5d1SDavid du Colombier 	Bputc(b, t);
3893e12c5d1SDavid du Colombier 
3903e12c5d1SDavid du Colombier 	if(t & T_INDEX) {	/* implies index, scale */
3913e12c5d1SDavid du Colombier 		Bputc(b, a->index);
3923e12c5d1SDavid du Colombier 		Bputc(b, a->scale);
3933e12c5d1SDavid du Colombier 	}
3943e12c5d1SDavid du Colombier 	if(t & T_OFFSET) {	/* implies offset */
3953e12c5d1SDavid du Colombier 		l = a->offset;
3963e12c5d1SDavid du Colombier 		Bputc(b, l);
3973e12c5d1SDavid du Colombier 		Bputc(b, l>>8);
3983e12c5d1SDavid du Colombier 		Bputc(b, l>>16);
3993e12c5d1SDavid du Colombier 		Bputc(b, l>>24);
4003e12c5d1SDavid du Colombier 	}
4013e12c5d1SDavid du Colombier 	if(t & T_SYM)		/* implies sym */
4023e12c5d1SDavid du Colombier 		Bputc(b, s);
4033e12c5d1SDavid du Colombier 	if(t & T_FCONST) {
4043e12c5d1SDavid du Colombier 		ieeedtod(&e, a->dval);
4053e12c5d1SDavid du Colombier 		l = e.l;
4063e12c5d1SDavid du Colombier 		Bputc(b, l);
4073e12c5d1SDavid du Colombier 		Bputc(b, l>>8);
4083e12c5d1SDavid du Colombier 		Bputc(b, l>>16);
4093e12c5d1SDavid du Colombier 		Bputc(b, l>>24);
4103e12c5d1SDavid du Colombier 		l = e.h;
4113e12c5d1SDavid du Colombier 		Bputc(b, l);
4123e12c5d1SDavid du Colombier 		Bputc(b, l>>8);
4133e12c5d1SDavid du Colombier 		Bputc(b, l>>16);
4143e12c5d1SDavid du Colombier 		Bputc(b, l>>24);
4153e12c5d1SDavid du Colombier 		return;
4163e12c5d1SDavid du Colombier 	}
4173e12c5d1SDavid du Colombier 	if(t & T_SCONST) {
4183e12c5d1SDavid du Colombier 		n = a->sval;
4193e12c5d1SDavid du Colombier 		for(i=0; i<NSNAME; i++) {
4203e12c5d1SDavid du Colombier 			Bputc(b, *n);
4213e12c5d1SDavid du Colombier 			n++;
4223e12c5d1SDavid du Colombier 		}
4233e12c5d1SDavid du Colombier 		return;
4243e12c5d1SDavid du Colombier 	}
4253e12c5d1SDavid du Colombier 	if(t & T_TYPE)
4263e12c5d1SDavid du Colombier 		Bputc(b, a->type);
4273e12c5d1SDavid du Colombier }
4283e12c5d1SDavid du Colombier 
4297dd7cddfSDavid du Colombier long
align(long i,Type * t,int op)4307dd7cddfSDavid du Colombier align(long i, Type *t, int op)
4313e12c5d1SDavid du Colombier {
4327dd7cddfSDavid du Colombier 	long o;
4337dd7cddfSDavid du Colombier 	Type *v;
4347dd7cddfSDavid du Colombier 	int w;
4353e12c5d1SDavid du Colombier 
4367dd7cddfSDavid du Colombier 	o = i;
4377dd7cddfSDavid du Colombier 	w = 1;
4387dd7cddfSDavid du Colombier 	switch(op) {
4397dd7cddfSDavid du Colombier 	default:
4407dd7cddfSDavid du Colombier 		diag(Z, "unknown align opcode %d", op);
4417dd7cddfSDavid du Colombier 		break;
4427dd7cddfSDavid du Colombier 
4437dd7cddfSDavid du Colombier 	case Asu2:	/* padding at end of a struct */
4447dd7cddfSDavid du Colombier 		w = SZ_LONG;
4459847521cSDavid du Colombier 		if(packflg)
4469847521cSDavid du Colombier 			w = packflg;
4477dd7cddfSDavid du Colombier 		break;
4487dd7cddfSDavid du Colombier 
4497dd7cddfSDavid du Colombier 	case Ael1:	/* initial allign of struct element */
4507dd7cddfSDavid du Colombier 		for(v=t; v->etype==TARRAY; v=v->link)
4517dd7cddfSDavid du Colombier 			;
4527dd7cddfSDavid du Colombier 		w = ewidth[v->etype];
4537dd7cddfSDavid du Colombier 		if(w <= 0 || w >= SZ_LONG)
4547dd7cddfSDavid du Colombier 			w = SZ_LONG;
4559847521cSDavid du Colombier 		if(packflg)
4569847521cSDavid du Colombier 			w = packflg;
4577dd7cddfSDavid du Colombier 		break;
4587dd7cddfSDavid du Colombier 
4597dd7cddfSDavid du Colombier 	case Ael2:	/* width of a struct element */
4607dd7cddfSDavid du Colombier 		o += t->width;
4617dd7cddfSDavid du Colombier 		break;
4627dd7cddfSDavid du Colombier 
4637dd7cddfSDavid du Colombier 	case Aarg0:	/* initial passbyptr argument in arg list */
4647dd7cddfSDavid du Colombier 		if(typesuv[t->etype]) {
4657dd7cddfSDavid du Colombier 			o = align(o, types[TIND], Aarg1);
4667dd7cddfSDavid du Colombier 			o = align(o, types[TIND], Aarg2);
4677dd7cddfSDavid du Colombier 		}
4687dd7cddfSDavid du Colombier 		break;
4697dd7cddfSDavid du Colombier 
4707dd7cddfSDavid du Colombier 	case Aarg1:	/* initial allign of parameter */
4717dd7cddfSDavid du Colombier 		w = ewidth[t->etype];
4727dd7cddfSDavid du Colombier 		if(w <= 0 || w >= SZ_LONG) {
4737dd7cddfSDavid du Colombier 			w = SZ_LONG;
4747dd7cddfSDavid du Colombier 			break;
4757dd7cddfSDavid du Colombier 		}
4767dd7cddfSDavid du Colombier 		w = 1;		/* little endian no adjustment */
4777dd7cddfSDavid du Colombier 		break;
4787dd7cddfSDavid du Colombier 
4797dd7cddfSDavid du Colombier 	case Aarg2:	/* width of a parameter */
4807dd7cddfSDavid du Colombier 		o += t->width;
4817dd7cddfSDavid du Colombier 		w = SZ_LONG;
4827dd7cddfSDavid du Colombier 		break;
4837dd7cddfSDavid du Colombier 
4847dd7cddfSDavid du Colombier 	case Aaut3:	/* total allign of automatic */
4857dd7cddfSDavid du Colombier 		o = align(o, t, Ael1);
4867dd7cddfSDavid du Colombier 		o = align(o, t, Ael2);
4877dd7cddfSDavid du Colombier 		break;
4887dd7cddfSDavid du Colombier 	}
4897dd7cddfSDavid du Colombier 	o = round(o, w);
4907dd7cddfSDavid du Colombier 	if(debug['A'])
4917dd7cddfSDavid du Colombier 		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
4927dd7cddfSDavid du Colombier 	return o;
4933e12c5d1SDavid du Colombier }
4943e12c5d1SDavid du Colombier 
4957dd7cddfSDavid du Colombier long
maxround(long max,long v)4967dd7cddfSDavid du Colombier maxround(long max, long v)
4973e12c5d1SDavid du Colombier {
49885e2e562SDavid du Colombier 	v = round(v, SZ_LONG);
4997dd7cddfSDavid du Colombier 	if(v > max)
50085e2e562SDavid du Colombier 		return v;
5017dd7cddfSDavid du Colombier 	return max;
502219b2ee8SDavid du Colombier }
503