xref: /plan9/sys/src/cmd/vl/asm.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
3bd389b36SDavid du Colombier long	OFFSET;
4bd389b36SDavid du Colombier /*
5bd389b36SDavid du Colombier long	BADOFFSET	=	-1;
6bd389b36SDavid du Colombier 
7bd389b36SDavid du Colombier 		if(OFFSET <= BADOFFSET && OFFSET+4 > BADOFFSET)\
8bd389b36SDavid du Colombier 			abort();\
9bd389b36SDavid du Colombier 		OFFSET += 4;\
10bd389b36SDavid du Colombier 
11bd389b36SDavid du Colombier 		if(OFFSET == BADOFFSET)\
12bd389b36SDavid du Colombier 			abort();\
13bd389b36SDavid du Colombier 		OFFSET++;\
14bd389b36SDavid du Colombier */
15bd389b36SDavid du Colombier 
163e12c5d1SDavid du Colombier #define	LPUT(c)\
173e12c5d1SDavid du Colombier 	{\
183e12c5d1SDavid du Colombier 		cbp[0] = (c)>>24;\
193e12c5d1SDavid du Colombier 		cbp[1] = (c)>>16;\
203e12c5d1SDavid du Colombier 		cbp[2] = (c)>>8;\
213e12c5d1SDavid du Colombier 		cbp[3] = (c);\
223e12c5d1SDavid du Colombier 		cbp += 4;\
233e12c5d1SDavid du Colombier 		cbc -= 4;\
243e12c5d1SDavid du Colombier 		if(cbc <= 0)\
253e12c5d1SDavid du Colombier 			cflush();\
263e12c5d1SDavid du Colombier 	}
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier #define	CPUT(c)\
293e12c5d1SDavid du Colombier 	{\
303e12c5d1SDavid du Colombier 		cbp[0] = (c);\
313e12c5d1SDavid du Colombier 		cbp++;\
323e12c5d1SDavid du Colombier 		cbc--;\
333e12c5d1SDavid du Colombier 		if(cbc <= 0)\
343e12c5d1SDavid du Colombier 			cflush();\
353e12c5d1SDavid du Colombier 	}
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier long
383e12c5d1SDavid du Colombier entryvalue(void)
393e12c5d1SDavid du Colombier {
403e12c5d1SDavid du Colombier 	char *a;
413e12c5d1SDavid du Colombier 	Sym *s;
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier 	a = INITENTRY;
443e12c5d1SDavid du Colombier 	if(*a >= '0' && *a <= '9')
453e12c5d1SDavid du Colombier 		return atolwhex(a);
463e12c5d1SDavid du Colombier 	s = lookup(a, 0);
473e12c5d1SDavid du Colombier 	if(s->type == 0)
483e12c5d1SDavid du Colombier 		return INITTEXT;
493e12c5d1SDavid du Colombier 	if(s->type != STEXT && s->type != SLEAF)
503e12c5d1SDavid du Colombier 		diag("entry not text: %s", s->name);
513e12c5d1SDavid du Colombier 	return s->value;
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier 
543e12c5d1SDavid du Colombier void
553e12c5d1SDavid du Colombier asmb(void)
563e12c5d1SDavid du Colombier {
573e12c5d1SDavid du Colombier 	Prog *p;
583e12c5d1SDavid du Colombier 	long t;
593e12c5d1SDavid du Colombier 	Optab *o;
603e12c5d1SDavid du Colombier 
613e12c5d1SDavid du Colombier 	if(debug['v'])
623e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f asm\n", cputime());
633e12c5d1SDavid du Colombier 	Bflush(&bso);
64bd389b36SDavid du Colombier 	OFFSET = HEADR;
65bd389b36SDavid du Colombier 	seek(cout, OFFSET, 0);
663e12c5d1SDavid du Colombier 	pc = INITTEXT;
673e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
683e12c5d1SDavid du Colombier 		if(p->as == ATEXT) {
693e12c5d1SDavid du Colombier 			curtext = p;
703e12c5d1SDavid du Colombier 			autosize = p->to.offset + 4;
713e12c5d1SDavid du Colombier 		}
723e12c5d1SDavid du Colombier 		if(p->pc != pc) {
733e12c5d1SDavid du Colombier 			diag("phase error %lux sb %lux\n",
743e12c5d1SDavid du Colombier 				p->pc, pc);
753e12c5d1SDavid du Colombier 			if(!debug['a'])
763e12c5d1SDavid du Colombier 				prasm(curp);
773e12c5d1SDavid du Colombier 			pc = p->pc;
783e12c5d1SDavid du Colombier 		}
793e12c5d1SDavid du Colombier 		curp = p;
803e12c5d1SDavid du Colombier 		o = oplook(p);	/* could probably avoid this call */
813e12c5d1SDavid du Colombier 		if(asmout(p, o, 0)) {
823e12c5d1SDavid du Colombier 			p = p->link;
833e12c5d1SDavid du Colombier 			pc += 4;
843e12c5d1SDavid du Colombier 		}
853e12c5d1SDavid du Colombier 		pc += o->size;
863e12c5d1SDavid du Colombier 	}
873e12c5d1SDavid du Colombier 	if(debug['a'])
883e12c5d1SDavid du Colombier 		Bprint(&bso, "\n");
893e12c5d1SDavid du Colombier 	Bflush(&bso);
903e12c5d1SDavid du Colombier 	cflush();
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 	curtext = P;
933e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
943e12c5d1SDavid du Colombier 	case 0:
95219b2ee8SDavid du Colombier 	case 4:
96bd389b36SDavid du Colombier 		OFFSET = rnd(HEADR+textsize, 4096);
97bd389b36SDavid du Colombier 		seek(cout, OFFSET, 0);
983e12c5d1SDavid du Colombier 		break;
993e12c5d1SDavid du Colombier 	case 1:
1003e12c5d1SDavid du Colombier 	case 2:
101219b2ee8SDavid du Colombier 	case 3:
102219b2ee8SDavid du Colombier 	case 5:
103bd389b36SDavid du Colombier 		OFFSET = HEADR+textsize;
104bd389b36SDavid du Colombier 		seek(cout, OFFSET, 0);
1053e12c5d1SDavid du Colombier 		break;
1063e12c5d1SDavid du Colombier 	}
1073e12c5d1SDavid du Colombier 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
1083e12c5d1SDavid du Colombier 		if(datsize-t > sizeof(buf)-100)
1093e12c5d1SDavid du Colombier 			datblk(t, sizeof(buf)-100);
1103e12c5d1SDavid du Colombier 		else
1113e12c5d1SDavid du Colombier 			datblk(t, datsize-t);
1123e12c5d1SDavid du Colombier 	}
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 	symsize = 0;
1153e12c5d1SDavid du Colombier 	lcsize = 0;
1163e12c5d1SDavid du Colombier 	if(!debug['s']) {
1173e12c5d1SDavid du Colombier 		if(debug['v'])
1183e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
1193e12c5d1SDavid du Colombier 		Bflush(&bso);
1203e12c5d1SDavid du Colombier 		switch(HEADTYPE) {
1213e12c5d1SDavid du Colombier 		case 0:
122219b2ee8SDavid du Colombier 		case 4:
123bd389b36SDavid du Colombier 			OFFSET = rnd(HEADR+textsize, 4096)+datsize;
124bd389b36SDavid du Colombier 			seek(cout, OFFSET, 0);
1253e12c5d1SDavid du Colombier 			break;
126219b2ee8SDavid du Colombier 		case 3:
1273e12c5d1SDavid du Colombier 		case 2:
1283e12c5d1SDavid du Colombier 		case 1:
129219b2ee8SDavid du Colombier 		case 5:
130bd389b36SDavid du Colombier 			OFFSET = HEADR+textsize+datsize;
131bd389b36SDavid du Colombier 			seek(cout, OFFSET, 0);
1323e12c5d1SDavid du Colombier 			break;
1333e12c5d1SDavid du Colombier 		}
1343e12c5d1SDavid du Colombier 		if(!debug['s'])
1353e12c5d1SDavid du Colombier 			asmsym();
1363e12c5d1SDavid du Colombier 		if(debug['v'])
1373e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f pc\n", cputime());
1383e12c5d1SDavid du Colombier 		Bflush(&bso);
1393e12c5d1SDavid du Colombier 		if(!debug['s'])
1403e12c5d1SDavid du Colombier 			asmlc();
1413e12c5d1SDavid du Colombier 		cflush();
1423e12c5d1SDavid du Colombier 	}
1433e12c5d1SDavid du Colombier 
1443e12c5d1SDavid du Colombier 	if(debug['v'])
1453e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f header\n", cputime());
1463e12c5d1SDavid du Colombier 	Bflush(&bso);
147bd389b36SDavid du Colombier 	OFFSET = 0;
148bd389b36SDavid du Colombier 	seek(cout, OFFSET, 0);
1493e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
1503e12c5d1SDavid du Colombier 	case 0:
1513e12c5d1SDavid du Colombier 		lput(0x160L<<16);		/* magic and sections */
1523e12c5d1SDavid du Colombier 		lput(0L);			/* time and date */
1533e12c5d1SDavid du Colombier 		lput(rnd(HEADR+textsize, 4096)+datsize);
1543e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
1553e12c5d1SDavid du Colombier 		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
1563e12c5d1SDavid du Colombier 		lput((0413<<16)|0437L);		/* magic and version */
1573e12c5d1SDavid du Colombier 		lput(rnd(HEADR+textsize, 4096));	/* sizes */
1583e12c5d1SDavid du Colombier 		lput(datsize);
1593e12c5d1SDavid du Colombier 		lput(bsssize);
1603e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
1613e12c5d1SDavid du Colombier 		lput(INITTEXT-HEADR);		/* va of base of text */
1623e12c5d1SDavid du Colombier 		lput(INITDAT);			/* va of base of data */
1633e12c5d1SDavid du Colombier 		lput(INITDAT+datsize);		/* va of base of bss */
1643e12c5d1SDavid du Colombier 		lput(~0L);			/* gp reg mask */
1653e12c5d1SDavid du Colombier 		lput(0L);
1663e12c5d1SDavid du Colombier 		lput(0L);
1673e12c5d1SDavid du Colombier 		lput(0L);
1683e12c5d1SDavid du Colombier 		lput(0L);
1693e12c5d1SDavid du Colombier 		lput(~0L);			/* gp value ?? */
1703e12c5d1SDavid du Colombier 		break;
1713e12c5d1SDavid du Colombier 	case 1:
1723e12c5d1SDavid du Colombier 		lput(0x160L<<16);		/* magic and sections */
1733e12c5d1SDavid du Colombier 		lput(0L);			/* time and date */
1743e12c5d1SDavid du Colombier 		lput(HEADR+textsize+datsize);
1753e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
1763e12c5d1SDavid du Colombier 		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
177219b2ee8SDavid du Colombier 
1783e12c5d1SDavid du Colombier 		lput((0407<<16)|0437L);		/* magic and version */
1793e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
1803e12c5d1SDavid du Colombier 		lput(datsize);
1813e12c5d1SDavid du Colombier 		lput(bsssize);
1823e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
1833e12c5d1SDavid du Colombier 		lput(INITTEXT);			/* va of base of text */
1843e12c5d1SDavid du Colombier 		lput(INITDAT);			/* va of base of data */
1853e12c5d1SDavid du Colombier 		lput(INITDAT+datsize);		/* va of base of bss */
1863e12c5d1SDavid du Colombier 		lput(~0L);			/* gp reg mask */
1873e12c5d1SDavid du Colombier 		lput(lcsize);
1883e12c5d1SDavid du Colombier 		lput(0L);
1893e12c5d1SDavid du Colombier 		lput(0L);
1903e12c5d1SDavid du Colombier 		lput(0L);
1913e12c5d1SDavid du Colombier 		lput(~0L);			/* gp value ?? */
1923e12c5d1SDavid du Colombier 		lput(0L);			/* complete mystery */
1933e12c5d1SDavid du Colombier 		break;
1943e12c5d1SDavid du Colombier 	case 2:
1953e12c5d1SDavid du Colombier 		lput(0x407);			/* magic */
1963e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
1973e12c5d1SDavid du Colombier 		lput(datsize);
1983e12c5d1SDavid du Colombier 		lput(bsssize);
1993e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
2003e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
2013e12c5d1SDavid du Colombier 		lput(0L);
2023e12c5d1SDavid du Colombier 		lput(lcsize);
2033e12c5d1SDavid du Colombier 		break;
204219b2ee8SDavid du Colombier 	case 3:
205219b2ee8SDavid du Colombier 		lput((0x160L<<16)|3L);		/* magic and sections */
206219b2ee8SDavid du Colombier 		lput(time(0));			/* time and date */
207219b2ee8SDavid du Colombier 		lput(HEADR+textsize+datsize);
208219b2ee8SDavid du Colombier 		lput(symsize);			/* nsyms */
209219b2ee8SDavid du Colombier 		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
210219b2ee8SDavid du Colombier 
211219b2ee8SDavid du Colombier 		lput((0407<<16)|0437L);		/* magic and version */
212219b2ee8SDavid du Colombier 		lput(textsize);			/* sizes */
213219b2ee8SDavid du Colombier 		lput(datsize);
214219b2ee8SDavid du Colombier 		lput(bsssize);
215219b2ee8SDavid du Colombier 		lput(entryvalue());		/* va of entry */
216219b2ee8SDavid du Colombier 		lput(INITTEXT);			/* va of base of text */
217219b2ee8SDavid du Colombier 		lput(INITDAT);			/* va of base of data */
218219b2ee8SDavid du Colombier 		lput(INITDAT+datsize);		/* va of base of bss */
219219b2ee8SDavid du Colombier 		lput(~0L);			/* gp reg mask */
220219b2ee8SDavid du Colombier 		lput(lcsize);
221219b2ee8SDavid du Colombier 		lput(0L);
222219b2ee8SDavid du Colombier 		lput(0L);
223219b2ee8SDavid du Colombier 		lput(0L);
224219b2ee8SDavid du Colombier 		lput(~0L);			/* gp value ?? */
225219b2ee8SDavid du Colombier 
226219b2ee8SDavid du Colombier 		strnput(".text", 8);		/* text segment */
227219b2ee8SDavid du Colombier 		lput(INITTEXT);			/* address */
228219b2ee8SDavid du Colombier 		lput(INITTEXT);
229219b2ee8SDavid du Colombier 		lput(textsize);
230219b2ee8SDavid du Colombier 		lput(HEADR);
231219b2ee8SDavid du Colombier 		lput(0L);
232219b2ee8SDavid du Colombier 		lput(HEADR+textsize+datsize+symsize);
233219b2ee8SDavid du Colombier 		lput(lcsize);			/* line number size */
234219b2ee8SDavid du Colombier 		lput(0x20L);			/* flags */
235219b2ee8SDavid du Colombier 
236219b2ee8SDavid du Colombier 		strnput(".data", 8);		/* data segment */
237219b2ee8SDavid du Colombier 		lput(INITDAT);			/* address */
238219b2ee8SDavid du Colombier 		lput(INITDAT);
239219b2ee8SDavid du Colombier 		lput(datsize);
240219b2ee8SDavid du Colombier 		lput(HEADR+textsize);
241219b2ee8SDavid du Colombier 		lput(0L);
242219b2ee8SDavid du Colombier 		lput(0L);
243219b2ee8SDavid du Colombier 		lput(0L);
244219b2ee8SDavid du Colombier 		lput(0x40L);			/* flags */
245219b2ee8SDavid du Colombier 
246219b2ee8SDavid du Colombier 		strnput(".bss", 8);		/* bss segment */
247219b2ee8SDavid du Colombier 		lput(INITDAT+datsize);		/* address */
248219b2ee8SDavid du Colombier 		lput(INITDAT+datsize);
249219b2ee8SDavid du Colombier 		lput(bsssize);
250219b2ee8SDavid du Colombier 		lput(0L);
251219b2ee8SDavid du Colombier 		lput(0L);
252219b2ee8SDavid du Colombier 		lput(0L);
253219b2ee8SDavid du Colombier 		lput(0L);
254219b2ee8SDavid du Colombier 		lput(0x80L);			/* flags */
255219b2ee8SDavid du Colombier 		break;
256219b2ee8SDavid du Colombier 	case 4:
257219b2ee8SDavid du Colombier 
258219b2ee8SDavid du Colombier 		lput((0x160L<<16)|3L);		/* magic and sections */
259219b2ee8SDavid du Colombier 		lput(time(0));			/* time and date */
260219b2ee8SDavid du Colombier 		lput(rnd(HEADR+textsize, 4096)+datsize);
261219b2ee8SDavid du Colombier 		lput(symsize);			/* nsyms */
262219b2ee8SDavid du Colombier 		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
263219b2ee8SDavid du Colombier 
264219b2ee8SDavid du Colombier 		lput((0413<<16)|01012L);	/* magic and version */
265219b2ee8SDavid du Colombier 		lput(textsize);			/* sizes */
266219b2ee8SDavid du Colombier 		lput(datsize);
267219b2ee8SDavid du Colombier 		lput(bsssize);
268219b2ee8SDavid du Colombier 		lput(entryvalue());		/* va of entry */
269219b2ee8SDavid du Colombier 		lput(INITTEXT);			/* va of base of text */
270219b2ee8SDavid du Colombier 		lput(INITDAT);			/* va of base of data */
271219b2ee8SDavid du Colombier 		lput(INITDAT+datsize);		/* va of base of bss */
272219b2ee8SDavid du Colombier 		lput(~0L);			/* gp reg mask */
273219b2ee8SDavid du Colombier 		lput(lcsize);
274219b2ee8SDavid du Colombier 		lput(0L);
275219b2ee8SDavid du Colombier 		lput(0L);
276219b2ee8SDavid du Colombier 		lput(0L);
277219b2ee8SDavid du Colombier 		lput(~0L);			/* gp value ?? */
278219b2ee8SDavid du Colombier 
279219b2ee8SDavid du Colombier 		strnput(".text", 8);		/* text segment */
280219b2ee8SDavid du Colombier 		lput(INITTEXT);			/* address */
281219b2ee8SDavid du Colombier 		lput(INITTEXT);
282219b2ee8SDavid du Colombier 		lput(textsize);
283219b2ee8SDavid du Colombier 		lput(HEADR);
284219b2ee8SDavid du Colombier 		lput(0L);
285219b2ee8SDavid du Colombier 		lput(HEADR+textsize+datsize+symsize);
286219b2ee8SDavid du Colombier 		lput(lcsize);			/* line number size */
287219b2ee8SDavid du Colombier 		lput(0x20L);			/* flags */
288219b2ee8SDavid du Colombier 
289219b2ee8SDavid du Colombier 		strnput(".data", 8);		/* data segment */
290219b2ee8SDavid du Colombier 		lput(INITDAT);			/* address */
291219b2ee8SDavid du Colombier 		lput(INITDAT);
292219b2ee8SDavid du Colombier 		lput(datsize);
293219b2ee8SDavid du Colombier 		lput(rnd(HEADR+textsize, 4096));	/* sizes */
294219b2ee8SDavid du Colombier 		lput(0L);
295219b2ee8SDavid du Colombier 		lput(0L);
296219b2ee8SDavid du Colombier 		lput(0L);
297219b2ee8SDavid du Colombier 		lput(0x40L);			/* flags */
298219b2ee8SDavid du Colombier 
299219b2ee8SDavid du Colombier 		strnput(".bss", 8);		/* bss segment */
300219b2ee8SDavid du Colombier 		lput(INITDAT+datsize);		/* address */
301219b2ee8SDavid du Colombier 		lput(INITDAT+datsize);
302219b2ee8SDavid du Colombier 		lput(bsssize);
303219b2ee8SDavid du Colombier 		lput(0L);
304219b2ee8SDavid du Colombier 		lput(0L);
305219b2ee8SDavid du Colombier 		lput(0L);
306219b2ee8SDavid du Colombier 		lput(0L);
307219b2ee8SDavid du Colombier 		lput(0x80L);			/* flags */
308219b2ee8SDavid du Colombier 		break;
309219b2ee8SDavid du Colombier 	case 5:
310219b2ee8SDavid du Colombier 		strnput("\177ELF", 4);		/* e_ident */
311219b2ee8SDavid du Colombier 		CPUT(1);			/* class = 32 bit */
312219b2ee8SDavid du Colombier 		CPUT(2);			/* data = MSB */
313219b2ee8SDavid du Colombier 		CPUT(1);			/* version = CURRENT */
314219b2ee8SDavid du Colombier 		strnput("", 9);
315219b2ee8SDavid du Colombier 		lput((2L<<16)|8L);		/* type = EXEC; machine = MIPS */
316219b2ee8SDavid du Colombier 		lput(1L);			/* version = CURRENT */
317219b2ee8SDavid du Colombier 		lput(entryvalue());		/* entry vaddr */
318219b2ee8SDavid du Colombier 		lput(52L);			/* offset to first phdr */
319219b2ee8SDavid du Colombier 		lput(0L);			/* offset to first shdr */
320219b2ee8SDavid du Colombier 		lput(0L);			/* flags = MIPS */
321219b2ee8SDavid du Colombier 		lput((52L<<16)|32L);		/* Ehdr & Phdr sizes*/
322219b2ee8SDavid du Colombier 		lput((3L<<16)|0L);		/* # Phdrs & Shdr size */
323219b2ee8SDavid du Colombier 		lput((0L<<16)|0L);		/* # Shdrs & shdr string size */
324219b2ee8SDavid du Colombier 
325219b2ee8SDavid du Colombier 		lput(1L);			/* text - type = PT_LOAD */
326219b2ee8SDavid du Colombier 		lput(0L);			/* file offset */
327219b2ee8SDavid du Colombier 		lput(INITTEXT-HEADR);		/* vaddr */
328219b2ee8SDavid du Colombier 		lput(INITTEXT-HEADR);		/* paddr */
329219b2ee8SDavid du Colombier 		lput(HEADR+textsize);		/* file size */
330219b2ee8SDavid du Colombier 		lput(HEADR+textsize);		/* memory size */
331*7dd7cddfSDavid du Colombier 		lput(0x05L);			/* protections = RX */
332219b2ee8SDavid du Colombier 		lput(0x10000L);			/* alignment code?? */
333219b2ee8SDavid du Colombier 
334219b2ee8SDavid du Colombier 		lput(1L);			/* data - type = PT_LOAD */
335219b2ee8SDavid du Colombier 		lput(HEADR+textsize);		/* file offset */
336219b2ee8SDavid du Colombier 		lput(INITDAT);			/* vaddr */
337219b2ee8SDavid du Colombier 		lput(INITDAT);			/* paddr */
338219b2ee8SDavid du Colombier 		lput(datsize);			/* file size */
339219b2ee8SDavid du Colombier 		lput(datsize+bsssize);		/* memory size */
340219b2ee8SDavid du Colombier 		lput(0x06L);			/* protections = RW */
341219b2ee8SDavid du Colombier 		lput(0x10000L);			/* alignment code?? */
342219b2ee8SDavid du Colombier 
343219b2ee8SDavid du Colombier 		lput(0L);			/* data - type = PT_NULL */
344219b2ee8SDavid du Colombier 		lput(HEADR+textsize+datsize);	/* file offset */
345219b2ee8SDavid du Colombier 		lput(0L);
346219b2ee8SDavid du Colombier 		lput(0L);
347219b2ee8SDavid du Colombier 		lput(symsize);			/* symbol table size */
348219b2ee8SDavid du Colombier 		lput(lcsize);			/* line number size */
349219b2ee8SDavid du Colombier 		lput(0x04L);			/* protections = R */
350219b2ee8SDavid du Colombier 		lput(0x04L);			/* alignment code?? */
3513e12c5d1SDavid du Colombier 	}
3523e12c5d1SDavid du Colombier 	cflush();
3533e12c5d1SDavid du Colombier }
3543e12c5d1SDavid du Colombier 
3553e12c5d1SDavid du Colombier void
356219b2ee8SDavid du Colombier strnput(char *s, int n)
357219b2ee8SDavid du Colombier {
358219b2ee8SDavid du Colombier 	for(; *s; s++){
359219b2ee8SDavid du Colombier 		CPUT(*s);
360219b2ee8SDavid du Colombier 		n--;
361219b2ee8SDavid du Colombier 	}
362219b2ee8SDavid du Colombier 	for(; n > 0; n--)
363219b2ee8SDavid du Colombier 		CPUT(0);
364219b2ee8SDavid du Colombier }
365219b2ee8SDavid du Colombier 
366219b2ee8SDavid du Colombier void
3673e12c5d1SDavid du Colombier lput(long l)
3683e12c5d1SDavid du Colombier {
3693e12c5d1SDavid du Colombier 
3703e12c5d1SDavid du Colombier 	LPUT(l);
3713e12c5d1SDavid du Colombier }
3723e12c5d1SDavid du Colombier 
3733e12c5d1SDavid du Colombier void
3743e12c5d1SDavid du Colombier cflush(void)
3753e12c5d1SDavid du Colombier {
3763e12c5d1SDavid du Colombier 	int n;
3773e12c5d1SDavid du Colombier 
3783e12c5d1SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
3793e12c5d1SDavid du Colombier 	if(n)
3803e12c5d1SDavid du Colombier 		write(cout, buf.cbuf, n);
3813e12c5d1SDavid du Colombier 	cbp = buf.cbuf;
3823e12c5d1SDavid du Colombier 	cbc = sizeof(buf.cbuf);
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier 
3853e12c5d1SDavid du Colombier void
386219b2ee8SDavid du Colombier nopstat(char *f, Count *c)
387219b2ee8SDavid du Colombier {
388219b2ee8SDavid du Colombier 	if(c->outof)
389219b2ee8SDavid du Colombier 	Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
390219b2ee8SDavid du Colombier 		c->outof - c->count, c->outof,
391219b2ee8SDavid du Colombier 		(double)(c->outof - c->count)/c->outof);
392219b2ee8SDavid du Colombier }
393219b2ee8SDavid du Colombier 
394219b2ee8SDavid du Colombier void
3953e12c5d1SDavid du Colombier asmsym(void)
3963e12c5d1SDavid du Colombier {
3973e12c5d1SDavid du Colombier 	Prog *p;
3983e12c5d1SDavid du Colombier 	Auto *a;
3993e12c5d1SDavid du Colombier 	Sym *s;
4003e12c5d1SDavid du Colombier 	int h;
4013e12c5d1SDavid du Colombier 
4023e12c5d1SDavid du Colombier 	s = lookup("etext", 0);
4033e12c5d1SDavid du Colombier 	if(s->type == STEXT)
4043e12c5d1SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
4053e12c5d1SDavid du Colombier 
4063e12c5d1SDavid du Colombier 	for(h=0; h<NHASH; h++)
4073e12c5d1SDavid du Colombier 		for(s=hash[h]; s!=S; s=s->link)
4083e12c5d1SDavid du Colombier 			switch(s->type) {
409219b2ee8SDavid du Colombier 			case SCONST:
410219b2ee8SDavid du Colombier 				putsymb(s->name, 'D', s->value, s->version);
411219b2ee8SDavid du Colombier 				continue;
412219b2ee8SDavid du Colombier 
4133e12c5d1SDavid du Colombier 			case SDATA:
4143e12c5d1SDavid du Colombier 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
4153e12c5d1SDavid du Colombier 				continue;
4163e12c5d1SDavid du Colombier 
4173e12c5d1SDavid du Colombier 			case SBSS:
4183e12c5d1SDavid du Colombier 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
4193e12c5d1SDavid du Colombier 				continue;
4203e12c5d1SDavid du Colombier 
4213e12c5d1SDavid du Colombier 			case SFILE:
4223e12c5d1SDavid du Colombier 				putsymb(s->name, 'f', s->value, s->version);
4233e12c5d1SDavid du Colombier 				continue;
4243e12c5d1SDavid du Colombier 			}
4253e12c5d1SDavid du Colombier 
4263e12c5d1SDavid du Colombier 	for(p=textp; p!=P; p=p->cond) {
4273e12c5d1SDavid du Colombier 		s = p->from.sym;
4283e12c5d1SDavid du Colombier 		if(s->type != STEXT && s->type != SLEAF)
4293e12c5d1SDavid du Colombier 			continue;
4303e12c5d1SDavid du Colombier 
4313e12c5d1SDavid du Colombier 		/* filenames first */
4323e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
4333e12c5d1SDavid du Colombier 			if(a->type == D_FILE)
434*7dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'z', a->aoffset, 0);
4353e12c5d1SDavid du Colombier 			else
436219b2ee8SDavid du Colombier 			if(a->type == D_FILE1)
437*7dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'Z', a->aoffset, 0);
4383e12c5d1SDavid du Colombier 
4393e12c5d1SDavid du Colombier 		if(s->type == STEXT)
4403e12c5d1SDavid du Colombier 			putsymb(s->name, 'T', s->value, s->version);
4413e12c5d1SDavid du Colombier 		else
4423e12c5d1SDavid du Colombier 			putsymb(s->name, 'L', s->value, s->version);
4433e12c5d1SDavid du Colombier 
4443e12c5d1SDavid du Colombier 		/* frame, auto and param after */
445219b2ee8SDavid du Colombier 		putsymb(".frame", 'm', p->to.offset+4, 0);
4463e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
4473e12c5d1SDavid du Colombier 			if(a->type == D_AUTO)
448*7dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'a', -a->aoffset, 0);
4493e12c5d1SDavid du Colombier 			else
4503e12c5d1SDavid du Colombier 			if(a->type == D_PARAM)
451*7dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'p', a->aoffset, 0);
4523e12c5d1SDavid du Colombier 	}
4533e12c5d1SDavid du Colombier 	if(debug['v'] || debug['n'])
4543e12c5d1SDavid du Colombier 		Bprint(&bso, "symsize = %lud\n", symsize);
4553e12c5d1SDavid du Colombier 	Bflush(&bso);
4563e12c5d1SDavid du Colombier }
4573e12c5d1SDavid du Colombier 
4583e12c5d1SDavid du Colombier void
4593e12c5d1SDavid du Colombier putsymb(char *s, int t, long v, int ver)
4603e12c5d1SDavid du Colombier {
4613e12c5d1SDavid du Colombier 	int i, f;
4623e12c5d1SDavid du Colombier 
4633e12c5d1SDavid du Colombier 	if(t == 'f')
4643e12c5d1SDavid du Colombier 		s++;
4653e12c5d1SDavid du Colombier 	LPUT(v);
4663e12c5d1SDavid du Colombier 	if(ver)
4673e12c5d1SDavid du Colombier 		t += 'a' - 'A';
468219b2ee8SDavid du Colombier 	CPUT(t+0x80);			/* 0x80 is variable length */
469219b2ee8SDavid du Colombier 
470219b2ee8SDavid du Colombier 	if(t == 'Z' || t == 'z') {
471219b2ee8SDavid du Colombier 		CPUT(s[0]);
472219b2ee8SDavid du Colombier 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
473219b2ee8SDavid du Colombier 			CPUT(s[i]);
474219b2ee8SDavid du Colombier 			CPUT(s[i+1]);
475219b2ee8SDavid du Colombier 		}
476219b2ee8SDavid du Colombier 		CPUT(0);
477219b2ee8SDavid du Colombier 		CPUT(0);
478219b2ee8SDavid du Colombier 		i++;
479219b2ee8SDavid du Colombier 	}
480219b2ee8SDavid du Colombier 	else {
481219b2ee8SDavid du Colombier 		for(i=0; s[i]; i++)
4823e12c5d1SDavid du Colombier 			CPUT(s[i]);
4833e12c5d1SDavid du Colombier 		CPUT(0);
484219b2ee8SDavid du Colombier 	}
485219b2ee8SDavid du Colombier 	symsize += 4 + 1 + i + 1;
486219b2ee8SDavid du Colombier 
4873e12c5d1SDavid du Colombier 	if(debug['n']) {
4883e12c5d1SDavid du Colombier 		if(t == 'z' || t == 'Z') {
489219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux ", t, v);
490219b2ee8SDavid du Colombier 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
4913e12c5d1SDavid du Colombier 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
492219b2ee8SDavid du Colombier 				Bprint(&bso, "/%x", f);
4933e12c5d1SDavid du Colombier 			}
494219b2ee8SDavid du Colombier 			Bprint(&bso, "\n");
4953e12c5d1SDavid du Colombier 			return;
4963e12c5d1SDavid du Colombier 		}
4973e12c5d1SDavid du Colombier 		if(ver)
4983e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
4993e12c5d1SDavid du Colombier 		else
5003e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
5013e12c5d1SDavid du Colombier 	}
5023e12c5d1SDavid du Colombier }
5033e12c5d1SDavid du Colombier 
5043e12c5d1SDavid du Colombier #define	MINLC	4
5053e12c5d1SDavid du Colombier void
5063e12c5d1SDavid du Colombier asmlc(void)
5073e12c5d1SDavid du Colombier {
5083e12c5d1SDavid du Colombier 	long oldpc, oldlc;
5093e12c5d1SDavid du Colombier 	Prog *p;
5103e12c5d1SDavid du Colombier 	long v, s;
5113e12c5d1SDavid du Colombier 
5123e12c5d1SDavid du Colombier 	oldpc = INITTEXT;
5133e12c5d1SDavid du Colombier 	oldlc = 0;
5143e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
5153e12c5d1SDavid du Colombier 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
5163e12c5d1SDavid du Colombier 			if(p->as == ATEXT)
5173e12c5d1SDavid du Colombier 				curtext = p;
5183e12c5d1SDavid du Colombier 			if(debug['L'])
5193e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
5203e12c5d1SDavid du Colombier 					p->pc, p);
5213e12c5d1SDavid du Colombier 			continue;
5223e12c5d1SDavid du Colombier 		}
5233e12c5d1SDavid du Colombier 		if(debug['L'])
5243e12c5d1SDavid du Colombier 			Bprint(&bso, "\t\t%6ld", lcsize);
5253e12c5d1SDavid du Colombier 		v = (p->pc - oldpc) / MINLC;
5263e12c5d1SDavid du Colombier 		while(v) {
5273e12c5d1SDavid du Colombier 			s = 127;
5283e12c5d1SDavid du Colombier 			if(v < 127)
5293e12c5d1SDavid du Colombier 				s = v;
5303e12c5d1SDavid du Colombier 			CPUT(s+128);	/* 129-255 +pc */
5313e12c5d1SDavid du Colombier 			if(debug['L'])
5323e12c5d1SDavid du Colombier 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
5333e12c5d1SDavid du Colombier 			v -= s;
5343e12c5d1SDavid du Colombier 			lcsize++;
5353e12c5d1SDavid du Colombier 		}
5363e12c5d1SDavid du Colombier 		s = p->line - oldlc;
5373e12c5d1SDavid du Colombier 		oldlc = p->line;
5383e12c5d1SDavid du Colombier 		oldpc = p->pc + MINLC;
5393e12c5d1SDavid du Colombier 		if(s > 64 || s < -64) {
5403e12c5d1SDavid du Colombier 			CPUT(0);	/* 0 vv +lc */
5413e12c5d1SDavid du Colombier 			CPUT(s>>24);
5423e12c5d1SDavid du Colombier 			CPUT(s>>16);
5433e12c5d1SDavid du Colombier 			CPUT(s>>8);
5443e12c5d1SDavid du Colombier 			CPUT(s);
5453e12c5d1SDavid du Colombier 			if(debug['L']) {
5463e12c5d1SDavid du Colombier 				if(s > 0)
5473e12c5d1SDavid du Colombier 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
5483e12c5d1SDavid du Colombier 						s, 0, s);
5493e12c5d1SDavid du Colombier 				else
5503e12c5d1SDavid du Colombier 					Bprint(&bso, " lc%ld(%d,%ld)\n",
5513e12c5d1SDavid du Colombier 						s, 0, s);
5523e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
5533e12c5d1SDavid du Colombier 					p->pc, p);
5543e12c5d1SDavid du Colombier 			}
5553e12c5d1SDavid du Colombier 			lcsize += 5;
5563e12c5d1SDavid du Colombier 			continue;
5573e12c5d1SDavid du Colombier 		}
5583e12c5d1SDavid du Colombier 		if(s > 0) {
5593e12c5d1SDavid du Colombier 			CPUT(0+s);	/* 1-64 +lc */
5603e12c5d1SDavid du Colombier 			if(debug['L']) {
5613e12c5d1SDavid du Colombier 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
5623e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
5633e12c5d1SDavid du Colombier 					p->pc, p);
5643e12c5d1SDavid du Colombier 			}
5653e12c5d1SDavid du Colombier 		} else {
5663e12c5d1SDavid du Colombier 			CPUT(64-s);	/* 65-128 -lc */
5673e12c5d1SDavid du Colombier 			if(debug['L']) {
5683e12c5d1SDavid du Colombier 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
5693e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
5703e12c5d1SDavid du Colombier 					p->pc, p);
5713e12c5d1SDavid du Colombier 			}
5723e12c5d1SDavid du Colombier 		}
5733e12c5d1SDavid du Colombier 		lcsize++;
5743e12c5d1SDavid du Colombier 	}
5753e12c5d1SDavid du Colombier 	while(lcsize & 1) {
5763e12c5d1SDavid du Colombier 		s = 129;
5773e12c5d1SDavid du Colombier 		CPUT(s);
5783e12c5d1SDavid du Colombier 		lcsize++;
5793e12c5d1SDavid du Colombier 	}
5803e12c5d1SDavid du Colombier 	if(debug['v'] || debug['L'])
5813e12c5d1SDavid du Colombier 		Bprint(&bso, "lcsize = %ld\n", lcsize);
5823e12c5d1SDavid du Colombier 	Bflush(&bso);
5833e12c5d1SDavid du Colombier }
5843e12c5d1SDavid du Colombier 
5853e12c5d1SDavid du Colombier void
5863e12c5d1SDavid du Colombier datblk(long s, long n)
5873e12c5d1SDavid du Colombier {
5883e12c5d1SDavid du Colombier 	Prog *p;
5893e12c5d1SDavid du Colombier 	char *cast;
5903e12c5d1SDavid du Colombier 	long l, fl, j, d;
5913e12c5d1SDavid du Colombier 	int i, c;
5923e12c5d1SDavid du Colombier 
5933e12c5d1SDavid du Colombier 	memset(buf.dbuf, 0, n+100);
5943e12c5d1SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
5953e12c5d1SDavid du Colombier 		curp = p;
5963e12c5d1SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
5973e12c5d1SDavid du Colombier 		c = p->reg;
5983e12c5d1SDavid du Colombier 		i = 0;
5993e12c5d1SDavid du Colombier 		if(l < 0) {
6003e12c5d1SDavid du Colombier 			if(l+c <= 0)
6013e12c5d1SDavid du Colombier 				continue;
6023e12c5d1SDavid du Colombier 			while(l < 0) {
6033e12c5d1SDavid du Colombier 				l++;
6043e12c5d1SDavid du Colombier 				i++;
6053e12c5d1SDavid du Colombier 			}
6063e12c5d1SDavid du Colombier 		}
6073e12c5d1SDavid du Colombier 		if(l >= n)
6083e12c5d1SDavid du Colombier 			continue;
609219b2ee8SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
6103e12c5d1SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
6113e12c5d1SDavid du Colombier 				if(buf.dbuf[j]) {
6123e12c5d1SDavid du Colombier 					print("%P\n", p);
6133e12c5d1SDavid du Colombier 					diag("multiple initialization\n");
6143e12c5d1SDavid du Colombier 					break;
6153e12c5d1SDavid du Colombier 				}
616219b2ee8SDavid du Colombier 		}
6173e12c5d1SDavid du Colombier 		switch(p->to.type) {
6183e12c5d1SDavid du Colombier 		default:
6193e12c5d1SDavid du Colombier 			diag("unknown mode in initialization\n%P\n", p);
6203e12c5d1SDavid du Colombier 			break;
6213e12c5d1SDavid du Colombier 
6223e12c5d1SDavid du Colombier 		case D_FCONST:
6233e12c5d1SDavid du Colombier 			switch(c) {
6243e12c5d1SDavid du Colombier 			default:
6253e12c5d1SDavid du Colombier 			case 4:
6263e12c5d1SDavid du Colombier 				fl = ieeedtof(p->to.ieee);
6273e12c5d1SDavid du Colombier 				cast = (char*)&fl;
6283e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6293e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i+4]];
6303e12c5d1SDavid du Colombier 					l++;
6313e12c5d1SDavid du Colombier 				}
6323e12c5d1SDavid du Colombier 				break;
6333e12c5d1SDavid du Colombier 			case 8:
6343e12c5d1SDavid du Colombier 				cast = (char*)p->to.ieee;
6353e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6363e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
6373e12c5d1SDavid du Colombier 					l++;
6383e12c5d1SDavid du Colombier 				}
6393e12c5d1SDavid du Colombier 				break;
6403e12c5d1SDavid du Colombier 			}
6413e12c5d1SDavid du Colombier 			break;
6423e12c5d1SDavid du Colombier 
6433e12c5d1SDavid du Colombier 		case D_SCONST:
6443e12c5d1SDavid du Colombier 			for(; i<c; i++) {
6453e12c5d1SDavid du Colombier 				buf.dbuf[l] = p->to.sval[i];
6463e12c5d1SDavid du Colombier 				l++;
6473e12c5d1SDavid du Colombier 			}
6483e12c5d1SDavid du Colombier 			break;
6493e12c5d1SDavid du Colombier 
6503e12c5d1SDavid du Colombier 		case D_CONST:
6513e12c5d1SDavid du Colombier 			d = p->to.offset;
6523e12c5d1SDavid du Colombier 			if(p->to.sym) {
6533e12c5d1SDavid du Colombier 				if(p->to.sym->type == STEXT ||
6543e12c5d1SDavid du Colombier 				   p->to.sym->type == SLEAF)
6553e12c5d1SDavid du Colombier 					d += p->to.sym->value;
6563e12c5d1SDavid du Colombier 				if(p->to.sym->type == SDATA)
6573e12c5d1SDavid du Colombier 					d += p->to.sym->value + INITDAT;
6583e12c5d1SDavid du Colombier 				if(p->to.sym->type == SBSS)
6593e12c5d1SDavid du Colombier 					d += p->to.sym->value + INITDAT;
6603e12c5d1SDavid du Colombier 			}
6613e12c5d1SDavid du Colombier 			cast = (char*)&d;
6623e12c5d1SDavid du Colombier 			switch(c) {
6633e12c5d1SDavid du Colombier 			default:
6643e12c5d1SDavid du Colombier 				diag("bad nuxi %d %d\n%P\n", c, i, curp);
6653e12c5d1SDavid du Colombier 				break;
6663e12c5d1SDavid du Colombier 			case 1:
6673e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6683e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
6693e12c5d1SDavid du Colombier 					l++;
6703e12c5d1SDavid du Colombier 				}
6713e12c5d1SDavid du Colombier 				break;
6723e12c5d1SDavid du Colombier 			case 2:
6733e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6743e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
6753e12c5d1SDavid du Colombier 					l++;
6763e12c5d1SDavid du Colombier 				}
6773e12c5d1SDavid du Colombier 				break;
6783e12c5d1SDavid du Colombier 			case 4:
6793e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6803e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
6813e12c5d1SDavid du Colombier 					l++;
6823e12c5d1SDavid du Colombier 				}
6833e12c5d1SDavid du Colombier 				break;
6843e12c5d1SDavid du Colombier 			}
6853e12c5d1SDavid du Colombier 			break;
6863e12c5d1SDavid du Colombier 		}
6873e12c5d1SDavid du Colombier 	}
6883e12c5d1SDavid du Colombier 	write(cout, buf.dbuf, n);
6893e12c5d1SDavid du Colombier }
6903e12c5d1SDavid du Colombier 
6913e12c5d1SDavid du Colombier #define	OP_RRR(op,r1,r2,r3)\
6923e12c5d1SDavid du Colombier 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))
6933e12c5d1SDavid du Colombier #define	OP_IRR(op,i,r2,r3)\
6943e12c5d1SDavid du Colombier 	(op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))
6953e12c5d1SDavid du Colombier #define	OP_SRR(op,s,r2,r3)\
6963e12c5d1SDavid du Colombier 	(op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))
6973e12c5d1SDavid du Colombier #define	OP_FRRR(op,r1,r2,r3)\
6983e12c5d1SDavid du Colombier 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))
6993e12c5d1SDavid du Colombier #define	OP_JMP(op,i)\
7003e12c5d1SDavid du Colombier 		((op)|((i)&0x3ffffffL))
7013e12c5d1SDavid du Colombier 
702219b2ee8SDavid du Colombier #define	OP(x,y)\
703219b2ee8SDavid du Colombier 	(((x)<<3)|((y)<<0))
704219b2ee8SDavid du Colombier #define	SP(x,y)\
705219b2ee8SDavid du Colombier 	(((x)<<29)|((y)<<26))
706219b2ee8SDavid du Colombier #define	BCOND(x,y)\
707219b2ee8SDavid du Colombier 	(((x)<<19)|((y)<<16))
708219b2ee8SDavid du Colombier #define	MMU(x,y)\
709219b2ee8SDavid du Colombier 	(SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))
710219b2ee8SDavid du Colombier #define	FPF(x,y)\
711219b2ee8SDavid du Colombier 	(SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))
712219b2ee8SDavid du Colombier #define	FPD(x,y)\
713219b2ee8SDavid du Colombier 	(SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))
714219b2ee8SDavid du Colombier #define	FPW(x,y)\
715219b2ee8SDavid du Colombier 	(SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))
716219b2ee8SDavid du Colombier 
7173e12c5d1SDavid du Colombier int
7183e12c5d1SDavid du Colombier asmout(Prog *p, Optab *o, int aflag)
7193e12c5d1SDavid du Colombier {
720*7dd7cddfSDavid du Colombier 	long o1, o2, o3, o4, o5, o6, o7, v;
7213e12c5d1SDavid du Colombier 	Prog *ct;
7223e12c5d1SDavid du Colombier 	int r, a;
7233e12c5d1SDavid du Colombier 
7243e12c5d1SDavid du Colombier 	o1 = 0;
7253e12c5d1SDavid du Colombier 	o2 = 0;
7263e12c5d1SDavid du Colombier 	o3 = 0;
7273e12c5d1SDavid du Colombier 	o4 = 0;
728219b2ee8SDavid du Colombier 	o5 = 0;
729*7dd7cddfSDavid du Colombier 	o6 = 0;
730*7dd7cddfSDavid du Colombier 	o7 = 0;
7313e12c5d1SDavid du Colombier 	switch(o->type) {
7323e12c5d1SDavid du Colombier 	default:
7333e12c5d1SDavid du Colombier 		diag("unknown type %d\n", o->type);
7343e12c5d1SDavid du Colombier 		if(!debug['a'])
7353e12c5d1SDavid du Colombier 			prasm(p);
7363e12c5d1SDavid du Colombier 		break;
7373e12c5d1SDavid du Colombier 
7383e12c5d1SDavid du Colombier 	case 0:		/* pseudo ops */
7393e12c5d1SDavid du Colombier 		if(aflag) {
7403e12c5d1SDavid du Colombier 			if(p->link) {
7413e12c5d1SDavid du Colombier 				if(p->as == ATEXT) {
7423e12c5d1SDavid du Colombier 					ct = curtext;
7433e12c5d1SDavid du Colombier 					o2 = autosize;
7443e12c5d1SDavid du Colombier 					curtext = p;
7453e12c5d1SDavid du Colombier 					autosize = p->to.offset + 4;
7463e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
7473e12c5d1SDavid du Colombier 					curtext = ct;
7483e12c5d1SDavid du Colombier 					autosize = o2;
7493e12c5d1SDavid du Colombier 				} else
7503e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
7513e12c5d1SDavid du Colombier 			}
7523e12c5d1SDavid du Colombier 			return o1;
7533e12c5d1SDavid du Colombier 		}
7543e12c5d1SDavid du Colombier 		break;
7553e12c5d1SDavid du Colombier 
756219b2ee8SDavid du Colombier 	case 1:		/* mov[v] r1,r2 ==> OR r1,r0,r2 */
7573e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg);
7583e12c5d1SDavid du Colombier 		break;
7593e12c5d1SDavid du Colombier 
7603e12c5d1SDavid du Colombier 	case 2:		/* add/sub r1,[r2],r3 */
7613e12c5d1SDavid du Colombier 		r = p->reg;
7623e12c5d1SDavid du Colombier 		if(r == NREG)
7633e12c5d1SDavid du Colombier 			r = p->to.reg;
7643e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg);
7653e12c5d1SDavid du Colombier 		break;
7663e12c5d1SDavid du Colombier 
7673e12c5d1SDavid du Colombier 	case 3:		/* mov $soreg, r ==> or/add $i,o,r */
7683e12c5d1SDavid du Colombier 		v = regoff(&p->from);
7693e12c5d1SDavid du Colombier 		r = p->from.reg;
7703e12c5d1SDavid du Colombier 		if(r == NREG)
7713e12c5d1SDavid du Colombier 			r = o->param;
772219b2ee8SDavid du Colombier 		a = AADDU;
7733e12c5d1SDavid du Colombier 		if(o->a1 == C_ANDCON)
7743e12c5d1SDavid du Colombier 			a = AOR;
7753e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(a), v, r, p->to.reg);
7763e12c5d1SDavid du Colombier 		break;
7773e12c5d1SDavid du Colombier 
7783e12c5d1SDavid du Colombier 	case 4:		/* add $scon,[r1],r2 */
7793e12c5d1SDavid du Colombier 		v = regoff(&p->from);
7803e12c5d1SDavid du Colombier 		r = p->reg;
7813e12c5d1SDavid du Colombier 		if(r == NREG)
7823e12c5d1SDavid du Colombier 			r = p->to.reg;
7833e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, r, p->to.reg);
7843e12c5d1SDavid du Colombier 		break;
7853e12c5d1SDavid du Colombier 
7863e12c5d1SDavid du Colombier 	case 5:		/* syscall */
7873e12c5d1SDavid du Colombier 		if(aflag)
7883e12c5d1SDavid du Colombier 			return 0;
7893e12c5d1SDavid du Colombier 		o1 = oprrr(p->as);
7903e12c5d1SDavid du Colombier 		break;
7913e12c5d1SDavid du Colombier 
7923e12c5d1SDavid du Colombier 	case 6:		/* beq r1,[r2],sbra */
7933e12c5d1SDavid du Colombier 		if(aflag)
7943e12c5d1SDavid du Colombier 			return 0;
7953e12c5d1SDavid du Colombier 		if(p->cond == P)
7963e12c5d1SDavid du Colombier 			v = -4 >> 2;
7973e12c5d1SDavid du Colombier 		else
7983e12c5d1SDavid du Colombier 			v = (p->cond->pc - pc-4) >> 2;
799*7dd7cddfSDavid du Colombier 		if(((v << 16) >> 16) != v)
800*7dd7cddfSDavid du Colombier 			diag("short branch too far: %d\n%P\n", v, p);
8013e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg);
8023e12c5d1SDavid du Colombier 		break;
8033e12c5d1SDavid du Colombier 
8043e12c5d1SDavid du Colombier 	case 7:		/* mov r, soreg ==> sw o(r) */
8053e12c5d1SDavid du Colombier 		r = p->to.reg;
8063e12c5d1SDavid du Colombier 		if(r == NREG)
8073e12c5d1SDavid du Colombier 			r = o->param;
8083e12c5d1SDavid du Colombier 		v = regoff(&p->to);
8093e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, r, p->from.reg);
8103e12c5d1SDavid du Colombier 		break;
8113e12c5d1SDavid du Colombier 
8123e12c5d1SDavid du Colombier 	case 8:		/* mov soreg, r ==> lw o(r) */
8133e12c5d1SDavid du Colombier 		r = p->from.reg;
8143e12c5d1SDavid du Colombier 		if(r == NREG)
8153e12c5d1SDavid du Colombier 			r = o->param;
8163e12c5d1SDavid du Colombier 		v = regoff(&p->from);
817219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg);
8183e12c5d1SDavid du Colombier 		break;
8193e12c5d1SDavid du Colombier 
8203e12c5d1SDavid du Colombier 	case 9:		/* asl r1,[r2],r3 */
8213e12c5d1SDavid du Colombier 		r = p->reg;
8223e12c5d1SDavid du Colombier 		if(r == NREG)
8233e12c5d1SDavid du Colombier 			r = p->to.reg;
8243e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
8253e12c5d1SDavid du Colombier 		break;
8263e12c5d1SDavid du Colombier 
8273e12c5d1SDavid du Colombier 	case 10:	/* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */
8283e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8293e12c5d1SDavid du Colombier 		r = AOR;
8303e12c5d1SDavid du Colombier 		if(v < 0)
831219b2ee8SDavid du Colombier 			r = AADDU;
8323e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(r), v, 0, REGTMP);
8333e12c5d1SDavid du Colombier 		r = p->reg;
8343e12c5d1SDavid du Colombier 		if(r == NREG)
8353e12c5d1SDavid du Colombier 			r = p->to.reg;
8363e12c5d1SDavid du Colombier 		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
8373e12c5d1SDavid du Colombier 		break;
8383e12c5d1SDavid du Colombier 
8393e12c5d1SDavid du Colombier 	case 11:	/* jmp lbra */
8403e12c5d1SDavid du Colombier 		if(aflag)
8413e12c5d1SDavid du Colombier 			return 0;
8423e12c5d1SDavid du Colombier 		if(p->cond == P)
8433e12c5d1SDavid du Colombier 			v = p->pc >> 2;
8443e12c5d1SDavid du Colombier 		else
8453e12c5d1SDavid du Colombier 			v = p->cond->pc >> 2;
8463e12c5d1SDavid du Colombier 		o1 = OP_JMP(opirr(p->as), v);
847219b2ee8SDavid du Colombier 		if(!debug['Y'] && p->link && p->cond && isnop(p->link)) {
848219b2ee8SDavid du Colombier 			nop.branch.count--;
849219b2ee8SDavid du Colombier 			nop.branch.outof--;
850219b2ee8SDavid du Colombier 			nop.jump.outof++;
8513e12c5d1SDavid du Colombier 			o2 = asmout(p->cond, oplook(p->cond), 1);
8523e12c5d1SDavid du Colombier 			if(o2) {
8533e12c5d1SDavid du Colombier 				o1 += 1;
8543e12c5d1SDavid du Colombier 				if(debug['a'])
855219b2ee8SDavid du Colombier 					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n",
856219b2ee8SDavid du Colombier 						p->pc, o1, o2, p);
8573e12c5d1SDavid du Colombier 				LPUT(o1);
8583e12c5d1SDavid du Colombier 				LPUT(o2);
8593e12c5d1SDavid du Colombier 				return 1;
8603e12c5d1SDavid du Colombier 			}
8613e12c5d1SDavid du Colombier 		}
8623e12c5d1SDavid du Colombier 		break;
8633e12c5d1SDavid du Colombier 
8643e12c5d1SDavid du Colombier 	case 12:	/* movbs r,r */
8653e12c5d1SDavid du Colombier 		v = 16;
8663e12c5d1SDavid du Colombier 		if(p->as == AMOVB)
8673e12c5d1SDavid du Colombier 			v = 24;
8683e12c5d1SDavid du Colombier 		o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg);
8693e12c5d1SDavid du Colombier 		o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg);
8703e12c5d1SDavid du Colombier 		break;
8713e12c5d1SDavid du Colombier 
8723e12c5d1SDavid du Colombier 	case 13:	/* movbu r,r */
8733e12c5d1SDavid du Colombier 		if(p->as == AMOVBU)
8743e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg);
8753e12c5d1SDavid du Colombier 		else
8763e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg);
8773e12c5d1SDavid du Colombier 		break;
8783e12c5d1SDavid du Colombier 
8793e12c5d1SDavid du Colombier 	case 16:	/* sll $c,[r1],r2 */
8803e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8813e12c5d1SDavid du Colombier 		r = p->reg;
8823e12c5d1SDavid du Colombier 		if(r == NREG)
8833e12c5d1SDavid du Colombier 			r = p->to.reg;
884219b2ee8SDavid du Colombier 		if(v >= 32)
885219b2ee8SDavid du Colombier 			o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg);
886219b2ee8SDavid du Colombier 		else
8873e12c5d1SDavid du Colombier 			o1 = OP_SRR(opirr(p->as), v, r, p->to.reg);
8883e12c5d1SDavid du Colombier 		break;
8893e12c5d1SDavid du Colombier 
8903e12c5d1SDavid du Colombier 	case 18:	/* jmp [r1],0(r2) */
8913e12c5d1SDavid du Colombier 		if(aflag)
8923e12c5d1SDavid du Colombier 			return 0;
8933e12c5d1SDavid du Colombier 		r = p->reg;
8943e12c5d1SDavid du Colombier 		if(r == NREG)
8953e12c5d1SDavid du Colombier 			r = o->param;
8963e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r);
8973e12c5d1SDavid du Colombier 		break;
8983e12c5d1SDavid du Colombier 
8993e12c5d1SDavid du Colombier 	case 19:	/* mov $lcon,r ==> lu+or */
9003e12c5d1SDavid du Colombier 		v = regoff(&p->from);
901219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9023e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg);
9033e12c5d1SDavid du Colombier 		break;
9043e12c5d1SDavid du Colombier 
905219b2ee8SDavid du Colombier 	case 20:	/* mov lohi,r */
906219b2ee8SDavid du Colombier 		r = OP(2,0);		/* mfhi */
9073e12c5d1SDavid du Colombier 		if(p->from.type == D_LO)
908219b2ee8SDavid du Colombier 			r = OP(2,2);	/* mflo */
909219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg);
9103e12c5d1SDavid du Colombier 		break;
9113e12c5d1SDavid du Colombier 
912219b2ee8SDavid du Colombier 	case 21:	/* mov r,lohi */
913219b2ee8SDavid du Colombier 		r = OP(2,1);		/* mthi */
9143e12c5d1SDavid du Colombier 		if(p->to.type == D_LO)
915219b2ee8SDavid du Colombier 			r = OP(2,3);	/* mtlo */
916219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO);
9173e12c5d1SDavid du Colombier 		break;
9183e12c5d1SDavid du Colombier 
9193e12c5d1SDavid du Colombier 	case 22:	/* mul r1,r2 */
9203e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO);
9213e12c5d1SDavid du Colombier 		break;
9223e12c5d1SDavid du Colombier 
9233e12c5d1SDavid du Colombier 	case 23:	/* add $lcon,r1,r2 ==> lu+or+add */
9243e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9253e12c5d1SDavid du Colombier 		if(p->to.reg == REGTMP || p->reg == REGTMP)
9263e12c5d1SDavid du Colombier 			diag("cant synthesize large constant\n%P\n", p);
927219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9283e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
9293e12c5d1SDavid du Colombier 		r = p->reg;
9303e12c5d1SDavid du Colombier 		if(r == NREG)
9313e12c5d1SDavid du Colombier 			r = p->to.reg;
9323e12c5d1SDavid du Colombier 		o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
9333e12c5d1SDavid du Colombier 		break;
9343e12c5d1SDavid du Colombier 
9353e12c5d1SDavid du Colombier 	case 24:	/* mov $ucon,,r ==> lu r */
9363e12c5d1SDavid du Colombier 		v = regoff(&p->from);
937219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9383e12c5d1SDavid du Colombier 		break;
9393e12c5d1SDavid du Colombier 
9403e12c5d1SDavid du Colombier 	case 25:	/* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */
9413e12c5d1SDavid du Colombier 		v = regoff(&p->from);
942219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9433e12c5d1SDavid du Colombier 		r = p->reg;
9443e12c5d1SDavid du Colombier 		if(r == NREG)
9453e12c5d1SDavid du Colombier 			r = p->to.reg;
9463e12c5d1SDavid du Colombier 		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
9473e12c5d1SDavid du Colombier 		break;
9483e12c5d1SDavid du Colombier 
9493e12c5d1SDavid du Colombier 	case 26:	/* mov $lsext/auto/oreg,,r2 ==> lu+or+add */
9503e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9513e12c5d1SDavid du Colombier 		if(p->to.reg == REGTMP)
9523e12c5d1SDavid du Colombier 			diag("cant synthesize large constant\n%P\n", p);
953219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9543e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
9553e12c5d1SDavid du Colombier 		r = p->from.reg;
9563e12c5d1SDavid du Colombier 		if(r == NREG)
9573e12c5d1SDavid du Colombier 			r = o->param;
958219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg);
9593e12c5d1SDavid du Colombier 		break;
9603e12c5d1SDavid du Colombier 
9613e12c5d1SDavid du Colombier 	case 27:		/* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
9623e12c5d1SDavid du Colombier 		r = p->from.reg;
9633e12c5d1SDavid du Colombier 		if(r == NREG)
9643e12c5d1SDavid du Colombier 			r = o->param;
9653e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9663e12c5d1SDavid du Colombier 		switch(o->size) {
967219b2ee8SDavid du Colombier 		case 20:
968219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
969219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
970219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
971219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1);
972219b2ee8SDavid du Colombier 			o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg);
9733e12c5d1SDavid du Colombier 			break;
974219b2ee8SDavid du Colombier 		case 16:
975219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
976219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
977219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
978219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg);
9793e12c5d1SDavid du Colombier 			break;
9803e12c5d1SDavid du Colombier 		case 8:
981219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1);
982219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg);
9833e12c5d1SDavid du Colombier 			break;
9843e12c5d1SDavid du Colombier 		case 4:
985219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg);
9863e12c5d1SDavid du Colombier 			break;
9873e12c5d1SDavid du Colombier 		}
9883e12c5d1SDavid du Colombier 		break;
9893e12c5d1SDavid du Colombier 
9903e12c5d1SDavid du Colombier 	case 28:		/* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */
9913e12c5d1SDavid du Colombier 		r = p->to.reg;
9923e12c5d1SDavid du Colombier 		if(r == NREG)
9933e12c5d1SDavid du Colombier 			r = o->param;
9943e12c5d1SDavid du Colombier 		v = regoff(&p->to);
9953e12c5d1SDavid du Colombier 		switch(o->size) {
996219b2ee8SDavid du Colombier 		case 20:
997219b2ee8SDavid du Colombier 			if(r == REGTMP)
998219b2ee8SDavid du Colombier 				diag("cant synthesize large constant\n%P\n", p);
999219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1000219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1001219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1002219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1);
1003219b2ee8SDavid du Colombier 			o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg);
10043e12c5d1SDavid du Colombier 			break;
1005219b2ee8SDavid du Colombier 		case 16:
1006219b2ee8SDavid du Colombier 			if(r == REGTMP)
1007219b2ee8SDavid du Colombier 				diag("cant synthesize large constant\n%P\n", p);
1008219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1009219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1010219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1011219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg);
10123e12c5d1SDavid du Colombier 			break;
10133e12c5d1SDavid du Colombier 		case 8:
10143e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1);
10153e12c5d1SDavid du Colombier 			o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg);
10163e12c5d1SDavid du Colombier 			break;
10173e12c5d1SDavid du Colombier 		case 4:
10183e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg);
10193e12c5d1SDavid du Colombier 			break;
10203e12c5d1SDavid du Colombier 		}
10213e12c5d1SDavid du Colombier 		break;
10223e12c5d1SDavid du Colombier 
10233e12c5d1SDavid du Colombier 	case 30:	/* movw r,fr */
1024219b2ee8SDavid du Colombier 		r = SP(2,1)|(4<<21);		/* mtc1 */
1025219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
10263e12c5d1SDavid du Colombier 		break;
10273e12c5d1SDavid du Colombier 
10283e12c5d1SDavid du Colombier 	case 31:	/* movw fr,r */
1029219b2ee8SDavid du Colombier 		r = SP(2,1)|(0<<21);		/* mfc1 */
1030219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
10313e12c5d1SDavid du Colombier 		break;
10323e12c5d1SDavid du Colombier 
10333e12c5d1SDavid du Colombier 	case 32:	/* fadd fr1,[fr2],fr3 */
10343e12c5d1SDavid du Colombier 		r = p->reg;
10353e12c5d1SDavid du Colombier 		if(r == NREG)
10363e12c5d1SDavid du Colombier 			o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg);
10373e12c5d1SDavid du Colombier 		else
10383e12c5d1SDavid du Colombier 			o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg);
10393e12c5d1SDavid du Colombier 		break;
10403e12c5d1SDavid du Colombier 
10413e12c5d1SDavid du Colombier 	case 33:	/* fabs fr1,fr3 */
10423e12c5d1SDavid du Colombier 		o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg);
10433e12c5d1SDavid du Colombier 		break;
10443e12c5d1SDavid du Colombier 
10453e12c5d1SDavid du Colombier 	case 34:	/* mov $con,fr ==> or/add $i,r,r2 */
10463e12c5d1SDavid du Colombier 		v = regoff(&p->from);
1047219b2ee8SDavid du Colombier 		r = AADDU;
10483e12c5d1SDavid du Colombier 		if(o->a1 == C_ANDCON)
10493e12c5d1SDavid du Colombier 			r = AOR;
10503e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(r), v, 0, REGTMP);
1051219b2ee8SDavid du Colombier 		o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg);	/* mtc1 */
10523e12c5d1SDavid du Colombier 		break;
10533e12c5d1SDavid du Colombier 
10543e12c5d1SDavid du Colombier 	case 35:	/* mov r,lext/luto/oreg ==> sw o(r) */
1055219b2ee8SDavid du Colombier 		/*
1056219b2ee8SDavid du Colombier 		 * the lowbits of the constant cannot
1057219b2ee8SDavid du Colombier 		 * be moved into the offset of the load
1058219b2ee8SDavid du Colombier 		 * because the mips 4000 in 64-bit mode
1059219b2ee8SDavid du Colombier 		 * does a 64-bit add and it will screw up.
1060219b2ee8SDavid du Colombier 		 */
10613e12c5d1SDavid du Colombier 		v = regoff(&p->to);
10623e12c5d1SDavid du Colombier 		r = p->to.reg;
10633e12c5d1SDavid du Colombier 		if(r == NREG)
10643e12c5d1SDavid du Colombier 			r = o->param;
1065219b2ee8SDavid du Colombier 		if(r == REGTMP)
1066219b2ee8SDavid du Colombier 			diag("cant synthesize large constant\n%P\n", p);
1067219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1068219b2ee8SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1069219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1070219b2ee8SDavid du Colombier 		o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg);
10713e12c5d1SDavid du Colombier 		break;
10723e12c5d1SDavid du Colombier 
10733e12c5d1SDavid du Colombier 	case 36:	/* mov lext/lauto/lreg,r ==> lw o(r30) */
10743e12c5d1SDavid du Colombier 		v = regoff(&p->from);
10753e12c5d1SDavid du Colombier 		r = p->from.reg;
10763e12c5d1SDavid du Colombier 		if(r == NREG)
10773e12c5d1SDavid du Colombier 			r = o->param;
1078219b2ee8SDavid du Colombier 		if(r == REGTMP)
1079219b2ee8SDavid du Colombier 			diag("cant synthesize large constant\n%P\n", p);
1080219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1081219b2ee8SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1082219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1083219b2ee8SDavid du Colombier 		o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg);
10843e12c5d1SDavid du Colombier 		break;
10853e12c5d1SDavid du Colombier 
10863e12c5d1SDavid du Colombier 	case 37:	/* movw r,mr */
1087219b2ee8SDavid du Colombier 		r = SP(2,0)|(4<<21);		/* mtc0 */
1088219b2ee8SDavid du Colombier 		if(p->as == AMOVV)
1089219b2ee8SDavid du Colombier 			r = SP(2,0)|(5<<21);	/* dmtc0 */
1090219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
10913e12c5d1SDavid du Colombier 		break;
10923e12c5d1SDavid du Colombier 
10933e12c5d1SDavid du Colombier 	case 38:	/* movw mr,r */
1094219b2ee8SDavid du Colombier 		r = SP(2,0)|(0<<21);		/* mfc0 */
1095219b2ee8SDavid du Colombier 		if(p->as == AMOVV)
1096219b2ee8SDavid du Colombier 			r = SP(2,0)|(1<<21);	/* dmfc0 */
1097219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
10983e12c5d1SDavid du Colombier 		break;
10993e12c5d1SDavid du Colombier 
11003e12c5d1SDavid du Colombier 	case 39:	/* rfe ==> jmp+rfe */
11013e12c5d1SDavid du Colombier 		if(aflag)
11023e12c5d1SDavid du Colombier 			return 0;
11033e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO);
11043e12c5d1SDavid du Colombier 		o2 = oprrr(p->as);
11053e12c5d1SDavid du Colombier 		break;
11063e12c5d1SDavid du Colombier 
11073e12c5d1SDavid du Colombier 	case 40:	/* word */
11083e12c5d1SDavid du Colombier 		if(aflag)
11093e12c5d1SDavid du Colombier 			return 0;
11103e12c5d1SDavid du Colombier 		o1 = regoff(&p->to);
11113e12c5d1SDavid du Colombier 		break;
11123e12c5d1SDavid du Colombier 
11133e12c5d1SDavid du Colombier 	case 41:	/* movw r,fcr */
1114219b2ee8SDavid du Colombier 		o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); 	/* mfcc1 */
1115219b2ee8SDavid du Colombier 		o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */
11163e12c5d1SDavid du Colombier 		break;
11173e12c5d1SDavid du Colombier 
11183e12c5d1SDavid du Colombier 	case 42:	/* movw fcr,r */
1119219b2ee8SDavid du Colombier 		o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */
11203e12c5d1SDavid du Colombier 		break;
1121*7dd7cddfSDavid du Colombier 
1122*7dd7cddfSDavid du Colombier 	case 45:	/* case r */
1123*7dd7cddfSDavid du Colombier 		if(p->link == P)
1124*7dd7cddfSDavid du Colombier 			v = p->pc+28;
1125*7dd7cddfSDavid du Colombier 		else
1126*7dd7cddfSDavid du Colombier 			v = p->link->pc;
1127*7dd7cddfSDavid du Colombier 		if(v & (1<<15))
1128*7dd7cddfSDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP);
1129*7dd7cddfSDavid du Colombier 		else
1130*7dd7cddfSDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1131*7dd7cddfSDavid du Colombier 		o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg);
1132*7dd7cddfSDavid du Colombier 		o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP);
1133*7dd7cddfSDavid du Colombier 		o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP);
1134*7dd7cddfSDavid du Colombier 		o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
1135*7dd7cddfSDavid du Colombier 		o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO);
1136*7dd7cddfSDavid du Colombier 		o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
1137*7dd7cddfSDavid du Colombier 		break;
1138*7dd7cddfSDavid du Colombier 
1139*7dd7cddfSDavid du Colombier 	case 46:	/* bcase $con,lbra */
1140*7dd7cddfSDavid du Colombier 		if(p->cond == P)
1141*7dd7cddfSDavid du Colombier 			v = p->pc;
1142*7dd7cddfSDavid du Colombier 		else
1143*7dd7cddfSDavid du Colombier 			v = p->cond->pc;
1144*7dd7cddfSDavid du Colombier 		o1 = v;
1145*7dd7cddfSDavid du Colombier 		break;
11463e12c5d1SDavid du Colombier 	}
11473e12c5d1SDavid du Colombier 	if(aflag)
11483e12c5d1SDavid du Colombier 		return o1;
11493e12c5d1SDavid du Colombier 	v = p->pc;
11503e12c5d1SDavid du Colombier 	switch(o->size) {
11513e12c5d1SDavid du Colombier 	default:
11523e12c5d1SDavid du Colombier 		if(debug['a'])
11533e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
11543e12c5d1SDavid du Colombier 		break;
11553e12c5d1SDavid du Colombier 	case 4:
11563e12c5d1SDavid du Colombier 		if(debug['a'])
11573e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
11583e12c5d1SDavid du Colombier 		LPUT(o1);
11593e12c5d1SDavid du Colombier 		break;
11603e12c5d1SDavid du Colombier 	case 8:
11613e12c5d1SDavid du Colombier 		if(debug['a'])
11623e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
11633e12c5d1SDavid du Colombier 		LPUT(o1);
11643e12c5d1SDavid du Colombier 		LPUT(o2);
11653e12c5d1SDavid du Colombier 		break;
11663e12c5d1SDavid du Colombier 	case 12:
11673e12c5d1SDavid du Colombier 		if(debug['a'])
11683e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
11693e12c5d1SDavid du Colombier 		LPUT(o1);
11703e12c5d1SDavid du Colombier 		LPUT(o2);
11713e12c5d1SDavid du Colombier 		LPUT(o3);
11723e12c5d1SDavid du Colombier 		break;
11733e12c5d1SDavid du Colombier 	case 16:
11743e12c5d1SDavid du Colombier 		if(debug['a'])
11753e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
11763e12c5d1SDavid du Colombier 				v, o1, o2, o3, o4, p);
11773e12c5d1SDavid du Colombier 		LPUT(o1);
11783e12c5d1SDavid du Colombier 		LPUT(o2);
11793e12c5d1SDavid du Colombier 		LPUT(o3);
11803e12c5d1SDavid du Colombier 		LPUT(o4);
11813e12c5d1SDavid du Colombier 		break;
1182219b2ee8SDavid du Colombier 	case 20:
1183219b2ee8SDavid du Colombier 		if(debug['a'])
1184219b2ee8SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
1185219b2ee8SDavid du Colombier 				v, o1, o2, o3, o4, o5, p);
1186219b2ee8SDavid du Colombier 		LPUT(o1);
1187219b2ee8SDavid du Colombier 		LPUT(o2);
1188219b2ee8SDavid du Colombier 		LPUT(o3);
1189219b2ee8SDavid du Colombier 		LPUT(o4);
1190219b2ee8SDavid du Colombier 		LPUT(o5);
1191219b2ee8SDavid du Colombier 		break;
1192*7dd7cddfSDavid du Colombier 
1193*7dd7cddfSDavid du Colombier 	case 28:
1194*7dd7cddfSDavid du Colombier 		if(debug['a'])
1195*7dd7cddfSDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
1196*7dd7cddfSDavid du Colombier 				v, o1, o2, o3, o4, o5, o6, o7, p);
1197*7dd7cddfSDavid du Colombier 		LPUT(o1);
1198*7dd7cddfSDavid du Colombier 		LPUT(o2);
1199*7dd7cddfSDavid du Colombier 		LPUT(o3);
1200*7dd7cddfSDavid du Colombier 		LPUT(o4);
1201*7dd7cddfSDavid du Colombier 		LPUT(o5);
1202*7dd7cddfSDavid du Colombier 		LPUT(o6);
1203*7dd7cddfSDavid du Colombier 		LPUT(o7);
1204*7dd7cddfSDavid du Colombier 		break;
12053e12c5d1SDavid du Colombier 	}
12063e12c5d1SDavid du Colombier 	return 0;
12073e12c5d1SDavid du Colombier }
12083e12c5d1SDavid du Colombier 
1209219b2ee8SDavid du Colombier int
1210219b2ee8SDavid du Colombier isnop(Prog *p)
1211219b2ee8SDavid du Colombier {
1212219b2ee8SDavid du Colombier 	if(p->as != ANOR)
1213219b2ee8SDavid du Colombier 		return 0;
1214219b2ee8SDavid du Colombier 	if(p->reg != REGZERO && p->reg != NREG)
1215219b2ee8SDavid du Colombier 		return 0;
1216219b2ee8SDavid du Colombier 	if(p->from.type != D_REG || p->from.reg != REGZERO)
1217219b2ee8SDavid du Colombier 		return 0;
1218219b2ee8SDavid du Colombier 	if(p->to.type != D_REG || p->to.reg != REGZERO)
1219219b2ee8SDavid du Colombier 		return 0;
1220219b2ee8SDavid du Colombier 	return 1;
1221219b2ee8SDavid du Colombier }
12223e12c5d1SDavid du Colombier 
12233e12c5d1SDavid du Colombier long
12243e12c5d1SDavid du Colombier oprrr(int a)
12253e12c5d1SDavid du Colombier {
12263e12c5d1SDavid du Colombier 	switch(a) {
12273e12c5d1SDavid du Colombier 	case AADD:	return OP(4,0);
12283e12c5d1SDavid du Colombier 	case AADDU:	return OP(4,1);
12293e12c5d1SDavid du Colombier 	case ASGT:	return OP(5,2);
12303e12c5d1SDavid du Colombier 	case ASGTU:	return OP(5,3);
12313e12c5d1SDavid du Colombier 	case AAND:	return OP(4,4);
12323e12c5d1SDavid du Colombier 	case AOR:	return OP(4,5);
12333e12c5d1SDavid du Colombier 	case AXOR:	return OP(4,6);
12343e12c5d1SDavid du Colombier 	case ASUB:	return OP(4,2);
12353e12c5d1SDavid du Colombier 	case ASUBU:	return OP(4,3);
12363e12c5d1SDavid du Colombier 	case ANOR:	return OP(4,7);
12373e12c5d1SDavid du Colombier 	case ASLL:	return OP(0,4);
12383e12c5d1SDavid du Colombier 	case ASRL:	return OP(0,6);
12393e12c5d1SDavid du Colombier 	case ASRA:	return OP(0,7);
12403e12c5d1SDavid du Colombier 
12413e12c5d1SDavid du Colombier 	case AREM:
12423e12c5d1SDavid du Colombier 	case ADIV:	return OP(3,2);
12433e12c5d1SDavid du Colombier 	case AREMU:
12443e12c5d1SDavid du Colombier 	case ADIVU:	return OP(3,3);
12453e12c5d1SDavid du Colombier 	case AMUL:	return OP(3,0);
12463e12c5d1SDavid du Colombier 	case AMULU:	return OP(3,1);
12473e12c5d1SDavid du Colombier 
12483e12c5d1SDavid du Colombier 	case AJMP:	return OP(1,0);
12493e12c5d1SDavid du Colombier 	case AJAL:	return OP(1,1);
12503e12c5d1SDavid du Colombier 
12513e12c5d1SDavid du Colombier 	case ABREAK:	return OP(1,5);
12523e12c5d1SDavid du Colombier 	case ASYSCALL:	return OP(1,4);
12533e12c5d1SDavid du Colombier 	case ATLBP:	return MMU(1,0);
12543e12c5d1SDavid du Colombier 	case ATLBR:	return MMU(0,1);
12553e12c5d1SDavid du Colombier 	case ATLBWI:	return MMU(0,2);
12563e12c5d1SDavid du Colombier 	case ATLBWR:	return MMU(0,6);
12573e12c5d1SDavid du Colombier 	case ARFE:	return MMU(2,0);
12583e12c5d1SDavid du Colombier 
12593e12c5d1SDavid du Colombier 	case ADIVF:	return FPF(0,3);
12603e12c5d1SDavid du Colombier 	case ADIVD:	return FPD(0,3);
12613e12c5d1SDavid du Colombier 	case AMULF:	return FPF(0,2);
12623e12c5d1SDavid du Colombier 	case AMULD:	return FPD(0,2);
12633e12c5d1SDavid du Colombier 	case ASUBF:	return FPF(0,1);
12643e12c5d1SDavid du Colombier 	case ASUBD:	return FPD(0,1);
12653e12c5d1SDavid du Colombier 	case AADDF:	return FPF(0,0);
12663e12c5d1SDavid du Colombier 	case AADDD:	return FPD(0,0);
12673e12c5d1SDavid du Colombier 
12683e12c5d1SDavid du Colombier 	case AMOVFW:	return FPF(4,4);
12693e12c5d1SDavid du Colombier 	case AMOVDW:	return FPD(4,4);
12703e12c5d1SDavid du Colombier 	case AMOVWF:	return FPW(4,0);
12713e12c5d1SDavid du Colombier 	case AMOVDF:	return FPD(4,0);
12723e12c5d1SDavid du Colombier 	case AMOVWD:	return FPW(4,1);
12733e12c5d1SDavid du Colombier 	case AMOVFD:	return FPF(4,1);
12743e12c5d1SDavid du Colombier 	case AABSF:	return FPF(0,5);
12753e12c5d1SDavid du Colombier 	case AABSD:	return FPD(0,5);
12763e12c5d1SDavid du Colombier 	case AMOVF:	return FPF(0,6);
12773e12c5d1SDavid du Colombier 	case AMOVD:	return FPD(0,6);
12783e12c5d1SDavid du Colombier 	case ANEGF:	return FPF(0,7);
12793e12c5d1SDavid du Colombier 	case ANEGD:	return FPD(0,7);
12803e12c5d1SDavid du Colombier 
12813e12c5d1SDavid du Colombier 	case ACMPEQF:	return FPF(6,2);
12823e12c5d1SDavid du Colombier 	case ACMPEQD:	return FPD(6,2);
12833e12c5d1SDavid du Colombier 	case ACMPGTF:	return FPF(7,4);
12843e12c5d1SDavid du Colombier 	case ACMPGTD:	return FPD(7,4);
12853e12c5d1SDavid du Colombier 	case ACMPGEF:	return FPF(7,6);
12863e12c5d1SDavid du Colombier 	case ACMPGED:	return FPD(7,6);
1287*7dd7cddfSDavid du Colombier 
1288*7dd7cddfSDavid du Colombier 	case ADIVV:	return OP(3,6);
1289*7dd7cddfSDavid du Colombier 	case ADIVVU:	return OP(3,7);
1290*7dd7cddfSDavid du Colombier 	case AADDV:	return OP(5,4);
1291*7dd7cddfSDavid du Colombier 	case AADDVU:	return OP(5,5);
12923e12c5d1SDavid du Colombier 	}
12933e12c5d1SDavid du Colombier 	diag("bad rrr %d\n", a);
12943e12c5d1SDavid du Colombier 	return 0;
12953e12c5d1SDavid du Colombier }
12963e12c5d1SDavid du Colombier 
12973e12c5d1SDavid du Colombier long
12983e12c5d1SDavid du Colombier opirr(int a)
12993e12c5d1SDavid du Colombier {
13003e12c5d1SDavid du Colombier 	switch(a) {
13013e12c5d1SDavid du Colombier 	case AADD:	return SP(1,0);
13023e12c5d1SDavid du Colombier 	case AADDU:	return SP(1,1);
13033e12c5d1SDavid du Colombier 	case ASGT:	return SP(1,2);
13043e12c5d1SDavid du Colombier 	case ASGTU:	return SP(1,3);
13053e12c5d1SDavid du Colombier 	case AAND:	return SP(1,4);
13063e12c5d1SDavid du Colombier 	case AOR:	return SP(1,5);
13073e12c5d1SDavid du Colombier 	case AXOR:	return SP(1,6);
1308219b2ee8SDavid du Colombier 	case ALAST:	return SP(1,7);
13093e12c5d1SDavid du Colombier 	case ASLL:	return OP(0,0);
13103e12c5d1SDavid du Colombier 	case ASRL:	return OP(0,2);
13113e12c5d1SDavid du Colombier 	case ASRA:	return OP(0,3);
13123e12c5d1SDavid du Colombier 
13133e12c5d1SDavid du Colombier 	case AJMP:	return SP(0,2);
13143e12c5d1SDavid du Colombier 	case AJAL:	return SP(0,3);
13153e12c5d1SDavid du Colombier 	case ABEQ:	return SP(0,4);
13163e12c5d1SDavid du Colombier 	case ABNE:	return SP(0,5);
13173e12c5d1SDavid du Colombier 
13183e12c5d1SDavid du Colombier 	case ABGEZ:	return SP(0,1)|BCOND(0,1);
13193e12c5d1SDavid du Colombier 	case ABGEZAL:	return SP(0,1)|BCOND(2,1);
13203e12c5d1SDavid du Colombier 	case ABGTZ:	return SP(0,7);
13213e12c5d1SDavid du Colombier 	case ABLEZ:	return SP(0,6);
13223e12c5d1SDavid du Colombier 	case ABLTZ:	return SP(0,1)|BCOND(0,0);
13233e12c5d1SDavid du Colombier 	case ABLTZAL:	return SP(0,1)|BCOND(2,0);
13243e12c5d1SDavid du Colombier 
13253e12c5d1SDavid du Colombier 	case ABFPT:	return SP(2,1)|(257<<16);
13263e12c5d1SDavid du Colombier 	case ABFPF:	return SP(2,1)|(256<<16);
13273e12c5d1SDavid du Colombier 
13283e12c5d1SDavid du Colombier 	case AMOVB:
13293e12c5d1SDavid du Colombier 	case AMOVBU:	return SP(5,0);
13303e12c5d1SDavid du Colombier 	case AMOVH:
13313e12c5d1SDavid du Colombier 	case AMOVHU:	return SP(5,1);
13323e12c5d1SDavid du Colombier 	case AMOVW:	return SP(5,3);
1333219b2ee8SDavid du Colombier 	case AMOVV:	return SP(7,7);
13343e12c5d1SDavid du Colombier 	case AMOVF:	return SP(7,1);
13353e12c5d1SDavid du Colombier 	case AMOVWL:	return SP(5,2);
13363e12c5d1SDavid du Colombier 	case AMOVWR:	return SP(5,6);
1337219b2ee8SDavid du Colombier 	case AMOVVL:	return SP(5,4);
1338219b2ee8SDavid du Colombier 	case AMOVVR:	return SP(5,5);
13393e12c5d1SDavid du Colombier 
1340bd389b36SDavid du Colombier 	case ABREAK:	return SP(5,7);
1341bd389b36SDavid du Colombier 
1342219b2ee8SDavid du Colombier 	case AMOVWL+ALAST:	return SP(4,2);
1343219b2ee8SDavid du Colombier 	case AMOVWR+ALAST:	return SP(4,6);
1344219b2ee8SDavid du Colombier 	case AMOVVL+ALAST:	return SP(3,2);
1345219b2ee8SDavid du Colombier 	case AMOVVR+ALAST:	return SP(3,3);
1346219b2ee8SDavid du Colombier 	case AMOVB+ALAST:	return SP(4,0);
1347219b2ee8SDavid du Colombier 	case AMOVBU+ALAST:	return SP(4,4);
1348219b2ee8SDavid du Colombier 	case AMOVH+ALAST:	return SP(4,1);
1349219b2ee8SDavid du Colombier 	case AMOVHU+ALAST:	return SP(4,5);
1350219b2ee8SDavid du Colombier 	case AMOVW+ALAST:	return SP(4,3);
1351219b2ee8SDavid du Colombier 	case AMOVV+ALAST:	return SP(6,7);
1352219b2ee8SDavid du Colombier 	case AMOVF+ALAST:	return SP(6,1);
13533e12c5d1SDavid du Colombier 
1354219b2ee8SDavid du Colombier 	case ASLLV:		return OP(7,0);
1355219b2ee8SDavid du Colombier 	case ASRLV:		return OP(7,2);
1356219b2ee8SDavid du Colombier 	case ASRAV:		return OP(7,3);
1357219b2ee8SDavid du Colombier 	case ASLLV+ALAST:	return OP(7,4);
1358219b2ee8SDavid du Colombier 	case ASRLV+ALAST:	return OP(7,6);
1359219b2ee8SDavid du Colombier 	case ASRAV+ALAST:	return OP(7,7);
1360*7dd7cddfSDavid du Colombier 
1361*7dd7cddfSDavid du Colombier 	case AADDV:		return SP(3,0);
1362*7dd7cddfSDavid du Colombier 	case AADDVU:		return SP(3,1);
13633e12c5d1SDavid du Colombier 	}
13643e12c5d1SDavid du Colombier 	diag("bad irr %d\n", a);
13653e12c5d1SDavid du Colombier 	return 0;
13663e12c5d1SDavid du Colombier }
1367