xref: /plan9/sys/src/cmd/kl/asm.c (revision b87cd620ecfdc8c76fc402275c5ab6ae2edfd4ee)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier #define	LPUT(c)\
43e12c5d1SDavid du Colombier 	{\
53e12c5d1SDavid du Colombier 		cbp[0] = (c)>>24;\
63e12c5d1SDavid du Colombier 		cbp[1] = (c)>>16;\
73e12c5d1SDavid du Colombier 		cbp[2] = (c)>>8;\
83e12c5d1SDavid du Colombier 		cbp[3] = (c);\
93e12c5d1SDavid du Colombier 		cbp += 4;\
103e12c5d1SDavid du Colombier 		cbc -= 4;\
113e12c5d1SDavid du Colombier 		if(cbc <= 0)\
123e12c5d1SDavid du Colombier 			cflush();\
133e12c5d1SDavid du Colombier 	}
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier #define	CPUT(c)\
163e12c5d1SDavid du Colombier 	{\
173e12c5d1SDavid du Colombier 		cbp[0] = (c);\
183e12c5d1SDavid du Colombier 		cbp++;\
193e12c5d1SDavid du Colombier 		cbc--;\
203e12c5d1SDavid du Colombier 		if(cbc <= 0)\
213e12c5d1SDavid du Colombier 			cflush();\
223e12c5d1SDavid du Colombier 	}
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier long
entryvalue(void)253e12c5d1SDavid du Colombier entryvalue(void)
263e12c5d1SDavid du Colombier {
273e12c5d1SDavid du Colombier 	char *a;
283e12c5d1SDavid du Colombier 	Sym *s;
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier 	a = INITENTRY;
313e12c5d1SDavid du Colombier 	if(*a >= '0' && *a <= '9')
323e12c5d1SDavid du Colombier 		return atolwhex(a);
333e12c5d1SDavid du Colombier 	s = lookup(a, 0);
343e12c5d1SDavid du Colombier 	if(s->type == 0)
353e12c5d1SDavid du Colombier 		return INITTEXT;
363e12c5d1SDavid du Colombier 	if(s->type != STEXT && s->type != SLEAF)
373e12c5d1SDavid du Colombier 		diag("entry not text: %s", s->name);
383e12c5d1SDavid du Colombier 	return s->value;
393e12c5d1SDavid du Colombier }
403e12c5d1SDavid du Colombier 
413e12c5d1SDavid du Colombier void
asmb(void)423e12c5d1SDavid du Colombier asmb(void)
433e12c5d1SDavid du Colombier {
443e12c5d1SDavid du Colombier 	Prog *p;
453e12c5d1SDavid du Colombier 	long t;
463e12c5d1SDavid du Colombier 	Optab *o;
473e12c5d1SDavid du Colombier 
483e12c5d1SDavid du Colombier 	if(debug['v'])
493e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f asm\n", cputime());
503e12c5d1SDavid du Colombier 	Bflush(&bso);
513e12c5d1SDavid du Colombier 	seek(cout, HEADR, 0);
523e12c5d1SDavid du Colombier 	pc = INITTEXT;
533e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
543e12c5d1SDavid du Colombier 		if(p->as == ATEXT) {
553e12c5d1SDavid du Colombier 			curtext = p;
563e12c5d1SDavid du Colombier 			autosize = p->to.offset + 4;
573e12c5d1SDavid du Colombier 		}
583e12c5d1SDavid du Colombier 		if(p->pc != pc) {
596b6b9ac8SDavid du Colombier 			diag("phase error %lux sb %lux",
603e12c5d1SDavid du Colombier 				p->pc, pc);
613e12c5d1SDavid du Colombier 			if(!debug['a'])
623e12c5d1SDavid du Colombier 				prasm(curp);
633e12c5d1SDavid du Colombier 			pc = p->pc;
643e12c5d1SDavid du Colombier 		}
653e12c5d1SDavid du Colombier 		curp = p;
663e12c5d1SDavid du Colombier 		o = oplook(p);	/* could probably avoid this call */
673e12c5d1SDavid du Colombier 		if(asmout(p, o, 0)) {
683e12c5d1SDavid du Colombier 			p = p->link;
693e12c5d1SDavid du Colombier 			pc += 4;
703e12c5d1SDavid du Colombier 		}
713e12c5d1SDavid du Colombier 		pc += o->size;
723e12c5d1SDavid du Colombier 	}
733e12c5d1SDavid du Colombier 	if(debug['a'])
743e12c5d1SDavid du Colombier 		Bprint(&bso, "\n");
753e12c5d1SDavid du Colombier 	Bflush(&bso);
763e12c5d1SDavid du Colombier 	cflush();
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier 	curtext = P;
793e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
803e12c5d1SDavid du Colombier 	case 0:
81b7b24591SDavid du Colombier 	case 3:
823e12c5d1SDavid du Colombier 		seek(cout, HEADR+textsize, 0);
833e12c5d1SDavid du Colombier 		break;
843e12c5d1SDavid du Colombier 	case 1:
853e12c5d1SDavid du Colombier 	case 2:
863e12c5d1SDavid du Colombier 		seek(cout, HEADR+textsize, 0);
873e12c5d1SDavid du Colombier 		break;
883e12c5d1SDavid du Colombier 	}
893e12c5d1SDavid du Colombier 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
903e12c5d1SDavid du Colombier 		if(datsize-t > sizeof(buf)-100)
913e12c5d1SDavid du Colombier 			datblk(t, sizeof(buf)-100);
923e12c5d1SDavid du Colombier 		else
933e12c5d1SDavid du Colombier 			datblk(t, datsize-t);
943e12c5d1SDavid du Colombier 	}
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 	symsize = 0;
973e12c5d1SDavid du Colombier 	lcsize = 0;
983e12c5d1SDavid du Colombier 	if(!debug['s']) {
993e12c5d1SDavid du Colombier 		if(debug['v'])
1003e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
1013e12c5d1SDavid du Colombier 		Bflush(&bso);
1023e12c5d1SDavid du Colombier 		switch(HEADTYPE) {
1033e12c5d1SDavid du Colombier 		case 0:
104b7b24591SDavid du Colombier 		case 3:
1053e12c5d1SDavid du Colombier 			seek(cout, HEADR+textsize+datsize, 0);
1063e12c5d1SDavid du Colombier 			break;
1073e12c5d1SDavid du Colombier 		case 2:
1083e12c5d1SDavid du Colombier 		case 1:
1093e12c5d1SDavid du Colombier 			seek(cout, HEADR+textsize+datsize, 0);
1103e12c5d1SDavid du Colombier 			break;
1113e12c5d1SDavid du Colombier 		}
1123e12c5d1SDavid du Colombier 		if(!debug['s'])
1133e12c5d1SDavid du Colombier 			asmsym();
1143e12c5d1SDavid du Colombier 		if(debug['v'])
1153e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sp\n", cputime());
1163e12c5d1SDavid du Colombier 		Bflush(&bso);
1173e12c5d1SDavid du Colombier 		if(!debug['s'])
1183e12c5d1SDavid du Colombier 			asmlc();
119b7b24591SDavid du Colombier 		 /* round up file length for boot image */
120b7b24591SDavid du Colombier 		if(HEADTYPE == 0 || HEADTYPE == 3)
121219b2ee8SDavid du Colombier 			if((symsize+lcsize) & 1)
122219b2ee8SDavid du Colombier 				CPUT(0);
1233e12c5d1SDavid du Colombier 		cflush();
1243e12c5d1SDavid du Colombier 	}
1253e12c5d1SDavid du Colombier 
1263e12c5d1SDavid du Colombier 	seek(cout, 0L, 0);
1273e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
1283e12c5d1SDavid du Colombier 	case 0:
1293e12c5d1SDavid du Colombier 		lput(0x1030107);		/* magic and sections */
1303e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
1313e12c5d1SDavid du Colombier 		lput(datsize);
1323e12c5d1SDavid du Colombier 		lput(bsssize);
1333e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
1343e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
1353e12c5d1SDavid du Colombier 		lput(0L);
1363e12c5d1SDavid du Colombier 		lput(lcsize);
1373e12c5d1SDavid du Colombier 		break;
1383e12c5d1SDavid du Colombier 	case 1:
1393e12c5d1SDavid du Colombier 		break;
1403e12c5d1SDavid du Colombier 	case 2:
1413e12c5d1SDavid du Colombier 		lput(4*13*13+7);		/* magic */
1423e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
1433e12c5d1SDavid du Colombier 		lput(datsize);
1443e12c5d1SDavid du Colombier 		lput(bsssize);
1453e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
1463e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
1473e12c5d1SDavid du Colombier 		lput(0L);
1483e12c5d1SDavid du Colombier 		lput(lcsize);
1493e12c5d1SDavid du Colombier 		break;
150b7b24591SDavid du Colombier 	case 3:
151b7b24591SDavid du Colombier 		lput(0x1030107);		/* magic and sections */
152b7b24591SDavid du Colombier 		lput(0x90100000);
153b7b24591SDavid du Colombier #define SPARC_NOOP 0x01000000
154b7b24591SDavid du Colombier 		lput(SPARC_NOOP);
155b7b24591SDavid du Colombier 		lput(SPARC_NOOP);
156b7b24591SDavid du Colombier 		lput(SPARC_NOOP);
157b7b24591SDavid du Colombier 		lput(SPARC_NOOP);
158b7b24591SDavid du Colombier 		lput(SPARC_NOOP);
159b7b24591SDavid du Colombier 		lput(SPARC_NOOP);
160b7b24591SDavid du Colombier 		break;
1613e12c5d1SDavid du Colombier 	}
1623e12c5d1SDavid du Colombier 	cflush();
1633e12c5d1SDavid du Colombier }
1643e12c5d1SDavid du Colombier 
1653e12c5d1SDavid du Colombier void
lput(long l)1663e12c5d1SDavid du Colombier lput(long l)
1673e12c5d1SDavid du Colombier {
1683e12c5d1SDavid du Colombier 
1693e12c5d1SDavid du Colombier 	LPUT(l);
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier void
cflush(void)1733e12c5d1SDavid du Colombier cflush(void)
1743e12c5d1SDavid du Colombier {
1753e12c5d1SDavid du Colombier 	int n;
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
1783e12c5d1SDavid du Colombier 	if(n)
1793e12c5d1SDavid du Colombier 		write(cout, buf.cbuf, n);
1803e12c5d1SDavid du Colombier 	cbp = buf.cbuf;
1813e12c5d1SDavid du Colombier 	cbc = sizeof(buf.cbuf);
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier void
asmsym(void)1853e12c5d1SDavid du Colombier asmsym(void)
1863e12c5d1SDavid du Colombier {
1873e12c5d1SDavid du Colombier 	Prog *p;
1883e12c5d1SDavid du Colombier 	Auto *a;
1893e12c5d1SDavid du Colombier 	Sym *s;
1903e12c5d1SDavid du Colombier 	int h;
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	s = lookup("etext", 0);
1933e12c5d1SDavid du Colombier 	if(s->type == STEXT)
1943e12c5d1SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier 	for(h=0; h<NHASH; h++)
1973e12c5d1SDavid du Colombier 		for(s=hash[h]; s!=S; s=s->link)
1983e12c5d1SDavid du Colombier 			switch(s->type) {
199219b2ee8SDavid du Colombier 			case SCONST:
200219b2ee8SDavid du Colombier 				putsymb(s->name, 'D', s->value, s->version);
201219b2ee8SDavid du Colombier 				continue;
202219b2ee8SDavid du Colombier 
2033e12c5d1SDavid du Colombier 			case SDATA:
2043e12c5d1SDavid du Colombier 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
2053e12c5d1SDavid du Colombier 				continue;
2063e12c5d1SDavid du Colombier 
2073e12c5d1SDavid du Colombier 			case SBSS:
2083e12c5d1SDavid du Colombier 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
2093e12c5d1SDavid du Colombier 				continue;
2103e12c5d1SDavid du Colombier 
2113e12c5d1SDavid du Colombier 			case SFILE:
2123e12c5d1SDavid du Colombier 				putsymb(s->name, 'f', s->value, s->version);
2133e12c5d1SDavid du Colombier 				continue;
2143e12c5d1SDavid du Colombier 			}
2153e12c5d1SDavid du Colombier 
2163e12c5d1SDavid du Colombier 	for(p=textp; p!=P; p=p->cond) {
2173e12c5d1SDavid du Colombier 		s = p->from.sym;
2183e12c5d1SDavid du Colombier 		if(s->type != STEXT && s->type != SLEAF)
2193e12c5d1SDavid du Colombier 			continue;
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier 		/* filenames first */
2223e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
2233e12c5d1SDavid du Colombier 			if(a->type == D_FILE)
2247dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'z', a->aoffset, 0);
2253e12c5d1SDavid du Colombier 			else
226219b2ee8SDavid du Colombier 			if(a->type == D_FILE1)
2277dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'Z', a->aoffset, 0);
2283e12c5d1SDavid du Colombier 
2293e12c5d1SDavid du Colombier 		if(s->type == STEXT)
2303e12c5d1SDavid du Colombier 			putsymb(s->name, 'T', s->value, s->version);
2313e12c5d1SDavid du Colombier 		else
2323e12c5d1SDavid du Colombier 			putsymb(s->name, 'L', s->value, s->version);
2333e12c5d1SDavid du Colombier 
2343e12c5d1SDavid du Colombier 		/* frame, auto and param after */
235219b2ee8SDavid du Colombier 		putsymb(".frame", 'm', p->to.offset+4, 0);
2363e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
2373e12c5d1SDavid du Colombier 			if(a->type == D_AUTO)
2387dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'a', -a->aoffset, 0);
2393e12c5d1SDavid du Colombier 			else
2403e12c5d1SDavid du Colombier 			if(a->type == D_PARAM)
2417dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'p', a->aoffset, 0);
2423e12c5d1SDavid du Colombier 	}
2433e12c5d1SDavid du Colombier 	if(debug['v'] || debug['n'])
2443e12c5d1SDavid du Colombier 		Bprint(&bso, "symsize = %lud\n", symsize);
2453e12c5d1SDavid du Colombier 	Bflush(&bso);
2463e12c5d1SDavid du Colombier }
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier void
putsymb(char * s,int t,long v,int ver)2493e12c5d1SDavid du Colombier putsymb(char *s, int t, long v, int ver)
2503e12c5d1SDavid du Colombier {
2513e12c5d1SDavid du Colombier 	int i, f;
2523e12c5d1SDavid du Colombier 
2533e12c5d1SDavid du Colombier 	if(t == 'f')
2543e12c5d1SDavid du Colombier 		s++;
2553e12c5d1SDavid du Colombier 	LPUT(v);
2563e12c5d1SDavid du Colombier 	if(ver)
2573e12c5d1SDavid du Colombier 		t += 'a' - 'A';
258219b2ee8SDavid du Colombier 	CPUT(t+0x80);			/* 0x80 is variable length */
259219b2ee8SDavid du Colombier 
260219b2ee8SDavid du Colombier 	if(t == 'Z' || t == 'z') {
261219b2ee8SDavid du Colombier 		CPUT(s[0]);
262219b2ee8SDavid du Colombier 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
263219b2ee8SDavid du Colombier 			CPUT(s[i]);
264219b2ee8SDavid du Colombier 			CPUT(s[i+1]);
265219b2ee8SDavid du Colombier 		}
266219b2ee8SDavid du Colombier 		CPUT(0);
267219b2ee8SDavid du Colombier 		CPUT(0);
268219b2ee8SDavid du Colombier 		i++;
269219b2ee8SDavid du Colombier 	}
270219b2ee8SDavid du Colombier 	else {
271219b2ee8SDavid du Colombier 		for(i=0; s[i]; i++)
2723e12c5d1SDavid du Colombier 			CPUT(s[i]);
2733e12c5d1SDavid du Colombier 		CPUT(0);
274219b2ee8SDavid du Colombier 	}
275219b2ee8SDavid du Colombier 	symsize += 4 + 1 + i + 1;
276219b2ee8SDavid du Colombier 
2773e12c5d1SDavid du Colombier 	if(debug['n']) {
2783e12c5d1SDavid du Colombier 		if(t == 'z' || t == 'Z') {
279219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux ", t, v);
280219b2ee8SDavid du Colombier 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
2813e12c5d1SDavid du Colombier 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
282219b2ee8SDavid du Colombier 				Bprint(&bso, "/%x", f);
2833e12c5d1SDavid du Colombier 			}
284219b2ee8SDavid du Colombier 			Bprint(&bso, "\n");
2853e12c5d1SDavid du Colombier 			return;
2863e12c5d1SDavid du Colombier 		}
2873e12c5d1SDavid du Colombier 		if(ver)
2883e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
2893e12c5d1SDavid du Colombier 		else
2903e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
2913e12c5d1SDavid du Colombier 	}
2923e12c5d1SDavid du Colombier }
2933e12c5d1SDavid du Colombier 
2943e12c5d1SDavid du Colombier #define	MINLC	4
2953e12c5d1SDavid du Colombier void
asmlc(void)2963e12c5d1SDavid du Colombier asmlc(void)
2973e12c5d1SDavid du Colombier {
2983e12c5d1SDavid du Colombier 	long oldpc, oldlc;
2993e12c5d1SDavid du Colombier 	Prog *p;
3003e12c5d1SDavid du Colombier 	long v, s;
3013e12c5d1SDavid du Colombier 
3023e12c5d1SDavid du Colombier 	oldpc = INITTEXT;
3033e12c5d1SDavid du Colombier 	oldlc = 0;
3043e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
3053e12c5d1SDavid du Colombier 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
3063e12c5d1SDavid du Colombier 			if(p->as == ATEXT)
3073e12c5d1SDavid du Colombier 				curtext = p;
308*b87cd620SDavid du Colombier 			if(debug['V'])
3093e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
3103e12c5d1SDavid du Colombier 					p->pc, p);
3113e12c5d1SDavid du Colombier 			continue;
3123e12c5d1SDavid du Colombier 		}
313*b87cd620SDavid du Colombier 		if(debug['V'])
3143e12c5d1SDavid du Colombier 			Bprint(&bso, "\t\t%6ld", lcsize);
3153e12c5d1SDavid du Colombier 		v = (p->pc - oldpc) / MINLC;
3163e12c5d1SDavid du Colombier 		while(v) {
3173e12c5d1SDavid du Colombier 			s = 127;
3183e12c5d1SDavid du Colombier 			if(v < 127)
3193e12c5d1SDavid du Colombier 				s = v;
3203e12c5d1SDavid du Colombier 			CPUT(s+128);	/* 129-255 +pc */
321*b87cd620SDavid du Colombier 			if(debug['V'])
3223e12c5d1SDavid du Colombier 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
3233e12c5d1SDavid du Colombier 			v -= s;
3243e12c5d1SDavid du Colombier 			lcsize++;
3253e12c5d1SDavid du Colombier 		}
3263e12c5d1SDavid du Colombier 		s = p->line - oldlc;
3273e12c5d1SDavid du Colombier 		oldlc = p->line;
3283e12c5d1SDavid du Colombier 		oldpc = p->pc + MINLC;
3293e12c5d1SDavid du Colombier 		if(s > 64 || s < -64) {
3303e12c5d1SDavid du Colombier 			CPUT(0);	/* 0 vv +lc */
3313e12c5d1SDavid du Colombier 			CPUT(s>>24);
3323e12c5d1SDavid du Colombier 			CPUT(s>>16);
3333e12c5d1SDavid du Colombier 			CPUT(s>>8);
3343e12c5d1SDavid du Colombier 			CPUT(s);
335*b87cd620SDavid du Colombier 			if(debug['V']) {
3363e12c5d1SDavid du Colombier 				if(s > 0)
3373e12c5d1SDavid du Colombier 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
3383e12c5d1SDavid du Colombier 						s, 0, s);
3393e12c5d1SDavid du Colombier 				else
3403e12c5d1SDavid du Colombier 					Bprint(&bso, " lc%ld(%d,%ld)\n",
3413e12c5d1SDavid du Colombier 						s, 0, s);
3423e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
3433e12c5d1SDavid du Colombier 					p->pc, p);
3443e12c5d1SDavid du Colombier 			}
3453e12c5d1SDavid du Colombier 			lcsize += 5;
3463e12c5d1SDavid du Colombier 			continue;
3473e12c5d1SDavid du Colombier 		}
3483e12c5d1SDavid du Colombier 		if(s > 0) {
3493e12c5d1SDavid du Colombier 			CPUT(0+s);	/* 1-64 +lc */
350*b87cd620SDavid du Colombier 			if(debug['V']) {
3513e12c5d1SDavid du Colombier 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
3523e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
3533e12c5d1SDavid du Colombier 					p->pc, p);
3543e12c5d1SDavid du Colombier 			}
3553e12c5d1SDavid du Colombier 		} else {
3563e12c5d1SDavid du Colombier 			CPUT(64-s);	/* 65-128 -lc */
357*b87cd620SDavid du Colombier 			if(debug['V']) {
3583e12c5d1SDavid du Colombier 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
3593e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
3603e12c5d1SDavid du Colombier 					p->pc, p);
3613e12c5d1SDavid du Colombier 			}
3623e12c5d1SDavid du Colombier 		}
3633e12c5d1SDavid du Colombier 		lcsize++;
3643e12c5d1SDavid du Colombier 	}
3653e12c5d1SDavid du Colombier 	while(lcsize & 1) {
3663e12c5d1SDavid du Colombier 		s = 129;
3673e12c5d1SDavid du Colombier 		CPUT(s);
3683e12c5d1SDavid du Colombier 		lcsize++;
3693e12c5d1SDavid du Colombier 	}
370*b87cd620SDavid du Colombier 	if(debug['v'] || debug['V'])
3713e12c5d1SDavid du Colombier 		Bprint(&bso, "lcsize = %ld\n", lcsize);
3723e12c5d1SDavid du Colombier 	Bflush(&bso);
3733e12c5d1SDavid du Colombier }
3743e12c5d1SDavid du Colombier 
3753e12c5d1SDavid du Colombier void
datblk(long s,long n)3763e12c5d1SDavid du Colombier datblk(long s, long n)
3773e12c5d1SDavid du Colombier {
3783e12c5d1SDavid du Colombier 	Prog *p;
3793e12c5d1SDavid du Colombier 	char *cast;
3803e12c5d1SDavid du Colombier 	long l, fl, j, d;
3813e12c5d1SDavid du Colombier 	int i, c;
3823e12c5d1SDavid du Colombier 
3833e12c5d1SDavid du Colombier 	memset(buf.dbuf, 0, n+100);
3843e12c5d1SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
3853e12c5d1SDavid du Colombier 		curp = p;
3863e12c5d1SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
3873e12c5d1SDavid du Colombier 		c = p->reg;
3883e12c5d1SDavid du Colombier 		i = 0;
3893e12c5d1SDavid du Colombier 		if(l < 0) {
3903e12c5d1SDavid du Colombier 			if(l+c <= 0)
3913e12c5d1SDavid du Colombier 				continue;
3923e12c5d1SDavid du Colombier 			while(l < 0) {
3933e12c5d1SDavid du Colombier 				l++;
3943e12c5d1SDavid du Colombier 				i++;
3953e12c5d1SDavid du Colombier 			}
3963e12c5d1SDavid du Colombier 		}
3973e12c5d1SDavid du Colombier 		if(l >= n)
3983e12c5d1SDavid du Colombier 			continue;
399219b2ee8SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
4003e12c5d1SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
4013e12c5d1SDavid du Colombier 				if(buf.dbuf[j]) {
4023e12c5d1SDavid du Colombier 					print("%P\n", p);
4036b6b9ac8SDavid du Colombier 					diag("multiple initialization");
4043e12c5d1SDavid du Colombier 					break;
4053e12c5d1SDavid du Colombier 				}
406219b2ee8SDavid du Colombier 		}
4073e12c5d1SDavid du Colombier 		switch(p->to.type) {
4083e12c5d1SDavid du Colombier 		default:
4096b6b9ac8SDavid du Colombier 			diag("unknown mode in initialization\n%P", p);
4103e12c5d1SDavid du Colombier 			break;
4113e12c5d1SDavid du Colombier 
4123e12c5d1SDavid du Colombier 		case D_FCONST:
4133e12c5d1SDavid du Colombier 			switch(c) {
4143e12c5d1SDavid du Colombier 			default:
4153e12c5d1SDavid du Colombier 			case 4:
4163e12c5d1SDavid du Colombier 				fl = ieeedtof(&p->to.ieee);
4173e12c5d1SDavid du Colombier 				cast = (char*)&fl;
4183e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4193e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i+4]];
4203e12c5d1SDavid du Colombier 					l++;
4213e12c5d1SDavid du Colombier 				}
4223e12c5d1SDavid du Colombier 				break;
4233e12c5d1SDavid du Colombier 			case 8:
4243e12c5d1SDavid du Colombier 				cast = (char*)&p->to.ieee;
4253e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4263e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
4273e12c5d1SDavid du Colombier 					l++;
4283e12c5d1SDavid du Colombier 				}
4293e12c5d1SDavid du Colombier 				break;
4303e12c5d1SDavid du Colombier 			}
4313e12c5d1SDavid du Colombier 			break;
4323e12c5d1SDavid du Colombier 
4333e12c5d1SDavid du Colombier 		case D_SCONST:
4343e12c5d1SDavid du Colombier 			for(; i<c; i++) {
4353e12c5d1SDavid du Colombier 				buf.dbuf[l] = p->to.sval[i];
4363e12c5d1SDavid du Colombier 				l++;
4373e12c5d1SDavid du Colombier 			}
4383e12c5d1SDavid du Colombier 			break;
4393e12c5d1SDavid du Colombier 
4403e12c5d1SDavid du Colombier 		case D_CONST:
4413e12c5d1SDavid du Colombier 			d = p->to.offset;
4423e12c5d1SDavid du Colombier 			if(p->to.sym) {
4433e12c5d1SDavid du Colombier 				if(p->to.sym->type == STEXT ||
4443e12c5d1SDavid du Colombier 				   p->to.sym->type == SLEAF)
4453e12c5d1SDavid du Colombier 					d += p->to.sym->value;
4463e12c5d1SDavid du Colombier 				if(p->to.sym->type == SDATA)
4473e12c5d1SDavid du Colombier 					d += p->to.sym->value + INITDAT;
4483e12c5d1SDavid du Colombier 				if(p->to.sym->type == SBSS)
4493e12c5d1SDavid du Colombier 					d += p->to.sym->value + INITDAT;
4503e12c5d1SDavid du Colombier 			}
4513e12c5d1SDavid du Colombier 			cast = (char*)&d;
4523e12c5d1SDavid du Colombier 			switch(c) {
4533e12c5d1SDavid du Colombier 			default:
4546b6b9ac8SDavid du Colombier 				diag("bad nuxi %d %d\n%P", c, i, curp);
4553e12c5d1SDavid du Colombier 				break;
4563e12c5d1SDavid du Colombier 			case 1:
4573e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4583e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
4593e12c5d1SDavid du Colombier 					l++;
4603e12c5d1SDavid du Colombier 				}
4613e12c5d1SDavid du Colombier 				break;
4623e12c5d1SDavid du Colombier 			case 2:
4633e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4643e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
4653e12c5d1SDavid du Colombier 					l++;
4663e12c5d1SDavid du Colombier 				}
4673e12c5d1SDavid du Colombier 				break;
4683e12c5d1SDavid du Colombier 			case 4:
4693e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4703e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
4713e12c5d1SDavid du Colombier 					l++;
4723e12c5d1SDavid du Colombier 				}
4733e12c5d1SDavid du Colombier 				break;
4743e12c5d1SDavid du Colombier 			}
4753e12c5d1SDavid du Colombier 			break;
4763e12c5d1SDavid du Colombier 		}
4773e12c5d1SDavid du Colombier 	}
4783e12c5d1SDavid du Colombier 	write(cout, buf.dbuf, n);
4793e12c5d1SDavid du Colombier }
4803e12c5d1SDavid du Colombier 
4813e12c5d1SDavid du Colombier #define	OP2(x)	(0x80000000|((x)<<19))
4823e12c5d1SDavid du Colombier #define	OP3(x)	(0xc0000000|((x)<<19))
4833e12c5d1SDavid du Colombier #define	OPB(x)	(0x00800000|((x)<<25))
4843e12c5d1SDavid du Colombier #define	OPT(x)	(0x81d02000|((x)<<25))
4853e12c5d1SDavid du Colombier #define	OPF1(x)	(0x81a00000|((x)<<5))
4863e12c5d1SDavid du Colombier #define	OPF2(x)	(0x81a80000|((x)<<5))
4873e12c5d1SDavid du Colombier #define	OPFB(x)	(0x01800000|((x)<<25))
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier #define	OP_RRR(op,r1,r2,r3)\
4903e12c5d1SDavid du Colombier 	(0x00000000 | op |\
4913e12c5d1SDavid du Colombier 	(((r1)&31L)<<0) |\
4923e12c5d1SDavid du Colombier 	(((r2)&31L)<<14) |\
4933e12c5d1SDavid du Colombier 	(((r3)&31L)<<25))
4943e12c5d1SDavid du Colombier #define	OP_IRR(op,i,r2,r3)\
4953e12c5d1SDavid du Colombier 	(0x00002000L | (op) |\
4963e12c5d1SDavid du Colombier 	(((i)&0x1fffL)<<0) |\
4973e12c5d1SDavid du Colombier 	(((r2)&31L)<<14) |\
4983e12c5d1SDavid du Colombier 	(((r3)&31L)<<25))
4993e12c5d1SDavid du Colombier #define	OP_BRA(op,pc)\
5003e12c5d1SDavid du Colombier 	((op) |\
5013e12c5d1SDavid du Colombier 	(((pc)&0x3fffff)<<0))
5023e12c5d1SDavid du Colombier 
5033e12c5d1SDavid du Colombier int
asmout(Prog * p,Optab * o,int aflag)5043e12c5d1SDavid du Colombier asmout(Prog *p, Optab *o, int aflag)
5053e12c5d1SDavid du Colombier {
5063e12c5d1SDavid du Colombier 	long o1, o2, o3, o4, o5, v;
5073e12c5d1SDavid du Colombier 	Prog *ct;
5083e12c5d1SDavid du Colombier 	int r;
5093e12c5d1SDavid du Colombier 
5103e12c5d1SDavid du Colombier 	o1 = 0;
5113e12c5d1SDavid du Colombier 	o2 = 0;
5123e12c5d1SDavid du Colombier 	o3 = 0;
5133e12c5d1SDavid du Colombier 	o4 = 0;
5143e12c5d1SDavid du Colombier 	o5 = 0;
5153e12c5d1SDavid du Colombier 
5163e12c5d1SDavid du Colombier 	switch(o->type) {
5173e12c5d1SDavid du Colombier 	default:
5183e12c5d1SDavid du Colombier 		if(aflag)
5193e12c5d1SDavid du Colombier 			return 0;
5206b6b9ac8SDavid du Colombier 		diag("unknown type %d", o->type);
5213e12c5d1SDavid du Colombier 		if(!debug['a'])
5223e12c5d1SDavid du Colombier 			prasm(p);
5233e12c5d1SDavid du Colombier 		break;
5243e12c5d1SDavid du Colombier 
5253e12c5d1SDavid du Colombier 	case 0:		/* pseudo ops */
5263e12c5d1SDavid du Colombier 		if(aflag) {
5273e12c5d1SDavid du Colombier 			if(p->link) {
5283e12c5d1SDavid du Colombier 				if(p->as == ATEXT) {
5293e12c5d1SDavid du Colombier 					ct = curtext;
5303e12c5d1SDavid du Colombier 					o2 = autosize;
5313e12c5d1SDavid du Colombier 					curtext = p;
5323e12c5d1SDavid du Colombier 					autosize = p->to.offset + 4;
5333e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
5343e12c5d1SDavid du Colombier 					curtext = ct;
5353e12c5d1SDavid du Colombier 					autosize = o2;
5363e12c5d1SDavid du Colombier 				} else
5373e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
5383e12c5d1SDavid du Colombier 			}
5393e12c5d1SDavid du Colombier 			return o1;
5403e12c5d1SDavid du Colombier 		}
5413e12c5d1SDavid du Colombier 		break;
5423e12c5d1SDavid du Colombier 
5433e12c5d1SDavid du Colombier 	case 1:		/* mov r1,r2 ==> OR r1,r0,r2 */
5443e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(AOR), p->from.reg, REGZERO, p->to.reg);
5453e12c5d1SDavid du Colombier 		break;
5463e12c5d1SDavid du Colombier 
5473e12c5d1SDavid du Colombier 	case 2:		/* mov $c,r ==> add r1,r0,r2 */
5483e12c5d1SDavid du Colombier 		r = p->from.reg;
5493e12c5d1SDavid du Colombier 		if(r == NREG)
5503e12c5d1SDavid du Colombier 			r = o->param;
5513e12c5d1SDavid du Colombier 		v = regoff(&p->from);
5523e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(AADD), v, r, p->to.reg);
5533e12c5d1SDavid du Colombier 		break;
5543e12c5d1SDavid du Colombier 
5553e12c5d1SDavid du Colombier 	case 3:		/* mov soreg, r */
5563e12c5d1SDavid du Colombier 		r = p->from.reg;
5573e12c5d1SDavid du Colombier 		if(r == NREG)
5583e12c5d1SDavid du Colombier 			r = o->param;
5593e12c5d1SDavid du Colombier 		v = regoff(&p->from);
5603e12c5d1SDavid du Colombier 		if(v == 0 && p->reg != NREG)
5613e12c5d1SDavid du Colombier 			o1 = OP_RRR(opcode(p->as), p->reg, r, p->to.reg);
5623e12c5d1SDavid du Colombier 		else
5633e12c5d1SDavid du Colombier 			o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);
5643e12c5d1SDavid du Colombier 		break;
5653e12c5d1SDavid du Colombier 
5663e12c5d1SDavid du Colombier 	case 4:		/* mov r, soreg */
5673e12c5d1SDavid du Colombier 		r = p->to.reg;
5683e12c5d1SDavid du Colombier 		if(r == NREG)
5693e12c5d1SDavid du Colombier 			r = o->param;
5703e12c5d1SDavid du Colombier 		v = regoff(&p->to);
5713e12c5d1SDavid du Colombier 		if(v == 0 && p->reg != NREG)
5723e12c5d1SDavid du Colombier 			o1 = OP_RRR(opcode(p->as+AEND), p->reg, r, p->from.reg);
5733e12c5d1SDavid du Colombier 		else
5743e12c5d1SDavid du Colombier 			o1 = OP_IRR(opcode(p->as+AEND), v, r, p->from.reg);
5753e12c5d1SDavid du Colombier 		break;
5763e12c5d1SDavid du Colombier 
5773e12c5d1SDavid du Colombier 	case 5:		/* mov $lcon, reg => sethi, add */
5783e12c5d1SDavid du Colombier 		v = regoff(&p->from);
5793e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
5803e12c5d1SDavid du Colombier 		o2 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, p->to.reg);
5813e12c5d1SDavid du Colombier 		break;
5823e12c5d1SDavid du Colombier 
5833e12c5d1SDavid du Colombier 	case 6:		/* mov asi, r[+r] */
5843e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(p->as), p->reg, p->from.reg, p->to.reg);
5853e12c5d1SDavid du Colombier 		o1 |= (1<<23) | ((p->from.offset&0xff)<<5);
5863e12c5d1SDavid du Colombier 		break;
5873e12c5d1SDavid du Colombier 
5883e12c5d1SDavid du Colombier 	case 7:		/* mov [+r]r, asi */
5893e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(p->as+AEND), p->reg, p->to.reg, p->from.reg);
5903e12c5d1SDavid du Colombier 		o1 |= (1<<23) | ((p->to.offset&0xff)<<5);
5913e12c5d1SDavid du Colombier 		break;
5923e12c5d1SDavid du Colombier 
5933e12c5d1SDavid du Colombier 	case 8:		/* mov r, preg and mov preg, r */
5943e12c5d1SDavid du Colombier 		if(p->to.type == D_PREG) {
5953e12c5d1SDavid du Colombier 			r = p->from.reg;
5963e12c5d1SDavid du Colombier 			switch(p->to.reg)
5973e12c5d1SDavid du Colombier 			{
5983e12c5d1SDavid du Colombier 			default:
5993e12c5d1SDavid du Colombier 				diag("unknown register P%d", p->to.reg);
6003e12c5d1SDavid du Colombier 			case D_Y:
6013e12c5d1SDavid du Colombier 				o1 = OP2(48);	/* wry */
6023e12c5d1SDavid du Colombier 				break;
6033e12c5d1SDavid du Colombier 			case D_PSR:
6043e12c5d1SDavid du Colombier 				o1 = OP2(49);	/* wrpsr */
6053e12c5d1SDavid du Colombier 				break;
6063e12c5d1SDavid du Colombier 			case D_WIM:
6073e12c5d1SDavid du Colombier 				o1 = OP2(50);	/* wrwim */
6083e12c5d1SDavid du Colombier 				break;
6093e12c5d1SDavid du Colombier 			case D_TBR:
6103e12c5d1SDavid du Colombier 				o1 = OP2(51);	/* wrtbr */
6113e12c5d1SDavid du Colombier 				break;
6123e12c5d1SDavid du Colombier 			}
6133e12c5d1SDavid du Colombier 			o1 = OP_IRR(o1, 0, r, 0);
6143e12c5d1SDavid du Colombier 			break;
6153e12c5d1SDavid du Colombier 		}
6163e12c5d1SDavid du Colombier 		if(p->from.type == D_PREG) {
6173e12c5d1SDavid du Colombier 			r = p->to.reg;
6183e12c5d1SDavid du Colombier 			switch(p->from.reg)
6193e12c5d1SDavid du Colombier 			{
6203e12c5d1SDavid du Colombier 			default:
6213e12c5d1SDavid du Colombier 				diag("unknown register P%d", p->to.reg);
6223e12c5d1SDavid du Colombier 			case D_Y:
6233e12c5d1SDavid du Colombier 				o1 = OP2(40);	/* rdy */
6243e12c5d1SDavid du Colombier 				break;
6253e12c5d1SDavid du Colombier 			case D_PSR:
6263e12c5d1SDavid du Colombier 				o1 = OP2(41);	/* rdpsr */
6273e12c5d1SDavid du Colombier 				break;
6283e12c5d1SDavid du Colombier 			case D_WIM:
6293e12c5d1SDavid du Colombier 				o1 = OP2(42);	/* rdwim */
6303e12c5d1SDavid du Colombier 				break;
6313e12c5d1SDavid du Colombier 			case D_TBR:
6323e12c5d1SDavid du Colombier 				o1 = OP2(43);	/* rdtbr */
6333e12c5d1SDavid du Colombier 				break;
6343e12c5d1SDavid du Colombier 			}
6353e12c5d1SDavid du Colombier 			o1 = OP_RRR(o1, 0, 0, r);
6363e12c5d1SDavid du Colombier 			break;
6373e12c5d1SDavid du Colombier 		}
6383e12c5d1SDavid du Colombier 		break;
6393e12c5d1SDavid du Colombier 
6403e12c5d1SDavid du Colombier 	case 9:		/* movb r,r */
6413e12c5d1SDavid du Colombier 		v = 24;
6423e12c5d1SDavid du Colombier 		if(p->as == AMOVH || p->as == AMOVHU)
6433e12c5d1SDavid du Colombier 			v = 16;
6443e12c5d1SDavid du Colombier 		r = ASRA;
6453e12c5d1SDavid du Colombier 		if(p->as == AMOVBU || p->as == AMOVHU)
6463e12c5d1SDavid du Colombier 			r = ASRL;
6473e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(ASLL), v, p->from.reg, p->to.reg);
6483e12c5d1SDavid du Colombier 		o2 = OP_IRR(opcode(r), v, p->to.reg, p->to.reg);
6493e12c5d1SDavid du Colombier 		break;
6503e12c5d1SDavid du Colombier 
6513e12c5d1SDavid du Colombier 	case 10:	/* mov $loreg, reg */
6523e12c5d1SDavid du Colombier 		r = p->from.reg;
6533e12c5d1SDavid du Colombier 		if(r == NREG)
6543e12c5d1SDavid du Colombier 			r = o->param;
6553e12c5d1SDavid du Colombier 		v = regoff(&p->from);
6563e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
6573e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
6583e12c5d1SDavid du Colombier 		o3 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, p->to.reg);
6593e12c5d1SDavid du Colombier 		break;
6603e12c5d1SDavid du Colombier 
6613e12c5d1SDavid du Colombier 	case 11:	/* mov loreg, r */
6623e12c5d1SDavid du Colombier 		r = p->from.reg;
6633e12c5d1SDavid du Colombier 		if(r == NREG)
6643e12c5d1SDavid du Colombier 			r = o->param;
6653e12c5d1SDavid du Colombier 		v = regoff(&p->from);
6663e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
6673e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
6683e12c5d1SDavid du Colombier 		o3 = OP_IRR(opcode(p->as), (v&0x3ff), REGTMP, p->to.reg);
6693e12c5d1SDavid du Colombier 		break;
6703e12c5d1SDavid du Colombier 
6713e12c5d1SDavid du Colombier 	case 12:	/* mov r, loreg */
6723e12c5d1SDavid du Colombier 		r = p->to.reg;
6733e12c5d1SDavid du Colombier 		if(r == NREG)
6743e12c5d1SDavid du Colombier 			r = o->param;
6753e12c5d1SDavid du Colombier 		v = regoff(&p->to);
6763e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
6773e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
6783e12c5d1SDavid du Colombier 		o3 = OP_IRR(opcode(p->as+AEND), (v&0x3ff), REGTMP, p->from.reg);
6793e12c5d1SDavid du Colombier 		break;
6803e12c5d1SDavid du Colombier 
6813e12c5d1SDavid du Colombier 	case 13:	/* mov $ucon, r */
6823e12c5d1SDavid du Colombier 		v = regoff(&p->from);
6833e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (p->to.reg<<25) | ((v>>10) & 0x3fffff);	/* sethi */
6843e12c5d1SDavid du Colombier 		break;
6853e12c5d1SDavid du Colombier 
6863e12c5d1SDavid du Colombier 	case 20:	/* op $scon,r */
6873e12c5d1SDavid du Colombier 		v = regoff(&p->from);
6883e12c5d1SDavid du Colombier 		r = p->reg;
6893e12c5d1SDavid du Colombier 		if(r == NREG)
6903e12c5d1SDavid du Colombier 			r = p->to.reg;
6913e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);
6923e12c5d1SDavid du Colombier 		break;
6933e12c5d1SDavid du Colombier 
6943e12c5d1SDavid du Colombier 	case 21:	/* op r1,r2 */
6953e12c5d1SDavid du Colombier 		r = p->reg;
6963e12c5d1SDavid du Colombier 		if(r == NREG)
6973e12c5d1SDavid du Colombier 			r = p->to.reg;
6983e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);
6993e12c5d1SDavid du Colombier 		break;
7003e12c5d1SDavid du Colombier 
7013e12c5d1SDavid du Colombier 	case 22:	/* op $lcon,r */
7023e12c5d1SDavid du Colombier 		v = regoff(&p->from);
7033e12c5d1SDavid du Colombier 		r = p->reg;
7043e12c5d1SDavid du Colombier 		if(r == NREG)
7053e12c5d1SDavid du Colombier 			r = p->to.reg;
7063e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
7073e12c5d1SDavid du Colombier 		o2 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, REGTMP);
7083e12c5d1SDavid du Colombier 		o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
7093e12c5d1SDavid du Colombier 		break;
7103e12c5d1SDavid du Colombier 
7113e12c5d1SDavid du Colombier 	case 23:	/* cmp r,r */
7123e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(ASUBCC), p->to.reg, p->from.reg, REGZERO);
7133e12c5d1SDavid du Colombier 		break;
7143e12c5d1SDavid du Colombier 
7153e12c5d1SDavid du Colombier 	case 24:	/* cmp r,$c */
7163e12c5d1SDavid du Colombier 		v = regoff(&p->to);
7173e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(ASUBCC), v, p->from.reg, REGZERO);
7183e12c5d1SDavid du Colombier 		break;
7193e12c5d1SDavid du Colombier 
7203e12c5d1SDavid du Colombier 	case 25:	/* cmp $c,r BOTCH, fix compiler */
7213e12c5d1SDavid du Colombier 		v = regoff(&p->from);
7223e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(AADD), v, NREG, REGTMP);
7233e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(ASUBCC), p->to.reg, REGTMP, REGZERO);
7243e12c5d1SDavid du Colombier 		break;
7253e12c5d1SDavid du Colombier 
7263e12c5d1SDavid du Colombier 	case 26:	/* op $ucon,r */
7273e12c5d1SDavid du Colombier 		v = regoff(&p->from);
7283e12c5d1SDavid du Colombier 		r = p->reg;
7293e12c5d1SDavid du Colombier 		if(r == NREG)
7303e12c5d1SDavid du Colombier 			r = p->to.reg;
7313e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
7323e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
7333e12c5d1SDavid du Colombier 		break;
7343e12c5d1SDavid du Colombier 
7353e12c5d1SDavid du Colombier 	case 30:	/* jmp/jmpl soreg */
7363e12c5d1SDavid du Colombier 		if(aflag)
7373e12c5d1SDavid du Colombier 			return 0;
7383e12c5d1SDavid du Colombier 		v = regoff(&p->to);
7393e12c5d1SDavid du Colombier 		r = p->reg;
7403e12c5d1SDavid du Colombier 		if(r == NREG && p->as == AJMPL)
7413e12c5d1SDavid du Colombier 			r = 15;
7423e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(AJMPL), v, p->to.reg, r);
7433e12c5d1SDavid du Colombier 		break;
7443e12c5d1SDavid du Colombier 
7453e12c5d1SDavid du Colombier 	case 31:	/* ba jmp */
7463e12c5d1SDavid du Colombier 		if(aflag)
7473e12c5d1SDavid du Colombier 			return 0;
7483e12c5d1SDavid du Colombier 		r = p->as;
7493e12c5d1SDavid du Colombier 		if(r == AJMP)
7503e12c5d1SDavid du Colombier 			r = ABA;
7513e12c5d1SDavid du Colombier 		v = 0;
7523e12c5d1SDavid du Colombier 		if(p->cond)
7533e12c5d1SDavid du Colombier 			v = p->cond->pc - p->pc;
7543e12c5d1SDavid du Colombier 		o1 = OP_BRA(opcode(r), v/4);
755219b2ee8SDavid du Colombier 		if(r == ABA && p->link && p->cond && isnop(p->link)) {
7563e12c5d1SDavid du Colombier 			o2 = asmout(p->cond, oplook(p->cond), 1);
7573e12c5d1SDavid du Colombier 			if(o2) {
7583e12c5d1SDavid du Colombier 				o1 += 1;
7593e12c5d1SDavid du Colombier 				if(debug['a'])
7603e12c5d1SDavid du Colombier 					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);
7613e12c5d1SDavid du Colombier 				LPUT(o1);
7623e12c5d1SDavid du Colombier 				LPUT(o2);
7633e12c5d1SDavid du Colombier 				return 1;
7643e12c5d1SDavid du Colombier 			}
7653e12c5d1SDavid du Colombier 			/* cant set annul here because pc has already been counted */
7663e12c5d1SDavid du Colombier 		}
7673e12c5d1SDavid du Colombier 		break;
7683e12c5d1SDavid du Colombier 
7693e12c5d1SDavid du Colombier 	case 32:	/* jmpl lbra */
7703e12c5d1SDavid du Colombier 		if(aflag)
7713e12c5d1SDavid du Colombier 			return 0;
7723e12c5d1SDavid du Colombier 		v = 0;
7733e12c5d1SDavid du Colombier 		if(p->cond)
7743e12c5d1SDavid du Colombier 			v = p->cond->pc - p->pc;
7753e12c5d1SDavid du Colombier 		r = p->reg;
7763e12c5d1SDavid du Colombier 		if(r != NREG && r != 15)
7776b6b9ac8SDavid du Colombier 			diag("cant jmpl other than R15");
7783e12c5d1SDavid du Colombier 		o1 = 0x40000000 | ((v/4) & 0x3fffffffL);	/* call */
779219b2ee8SDavid du Colombier 		if(p->link && p->cond && isnop(p->link)) {
7803e12c5d1SDavid du Colombier 			o2 = asmout(p->cond, oplook(p->cond), 1);
7813e12c5d1SDavid du Colombier 			if(o2) {
7823e12c5d1SDavid du Colombier 				o1 += 1;
7833e12c5d1SDavid du Colombier 				if(debug['a'])
7843e12c5d1SDavid du Colombier 					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);
7853e12c5d1SDavid du Colombier 				LPUT(o1);
7863e12c5d1SDavid du Colombier 				LPUT(o2);
7873e12c5d1SDavid du Colombier 				return 1;
7883e12c5d1SDavid du Colombier 			}
7893e12c5d1SDavid du Colombier 		}
7903e12c5d1SDavid du Colombier 		break;
7913e12c5d1SDavid du Colombier 
7923e12c5d1SDavid du Colombier 	case 33:	/* trap r */
7933e12c5d1SDavid du Colombier 		if(aflag)
7943e12c5d1SDavid du Colombier 			return 0;
7953e12c5d1SDavid du Colombier 		o1 = opcode(p->as) | (p->from.reg<<14);
7963e12c5d1SDavid du Colombier 		break;
7973e12c5d1SDavid du Colombier 
7983e12c5d1SDavid du Colombier 	case 34:	/* rett r1,r2 -> jmpl (r1); rett (r2) */
7993e12c5d1SDavid du Colombier 		if(aflag)
8003e12c5d1SDavid du Colombier 			return 0;
8013e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(AJMPL), 0, p->from.reg, REGZERO);
8023e12c5d1SDavid du Colombier 		o2 = OP_IRR(opcode(ARETT), 0, p->to.reg, REGZERO);
8033e12c5d1SDavid du Colombier 		break;
8043e12c5d1SDavid du Colombier 
8053e12c5d1SDavid du Colombier 	case 40:	/* ldfsr, stfsr, stdq */
8063e12c5d1SDavid du Colombier 		if(p->to.type == D_PREG) {
8073e12c5d1SDavid du Colombier 			r = p->from.reg;
8083e12c5d1SDavid du Colombier 			if(r == NREG)
8093e12c5d1SDavid du Colombier 				r = o->param;
8103e12c5d1SDavid du Colombier 			v = regoff(&p->from);
8113e12c5d1SDavid du Colombier 			if(p->to.reg == D_FSR) {
8123e12c5d1SDavid du Colombier 				o1 = OP_IRR(OP3(33), v, r, 0);
8133e12c5d1SDavid du Colombier 				break;
8143e12c5d1SDavid du Colombier 			}
8153e12c5d1SDavid du Colombier 			diag("unknown reg load %d", p->to.reg);
8163e12c5d1SDavid du Colombier 		} else {
8173e12c5d1SDavid du Colombier 			r = p->to.reg;
8183e12c5d1SDavid du Colombier 			if(r == NREG)
8193e12c5d1SDavid du Colombier 				r = o->param;
8203e12c5d1SDavid du Colombier 			v = regoff(&p->to);
8213e12c5d1SDavid du Colombier 			if(p->from.reg == D_FSR) {
8223e12c5d1SDavid du Colombier 				o1 = OP_IRR(OP3(37), v, r, 0);
8233e12c5d1SDavid du Colombier 				break;
8243e12c5d1SDavid du Colombier 			}
8253e12c5d1SDavid du Colombier 			if(p->as == AMOVD && p->from.reg == D_FPQ) {
8263e12c5d1SDavid du Colombier 				o1 = OP_IRR(OP3(38), v, r, 0);
8273e12c5d1SDavid du Colombier 				break;
8283e12c5d1SDavid du Colombier 			}
8293e12c5d1SDavid du Colombier 			diag("unknown reg store %d", p->from.reg);
8303e12c5d1SDavid du Colombier 		}
8313e12c5d1SDavid du Colombier 		break;
8323e12c5d1SDavid du Colombier 
8333e12c5d1SDavid du Colombier 	case 41:	/* ldf,ldd */
8343e12c5d1SDavid du Colombier 		r = p->from.reg;
8353e12c5d1SDavid du Colombier 		if(r == NREG)
8363e12c5d1SDavid du Colombier 			r = o->param;
8373e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8383e12c5d1SDavid du Colombier 		if(p->as == AFMOVF || p->as == AMOVW) {
8393e12c5d1SDavid du Colombier 			o1 = OP_IRR(OP3(32), v, r, p->to.reg);
8403e12c5d1SDavid du Colombier 			break;
8413e12c5d1SDavid du Colombier 		}
8423e12c5d1SDavid du Colombier 		if(p->as == AMOVD || p->as == AFMOVD) {
8433e12c5d1SDavid du Colombier 			o1 = OP_IRR(OP3(35), v, r, p->to.reg);
8443e12c5d1SDavid du Colombier 			break;
8453e12c5d1SDavid du Colombier 		}
8463e12c5d1SDavid du Colombier 		diag("only MOVD and MOVW to FREG");
8473e12c5d1SDavid du Colombier 		break;
8483e12c5d1SDavid du Colombier 
8493e12c5d1SDavid du Colombier 	case 42:	/* ldd -> ldf,ldf */
8503e12c5d1SDavid du Colombier 		/* note should be ldd with proper allignment */
8513e12c5d1SDavid du Colombier 		r = p->from.reg;
8523e12c5d1SDavid du Colombier 		if(r == NREG)
8533e12c5d1SDavid du Colombier 			r = o->param;
8543e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8553e12c5d1SDavid du Colombier 		o1 = OP_IRR(OP3(32), v, r, p->to.reg);
8563e12c5d1SDavid du Colombier 		o2 = OP_IRR(OP3(32), v+4, r, p->to.reg+1);
8573e12c5d1SDavid du Colombier 		break;
8583e12c5d1SDavid du Colombier 
8593e12c5d1SDavid du Colombier 	case 43:	/* stf */
8603e12c5d1SDavid du Colombier 		r = p->to.reg;
8613e12c5d1SDavid du Colombier 		if(r == NREG)
8623e12c5d1SDavid du Colombier 			r = o->param;
8633e12c5d1SDavid du Colombier 		v = regoff(&p->to);
8643e12c5d1SDavid du Colombier 		if(p->as == AFMOVF || p->as == AMOVW) {
8653e12c5d1SDavid du Colombier 			o1 = OP_IRR(OP3(36), v, r, p->from.reg);
8663e12c5d1SDavid du Colombier 			break;
8673e12c5d1SDavid du Colombier 		}
8683e12c5d1SDavid du Colombier 		if(p->as == AMOVD || p->as == AFMOVD) {
8693e12c5d1SDavid du Colombier 			o1 = OP_IRR(OP3(39), v, r, p->from.reg);
8703e12c5d1SDavid du Colombier 			break;
8713e12c5d1SDavid du Colombier 		}
8723e12c5d1SDavid du Colombier 		diag("only MOVD and MOVW from FREG");
8733e12c5d1SDavid du Colombier 		break;
8743e12c5d1SDavid du Colombier 
8753e12c5d1SDavid du Colombier 	case 44:	/* std -> stf,stf */
8763e12c5d1SDavid du Colombier 		/* note should be std with proper allignment */
8773e12c5d1SDavid du Colombier 		r = p->to.reg;
8783e12c5d1SDavid du Colombier 		if(r == NREG)
8793e12c5d1SDavid du Colombier 			r = o->param;
8803e12c5d1SDavid du Colombier 		v = regoff(&p->to);
8813e12c5d1SDavid du Colombier 		o1 = OP_IRR(OP3(36), v, r, p->from.reg);
8823e12c5d1SDavid du Colombier 		o2 = OP_IRR(OP3(36), v+4, r, p->from.reg+1);
8833e12c5d1SDavid du Colombier 		break;
8843e12c5d1SDavid du Colombier 
8853e12c5d1SDavid du Colombier 	case 45:	/* ldf lorg */
8863e12c5d1SDavid du Colombier 		r = p->from.reg;
8873e12c5d1SDavid du Colombier 		if(r == NREG)
8883e12c5d1SDavid du Colombier 			r = o->param;
8893e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8903e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
8913e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
8923e12c5d1SDavid du Colombier 		o3 = OP_IRR(OP3(32), v&0x3ff, REGTMP, p->to.reg);
8933e12c5d1SDavid du Colombier 		break;
8943e12c5d1SDavid du Colombier 
8953e12c5d1SDavid du Colombier 	case 46:	/* ldd lorg -> ldf,ldf */
8963e12c5d1SDavid du Colombier 		/* note should be ldd with proper allignment */
8973e12c5d1SDavid du Colombier 		r = p->from.reg;
8983e12c5d1SDavid du Colombier 		if(r == NREG)
8993e12c5d1SDavid du Colombier 			r = o->param;
9003e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9013e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
9023e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
9033e12c5d1SDavid du Colombier 		o3 = OP_IRR(OP3(32), (v&0x3ff), REGTMP, p->to.reg);
9043e12c5d1SDavid du Colombier 		o4 = OP_IRR(OP3(32), (v&0x3ff)+4, REGTMP, p->to.reg+1);
9053e12c5d1SDavid du Colombier 		break;
9063e12c5d1SDavid du Colombier 
9073e12c5d1SDavid du Colombier 	case 47:	/* stf lorg */
9083e12c5d1SDavid du Colombier 		r = p->to.reg;
9093e12c5d1SDavid du Colombier 		if(r == NREG)
9103e12c5d1SDavid du Colombier 			r = o->param;
9113e12c5d1SDavid du Colombier 		v = regoff(&p->to);
9123e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
9133e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
9143e12c5d1SDavid du Colombier 		o3 = OP_IRR(OP3(36), v&0x3ff, REGTMP, p->from.reg);
9153e12c5d1SDavid du Colombier 		break;
9163e12c5d1SDavid du Colombier 
9173e12c5d1SDavid du Colombier 	case 48:	/* std lorg -> stf,stf */
9183e12c5d1SDavid du Colombier 		/* note should be std with proper allignment */
9193e12c5d1SDavid du Colombier 		r = p->to.reg;
9203e12c5d1SDavid du Colombier 		if(r == NREG)
9213e12c5d1SDavid du Colombier 			r = o->param;
9223e12c5d1SDavid du Colombier 		v = regoff(&p->to);
9233e12c5d1SDavid du Colombier 		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */
9243e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
9253e12c5d1SDavid du Colombier 		o3 = OP_IRR(OP3(36), (v&0x3ff), REGTMP, p->from.reg);
9263e12c5d1SDavid du Colombier 		o4 = OP_IRR(OP3(36), (v&0x3ff)+4, REGTMP, p->from.reg+1);
9273e12c5d1SDavid du Colombier 		break;
9283e12c5d1SDavid du Colombier 
9293e12c5d1SDavid du Colombier 	case 49:	/* fmovd -> fmovf,fmovf */
9303e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(AFMOVF), p->from.reg, 0, p->to.reg);
9313e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(AFMOVF), p->from.reg+1, 0, p->to.reg+1);
9323e12c5d1SDavid du Colombier 		break;
9333e12c5d1SDavid du Colombier 
9343e12c5d1SDavid du Colombier 	case 50:	/* fcmp */
9353e12c5d1SDavid du Colombier 		o1 = OP_RRR(opcode(p->as), p->to.reg, p->from.reg, 0);
9363e12c5d1SDavid du Colombier 		break;
9373e12c5d1SDavid du Colombier 
9383e12c5d1SDavid du Colombier 	case 51:	/* word */
9393e12c5d1SDavid du Colombier 		if(aflag)
9403e12c5d1SDavid du Colombier 			return 0;
9413e12c5d1SDavid du Colombier 		o1 = regoff(&p->from);
9423e12c5d1SDavid du Colombier 		break;
9433e12c5d1SDavid du Colombier 
9443e12c5d1SDavid du Colombier 	case 52:	/* div */
9453e12c5d1SDavid du Colombier 		r = p->reg;
9463e12c5d1SDavid du Colombier 		if(r == NREG)
9473e12c5d1SDavid du Colombier 			r = p->to.reg;
9483e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP);
9493e12c5d1SDavid du Colombier 		o2 = OP_IRR(OP2(48), 0, REGTMP, 0);
9503e12c5d1SDavid du Colombier 		o3 = OP_RRR(opcode(ADIV), p->from.reg, r, p->to.reg);
9513e12c5d1SDavid du Colombier 		break;
9523e12c5d1SDavid du Colombier 
9533e12c5d1SDavid du Colombier 	case 53:	/* divl */
9543e12c5d1SDavid du Colombier 		r = p->reg;
9553e12c5d1SDavid du Colombier 		if(r == NREG)
9563e12c5d1SDavid du Colombier 			r = p->to.reg;
9573e12c5d1SDavid du Colombier 		o1 = OP_IRR(OP2(48), 0, REGZERO, 0);
9583e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, p->to.reg);
9593e12c5d1SDavid du Colombier 		break;
9603e12c5d1SDavid du Colombier 
9613e12c5d1SDavid du Colombier 	case 54:	/* mod */
9623e12c5d1SDavid du Colombier 		r = p->reg;
9633e12c5d1SDavid du Colombier 		if(r == NREG)
9643e12c5d1SDavid du Colombier 			r = p->to.reg;
9653e12c5d1SDavid du Colombier 		o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP);
9663e12c5d1SDavid du Colombier 		o2 = OP_IRR(OP2(48), 0, REGTMP, 0);
9673e12c5d1SDavid du Colombier 		o3 = OP_RRR(opcode(ADIV), p->from.reg, r, REGTMP);
9683e12c5d1SDavid du Colombier 		o4 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP);
9693e12c5d1SDavid du Colombier 		o5 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg);
9703e12c5d1SDavid du Colombier 		break;
9713e12c5d1SDavid du Colombier 
9723e12c5d1SDavid du Colombier 	case 55:	/* modl */
9733e12c5d1SDavid du Colombier 		r = p->reg;
9743e12c5d1SDavid du Colombier 		if(r == NREG)
9753e12c5d1SDavid du Colombier 			r = p->to.reg;
9763e12c5d1SDavid du Colombier 		o1 = OP_IRR(OP2(48), 0, REGZERO, 0);
9773e12c5d1SDavid du Colombier 		o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, REGTMP);
9783e12c5d1SDavid du Colombier 		o3 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP);
9793e12c5d1SDavid du Colombier 		o4 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg);
9803e12c5d1SDavid du Colombier 		break;
9813e12c5d1SDavid du Colombier 
9823e12c5d1SDavid du Colombier 	case 56:	/* b(cc) -- annullable */
9833e12c5d1SDavid du Colombier 		if(aflag)
9843e12c5d1SDavid du Colombier 			return 0;
9853e12c5d1SDavid du Colombier 		r = p->as;
9863e12c5d1SDavid du Colombier 		v = 0;
9873e12c5d1SDavid du Colombier 		if(p->cond)
9883e12c5d1SDavid du Colombier 			v = p->cond->pc - p->pc;
9893e12c5d1SDavid du Colombier 		o1 = OP_BRA(opcode(r), v/4);
990219b2ee8SDavid du Colombier 		if(p->link && p->cond && isnop(p->link))
9913e12c5d1SDavid du Colombier 		if(!debug['A']) {
9923e12c5d1SDavid du Colombier 			o2 = asmout(p->cond, oplook(p->cond), 2);
9933e12c5d1SDavid du Colombier 			if(o2) {
9943e12c5d1SDavid du Colombier 				o1 |= 1<<29;	/* annul */
9953e12c5d1SDavid du Colombier 				o1 += 1;
9963e12c5d1SDavid du Colombier 				if(debug['a'])
9973e12c5d1SDavid du Colombier 					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);
9983e12c5d1SDavid du Colombier 				LPUT(o1);
9993e12c5d1SDavid du Colombier 				LPUT(o2);
10003e12c5d1SDavid du Colombier 				return 1;
10013e12c5d1SDavid du Colombier 			}
10023e12c5d1SDavid du Colombier 		}
10033e12c5d1SDavid du Colombier 		break;
1004a83436dfSDavid du Colombier 
1005a83436dfSDavid du Colombier 	case 57:	/* op r1,r2 with reserved rs1 */
1006a83436dfSDavid du Colombier 		r = 0;
1007a83436dfSDavid du Colombier 		o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);
1008a83436dfSDavid du Colombier 		break;
10093e12c5d1SDavid du Colombier 	}
10103e12c5d1SDavid du Colombier 	if(aflag)
10113e12c5d1SDavid du Colombier 		return o1;
10123e12c5d1SDavid du Colombier 	v = p->pc;
10133e12c5d1SDavid du Colombier 	switch(o->size) {
10143e12c5d1SDavid du Colombier 	default:
10153e12c5d1SDavid du Colombier 		if(debug['a'])
10163e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
10173e12c5d1SDavid du Colombier 		break;
10183e12c5d1SDavid du Colombier 	case 4:
10193e12c5d1SDavid du Colombier 		if(debug['a'])
10203e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
10213e12c5d1SDavid du Colombier 		LPUT(o1);
10223e12c5d1SDavid du Colombier 		break;
10233e12c5d1SDavid du Colombier 	case 8:
10243e12c5d1SDavid du Colombier 		if(debug['a'])
10253e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
10263e12c5d1SDavid du Colombier 		LPUT(o1);
10273e12c5d1SDavid du Colombier 		LPUT(o2);
10283e12c5d1SDavid du Colombier 		break;
10293e12c5d1SDavid du Colombier 	case 12:
10303e12c5d1SDavid du Colombier 		if(debug['a'])
10313e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
10323e12c5d1SDavid du Colombier 		LPUT(o1);
10333e12c5d1SDavid du Colombier 		LPUT(o2);
10343e12c5d1SDavid du Colombier 		LPUT(o3);
10353e12c5d1SDavid du Colombier 		break;
10363e12c5d1SDavid du Colombier 	case 16:
10373e12c5d1SDavid du Colombier 		if(debug['a'])
10383e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
10393e12c5d1SDavid du Colombier 				v, o1, o2, o3, o4, p);
10403e12c5d1SDavid du Colombier 		LPUT(o1);
10413e12c5d1SDavid du Colombier 		LPUT(o2);
10423e12c5d1SDavid du Colombier 		LPUT(o3);
10433e12c5d1SDavid du Colombier 		LPUT(o4);
10443e12c5d1SDavid du Colombier 		break;
10453e12c5d1SDavid du Colombier 	case 20:
10463e12c5d1SDavid du Colombier 		if(debug['a'])
10473e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
10483e12c5d1SDavid du Colombier 				v, o1, o2, o3, o4, o5, p);
10493e12c5d1SDavid du Colombier 		LPUT(o1);
10503e12c5d1SDavid du Colombier 		LPUT(o2);
10513e12c5d1SDavid du Colombier 		LPUT(o3);
10523e12c5d1SDavid du Colombier 		LPUT(o4);
10533e12c5d1SDavid du Colombier 		LPUT(o5);
10543e12c5d1SDavid du Colombier 		break;
10553e12c5d1SDavid du Colombier 	}
10563e12c5d1SDavid du Colombier 	return 0;
10573e12c5d1SDavid du Colombier }
10583e12c5d1SDavid du Colombier 
1059219b2ee8SDavid du Colombier int
isnop(Prog * p)1060219b2ee8SDavid du Colombier isnop(Prog *p)
1061219b2ee8SDavid du Colombier {
1062219b2ee8SDavid du Colombier 	if(p->as != AORN)
1063219b2ee8SDavid du Colombier 		return 0;
1064219b2ee8SDavid du Colombier 	if(p->reg != REGZERO && p->reg != NREG)
1065219b2ee8SDavid du Colombier 		return 0;
1066219b2ee8SDavid du Colombier 	if(p->from.type != D_REG || p->from.reg != REGZERO)
1067219b2ee8SDavid du Colombier 		return 0;
1068219b2ee8SDavid du Colombier 	if(p->to.type != D_REG || p->to.reg != REGZERO)
1069219b2ee8SDavid du Colombier 		return 0;
1070219b2ee8SDavid du Colombier 	return 1;
1071219b2ee8SDavid du Colombier }
1072219b2ee8SDavid du Colombier 
10733e12c5d1SDavid du Colombier long
opcode(int a)10743e12c5d1SDavid du Colombier opcode(int a)
10753e12c5d1SDavid du Colombier {
10763e12c5d1SDavid du Colombier 	switch(a) {
10773e12c5d1SDavid du Colombier 	case AADD:	return OP2(0);
10783e12c5d1SDavid du Colombier 	case AADDCC:	return OP2(16);
10793e12c5d1SDavid du Colombier 	case AADDX:	return OP2(8);
10803e12c5d1SDavid du Colombier 	case AADDXCC:	return OP2(24);
10813e12c5d1SDavid du Colombier 
10823e12c5d1SDavid du Colombier 	case AMUL:	return OP2(10);
10833e12c5d1SDavid du Colombier 	case ADIV:	return OP2(15);
10843e12c5d1SDavid du Colombier 	case ADIVL:	return OP2(14);
10853e12c5d1SDavid du Colombier 
10863e12c5d1SDavid du Colombier 	case ATADDCC:	return OP2(32);
10873e12c5d1SDavid du Colombier 	case ATADDCCTV:	return OP2(34);
10883e12c5d1SDavid du Colombier 
10893e12c5d1SDavid du Colombier 	case ASUB:	return OP2(4);
10903e12c5d1SDavid du Colombier 	case ASUBCC:	return OP2(20);
10913e12c5d1SDavid du Colombier 	case ASUBX:	return OP2(12);
10923e12c5d1SDavid du Colombier 	case ASUBXCC:	return OP2(28);
10933e12c5d1SDavid du Colombier 
10943e12c5d1SDavid du Colombier 	case ATSUBCC:	return OP2(33);
10953e12c5d1SDavid du Colombier 	case ATSUBCCTV:	return OP2(35);
10963e12c5d1SDavid du Colombier 
10973e12c5d1SDavid du Colombier 	case AMULSCC:	return OP2(36);
10983e12c5d1SDavid du Colombier 	case ASAVE:	return OP2(60);
10993e12c5d1SDavid du Colombier 	case ARESTORE:	return OP2(61);
11003e12c5d1SDavid du Colombier 
11013e12c5d1SDavid du Colombier 	case AAND:	return OP2(1);
11023e12c5d1SDavid du Colombier 	case AANDCC:	return OP2(17);
11033e12c5d1SDavid du Colombier 	case AANDN:	return OP2(5);
11043e12c5d1SDavid du Colombier 	case AANDNCC:	return OP2(21);
11053e12c5d1SDavid du Colombier 
11063e12c5d1SDavid du Colombier 	case AOR:	return OP2(2);
11073e12c5d1SDavid du Colombier 	case AORCC:	return OP2(18);
11083e12c5d1SDavid du Colombier 	case AORN:	return OP2(6);
11093e12c5d1SDavid du Colombier 	case AORNCC:	return OP2(22);
11103e12c5d1SDavid du Colombier 
11113e12c5d1SDavid du Colombier 	case AXOR:	return OP2(3);
11123e12c5d1SDavid du Colombier 	case AXORCC:	return OP2(19);
11133e12c5d1SDavid du Colombier 	case AXNOR:	return OP2(7);
11143e12c5d1SDavid du Colombier 	case AXNORCC:	return OP2(23);
11153e12c5d1SDavid du Colombier 
11163e12c5d1SDavid du Colombier 	case ASLL:	return OP2(37);
11173e12c5d1SDavid du Colombier 	case ASRL:	return OP2(38);
11183e12c5d1SDavid du Colombier 	case ASRA:	return OP2(39);
11193e12c5d1SDavid du Colombier 
11203e12c5d1SDavid du Colombier 	case AJMPL:
11213e12c5d1SDavid du Colombier 	case AJMP:	return OP2(56);
11223e12c5d1SDavid du Colombier 	case ARETT:	return OP2(57);
11233e12c5d1SDavid du Colombier 
11243e12c5d1SDavid du Colombier 	case AMOVBU:	return OP3(1);	/* ldub */
11253e12c5d1SDavid du Colombier 	case AMOVB:	return OP3(9);	/* ldsb */
11263e12c5d1SDavid du Colombier 	case AMOVHU:	return OP3(2);	/* lduh */
11273e12c5d1SDavid du Colombier 	case AMOVH:	return OP3(10);	/* ldsh */
11283e12c5d1SDavid du Colombier 	case AMOVW:	return OP3(0);	/* ld */
11293e12c5d1SDavid du Colombier 	case AMOVD:	return OP3(3);	/* ldd */
11303e12c5d1SDavid du Colombier 
11313e12c5d1SDavid du Colombier 	case AMOVBU+AEND:
11323e12c5d1SDavid du Colombier 	case AMOVB+AEND:return OP3(5);	/* stb */
11333e12c5d1SDavid du Colombier 
11343e12c5d1SDavid du Colombier 	case AMOVHU+AEND:
11353e12c5d1SDavid du Colombier 	case AMOVH+AEND:return OP3(6);	/* sth */
11363e12c5d1SDavid du Colombier 
11373e12c5d1SDavid du Colombier 	case AMOVW+AEND:return OP3(4);	/* st */
11383e12c5d1SDavid du Colombier 
11393e12c5d1SDavid du Colombier 	case AMOVD+AEND:return OP3(7);	/* std */
11403e12c5d1SDavid du Colombier 
11413e12c5d1SDavid du Colombier 	case ASWAP:			/* swap is symmetric */
11423e12c5d1SDavid du Colombier 	case ASWAP+AEND:return OP3(15);
11433e12c5d1SDavid du Colombier 
11443e12c5d1SDavid du Colombier 	case ATAS:	return OP3(13);	/* tas is really ldstub */
11453e12c5d1SDavid du Colombier 
11463e12c5d1SDavid du Colombier 	case ABN:	return OPB(0);
11473e12c5d1SDavid du Colombier 	case ABE:	return OPB(1);
11483e12c5d1SDavid du Colombier 	case ABLE:	return OPB(2);
11493e12c5d1SDavid du Colombier 	case ABL:	return OPB(3);
11503e12c5d1SDavid du Colombier 	case ABLEU:	return OPB(4);
11513e12c5d1SDavid du Colombier 	case ABCS:	return OPB(5);
11523e12c5d1SDavid du Colombier 	case ABNEG:	return OPB(6);
11533e12c5d1SDavid du Colombier 	case ABVS:	return OPB(7);
11543e12c5d1SDavid du Colombier 	case ABA:	return OPB(8);
11553e12c5d1SDavid du Colombier 	case ABNE:	return OPB(9);
11563e12c5d1SDavid du Colombier 	case ABG:	return OPB(10);
11573e12c5d1SDavid du Colombier 	case ABGE:	return OPB(11);
11583e12c5d1SDavid du Colombier 	case ABGU:	return OPB(12);
11593e12c5d1SDavid du Colombier 	case ABCC:	return OPB(13);
11603e12c5d1SDavid du Colombier 	case ABPOS:	return OPB(14);
11613e12c5d1SDavid du Colombier 	case ABVC:	return OPB(15);
11623e12c5d1SDavid du Colombier 
11633e12c5d1SDavid du Colombier 	case AFBA:	return OPFB(8);
11643e12c5d1SDavid du Colombier 	case AFBE:	return OPFB(9);
11653e12c5d1SDavid du Colombier 	case AFBG:	return OPFB(6);
11663e12c5d1SDavid du Colombier 	case AFBGE:	return OPFB(11);
11673e12c5d1SDavid du Colombier 	case AFBL:	return OPFB(4);
11683e12c5d1SDavid du Colombier 	case AFBLE:	return OPFB(13);
11693e12c5d1SDavid du Colombier 	case AFBLG:	return OPFB(2);
11703e12c5d1SDavid du Colombier 	case AFBN:	return OPFB(0);
11713e12c5d1SDavid du Colombier 	case AFBNE:	return OPFB(1);
11723e12c5d1SDavid du Colombier 	case AFBO:	return OPFB(15);
11733e12c5d1SDavid du Colombier 	case AFBU:	return OPFB(7);
11743e12c5d1SDavid du Colombier 	case AFBUE:	return OPFB(10);
11753e12c5d1SDavid du Colombier 	case AFBUG:	return OPFB(5);
11763e12c5d1SDavid du Colombier 	case AFBUGE:	return OPFB(12);
11773e12c5d1SDavid du Colombier 	case AFBUL:	return OPFB(3);
11783e12c5d1SDavid du Colombier 	case AFBULE:	return OPFB(14);
11793e12c5d1SDavid du Colombier 
11803e12c5d1SDavid du Colombier 	case ATN:	return OPT(0);
11813e12c5d1SDavid du Colombier 	case ATE:	return OPT(1);
11823e12c5d1SDavid du Colombier 	case ATLE:	return OPT(2);
11833e12c5d1SDavid du Colombier 	case ATL:	return OPT(3);
11843e12c5d1SDavid du Colombier 	case ATLEU:	return OPT(4);
11853e12c5d1SDavid du Colombier 	case ATCS:	return OPT(5);
11863e12c5d1SDavid du Colombier 	case ATNEG:	return OPT(6);
11873e12c5d1SDavid du Colombier 	case ATVS:	return OPT(7);
11883e12c5d1SDavid du Colombier 	case ATA:	return OPT(8);
11893e12c5d1SDavid du Colombier 	case ATNE:	return OPT(9);
11903e12c5d1SDavid du Colombier 	case ATG:	return OPT(10);
11913e12c5d1SDavid du Colombier 	case ATGE:	return OPT(11);
11923e12c5d1SDavid du Colombier 	case ATGU:	return OPT(12);
11933e12c5d1SDavid du Colombier 	case ATCC:	return OPT(13);
11943e12c5d1SDavid du Colombier 	case ATPOS:	return OPT(14);
11953e12c5d1SDavid du Colombier 	case ATVC:	return OPT(15);
11963e12c5d1SDavid du Colombier 
11973e12c5d1SDavid du Colombier 	case AFADDF:	return OPF1(65);
11983e12c5d1SDavid du Colombier 	case AFADDD:	return OPF1(66);
11993e12c5d1SDavid du Colombier 	case AFADDX:	return OPF1(67);
12003e12c5d1SDavid du Colombier 	case AFSUBF:	return OPF1(69);
12013e12c5d1SDavid du Colombier 	case AFSUBD:	return OPF1(70);
12023e12c5d1SDavid du Colombier 	case AFSUBX:	return OPF1(71);
12033e12c5d1SDavid du Colombier 	case AFMULF:	return OPF1(73);
12043e12c5d1SDavid du Colombier 	case AFMULD:	return OPF1(74);
12053e12c5d1SDavid du Colombier 	case AFMULX:	return OPF1(75);
12063e12c5d1SDavid du Colombier 	case AFDIVF:	return OPF1(77);
12073e12c5d1SDavid du Colombier 	case AFDIVD:	return OPF1(78);
12083e12c5d1SDavid du Colombier 	case AFDIVX:	return OPF1(79);
12093e12c5d1SDavid du Colombier 
12103e12c5d1SDavid du Colombier 	case AFMOVF:	return OPF1(1);
12113e12c5d1SDavid du Colombier 	case AFNEGF:	return OPF1(5);
12123e12c5d1SDavid du Colombier 	case AFABSF:	return OPF1(9);
12133e12c5d1SDavid du Colombier 
1214219b2ee8SDavid du Colombier 	case AFSQRTF:	return OPF1(41);
1215219b2ee8SDavid du Colombier 	case AFSQRTD:	return OPF1(42);
1216219b2ee8SDavid du Colombier 	case AFSQRTX:	return OPF1(43);
1217219b2ee8SDavid du Colombier 
12183e12c5d1SDavid du Colombier 	case AFMOVWF:	return OPF1(196);
12193e12c5d1SDavid du Colombier 	case AFMOVWD:	return OPF1(200);
12203e12c5d1SDavid du Colombier 	case AFMOVWX:	return OPF1(204);
12213e12c5d1SDavid du Colombier 	case AFMOVFW:	return OPF1(209);
12223e12c5d1SDavid du Colombier 	case AFMOVDW:	return OPF1(210);
12233e12c5d1SDavid du Colombier 	case AFMOVXW:	return OPF1(211);
12243e12c5d1SDavid du Colombier 	case AFMOVFD:	return OPF1(201);
12253e12c5d1SDavid du Colombier 	case AFMOVFX:	return OPF1(205);
12263e12c5d1SDavid du Colombier 	case AFMOVDF:	return OPF1(198);
12273e12c5d1SDavid du Colombier 	case AFMOVDX:	return OPF1(206);
12283e12c5d1SDavid du Colombier 	case AFMOVXF:	return OPF1(199);
12293e12c5d1SDavid du Colombier 	case AFMOVXD:	return OPF1(203);
12303e12c5d1SDavid du Colombier 
12313e12c5d1SDavid du Colombier 	case AFCMPF:	return OPF2(81);
12323e12c5d1SDavid du Colombier 	case AFCMPD:	return OPF2(82);
12333e12c5d1SDavid du Colombier 	case AFCMPX:	return OPF2(83);
12343e12c5d1SDavid du Colombier 	case AFCMPEF:	return OPF2(85);
12353e12c5d1SDavid du Colombier 	case AFCMPED:	return OPF2(86);
12363e12c5d1SDavid du Colombier 	case AFCMPEX:	return OPF2(87);
12373e12c5d1SDavid du Colombier 
12383e12c5d1SDavid du Colombier 	case AUNIMP:	return 0;
12393e12c5d1SDavid du Colombier 	}
12406b6b9ac8SDavid du Colombier 	diag("bad opcode %A", a);
12413e12c5d1SDavid du Colombier 	return 0;
12423e12c5d1SDavid du Colombier }
1243