xref: /plan9-contrib/sys/src/cmd/8c/swt.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier int
43e12c5d1SDavid du Colombier swcmp(void *a1, void *a2)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	C1 *p1, *p2;
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier 	p1 = a1;
93e12c5d1SDavid du Colombier 	p2 = a2;
103e12c5d1SDavid du Colombier 	if(p1->val < p2->val)
113e12c5d1SDavid du Colombier 		return -1;
123e12c5d1SDavid du Colombier 	return  p1->val > p2->val;
133e12c5d1SDavid du Colombier }
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier void
163e12c5d1SDavid du Colombier doswit(Node *n)
173e12c5d1SDavid du Colombier {
183e12c5d1SDavid du Colombier 	Case *c;
193e12c5d1SDavid du Colombier 	C1 *q, *iq;
203e12c5d1SDavid du Colombier 	long def, nc, i;
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier 	def = 0;
233e12c5d1SDavid du Colombier 	nc = 0;
243e12c5d1SDavid du Colombier 	for(c = cases; c->link != C; c = c->link) {
253e12c5d1SDavid du Colombier 		if(c->def) {
263e12c5d1SDavid du Colombier 			if(def)
273e12c5d1SDavid du Colombier 				diag(n, "more than one default in switch");
283e12c5d1SDavid du Colombier 			def = c->label;
293e12c5d1SDavid du Colombier 			continue;
303e12c5d1SDavid du Colombier 		}
313e12c5d1SDavid du Colombier 		nc++;
323e12c5d1SDavid du Colombier 	}
333e12c5d1SDavid du Colombier 
343e12c5d1SDavid du Colombier 	i = nc*sizeof(C1);
353e12c5d1SDavid du Colombier 	while(nhunk < i)
363e12c5d1SDavid du Colombier 		gethunk();
373e12c5d1SDavid du Colombier 	iq = (C1*)hunk;
383e12c5d1SDavid du Colombier 	nhunk -= i;
393e12c5d1SDavid du Colombier 	hunk += i;
403e12c5d1SDavid du Colombier 
413e12c5d1SDavid du Colombier 	q = iq;
423e12c5d1SDavid du Colombier 	for(c = cases; c->link != C; c = c->link) {
433e12c5d1SDavid du Colombier 		if(c->def)
443e12c5d1SDavid du Colombier 			continue;
453e12c5d1SDavid du Colombier 		q->label = c->label;
463e12c5d1SDavid du Colombier 		q->val = c->val;
473e12c5d1SDavid du Colombier 		q++;
483e12c5d1SDavid du Colombier 	}
493e12c5d1SDavid du Colombier 	qsort(iq, nc, sizeof(C1), swcmp);
503e12c5d1SDavid du Colombier 	if(debug['W'])
513e12c5d1SDavid du Colombier 	for(i=0; i<nc; i++)
523e12c5d1SDavid du Colombier 		print("case %2d: = %.8lux\n", i, iq[i].val);
533e12c5d1SDavid du Colombier 	if(def == 0)
543e12c5d1SDavid du Colombier 		def = breakpc;
553e12c5d1SDavid du Colombier 	for(i=0; i<nc-1; i++)
563e12c5d1SDavid du Colombier 		if(iq[i].val == iq[i+1].val)
573e12c5d1SDavid du Colombier 			diag(n, "duplicate cases in switch %ld", iq[i].val);
583e12c5d1SDavid du Colombier 	swit1(iq, nc, def, n);
593e12c5d1SDavid du Colombier }
603e12c5d1SDavid du Colombier 
613e12c5d1SDavid du Colombier void
623e12c5d1SDavid du Colombier swit1(C1 *q, int nc, long def, Node *n)
633e12c5d1SDavid du Colombier {
643e12c5d1SDavid du Colombier 	C1 *r;
653e12c5d1SDavid du Colombier 	int i;
663e12c5d1SDavid du Colombier 	Prog *sp;
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier 	if(nc < 5) {
693e12c5d1SDavid du Colombier 		for(i=0; i<nc; i++) {
703e12c5d1SDavid du Colombier 			if(debug['W'])
713e12c5d1SDavid du Colombier 				print("case = %.8lux\n", q->val);
723e12c5d1SDavid du Colombier 			gopcode(OEQ, n->type, n, nodconst(q->val));
733e12c5d1SDavid du Colombier 			patch(p, q->label);
743e12c5d1SDavid du Colombier 			q++;
753e12c5d1SDavid du Colombier 		}
763e12c5d1SDavid du Colombier 		gbranch(OGOTO);
773e12c5d1SDavid du Colombier 		patch(p, def);
783e12c5d1SDavid du Colombier 		return;
793e12c5d1SDavid du Colombier 	}
803e12c5d1SDavid du Colombier 	i = nc / 2;
813e12c5d1SDavid du Colombier 	r = q+i;
823e12c5d1SDavid du Colombier 	if(debug['W'])
833e12c5d1SDavid du Colombier 		print("case > %.8lux\n", r->val);
843e12c5d1SDavid du Colombier 	gopcode(OGT, n->type, n, nodconst(r->val));
853e12c5d1SDavid du Colombier 	sp = p;
863e12c5d1SDavid du Colombier 	gbranch(OGOTO);
873e12c5d1SDavid du Colombier 	p->as = AJEQ;
883e12c5d1SDavid du Colombier 	patch(p, r->label);
893e12c5d1SDavid du Colombier 	swit1(q, i, def, n);
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier 	if(debug['W'])
923e12c5d1SDavid du Colombier 		print("case < %.8lux\n", r->val);
933e12c5d1SDavid du Colombier 	patch(sp, pc);
943e12c5d1SDavid du Colombier 	swit1(r+1, nc-i-1, def, n);
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier 
973e12c5d1SDavid du Colombier void
983e12c5d1SDavid du Colombier cas(void)
993e12c5d1SDavid du Colombier {
1003e12c5d1SDavid du Colombier 	Case *c;
1013e12c5d1SDavid du Colombier 
1023e12c5d1SDavid du Colombier 	ALLOC(c, Case);
1033e12c5d1SDavid du Colombier 	c->link = cases;
1043e12c5d1SDavid du Colombier 	cases = c;
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier 
1073e12c5d1SDavid du Colombier void
1083e12c5d1SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
1093e12c5d1SDavid du Colombier {
1103e12c5d1SDavid du Colombier 	int sh;
1113e12c5d1SDavid du Colombier 	long v;
1123e12c5d1SDavid du Colombier 	Node *l;
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 	/*
1153e12c5d1SDavid du Colombier 	 * n1 gets adjusted/masked value
1163e12c5d1SDavid du Colombier 	 * n2 gets address of cell
1173e12c5d1SDavid du Colombier 	 * n3 gets contents of cell
1183e12c5d1SDavid du Colombier 	 */
1193e12c5d1SDavid du Colombier 	l = b->left;
1203e12c5d1SDavid du Colombier 	if(n2 != Z) {
1213e12c5d1SDavid du Colombier 		regalloc(n1, l, nn);
1223e12c5d1SDavid du Colombier 		reglcgen(n2, l, Z);
1233e12c5d1SDavid du Colombier 		regalloc(n3, l, Z);
1243e12c5d1SDavid du Colombier 		gmove(n2, n3);
1253e12c5d1SDavid du Colombier 		gmove(n3, n1);
1263e12c5d1SDavid du Colombier 	} else {
1273e12c5d1SDavid du Colombier 		regalloc(n1, l, nn);
1283e12c5d1SDavid du Colombier 		cgen(l, n1);
1293e12c5d1SDavid du Colombier 	}
1303e12c5d1SDavid du Colombier 	if(b->type->shift == 0 && typeu[b->type->etype]) {
1313e12c5d1SDavid du Colombier 		v = ~0 + (1L << b->type->nbits);
1323e12c5d1SDavid du Colombier 		gopcode(OAND, types[TLONG], nodconst(v), n1);
1333e12c5d1SDavid du Colombier 	} else {
1343e12c5d1SDavid du Colombier 		sh = 32 - b->type->shift - b->type->nbits;
1353e12c5d1SDavid du Colombier 		if(sh > 0)
1363e12c5d1SDavid du Colombier 			gopcode(OASHL, types[TLONG], nodconst(sh), n1);
1373e12c5d1SDavid du Colombier 		sh += b->type->shift;
1383e12c5d1SDavid du Colombier 		if(sh > 0)
1393e12c5d1SDavid du Colombier 			if(typeu[b->type->etype])
1403e12c5d1SDavid du Colombier 				gopcode(OLSHR, types[TLONG], nodconst(sh), n1);
1413e12c5d1SDavid du Colombier 			else
1423e12c5d1SDavid du Colombier 				gopcode(OASHR, types[TLONG], nodconst(sh), n1);
1433e12c5d1SDavid du Colombier 	}
1443e12c5d1SDavid du Colombier }
1453e12c5d1SDavid du Colombier 
1463e12c5d1SDavid du Colombier void
1473e12c5d1SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
1483e12c5d1SDavid du Colombier {
1493e12c5d1SDavid du Colombier 	long v;
1503e12c5d1SDavid du Colombier 	Node nod;
1513e12c5d1SDavid du Colombier 	int sh;
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier 	regalloc(&nod, b->left, Z);
1543e12c5d1SDavid du Colombier 	v = ~0 + (1L << b->type->nbits);
1553e12c5d1SDavid du Colombier 	gopcode(OAND, types[TLONG], nodconst(v), n1);
1563e12c5d1SDavid du Colombier 	gmove(n1, &nod);
1573e12c5d1SDavid du Colombier 	if(nn != Z)
1583e12c5d1SDavid du Colombier 		gmove(n1, nn);
1593e12c5d1SDavid du Colombier 	sh = b->type->shift;
1603e12c5d1SDavid du Colombier 	if(sh > 0)
1613e12c5d1SDavid du Colombier 		gopcode(OASHL, types[TLONG], nodconst(sh), &nod);
1623e12c5d1SDavid du Colombier 	v <<= sh;
1633e12c5d1SDavid du Colombier 	gopcode(OAND, types[TLONG], nodconst(~v), n3);
1643e12c5d1SDavid du Colombier 	gopcode(OOR, types[TLONG], n3, &nod);
1653e12c5d1SDavid du Colombier 	gmove(&nod, n2);
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier 	regfree(&nod);
1683e12c5d1SDavid du Colombier 	regfree(n1);
1693e12c5d1SDavid du Colombier 	regfree(n2);
1703e12c5d1SDavid du Colombier 	regfree(n3);
1713e12c5d1SDavid du Colombier }
1723e12c5d1SDavid du Colombier 
1733e12c5d1SDavid du Colombier long
1743e12c5d1SDavid du Colombier outstring(char *s, long n)
1753e12c5d1SDavid du Colombier {
1763e12c5d1SDavid du Colombier 	long r;
1773e12c5d1SDavid du Colombier 
1783e12c5d1SDavid du Colombier 	r = nstring;
1793e12c5d1SDavid du Colombier 	while(n) {
1803e12c5d1SDavid du Colombier 		string[mnstring] = *s++;
1813e12c5d1SDavid du Colombier 		mnstring++;
1823e12c5d1SDavid du Colombier 		nstring++;
1833e12c5d1SDavid du Colombier 		if(mnstring >= NSNAME) {
1843e12c5d1SDavid du Colombier 			gpseudo(ADATA, symstring, nodconst(0L));
1853e12c5d1SDavid du Colombier 			p->from.offset += nstring - NSNAME;
1863e12c5d1SDavid du Colombier 			p->from.scale = NSNAME;
1873e12c5d1SDavid du Colombier 			p->to.type = D_SCONST;
1883e12c5d1SDavid du Colombier 			memmove(p->to.sval, string, NSNAME);
1893e12c5d1SDavid du Colombier 			mnstring = 0;
1903e12c5d1SDavid du Colombier 		}
1913e12c5d1SDavid du Colombier 		n--;
1923e12c5d1SDavid du Colombier 	}
1933e12c5d1SDavid du Colombier 	return r;
1943e12c5d1SDavid du Colombier }
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier long
1973e12c5d1SDavid du Colombier outlstring(ushort *s, long n)
1983e12c5d1SDavid du Colombier {
1993e12c5d1SDavid du Colombier 	char buf[2];
2003e12c5d1SDavid du Colombier 	int c;
2013e12c5d1SDavid du Colombier 	long r;
2023e12c5d1SDavid du Colombier 
2033e12c5d1SDavid du Colombier 	while(nstring & 1)
2043e12c5d1SDavid du Colombier 		outstring("", 1);
2053e12c5d1SDavid du Colombier 	r = nstring;
2063e12c5d1SDavid du Colombier 	while(n > 0) {
2073e12c5d1SDavid du Colombier 		c = *s++;
2083e12c5d1SDavid du Colombier 		if(endian(0)) {
2093e12c5d1SDavid du Colombier 			buf[0] = c>>8;
2103e12c5d1SDavid du Colombier 			buf[1] = c;
2113e12c5d1SDavid du Colombier 		} else {
2123e12c5d1SDavid du Colombier 			buf[0] = c;
2133e12c5d1SDavid du Colombier 			buf[1] = c>>8;
2143e12c5d1SDavid du Colombier 		}
2153e12c5d1SDavid du Colombier 		outstring(buf, 2);
2163e12c5d1SDavid du Colombier 		n -= sizeof(ushort);
2173e12c5d1SDavid du Colombier 	}
2183e12c5d1SDavid du Colombier 	return r;
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier int
2223e12c5d1SDavid du Colombier vlog(Node *n)
2233e12c5d1SDavid du Colombier {
224*219b2ee8SDavid du Colombier 
225*219b2ee8SDavid du Colombier 	int s, i;
226*219b2ee8SDavid du Colombier 	ulong m, v;
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 	if(n->op != OCONST)
2293e12c5d1SDavid du Colombier 		goto bad;
2303e12c5d1SDavid du Colombier 	if(!typechlp[n->type->etype])
2313e12c5d1SDavid du Colombier 		goto bad;
232*219b2ee8SDavid du Colombier 
233*219b2ee8SDavid du Colombier 	v = n->vconst;
234*219b2ee8SDavid du Colombier 
235*219b2ee8SDavid du Colombier 	s = 0;
236*219b2ee8SDavid du Colombier 	m = MASK(64);
237*219b2ee8SDavid du Colombier 	for(i=32; i; i>>=1) {
238*219b2ee8SDavid du Colombier 		m >>= i;
239*219b2ee8SDavid du Colombier 		if(!(v & m)) {
240*219b2ee8SDavid du Colombier 			v >>= i;
241*219b2ee8SDavid du Colombier 			s += i;
2423e12c5d1SDavid du Colombier 		}
2433e12c5d1SDavid du Colombier 	}
244*219b2ee8SDavid du Colombier 	if(v == 1)
245*219b2ee8SDavid du Colombier 		return s;
2463e12c5d1SDavid du Colombier 
2473e12c5d1SDavid du Colombier bad:
2483e12c5d1SDavid du Colombier 	return -1;
2493e12c5d1SDavid du Colombier }
2503e12c5d1SDavid du Colombier 
2513e12c5d1SDavid du Colombier void
2523e12c5d1SDavid du Colombier nullwarn(Node *l, Node *r)
2533e12c5d1SDavid du Colombier {
2543e12c5d1SDavid du Colombier 	warn(Z, "result of operation not used");
2553e12c5d1SDavid du Colombier 	if(l != Z)
2563e12c5d1SDavid du Colombier 		cgen(l, Z);
2573e12c5d1SDavid du Colombier 	if(r != Z)
2583e12c5d1SDavid du Colombier 		cgen(r, Z);
2593e12c5d1SDavid du Colombier }
2603e12c5d1SDavid du Colombier 
2613e12c5d1SDavid du Colombier void
2623e12c5d1SDavid du Colombier sextern(Sym *s, Node *a, long o, long w)
2633e12c5d1SDavid du Colombier {
2643e12c5d1SDavid du Colombier 	long e, lw;
2653e12c5d1SDavid du Colombier 
2663e12c5d1SDavid du Colombier 	for(e=0; e<w; e+=NSNAME) {
2673e12c5d1SDavid du Colombier 		lw = NSNAME;
2683e12c5d1SDavid du Colombier 		if(w-e < lw)
2693e12c5d1SDavid du Colombier 			lw = w-e;
2703e12c5d1SDavid du Colombier 		gpseudo(ADATA, s, nodconst(0L));
2713e12c5d1SDavid du Colombier 		p->from.offset += o+e;
2723e12c5d1SDavid du Colombier 		p->from.scale = lw;
2733e12c5d1SDavid du Colombier 		p->to.type = D_SCONST;
274*219b2ee8SDavid du Colombier 		memmove(p->to.sval, a->cstring+e, lw);
2753e12c5d1SDavid du Colombier 	}
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier void
2793e12c5d1SDavid du Colombier gextern(Sym *s, Node *a, long o, long w)
2803e12c5d1SDavid du Colombier {
281*219b2ee8SDavid du Colombier 	if(a->op == OCONST && typev[a->type->etype]) {
282*219b2ee8SDavid du Colombier 		gpseudo(ADATA, s, nodconst((long)(a->vconst>>32)));
283*219b2ee8SDavid du Colombier 		p->from.offset += o;
284*219b2ee8SDavid du Colombier 		p->from.scale = 4;
285*219b2ee8SDavid du Colombier 		gpseudo(ADATA, s, nodconst((long)(a->vconst)));
286*219b2ee8SDavid du Colombier 		p->from.offset += o + 4;
287*219b2ee8SDavid du Colombier 		p->from.scale = 4;
288*219b2ee8SDavid du Colombier 		return;
289*219b2ee8SDavid du Colombier 	}
2903e12c5d1SDavid du Colombier 	gpseudo(ADATA, s, a);
2913e12c5d1SDavid du Colombier 	p->from.offset += o;
2923e12c5d1SDavid du Colombier 	p->from.scale = w;
2933e12c5d1SDavid du Colombier 	switch(p->to.type) {
2943e12c5d1SDavid du Colombier 	default:
2953e12c5d1SDavid du Colombier 		p->to.index = p->to.type;
2963e12c5d1SDavid du Colombier 		p->to.type = D_ADDR;
2973e12c5d1SDavid du Colombier 	case D_CONST:
2983e12c5d1SDavid du Colombier 	case D_FCONST:
2993e12c5d1SDavid du Colombier 	case D_ADDR:
3003e12c5d1SDavid du Colombier 		break;
3013e12c5d1SDavid du Colombier 	}
3023e12c5d1SDavid du Colombier }
3033e12c5d1SDavid du Colombier 
3043e12c5d1SDavid du Colombier void	zname(Biobuf*, char*, int, int);
3053e12c5d1SDavid du Colombier void	zaddr(Biobuf*, Adr*, int);
3063e12c5d1SDavid du Colombier void	outhist(Biobuf*);
3073e12c5d1SDavid du Colombier 
3083e12c5d1SDavid du Colombier void
3093e12c5d1SDavid du Colombier outcode(void)
3103e12c5d1SDavid du Colombier {
3113e12c5d1SDavid du Colombier 	struct { Sym *sym; short type; } h[NSYM];
3123e12c5d1SDavid du Colombier 	Prog *p;
3133e12c5d1SDavid du Colombier 	Sym *s;
3143e12c5d1SDavid du Colombier 	int f, sf, st, t, sym;
3153e12c5d1SDavid du Colombier 	Biobuf b;
3163e12c5d1SDavid du Colombier 
3173e12c5d1SDavid du Colombier 	if(debug['S']) {
3183e12c5d1SDavid du Colombier 		for(p = firstp; p != P; p = p->link)
3193e12c5d1SDavid du Colombier 			if(p->as != ADATA && p->as != AGLOBL)
3203e12c5d1SDavid du Colombier 				pc--;
3213e12c5d1SDavid du Colombier 		for(p = firstp; p != P; p = p->link) {
3223e12c5d1SDavid du Colombier 			print("%P\n", p);
3233e12c5d1SDavid du Colombier 			if(p->as != ADATA && p->as != AGLOBL)
3243e12c5d1SDavid du Colombier 				pc++;
3253e12c5d1SDavid du Colombier 		}
3263e12c5d1SDavid du Colombier 	}
3273e12c5d1SDavid du Colombier 	f = open(outfile, OWRITE);
3283e12c5d1SDavid du Colombier 	if(f < 0) {
3293e12c5d1SDavid du Colombier 		diag(Z, "cannot open %s", outfile);
3303e12c5d1SDavid du Colombier 		return;
3313e12c5d1SDavid du Colombier 	}
3323e12c5d1SDavid du Colombier 	Binit(&b, f, OWRITE);
3333e12c5d1SDavid du Colombier 	Bseek(&b, 0L, 2);
3343e12c5d1SDavid du Colombier 	outhist(&b);
3353e12c5d1SDavid du Colombier 	for(sym=0; sym<NSYM; sym++) {
3363e12c5d1SDavid du Colombier 		h[sym].sym = S;
3373e12c5d1SDavid du Colombier 		h[sym].type = 0;
3383e12c5d1SDavid du Colombier 	}
3393e12c5d1SDavid du Colombier 	sym = 1;
3403e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
3413e12c5d1SDavid du Colombier 	jackpot:
3423e12c5d1SDavid du Colombier 		sf = 0;
3433e12c5d1SDavid du Colombier 		s = p->from.sym;
3443e12c5d1SDavid du Colombier 		while(s != S) {
3453e12c5d1SDavid du Colombier 			sf = s->sym;
3463e12c5d1SDavid du Colombier 			if(sf < 0 || sf >= NSYM)
3473e12c5d1SDavid du Colombier 				sf = 0;
3483e12c5d1SDavid du Colombier 			t = p->from.type;
3493e12c5d1SDavid du Colombier 			if(t == D_ADDR)
3503e12c5d1SDavid du Colombier 				t = p->from.index;
3513e12c5d1SDavid du Colombier 			if(h[sf].type == t)
3523e12c5d1SDavid du Colombier 			if(h[sf].sym == s)
3533e12c5d1SDavid du Colombier 				break;
3543e12c5d1SDavid du Colombier 			zname(&b, s->name, t, sym);
3553e12c5d1SDavid du Colombier 			s->sym = sym;
3563e12c5d1SDavid du Colombier 			h[sym].sym = s;
3573e12c5d1SDavid du Colombier 			h[sym].type = t;
3583e12c5d1SDavid du Colombier 			sf = sym;
3593e12c5d1SDavid du Colombier 			sym++;
3603e12c5d1SDavid du Colombier 			if(sym >= NSYM)
3613e12c5d1SDavid du Colombier 				sym = 1;
3623e12c5d1SDavid du Colombier 			break;
3633e12c5d1SDavid du Colombier 		}
3643e12c5d1SDavid du Colombier 		st = 0;
3653e12c5d1SDavid du Colombier 		s = p->to.sym;
3663e12c5d1SDavid du Colombier 		while(s != S) {
3673e12c5d1SDavid du Colombier 			st = s->sym;
3683e12c5d1SDavid du Colombier 			if(st < 0 || st >= NSYM)
3693e12c5d1SDavid du Colombier 				st = 0;
3703e12c5d1SDavid du Colombier 			t = p->to.type;
3713e12c5d1SDavid du Colombier 			if(t == D_ADDR)
3723e12c5d1SDavid du Colombier 				t = p->to.index;
3733e12c5d1SDavid du Colombier 			if(h[st].type == t)
3743e12c5d1SDavid du Colombier 			if(h[st].sym == s)
3753e12c5d1SDavid du Colombier 				break;
3763e12c5d1SDavid du Colombier 			zname(&b, s->name, t, sym);
3773e12c5d1SDavid du Colombier 			s->sym = sym;
3783e12c5d1SDavid du Colombier 			h[sym].sym = s;
3793e12c5d1SDavid du Colombier 			h[sym].type = t;
3803e12c5d1SDavid du Colombier 			st = sym;
3813e12c5d1SDavid du Colombier 			sym++;
3823e12c5d1SDavid du Colombier 			if(sym >= NSYM)
3833e12c5d1SDavid du Colombier 				sym = 1;
3843e12c5d1SDavid du Colombier 			if(st == sf)
3853e12c5d1SDavid du Colombier 				goto jackpot;
3863e12c5d1SDavid du Colombier 			break;
3873e12c5d1SDavid du Colombier 		}
3883e12c5d1SDavid du Colombier 		Bputc(&b, p->as);
3893e12c5d1SDavid du Colombier 		Bputc(&b, p->as>>8);
3903e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno);
3913e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno>>8);
3923e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno>>16);
3933e12c5d1SDavid du Colombier 		Bputc(&b, p->lineno>>24);
3943e12c5d1SDavid du Colombier 		zaddr(&b, &p->from, sf);
3953e12c5d1SDavid du Colombier 		zaddr(&b, &p->to, st);
3963e12c5d1SDavid du Colombier 	}
3973e12c5d1SDavid du Colombier 	Bflush(&b);
3983e12c5d1SDavid du Colombier 	close(f);
3993e12c5d1SDavid du Colombier 	firstp = P;
4003e12c5d1SDavid du Colombier 	lastp = P;
4013e12c5d1SDavid du Colombier }
4023e12c5d1SDavid du Colombier 
403*219b2ee8SDavid du Colombier 
404*219b2ee8SDavid du Colombier 
4053e12c5d1SDavid du Colombier void
4063e12c5d1SDavid du Colombier outhist(Biobuf *b)
4073e12c5d1SDavid du Colombier {
4083e12c5d1SDavid du Colombier 	Hist *h;
409*219b2ee8SDavid du Colombier 	char *p, *q, *op;
4103e12c5d1SDavid du Colombier 	Prog pg;
4113e12c5d1SDavid du Colombier 	int n;
4123e12c5d1SDavid du Colombier 
4133e12c5d1SDavid du Colombier 	pg = zprog;
4143e12c5d1SDavid du Colombier 	pg.as = AHISTORY;
4153e12c5d1SDavid du Colombier 	for(h = hist; h != H; h = h->link) {
4163e12c5d1SDavid du Colombier 		p = h->name;
417*219b2ee8SDavid du Colombier 		op = 0;
418*219b2ee8SDavid du Colombier 		if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
419*219b2ee8SDavid du Colombier 			op = p;
420*219b2ee8SDavid du Colombier 			p = pathname;
421*219b2ee8SDavid du Colombier 		}
4223e12c5d1SDavid du Colombier 		while(p) {
4233e12c5d1SDavid du Colombier 			q = utfrune(p, '/');
4243e12c5d1SDavid du Colombier 			if(q) {
4253e12c5d1SDavid du Colombier 				n = q-p;
4263e12c5d1SDavid du Colombier 				if(n == 0)
4273e12c5d1SDavid du Colombier 					n = 1;	/* leading "/" */
4283e12c5d1SDavid du Colombier 				q++;
4293e12c5d1SDavid du Colombier 			} else {
4303e12c5d1SDavid du Colombier 				n = strlen(p);
4313e12c5d1SDavid du Colombier 				q = 0;
4323e12c5d1SDavid du Colombier 			}
4333e12c5d1SDavid du Colombier 			if(n) {
434*219b2ee8SDavid du Colombier 				Bputc(b, ANAME);
435*219b2ee8SDavid du Colombier 				Bputc(b, ANAME>>8);
436*219b2ee8SDavid du Colombier 				Bputc(b, D_FILE);
437*219b2ee8SDavid du Colombier 				Bputc(b, 1);
438*219b2ee8SDavid du Colombier 				Bputc(b, '<');
439*219b2ee8SDavid du Colombier 				Bwrite(b, p, n);
440*219b2ee8SDavid du Colombier 				Bputc(b, 0);
4413e12c5d1SDavid du Colombier 			}
4423e12c5d1SDavid du Colombier 			p = q;
443*219b2ee8SDavid du Colombier 			if(p == 0 && op) {
444*219b2ee8SDavid du Colombier 				p = op;
445*219b2ee8SDavid du Colombier 				op = 0;
446*219b2ee8SDavid du Colombier 			}
4473e12c5d1SDavid du Colombier 		}
4483e12c5d1SDavid du Colombier 		pg.lineno = h->line;
4493e12c5d1SDavid du Colombier 		pg.to.type = zprog.to.type;
4503e12c5d1SDavid du Colombier 		pg.to.offset = h->offset;
4513e12c5d1SDavid du Colombier 		if(h->offset)
4523e12c5d1SDavid du Colombier 			pg.to.type = D_CONST;
4533e12c5d1SDavid du Colombier 
4543e12c5d1SDavid du Colombier 		Bputc(b, pg.as);
4553e12c5d1SDavid du Colombier 		Bputc(b, pg.as>>8);
4563e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno);
4573e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno>>8);
4583e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno>>16);
4593e12c5d1SDavid du Colombier 		Bputc(b, pg.lineno>>24);
4603e12c5d1SDavid du Colombier 		zaddr(b, &pg.from, 0);
4613e12c5d1SDavid du Colombier 		zaddr(b, &pg.to, 0);
4623e12c5d1SDavid du Colombier 	}
4633e12c5d1SDavid du Colombier }
4643e12c5d1SDavid du Colombier 
4653e12c5d1SDavid du Colombier void
4663e12c5d1SDavid du Colombier zname(Biobuf *b, char *n, int t, int s)
4673e12c5d1SDavid du Colombier {
4683e12c5d1SDavid du Colombier 
4693e12c5d1SDavid du Colombier 	Bputc(b, ANAME);	/* as */
4703e12c5d1SDavid du Colombier 	Bputc(b, ANAME>>8);	/* as */
4713e12c5d1SDavid du Colombier 	Bputc(b, t);		/* type */
4723e12c5d1SDavid du Colombier 	Bputc(b, s);		/* sym */
4733e12c5d1SDavid du Colombier 	while(*n) {
4743e12c5d1SDavid du Colombier 		Bputc(b, *n);
4753e12c5d1SDavid du Colombier 		n++;
4763e12c5d1SDavid du Colombier 	}
4773e12c5d1SDavid du Colombier 	Bputc(b, 0);
4783e12c5d1SDavid du Colombier }
4793e12c5d1SDavid du Colombier 
4803e12c5d1SDavid du Colombier void
4813e12c5d1SDavid du Colombier zaddr(Biobuf *b, Adr *a, int s)
4823e12c5d1SDavid du Colombier {
4833e12c5d1SDavid du Colombier 	long l;
4843e12c5d1SDavid du Colombier 	int i, t;
4853e12c5d1SDavid du Colombier 	char *n;
4863e12c5d1SDavid du Colombier 	Ieee e;
4873e12c5d1SDavid du Colombier 
4883e12c5d1SDavid du Colombier 	t = 0;
4893e12c5d1SDavid du Colombier 	if(a->index != D_NONE || a->scale != 0)
4903e12c5d1SDavid du Colombier 		t |= T_INDEX;
4913e12c5d1SDavid du Colombier 	if(s != 0)
4923e12c5d1SDavid du Colombier 		t |= T_SYM;
4933e12c5d1SDavid du Colombier 
4943e12c5d1SDavid du Colombier 	switch(a->type) {
4953e12c5d1SDavid du Colombier 	default:
4963e12c5d1SDavid du Colombier 		t |= T_TYPE;
4973e12c5d1SDavid du Colombier 	case D_NONE:
4983e12c5d1SDavid du Colombier 		if(a->offset != 0)
4993e12c5d1SDavid du Colombier 			t |= T_OFFSET;
5003e12c5d1SDavid du Colombier 		break;
5013e12c5d1SDavid du Colombier 	case D_FCONST:
5023e12c5d1SDavid du Colombier 		t |= T_FCONST;
5033e12c5d1SDavid du Colombier 		break;
5043e12c5d1SDavid du Colombier 	case D_SCONST:
5053e12c5d1SDavid du Colombier 		t |= T_SCONST;
5063e12c5d1SDavid du Colombier 		break;
5073e12c5d1SDavid du Colombier 	}
5083e12c5d1SDavid du Colombier 	Bputc(b, t);
5093e12c5d1SDavid du Colombier 
5103e12c5d1SDavid du Colombier 	if(t & T_INDEX) {	/* implies index, scale */
5113e12c5d1SDavid du Colombier 		Bputc(b, a->index);
5123e12c5d1SDavid du Colombier 		Bputc(b, a->scale);
5133e12c5d1SDavid du Colombier 	}
5143e12c5d1SDavid du Colombier 	if(t & T_OFFSET) {	/* implies offset */
5153e12c5d1SDavid du Colombier 		l = a->offset;
5163e12c5d1SDavid du Colombier 		Bputc(b, l);
5173e12c5d1SDavid du Colombier 		Bputc(b, l>>8);
5183e12c5d1SDavid du Colombier 		Bputc(b, l>>16);
5193e12c5d1SDavid du Colombier 		Bputc(b, l>>24);
5203e12c5d1SDavid du Colombier 	}
5213e12c5d1SDavid du Colombier 	if(t & T_SYM)		/* implies sym */
5223e12c5d1SDavid du Colombier 		Bputc(b, s);
5233e12c5d1SDavid du Colombier 	if(t & T_FCONST) {
5243e12c5d1SDavid du Colombier 		ieeedtod(&e, a->dval);
5253e12c5d1SDavid du Colombier 		l = e.l;
5263e12c5d1SDavid du Colombier 		Bputc(b, l);
5273e12c5d1SDavid du Colombier 		Bputc(b, l>>8);
5283e12c5d1SDavid du Colombier 		Bputc(b, l>>16);
5293e12c5d1SDavid du Colombier 		Bputc(b, l>>24);
5303e12c5d1SDavid du Colombier 		l = e.h;
5313e12c5d1SDavid du Colombier 		Bputc(b, l);
5323e12c5d1SDavid du Colombier 		Bputc(b, l>>8);
5333e12c5d1SDavid du Colombier 		Bputc(b, l>>16);
5343e12c5d1SDavid du Colombier 		Bputc(b, l>>24);
5353e12c5d1SDavid du Colombier 		return;
5363e12c5d1SDavid du Colombier 	}
5373e12c5d1SDavid du Colombier 	if(t & T_SCONST) {
5383e12c5d1SDavid du Colombier 		n = a->sval;
5393e12c5d1SDavid du Colombier 		for(i=0; i<NSNAME; i++) {
5403e12c5d1SDavid du Colombier 			Bputc(b, *n);
5413e12c5d1SDavid du Colombier 			n++;
5423e12c5d1SDavid du Colombier 		}
5433e12c5d1SDavid du Colombier 		return;
5443e12c5d1SDavid du Colombier 	}
5453e12c5d1SDavid du Colombier 	if(t & T_TYPE)
5463e12c5d1SDavid du Colombier 		Bputc(b, a->type);
5473e12c5d1SDavid du Colombier }
5483e12c5d1SDavid du Colombier 
5493e12c5d1SDavid du Colombier void
5503e12c5d1SDavid du Colombier ieeedtod(Ieee *ieee, double native)
5513e12c5d1SDavid du Colombier {
5523e12c5d1SDavid du Colombier 	double fr, ho, f;
5533e12c5d1SDavid du Colombier 	int exp;
5543e12c5d1SDavid du Colombier 
5553e12c5d1SDavid du Colombier 	if(native < 0) {
5563e12c5d1SDavid du Colombier 		ieeedtod(ieee, -native);
5573e12c5d1SDavid du Colombier 		ieee->h |= 0x80000000L;
5583e12c5d1SDavid du Colombier 		return;
5593e12c5d1SDavid du Colombier 	}
5603e12c5d1SDavid du Colombier 	if(native == 0) {
5613e12c5d1SDavid du Colombier 		ieee->l = 0;
5623e12c5d1SDavid du Colombier 		ieee->h = 0;
5633e12c5d1SDavid du Colombier 		return;
5643e12c5d1SDavid du Colombier 	}
5653e12c5d1SDavid du Colombier 	fr = frexp(native, &exp);
5663e12c5d1SDavid du Colombier 	f = 2097152L;		/* shouldnt use fp constants here */
5673e12c5d1SDavid du Colombier 	fr = modf(fr*f, &ho);
5683e12c5d1SDavid du Colombier 	ieee->h = ho;
5693e12c5d1SDavid du Colombier 	ieee->h &= 0xfffffL;
5703e12c5d1SDavid du Colombier 	ieee->h |= (exp+1022L) << 20;
5713e12c5d1SDavid du Colombier 	f = 65536L;
5723e12c5d1SDavid du Colombier 	fr = modf(fr*f, &ho);
5733e12c5d1SDavid du Colombier 	ieee->l = ho;
5743e12c5d1SDavid du Colombier 	ieee->l <<= 16;
5753e12c5d1SDavid du Colombier 	ieee->l |= (long)(fr*f);
5763e12c5d1SDavid du Colombier }
5773e12c5d1SDavid du Colombier 
5783e12c5d1SDavid du Colombier char*	xonames[] =
5793e12c5d1SDavid du Colombier {
5803e12c5d1SDavid du Colombier 	"INDEX",
5813e12c5d1SDavid du Colombier 	"XEND",
5823e12c5d1SDavid du Colombier };
5833e12c5d1SDavid du Colombier 
5843e12c5d1SDavid du Colombier char*
5853e12c5d1SDavid du Colombier xOconv(int a)
5863e12c5d1SDavid du Colombier {
5873e12c5d1SDavid du Colombier 	if(a <= OEND || a > OXEND)
5883e12c5d1SDavid du Colombier 		return "**badO**";
5893e12c5d1SDavid du Colombier 	return xonames[a-OEND-1];
5903e12c5d1SDavid du Colombier }
5913e12c5d1SDavid du Colombier 
5923e12c5d1SDavid du Colombier int
5933e12c5d1SDavid du Colombier endian(int w)
5943e12c5d1SDavid du Colombier {
5953e12c5d1SDavid du Colombier 
5963e12c5d1SDavid du Colombier 	USED(w);
5973e12c5d1SDavid du Colombier 	return 0;
5983e12c5d1SDavid du Colombier }
599*219b2ee8SDavid du Colombier 
600*219b2ee8SDavid du Colombier int
601*219b2ee8SDavid du Colombier passbypointer(int et)
602*219b2ee8SDavid du Colombier {
603*219b2ee8SDavid du Colombier 
604*219b2ee8SDavid du Colombier 	return typesuv[et];
605*219b2ee8SDavid du Colombier }
606*219b2ee8SDavid du Colombier 
607*219b2ee8SDavid du Colombier int
608*219b2ee8SDavid du Colombier argalign(long typewidth, long offset, int offsp)
609*219b2ee8SDavid du Colombier {
610*219b2ee8SDavid du Colombier 	USED(typewidth,offset,offsp);
611*219b2ee8SDavid du Colombier 	return 0;
612*219b2ee8SDavid du Colombier }
613