xref: /inferno-os/utils/8c/swt.c (revision 45a20ab721a513710138340faff3d59a31c3e01e)
174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth void
swit1(C1 * q,int nc,long def,Node * n)474a4d8c2SCharles.Forsyth swit1(C1 *q, int nc, long def, Node *n)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 	C1 *r;
774a4d8c2SCharles.Forsyth 	int i;
874a4d8c2SCharles.Forsyth 	Prog *sp;
974a4d8c2SCharles.Forsyth 
1074a4d8c2SCharles.Forsyth 	if(nc < 5) {
1174a4d8c2SCharles.Forsyth 		for(i=0; i<nc; i++) {
12*45a20ab7Sforsyth 			if(debug['K'])
13*45a20ab7Sforsyth 				print("case = %.8llux\n", q->val);
1474a4d8c2SCharles.Forsyth 			gopcode(OEQ, n->type, n, nodconst(q->val));
1574a4d8c2SCharles.Forsyth 			patch(p, q->label);
1674a4d8c2SCharles.Forsyth 			q++;
1774a4d8c2SCharles.Forsyth 		}
1874a4d8c2SCharles.Forsyth 		gbranch(OGOTO);
1974a4d8c2SCharles.Forsyth 		patch(p, def);
2074a4d8c2SCharles.Forsyth 		return;
2174a4d8c2SCharles.Forsyth 	}
2274a4d8c2SCharles.Forsyth 	i = nc / 2;
2374a4d8c2SCharles.Forsyth 	r = q+i;
24*45a20ab7Sforsyth 	if(debug['K'])
25*45a20ab7Sforsyth 		print("case > %.8llux\n", r->val);
2674a4d8c2SCharles.Forsyth 	gopcode(OGT, n->type, n, nodconst(r->val));
2774a4d8c2SCharles.Forsyth 	sp = p;
2874a4d8c2SCharles.Forsyth 	gbranch(OGOTO);
2974a4d8c2SCharles.Forsyth 	p->as = AJEQ;
3074a4d8c2SCharles.Forsyth 	patch(p, r->label);
3174a4d8c2SCharles.Forsyth 	swit1(q, i, def, n);
3274a4d8c2SCharles.Forsyth 
33*45a20ab7Sforsyth 	if(debug['K'])
34*45a20ab7Sforsyth 		print("case < %.8llux\n", r->val);
3574a4d8c2SCharles.Forsyth 	patch(sp, pc);
3674a4d8c2SCharles.Forsyth 	swit1(r+1, nc-i-1, def, n);
3774a4d8c2SCharles.Forsyth }
3874a4d8c2SCharles.Forsyth 
3974a4d8c2SCharles.Forsyth void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)4074a4d8c2SCharles.Forsyth bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
4174a4d8c2SCharles.Forsyth {
4274a4d8c2SCharles.Forsyth 	int sh;
4374a4d8c2SCharles.Forsyth 	long v;
4474a4d8c2SCharles.Forsyth 	Node *l;
4574a4d8c2SCharles.Forsyth 
4674a4d8c2SCharles.Forsyth 	/*
4774a4d8c2SCharles.Forsyth 	 * n1 gets adjusted/masked value
4874a4d8c2SCharles.Forsyth 	 * n2 gets address of cell
4974a4d8c2SCharles.Forsyth 	 * n3 gets contents of cell
5074a4d8c2SCharles.Forsyth 	 */
5174a4d8c2SCharles.Forsyth 	l = b->left;
5274a4d8c2SCharles.Forsyth 	if(n2 != Z) {
5374a4d8c2SCharles.Forsyth 		regalloc(n1, l, nn);
5474a4d8c2SCharles.Forsyth 		reglcgen(n2, l, Z);
5574a4d8c2SCharles.Forsyth 		regalloc(n3, l, Z);
5674a4d8c2SCharles.Forsyth 		gmove(n2, n3);
5774a4d8c2SCharles.Forsyth 		gmove(n3, n1);
5874a4d8c2SCharles.Forsyth 	} else {
5974a4d8c2SCharles.Forsyth 		regalloc(n1, l, nn);
6074a4d8c2SCharles.Forsyth 		cgen(l, n1);
6174a4d8c2SCharles.Forsyth 	}
6274a4d8c2SCharles.Forsyth 	if(b->type->shift == 0 && typeu[b->type->etype]) {
6374a4d8c2SCharles.Forsyth 		v = ~0 + (1L << b->type->nbits);
6474a4d8c2SCharles.Forsyth 		gopcode(OAND, types[TLONG], nodconst(v), n1);
6574a4d8c2SCharles.Forsyth 	} else {
6674a4d8c2SCharles.Forsyth 		sh = 32 - b->type->shift - b->type->nbits;
6774a4d8c2SCharles.Forsyth 		if(sh > 0)
6874a4d8c2SCharles.Forsyth 			gopcode(OASHL, types[TLONG], nodconst(sh), n1);
6974a4d8c2SCharles.Forsyth 		sh += b->type->shift;
7074a4d8c2SCharles.Forsyth 		if(sh > 0)
7174a4d8c2SCharles.Forsyth 			if(typeu[b->type->etype])
7274a4d8c2SCharles.Forsyth 				gopcode(OLSHR, types[TLONG], nodconst(sh), n1);
7374a4d8c2SCharles.Forsyth 			else
7474a4d8c2SCharles.Forsyth 				gopcode(OASHR, types[TLONG], nodconst(sh), n1);
7574a4d8c2SCharles.Forsyth 	}
7674a4d8c2SCharles.Forsyth }
7774a4d8c2SCharles.Forsyth 
7874a4d8c2SCharles.Forsyth void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)7974a4d8c2SCharles.Forsyth bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
8074a4d8c2SCharles.Forsyth {
8174a4d8c2SCharles.Forsyth 	long v;
8274a4d8c2SCharles.Forsyth 	Node nod;
8374a4d8c2SCharles.Forsyth 	int sh;
8474a4d8c2SCharles.Forsyth 
8574a4d8c2SCharles.Forsyth 	regalloc(&nod, b->left, Z);
8674a4d8c2SCharles.Forsyth 	v = ~0 + (1L << b->type->nbits);
8774a4d8c2SCharles.Forsyth 	gopcode(OAND, types[TLONG], nodconst(v), n1);
8874a4d8c2SCharles.Forsyth 	gmove(n1, &nod);
8974a4d8c2SCharles.Forsyth 	if(nn != Z)
9074a4d8c2SCharles.Forsyth 		gmove(n1, nn);
9174a4d8c2SCharles.Forsyth 	sh = b->type->shift;
9274a4d8c2SCharles.Forsyth 	if(sh > 0)
9374a4d8c2SCharles.Forsyth 		gopcode(OASHL, types[TLONG], nodconst(sh), &nod);
9474a4d8c2SCharles.Forsyth 	v <<= sh;
9574a4d8c2SCharles.Forsyth 	gopcode(OAND, types[TLONG], nodconst(~v), n3);
9674a4d8c2SCharles.Forsyth 	gopcode(OOR, types[TLONG], n3, &nod);
9774a4d8c2SCharles.Forsyth 	gmove(&nod, n2);
9874a4d8c2SCharles.Forsyth 
9974a4d8c2SCharles.Forsyth 	regfree(&nod);
10074a4d8c2SCharles.Forsyth 	regfree(n1);
10174a4d8c2SCharles.Forsyth 	regfree(n2);
10274a4d8c2SCharles.Forsyth 	regfree(n3);
10374a4d8c2SCharles.Forsyth }
10474a4d8c2SCharles.Forsyth 
10574a4d8c2SCharles.Forsyth long
outstring(char * s,long n)10674a4d8c2SCharles.Forsyth outstring(char *s, long n)
10774a4d8c2SCharles.Forsyth {
10874a4d8c2SCharles.Forsyth 	long r;
10974a4d8c2SCharles.Forsyth 
11074a4d8c2SCharles.Forsyth 	if(suppress)
11174a4d8c2SCharles.Forsyth 		return nstring;
11274a4d8c2SCharles.Forsyth 	r = nstring;
11374a4d8c2SCharles.Forsyth 	while(n) {
11474a4d8c2SCharles.Forsyth 		string[mnstring] = *s++;
11574a4d8c2SCharles.Forsyth 		mnstring++;
11674a4d8c2SCharles.Forsyth 		nstring++;
11774a4d8c2SCharles.Forsyth 		if(mnstring >= NSNAME) {
11874a4d8c2SCharles.Forsyth 			gpseudo(ADATA, symstring, nodconst(0L));
11974a4d8c2SCharles.Forsyth 			p->from.offset += nstring - NSNAME;
12074a4d8c2SCharles.Forsyth 			p->from.scale = NSNAME;
12174a4d8c2SCharles.Forsyth 			p->to.type = D_SCONST;
12274a4d8c2SCharles.Forsyth 			memmove(p->to.sval, string, NSNAME);
12374a4d8c2SCharles.Forsyth 			mnstring = 0;
12474a4d8c2SCharles.Forsyth 		}
12574a4d8c2SCharles.Forsyth 		n--;
12674a4d8c2SCharles.Forsyth 	}
12774a4d8c2SCharles.Forsyth 	return r;
12874a4d8c2SCharles.Forsyth }
12974a4d8c2SCharles.Forsyth 
13074a4d8c2SCharles.Forsyth void
gextern(Sym * s,Node * a,long o,long w)13174a4d8c2SCharles.Forsyth gextern(Sym *s, Node *a, long o, long w)
13274a4d8c2SCharles.Forsyth {
13374a4d8c2SCharles.Forsyth 	if(a->op == OCONST && typev[a->type->etype]) {
13474a4d8c2SCharles.Forsyth 		gpseudo(ADATA, s, lo64(a));
13574a4d8c2SCharles.Forsyth 		p->from.offset += o;
13674a4d8c2SCharles.Forsyth 		p->from.scale = 4;
13774a4d8c2SCharles.Forsyth 		gpseudo(ADATA, s, hi64(a));
13874a4d8c2SCharles.Forsyth 		p->from.offset += o + 4;
13974a4d8c2SCharles.Forsyth 		p->from.scale = 4;
14074a4d8c2SCharles.Forsyth 		return;
14174a4d8c2SCharles.Forsyth 	}
14274a4d8c2SCharles.Forsyth 	gpseudo(ADATA, s, a);
14374a4d8c2SCharles.Forsyth 	p->from.offset += o;
14474a4d8c2SCharles.Forsyth 	p->from.scale = w;
14574a4d8c2SCharles.Forsyth 	switch(p->to.type) {
14674a4d8c2SCharles.Forsyth 	default:
14774a4d8c2SCharles.Forsyth 		p->to.index = p->to.type;
14874a4d8c2SCharles.Forsyth 		p->to.type = D_ADDR;
14974a4d8c2SCharles.Forsyth 	case D_CONST:
15074a4d8c2SCharles.Forsyth 	case D_FCONST:
15174a4d8c2SCharles.Forsyth 	case D_ADDR:
15274a4d8c2SCharles.Forsyth 		break;
15374a4d8c2SCharles.Forsyth 	}
15474a4d8c2SCharles.Forsyth }
15574a4d8c2SCharles.Forsyth 
15674a4d8c2SCharles.Forsyth void	zname(Biobuf*, Sym*, int);
15774a4d8c2SCharles.Forsyth void	zaddr(Biobuf*, Adr*, int);
15874a4d8c2SCharles.Forsyth void	outhist(Biobuf*);
15974a4d8c2SCharles.Forsyth 
16074a4d8c2SCharles.Forsyth void
outcode(void)16174a4d8c2SCharles.Forsyth outcode(void)
16274a4d8c2SCharles.Forsyth {
16374a4d8c2SCharles.Forsyth 	struct { Sym *sym; short type; } h[NSYM];
16474a4d8c2SCharles.Forsyth 	Prog *p;
16574a4d8c2SCharles.Forsyth 	Sym *s;
16674a4d8c2SCharles.Forsyth 	int f, sf, st, t, sym;
16774a4d8c2SCharles.Forsyth 	Biobuf b;
16874a4d8c2SCharles.Forsyth 
16974a4d8c2SCharles.Forsyth 	if(debug['S']) {
17074a4d8c2SCharles.Forsyth 		for(p = firstp; p != P; p = p->link)
17174a4d8c2SCharles.Forsyth 			if(p->as != ADATA && p->as != AGLOBL)
17274a4d8c2SCharles.Forsyth 				pc--;
17374a4d8c2SCharles.Forsyth 		for(p = firstp; p != P; p = p->link) {
17474a4d8c2SCharles.Forsyth 			print("%P\n", p);
17574a4d8c2SCharles.Forsyth 			if(p->as != ADATA && p->as != AGLOBL)
17674a4d8c2SCharles.Forsyth 				pc++;
17774a4d8c2SCharles.Forsyth 		}
17874a4d8c2SCharles.Forsyth 	}
17974a4d8c2SCharles.Forsyth 	f = open(outfile, OWRITE);
18074a4d8c2SCharles.Forsyth 	if(f < 0) {
18174a4d8c2SCharles.Forsyth 		diag(Z, "cannot open %s", outfile);
18274a4d8c2SCharles.Forsyth 		return;
18374a4d8c2SCharles.Forsyth 	}
18474a4d8c2SCharles.Forsyth 	Binit(&b, f, OWRITE);
18574a4d8c2SCharles.Forsyth 	Bseek(&b, 0L, 2);
18674a4d8c2SCharles.Forsyth 	outhist(&b);
18774a4d8c2SCharles.Forsyth 	for(sym=0; sym<NSYM; sym++) {
18874a4d8c2SCharles.Forsyth 		h[sym].sym = S;
18974a4d8c2SCharles.Forsyth 		h[sym].type = 0;
19074a4d8c2SCharles.Forsyth 	}
19174a4d8c2SCharles.Forsyth 	sym = 1;
19274a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
19374a4d8c2SCharles.Forsyth 	jackpot:
19474a4d8c2SCharles.Forsyth 		sf = 0;
19574a4d8c2SCharles.Forsyth 		s = p->from.sym;
19674a4d8c2SCharles.Forsyth 		while(s != S) {
19774a4d8c2SCharles.Forsyth 			sf = s->sym;
19874a4d8c2SCharles.Forsyth 			if(sf < 0 || sf >= NSYM)
19974a4d8c2SCharles.Forsyth 				sf = 0;
20074a4d8c2SCharles.Forsyth 			t = p->from.type;
20174a4d8c2SCharles.Forsyth 			if(t == D_ADDR)
20274a4d8c2SCharles.Forsyth 				t = p->from.index;
20374a4d8c2SCharles.Forsyth 			if(h[sf].type == t)
20474a4d8c2SCharles.Forsyth 			if(h[sf].sym == s)
20574a4d8c2SCharles.Forsyth 				break;
20674a4d8c2SCharles.Forsyth 			s->sym = sym;
20774a4d8c2SCharles.Forsyth 			zname(&b, s, t);
20874a4d8c2SCharles.Forsyth 			h[sym].sym = s;
20974a4d8c2SCharles.Forsyth 			h[sym].type = t;
21074a4d8c2SCharles.Forsyth 			sf = sym;
21174a4d8c2SCharles.Forsyth 			sym++;
21274a4d8c2SCharles.Forsyth 			if(sym >= NSYM)
21374a4d8c2SCharles.Forsyth 				sym = 1;
21474a4d8c2SCharles.Forsyth 			break;
21574a4d8c2SCharles.Forsyth 		}
21674a4d8c2SCharles.Forsyth 		st = 0;
21774a4d8c2SCharles.Forsyth 		s = p->to.sym;
21874a4d8c2SCharles.Forsyth 		while(s != S) {
21974a4d8c2SCharles.Forsyth 			st = s->sym;
22074a4d8c2SCharles.Forsyth 			if(st < 0 || st >= NSYM)
22174a4d8c2SCharles.Forsyth 				st = 0;
22274a4d8c2SCharles.Forsyth 			t = p->to.type;
22374a4d8c2SCharles.Forsyth 			if(t == D_ADDR)
22474a4d8c2SCharles.Forsyth 				t = p->to.index;
22574a4d8c2SCharles.Forsyth 			if(h[st].type == t)
22674a4d8c2SCharles.Forsyth 			if(h[st].sym == s)
22774a4d8c2SCharles.Forsyth 				break;
22874a4d8c2SCharles.Forsyth 			s->sym = sym;
22974a4d8c2SCharles.Forsyth 			zname(&b, s, t);
23074a4d8c2SCharles.Forsyth 			h[sym].sym = s;
23174a4d8c2SCharles.Forsyth 			h[sym].type = t;
23274a4d8c2SCharles.Forsyth 			st = sym;
23374a4d8c2SCharles.Forsyth 			sym++;
23474a4d8c2SCharles.Forsyth 			if(sym >= NSYM)
23574a4d8c2SCharles.Forsyth 				sym = 1;
23674a4d8c2SCharles.Forsyth 			if(st == sf)
23774a4d8c2SCharles.Forsyth 				goto jackpot;
23874a4d8c2SCharles.Forsyth 			break;
23974a4d8c2SCharles.Forsyth 		}
24074a4d8c2SCharles.Forsyth 		Bputc(&b, p->as);
24174a4d8c2SCharles.Forsyth 		Bputc(&b, p->as>>8);
24274a4d8c2SCharles.Forsyth 		Bputc(&b, p->lineno);
24374a4d8c2SCharles.Forsyth 		Bputc(&b, p->lineno>>8);
24474a4d8c2SCharles.Forsyth 		Bputc(&b, p->lineno>>16);
24574a4d8c2SCharles.Forsyth 		Bputc(&b, p->lineno>>24);
24674a4d8c2SCharles.Forsyth 		zaddr(&b, &p->from, sf);
24774a4d8c2SCharles.Forsyth 		zaddr(&b, &p->to, st);
24874a4d8c2SCharles.Forsyth 	}
24974a4d8c2SCharles.Forsyth 	Bflush(&b);
25074a4d8c2SCharles.Forsyth 	close(f);
25174a4d8c2SCharles.Forsyth 	firstp = P;
25274a4d8c2SCharles.Forsyth 	lastp = P;
25374a4d8c2SCharles.Forsyth }
25474a4d8c2SCharles.Forsyth 
25574a4d8c2SCharles.Forsyth void
outhist(Biobuf * b)25674a4d8c2SCharles.Forsyth outhist(Biobuf *b)
25774a4d8c2SCharles.Forsyth {
25874a4d8c2SCharles.Forsyth 	Hist *h;
25974a4d8c2SCharles.Forsyth 	char *p, *q, *op, c;
26074a4d8c2SCharles.Forsyth 	Prog pg;
26174a4d8c2SCharles.Forsyth 	int n;
26274a4d8c2SCharles.Forsyth 
26374a4d8c2SCharles.Forsyth 	pg = zprog;
26474a4d8c2SCharles.Forsyth 	pg.as = AHISTORY;
26574a4d8c2SCharles.Forsyth 	c = pathchar();
26674a4d8c2SCharles.Forsyth 	for(h = hist; h != H; h = h->link) {
26774a4d8c2SCharles.Forsyth 		p = h->name;
26874a4d8c2SCharles.Forsyth 		op = 0;
26974a4d8c2SCharles.Forsyth 		/* on windows skip drive specifier in pathname */
27074a4d8c2SCharles.Forsyth 		if(systemtype(Windows) && p && p[1] == ':'){
27174a4d8c2SCharles.Forsyth 			p += 2;
27274a4d8c2SCharles.Forsyth 			c = *p;
27374a4d8c2SCharles.Forsyth 		}
27474a4d8c2SCharles.Forsyth 		if(p && p[0] != c && h->offset == 0 && pathname){
27574a4d8c2SCharles.Forsyth 			/* on windows skip drive specifier in pathname */
27674a4d8c2SCharles.Forsyth 			if(systemtype(Windows) && pathname[1] == ':') {
27774a4d8c2SCharles.Forsyth 				op = p;
27874a4d8c2SCharles.Forsyth 				p = pathname+2;
27974a4d8c2SCharles.Forsyth 				c = *p;
28074a4d8c2SCharles.Forsyth 			} else if(pathname[0] == c){
28174a4d8c2SCharles.Forsyth 				op = p;
28274a4d8c2SCharles.Forsyth 				p = pathname;
28374a4d8c2SCharles.Forsyth 			}
28474a4d8c2SCharles.Forsyth 		}
28574a4d8c2SCharles.Forsyth 		while(p) {
28674a4d8c2SCharles.Forsyth 			q = utfrune(p, c);
28774a4d8c2SCharles.Forsyth 			if(q) {
28874a4d8c2SCharles.Forsyth 				n = q-p;
28974a4d8c2SCharles.Forsyth 				if(n == 0){
29074a4d8c2SCharles.Forsyth 					n = 1;	/* leading "/" */
29174a4d8c2SCharles.Forsyth 					*p = '/';	/* don't emit "\" on windows */
29274a4d8c2SCharles.Forsyth 				}
29374a4d8c2SCharles.Forsyth 				q++;
29474a4d8c2SCharles.Forsyth 			} else {
29574a4d8c2SCharles.Forsyth 				n = strlen(p);
29674a4d8c2SCharles.Forsyth 				q = 0;
29774a4d8c2SCharles.Forsyth 			}
29874a4d8c2SCharles.Forsyth 			if(n) {
29974a4d8c2SCharles.Forsyth 				Bputc(b, ANAME);
30074a4d8c2SCharles.Forsyth 				Bputc(b, ANAME>>8);
30174a4d8c2SCharles.Forsyth 				Bputc(b, D_FILE);
30274a4d8c2SCharles.Forsyth 				Bputc(b, 1);
30374a4d8c2SCharles.Forsyth 				Bputc(b, '<');
30474a4d8c2SCharles.Forsyth 				Bwrite(b, p, n);
30574a4d8c2SCharles.Forsyth 				Bputc(b, 0);
30674a4d8c2SCharles.Forsyth 			}
30774a4d8c2SCharles.Forsyth 			p = q;
30874a4d8c2SCharles.Forsyth 			if(p == 0 && op) {
30974a4d8c2SCharles.Forsyth 				p = op;
31074a4d8c2SCharles.Forsyth 				op = 0;
31174a4d8c2SCharles.Forsyth 			}
31274a4d8c2SCharles.Forsyth 		}
31374a4d8c2SCharles.Forsyth 		pg.lineno = h->line;
31474a4d8c2SCharles.Forsyth 		pg.to.type = zprog.to.type;
31574a4d8c2SCharles.Forsyth 		pg.to.offset = h->offset;
31674a4d8c2SCharles.Forsyth 		if(h->offset)
31774a4d8c2SCharles.Forsyth 			pg.to.type = D_CONST;
31874a4d8c2SCharles.Forsyth 
31974a4d8c2SCharles.Forsyth 		Bputc(b, pg.as);
32074a4d8c2SCharles.Forsyth 		Bputc(b, pg.as>>8);
32174a4d8c2SCharles.Forsyth 		Bputc(b, pg.lineno);
32274a4d8c2SCharles.Forsyth 		Bputc(b, pg.lineno>>8);
32374a4d8c2SCharles.Forsyth 		Bputc(b, pg.lineno>>16);
32474a4d8c2SCharles.Forsyth 		Bputc(b, pg.lineno>>24);
32574a4d8c2SCharles.Forsyth 		zaddr(b, &pg.from, 0);
32674a4d8c2SCharles.Forsyth 		zaddr(b, &pg.to, 0);
32774a4d8c2SCharles.Forsyth 	}
32874a4d8c2SCharles.Forsyth }
32974a4d8c2SCharles.Forsyth 
33074a4d8c2SCharles.Forsyth void
zname(Biobuf * b,Sym * s,int t)33174a4d8c2SCharles.Forsyth zname(Biobuf *b, Sym *s, int t)
33274a4d8c2SCharles.Forsyth {
33374a4d8c2SCharles.Forsyth 	char *n;
33474a4d8c2SCharles.Forsyth 	ulong sig;
33574a4d8c2SCharles.Forsyth 
33674a4d8c2SCharles.Forsyth 	if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
33774a4d8c2SCharles.Forsyth 		sig = sign(s);
33874a4d8c2SCharles.Forsyth 		Bputc(b, ASIGNAME);
33974a4d8c2SCharles.Forsyth 		Bputc(b, ASIGNAME>>8);
34074a4d8c2SCharles.Forsyth 		Bputc(b, sig);
34174a4d8c2SCharles.Forsyth 		Bputc(b, sig>>8);
34274a4d8c2SCharles.Forsyth 		Bputc(b, sig>>16);
34374a4d8c2SCharles.Forsyth 		Bputc(b, sig>>24);
34474a4d8c2SCharles.Forsyth 		s->sig = SIGDONE;
34574a4d8c2SCharles.Forsyth 	}
34674a4d8c2SCharles.Forsyth 	else{
34774a4d8c2SCharles.Forsyth 		Bputc(b, ANAME);	/* as */
34874a4d8c2SCharles.Forsyth 		Bputc(b, ANAME>>8);	/* as */
34974a4d8c2SCharles.Forsyth 	}
35074a4d8c2SCharles.Forsyth 	Bputc(b, t);			/* type */
35174a4d8c2SCharles.Forsyth 	Bputc(b, s->sym);		/* sym */
35274a4d8c2SCharles.Forsyth 	n = s->name;
35374a4d8c2SCharles.Forsyth 	while(*n) {
35474a4d8c2SCharles.Forsyth 		Bputc(b, *n);
35574a4d8c2SCharles.Forsyth 		n++;
35674a4d8c2SCharles.Forsyth 	}
35774a4d8c2SCharles.Forsyth 	Bputc(b, 0);
35874a4d8c2SCharles.Forsyth }
35974a4d8c2SCharles.Forsyth 
36074a4d8c2SCharles.Forsyth void
zaddr(Biobuf * b,Adr * a,int s)36174a4d8c2SCharles.Forsyth zaddr(Biobuf *b, Adr *a, int s)
36274a4d8c2SCharles.Forsyth {
36374a4d8c2SCharles.Forsyth 	long l;
36474a4d8c2SCharles.Forsyth 	int i, t;
36574a4d8c2SCharles.Forsyth 	char *n;
36674a4d8c2SCharles.Forsyth 	Ieee e;
36774a4d8c2SCharles.Forsyth 
36874a4d8c2SCharles.Forsyth 	t = 0;
36974a4d8c2SCharles.Forsyth 	if(a->index != D_NONE || a->scale != 0)
37074a4d8c2SCharles.Forsyth 		t |= T_INDEX;
37174a4d8c2SCharles.Forsyth 	if(s != 0)
37274a4d8c2SCharles.Forsyth 		t |= T_SYM;
37374a4d8c2SCharles.Forsyth 
37474a4d8c2SCharles.Forsyth 	switch(a->type) {
37574a4d8c2SCharles.Forsyth 	default:
37674a4d8c2SCharles.Forsyth 		t |= T_TYPE;
37774a4d8c2SCharles.Forsyth 	case D_NONE:
37874a4d8c2SCharles.Forsyth 		if(a->offset != 0)
37974a4d8c2SCharles.Forsyth 			t |= T_OFFSET;
38074a4d8c2SCharles.Forsyth 		break;
38174a4d8c2SCharles.Forsyth 	case D_FCONST:
38274a4d8c2SCharles.Forsyth 		t |= T_FCONST;
38374a4d8c2SCharles.Forsyth 		break;
38474a4d8c2SCharles.Forsyth 	case D_SCONST:
38574a4d8c2SCharles.Forsyth 		t |= T_SCONST;
38674a4d8c2SCharles.Forsyth 		break;
38774a4d8c2SCharles.Forsyth 	}
38874a4d8c2SCharles.Forsyth 	Bputc(b, t);
38974a4d8c2SCharles.Forsyth 
39074a4d8c2SCharles.Forsyth 	if(t & T_INDEX) {	/* implies index, scale */
39174a4d8c2SCharles.Forsyth 		Bputc(b, a->index);
39274a4d8c2SCharles.Forsyth 		Bputc(b, a->scale);
39374a4d8c2SCharles.Forsyth 	}
39474a4d8c2SCharles.Forsyth 	if(t & T_OFFSET) {	/* implies offset */
39574a4d8c2SCharles.Forsyth 		l = a->offset;
39674a4d8c2SCharles.Forsyth 		Bputc(b, l);
39774a4d8c2SCharles.Forsyth 		Bputc(b, l>>8);
39874a4d8c2SCharles.Forsyth 		Bputc(b, l>>16);
39974a4d8c2SCharles.Forsyth 		Bputc(b, l>>24);
40074a4d8c2SCharles.Forsyth 	}
40174a4d8c2SCharles.Forsyth 	if(t & T_SYM)		/* implies sym */
40274a4d8c2SCharles.Forsyth 		Bputc(b, s);
40374a4d8c2SCharles.Forsyth 	if(t & T_FCONST) {
40474a4d8c2SCharles.Forsyth 		ieeedtod(&e, a->dval);
40574a4d8c2SCharles.Forsyth 		l = e.l;
40674a4d8c2SCharles.Forsyth 		Bputc(b, l);
40774a4d8c2SCharles.Forsyth 		Bputc(b, l>>8);
40874a4d8c2SCharles.Forsyth 		Bputc(b, l>>16);
40974a4d8c2SCharles.Forsyth 		Bputc(b, l>>24);
41074a4d8c2SCharles.Forsyth 		l = e.h;
41174a4d8c2SCharles.Forsyth 		Bputc(b, l);
41274a4d8c2SCharles.Forsyth 		Bputc(b, l>>8);
41374a4d8c2SCharles.Forsyth 		Bputc(b, l>>16);
41474a4d8c2SCharles.Forsyth 		Bputc(b, l>>24);
41574a4d8c2SCharles.Forsyth 		return;
41674a4d8c2SCharles.Forsyth 	}
41774a4d8c2SCharles.Forsyth 	if(t & T_SCONST) {
41874a4d8c2SCharles.Forsyth 		n = a->sval;
41974a4d8c2SCharles.Forsyth 		for(i=0; i<NSNAME; i++) {
42074a4d8c2SCharles.Forsyth 			Bputc(b, *n);
42174a4d8c2SCharles.Forsyth 			n++;
42274a4d8c2SCharles.Forsyth 		}
42374a4d8c2SCharles.Forsyth 		return;
42474a4d8c2SCharles.Forsyth 	}
42574a4d8c2SCharles.Forsyth 	if(t & T_TYPE)
42674a4d8c2SCharles.Forsyth 		Bputc(b, a->type);
42774a4d8c2SCharles.Forsyth }
42874a4d8c2SCharles.Forsyth 
42974a4d8c2SCharles.Forsyth long
align(long i,Type * t,int op)43074a4d8c2SCharles.Forsyth align(long i, Type *t, int op)
43174a4d8c2SCharles.Forsyth {
43274a4d8c2SCharles.Forsyth 	long o;
43374a4d8c2SCharles.Forsyth 	Type *v;
43474a4d8c2SCharles.Forsyth 	int w;
43574a4d8c2SCharles.Forsyth 
43674a4d8c2SCharles.Forsyth 	o = i;
43774a4d8c2SCharles.Forsyth 	w = 1;
43874a4d8c2SCharles.Forsyth 	switch(op) {
43974a4d8c2SCharles.Forsyth 	default:
44074a4d8c2SCharles.Forsyth 		diag(Z, "unknown align opcode %d", op);
44174a4d8c2SCharles.Forsyth 		break;
44274a4d8c2SCharles.Forsyth 
44374a4d8c2SCharles.Forsyth 	case Asu2:	/* padding at end of a struct */
44474a4d8c2SCharles.Forsyth 		w = SZ_LONG;
44574a4d8c2SCharles.Forsyth 		if(packflg)
44674a4d8c2SCharles.Forsyth 			w = packflg;
44774a4d8c2SCharles.Forsyth 		break;
44874a4d8c2SCharles.Forsyth 
44974a4d8c2SCharles.Forsyth 	case Ael1:	/* initial allign of struct element */
45074a4d8c2SCharles.Forsyth 		for(v=t; v->etype==TARRAY; v=v->link)
45174a4d8c2SCharles.Forsyth 			;
45274a4d8c2SCharles.Forsyth 		w = ewidth[v->etype];
45374a4d8c2SCharles.Forsyth 		if(w <= 0 || w >= SZ_LONG)
45474a4d8c2SCharles.Forsyth 			w = SZ_LONG;
45574a4d8c2SCharles.Forsyth 		if(packflg)
45674a4d8c2SCharles.Forsyth 			w = packflg;
45774a4d8c2SCharles.Forsyth 		break;
45874a4d8c2SCharles.Forsyth 
45974a4d8c2SCharles.Forsyth 	case Ael2:	/* width of a struct element */
46074a4d8c2SCharles.Forsyth 		o += t->width;
46174a4d8c2SCharles.Forsyth 		break;
46274a4d8c2SCharles.Forsyth 
46374a4d8c2SCharles.Forsyth 	case Aarg0:	/* initial passbyptr argument in arg list */
46474a4d8c2SCharles.Forsyth 		if(typesuv[t->etype]) {
46574a4d8c2SCharles.Forsyth 			o = align(o, types[TIND], Aarg1);
46674a4d8c2SCharles.Forsyth 			o = align(o, types[TIND], Aarg2);
46774a4d8c2SCharles.Forsyth 		}
46874a4d8c2SCharles.Forsyth 		break;
46974a4d8c2SCharles.Forsyth 
47074a4d8c2SCharles.Forsyth 	case Aarg1:	/* initial allign of parameter */
47174a4d8c2SCharles.Forsyth 		w = ewidth[t->etype];
47274a4d8c2SCharles.Forsyth 		if(w <= 0 || w >= SZ_LONG) {
47374a4d8c2SCharles.Forsyth 			w = SZ_LONG;
47474a4d8c2SCharles.Forsyth 			break;
47574a4d8c2SCharles.Forsyth 		}
47674a4d8c2SCharles.Forsyth 		w = 1;		/* little endian no adjustment */
47774a4d8c2SCharles.Forsyth 		break;
47874a4d8c2SCharles.Forsyth 
47974a4d8c2SCharles.Forsyth 	case Aarg2:	/* width of a parameter */
48074a4d8c2SCharles.Forsyth 		o += t->width;
48174a4d8c2SCharles.Forsyth 		w = SZ_LONG;
48274a4d8c2SCharles.Forsyth 		break;
48374a4d8c2SCharles.Forsyth 
48474a4d8c2SCharles.Forsyth 	case Aaut3:	/* total allign of automatic */
48574a4d8c2SCharles.Forsyth 		o = align(o, t, Ael1);
48674a4d8c2SCharles.Forsyth 		o = align(o, t, Ael2);
48774a4d8c2SCharles.Forsyth 		break;
48874a4d8c2SCharles.Forsyth 	}
48974a4d8c2SCharles.Forsyth 	o = round(o, w);
49074a4d8c2SCharles.Forsyth 	if(debug['A'])
49174a4d8c2SCharles.Forsyth 		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
49274a4d8c2SCharles.Forsyth 	return o;
49374a4d8c2SCharles.Forsyth }
49474a4d8c2SCharles.Forsyth 
49574a4d8c2SCharles.Forsyth long
maxround(long max,long v)49674a4d8c2SCharles.Forsyth maxround(long max, long v)
49774a4d8c2SCharles.Forsyth {
498*45a20ab7Sforsyth 	v = round(v, SZ_LONG);
49974a4d8c2SCharles.Forsyth 	if(v > max)
500*45a20ab7Sforsyth 		return v;
50174a4d8c2SCharles.Forsyth 	return max;
50274a4d8c2SCharles.Forsyth }
503