xref: /plan9-contrib/sys/src/cmd/vl/asm.c (revision 08d89a7ddd3efcb6506e1dba5a76916c48fe9a2f)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33305c317SDavid du Colombier /* can't include a.out.h due to name clashes, but these are taken from it */
43305c317SDavid du Colombier #define	_MAGIC(f, b)	((f)|((((4*(b))+0)*(b))+7))
53305c317SDavid du Colombier #define	V_MAGIC		_MAGIC(0, 16)		/* mips 3000 BE */
63305c317SDavid du Colombier #define	M_MAGIC		_MAGIC(0, 18)		/* mips 4000 BE */
73305c317SDavid du Colombier #define	N_MAGIC		_MAGIC(0, 22)		/* mips 4000 LE */
83305c317SDavid du Colombier #define	P_MAGIC		_MAGIC(0, 24)		/* mips 3000 LE */
93305c317SDavid du Colombier 
10bd389b36SDavid du Colombier long	OFFSET;
11bd389b36SDavid du Colombier /*
12bd389b36SDavid du Colombier long	BADOFFSET	=	-1;
13bd389b36SDavid du Colombier 
14bd389b36SDavid du Colombier 		if(OFFSET <= BADOFFSET && OFFSET+4 > BADOFFSET)\
15bd389b36SDavid du Colombier 			abort();\
16bd389b36SDavid du Colombier 		OFFSET += 4;\
17bd389b36SDavid du Colombier 
18bd389b36SDavid du Colombier 		if(OFFSET == BADOFFSET)\
19bd389b36SDavid du Colombier 			abort();\
20bd389b36SDavid du Colombier 		OFFSET++;\
21bd389b36SDavid du Colombier */
22bd389b36SDavid du Colombier 
2391178603SDavid du Colombier #define LPUT(l) { \
2491178603SDavid du Colombier 		if (little) { \
2591178603SDavid du Colombier 			LLEPUT(l); \
2691178603SDavid du Colombier 		} else { \
2791178603SDavid du Colombier 			LBEPUT(l); \
2891178603SDavid du Colombier 		} \
2991178603SDavid du Colombier 	}
3091178603SDavid du Colombier 
3191178603SDavid du Colombier #define	LLEPUT(c)\
3291178603SDavid du Colombier 	{\
3391178603SDavid du Colombier 		cbp[0] = (c);\
3491178603SDavid du Colombier 		cbp[1] = (c)>>8;\
3591178603SDavid du Colombier 		cbp[2] = (c)>>16;\
3691178603SDavid du Colombier 		cbp[3] = (c)>>24;\
3791178603SDavid du Colombier 		cbp += 4;\
3891178603SDavid du Colombier 		cbc -= 4;\
3991178603SDavid du Colombier 		if(cbc <= 0)\
4091178603SDavid du Colombier 			cflush();\
4191178603SDavid du Colombier 	}
4291178603SDavid du Colombier 
4391178603SDavid du Colombier #define	LBEPUT(c)\
443e12c5d1SDavid du Colombier 	{\
453e12c5d1SDavid du Colombier 		cbp[0] = (c)>>24;\
463e12c5d1SDavid du Colombier 		cbp[1] = (c)>>16;\
473e12c5d1SDavid du Colombier 		cbp[2] = (c)>>8;\
483e12c5d1SDavid du Colombier 		cbp[3] = (c);\
493e12c5d1SDavid du Colombier 		cbp += 4;\
503e12c5d1SDavid du Colombier 		cbc -= 4;\
513e12c5d1SDavid du Colombier 		if(cbc <= 0)\
523e12c5d1SDavid du Colombier 			cflush();\
533e12c5d1SDavid du Colombier 	}
543e12c5d1SDavid du Colombier 
55bfb6eab9SDavid du Colombier #define HPUT(h) { \
56bfb6eab9SDavid du Colombier 		if (little) { \
57bfb6eab9SDavid du Colombier 			HLEPUT(h); \
58bfb6eab9SDavid du Colombier 		} else { \
59bfb6eab9SDavid du Colombier 			HBEPUT(h); \
60bfb6eab9SDavid du Colombier 		} \
61bfb6eab9SDavid du Colombier 	}
62bfb6eab9SDavid du Colombier 
63bfb6eab9SDavid du Colombier #define	HLEPUT(c)\
64bfb6eab9SDavid du Colombier 	{\
65bfb6eab9SDavid du Colombier 		cbp[0] = (c);\
66bfb6eab9SDavid du Colombier 		cbp[1] = (c)>>8;\
67bfb6eab9SDavid du Colombier 		cbp += 2;\
68bfb6eab9SDavid du Colombier 		cbc -= 2;\
69bfb6eab9SDavid du Colombier 		if(cbc <= 0)\
70bfb6eab9SDavid du Colombier 			cflush();\
71bfb6eab9SDavid du Colombier 	}
72bfb6eab9SDavid du Colombier 
73bfb6eab9SDavid du Colombier #define	HBEPUT(c)\
74bfb6eab9SDavid du Colombier 	{\
75bfb6eab9SDavid du Colombier 		cbp[0] = (c)>>8;\
76bfb6eab9SDavid du Colombier 		cbp[1] = (c);\
77bfb6eab9SDavid du Colombier 		cbp += 2;\
78bfb6eab9SDavid du Colombier 		cbc -= 2;\
79bfb6eab9SDavid du Colombier 		if(cbc <= 0)\
80bfb6eab9SDavid du Colombier 			cflush();\
81bfb6eab9SDavid du Colombier 	}
82bfb6eab9SDavid du Colombier 
8391178603SDavid du Colombier 
843e12c5d1SDavid du Colombier #define	CPUT(c)\
853e12c5d1SDavid du Colombier 	{\
863e12c5d1SDavid du Colombier 		cbp[0] = (c);\
873e12c5d1SDavid du Colombier 		cbp++;\
883e12c5d1SDavid du Colombier 		cbc--;\
893e12c5d1SDavid du Colombier 		if(cbc <= 0)\
903e12c5d1SDavid du Colombier 			cflush();\
913e12c5d1SDavid du Colombier 	}
923e12c5d1SDavid du Colombier 
9391178603SDavid du Colombier void
948153b942SDavid du Colombier cput(long l)
958153b942SDavid du Colombier {
968153b942SDavid du Colombier 	CPUT(l);
978153b942SDavid du Colombier }
988153b942SDavid du Colombier 
998153b942SDavid du Colombier void
10091178603SDavid du Colombier objput(long l)	/* emit long in byte order appropriate to object machine */
10191178603SDavid du Colombier {
10291178603SDavid du Colombier 	LPUT(l);
10391178603SDavid du Colombier }
10491178603SDavid du Colombier 
10591178603SDavid du Colombier void
106bfb6eab9SDavid du Colombier objhput(short s)
107bfb6eab9SDavid du Colombier {
108bfb6eab9SDavid du Colombier 	HPUT(s);
109bfb6eab9SDavid du Colombier }
110bfb6eab9SDavid du Colombier 
111bfb6eab9SDavid du Colombier void
1128153b942SDavid du Colombier wput(long l)
1138153b942SDavid du Colombier {
1148153b942SDavid du Colombier 
1158153b942SDavid du Colombier 	cbp[0] = l>>8;
1168153b942SDavid du Colombier 	cbp[1] = l;
1178153b942SDavid du Colombier 	cbp += 2;
1188153b942SDavid du Colombier 	cbc -= 2;
1198153b942SDavid du Colombier 	if(cbc <= 0)
1208153b942SDavid du Colombier 		cflush();
1218153b942SDavid du Colombier }
1228153b942SDavid du Colombier 
1238153b942SDavid du Colombier void
1248153b942SDavid du Colombier wputl(long l)
1258153b942SDavid du Colombier {
1268153b942SDavid du Colombier 
1278153b942SDavid du Colombier 	cbp[0] = l;
1288153b942SDavid du Colombier 	cbp[1] = l>>8;
1298153b942SDavid du Colombier 	cbp += 2;
1308153b942SDavid du Colombier 	cbc -= 2;
1318153b942SDavid du Colombier 	if(cbc <= 0)
1328153b942SDavid du Colombier 		cflush();
1338153b942SDavid du Colombier }
1348153b942SDavid du Colombier 
1358153b942SDavid du Colombier void
13691178603SDavid du Colombier lput(long l)		/* emit long in big-endian byte order */
13791178603SDavid du Colombier {
13891178603SDavid du Colombier 	LBEPUT(l);
13991178603SDavid du Colombier }
14091178603SDavid du Colombier 
1418153b942SDavid du Colombier void
1428153b942SDavid du Colombier lputl(long l)		/* emit long in big-endian byte order */
1438153b942SDavid du Colombier {
1448153b942SDavid du Colombier 	LLEPUT(l);
1458153b942SDavid du Colombier }
1468153b942SDavid du Colombier 
1478153b942SDavid du Colombier void
1488153b942SDavid du Colombier llput(vlong v)
1498153b942SDavid du Colombier {
1508153b942SDavid du Colombier 	lput(v>>32);
1518153b942SDavid du Colombier 	lput(v);
1528153b942SDavid du Colombier }
1538153b942SDavid du Colombier 
1548153b942SDavid du Colombier void
1558153b942SDavid du Colombier llputl(vlong v)
1568153b942SDavid du Colombier {
1578153b942SDavid du Colombier 	lputl(v);
1588153b942SDavid du Colombier 	lputl(v>>32);
1598153b942SDavid du Colombier }
1608153b942SDavid du Colombier 
1613e12c5d1SDavid du Colombier long
1623e12c5d1SDavid du Colombier entryvalue(void)
1633e12c5d1SDavid du Colombier {
1643e12c5d1SDavid du Colombier 	char *a;
1653e12c5d1SDavid du Colombier 	Sym *s;
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier 	a = INITENTRY;
1683e12c5d1SDavid du Colombier 	if(*a >= '0' && *a <= '9')
1693e12c5d1SDavid du Colombier 		return atolwhex(a);
1703e12c5d1SDavid du Colombier 	s = lookup(a, 0);
1713e12c5d1SDavid du Colombier 	if(s->type == 0)
1723e12c5d1SDavid du Colombier 		return INITTEXT;
1733e12c5d1SDavid du Colombier 	if(s->type != STEXT && s->type != SLEAF)
1743e12c5d1SDavid du Colombier 		diag("entry not text: %s", s->name);
1753e12c5d1SDavid du Colombier 	return s->value;
1763e12c5d1SDavid du Colombier }
1773e12c5d1SDavid du Colombier 
1785482313dSDavid du Colombier static void
1795482313dSDavid du Colombier plan9bootimage(ulong sects, ulong submagicvers, ulong tm,
1805482313dSDavid du Colombier 	ulong hdrtxtsz, ulong textsz, ulong textva, ulong lcsize)
1815482313dSDavid du Colombier {
1825482313dSDavid du Colombier 	lput(0x160L<<16|sects);		/* magic and sections */
1835482313dSDavid du Colombier 	lput(tm);			/* time and date */
1845482313dSDavid du Colombier 	lput(hdrtxtsz+datsize);		/* offset to symbol table */
1855482313dSDavid du Colombier 	lput(symsize);			/* size of symbol table */
1865482313dSDavid du Colombier 	lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
1875482313dSDavid du Colombier 	lput(submagicvers);		/* magic and version */
1885482313dSDavid du Colombier 
1895482313dSDavid du Colombier 	lput(textsz);			/* segment sizes */
1905482313dSDavid du Colombier 	lput(datsize);
1915482313dSDavid du Colombier 	lput(bsssize);
1925482313dSDavid du Colombier 
1935482313dSDavid du Colombier 	lput(entryvalue());		/* va of entry */
1945482313dSDavid du Colombier 	lput(textva);			/* va of base of text */
1955482313dSDavid du Colombier 	lput(INITDAT);			/* va of base of data */
1965482313dSDavid du Colombier 	lput(INITDAT+datsize);		/* va of base of bss */
1975482313dSDavid du Colombier 
1985482313dSDavid du Colombier 	lput(~0);			/* gp reg mask */
1995482313dSDavid du Colombier 	lput(lcsize);			/* pcsize / cprmask[0] */
2005482313dSDavid du Colombier 	lput(0);			/* coproc reg masks[1⋯3] */
2015482313dSDavid du Colombier 	lput(0);
2025482313dSDavid du Colombier 	lput(0);
2035482313dSDavid du Colombier 	lput(~0);			/* gp value ?? */
2045482313dSDavid du Colombier }
2055482313dSDavid du Colombier 
2065482313dSDavid du Colombier static void
2075482313dSDavid du Colombier symhdrs(ulong hdrtxtsz)
2085482313dSDavid du Colombier {
2095482313dSDavid du Colombier 	strnput(".text", 8);		/* text segment */
2105482313dSDavid du Colombier 	lput(INITTEXT);			/* address */
2115482313dSDavid du Colombier 	lput(INITTEXT);
2125482313dSDavid du Colombier 	lput(textsize);
2135482313dSDavid du Colombier 	lput(HEADR);
2145482313dSDavid du Colombier 	lput(0);
2155482313dSDavid du Colombier 	lput(HEADR+textsize+datsize+symsize);
2165482313dSDavid du Colombier 	lput(lcsize);			/* line number size */
2175482313dSDavid du Colombier 	lput(0x20);			/* flags */
2185482313dSDavid du Colombier 
2195482313dSDavid du Colombier 	strnput(".data", 8);		/* data segment */
2205482313dSDavid du Colombier 	lput(INITDAT);			/* address */
2215482313dSDavid du Colombier 	lput(INITDAT);
2225482313dSDavid du Colombier 	lput(datsize);
2235482313dSDavid du Colombier 	lput(hdrtxtsz);
2245482313dSDavid du Colombier 	lput(0);
2255482313dSDavid du Colombier 	lput(0);
2265482313dSDavid du Colombier 	lput(0);
2275482313dSDavid du Colombier 	lput(0x40);			/* flags */
2285482313dSDavid du Colombier 
2295482313dSDavid du Colombier 	strnput(".bss", 8);		/* bss segment */
2305482313dSDavid du Colombier 	lput(INITDAT+datsize);		/* address */
2315482313dSDavid du Colombier 	lput(INITDAT+datsize);
2325482313dSDavid du Colombier 	lput(bsssize);
2335482313dSDavid du Colombier 	lput(0);
2345482313dSDavid du Colombier 	lput(0);
2355482313dSDavid du Colombier 	lput(0);
2365482313dSDavid du Colombier 	lput(0);
2375482313dSDavid du Colombier 	lput(0x80);			/* flags */
2385482313dSDavid du Colombier }
2395482313dSDavid du Colombier 
2403e12c5d1SDavid du Colombier void
2413e12c5d1SDavid du Colombier asmb(void)
2423e12c5d1SDavid du Colombier {
2433e12c5d1SDavid du Colombier 	Prog *p;
2445482313dSDavid du Colombier 	long tm;
2455482313dSDavid du Colombier 	ulong rndtxtsz;
246a587111cSDavid du Colombier 	vlong t, etext;
2473e12c5d1SDavid du Colombier 	Optab *o;
2483e12c5d1SDavid du Colombier 
2493e12c5d1SDavid du Colombier 	if(debug['v'])
2503e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f asm\n", cputime());
2513e12c5d1SDavid du Colombier 	Bflush(&bso);
252bd389b36SDavid du Colombier 	OFFSET = HEADR;
253bd389b36SDavid du Colombier 	seek(cout, OFFSET, 0);
2543e12c5d1SDavid du Colombier 	pc = INITTEXT;
2553e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
2563e12c5d1SDavid du Colombier 		if(p->as == ATEXT) {
2573e12c5d1SDavid du Colombier 			curtext = p;
2583e12c5d1SDavid du Colombier 			autosize = p->to.offset + 4;
2593e12c5d1SDavid du Colombier 		}
2603e12c5d1SDavid du Colombier 		if(p->pc != pc) {
261a587111cSDavid du Colombier 			diag("phase error %llux sb %llux", p->pc, pc);
2623e12c5d1SDavid du Colombier 			if(!debug['a'])
2633e12c5d1SDavid du Colombier 				prasm(curp);
2643e12c5d1SDavid du Colombier 			pc = p->pc;
2653e12c5d1SDavid du Colombier 		}
2663e12c5d1SDavid du Colombier 		curp = p;
2673e12c5d1SDavid du Colombier 		o = oplook(p);	/* could probably avoid this call */
2683e12c5d1SDavid du Colombier 		if(asmout(p, o, 0)) {
2693e12c5d1SDavid du Colombier 			p = p->link;
2703e12c5d1SDavid du Colombier 			pc += 4;
2713e12c5d1SDavid du Colombier 		}
2723e12c5d1SDavid du Colombier 		pc += o->size;
2733e12c5d1SDavid du Colombier 	}
2743e12c5d1SDavid du Colombier 	if(debug['a'])
2753e12c5d1SDavid du Colombier 		Bprint(&bso, "\n");
2763e12c5d1SDavid du Colombier 	Bflush(&bso);
2773e12c5d1SDavid du Colombier 	cflush();
2783e12c5d1SDavid du Colombier 
2799a747e4fSDavid du Colombier 	etext = INITTEXT + textsize;
2809a747e4fSDavid du Colombier 	for(t = pc; t < etext; t += sizeof(buf)-100) {
2819a747e4fSDavid du Colombier 		if(etext-t > sizeof(buf)-100)
2829a747e4fSDavid du Colombier 			datblk(t, sizeof(buf)-100, 1);
2839a747e4fSDavid du Colombier 		else
2849a747e4fSDavid du Colombier 			datblk(t, etext-t, 1);
2859a747e4fSDavid du Colombier 	}
2869a747e4fSDavid du Colombier 
2879a747e4fSDavid du Colombier 	Bflush(&bso);
2889a747e4fSDavid du Colombier 	cflush();
2899a747e4fSDavid du Colombier 
2903e12c5d1SDavid du Colombier 	curtext = P;
2913e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
2923e12c5d1SDavid du Colombier 	case 0:
293219b2ee8SDavid du Colombier 	case 4:
294bd389b36SDavid du Colombier 		OFFSET = rnd(HEADR+textsize, 4096);
295bd389b36SDavid du Colombier 		seek(cout, OFFSET, 0);
2963e12c5d1SDavid du Colombier 		break;
297*08d89a7dSDavid du Colombier 	case 6:
298*08d89a7dSDavid du Colombier 		OFFSET = rnd(HEADR+textsize, INITRND);
299*08d89a7dSDavid du Colombier 		seek(cout, OFFSET, 0);
300*08d89a7dSDavid du Colombier 		break;
3013e12c5d1SDavid du Colombier 	case 1:
3023e12c5d1SDavid du Colombier 	case 2:
303219b2ee8SDavid du Colombier 	case 3:
304219b2ee8SDavid du Colombier 	case 5:
305a826b788SDavid du Colombier 	case 7:
306bd389b36SDavid du Colombier 		OFFSET = HEADR+textsize;
307bd389b36SDavid du Colombier 		seek(cout, OFFSET, 0);
3083e12c5d1SDavid du Colombier 		break;
3093e12c5d1SDavid du Colombier 	}
3103e12c5d1SDavid du Colombier 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
3113e12c5d1SDavid du Colombier 		if(datsize-t > sizeof(buf)-100)
3129a747e4fSDavid du Colombier 			datblk(t, sizeof(buf)-100, 0);
3133e12c5d1SDavid du Colombier 		else
3149a747e4fSDavid du Colombier 			datblk(t, datsize-t, 0);
3153e12c5d1SDavid du Colombier 	}
3163e12c5d1SDavid du Colombier 
3173e12c5d1SDavid du Colombier 	symsize = 0;
3183e12c5d1SDavid du Colombier 	lcsize = 0;
3193e12c5d1SDavid du Colombier 	if(!debug['s']) {
3203e12c5d1SDavid du Colombier 		if(debug['v'])
3213e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
3223e12c5d1SDavid du Colombier 		Bflush(&bso);
3233e12c5d1SDavid du Colombier 		switch(HEADTYPE) {
3243e12c5d1SDavid du Colombier 		case 0:
325219b2ee8SDavid du Colombier 		case 4:
326bd389b36SDavid du Colombier 			OFFSET = rnd(HEADR+textsize, 4096)+datsize;
327bd389b36SDavid du Colombier 			seek(cout, OFFSET, 0);
3283e12c5d1SDavid du Colombier 			break;
329*08d89a7dSDavid du Colombier 		case 6:
330*08d89a7dSDavid du Colombier 			OFFSET = rnd(HEADR+textsize, INITRND)+datsize;
331*08d89a7dSDavid du Colombier 			seek(cout, OFFSET, 0);
332*08d89a7dSDavid du Colombier 			break;
333219b2ee8SDavid du Colombier 		case 3:
3343e12c5d1SDavid du Colombier 		case 2:
3353e12c5d1SDavid du Colombier 		case 1:
336219b2ee8SDavid du Colombier 		case 5:
337a826b788SDavid du Colombier 		case 7:
338bd389b36SDavid du Colombier 			OFFSET = HEADR+textsize+datsize;
339bd389b36SDavid du Colombier 			seek(cout, OFFSET, 0);
3403e12c5d1SDavid du Colombier 			break;
3413e12c5d1SDavid du Colombier 		}
3423e12c5d1SDavid du Colombier 		if(!debug['s'])
3433e12c5d1SDavid du Colombier 			asmsym();
3443e12c5d1SDavid du Colombier 		if(debug['v'])
3453e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f pc\n", cputime());
3463e12c5d1SDavid du Colombier 		Bflush(&bso);
3473e12c5d1SDavid du Colombier 		if(!debug['s'])
3483e12c5d1SDavid du Colombier 			asmlc();
3493e12c5d1SDavid du Colombier 		cflush();
3503e12c5d1SDavid du Colombier 	}
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier 	if(debug['v'])
3533e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f header\n", cputime());
3543e12c5d1SDavid du Colombier 	Bflush(&bso);
355bd389b36SDavid du Colombier 	OFFSET = 0;
356bd389b36SDavid du Colombier 	seek(cout, OFFSET, 0);
3575482313dSDavid du Colombier 
3585482313dSDavid du Colombier 	rndtxtsz = rnd(HEADR+textsize, (INITRND > 0? INITRND: 4096));
3595482313dSDavid du Colombier 	tm = time(0);
3603e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
3613e12c5d1SDavid du Colombier 	case 0:
3625482313dSDavid du Colombier 		/* 0413: plan 9 boot image, text segment rounded (to 4KB) */
3635482313dSDavid du Colombier 		plan9bootimage(0, 0413<<16|0437, 0, rndtxtsz, rndtxtsz,
3645482313dSDavid du Colombier 			INITTEXT-HEADR, 0);
3653e12c5d1SDavid du Colombier 		break;
3663e12c5d1SDavid du Colombier 	case 1:
3675482313dSDavid du Colombier 		/* 0407: plan 9 boot image, extra word */
3685482313dSDavid du Colombier 		plan9bootimage(0, 0407<<16|0437, 0, HEADR+textsize, textsize,
3695482313dSDavid du Colombier 			INITTEXT, lcsize);
3705482313dSDavid du Colombier 		lput(0);			/* extra; complete mystery */
3713e12c5d1SDavid du Colombier 		break;
3723305c317SDavid du Colombier 	case 2:					/* plan 9 format */
37391178603SDavid du Colombier 		if (little)
3743305c317SDavid du Colombier 			lput(P_MAGIC);		/* mips 3000 LE */
37591178603SDavid du Colombier 		else
3763305c317SDavid du Colombier 			lput(V_MAGIC);		/* mips 3000 BE */
3773e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
3783e12c5d1SDavid du Colombier 		lput(datsize);
3793e12c5d1SDavid du Colombier 		lput(bsssize);
3803e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
3813e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
3823e12c5d1SDavid du Colombier 		lput(0L);
3833e12c5d1SDavid du Colombier 		lput(lcsize);
3843e12c5d1SDavid du Colombier 		break;
385219b2ee8SDavid du Colombier 	case 3:
3865482313dSDavid du Colombier 		/* 0407: plan 9 mips 4k boot image with symbols */
3875482313dSDavid du Colombier 		plan9bootimage(3, 0407<<16|0437, tm, HEADR+textsize, textsize,
3885482313dSDavid du Colombier 			INITTEXT, lcsize);
3895482313dSDavid du Colombier 		symhdrs(HEADR+textsize);
390219b2ee8SDavid du Colombier 		break;
391219b2ee8SDavid du Colombier 	case 4:
3925482313dSDavid du Colombier 		/* 0413: plan 9 mips 4k boot image with symbols */
3935482313dSDavid du Colombier 		plan9bootimage(3, 0413<<16|01012, tm, rndtxtsz, textsize,
3945482313dSDavid du Colombier 			INITTEXT, lcsize);
3955482313dSDavid du Colombier 		symhdrs(rndtxtsz);
396219b2ee8SDavid du Colombier 		break;
397219b2ee8SDavid du Colombier 	case 5:
3988153b942SDavid du Colombier 		elf32(MIPS, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
39991178603SDavid du Colombier 		break;
40091178603SDavid du Colombier 	case 6:
40191178603SDavid du Colombier 		break;
402a587111cSDavid du Colombier 	case 7:
403a587111cSDavid du Colombier 		elf64(MIPSR4K, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
404a587111cSDavid du Colombier 		break;
4053e12c5d1SDavid du Colombier 	}
4063e12c5d1SDavid du Colombier 	cflush();
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier void
410219b2ee8SDavid du Colombier strnput(char *s, int n)
411219b2ee8SDavid du Colombier {
412219b2ee8SDavid du Colombier 	for(; *s; s++){
413219b2ee8SDavid du Colombier 		CPUT(*s);
414219b2ee8SDavid du Colombier 		n--;
415219b2ee8SDavid du Colombier 	}
416219b2ee8SDavid du Colombier 	for(; n > 0; n--)
417219b2ee8SDavid du Colombier 		CPUT(0);
418219b2ee8SDavid du Colombier }
419219b2ee8SDavid du Colombier 
420219b2ee8SDavid du Colombier void
4213e12c5d1SDavid du Colombier cflush(void)
4223e12c5d1SDavid du Colombier {
4233e12c5d1SDavid du Colombier 	int n;
4243e12c5d1SDavid du Colombier 
4253e12c5d1SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
4263e12c5d1SDavid du Colombier 	if(n)
4273e12c5d1SDavid du Colombier 		write(cout, buf.cbuf, n);
4283e12c5d1SDavid du Colombier 	cbp = buf.cbuf;
4293e12c5d1SDavid du Colombier 	cbc = sizeof(buf.cbuf);
4303e12c5d1SDavid du Colombier }
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier void
433219b2ee8SDavid du Colombier nopstat(char *f, Count *c)
434219b2ee8SDavid du Colombier {
435219b2ee8SDavid du Colombier 	if(c->outof)
436219b2ee8SDavid du Colombier 	Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
437219b2ee8SDavid du Colombier 		c->outof - c->count, c->outof,
438219b2ee8SDavid du Colombier 		(double)(c->outof - c->count)/c->outof);
439219b2ee8SDavid du Colombier }
440219b2ee8SDavid du Colombier 
441219b2ee8SDavid du Colombier void
4423e12c5d1SDavid du Colombier asmsym(void)
4433e12c5d1SDavid du Colombier {
4443e12c5d1SDavid du Colombier 	Prog *p;
4453e12c5d1SDavid du Colombier 	Auto *a;
4463e12c5d1SDavid du Colombier 	Sym *s;
4473e12c5d1SDavid du Colombier 	int h;
4483e12c5d1SDavid du Colombier 
4493e12c5d1SDavid du Colombier 	s = lookup("etext", 0);
4503e12c5d1SDavid du Colombier 	if(s->type == STEXT)
4513e12c5d1SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
4523e12c5d1SDavid du Colombier 
4533e12c5d1SDavid du Colombier 	for(h=0; h<NHASH; h++)
4543e12c5d1SDavid du Colombier 		for(s=hash[h]; s!=S; s=s->link)
4553e12c5d1SDavid du Colombier 			switch(s->type) {
456219b2ee8SDavid du Colombier 			case SCONST:
457219b2ee8SDavid du Colombier 				putsymb(s->name, 'D', s->value, s->version);
458219b2ee8SDavid du Colombier 				continue;
459219b2ee8SDavid du Colombier 
4609a747e4fSDavid du Colombier 			case SSTRING:
4619a747e4fSDavid du Colombier 				putsymb(s->name, 'T', s->value, s->version);
4629a747e4fSDavid du Colombier 				continue;
4639a747e4fSDavid du Colombier 
4643e12c5d1SDavid du Colombier 			case SDATA:
4653e12c5d1SDavid du Colombier 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
4663e12c5d1SDavid du Colombier 				continue;
4673e12c5d1SDavid du Colombier 
4683e12c5d1SDavid du Colombier 			case SBSS:
4693e12c5d1SDavid du Colombier 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
4703e12c5d1SDavid du Colombier 				continue;
4713e12c5d1SDavid du Colombier 
4723e12c5d1SDavid du Colombier 			case SFILE:
4733e12c5d1SDavid du Colombier 				putsymb(s->name, 'f', s->value, s->version);
4743e12c5d1SDavid du Colombier 				continue;
4753e12c5d1SDavid du Colombier 			}
4763e12c5d1SDavid du Colombier 
4773e12c5d1SDavid du Colombier 	for(p=textp; p!=P; p=p->cond) {
4783e12c5d1SDavid du Colombier 		s = p->from.sym;
4793e12c5d1SDavid du Colombier 		if(s->type != STEXT && s->type != SLEAF)
4803e12c5d1SDavid du Colombier 			continue;
4813e12c5d1SDavid du Colombier 
4823e12c5d1SDavid du Colombier 		/* filenames first */
4833e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
4843e12c5d1SDavid du Colombier 			if(a->type == D_FILE)
4857dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'z', a->aoffset, 0);
4863e12c5d1SDavid du Colombier 			else
487219b2ee8SDavid du Colombier 			if(a->type == D_FILE1)
4887dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'Z', a->aoffset, 0);
4893e12c5d1SDavid du Colombier 
4903e12c5d1SDavid du Colombier 		if(s->type == STEXT)
4913e12c5d1SDavid du Colombier 			putsymb(s->name, 'T', s->value, s->version);
4923e12c5d1SDavid du Colombier 		else
4933e12c5d1SDavid du Colombier 			putsymb(s->name, 'L', s->value, s->version);
4943e12c5d1SDavid du Colombier 
4953e12c5d1SDavid du Colombier 		/* frame, auto and param after */
496219b2ee8SDavid du Colombier 		putsymb(".frame", 'm', p->to.offset+4, 0);
4973e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
4983e12c5d1SDavid du Colombier 			if(a->type == D_AUTO)
4997dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'a', -a->aoffset, 0);
5003e12c5d1SDavid du Colombier 			else
5013e12c5d1SDavid du Colombier 			if(a->type == D_PARAM)
5027dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'p', a->aoffset, 0);
5033e12c5d1SDavid du Colombier 	}
5043e12c5d1SDavid du Colombier 	if(debug['v'] || debug['n'])
5053e12c5d1SDavid du Colombier 		Bprint(&bso, "symsize = %lud\n", symsize);
5063e12c5d1SDavid du Colombier 	Bflush(&bso);
5073e12c5d1SDavid du Colombier }
5083e12c5d1SDavid du Colombier 
5093e12c5d1SDavid du Colombier void
5103e12c5d1SDavid du Colombier putsymb(char *s, int t, long v, int ver)
5113e12c5d1SDavid du Colombier {
5123e12c5d1SDavid du Colombier 	int i, f;
5133e12c5d1SDavid du Colombier 
5143e12c5d1SDavid du Colombier 	if(t == 'f')
5153e12c5d1SDavid du Colombier 		s++;
51691178603SDavid du Colombier 	LBEPUT(v);
5173e12c5d1SDavid du Colombier 	if(ver)
5183e12c5d1SDavid du Colombier 		t += 'a' - 'A';
519219b2ee8SDavid du Colombier 	CPUT(t+0x80);			/* 0x80 is variable length */
520219b2ee8SDavid du Colombier 
521219b2ee8SDavid du Colombier 	if(t == 'Z' || t == 'z') {
522219b2ee8SDavid du Colombier 		CPUT(s[0]);
523219b2ee8SDavid du Colombier 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
524219b2ee8SDavid du Colombier 			CPUT(s[i]);
525219b2ee8SDavid du Colombier 			CPUT(s[i+1]);
526219b2ee8SDavid du Colombier 		}
527219b2ee8SDavid du Colombier 		CPUT(0);
528219b2ee8SDavid du Colombier 		CPUT(0);
529219b2ee8SDavid du Colombier 		i++;
530219b2ee8SDavid du Colombier 	}
531219b2ee8SDavid du Colombier 	else {
532219b2ee8SDavid du Colombier 		for(i=0; s[i]; i++)
5333e12c5d1SDavid du Colombier 			CPUT(s[i]);
5343e12c5d1SDavid du Colombier 		CPUT(0);
535219b2ee8SDavid du Colombier 	}
536219b2ee8SDavid du Colombier 	symsize += 4 + 1 + i + 1;
537219b2ee8SDavid du Colombier 
5383e12c5d1SDavid du Colombier 	if(debug['n']) {
5393e12c5d1SDavid du Colombier 		if(t == 'z' || t == 'Z') {
540219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux ", t, v);
541219b2ee8SDavid du Colombier 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
5423e12c5d1SDavid du Colombier 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
543219b2ee8SDavid du Colombier 				Bprint(&bso, "/%x", f);
5443e12c5d1SDavid du Colombier 			}
545219b2ee8SDavid du Colombier 			Bprint(&bso, "\n");
5463e12c5d1SDavid du Colombier 			return;
5473e12c5d1SDavid du Colombier 		}
5483e12c5d1SDavid du Colombier 		if(ver)
5493e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
5503e12c5d1SDavid du Colombier 		else
5513e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
5523e12c5d1SDavid du Colombier 	}
5533e12c5d1SDavid du Colombier }
5543e12c5d1SDavid du Colombier 
5553e12c5d1SDavid du Colombier #define	MINLC	4
5563e12c5d1SDavid du Colombier void
5573e12c5d1SDavid du Colombier asmlc(void)
5583e12c5d1SDavid du Colombier {
559a587111cSDavid du Colombier 	long oldlc, v, s;
560a587111cSDavid du Colombier 	vlong oldpc;
5613e12c5d1SDavid du Colombier 	Prog *p;
5623e12c5d1SDavid du Colombier 
5633e12c5d1SDavid du Colombier 	oldpc = INITTEXT;
5643e12c5d1SDavid du Colombier 	oldlc = 0;
5653e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
5663e12c5d1SDavid du Colombier 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
5673e12c5d1SDavid du Colombier 			if(p->as == ATEXT)
5683e12c5d1SDavid du Colombier 				curtext = p;
569b87cd620SDavid du Colombier 			if(debug['V'])
570a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
5713e12c5d1SDavid du Colombier 			continue;
5723e12c5d1SDavid du Colombier 		}
573b87cd620SDavid du Colombier 		if(debug['V'])
5743e12c5d1SDavid du Colombier 			Bprint(&bso, "\t\t%6ld", lcsize);
5753e12c5d1SDavid du Colombier 		v = (p->pc - oldpc) / MINLC;
5763e12c5d1SDavid du Colombier 		while(v) {
5773e12c5d1SDavid du Colombier 			s = 127;
5783e12c5d1SDavid du Colombier 			if(v < 127)
5793e12c5d1SDavid du Colombier 				s = v;
5803e12c5d1SDavid du Colombier 			CPUT(s+128);	/* 129-255 +pc */
581b87cd620SDavid du Colombier 			if(debug['V'])
5823e12c5d1SDavid du Colombier 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
5833e12c5d1SDavid du Colombier 			v -= s;
5843e12c5d1SDavid du Colombier 			lcsize++;
5853e12c5d1SDavid du Colombier 		}
5863e12c5d1SDavid du Colombier 		s = p->line - oldlc;
5873e12c5d1SDavid du Colombier 		oldlc = p->line;
5883e12c5d1SDavid du Colombier 		oldpc = p->pc + MINLC;
5893e12c5d1SDavid du Colombier 		if(s > 64 || s < -64) {
5903e12c5d1SDavid du Colombier 			CPUT(0);	/* 0 vv +lc */
5913e12c5d1SDavid du Colombier 			CPUT(s>>24);
5923e12c5d1SDavid du Colombier 			CPUT(s>>16);
5933e12c5d1SDavid du Colombier 			CPUT(s>>8);
5943e12c5d1SDavid du Colombier 			CPUT(s);
595b87cd620SDavid du Colombier 			if(debug['V']) {
5963e12c5d1SDavid du Colombier 				if(s > 0)
5973e12c5d1SDavid du Colombier 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
5983e12c5d1SDavid du Colombier 						s, 0, s);
5993e12c5d1SDavid du Colombier 				else
6003e12c5d1SDavid du Colombier 					Bprint(&bso, " lc%ld(%d,%ld)\n",
6013e12c5d1SDavid du Colombier 						s, 0, s);
602a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
6033e12c5d1SDavid du Colombier 			}
6043e12c5d1SDavid du Colombier 			lcsize += 5;
6053e12c5d1SDavid du Colombier 			continue;
6063e12c5d1SDavid du Colombier 		}
6073e12c5d1SDavid du Colombier 		if(s > 0) {
6083e12c5d1SDavid du Colombier 			CPUT(0+s);	/* 1-64 +lc */
609b87cd620SDavid du Colombier 			if(debug['V']) {
6103e12c5d1SDavid du Colombier 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
611a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
6123e12c5d1SDavid du Colombier 			}
6133e12c5d1SDavid du Colombier 		} else {
6143e12c5d1SDavid du Colombier 			CPUT(64-s);	/* 65-128 -lc */
615b87cd620SDavid du Colombier 			if(debug['V']) {
6163e12c5d1SDavid du Colombier 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
617a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
6183e12c5d1SDavid du Colombier 			}
6193e12c5d1SDavid du Colombier 		}
6203e12c5d1SDavid du Colombier 		lcsize++;
6213e12c5d1SDavid du Colombier 	}
6223e12c5d1SDavid du Colombier 	while(lcsize & 1) {
6233e12c5d1SDavid du Colombier 		s = 129;
6243e12c5d1SDavid du Colombier 		CPUT(s);
6253e12c5d1SDavid du Colombier 		lcsize++;
6263e12c5d1SDavid du Colombier 	}
627b87cd620SDavid du Colombier 	if(debug['v'] || debug['V'])
6283e12c5d1SDavid du Colombier 		Bprint(&bso, "lcsize = %ld\n", lcsize);
6293e12c5d1SDavid du Colombier 	Bflush(&bso);
6303e12c5d1SDavid du Colombier }
6313e12c5d1SDavid du Colombier 
6323e12c5d1SDavid du Colombier void
6339a747e4fSDavid du Colombier datblk(long s, long n, int str)
6343e12c5d1SDavid du Colombier {
6353e12c5d1SDavid du Colombier 	Prog *p;
6363e12c5d1SDavid du Colombier 	char *cast;
6373e12c5d1SDavid du Colombier 	long l, fl, j, d;
6383e12c5d1SDavid du Colombier 	int i, c;
6393e12c5d1SDavid du Colombier 
6403e12c5d1SDavid du Colombier 	memset(buf.dbuf, 0, n+100);
6413e12c5d1SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
6423e12c5d1SDavid du Colombier 		curp = p;
6439a747e4fSDavid du Colombier 		if(str != (p->from.sym->type == SSTRING))
6449a747e4fSDavid du Colombier 			continue;
6453e12c5d1SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
6463e12c5d1SDavid du Colombier 		c = p->reg;
6473e12c5d1SDavid du Colombier 		i = 0;
6483e12c5d1SDavid du Colombier 		if(l < 0) {
6493e12c5d1SDavid du Colombier 			if(l+c <= 0)
6503e12c5d1SDavid du Colombier 				continue;
6513e12c5d1SDavid du Colombier 			while(l < 0) {
6523e12c5d1SDavid du Colombier 				l++;
6533e12c5d1SDavid du Colombier 				i++;
6543e12c5d1SDavid du Colombier 			}
6553e12c5d1SDavid du Colombier 		}
6563e12c5d1SDavid du Colombier 		if(l >= n)
6573e12c5d1SDavid du Colombier 			continue;
658219b2ee8SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
6593e12c5d1SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
6603e12c5d1SDavid du Colombier 				if(buf.dbuf[j]) {
6613e12c5d1SDavid du Colombier 					print("%P\n", p);
6626b6b9ac8SDavid du Colombier 					diag("multiple initialization");
6633e12c5d1SDavid du Colombier 					break;
6643e12c5d1SDavid du Colombier 				}
665219b2ee8SDavid du Colombier 		}
6663e12c5d1SDavid du Colombier 		switch(p->to.type) {
6673e12c5d1SDavid du Colombier 		default:
6686b6b9ac8SDavid du Colombier 			diag("unknown mode in initialization\n%P", p);
6693e12c5d1SDavid du Colombier 			break;
6703e12c5d1SDavid du Colombier 
6713e12c5d1SDavid du Colombier 		case D_FCONST:
6723e12c5d1SDavid du Colombier 			switch(c) {
6733e12c5d1SDavid du Colombier 			default:
6743e12c5d1SDavid du Colombier 			case 4:
6753e12c5d1SDavid du Colombier 				fl = ieeedtof(p->to.ieee);
6763e12c5d1SDavid du Colombier 				cast = (char*)&fl;
6773e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6783e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i+4]];
6793e12c5d1SDavid du Colombier 					l++;
6803e12c5d1SDavid du Colombier 				}
6813e12c5d1SDavid du Colombier 				break;
6823e12c5d1SDavid du Colombier 			case 8:
6833e12c5d1SDavid du Colombier 				cast = (char*)p->to.ieee;
6843e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6853e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
6863e12c5d1SDavid du Colombier 					l++;
6873e12c5d1SDavid du Colombier 				}
6883e12c5d1SDavid du Colombier 				break;
6893e12c5d1SDavid du Colombier 			}
6903e12c5d1SDavid du Colombier 			break;
6913e12c5d1SDavid du Colombier 
6923e12c5d1SDavid du Colombier 		case D_SCONST:
6933e12c5d1SDavid du Colombier 			for(; i<c; i++) {
6943e12c5d1SDavid du Colombier 				buf.dbuf[l] = p->to.sval[i];
6953e12c5d1SDavid du Colombier 				l++;
6963e12c5d1SDavid du Colombier 			}
6973e12c5d1SDavid du Colombier 			break;
6983e12c5d1SDavid du Colombier 
6993e12c5d1SDavid du Colombier 		case D_CONST:
7003e12c5d1SDavid du Colombier 			d = p->to.offset;
7013e12c5d1SDavid du Colombier 			if(p->to.sym) {
7029a747e4fSDavid du Colombier 				switch(p->to.sym->type) {
7039a747e4fSDavid du Colombier 				case STEXT:
7049a747e4fSDavid du Colombier 				case SLEAF:
7059a747e4fSDavid du Colombier 				case SSTRING:
7063e12c5d1SDavid du Colombier 					d += p->to.sym->value;
7079a747e4fSDavid du Colombier 					break;
7089a747e4fSDavid du Colombier 				case SDATA:
7099a747e4fSDavid du Colombier 				case SBSS:
7103e12c5d1SDavid du Colombier 					d += p->to.sym->value + INITDAT;
7119a747e4fSDavid du Colombier 					break;
7129a747e4fSDavid du Colombier 				}
7133e12c5d1SDavid du Colombier 			}
7143e12c5d1SDavid du Colombier 			cast = (char*)&d;
7153e12c5d1SDavid du Colombier 			switch(c) {
7163e12c5d1SDavid du Colombier 			default:
7176b6b9ac8SDavid du Colombier 				diag("bad nuxi %d %d\n%P", c, i, curp);
7183e12c5d1SDavid du Colombier 				break;
7193e12c5d1SDavid du Colombier 			case 1:
7203e12c5d1SDavid du Colombier 				for(; i<c; i++) {
7213e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
7223e12c5d1SDavid du Colombier 					l++;
7233e12c5d1SDavid du Colombier 				}
7243e12c5d1SDavid du Colombier 				break;
7253e12c5d1SDavid du Colombier 			case 2:
7263e12c5d1SDavid du Colombier 				for(; i<c; i++) {
7273e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
7283e12c5d1SDavid du Colombier 					l++;
7293e12c5d1SDavid du Colombier 				}
7303e12c5d1SDavid du Colombier 				break;
7313e12c5d1SDavid du Colombier 			case 4:
7323e12c5d1SDavid du Colombier 				for(; i<c; i++) {
7333e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
7343e12c5d1SDavid du Colombier 					l++;
7353e12c5d1SDavid du Colombier 				}
7363e12c5d1SDavid du Colombier 				break;
7373e12c5d1SDavid du Colombier 			}
7383e12c5d1SDavid du Colombier 			break;
7393e12c5d1SDavid du Colombier 		}
7403e12c5d1SDavid du Colombier 	}
7413e12c5d1SDavid du Colombier 	write(cout, buf.dbuf, n);
7423e12c5d1SDavid du Colombier }
7433e12c5d1SDavid du Colombier 
7443e12c5d1SDavid du Colombier #define	OP_RRR(op,r1,r2,r3)\
7453e12c5d1SDavid du Colombier 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))
7463e12c5d1SDavid du Colombier #define	OP_IRR(op,i,r2,r3)\
7473e12c5d1SDavid du Colombier 	(op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))
7483e12c5d1SDavid du Colombier #define	OP_SRR(op,s,r2,r3)\
7493e12c5d1SDavid du Colombier 	(op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))
7503e12c5d1SDavid du Colombier #define	OP_FRRR(op,r1,r2,r3)\
7513e12c5d1SDavid du Colombier 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))
7523e12c5d1SDavid du Colombier #define	OP_JMP(op,i)\
7533e12c5d1SDavid du Colombier 		((op)|((i)&0x3ffffffL))
7543e12c5d1SDavid du Colombier 
755219b2ee8SDavid du Colombier #define	OP(x,y)\
756219b2ee8SDavid du Colombier 	(((x)<<3)|((y)<<0))
757219b2ee8SDavid du Colombier #define	SP(x,y)\
758219b2ee8SDavid du Colombier 	(((x)<<29)|((y)<<26))
759219b2ee8SDavid du Colombier #define	BCOND(x,y)\
760219b2ee8SDavid du Colombier 	(((x)<<19)|((y)<<16))
761219b2ee8SDavid du Colombier #define	MMU(x,y)\
762219b2ee8SDavid du Colombier 	(SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))
763219b2ee8SDavid du Colombier #define	FPF(x,y)\
764219b2ee8SDavid du Colombier 	(SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))
765219b2ee8SDavid du Colombier #define	FPD(x,y)\
766219b2ee8SDavid du Colombier 	(SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))
767219b2ee8SDavid du Colombier #define	FPW(x,y)\
768219b2ee8SDavid du Colombier 	(SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))
769219b2ee8SDavid du Colombier 
770dc5a79c1SDavid du Colombier int vshift(int);
771dc5a79c1SDavid du Colombier 
7723e12c5d1SDavid du Colombier int
7733e12c5d1SDavid du Colombier asmout(Prog *p, Optab *o, int aflag)
7743e12c5d1SDavid du Colombier {
7757dd7cddfSDavid du Colombier 	long o1, o2, o3, o4, o5, o6, o7, v;
7763e12c5d1SDavid du Colombier 	Prog *ct;
7773e12c5d1SDavid du Colombier 	int r, a;
7783e12c5d1SDavid du Colombier 
7793e12c5d1SDavid du Colombier 	o1 = 0;
7803e12c5d1SDavid du Colombier 	o2 = 0;
7813e12c5d1SDavid du Colombier 	o3 = 0;
7823e12c5d1SDavid du Colombier 	o4 = 0;
783219b2ee8SDavid du Colombier 	o5 = 0;
7847dd7cddfSDavid du Colombier 	o6 = 0;
7857dd7cddfSDavid du Colombier 	o7 = 0;
7863e12c5d1SDavid du Colombier 	switch(o->type) {
7873e12c5d1SDavid du Colombier 	default:
7886b6b9ac8SDavid du Colombier 		diag("unknown type %d", o->type);
7893e12c5d1SDavid du Colombier 		if(!debug['a'])
7903e12c5d1SDavid du Colombier 			prasm(p);
7913e12c5d1SDavid du Colombier 		break;
7923e12c5d1SDavid du Colombier 
7933e12c5d1SDavid du Colombier 	case 0:		/* pseudo ops */
7943e12c5d1SDavid du Colombier 		if(aflag) {
7953e12c5d1SDavid du Colombier 			if(p->link) {
7963e12c5d1SDavid du Colombier 				if(p->as == ATEXT) {
7973e12c5d1SDavid du Colombier 					ct = curtext;
7983e12c5d1SDavid du Colombier 					o2 = autosize;
7993e12c5d1SDavid du Colombier 					curtext = p;
8003e12c5d1SDavid du Colombier 					autosize = p->to.offset + 4;
8013e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
8023e12c5d1SDavid du Colombier 					curtext = ct;
8033e12c5d1SDavid du Colombier 					autosize = o2;
8043e12c5d1SDavid du Colombier 				} else
8053e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
8063e12c5d1SDavid du Colombier 			}
8073e12c5d1SDavid du Colombier 			return o1;
8083e12c5d1SDavid du Colombier 		}
8093e12c5d1SDavid du Colombier 		break;
8103e12c5d1SDavid du Colombier 
811219b2ee8SDavid du Colombier 	case 1:		/* mov[v] r1,r2 ==> OR r1,r0,r2 */
8123e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg);
8133e12c5d1SDavid du Colombier 		break;
8143e12c5d1SDavid du Colombier 
8153e12c5d1SDavid du Colombier 	case 2:		/* add/sub r1,[r2],r3 */
8163e12c5d1SDavid du Colombier 		r = p->reg;
8173e12c5d1SDavid du Colombier 		if(r == NREG)
8183e12c5d1SDavid du Colombier 			r = p->to.reg;
8193e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg);
8203e12c5d1SDavid du Colombier 		break;
8213e12c5d1SDavid du Colombier 
8223e12c5d1SDavid du Colombier 	case 3:		/* mov $soreg, r ==> or/add $i,o,r */
8233e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8243e12c5d1SDavid du Colombier 		r = p->from.reg;
8253e12c5d1SDavid du Colombier 		if(r == NREG)
8263e12c5d1SDavid du Colombier 			r = o->param;
827219b2ee8SDavid du Colombier 		a = AADDU;
8283e12c5d1SDavid du Colombier 		if(o->a1 == C_ANDCON)
8293e12c5d1SDavid du Colombier 			a = AOR;
8303e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(a), v, r, p->to.reg);
8313e12c5d1SDavid du Colombier 		break;
8323e12c5d1SDavid du Colombier 
8333e12c5d1SDavid du Colombier 	case 4:		/* add $scon,[r1],r2 */
8343e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8353e12c5d1SDavid du Colombier 		r = p->reg;
8363e12c5d1SDavid du Colombier 		if(r == NREG)
8373e12c5d1SDavid du Colombier 			r = p->to.reg;
8383e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, r, p->to.reg);
8393e12c5d1SDavid du Colombier 		break;
8403e12c5d1SDavid du Colombier 
8413e12c5d1SDavid du Colombier 	case 5:		/* syscall */
8423e12c5d1SDavid du Colombier 		if(aflag)
8433e12c5d1SDavid du Colombier 			return 0;
8443e12c5d1SDavid du Colombier 		o1 = oprrr(p->as);
8453e12c5d1SDavid du Colombier 		break;
8463e12c5d1SDavid du Colombier 
8473e12c5d1SDavid du Colombier 	case 6:		/* beq r1,[r2],sbra */
8483e12c5d1SDavid du Colombier 		if(aflag)
8493e12c5d1SDavid du Colombier 			return 0;
8503e12c5d1SDavid du Colombier 		if(p->cond == P)
8513e12c5d1SDavid du Colombier 			v = -4 >> 2;
8523e12c5d1SDavid du Colombier 		else
8533e12c5d1SDavid du Colombier 			v = (p->cond->pc - pc-4) >> 2;
8547dd7cddfSDavid du Colombier 		if(((v << 16) >> 16) != v)
855406758d9SDavid du Colombier 			diag("short branch too far: %ld\n%P", v, p);
8563e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg);
8573e12c5d1SDavid du Colombier 		break;
8583e12c5d1SDavid du Colombier 
8593e12c5d1SDavid du Colombier 	case 7:		/* mov r, soreg ==> sw o(r) */
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 		o1 = OP_IRR(opirr(p->as), v, r, p->from.reg);
8653e12c5d1SDavid du Colombier 		break;
8663e12c5d1SDavid du Colombier 
8673e12c5d1SDavid du Colombier 	case 8:		/* mov soreg, r ==> lw o(r) */
8683e12c5d1SDavid du Colombier 		r = p->from.reg;
8693e12c5d1SDavid du Colombier 		if(r == NREG)
8703e12c5d1SDavid du Colombier 			r = o->param;
8713e12c5d1SDavid du Colombier 		v = regoff(&p->from);
872219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg);
8733e12c5d1SDavid du Colombier 		break;
8743e12c5d1SDavid du Colombier 
8753e12c5d1SDavid du Colombier 	case 9:		/* asl r1,[r2],r3 */
8763e12c5d1SDavid du Colombier 		r = p->reg;
8773e12c5d1SDavid du Colombier 		if(r == NREG)
8783e12c5d1SDavid du Colombier 			r = p->to.reg;
8793e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
8803e12c5d1SDavid du Colombier 		break;
8813e12c5d1SDavid du Colombier 
8823e12c5d1SDavid du Colombier 	case 10:	/* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */
8833e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8843e12c5d1SDavid du Colombier 		r = AOR;
8853e12c5d1SDavid du Colombier 		if(v < 0)
886219b2ee8SDavid du Colombier 			r = AADDU;
8873e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(r), v, 0, REGTMP);
8883e12c5d1SDavid du Colombier 		r = p->reg;
8893e12c5d1SDavid du Colombier 		if(r == NREG)
8903e12c5d1SDavid du Colombier 			r = p->to.reg;
8913e12c5d1SDavid du Colombier 		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
8923e12c5d1SDavid du Colombier 		break;
8933e12c5d1SDavid du Colombier 
8943e12c5d1SDavid du Colombier 	case 11:	/* jmp lbra */
8953e12c5d1SDavid du Colombier 		if(aflag)
8963e12c5d1SDavid du Colombier 			return 0;
8973e12c5d1SDavid du Colombier 		if(p->cond == P)
8983e12c5d1SDavid du Colombier 			v = p->pc >> 2;
8993e12c5d1SDavid du Colombier 		else
9003e12c5d1SDavid du Colombier 			v = p->cond->pc >> 2;
9013e12c5d1SDavid du Colombier 		o1 = OP_JMP(opirr(p->as), v);
902219b2ee8SDavid du Colombier 		if(!debug['Y'] && p->link && p->cond && isnop(p->link)) {
903219b2ee8SDavid du Colombier 			nop.branch.count--;
904219b2ee8SDavid du Colombier 			nop.branch.outof--;
905219b2ee8SDavid du Colombier 			nop.jump.outof++;
9063e12c5d1SDavid du Colombier 			o2 = asmout(p->cond, oplook(p->cond), 1);
9073e12c5d1SDavid du Colombier 			if(o2) {
9083e12c5d1SDavid du Colombier 				o1 += 1;
9093e12c5d1SDavid du Colombier 				if(debug['a'])
910a587111cSDavid du Colombier 					Bprint(&bso, " %.8llux: %.8lux %.8lux%P\n",
911219b2ee8SDavid du Colombier 						p->pc, o1, o2, p);
9123e12c5d1SDavid du Colombier 				LPUT(o1);
9133e12c5d1SDavid du Colombier 				LPUT(o2);
9143e12c5d1SDavid du Colombier 				return 1;
9153e12c5d1SDavid du Colombier 			}
9163e12c5d1SDavid du Colombier 		}
9173e12c5d1SDavid du Colombier 		break;
9183e12c5d1SDavid du Colombier 
9193e12c5d1SDavid du Colombier 	case 12:	/* movbs r,r */
9203e12c5d1SDavid du Colombier 		v = 16;
9213e12c5d1SDavid du Colombier 		if(p->as == AMOVB)
9223e12c5d1SDavid du Colombier 			v = 24;
9233e12c5d1SDavid du Colombier 		o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg);
9243e12c5d1SDavid du Colombier 		o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg);
9253e12c5d1SDavid du Colombier 		break;
9263e12c5d1SDavid du Colombier 
9273e12c5d1SDavid du Colombier 	case 13:	/* movbu r,r */
9283e12c5d1SDavid du Colombier 		if(p->as == AMOVBU)
9293e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg);
9303e12c5d1SDavid du Colombier 		else
9313e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg);
9323e12c5d1SDavid du Colombier 		break;
9333e12c5d1SDavid du Colombier 
9343e12c5d1SDavid du Colombier 	case 16:	/* sll $c,[r1],r2 */
9353e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9363e12c5d1SDavid du Colombier 		r = p->reg;
9373e12c5d1SDavid du Colombier 		if(r == NREG)
9383e12c5d1SDavid du Colombier 			r = p->to.reg;
939dc5a79c1SDavid du Colombier 
940dc5a79c1SDavid du Colombier 		/* OP_SRR will use only the low 5 bits of the shift value */
941dc5a79c1SDavid du Colombier 		if(v >= 32 && vshift(p->as))
942219b2ee8SDavid du Colombier 			o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg);
943219b2ee8SDavid du Colombier 		else
9443e12c5d1SDavid du Colombier 			o1 = OP_SRR(opirr(p->as), v, r, p->to.reg);
9453e12c5d1SDavid du Colombier 		break;
9463e12c5d1SDavid du Colombier 
9473e12c5d1SDavid du Colombier 	case 18:	/* jmp [r1],0(r2) */
9483e12c5d1SDavid du Colombier 		if(aflag)
9493e12c5d1SDavid du Colombier 			return 0;
9503e12c5d1SDavid du Colombier 		r = p->reg;
9513e12c5d1SDavid du Colombier 		if(r == NREG)
9523e12c5d1SDavid du Colombier 			r = o->param;
9533e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r);
9543e12c5d1SDavid du Colombier 		break;
9553e12c5d1SDavid du Colombier 
9563e12c5d1SDavid du Colombier 	case 19:	/* mov $lcon,r ==> lu+or */
9573e12c5d1SDavid du Colombier 		v = regoff(&p->from);
958219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9593e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg);
9603e12c5d1SDavid du Colombier 		break;
9613e12c5d1SDavid du Colombier 
962219b2ee8SDavid du Colombier 	case 20:	/* mov lohi,r */
963219b2ee8SDavid du Colombier 		r = OP(2,0);		/* mfhi */
9643e12c5d1SDavid du Colombier 		if(p->from.type == D_LO)
965219b2ee8SDavid du Colombier 			r = OP(2,2);	/* mflo */
966219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg);
9673e12c5d1SDavid du Colombier 		break;
9683e12c5d1SDavid du Colombier 
969219b2ee8SDavid du Colombier 	case 21:	/* mov r,lohi */
970219b2ee8SDavid du Colombier 		r = OP(2,1);		/* mthi */
9713e12c5d1SDavid du Colombier 		if(p->to.type == D_LO)
972219b2ee8SDavid du Colombier 			r = OP(2,3);	/* mtlo */
973219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO);
9743e12c5d1SDavid du Colombier 		break;
9753e12c5d1SDavid du Colombier 
9763e12c5d1SDavid du Colombier 	case 22:	/* mul r1,r2 */
9773e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO);
9783e12c5d1SDavid du Colombier 		break;
9793e12c5d1SDavid du Colombier 
9803e12c5d1SDavid du Colombier 	case 23:	/* add $lcon,r1,r2 ==> lu+or+add */
9813e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9823e12c5d1SDavid du Colombier 		if(p->to.reg == REGTMP || p->reg == REGTMP)
9836b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
984219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9853e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
9863e12c5d1SDavid du Colombier 		r = p->reg;
9873e12c5d1SDavid du Colombier 		if(r == NREG)
9883e12c5d1SDavid du Colombier 			r = p->to.reg;
9893e12c5d1SDavid du Colombier 		o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
9903e12c5d1SDavid du Colombier 		break;
9913e12c5d1SDavid du Colombier 
9923e12c5d1SDavid du Colombier 	case 24:	/* mov $ucon,,r ==> lu r */
9933e12c5d1SDavid du Colombier 		v = regoff(&p->from);
994219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9953e12c5d1SDavid du Colombier 		break;
9963e12c5d1SDavid du Colombier 
9973e12c5d1SDavid du Colombier 	case 25:	/* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */
9983e12c5d1SDavid du Colombier 		v = regoff(&p->from);
999219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
10003e12c5d1SDavid du Colombier 		r = p->reg;
10013e12c5d1SDavid du Colombier 		if(r == NREG)
10023e12c5d1SDavid du Colombier 			r = p->to.reg;
10033e12c5d1SDavid du Colombier 		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
10043e12c5d1SDavid du Colombier 		break;
10053e12c5d1SDavid du Colombier 
10063e12c5d1SDavid du Colombier 	case 26:	/* mov $lsext/auto/oreg,,r2 ==> lu+or+add */
10073e12c5d1SDavid du Colombier 		v = regoff(&p->from);
10083e12c5d1SDavid du Colombier 		if(p->to.reg == REGTMP)
10096b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
1010219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
10113e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
10123e12c5d1SDavid du Colombier 		r = p->from.reg;
10133e12c5d1SDavid du Colombier 		if(r == NREG)
10143e12c5d1SDavid du Colombier 			r = o->param;
1015219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg);
10163e12c5d1SDavid du Colombier 		break;
10173e12c5d1SDavid du Colombier 
10183e12c5d1SDavid du Colombier 	case 27:		/* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
10193e12c5d1SDavid du Colombier 		r = p->from.reg;
10203e12c5d1SDavid du Colombier 		if(r == NREG)
10213e12c5d1SDavid du Colombier 			r = o->param;
10223e12c5d1SDavid du Colombier 		v = regoff(&p->from);
10233e12c5d1SDavid du Colombier 		switch(o->size) {
1024219b2ee8SDavid du Colombier 		case 20:
1025219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1026219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1027219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1028219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1);
1029219b2ee8SDavid du Colombier 			o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg);
10303e12c5d1SDavid du Colombier 			break;
1031219b2ee8SDavid du Colombier 		case 16:
1032219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1033219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1034219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1035219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg);
10363e12c5d1SDavid du Colombier 			break;
10373e12c5d1SDavid du Colombier 		case 8:
1038219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1);
1039219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg);
10403e12c5d1SDavid du Colombier 			break;
10413e12c5d1SDavid du Colombier 		case 4:
1042219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg);
10433e12c5d1SDavid du Colombier 			break;
10443e12c5d1SDavid du Colombier 		}
10453e12c5d1SDavid du Colombier 		break;
10463e12c5d1SDavid du Colombier 
10473e12c5d1SDavid du Colombier 	case 28:		/* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */
10483e12c5d1SDavid du Colombier 		r = p->to.reg;
10493e12c5d1SDavid du Colombier 		if(r == NREG)
10503e12c5d1SDavid du Colombier 			r = o->param;
10513e12c5d1SDavid du Colombier 		v = regoff(&p->to);
10523e12c5d1SDavid du Colombier 		switch(o->size) {
1053219b2ee8SDavid du Colombier 		case 20:
1054219b2ee8SDavid du Colombier 			if(r == REGTMP)
10556b6b9ac8SDavid du Colombier 				diag("cant synthesize large constant\n%P", p);
1056219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1057219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1058219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1059219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1);
1060219b2ee8SDavid du Colombier 			o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg);
10613e12c5d1SDavid du Colombier 			break;
1062219b2ee8SDavid du Colombier 		case 16:
1063219b2ee8SDavid du Colombier 			if(r == REGTMP)
10646b6b9ac8SDavid du Colombier 				diag("cant synthesize large constant\n%P", p);
1065219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1066219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1067219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1068219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg);
10693e12c5d1SDavid du Colombier 			break;
10703e12c5d1SDavid du Colombier 		case 8:
10713e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1);
10723e12c5d1SDavid du Colombier 			o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg);
10733e12c5d1SDavid du Colombier 			break;
10743e12c5d1SDavid du Colombier 		case 4:
10753e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg);
10763e12c5d1SDavid du Colombier 			break;
10773e12c5d1SDavid du Colombier 		}
10783e12c5d1SDavid du Colombier 		break;
10793e12c5d1SDavid du Colombier 
10803e12c5d1SDavid du Colombier 	case 30:	/* movw r,fr */
1081219b2ee8SDavid du Colombier 		r = SP(2,1)|(4<<21);		/* mtc1 */
1082219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
10833e12c5d1SDavid du Colombier 		break;
10843e12c5d1SDavid du Colombier 
10853e12c5d1SDavid du Colombier 	case 31:	/* movw fr,r */
1086219b2ee8SDavid du Colombier 		r = SP(2,1)|(0<<21);		/* mfc1 */
1087219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
10883e12c5d1SDavid du Colombier 		break;
10893e12c5d1SDavid du Colombier 
10903e12c5d1SDavid du Colombier 	case 32:	/* fadd fr1,[fr2],fr3 */
10913e12c5d1SDavid du Colombier 		r = p->reg;
10923e12c5d1SDavid du Colombier 		if(r == NREG)
10933e12c5d1SDavid du Colombier 			o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg);
10943e12c5d1SDavid du Colombier 		else
10953e12c5d1SDavid du Colombier 			o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg);
10963e12c5d1SDavid du Colombier 		break;
10973e12c5d1SDavid du Colombier 
10983e12c5d1SDavid du Colombier 	case 33:	/* fabs fr1,fr3 */
10993e12c5d1SDavid du Colombier 		o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg);
11003e12c5d1SDavid du Colombier 		break;
11013e12c5d1SDavid du Colombier 
11023e12c5d1SDavid du Colombier 	case 34:	/* mov $con,fr ==> or/add $i,r,r2 */
11033e12c5d1SDavid du Colombier 		v = regoff(&p->from);
1104219b2ee8SDavid du Colombier 		r = AADDU;
11053e12c5d1SDavid du Colombier 		if(o->a1 == C_ANDCON)
11063e12c5d1SDavid du Colombier 			r = AOR;
11073e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(r), v, 0, REGTMP);
1108219b2ee8SDavid du Colombier 		o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg);	/* mtc1 */
11093e12c5d1SDavid du Colombier 		break;
11103e12c5d1SDavid du Colombier 
11113e12c5d1SDavid du Colombier 	case 35:	/* mov r,lext/luto/oreg ==> sw o(r) */
1112219b2ee8SDavid du Colombier 		/*
1113219b2ee8SDavid du Colombier 		 * the lowbits of the constant cannot
1114219b2ee8SDavid du Colombier 		 * be moved into the offset of the load
1115219b2ee8SDavid du Colombier 		 * because the mips 4000 in 64-bit mode
1116219b2ee8SDavid du Colombier 		 * does a 64-bit add and it will screw up.
1117219b2ee8SDavid du Colombier 		 */
11183e12c5d1SDavid du Colombier 		v = regoff(&p->to);
11193e12c5d1SDavid du Colombier 		r = p->to.reg;
11203e12c5d1SDavid du Colombier 		if(r == NREG)
11213e12c5d1SDavid du Colombier 			r = o->param;
1122219b2ee8SDavid du Colombier 		if(r == REGTMP)
11236b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
1124219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1125219b2ee8SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1126219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1127219b2ee8SDavid du Colombier 		o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg);
11283e12c5d1SDavid du Colombier 		break;
11293e12c5d1SDavid du Colombier 
11303e12c5d1SDavid du Colombier 	case 36:	/* mov lext/lauto/lreg,r ==> lw o(r30) */
11313e12c5d1SDavid du Colombier 		v = regoff(&p->from);
11323e12c5d1SDavid du Colombier 		r = p->from.reg;
11333e12c5d1SDavid du Colombier 		if(r == NREG)
11343e12c5d1SDavid du Colombier 			r = o->param;
1135219b2ee8SDavid du Colombier 		if(r == REGTMP)
11366b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
1137219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1138219b2ee8SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1139219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1140219b2ee8SDavid du Colombier 		o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg);
11413e12c5d1SDavid du Colombier 		break;
11423e12c5d1SDavid du Colombier 
11433e12c5d1SDavid du Colombier 	case 37:	/* movw r,mr */
1144219b2ee8SDavid du Colombier 		r = SP(2,0)|(4<<21);		/* mtc0 */
1145219b2ee8SDavid du Colombier 		if(p->as == AMOVV)
1146219b2ee8SDavid du Colombier 			r = SP(2,0)|(5<<21);	/* dmtc0 */
1147219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
11483e12c5d1SDavid du Colombier 		break;
11493e12c5d1SDavid du Colombier 
11503e12c5d1SDavid du Colombier 	case 38:	/* movw mr,r */
1151219b2ee8SDavid du Colombier 		r = SP(2,0)|(0<<21);		/* mfc0 */
1152219b2ee8SDavid du Colombier 		if(p->as == AMOVV)
1153219b2ee8SDavid du Colombier 			r = SP(2,0)|(1<<21);	/* dmfc0 */
1154219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
11553e12c5d1SDavid du Colombier 		break;
11563e12c5d1SDavid du Colombier 
11573e12c5d1SDavid du Colombier 	case 39:	/* rfe ==> jmp+rfe */
11583e12c5d1SDavid du Colombier 		if(aflag)
11593e12c5d1SDavid du Colombier 			return 0;
11603e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO);
11613e12c5d1SDavid du Colombier 		o2 = oprrr(p->as);
11623e12c5d1SDavid du Colombier 		break;
11633e12c5d1SDavid du Colombier 
11643e12c5d1SDavid du Colombier 	case 40:	/* word */
11653e12c5d1SDavid du Colombier 		if(aflag)
11663e12c5d1SDavid du Colombier 			return 0;
11673e12c5d1SDavid du Colombier 		o1 = regoff(&p->to);
11683e12c5d1SDavid du Colombier 		break;
11693e12c5d1SDavid du Colombier 
11703e12c5d1SDavid du Colombier 	case 41:	/* movw r,fcr */
1171219b2ee8SDavid du Colombier 		o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); 	/* mfcc1 */
1172219b2ee8SDavid du Colombier 		o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */
11733e12c5d1SDavid du Colombier 		break;
11743e12c5d1SDavid du Colombier 
11753e12c5d1SDavid du Colombier 	case 42:	/* movw fcr,r */
1176219b2ee8SDavid du Colombier 		o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */
11773e12c5d1SDavid du Colombier 		break;
11787dd7cddfSDavid du Colombier 
11797dd7cddfSDavid du Colombier 	case 45:	/* case r */
11807dd7cddfSDavid du Colombier 		if(p->link == P)
11817dd7cddfSDavid du Colombier 			v = p->pc+28;
11827dd7cddfSDavid du Colombier 		else
11837dd7cddfSDavid du Colombier 			v = p->link->pc;
11847dd7cddfSDavid du Colombier 		if(v & (1<<15))
11857dd7cddfSDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP);
11867dd7cddfSDavid du Colombier 		else
11877dd7cddfSDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
11887dd7cddfSDavid du Colombier 		o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg);
11897dd7cddfSDavid du Colombier 		o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP);
11907dd7cddfSDavid du Colombier 		o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP);
11917dd7cddfSDavid du Colombier 		o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
11927dd7cddfSDavid du Colombier 		o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO);
11937dd7cddfSDavid du Colombier 		o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
11947dd7cddfSDavid du Colombier 		break;
11957dd7cddfSDavid du Colombier 
11967dd7cddfSDavid du Colombier 	case 46:	/* bcase $con,lbra */
11977dd7cddfSDavid du Colombier 		if(p->cond == P)
11987dd7cddfSDavid du Colombier 			v = p->pc;
11997dd7cddfSDavid du Colombier 		else
12007dd7cddfSDavid du Colombier 			v = p->cond->pc;
12017dd7cddfSDavid du Colombier 		o1 = v;
12027dd7cddfSDavid du Colombier 		break;
12033e12c5d1SDavid du Colombier 	}
12043e12c5d1SDavid du Colombier 	if(aflag)
12053e12c5d1SDavid du Colombier 		return o1;
12063e12c5d1SDavid du Colombier 	v = p->pc;
12073e12c5d1SDavid du Colombier 	switch(o->size) {
12083e12c5d1SDavid du Colombier 	default:
12093e12c5d1SDavid du Colombier 		if(debug['a'])
12103e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
12113e12c5d1SDavid du Colombier 		break;
12123e12c5d1SDavid du Colombier 	case 4:
12133e12c5d1SDavid du Colombier 		if(debug['a'])
12143e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
12153e12c5d1SDavid du Colombier 		LPUT(o1);
12163e12c5d1SDavid du Colombier 		break;
12173e12c5d1SDavid du Colombier 	case 8:
12183e12c5d1SDavid du Colombier 		if(debug['a'])
12193e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
12203e12c5d1SDavid du Colombier 		LPUT(o1);
12213e12c5d1SDavid du Colombier 		LPUT(o2);
12223e12c5d1SDavid du Colombier 		break;
12233e12c5d1SDavid du Colombier 	case 12:
12243e12c5d1SDavid du Colombier 		if(debug['a'])
12253e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
12263e12c5d1SDavid du Colombier 		LPUT(o1);
12273e12c5d1SDavid du Colombier 		LPUT(o2);
12283e12c5d1SDavid du Colombier 		LPUT(o3);
12293e12c5d1SDavid du Colombier 		break;
12303e12c5d1SDavid du Colombier 	case 16:
12313e12c5d1SDavid du Colombier 		if(debug['a'])
12323e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
12333e12c5d1SDavid du Colombier 				v, o1, o2, o3, o4, p);
12343e12c5d1SDavid du Colombier 		LPUT(o1);
12353e12c5d1SDavid du Colombier 		LPUT(o2);
12363e12c5d1SDavid du Colombier 		LPUT(o3);
12373e12c5d1SDavid du Colombier 		LPUT(o4);
12383e12c5d1SDavid du Colombier 		break;
1239219b2ee8SDavid du Colombier 	case 20:
1240219b2ee8SDavid du Colombier 		if(debug['a'])
1241219b2ee8SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
1242219b2ee8SDavid du Colombier 				v, o1, o2, o3, o4, o5, p);
1243219b2ee8SDavid du Colombier 		LPUT(o1);
1244219b2ee8SDavid du Colombier 		LPUT(o2);
1245219b2ee8SDavid du Colombier 		LPUT(o3);
1246219b2ee8SDavid du Colombier 		LPUT(o4);
1247219b2ee8SDavid du Colombier 		LPUT(o5);
1248219b2ee8SDavid du Colombier 		break;
12497dd7cddfSDavid du Colombier 
12507dd7cddfSDavid du Colombier 	case 28:
12517dd7cddfSDavid du Colombier 		if(debug['a'])
12527dd7cddfSDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
12537dd7cddfSDavid du Colombier 				v, o1, o2, o3, o4, o5, o6, o7, p);
12547dd7cddfSDavid du Colombier 		LPUT(o1);
12557dd7cddfSDavid du Colombier 		LPUT(o2);
12567dd7cddfSDavid du Colombier 		LPUT(o3);
12577dd7cddfSDavid du Colombier 		LPUT(o4);
12587dd7cddfSDavid du Colombier 		LPUT(o5);
12597dd7cddfSDavid du Colombier 		LPUT(o6);
12607dd7cddfSDavid du Colombier 		LPUT(o7);
12617dd7cddfSDavid du Colombier 		break;
12623e12c5d1SDavid du Colombier 	}
12633e12c5d1SDavid du Colombier 	return 0;
12643e12c5d1SDavid du Colombier }
12653e12c5d1SDavid du Colombier 
1266219b2ee8SDavid du Colombier int
1267219b2ee8SDavid du Colombier isnop(Prog *p)
1268219b2ee8SDavid du Colombier {
1269219b2ee8SDavid du Colombier 	if(p->as != ANOR)
1270219b2ee8SDavid du Colombier 		return 0;
1271219b2ee8SDavid du Colombier 	if(p->reg != REGZERO && p->reg != NREG)
1272219b2ee8SDavid du Colombier 		return 0;
1273219b2ee8SDavid du Colombier 	if(p->from.type != D_REG || p->from.reg != REGZERO)
1274219b2ee8SDavid du Colombier 		return 0;
1275219b2ee8SDavid du Colombier 	if(p->to.type != D_REG || p->to.reg != REGZERO)
1276219b2ee8SDavid du Colombier 		return 0;
1277219b2ee8SDavid du Colombier 	return 1;
1278219b2ee8SDavid du Colombier }
12793e12c5d1SDavid du Colombier 
12803e12c5d1SDavid du Colombier long
12813e12c5d1SDavid du Colombier oprrr(int a)
12823e12c5d1SDavid du Colombier {
12833e12c5d1SDavid du Colombier 	switch(a) {
12843e12c5d1SDavid du Colombier 	case AADD:	return OP(4,0);
12853e12c5d1SDavid du Colombier 	case AADDU:	return OP(4,1);
12863e12c5d1SDavid du Colombier 	case ASGT:	return OP(5,2);
12873e12c5d1SDavid du Colombier 	case ASGTU:	return OP(5,3);
12883e12c5d1SDavid du Colombier 	case AAND:	return OP(4,4);
12893e12c5d1SDavid du Colombier 	case AOR:	return OP(4,5);
12903e12c5d1SDavid du Colombier 	case AXOR:	return OP(4,6);
12913e12c5d1SDavid du Colombier 	case ASUB:	return OP(4,2);
12923e12c5d1SDavid du Colombier 	case ASUBU:	return OP(4,3);
12933e12c5d1SDavid du Colombier 	case ANOR:	return OP(4,7);
12943e12c5d1SDavid du Colombier 	case ASLL:	return OP(0,4);
12953e12c5d1SDavid du Colombier 	case ASRL:	return OP(0,6);
12963e12c5d1SDavid du Colombier 	case ASRA:	return OP(0,7);
12973e12c5d1SDavid du Colombier 
12983e12c5d1SDavid du Colombier 	case AREM:
12993e12c5d1SDavid du Colombier 	case ADIV:	return OP(3,2);
13003e12c5d1SDavid du Colombier 	case AREMU:
13013e12c5d1SDavid du Colombier 	case ADIVU:	return OP(3,3);
13023e12c5d1SDavid du Colombier 	case AMUL:	return OP(3,0);
13033e12c5d1SDavid du Colombier 	case AMULU:	return OP(3,1);
13043e12c5d1SDavid du Colombier 
13053e12c5d1SDavid du Colombier 	case AJMP:	return OP(1,0);
13063e12c5d1SDavid du Colombier 	case AJAL:	return OP(1,1);
13073e12c5d1SDavid du Colombier 
13083e12c5d1SDavid du Colombier 	case ABREAK:	return OP(1,5);
13093e12c5d1SDavid du Colombier 	case ASYSCALL:	return OP(1,4);
13103e12c5d1SDavid du Colombier 	case ATLBP:	return MMU(1,0);
13113e12c5d1SDavid du Colombier 	case ATLBR:	return MMU(0,1);
13123e12c5d1SDavid du Colombier 	case ATLBWI:	return MMU(0,2);
13133e12c5d1SDavid du Colombier 	case ATLBWR:	return MMU(0,6);
13143e12c5d1SDavid du Colombier 	case ARFE:	return MMU(2,0);
13153e12c5d1SDavid du Colombier 
13163e12c5d1SDavid du Colombier 	case ADIVF:	return FPF(0,3);
13173e12c5d1SDavid du Colombier 	case ADIVD:	return FPD(0,3);
13183e12c5d1SDavid du Colombier 	case AMULF:	return FPF(0,2);
13193e12c5d1SDavid du Colombier 	case AMULD:	return FPD(0,2);
13203e12c5d1SDavid du Colombier 	case ASUBF:	return FPF(0,1);
13213e12c5d1SDavid du Colombier 	case ASUBD:	return FPD(0,1);
13223e12c5d1SDavid du Colombier 	case AADDF:	return FPF(0,0);
13233e12c5d1SDavid du Colombier 	case AADDD:	return FPD(0,0);
13243e12c5d1SDavid du Colombier 
13253e12c5d1SDavid du Colombier 	case AMOVFW:	return FPF(4,4);
13263e12c5d1SDavid du Colombier 	case AMOVDW:	return FPD(4,4);
13273e12c5d1SDavid du Colombier 	case AMOVWF:	return FPW(4,0);
13283e12c5d1SDavid du Colombier 	case AMOVDF:	return FPD(4,0);
13293e12c5d1SDavid du Colombier 	case AMOVWD:	return FPW(4,1);
13303e12c5d1SDavid du Colombier 	case AMOVFD:	return FPF(4,1);
13313e12c5d1SDavid du Colombier 	case AABSF:	return FPF(0,5);
13323e12c5d1SDavid du Colombier 	case AABSD:	return FPD(0,5);
13333e12c5d1SDavid du Colombier 	case AMOVF:	return FPF(0,6);
13343e12c5d1SDavid du Colombier 	case AMOVD:	return FPD(0,6);
13353e12c5d1SDavid du Colombier 	case ANEGF:	return FPF(0,7);
13363e12c5d1SDavid du Colombier 	case ANEGD:	return FPD(0,7);
13373e12c5d1SDavid du Colombier 
13383e12c5d1SDavid du Colombier 	case ACMPEQF:	return FPF(6,2);
13393e12c5d1SDavid du Colombier 	case ACMPEQD:	return FPD(6,2);
13403e12c5d1SDavid du Colombier 	case ACMPGTF:	return FPF(7,4);
13413e12c5d1SDavid du Colombier 	case ACMPGTD:	return FPD(7,4);
13423e12c5d1SDavid du Colombier 	case ACMPGEF:	return FPF(7,6);
13433e12c5d1SDavid du Colombier 	case ACMPGED:	return FPD(7,6);
13447dd7cddfSDavid du Colombier 
13457dd7cddfSDavid du Colombier 	case ADIVV:	return OP(3,6);
13467dd7cddfSDavid du Colombier 	case ADIVVU:	return OP(3,7);
13477dd7cddfSDavid du Colombier 	case AADDV:	return OP(5,4);
13487dd7cddfSDavid du Colombier 	case AADDVU:	return OP(5,5);
13493e12c5d1SDavid du Colombier 	}
13506b6b9ac8SDavid du Colombier 	diag("bad rrr %d", a);
13513e12c5d1SDavid du Colombier 	return 0;
13523e12c5d1SDavid du Colombier }
13533e12c5d1SDavid du Colombier 
13543e12c5d1SDavid du Colombier long
13553e12c5d1SDavid du Colombier opirr(int a)
13563e12c5d1SDavid du Colombier {
13573e12c5d1SDavid du Colombier 	switch(a) {
13583e12c5d1SDavid du Colombier 	case AADD:	return SP(1,0);
13593e12c5d1SDavid du Colombier 	case AADDU:	return SP(1,1);
13603e12c5d1SDavid du Colombier 	case ASGT:	return SP(1,2);
13613e12c5d1SDavid du Colombier 	case ASGTU:	return SP(1,3);
13623e12c5d1SDavid du Colombier 	case AAND:	return SP(1,4);
13633e12c5d1SDavid du Colombier 	case AOR:	return SP(1,5);
13643e12c5d1SDavid du Colombier 	case AXOR:	return SP(1,6);
1365219b2ee8SDavid du Colombier 	case ALAST:	return SP(1,7);
13663e12c5d1SDavid du Colombier 	case ASLL:	return OP(0,0);
13673e12c5d1SDavid du Colombier 	case ASRL:	return OP(0,2);
13683e12c5d1SDavid du Colombier 	case ASRA:	return OP(0,3);
13693e12c5d1SDavid du Colombier 
13703e12c5d1SDavid du Colombier 	case AJMP:	return SP(0,2);
13713e12c5d1SDavid du Colombier 	case AJAL:	return SP(0,3);
13723e12c5d1SDavid du Colombier 	case ABEQ:	return SP(0,4);
13733e12c5d1SDavid du Colombier 	case ABNE:	return SP(0,5);
13743e12c5d1SDavid du Colombier 
13753e12c5d1SDavid du Colombier 	case ABGEZ:	return SP(0,1)|BCOND(0,1);
13763e12c5d1SDavid du Colombier 	case ABGEZAL:	return SP(0,1)|BCOND(2,1);
13773e12c5d1SDavid du Colombier 	case ABGTZ:	return SP(0,7);
13783e12c5d1SDavid du Colombier 	case ABLEZ:	return SP(0,6);
13793e12c5d1SDavid du Colombier 	case ABLTZ:	return SP(0,1)|BCOND(0,0);
13803e12c5d1SDavid du Colombier 	case ABLTZAL:	return SP(0,1)|BCOND(2,0);
13813e12c5d1SDavid du Colombier 
13823e12c5d1SDavid du Colombier 	case ABFPT:	return SP(2,1)|(257<<16);
13833e12c5d1SDavid du Colombier 	case ABFPF:	return SP(2,1)|(256<<16);
13843e12c5d1SDavid du Colombier 
13853e12c5d1SDavid du Colombier 	case AMOVB:
13863e12c5d1SDavid du Colombier 	case AMOVBU:	return SP(5,0);
13873e12c5d1SDavid du Colombier 	case AMOVH:
13883e12c5d1SDavid du Colombier 	case AMOVHU:	return SP(5,1);
13893e12c5d1SDavid du Colombier 	case AMOVW:	return SP(5,3);
1390219b2ee8SDavid du Colombier 	case AMOVV:	return SP(7,7);
13913e12c5d1SDavid du Colombier 	case AMOVF:	return SP(7,1);
13923e12c5d1SDavid du Colombier 	case AMOVWL:	return SP(5,2);
13933e12c5d1SDavid du Colombier 	case AMOVWR:	return SP(5,6);
1394219b2ee8SDavid du Colombier 	case AMOVVL:	return SP(5,4);
1395219b2ee8SDavid du Colombier 	case AMOVVR:	return SP(5,5);
13963e12c5d1SDavid du Colombier 
1397bd389b36SDavid du Colombier 	case ABREAK:	return SP(5,7);
1398bd389b36SDavid du Colombier 
1399219b2ee8SDavid du Colombier 	case AMOVWL+ALAST:	return SP(4,2);
1400219b2ee8SDavid du Colombier 	case AMOVWR+ALAST:	return SP(4,6);
1401219b2ee8SDavid du Colombier 	case AMOVVL+ALAST:	return SP(3,2);
1402219b2ee8SDavid du Colombier 	case AMOVVR+ALAST:	return SP(3,3);
1403219b2ee8SDavid du Colombier 	case AMOVB+ALAST:	return SP(4,0);
1404219b2ee8SDavid du Colombier 	case AMOVBU+ALAST:	return SP(4,4);
1405219b2ee8SDavid du Colombier 	case AMOVH+ALAST:	return SP(4,1);
1406219b2ee8SDavid du Colombier 	case AMOVHU+ALAST:	return SP(4,5);
1407219b2ee8SDavid du Colombier 	case AMOVW+ALAST:	return SP(4,3);
1408219b2ee8SDavid du Colombier 	case AMOVV+ALAST:	return SP(6,7);
1409219b2ee8SDavid du Colombier 	case AMOVF+ALAST:	return SP(6,1);
14103e12c5d1SDavid du Colombier 
1411219b2ee8SDavid du Colombier 	case ASLLV:		return OP(7,0);
1412219b2ee8SDavid du Colombier 	case ASRLV:		return OP(7,2);
1413219b2ee8SDavid du Colombier 	case ASRAV:		return OP(7,3);
1414219b2ee8SDavid du Colombier 	case ASLLV+ALAST:	return OP(7,4);
1415219b2ee8SDavid du Colombier 	case ASRLV+ALAST:	return OP(7,6);
1416219b2ee8SDavid du Colombier 	case ASRAV+ALAST:	return OP(7,7);
14177dd7cddfSDavid du Colombier 
14187dd7cddfSDavid du Colombier 	case AADDV:		return SP(3,0);
14197dd7cddfSDavid du Colombier 	case AADDVU:		return SP(3,1);
14203e12c5d1SDavid du Colombier 	}
14216b6b9ac8SDavid du Colombier 	diag("bad irr %d", a);
1422dc5a79c1SDavid du Colombier abort();
1423dc5a79c1SDavid du Colombier 	return 0;
1424dc5a79c1SDavid du Colombier }
1425dc5a79c1SDavid du Colombier 
1426dc5a79c1SDavid du Colombier int
1427dc5a79c1SDavid du Colombier vshift(int a)
1428dc5a79c1SDavid du Colombier {
1429dc5a79c1SDavid du Colombier 	switch(a){
1430dc5a79c1SDavid du Colombier 	case ASLLV:		return 1;
1431dc5a79c1SDavid du Colombier 	case ASRLV:		return 1;
1432dc5a79c1SDavid du Colombier 	case ASRAV:		return 1;
1433dc5a79c1SDavid du Colombier 	}
14343e12c5d1SDavid du Colombier 	return 0;
14353e12c5d1SDavid du Colombier }
1436