xref: /inferno-os/utils/tc/swt.c (revision 75323f4992b2b4e593bd2f548db9ac6897e894d3)
174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth int
swcmp(void * a1,void * a2)445a20ab7Sforsyth swcmp(void *a1, void *a2)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 	C1 *p1, *p2;
774a4d8c2SCharles.Forsyth 
874a4d8c2SCharles.Forsyth 	p1 = (C1*)a1;
974a4d8c2SCharles.Forsyth 	p2 = (C1*)a2;
1074a4d8c2SCharles.Forsyth 	if(p1->val < p2->val)
1174a4d8c2SCharles.Forsyth 		return -1;
1274a4d8c2SCharles.Forsyth 	return  p1->val > p2->val;
1374a4d8c2SCharles.Forsyth }
1474a4d8c2SCharles.Forsyth 
1574a4d8c2SCharles.Forsyth void
doswit(Node * n)1674a4d8c2SCharles.Forsyth doswit(Node *n)
1774a4d8c2SCharles.Forsyth {
1874a4d8c2SCharles.Forsyth 	Case *c;
1974a4d8c2SCharles.Forsyth 	C1 *q, *iq;
2074a4d8c2SCharles.Forsyth 	long def, nc, i;
2174a4d8c2SCharles.Forsyth 
2274a4d8c2SCharles.Forsyth 	def = 0;
2374a4d8c2SCharles.Forsyth 	nc = 0;
2474a4d8c2SCharles.Forsyth 	for(c = cases; c->link != C; c = c->link) {
2574a4d8c2SCharles.Forsyth 		if(c->def) {
2674a4d8c2SCharles.Forsyth 			if(def)
2774a4d8c2SCharles.Forsyth 				diag(n, "more than one default in switch");
2874a4d8c2SCharles.Forsyth 			def = c->label;
2974a4d8c2SCharles.Forsyth 			continue;
3074a4d8c2SCharles.Forsyth 		}
3174a4d8c2SCharles.Forsyth 		nc++;
3274a4d8c2SCharles.Forsyth 	}
3374a4d8c2SCharles.Forsyth 
3474a4d8c2SCharles.Forsyth 	iq = alloc(nc*sizeof(C1));
3574a4d8c2SCharles.Forsyth 	q = iq;
3674a4d8c2SCharles.Forsyth 	for(c = cases; c->link != C; c = c->link) {
3774a4d8c2SCharles.Forsyth 		if(c->def)
3874a4d8c2SCharles.Forsyth 			continue;
3974a4d8c2SCharles.Forsyth 		q->label = c->label;
4074a4d8c2SCharles.Forsyth 		q->val = c->val;
4174a4d8c2SCharles.Forsyth 		q++;
4274a4d8c2SCharles.Forsyth 	}
4374a4d8c2SCharles.Forsyth 	qsort(iq, nc, sizeof(C1), swcmp);
4474a4d8c2SCharles.Forsyth 	if(debug['W'])
4574a4d8c2SCharles.Forsyth 		for(i=0; i<nc; i++)
4674a4d8c2SCharles.Forsyth 			print("case %2ld: = %.8lux\n", i, iq[i].val);
4774a4d8c2SCharles.Forsyth 	if(def == 0)
4874a4d8c2SCharles.Forsyth 		def = breakpc;
4974a4d8c2SCharles.Forsyth 	for(i=0; i<nc-1; i++)
5074a4d8c2SCharles.Forsyth 		if(iq[i].val == iq[i+1].val)
5174a4d8c2SCharles.Forsyth 			diag(n, "duplicate cases in switch %ld", iq[i].val);
5274a4d8c2SCharles.Forsyth 	swit1(iq, nc, def, n);
5374a4d8c2SCharles.Forsyth }
5474a4d8c2SCharles.Forsyth 
5574a4d8c2SCharles.Forsyth void
swit1(C1 * q,int nc,long def,Node * n)5674a4d8c2SCharles.Forsyth swit1(C1 *q, int nc, long def, Node *n)
5774a4d8c2SCharles.Forsyth {
5874a4d8c2SCharles.Forsyth 	C1 *r;
5974a4d8c2SCharles.Forsyth 	int i;
6074a4d8c2SCharles.Forsyth 	Prog *sp;
6174a4d8c2SCharles.Forsyth 
6274a4d8c2SCharles.Forsyth 	if(nc < 5) {
6374a4d8c2SCharles.Forsyth 		for(i=0; i<nc; i++) {
6474a4d8c2SCharles.Forsyth 			if(debug['W'])
6574a4d8c2SCharles.Forsyth 				print("case = %.8lux\n", q->val);
6674a4d8c2SCharles.Forsyth 			gopcode(OEQ, nodconst(q->val), n, Z);
6774a4d8c2SCharles.Forsyth 			patch(p, q->label);
6874a4d8c2SCharles.Forsyth 			q++;
6974a4d8c2SCharles.Forsyth 		}
7074a4d8c2SCharles.Forsyth 		gbranch(OGOTO);
7174a4d8c2SCharles.Forsyth 		patch(p, def);
7274a4d8c2SCharles.Forsyth 		return;
7374a4d8c2SCharles.Forsyth 	}
7474a4d8c2SCharles.Forsyth 
7574a4d8c2SCharles.Forsyth 	i = nc / 2;
7674a4d8c2SCharles.Forsyth 	r = q+i;
7774a4d8c2SCharles.Forsyth 	if(debug['W'])
7874a4d8c2SCharles.Forsyth 		print("case > %.8lux\n", r->val);
7974a4d8c2SCharles.Forsyth 	gopcode(OGT, nodconst(r->val), n, Z);
8074a4d8c2SCharles.Forsyth 	sp = p;
8174a4d8c2SCharles.Forsyth 	gopcode(OEQ, nodconst(r->val), n, Z);	/* just gen the B.EQ */
8274a4d8c2SCharles.Forsyth 	patch(p, r->label);
8374a4d8c2SCharles.Forsyth 	swit1(q, i, def, n);
8474a4d8c2SCharles.Forsyth 
8574a4d8c2SCharles.Forsyth 	if(debug['W'])
8674a4d8c2SCharles.Forsyth 		print("case < %.8lux\n", r->val);
8774a4d8c2SCharles.Forsyth 	patch(sp, pc);
8874a4d8c2SCharles.Forsyth 	swit1(r+1, nc-i-1, def, n);
8974a4d8c2SCharles.Forsyth }
9074a4d8c2SCharles.Forsyth 
9174a4d8c2SCharles.Forsyth void
casf(void)92d67b7dadSforsyth casf(void)
9374a4d8c2SCharles.Forsyth {
9474a4d8c2SCharles.Forsyth 	Case *c;
9574a4d8c2SCharles.Forsyth 
9674a4d8c2SCharles.Forsyth 	c = alloc(sizeof(*c));
9774a4d8c2SCharles.Forsyth 	c->link = cases;
9874a4d8c2SCharles.Forsyth 	cases = c;
9974a4d8c2SCharles.Forsyth }
10074a4d8c2SCharles.Forsyth 
10174a4d8c2SCharles.Forsyth void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)10274a4d8c2SCharles.Forsyth bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
10374a4d8c2SCharles.Forsyth {
10474a4d8c2SCharles.Forsyth 	int sh;
10574a4d8c2SCharles.Forsyth 	long v;
10674a4d8c2SCharles.Forsyth 	Node *l;
10774a4d8c2SCharles.Forsyth 
10874a4d8c2SCharles.Forsyth 	/*
10974a4d8c2SCharles.Forsyth 	 * n1 gets adjusted/masked value
11074a4d8c2SCharles.Forsyth 	 * n2 gets address of cell
11174a4d8c2SCharles.Forsyth 	 * n3 gets contents of cell
11274a4d8c2SCharles.Forsyth 	 */
11374a4d8c2SCharles.Forsyth 	l = b->left;
11474a4d8c2SCharles.Forsyth 	if(n2 != Z) {
11574a4d8c2SCharles.Forsyth 		regalloc(n1, l, nn);
11674a4d8c2SCharles.Forsyth 		reglcgen(n2, l, Z);
11774a4d8c2SCharles.Forsyth 		regalloc(n3, l, Z);
11874a4d8c2SCharles.Forsyth 		gopcode(OAS, n2, Z, n3);
11974a4d8c2SCharles.Forsyth 		gopcode(OAS, n3, Z, n1);
12074a4d8c2SCharles.Forsyth 	} else {
12174a4d8c2SCharles.Forsyth 		regalloc(n1, l, nn);
12274a4d8c2SCharles.Forsyth 		cgen(l, n1);
12374a4d8c2SCharles.Forsyth 	}
12474a4d8c2SCharles.Forsyth 	if(b->type->shift == 0 && typeu[b->type->etype]) {
12574a4d8c2SCharles.Forsyth 		v = ~0 + (1L << b->type->nbits);
12674a4d8c2SCharles.Forsyth 		gopcode2(OAND, nodconst(v), Z, n1);
12774a4d8c2SCharles.Forsyth 	} else {
12874a4d8c2SCharles.Forsyth 		sh = 32 - b->type->shift - b->type->nbits;
12974a4d8c2SCharles.Forsyth 		if(sh > 0)
13074a4d8c2SCharles.Forsyth 			gopcode(OASHL, nodconst(sh), Z, n1);
13174a4d8c2SCharles.Forsyth 		sh += b->type->shift;
13274a4d8c2SCharles.Forsyth 		if(sh > 0)
13374a4d8c2SCharles.Forsyth 			if(typeu[b->type->etype])
13474a4d8c2SCharles.Forsyth 				gopcode(OLSHR, nodconst(sh), Z, n1);
13574a4d8c2SCharles.Forsyth 			else
13674a4d8c2SCharles.Forsyth 				gopcode(OASHR, nodconst(sh), Z, n1);
13774a4d8c2SCharles.Forsyth 	}
13874a4d8c2SCharles.Forsyth }
13974a4d8c2SCharles.Forsyth 
14074a4d8c2SCharles.Forsyth void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)14174a4d8c2SCharles.Forsyth bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
14274a4d8c2SCharles.Forsyth {
14374a4d8c2SCharles.Forsyth 	long v;
14474a4d8c2SCharles.Forsyth 	Node nod, *l;
14574a4d8c2SCharles.Forsyth 	int sh;
14674a4d8c2SCharles.Forsyth 
14774a4d8c2SCharles.Forsyth 	/*
14874a4d8c2SCharles.Forsyth 	 * n1 has adjusted/masked value
14974a4d8c2SCharles.Forsyth 	 * n2 has address of cell
15074a4d8c2SCharles.Forsyth 	 * n3 has contents of cell
15174a4d8c2SCharles.Forsyth 	 */
15274a4d8c2SCharles.Forsyth 	l = b->left;
15374a4d8c2SCharles.Forsyth 	regalloc(&nod, l, Z);
15474a4d8c2SCharles.Forsyth 	v = ~0 + (1L << b->type->nbits);
15574a4d8c2SCharles.Forsyth 	gopcode2(OAND, nodconst(v), Z, n1);
15674a4d8c2SCharles.Forsyth 	gopcode(OAS, n1, Z, &nod);
15774a4d8c2SCharles.Forsyth 	if(nn != Z)
15874a4d8c2SCharles.Forsyth 		gopcode(OAS, n1, Z, nn);
15974a4d8c2SCharles.Forsyth 	sh = b->type->shift;
16074a4d8c2SCharles.Forsyth 	if(sh > 0)
16174a4d8c2SCharles.Forsyth 		gopcode(OASHL, nodconst(sh), Z, &nod);
16274a4d8c2SCharles.Forsyth 	v <<= sh;
16374a4d8c2SCharles.Forsyth 	gopcode2(OAND, nodconst(~v), Z, n3);
16474a4d8c2SCharles.Forsyth 	gopcode(OOR, n3, Z, &nod);
16574a4d8c2SCharles.Forsyth 	gopcode(OAS, &nod, Z, n2);
16674a4d8c2SCharles.Forsyth 
16774a4d8c2SCharles.Forsyth 	regfree(&nod);
16874a4d8c2SCharles.Forsyth 	regfree(n1);
16974a4d8c2SCharles.Forsyth 	regfree(n2);
17074a4d8c2SCharles.Forsyth 	regfree(n3);
17174a4d8c2SCharles.Forsyth }
17274a4d8c2SCharles.Forsyth 
17374a4d8c2SCharles.Forsyth long
outstring(char * s,long n)17474a4d8c2SCharles.Forsyth outstring(char *s, long n)
17574a4d8c2SCharles.Forsyth {
17674a4d8c2SCharles.Forsyth 	long r;
17774a4d8c2SCharles.Forsyth 
17874a4d8c2SCharles.Forsyth 	if(suppress)
17974a4d8c2SCharles.Forsyth 		return nstring;
18074a4d8c2SCharles.Forsyth 	r = nstring;
18174a4d8c2SCharles.Forsyth 	while(n) {
18274a4d8c2SCharles.Forsyth 		string[mnstring] = *s++;
18374a4d8c2SCharles.Forsyth 		mnstring++;
18474a4d8c2SCharles.Forsyth 		nstring++;
18574a4d8c2SCharles.Forsyth 		if(mnstring >= NSNAME) {
18674a4d8c2SCharles.Forsyth 			gpseudo(ADATA, symstring, nodconst(0L));
18774a4d8c2SCharles.Forsyth 			p->from.offset += nstring - NSNAME;
18874a4d8c2SCharles.Forsyth 			p->reg = NSNAME;
18974a4d8c2SCharles.Forsyth 			p->to.type = D_SCONST;
19074a4d8c2SCharles.Forsyth 			memmove(p->to.sval, string, NSNAME);
19174a4d8c2SCharles.Forsyth 			mnstring = 0;
19274a4d8c2SCharles.Forsyth 		}
19374a4d8c2SCharles.Forsyth 		n--;
19474a4d8c2SCharles.Forsyth 	}
19574a4d8c2SCharles.Forsyth 	return r;
19674a4d8c2SCharles.Forsyth }
19774a4d8c2SCharles.Forsyth 
19874a4d8c2SCharles.Forsyth long
outlstring(TRune * s,long n)199*de44e51cSDavid Boddie outlstring(TRune *s, long n)
20074a4d8c2SCharles.Forsyth {
20174a4d8c2SCharles.Forsyth 	char buf[2];
20274a4d8c2SCharles.Forsyth 	int c;
20374a4d8c2SCharles.Forsyth 	long r;
20474a4d8c2SCharles.Forsyth 
20574a4d8c2SCharles.Forsyth 	if(suppress)
20674a4d8c2SCharles.Forsyth 		return nstring;
20774a4d8c2SCharles.Forsyth 	while(nstring & 1)
20874a4d8c2SCharles.Forsyth 		outstring("", 1);
20974a4d8c2SCharles.Forsyth 	r = nstring;
21074a4d8c2SCharles.Forsyth 	while(n > 0) {
21174a4d8c2SCharles.Forsyth 		c = *s++;
21274a4d8c2SCharles.Forsyth 		if(align(0, types[TCHAR], Aarg1)) {
21374a4d8c2SCharles.Forsyth 			buf[0] = c>>8;
21474a4d8c2SCharles.Forsyth 			buf[1] = c;
21574a4d8c2SCharles.Forsyth 		} else {
21674a4d8c2SCharles.Forsyth 			buf[0] = c;
21774a4d8c2SCharles.Forsyth 			buf[1] = c>>8;
21874a4d8c2SCharles.Forsyth 		}
21974a4d8c2SCharles.Forsyth 		outstring(buf, 2);
22074a4d8c2SCharles.Forsyth 		n -= sizeof(ushort);
22174a4d8c2SCharles.Forsyth 	}
22274a4d8c2SCharles.Forsyth 	return r;
22374a4d8c2SCharles.Forsyth }
22474a4d8c2SCharles.Forsyth 
22574a4d8c2SCharles.Forsyth int
mulcon(Node * n,Node * nn)22674a4d8c2SCharles.Forsyth mulcon(Node *n, Node *nn)
22774a4d8c2SCharles.Forsyth {
22874a4d8c2SCharles.Forsyth 	Node *l, *r, nod1, nod2;
22974a4d8c2SCharles.Forsyth 	Multab *m;
23074a4d8c2SCharles.Forsyth 	long v, vs;
23174a4d8c2SCharles.Forsyth 	int o;
23274a4d8c2SCharles.Forsyth 	char code[sizeof(m->code)+2], *p;
23374a4d8c2SCharles.Forsyth 
23474a4d8c2SCharles.Forsyth 	if(typefd[n->type->etype])
23574a4d8c2SCharles.Forsyth 		return 0;
23674a4d8c2SCharles.Forsyth 	l = n->left;
23774a4d8c2SCharles.Forsyth 	r = n->right;
23874a4d8c2SCharles.Forsyth 	if(l->op == OCONST) {
23974a4d8c2SCharles.Forsyth 		l = r;
24074a4d8c2SCharles.Forsyth 		r = n->left;
24174a4d8c2SCharles.Forsyth 	}
24274a4d8c2SCharles.Forsyth 	if(r->op != OCONST)
24374a4d8c2SCharles.Forsyth 		return 0;
24474a4d8c2SCharles.Forsyth 	v = convvtox(r->vconst, n->type->etype);
24574a4d8c2SCharles.Forsyth 	if(v != r->vconst) {
24674a4d8c2SCharles.Forsyth 		if(debug['M'])
24774a4d8c2SCharles.Forsyth 			print("%L multiply conv: %lld\n", n->lineno, r->vconst);
24874a4d8c2SCharles.Forsyth 		return 0;
24974a4d8c2SCharles.Forsyth 	}
25074a4d8c2SCharles.Forsyth 	m = mulcon0(v);
25174a4d8c2SCharles.Forsyth 	if(!m) {
25274a4d8c2SCharles.Forsyth 		if(debug['M'])
25374a4d8c2SCharles.Forsyth 			print("%L multiply table: %lld\n", n->lineno, r->vconst);
25474a4d8c2SCharles.Forsyth 		return 0;
25574a4d8c2SCharles.Forsyth 	}
25674a4d8c2SCharles.Forsyth 	if(debug['M'] && debug['v'])
25774a4d8c2SCharles.Forsyth 		print("%L multiply: %ld\n", n->lineno, v);
25874a4d8c2SCharles.Forsyth 
25974a4d8c2SCharles.Forsyth 	memmove(code, m->code, sizeof(m->code));
26074a4d8c2SCharles.Forsyth 	code[sizeof(m->code)] = 0;
26174a4d8c2SCharles.Forsyth 
26274a4d8c2SCharles.Forsyth 	p = code;
26374a4d8c2SCharles.Forsyth 	if(p[1] == 'i')
26474a4d8c2SCharles.Forsyth 		p += 2;
26574a4d8c2SCharles.Forsyth 	regalloc(&nod1, n, nn);
26674a4d8c2SCharles.Forsyth 	cgen(l, &nod1);
26774a4d8c2SCharles.Forsyth 	vs = v;
26874a4d8c2SCharles.Forsyth 	regalloc(&nod2, n, Z);
26974a4d8c2SCharles.Forsyth 
27074a4d8c2SCharles.Forsyth loop:
27174a4d8c2SCharles.Forsyth 	switch(*p) {
27274a4d8c2SCharles.Forsyth 	case 0:
27374a4d8c2SCharles.Forsyth 		regfree(&nod2);
27474a4d8c2SCharles.Forsyth 		if(vs < 0) {
27574a4d8c2SCharles.Forsyth 			gopcode(OAS, &nod1, Z, &nod1);
27674a4d8c2SCharles.Forsyth 			gopcode(OSUB, &nod1, nodconst(0), nn);
27774a4d8c2SCharles.Forsyth 		} else
27874a4d8c2SCharles.Forsyth 			gopcode(OAS, &nod1, Z, nn);
27974a4d8c2SCharles.Forsyth /*
28074a4d8c2SCharles.Forsyth 		if(vs < 0)
28174a4d8c2SCharles.Forsyth 			gopcode(ONEG, &nod1, Z, &nod1);
28274a4d8c2SCharles.Forsyth 		gopcode(OAS, &nod1, Z, nn);
28374a4d8c2SCharles.Forsyth */
28474a4d8c2SCharles.Forsyth 		regfree(&nod1);
28574a4d8c2SCharles.Forsyth 		return 1;
28674a4d8c2SCharles.Forsyth 	case '+':
28774a4d8c2SCharles.Forsyth 		o = OADD;
28874a4d8c2SCharles.Forsyth 		goto addsub;
28974a4d8c2SCharles.Forsyth 	case '-':
29074a4d8c2SCharles.Forsyth 		o = OSUB;
29174a4d8c2SCharles.Forsyth 	addsub:	/* number is r,n,l */
29274a4d8c2SCharles.Forsyth 		v = p[1] - '0';
29374a4d8c2SCharles.Forsyth 		r = &nod1;
29474a4d8c2SCharles.Forsyth 		if(v&4)
29574a4d8c2SCharles.Forsyth 			r = &nod2;
29674a4d8c2SCharles.Forsyth 		n = &nod1;
29774a4d8c2SCharles.Forsyth 		if(v&2)
29874a4d8c2SCharles.Forsyth 			n = &nod2;
29974a4d8c2SCharles.Forsyth 		l = &nod1;
30074a4d8c2SCharles.Forsyth 		if(v&1)
30174a4d8c2SCharles.Forsyth 			l = &nod2;
30274a4d8c2SCharles.Forsyth 		gopcode(o, l, n, r);
30374a4d8c2SCharles.Forsyth 		break;
30474a4d8c2SCharles.Forsyth 	default: /* op is shiftcount, number is r,l */
30574a4d8c2SCharles.Forsyth 		v = p[1] - '0';
30674a4d8c2SCharles.Forsyth 		r = &nod1;
30774a4d8c2SCharles.Forsyth 		if(v&2)
30874a4d8c2SCharles.Forsyth 			r = &nod2;
30974a4d8c2SCharles.Forsyth 		l = &nod1;
31074a4d8c2SCharles.Forsyth 		if(v&1)
31174a4d8c2SCharles.Forsyth 			l = &nod2;
31274a4d8c2SCharles.Forsyth 		v = *p - 'a';
31374a4d8c2SCharles.Forsyth 		if(v < 0 || v >= 32) {
31474a4d8c2SCharles.Forsyth 			diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
31574a4d8c2SCharles.Forsyth 			break;
31674a4d8c2SCharles.Forsyth 		}
31774a4d8c2SCharles.Forsyth 		gopcode(OASHL, nodconst(v), l, r);
31874a4d8c2SCharles.Forsyth 		break;
31974a4d8c2SCharles.Forsyth 	}
32074a4d8c2SCharles.Forsyth 	p += 2;
32174a4d8c2SCharles.Forsyth 	goto loop;
32274a4d8c2SCharles.Forsyth }
32374a4d8c2SCharles.Forsyth 
32474a4d8c2SCharles.Forsyth void
nullwarn(Node * l,Node * r)32574a4d8c2SCharles.Forsyth nullwarn(Node *l, Node *r)
32674a4d8c2SCharles.Forsyth {
32774a4d8c2SCharles.Forsyth 	warn(Z, "result of operation not used");
32874a4d8c2SCharles.Forsyth 	if(l != Z)
32974a4d8c2SCharles.Forsyth 		cgen(l, Z);
33074a4d8c2SCharles.Forsyth 	if(r != Z)
33174a4d8c2SCharles.Forsyth 		cgen(r, Z);
33274a4d8c2SCharles.Forsyth }
33374a4d8c2SCharles.Forsyth 
33474a4d8c2SCharles.Forsyth void
sextern(Sym * s,Node * a,long o,long w)33574a4d8c2SCharles.Forsyth sextern(Sym *s, Node *a, long o, long w)
33674a4d8c2SCharles.Forsyth {
33774a4d8c2SCharles.Forsyth 	long e, lw;
33874a4d8c2SCharles.Forsyth 
33974a4d8c2SCharles.Forsyth 	for(e=0; e<w; e+=NSNAME) {
34074a4d8c2SCharles.Forsyth 		lw = NSNAME;
34174a4d8c2SCharles.Forsyth 		if(w-e < lw)
34274a4d8c2SCharles.Forsyth 			lw = w-e;
34374a4d8c2SCharles.Forsyth 		gpseudo(ADATA, s, nodconst(0));
34474a4d8c2SCharles.Forsyth 		p->from.offset += o+e;
34574a4d8c2SCharles.Forsyth 		p->reg = lw;
34674a4d8c2SCharles.Forsyth 		p->to.type = D_SCONST;
34774a4d8c2SCharles.Forsyth 		memmove(p->to.sval, a->cstring+e, lw);
34874a4d8c2SCharles.Forsyth 	}
34974a4d8c2SCharles.Forsyth }
35074a4d8c2SCharles.Forsyth 
35174a4d8c2SCharles.Forsyth void
gextern(Sym * s,Node * a,long o,long w)35274a4d8c2SCharles.Forsyth gextern(Sym *s, Node *a, long o, long w)
35374a4d8c2SCharles.Forsyth {
35474a4d8c2SCharles.Forsyth 
35574a4d8c2SCharles.Forsyth 	if(a->op == OCONST && typev[a->type->etype]) {
35674a4d8c2SCharles.Forsyth 		gpseudo(ADATA, s, nod32const(a->vconst>>32));
35774a4d8c2SCharles.Forsyth 		p->from.offset += o;
35874a4d8c2SCharles.Forsyth 		p->reg = 4;
35974a4d8c2SCharles.Forsyth 		gpseudo(ADATA, s, nod32const(a->vconst));
36074a4d8c2SCharles.Forsyth 		p->from.offset += o + 4;
36174a4d8c2SCharles.Forsyth 		p->reg = 4;
36274a4d8c2SCharles.Forsyth 		return;
36374a4d8c2SCharles.Forsyth 	}
36474a4d8c2SCharles.Forsyth 	gpseudo(ADATA, s, a);
36574a4d8c2SCharles.Forsyth 	p->from.offset += o;
36674a4d8c2SCharles.Forsyth 	p->reg = w;
36774a4d8c2SCharles.Forsyth 	if(p->to.type == D_OREG)
36874a4d8c2SCharles.Forsyth 		p->to.type = D_CONST;
36974a4d8c2SCharles.Forsyth }
37074a4d8c2SCharles.Forsyth 
37174a4d8c2SCharles.Forsyth void	zname(Biobuf*, Sym*, int);
37274a4d8c2SCharles.Forsyth char*	zaddr(char*, Adr*, int);
37374a4d8c2SCharles.Forsyth void	zwrite(Biobuf*, Prog*, int, int);
37474a4d8c2SCharles.Forsyth void	outhist(Biobuf*);
37574a4d8c2SCharles.Forsyth 
37674a4d8c2SCharles.Forsyth void
zwrite(Biobuf * b,Prog * p,int sf,int st)37774a4d8c2SCharles.Forsyth zwrite(Biobuf *b, Prog *p, int sf, int st)
37874a4d8c2SCharles.Forsyth {
37974a4d8c2SCharles.Forsyth 	char bf[100], *bp;
38074a4d8c2SCharles.Forsyth 
38174a4d8c2SCharles.Forsyth 	bf[0] = p->as;
38274a4d8c2SCharles.Forsyth 	bf[1] = 14;
38374a4d8c2SCharles.Forsyth 	bf[2] = p->reg;
38474a4d8c2SCharles.Forsyth 	bf[3] = p->lineno;
38574a4d8c2SCharles.Forsyth 	bf[4] = p->lineno>>8;
38674a4d8c2SCharles.Forsyth 	bf[5] = p->lineno>>16;
38774a4d8c2SCharles.Forsyth 	bf[6] = p->lineno>>24;
38874a4d8c2SCharles.Forsyth 	bp = zaddr(bf+7, &p->from, sf);
38974a4d8c2SCharles.Forsyth 	bp = zaddr(bp, &p->to, st);
39074a4d8c2SCharles.Forsyth 	Bwrite(b, bf, bp-bf);
39174a4d8c2SCharles.Forsyth }
39274a4d8c2SCharles.Forsyth 
39374a4d8c2SCharles.Forsyth void
outcode(void)39474a4d8c2SCharles.Forsyth outcode(void)
39574a4d8c2SCharles.Forsyth {
39674a4d8c2SCharles.Forsyth 	struct { Sym *sym; short type; } h[NSYM];
39774a4d8c2SCharles.Forsyth 	Prog *p;
39874a4d8c2SCharles.Forsyth 	Sym *s;
39974a4d8c2SCharles.Forsyth 	int sf, st, t, sym;
40074a4d8c2SCharles.Forsyth 
40174a4d8c2SCharles.Forsyth 	if(debug['S']) {
40274a4d8c2SCharles.Forsyth 		for(p = firstp; p != P; p = p->link)
40374a4d8c2SCharles.Forsyth 			if(p->as != ADATA && p->as != AGLOBL)
40474a4d8c2SCharles.Forsyth 				pc--;
40574a4d8c2SCharles.Forsyth 		for(p = firstp; p != P; p = p->link) {
40674a4d8c2SCharles.Forsyth 			print("%P\n", p);
40774a4d8c2SCharles.Forsyth 			if(p->as != ADATA && p->as != AGLOBL)
40874a4d8c2SCharles.Forsyth 				pc++;
40974a4d8c2SCharles.Forsyth 		}
41074a4d8c2SCharles.Forsyth 	}
41174a4d8c2SCharles.Forsyth 	outhist(&outbuf);
41274a4d8c2SCharles.Forsyth 	for(sym=0; sym<NSYM; sym++) {
41374a4d8c2SCharles.Forsyth 		h[sym].sym = S;
41474a4d8c2SCharles.Forsyth 		h[sym].type = 0;
41574a4d8c2SCharles.Forsyth 	}
41674a4d8c2SCharles.Forsyth 	sym = 1;
41774a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
41874a4d8c2SCharles.Forsyth 	jackpot:
41974a4d8c2SCharles.Forsyth 		sf = 0;
42074a4d8c2SCharles.Forsyth 		s = p->from.sym;
42174a4d8c2SCharles.Forsyth 		while(s != S) {
42274a4d8c2SCharles.Forsyth 			sf = s->sym;
42374a4d8c2SCharles.Forsyth 			if(sf < 0 || sf >= NSYM)
42474a4d8c2SCharles.Forsyth 				sf = 0;
42574a4d8c2SCharles.Forsyth 			t = p->from.name;
42674a4d8c2SCharles.Forsyth 			if(h[sf].type == t)
42774a4d8c2SCharles.Forsyth 			if(h[sf].sym == s)
42874a4d8c2SCharles.Forsyth 				break;
42974a4d8c2SCharles.Forsyth 			s->sym = sym;
43074a4d8c2SCharles.Forsyth 			zname(&outbuf, s, t);
43174a4d8c2SCharles.Forsyth 			h[sym].sym = s;
43274a4d8c2SCharles.Forsyth 			h[sym].type = t;
43374a4d8c2SCharles.Forsyth 			sf = sym;
43474a4d8c2SCharles.Forsyth 			sym++;
43574a4d8c2SCharles.Forsyth 			if(sym >= NSYM)
43674a4d8c2SCharles.Forsyth 				sym = 1;
43774a4d8c2SCharles.Forsyth 			break;
43874a4d8c2SCharles.Forsyth 		}
43974a4d8c2SCharles.Forsyth 		st = 0;
44074a4d8c2SCharles.Forsyth 		s = p->to.sym;
44174a4d8c2SCharles.Forsyth 		while(s != S) {
44274a4d8c2SCharles.Forsyth 			st = s->sym;
44374a4d8c2SCharles.Forsyth 			if(st < 0 || st >= NSYM)
44474a4d8c2SCharles.Forsyth 				st = 0;
44574a4d8c2SCharles.Forsyth 			t = p->to.name;
44674a4d8c2SCharles.Forsyth 			if(h[st].type == t)
44774a4d8c2SCharles.Forsyth 			if(h[st].sym == s)
44874a4d8c2SCharles.Forsyth 				break;
44974a4d8c2SCharles.Forsyth 			s->sym = sym;
45074a4d8c2SCharles.Forsyth 			zname(&outbuf, s, t);
45174a4d8c2SCharles.Forsyth 			h[sym].sym = s;
45274a4d8c2SCharles.Forsyth 			h[sym].type = t;
45374a4d8c2SCharles.Forsyth 			st = sym;
45474a4d8c2SCharles.Forsyth 			sym++;
45574a4d8c2SCharles.Forsyth 			if(sym >= NSYM)
45674a4d8c2SCharles.Forsyth 				sym = 1;
45774a4d8c2SCharles.Forsyth 			if(st == sf)
45874a4d8c2SCharles.Forsyth 				goto jackpot;
45974a4d8c2SCharles.Forsyth 			break;
46074a4d8c2SCharles.Forsyth 		}
46174a4d8c2SCharles.Forsyth 		zwrite(&outbuf, p, sf, st);
46274a4d8c2SCharles.Forsyth 	}
46374a4d8c2SCharles.Forsyth 	firstp = P;
46474a4d8c2SCharles.Forsyth 	lastp = P;
46574a4d8c2SCharles.Forsyth }
46674a4d8c2SCharles.Forsyth 
46774a4d8c2SCharles.Forsyth void
outhist(Biobuf * b)46874a4d8c2SCharles.Forsyth outhist(Biobuf *b)
46974a4d8c2SCharles.Forsyth {
47074a4d8c2SCharles.Forsyth 	Hist *h;
47174a4d8c2SCharles.Forsyth 	char *p, *q, *op, c;
47274a4d8c2SCharles.Forsyth 	Prog pg;
47374a4d8c2SCharles.Forsyth 	int n;
47474a4d8c2SCharles.Forsyth 
47574a4d8c2SCharles.Forsyth 	pg = zprog;
47674a4d8c2SCharles.Forsyth 	pg.as = AHISTORY;
47774a4d8c2SCharles.Forsyth 	c = pathchar();
47874a4d8c2SCharles.Forsyth 	for(h = hist; h != H; h = h->link) {
47974a4d8c2SCharles.Forsyth 		p = h->name;
48074a4d8c2SCharles.Forsyth 		op = 0;
48174a4d8c2SCharles.Forsyth 		/* on windows skip drive specifier in pathname */
48274a4d8c2SCharles.Forsyth 		if(systemtype(Windows) && p && p[1] == ':'){
48374a4d8c2SCharles.Forsyth 			p += 2;
48474a4d8c2SCharles.Forsyth 			c = *p;
48574a4d8c2SCharles.Forsyth 		}
48674a4d8c2SCharles.Forsyth 		if(p && p[0] != c && h->offset == 0 && pathname){
48774a4d8c2SCharles.Forsyth 			/* on windows skip drive specifier in pathname */
48874a4d8c2SCharles.Forsyth 			if(systemtype(Windows) && pathname[1] == ':') {
48974a4d8c2SCharles.Forsyth 				op = p;
49074a4d8c2SCharles.Forsyth 				p = pathname+2;
49174a4d8c2SCharles.Forsyth 				c = *p;
49274a4d8c2SCharles.Forsyth 			} else if(pathname[0] == c){
49374a4d8c2SCharles.Forsyth 				op = p;
49474a4d8c2SCharles.Forsyth 				p = pathname;
49574a4d8c2SCharles.Forsyth 			}
49674a4d8c2SCharles.Forsyth 		}
49774a4d8c2SCharles.Forsyth 		while(p) {
49874a4d8c2SCharles.Forsyth 			q = utfrune(p, c);
49974a4d8c2SCharles.Forsyth 			if(q) {
50074a4d8c2SCharles.Forsyth 				n = q-p;
50174a4d8c2SCharles.Forsyth 				if(n == 0){
50274a4d8c2SCharles.Forsyth 					n = 1;	/* leading "/" */
50374a4d8c2SCharles.Forsyth 					*p = '/';	/* don't emit "\" on windows */
50474a4d8c2SCharles.Forsyth 				}
50574a4d8c2SCharles.Forsyth 				q++;
50674a4d8c2SCharles.Forsyth 			} else {
50774a4d8c2SCharles.Forsyth 				n = strlen(p);
50874a4d8c2SCharles.Forsyth 				q = 0;
50974a4d8c2SCharles.Forsyth 			}
51074a4d8c2SCharles.Forsyth 			if(n) {
51174a4d8c2SCharles.Forsyth 				Bputc(b, ANAME);
51274a4d8c2SCharles.Forsyth 				Bputc(b, D_FILE);
51374a4d8c2SCharles.Forsyth 				Bputc(b, 1);
51474a4d8c2SCharles.Forsyth 				Bputc(b, '<');
51574a4d8c2SCharles.Forsyth 				Bwrite(b, p, n);
51674a4d8c2SCharles.Forsyth 				Bputc(b, 0);
51774a4d8c2SCharles.Forsyth 			}
51874a4d8c2SCharles.Forsyth 			p = q;
51974a4d8c2SCharles.Forsyth 			if(p == 0 && op) {
52074a4d8c2SCharles.Forsyth 				p = op;
52174a4d8c2SCharles.Forsyth 				op = 0;
52274a4d8c2SCharles.Forsyth 			}
52374a4d8c2SCharles.Forsyth 		}
52474a4d8c2SCharles.Forsyth 		pg.lineno = h->line;
52574a4d8c2SCharles.Forsyth 		pg.to.type = zprog.to.type;
52674a4d8c2SCharles.Forsyth 		pg.to.offset = h->offset;
52774a4d8c2SCharles.Forsyth 		if(h->offset)
52874a4d8c2SCharles.Forsyth 			pg.to.type = D_CONST;
52974a4d8c2SCharles.Forsyth 
53074a4d8c2SCharles.Forsyth 		zwrite(b, &pg, 0, 0);
53174a4d8c2SCharles.Forsyth 	}
53274a4d8c2SCharles.Forsyth }
53374a4d8c2SCharles.Forsyth 
53474a4d8c2SCharles.Forsyth void
zname(Biobuf * b,Sym * s,int t)53574a4d8c2SCharles.Forsyth zname(Biobuf *b, Sym *s, int t)
53674a4d8c2SCharles.Forsyth {
53774a4d8c2SCharles.Forsyth 	char *n, bf[7];
53874a4d8c2SCharles.Forsyth 	ulong sig;
53974a4d8c2SCharles.Forsyth 
54074a4d8c2SCharles.Forsyth 	n = s->name;
54174a4d8c2SCharles.Forsyth 	if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
54274a4d8c2SCharles.Forsyth 		sig = sign(s);
54374a4d8c2SCharles.Forsyth 		bf[0] = ASIGNAME;
54474a4d8c2SCharles.Forsyth 		bf[1] = sig;
54574a4d8c2SCharles.Forsyth 		bf[2] = sig>>8;
54674a4d8c2SCharles.Forsyth 		bf[3] = sig>>16;
54774a4d8c2SCharles.Forsyth 		bf[4] = sig>>24;
54874a4d8c2SCharles.Forsyth 		bf[5] = t;
54974a4d8c2SCharles.Forsyth 		bf[6] = s->sym;
55074a4d8c2SCharles.Forsyth 		Bwrite(b, bf, 7);
55174a4d8c2SCharles.Forsyth 		s->sig = SIGDONE;
55274a4d8c2SCharles.Forsyth 	}
55374a4d8c2SCharles.Forsyth 	else{
55474a4d8c2SCharles.Forsyth 		bf[0] = ANAME;
55574a4d8c2SCharles.Forsyth 		bf[1] = t;	/* type */
55674a4d8c2SCharles.Forsyth 		bf[2] = s->sym;	/* sym */
55774a4d8c2SCharles.Forsyth 		Bwrite(b, bf, 3);
55874a4d8c2SCharles.Forsyth 	}
55974a4d8c2SCharles.Forsyth 	Bwrite(b, n, strlen(n)+1);
56074a4d8c2SCharles.Forsyth }
56174a4d8c2SCharles.Forsyth 
56274a4d8c2SCharles.Forsyth char*
zaddr(char * bp,Adr * a,int s)56374a4d8c2SCharles.Forsyth zaddr(char *bp, Adr *a, int s)
56474a4d8c2SCharles.Forsyth {
56574a4d8c2SCharles.Forsyth 	long l;
56674a4d8c2SCharles.Forsyth 	Ieee e;
56774a4d8c2SCharles.Forsyth 
56874a4d8c2SCharles.Forsyth 	bp[0] = a->type;
56974a4d8c2SCharles.Forsyth 	bp[1] = a->reg;
57074a4d8c2SCharles.Forsyth 	bp[2] = s;
57174a4d8c2SCharles.Forsyth 	bp[3] = a->name;
57274a4d8c2SCharles.Forsyth 	bp += 4;
57374a4d8c2SCharles.Forsyth 	switch(a->type) {
57474a4d8c2SCharles.Forsyth 	default:
57574a4d8c2SCharles.Forsyth 		diag(Z, "unknown type %d in zaddr", a->type);
57674a4d8c2SCharles.Forsyth 
57774a4d8c2SCharles.Forsyth 	case D_NONE:
57874a4d8c2SCharles.Forsyth 	case D_REG:
57974a4d8c2SCharles.Forsyth 	case D_FREG:
58074a4d8c2SCharles.Forsyth 	case D_PSR:
58174a4d8c2SCharles.Forsyth 		break;
58274a4d8c2SCharles.Forsyth 
58374a4d8c2SCharles.Forsyth 	case D_OREG:
58474a4d8c2SCharles.Forsyth 	case D_CONST:
58574a4d8c2SCharles.Forsyth 	case D_BRANCH:
58674a4d8c2SCharles.Forsyth 		l = a->offset;
58774a4d8c2SCharles.Forsyth 		bp[0] = l;
58874a4d8c2SCharles.Forsyth 		bp[1] = l>>8;
58974a4d8c2SCharles.Forsyth 		bp[2] = l>>16;
59074a4d8c2SCharles.Forsyth 		bp[3] = l>>24;
59174a4d8c2SCharles.Forsyth 		bp += 4;
59274a4d8c2SCharles.Forsyth 		break;
59374a4d8c2SCharles.Forsyth 
59474a4d8c2SCharles.Forsyth 	case D_SCONST:
59574a4d8c2SCharles.Forsyth 		memmove(bp, a->sval, NSNAME);
59674a4d8c2SCharles.Forsyth 		bp += NSNAME;
59774a4d8c2SCharles.Forsyth 		break;
59874a4d8c2SCharles.Forsyth 
59974a4d8c2SCharles.Forsyth 	case D_FCONST:
60074a4d8c2SCharles.Forsyth 		ieeedtod(&e, a->dval);
60174a4d8c2SCharles.Forsyth 		l = e.l;
60274a4d8c2SCharles.Forsyth 		bp[0] = l;
60374a4d8c2SCharles.Forsyth 		bp[1] = l>>8;
60474a4d8c2SCharles.Forsyth 		bp[2] = l>>16;
60574a4d8c2SCharles.Forsyth 		bp[3] = l>>24;
60674a4d8c2SCharles.Forsyth 		bp += 4;
60774a4d8c2SCharles.Forsyth 		l = e.h;
60874a4d8c2SCharles.Forsyth 		bp[0] = l;
60974a4d8c2SCharles.Forsyth 		bp[1] = l>>8;
61074a4d8c2SCharles.Forsyth 		bp[2] = l>>16;
61174a4d8c2SCharles.Forsyth 		bp[3] = l>>24;
61274a4d8c2SCharles.Forsyth 		bp += 4;
61374a4d8c2SCharles.Forsyth 		break;
61474a4d8c2SCharles.Forsyth 	}
61574a4d8c2SCharles.Forsyth 	return bp;
61674a4d8c2SCharles.Forsyth }
61774a4d8c2SCharles.Forsyth 
61874a4d8c2SCharles.Forsyth void
ieeedtod(Ieee * ieee,double native)61974a4d8c2SCharles.Forsyth ieeedtod(Ieee *ieee, double native)
62074a4d8c2SCharles.Forsyth {
62174a4d8c2SCharles.Forsyth 	double fr, ho, f;
62274a4d8c2SCharles.Forsyth 	int exp;
62374a4d8c2SCharles.Forsyth 
62474a4d8c2SCharles.Forsyth 	if(native < 0) {
62574a4d8c2SCharles.Forsyth 		ieeedtod(ieee, -native);
62674a4d8c2SCharles.Forsyth 		ieee->h |= 0x80000000L;
62774a4d8c2SCharles.Forsyth 		return;
62874a4d8c2SCharles.Forsyth 	}
62974a4d8c2SCharles.Forsyth 	if(native == 0) {
63074a4d8c2SCharles.Forsyth 		ieee->l = 0;
63174a4d8c2SCharles.Forsyth 		ieee->h = 0;
63274a4d8c2SCharles.Forsyth 		return;
63374a4d8c2SCharles.Forsyth 	}
63474a4d8c2SCharles.Forsyth 	fr = frexp(native, &exp);
63574a4d8c2SCharles.Forsyth 	f = 2097152L;		/* shouldnt use fp constants here */
63674a4d8c2SCharles.Forsyth 	fr = modf(fr*f, &ho);
63774a4d8c2SCharles.Forsyth 	ieee->h = ho;
63874a4d8c2SCharles.Forsyth 	ieee->h &= 0xfffffL;
63974a4d8c2SCharles.Forsyth 	ieee->h |= (exp+1022L) << 20;
64074a4d8c2SCharles.Forsyth 	f = 65536L;
64174a4d8c2SCharles.Forsyth 	fr = modf(fr*f, &ho);
64274a4d8c2SCharles.Forsyth 	ieee->l = ho;
64374a4d8c2SCharles.Forsyth 	ieee->l <<= 16;
64474a4d8c2SCharles.Forsyth 	ieee->l |= (long)(fr*f);
64574a4d8c2SCharles.Forsyth }
64674a4d8c2SCharles.Forsyth 
64774a4d8c2SCharles.Forsyth long
align(long i,Type * t,int op)64874a4d8c2SCharles.Forsyth align(long i, Type *t, int op)
64974a4d8c2SCharles.Forsyth {
65074a4d8c2SCharles.Forsyth 	long o;
65174a4d8c2SCharles.Forsyth 	Type *v;
65274a4d8c2SCharles.Forsyth 	int w;
65374a4d8c2SCharles.Forsyth 
65474a4d8c2SCharles.Forsyth 	o = i;
65574a4d8c2SCharles.Forsyth 	w = 1;
65674a4d8c2SCharles.Forsyth 	switch(op) {
65774a4d8c2SCharles.Forsyth 	default:
65874a4d8c2SCharles.Forsyth 		diag(Z, "unknown align opcode %d", op);
65974a4d8c2SCharles.Forsyth 		break;
66074a4d8c2SCharles.Forsyth 
66174a4d8c2SCharles.Forsyth 	case Asu2:	/* padding at end of a struct */
66274a4d8c2SCharles.Forsyth 		w = SZ_LONG;
66374a4d8c2SCharles.Forsyth 		break;
66474a4d8c2SCharles.Forsyth 
66574a4d8c2SCharles.Forsyth 	case Ael1:	/* initial allign of struct element */
66674a4d8c2SCharles.Forsyth 		for(v=t; v->etype==TARRAY; v=v->link)
66774a4d8c2SCharles.Forsyth 			;
66874a4d8c2SCharles.Forsyth 		w = ewidth[v->etype];
66974a4d8c2SCharles.Forsyth 		if(w <= 0 || w >= SZ_LONG)
67074a4d8c2SCharles.Forsyth 			w = SZ_LONG;
67174a4d8c2SCharles.Forsyth 		break;
67274a4d8c2SCharles.Forsyth 
67374a4d8c2SCharles.Forsyth 	case Ael2:	/* width of a struct element */
67474a4d8c2SCharles.Forsyth 		o += t->width;
67574a4d8c2SCharles.Forsyth 		break;
67674a4d8c2SCharles.Forsyth 
67774a4d8c2SCharles.Forsyth 	case Aarg0:	/* initial passbyptr argument in arg list */
67874a4d8c2SCharles.Forsyth 		if(typesuv[t->etype]) {
67974a4d8c2SCharles.Forsyth 			o = align(o, types[TIND], Aarg1);
68074a4d8c2SCharles.Forsyth 			o = align(o, types[TIND], Aarg2);
68174a4d8c2SCharles.Forsyth 		}
68274a4d8c2SCharles.Forsyth 		break;
68374a4d8c2SCharles.Forsyth 
68474a4d8c2SCharles.Forsyth 	case Aarg1:	/* initial allign of parameter */
68574a4d8c2SCharles.Forsyth 		w = ewidth[t->etype];
68674a4d8c2SCharles.Forsyth 		if(w <= 0 || w >= SZ_LONG) {
68774a4d8c2SCharles.Forsyth 			w = SZ_LONG;
68874a4d8c2SCharles.Forsyth 			break;
68974a4d8c2SCharles.Forsyth 		}
69074a4d8c2SCharles.Forsyth 		w = 1;		/* little endian no adjustment */
69174a4d8c2SCharles.Forsyth 		break;
69274a4d8c2SCharles.Forsyth 
69374a4d8c2SCharles.Forsyth 	case Aarg2:	/* width of a parameter */
69474a4d8c2SCharles.Forsyth 		o += t->width;
69574a4d8c2SCharles.Forsyth 		w = SZ_LONG;
69674a4d8c2SCharles.Forsyth 		break;
69774a4d8c2SCharles.Forsyth 
69874a4d8c2SCharles.Forsyth 	case Aaut3:	/* total allign of automatic */
69974a4d8c2SCharles.Forsyth 		o = align(o, t, Ael2);
70074a4d8c2SCharles.Forsyth 		o = align(o, t, Ael1);
70174a4d8c2SCharles.Forsyth 		w = SZ_LONG;	/* because of a pun in cc/dcl.c:contig() */
70274a4d8c2SCharles.Forsyth 		break;
70374a4d8c2SCharles.Forsyth 	}
70474a4d8c2SCharles.Forsyth 	o = round(o, w);
70574a4d8c2SCharles.Forsyth 	if(debug['A'])
70674a4d8c2SCharles.Forsyth 		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
70774a4d8c2SCharles.Forsyth 	return o;
70874a4d8c2SCharles.Forsyth }
70974a4d8c2SCharles.Forsyth 
71074a4d8c2SCharles.Forsyth long
maxround(long max,long v)71174a4d8c2SCharles.Forsyth maxround(long max, long v)
71274a4d8c2SCharles.Forsyth {
71374a4d8c2SCharles.Forsyth 	v = round(v, SZ_LONG);
71474a4d8c2SCharles.Forsyth 	if(v > max)
71574a4d8c2SCharles.Forsyth 		return v;
71674a4d8c2SCharles.Forsyth 	return max;
71774a4d8c2SCharles.Forsyth }
718