xref: /plan9/sys/src/cmd/vl/asm.c (revision a826b788f46ccc92a1e0e05eb47067d9d683fddd)
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
cput(long l)948153b942SDavid du Colombier cput(long l)
958153b942SDavid du Colombier {
968153b942SDavid du Colombier 	CPUT(l);
978153b942SDavid du Colombier }
988153b942SDavid du Colombier 
998153b942SDavid du Colombier void
objput(long l)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
objhput(short s)106bfb6eab9SDavid du Colombier objhput(short s)
107bfb6eab9SDavid du Colombier {
108bfb6eab9SDavid du Colombier 	HPUT(s);
109bfb6eab9SDavid du Colombier }
110bfb6eab9SDavid du Colombier 
111bfb6eab9SDavid du Colombier void
wput(long l)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
wputl(long l)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
lput(long l)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
lputl(long l)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
llput(vlong v)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
llputl(vlong v)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
entryvalue(void)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
plan9bootimage(ulong sects,ulong submagicvers,ulong tm,ulong hdrtxtsz,ulong textsz,ulong textva,ulong lcsize)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
symhdrs(ulong hdrtxtsz)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
asmb(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;
2973e12c5d1SDavid du Colombier 	case 1:
2983e12c5d1SDavid du Colombier 	case 2:
299219b2ee8SDavid du Colombier 	case 3:
300219b2ee8SDavid du Colombier 	case 5:
30191178603SDavid du Colombier 	case 6:
302*a826b788SDavid du Colombier 	case 7:
303bd389b36SDavid du Colombier 		OFFSET = HEADR+textsize;
304bd389b36SDavid du Colombier 		seek(cout, OFFSET, 0);
3053e12c5d1SDavid du Colombier 		break;
3063e12c5d1SDavid du Colombier 	}
3073e12c5d1SDavid du Colombier 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
3083e12c5d1SDavid du Colombier 		if(datsize-t > sizeof(buf)-100)
3099a747e4fSDavid du Colombier 			datblk(t, sizeof(buf)-100, 0);
3103e12c5d1SDavid du Colombier 		else
3119a747e4fSDavid du Colombier 			datblk(t, datsize-t, 0);
3123e12c5d1SDavid du Colombier 	}
3133e12c5d1SDavid du Colombier 
3143e12c5d1SDavid du Colombier 	symsize = 0;
3153e12c5d1SDavid du Colombier 	lcsize = 0;
3163e12c5d1SDavid du Colombier 	if(!debug['s']) {
3173e12c5d1SDavid du Colombier 		if(debug['v'])
3183e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
3193e12c5d1SDavid du Colombier 		Bflush(&bso);
3203e12c5d1SDavid du Colombier 		switch(HEADTYPE) {
3213e12c5d1SDavid du Colombier 		case 0:
322219b2ee8SDavid du Colombier 		case 4:
323bd389b36SDavid du Colombier 			OFFSET = rnd(HEADR+textsize, 4096)+datsize;
324bd389b36SDavid du Colombier 			seek(cout, OFFSET, 0);
3253e12c5d1SDavid du Colombier 			break;
326219b2ee8SDavid du Colombier 		case 3:
3273e12c5d1SDavid du Colombier 		case 2:
3283e12c5d1SDavid du Colombier 		case 1:
329219b2ee8SDavid du Colombier 		case 5:
33091178603SDavid du Colombier 		case 6:
331*a826b788SDavid du Colombier 		case 7:
332bd389b36SDavid du Colombier 			OFFSET = HEADR+textsize+datsize;
333bd389b36SDavid du Colombier 			seek(cout, OFFSET, 0);
3343e12c5d1SDavid du Colombier 			break;
3353e12c5d1SDavid du Colombier 		}
3363e12c5d1SDavid du Colombier 		if(!debug['s'])
3373e12c5d1SDavid du Colombier 			asmsym();
3383e12c5d1SDavid du Colombier 		if(debug['v'])
3393e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f pc\n", cputime());
3403e12c5d1SDavid du Colombier 		Bflush(&bso);
3413e12c5d1SDavid du Colombier 		if(!debug['s'])
3423e12c5d1SDavid du Colombier 			asmlc();
3433e12c5d1SDavid du Colombier 		cflush();
3443e12c5d1SDavid du Colombier 	}
3453e12c5d1SDavid du Colombier 
3463e12c5d1SDavid du Colombier 	if(debug['v'])
3473e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f header\n", cputime());
3483e12c5d1SDavid du Colombier 	Bflush(&bso);
349bd389b36SDavid du Colombier 	OFFSET = 0;
350bd389b36SDavid du Colombier 	seek(cout, OFFSET, 0);
3515482313dSDavid du Colombier 
3525482313dSDavid du Colombier 	rndtxtsz = rnd(HEADR+textsize, (INITRND > 0? INITRND: 4096));
3535482313dSDavid du Colombier 	tm = time(0);
3543e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
3553e12c5d1SDavid du Colombier 	case 0:
3565482313dSDavid du Colombier 		/* 0413: plan 9 boot image, text segment rounded (to 4KB) */
3575482313dSDavid du Colombier 		plan9bootimage(0, 0413<<16|0437, 0, rndtxtsz, rndtxtsz,
3585482313dSDavid du Colombier 			INITTEXT-HEADR, 0);
3593e12c5d1SDavid du Colombier 		break;
3603e12c5d1SDavid du Colombier 	case 1:
3615482313dSDavid du Colombier 		/* 0407: plan 9 boot image, extra word */
3625482313dSDavid du Colombier 		plan9bootimage(0, 0407<<16|0437, 0, HEADR+textsize, textsize,
3635482313dSDavid du Colombier 			INITTEXT, lcsize);
3645482313dSDavid du Colombier 		lput(0);			/* extra; complete mystery */
3653e12c5d1SDavid du Colombier 		break;
3663305c317SDavid du Colombier 	case 2:					/* plan 9 format */
36791178603SDavid du Colombier 		if (little)
3683305c317SDavid du Colombier 			lput(P_MAGIC);		/* mips 3000 LE */
36991178603SDavid du Colombier 		else
3703305c317SDavid du Colombier 			lput(V_MAGIC);		/* mips 3000 BE */
3713e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
3723e12c5d1SDavid du Colombier 		lput(datsize);
3733e12c5d1SDavid du Colombier 		lput(bsssize);
3743e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
3753e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
3763e12c5d1SDavid du Colombier 		lput(0L);
3773e12c5d1SDavid du Colombier 		lput(lcsize);
3783e12c5d1SDavid du Colombier 		break;
379219b2ee8SDavid du Colombier 	case 3:
3805482313dSDavid du Colombier 		/* 0407: plan 9 mips 4k boot image with symbols */
3815482313dSDavid du Colombier 		plan9bootimage(3, 0407<<16|0437, tm, HEADR+textsize, textsize,
3825482313dSDavid du Colombier 			INITTEXT, lcsize);
3835482313dSDavid du Colombier 		symhdrs(HEADR+textsize);
384219b2ee8SDavid du Colombier 		break;
385219b2ee8SDavid du Colombier 	case 4:
3865482313dSDavid du Colombier 		/* 0413: plan 9 mips 4k boot image with symbols */
3875482313dSDavid du Colombier 		plan9bootimage(3, 0413<<16|01012, tm, rndtxtsz, textsize,
3885482313dSDavid du Colombier 			INITTEXT, lcsize);
3895482313dSDavid du Colombier 		symhdrs(rndtxtsz);
390219b2ee8SDavid du Colombier 		break;
391219b2ee8SDavid du Colombier 	case 5:
3928153b942SDavid du Colombier 		elf32(MIPS, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
39391178603SDavid du Colombier 		break;
39491178603SDavid du Colombier 	case 6:
39591178603SDavid du Colombier 		break;
396a587111cSDavid du Colombier 	case 7:
397a587111cSDavid du Colombier 		elf64(MIPSR4K, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
398a587111cSDavid du Colombier 		break;
3993e12c5d1SDavid du Colombier 	}
4003e12c5d1SDavid du Colombier 	cflush();
4013e12c5d1SDavid du Colombier }
4023e12c5d1SDavid du Colombier 
4033e12c5d1SDavid du Colombier void
strnput(char * s,int n)404219b2ee8SDavid du Colombier strnput(char *s, int n)
405219b2ee8SDavid du Colombier {
406219b2ee8SDavid du Colombier 	for(; *s; s++){
407219b2ee8SDavid du Colombier 		CPUT(*s);
408219b2ee8SDavid du Colombier 		n--;
409219b2ee8SDavid du Colombier 	}
410219b2ee8SDavid du Colombier 	for(; n > 0; n--)
411219b2ee8SDavid du Colombier 		CPUT(0);
412219b2ee8SDavid du Colombier }
413219b2ee8SDavid du Colombier 
414219b2ee8SDavid du Colombier void
cflush(void)4153e12c5d1SDavid du Colombier cflush(void)
4163e12c5d1SDavid du Colombier {
4173e12c5d1SDavid du Colombier 	int n;
4183e12c5d1SDavid du Colombier 
4193e12c5d1SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
4203e12c5d1SDavid du Colombier 	if(n)
4213e12c5d1SDavid du Colombier 		write(cout, buf.cbuf, n);
4223e12c5d1SDavid du Colombier 	cbp = buf.cbuf;
4233e12c5d1SDavid du Colombier 	cbc = sizeof(buf.cbuf);
4243e12c5d1SDavid du Colombier }
4253e12c5d1SDavid du Colombier 
4263e12c5d1SDavid du Colombier void
nopstat(char * f,Count * c)427219b2ee8SDavid du Colombier nopstat(char *f, Count *c)
428219b2ee8SDavid du Colombier {
429219b2ee8SDavid du Colombier 	if(c->outof)
430219b2ee8SDavid du Colombier 	Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
431219b2ee8SDavid du Colombier 		c->outof - c->count, c->outof,
432219b2ee8SDavid du Colombier 		(double)(c->outof - c->count)/c->outof);
433219b2ee8SDavid du Colombier }
434219b2ee8SDavid du Colombier 
435219b2ee8SDavid du Colombier void
asmsym(void)4363e12c5d1SDavid du Colombier asmsym(void)
4373e12c5d1SDavid du Colombier {
4383e12c5d1SDavid du Colombier 	Prog *p;
4393e12c5d1SDavid du Colombier 	Auto *a;
4403e12c5d1SDavid du Colombier 	Sym *s;
4413e12c5d1SDavid du Colombier 	int h;
4423e12c5d1SDavid du Colombier 
4433e12c5d1SDavid du Colombier 	s = lookup("etext", 0);
4443e12c5d1SDavid du Colombier 	if(s->type == STEXT)
4453e12c5d1SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
4463e12c5d1SDavid du Colombier 
4473e12c5d1SDavid du Colombier 	for(h=0; h<NHASH; h++)
4483e12c5d1SDavid du Colombier 		for(s=hash[h]; s!=S; s=s->link)
4493e12c5d1SDavid du Colombier 			switch(s->type) {
450219b2ee8SDavid du Colombier 			case SCONST:
451219b2ee8SDavid du Colombier 				putsymb(s->name, 'D', s->value, s->version);
452219b2ee8SDavid du Colombier 				continue;
453219b2ee8SDavid du Colombier 
4549a747e4fSDavid du Colombier 			case SSTRING:
4559a747e4fSDavid du Colombier 				putsymb(s->name, 'T', s->value, s->version);
4569a747e4fSDavid du Colombier 				continue;
4579a747e4fSDavid du Colombier 
4583e12c5d1SDavid du Colombier 			case SDATA:
4593e12c5d1SDavid du Colombier 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
4603e12c5d1SDavid du Colombier 				continue;
4613e12c5d1SDavid du Colombier 
4623e12c5d1SDavid du Colombier 			case SBSS:
4633e12c5d1SDavid du Colombier 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
4643e12c5d1SDavid du Colombier 				continue;
4653e12c5d1SDavid du Colombier 
4663e12c5d1SDavid du Colombier 			case SFILE:
4673e12c5d1SDavid du Colombier 				putsymb(s->name, 'f', s->value, s->version);
4683e12c5d1SDavid du Colombier 				continue;
4693e12c5d1SDavid du Colombier 			}
4703e12c5d1SDavid du Colombier 
4713e12c5d1SDavid du Colombier 	for(p=textp; p!=P; p=p->cond) {
4723e12c5d1SDavid du Colombier 		s = p->from.sym;
4733e12c5d1SDavid du Colombier 		if(s->type != STEXT && s->type != SLEAF)
4743e12c5d1SDavid du Colombier 			continue;
4753e12c5d1SDavid du Colombier 
4763e12c5d1SDavid du Colombier 		/* filenames first */
4773e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
4783e12c5d1SDavid du Colombier 			if(a->type == D_FILE)
4797dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'z', a->aoffset, 0);
4803e12c5d1SDavid du Colombier 			else
481219b2ee8SDavid du Colombier 			if(a->type == D_FILE1)
4827dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'Z', a->aoffset, 0);
4833e12c5d1SDavid du Colombier 
4843e12c5d1SDavid du Colombier 		if(s->type == STEXT)
4853e12c5d1SDavid du Colombier 			putsymb(s->name, 'T', s->value, s->version);
4863e12c5d1SDavid du Colombier 		else
4873e12c5d1SDavid du Colombier 			putsymb(s->name, 'L', s->value, s->version);
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier 		/* frame, auto and param after */
490219b2ee8SDavid du Colombier 		putsymb(".frame", 'm', p->to.offset+4, 0);
4913e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
4923e12c5d1SDavid du Colombier 			if(a->type == D_AUTO)
4937dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'a', -a->aoffset, 0);
4943e12c5d1SDavid du Colombier 			else
4953e12c5d1SDavid du Colombier 			if(a->type == D_PARAM)
4967dd7cddfSDavid du Colombier 				putsymb(a->asym->name, 'p', a->aoffset, 0);
4973e12c5d1SDavid du Colombier 	}
4983e12c5d1SDavid du Colombier 	if(debug['v'] || debug['n'])
4993e12c5d1SDavid du Colombier 		Bprint(&bso, "symsize = %lud\n", symsize);
5003e12c5d1SDavid du Colombier 	Bflush(&bso);
5013e12c5d1SDavid du Colombier }
5023e12c5d1SDavid du Colombier 
5033e12c5d1SDavid du Colombier void
putsymb(char * s,int t,long v,int ver)5043e12c5d1SDavid du Colombier putsymb(char *s, int t, long v, int ver)
5053e12c5d1SDavid du Colombier {
5063e12c5d1SDavid du Colombier 	int i, f;
5073e12c5d1SDavid du Colombier 
5083e12c5d1SDavid du Colombier 	if(t == 'f')
5093e12c5d1SDavid du Colombier 		s++;
51091178603SDavid du Colombier 	LBEPUT(v);
5113e12c5d1SDavid du Colombier 	if(ver)
5123e12c5d1SDavid du Colombier 		t += 'a' - 'A';
513219b2ee8SDavid du Colombier 	CPUT(t+0x80);			/* 0x80 is variable length */
514219b2ee8SDavid du Colombier 
515219b2ee8SDavid du Colombier 	if(t == 'Z' || t == 'z') {
516219b2ee8SDavid du Colombier 		CPUT(s[0]);
517219b2ee8SDavid du Colombier 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
518219b2ee8SDavid du Colombier 			CPUT(s[i]);
519219b2ee8SDavid du Colombier 			CPUT(s[i+1]);
520219b2ee8SDavid du Colombier 		}
521219b2ee8SDavid du Colombier 		CPUT(0);
522219b2ee8SDavid du Colombier 		CPUT(0);
523219b2ee8SDavid du Colombier 		i++;
524219b2ee8SDavid du Colombier 	}
525219b2ee8SDavid du Colombier 	else {
526219b2ee8SDavid du Colombier 		for(i=0; s[i]; i++)
5273e12c5d1SDavid du Colombier 			CPUT(s[i]);
5283e12c5d1SDavid du Colombier 		CPUT(0);
529219b2ee8SDavid du Colombier 	}
530219b2ee8SDavid du Colombier 	symsize += 4 + 1 + i + 1;
531219b2ee8SDavid du Colombier 
5323e12c5d1SDavid du Colombier 	if(debug['n']) {
5333e12c5d1SDavid du Colombier 		if(t == 'z' || t == 'Z') {
534219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux ", t, v);
535219b2ee8SDavid du Colombier 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
5363e12c5d1SDavid du Colombier 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
537219b2ee8SDavid du Colombier 				Bprint(&bso, "/%x", f);
5383e12c5d1SDavid du Colombier 			}
539219b2ee8SDavid du Colombier 			Bprint(&bso, "\n");
5403e12c5d1SDavid du Colombier 			return;
5413e12c5d1SDavid du Colombier 		}
5423e12c5d1SDavid du Colombier 		if(ver)
5433e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
5443e12c5d1SDavid du Colombier 		else
5453e12c5d1SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
5463e12c5d1SDavid du Colombier 	}
5473e12c5d1SDavid du Colombier }
5483e12c5d1SDavid du Colombier 
5493e12c5d1SDavid du Colombier #define	MINLC	4
5503e12c5d1SDavid du Colombier void
asmlc(void)5513e12c5d1SDavid du Colombier asmlc(void)
5523e12c5d1SDavid du Colombier {
553a587111cSDavid du Colombier 	long oldlc, v, s;
554a587111cSDavid du Colombier 	vlong oldpc;
5553e12c5d1SDavid du Colombier 	Prog *p;
5563e12c5d1SDavid du Colombier 
5573e12c5d1SDavid du Colombier 	oldpc = INITTEXT;
5583e12c5d1SDavid du Colombier 	oldlc = 0;
5593e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
5603e12c5d1SDavid du Colombier 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
5613e12c5d1SDavid du Colombier 			if(p->as == ATEXT)
5623e12c5d1SDavid du Colombier 				curtext = p;
563b87cd620SDavid du Colombier 			if(debug['V'])
564a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
5653e12c5d1SDavid du Colombier 			continue;
5663e12c5d1SDavid du Colombier 		}
567b87cd620SDavid du Colombier 		if(debug['V'])
5683e12c5d1SDavid du Colombier 			Bprint(&bso, "\t\t%6ld", lcsize);
5693e12c5d1SDavid du Colombier 		v = (p->pc - oldpc) / MINLC;
5703e12c5d1SDavid du Colombier 		while(v) {
5713e12c5d1SDavid du Colombier 			s = 127;
5723e12c5d1SDavid du Colombier 			if(v < 127)
5733e12c5d1SDavid du Colombier 				s = v;
5743e12c5d1SDavid du Colombier 			CPUT(s+128);	/* 129-255 +pc */
575b87cd620SDavid du Colombier 			if(debug['V'])
5763e12c5d1SDavid du Colombier 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
5773e12c5d1SDavid du Colombier 			v -= s;
5783e12c5d1SDavid du Colombier 			lcsize++;
5793e12c5d1SDavid du Colombier 		}
5803e12c5d1SDavid du Colombier 		s = p->line - oldlc;
5813e12c5d1SDavid du Colombier 		oldlc = p->line;
5823e12c5d1SDavid du Colombier 		oldpc = p->pc + MINLC;
5833e12c5d1SDavid du Colombier 		if(s > 64 || s < -64) {
5843e12c5d1SDavid du Colombier 			CPUT(0);	/* 0 vv +lc */
5853e12c5d1SDavid du Colombier 			CPUT(s>>24);
5863e12c5d1SDavid du Colombier 			CPUT(s>>16);
5873e12c5d1SDavid du Colombier 			CPUT(s>>8);
5883e12c5d1SDavid du Colombier 			CPUT(s);
589b87cd620SDavid du Colombier 			if(debug['V']) {
5903e12c5d1SDavid du Colombier 				if(s > 0)
5913e12c5d1SDavid du Colombier 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
5923e12c5d1SDavid du Colombier 						s, 0, s);
5933e12c5d1SDavid du Colombier 				else
5943e12c5d1SDavid du Colombier 					Bprint(&bso, " lc%ld(%d,%ld)\n",
5953e12c5d1SDavid du Colombier 						s, 0, s);
596a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
5973e12c5d1SDavid du Colombier 			}
5983e12c5d1SDavid du Colombier 			lcsize += 5;
5993e12c5d1SDavid du Colombier 			continue;
6003e12c5d1SDavid du Colombier 		}
6013e12c5d1SDavid du Colombier 		if(s > 0) {
6023e12c5d1SDavid du Colombier 			CPUT(0+s);	/* 1-64 +lc */
603b87cd620SDavid du Colombier 			if(debug['V']) {
6043e12c5d1SDavid du Colombier 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
605a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
6063e12c5d1SDavid du Colombier 			}
6073e12c5d1SDavid du Colombier 		} else {
6083e12c5d1SDavid du Colombier 			CPUT(64-s);	/* 65-128 -lc */
609b87cd620SDavid du Colombier 			if(debug['V']) {
6103e12c5d1SDavid du Colombier 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
611a587111cSDavid du Colombier 				Bprint(&bso, "%6llux %P\n", p->pc, p);
6123e12c5d1SDavid du Colombier 			}
6133e12c5d1SDavid du Colombier 		}
6143e12c5d1SDavid du Colombier 		lcsize++;
6153e12c5d1SDavid du Colombier 	}
6163e12c5d1SDavid du Colombier 	while(lcsize & 1) {
6173e12c5d1SDavid du Colombier 		s = 129;
6183e12c5d1SDavid du Colombier 		CPUT(s);
6193e12c5d1SDavid du Colombier 		lcsize++;
6203e12c5d1SDavid du Colombier 	}
621b87cd620SDavid du Colombier 	if(debug['v'] || debug['V'])
6223e12c5d1SDavid du Colombier 		Bprint(&bso, "lcsize = %ld\n", lcsize);
6233e12c5d1SDavid du Colombier 	Bflush(&bso);
6243e12c5d1SDavid du Colombier }
6253e12c5d1SDavid du Colombier 
6263e12c5d1SDavid du Colombier void
datblk(long s,long n,int str)6279a747e4fSDavid du Colombier datblk(long s, long n, int str)
6283e12c5d1SDavid du Colombier {
6293e12c5d1SDavid du Colombier 	Prog *p;
6303e12c5d1SDavid du Colombier 	char *cast;
6313e12c5d1SDavid du Colombier 	long l, fl, j, d;
6323e12c5d1SDavid du Colombier 	int i, c;
6333e12c5d1SDavid du Colombier 
6343e12c5d1SDavid du Colombier 	memset(buf.dbuf, 0, n+100);
6353e12c5d1SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
6363e12c5d1SDavid du Colombier 		curp = p;
6379a747e4fSDavid du Colombier 		if(str != (p->from.sym->type == SSTRING))
6389a747e4fSDavid du Colombier 			continue;
6393e12c5d1SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
6403e12c5d1SDavid du Colombier 		c = p->reg;
6413e12c5d1SDavid du Colombier 		i = 0;
6423e12c5d1SDavid du Colombier 		if(l < 0) {
6433e12c5d1SDavid du Colombier 			if(l+c <= 0)
6443e12c5d1SDavid du Colombier 				continue;
6453e12c5d1SDavid du Colombier 			while(l < 0) {
6463e12c5d1SDavid du Colombier 				l++;
6473e12c5d1SDavid du Colombier 				i++;
6483e12c5d1SDavid du Colombier 			}
6493e12c5d1SDavid du Colombier 		}
6503e12c5d1SDavid du Colombier 		if(l >= n)
6513e12c5d1SDavid du Colombier 			continue;
652219b2ee8SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
6533e12c5d1SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
6543e12c5d1SDavid du Colombier 				if(buf.dbuf[j]) {
6553e12c5d1SDavid du Colombier 					print("%P\n", p);
6566b6b9ac8SDavid du Colombier 					diag("multiple initialization");
6573e12c5d1SDavid du Colombier 					break;
6583e12c5d1SDavid du Colombier 				}
659219b2ee8SDavid du Colombier 		}
6603e12c5d1SDavid du Colombier 		switch(p->to.type) {
6613e12c5d1SDavid du Colombier 		default:
6626b6b9ac8SDavid du Colombier 			diag("unknown mode in initialization\n%P", p);
6633e12c5d1SDavid du Colombier 			break;
6643e12c5d1SDavid du Colombier 
6653e12c5d1SDavid du Colombier 		case D_FCONST:
6663e12c5d1SDavid du Colombier 			switch(c) {
6673e12c5d1SDavid du Colombier 			default:
6683e12c5d1SDavid du Colombier 			case 4:
6693e12c5d1SDavid du Colombier 				fl = ieeedtof(p->to.ieee);
6703e12c5d1SDavid du Colombier 				cast = (char*)&fl;
6713e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6723e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i+4]];
6733e12c5d1SDavid du Colombier 					l++;
6743e12c5d1SDavid du Colombier 				}
6753e12c5d1SDavid du Colombier 				break;
6763e12c5d1SDavid du Colombier 			case 8:
6773e12c5d1SDavid du Colombier 				cast = (char*)p->to.ieee;
6783e12c5d1SDavid du Colombier 				for(; i<c; i++) {
6793e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
6803e12c5d1SDavid du Colombier 					l++;
6813e12c5d1SDavid du Colombier 				}
6823e12c5d1SDavid du Colombier 				break;
6833e12c5d1SDavid du Colombier 			}
6843e12c5d1SDavid du Colombier 			break;
6853e12c5d1SDavid du Colombier 
6863e12c5d1SDavid du Colombier 		case D_SCONST:
6873e12c5d1SDavid du Colombier 			for(; i<c; i++) {
6883e12c5d1SDavid du Colombier 				buf.dbuf[l] = p->to.sval[i];
6893e12c5d1SDavid du Colombier 				l++;
6903e12c5d1SDavid du Colombier 			}
6913e12c5d1SDavid du Colombier 			break;
6923e12c5d1SDavid du Colombier 
6933e12c5d1SDavid du Colombier 		case D_CONST:
6943e12c5d1SDavid du Colombier 			d = p->to.offset;
6953e12c5d1SDavid du Colombier 			if(p->to.sym) {
6969a747e4fSDavid du Colombier 				switch(p->to.sym->type) {
6979a747e4fSDavid du Colombier 				case STEXT:
6989a747e4fSDavid du Colombier 				case SLEAF:
6999a747e4fSDavid du Colombier 				case SSTRING:
7003e12c5d1SDavid du Colombier 					d += p->to.sym->value;
7019a747e4fSDavid du Colombier 					break;
7029a747e4fSDavid du Colombier 				case SDATA:
7039a747e4fSDavid du Colombier 				case SBSS:
7043e12c5d1SDavid du Colombier 					d += p->to.sym->value + INITDAT;
7059a747e4fSDavid du Colombier 					break;
7069a747e4fSDavid du Colombier 				}
7073e12c5d1SDavid du Colombier 			}
7083e12c5d1SDavid du Colombier 			cast = (char*)&d;
7093e12c5d1SDavid du Colombier 			switch(c) {
7103e12c5d1SDavid du Colombier 			default:
7116b6b9ac8SDavid du Colombier 				diag("bad nuxi %d %d\n%P", c, i, curp);
7123e12c5d1SDavid du Colombier 				break;
7133e12c5d1SDavid du Colombier 			case 1:
7143e12c5d1SDavid du Colombier 				for(; i<c; i++) {
7153e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
7163e12c5d1SDavid du Colombier 					l++;
7173e12c5d1SDavid du Colombier 				}
7183e12c5d1SDavid du Colombier 				break;
7193e12c5d1SDavid du Colombier 			case 2:
7203e12c5d1SDavid du Colombier 				for(; i<c; i++) {
7213e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
7223e12c5d1SDavid du Colombier 					l++;
7233e12c5d1SDavid du Colombier 				}
7243e12c5d1SDavid du Colombier 				break;
7253e12c5d1SDavid du Colombier 			case 4:
7263e12c5d1SDavid du Colombier 				for(; i<c; i++) {
7273e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
7283e12c5d1SDavid du Colombier 					l++;
7293e12c5d1SDavid du Colombier 				}
7303e12c5d1SDavid du Colombier 				break;
7313e12c5d1SDavid du Colombier 			}
7323e12c5d1SDavid du Colombier 			break;
7333e12c5d1SDavid du Colombier 		}
7343e12c5d1SDavid du Colombier 	}
7353e12c5d1SDavid du Colombier 	write(cout, buf.dbuf, n);
7363e12c5d1SDavid du Colombier }
7373e12c5d1SDavid du Colombier 
7383e12c5d1SDavid du Colombier #define	OP_RRR(op,r1,r2,r3)\
7393e12c5d1SDavid du Colombier 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))
7403e12c5d1SDavid du Colombier #define	OP_IRR(op,i,r2,r3)\
7413e12c5d1SDavid du Colombier 	(op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))
7423e12c5d1SDavid du Colombier #define	OP_SRR(op,s,r2,r3)\
7433e12c5d1SDavid du Colombier 	(op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))
7443e12c5d1SDavid du Colombier #define	OP_FRRR(op,r1,r2,r3)\
7453e12c5d1SDavid du Colombier 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))
7463e12c5d1SDavid du Colombier #define	OP_JMP(op,i)\
7473e12c5d1SDavid du Colombier 		((op)|((i)&0x3ffffffL))
7483e12c5d1SDavid du Colombier 
749219b2ee8SDavid du Colombier #define	OP(x,y)\
750219b2ee8SDavid du Colombier 	(((x)<<3)|((y)<<0))
751219b2ee8SDavid du Colombier #define	SP(x,y)\
752219b2ee8SDavid du Colombier 	(((x)<<29)|((y)<<26))
753219b2ee8SDavid du Colombier #define	BCOND(x,y)\
754219b2ee8SDavid du Colombier 	(((x)<<19)|((y)<<16))
755219b2ee8SDavid du Colombier #define	MMU(x,y)\
756219b2ee8SDavid du Colombier 	(SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))
757219b2ee8SDavid du Colombier #define	FPF(x,y)\
758219b2ee8SDavid du Colombier 	(SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))
759219b2ee8SDavid du Colombier #define	FPD(x,y)\
760219b2ee8SDavid du Colombier 	(SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))
761219b2ee8SDavid du Colombier #define	FPW(x,y)\
762219b2ee8SDavid du Colombier 	(SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))
763219b2ee8SDavid du Colombier 
764dc5a79c1SDavid du Colombier int vshift(int);
765dc5a79c1SDavid du Colombier 
7663e12c5d1SDavid du Colombier int
asmout(Prog * p,Optab * o,int aflag)7673e12c5d1SDavid du Colombier asmout(Prog *p, Optab *o, int aflag)
7683e12c5d1SDavid du Colombier {
7697dd7cddfSDavid du Colombier 	long o1, o2, o3, o4, o5, o6, o7, v;
7703e12c5d1SDavid du Colombier 	Prog *ct;
7713e12c5d1SDavid du Colombier 	int r, a;
7723e12c5d1SDavid du Colombier 
7733e12c5d1SDavid du Colombier 	o1 = 0;
7743e12c5d1SDavid du Colombier 	o2 = 0;
7753e12c5d1SDavid du Colombier 	o3 = 0;
7763e12c5d1SDavid du Colombier 	o4 = 0;
777219b2ee8SDavid du Colombier 	o5 = 0;
7787dd7cddfSDavid du Colombier 	o6 = 0;
7797dd7cddfSDavid du Colombier 	o7 = 0;
7803e12c5d1SDavid du Colombier 	switch(o->type) {
7813e12c5d1SDavid du Colombier 	default:
7826b6b9ac8SDavid du Colombier 		diag("unknown type %d", o->type);
7833e12c5d1SDavid du Colombier 		if(!debug['a'])
7843e12c5d1SDavid du Colombier 			prasm(p);
7853e12c5d1SDavid du Colombier 		break;
7863e12c5d1SDavid du Colombier 
7873e12c5d1SDavid du Colombier 	case 0:		/* pseudo ops */
7883e12c5d1SDavid du Colombier 		if(aflag) {
7893e12c5d1SDavid du Colombier 			if(p->link) {
7903e12c5d1SDavid du Colombier 				if(p->as == ATEXT) {
7913e12c5d1SDavid du Colombier 					ct = curtext;
7923e12c5d1SDavid du Colombier 					o2 = autosize;
7933e12c5d1SDavid du Colombier 					curtext = p;
7943e12c5d1SDavid du Colombier 					autosize = p->to.offset + 4;
7953e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
7963e12c5d1SDavid du Colombier 					curtext = ct;
7973e12c5d1SDavid du Colombier 					autosize = o2;
7983e12c5d1SDavid du Colombier 				} else
7993e12c5d1SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
8003e12c5d1SDavid du Colombier 			}
8013e12c5d1SDavid du Colombier 			return o1;
8023e12c5d1SDavid du Colombier 		}
8033e12c5d1SDavid du Colombier 		break;
8043e12c5d1SDavid du Colombier 
805219b2ee8SDavid du Colombier 	case 1:		/* mov[v] r1,r2 ==> OR r1,r0,r2 */
8063e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg);
8073e12c5d1SDavid du Colombier 		break;
8083e12c5d1SDavid du Colombier 
8093e12c5d1SDavid du Colombier 	case 2:		/* add/sub r1,[r2],r3 */
8103e12c5d1SDavid du Colombier 		r = p->reg;
8113e12c5d1SDavid du Colombier 		if(r == NREG)
8123e12c5d1SDavid du Colombier 			r = p->to.reg;
8133e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg);
8143e12c5d1SDavid du Colombier 		break;
8153e12c5d1SDavid du Colombier 
8163e12c5d1SDavid du Colombier 	case 3:		/* mov $soreg, r ==> or/add $i,o,r */
8173e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8183e12c5d1SDavid du Colombier 		r = p->from.reg;
8193e12c5d1SDavid du Colombier 		if(r == NREG)
8203e12c5d1SDavid du Colombier 			r = o->param;
821219b2ee8SDavid du Colombier 		a = AADDU;
8223e12c5d1SDavid du Colombier 		if(o->a1 == C_ANDCON)
8233e12c5d1SDavid du Colombier 			a = AOR;
8243e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(a), v, r, p->to.reg);
8253e12c5d1SDavid du Colombier 		break;
8263e12c5d1SDavid du Colombier 
8273e12c5d1SDavid du Colombier 	case 4:		/* add $scon,[r1],r2 */
8283e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8293e12c5d1SDavid du Colombier 		r = p->reg;
8303e12c5d1SDavid du Colombier 		if(r == NREG)
8313e12c5d1SDavid du Colombier 			r = p->to.reg;
8323e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, r, p->to.reg);
8333e12c5d1SDavid du Colombier 		break;
8343e12c5d1SDavid du Colombier 
8353e12c5d1SDavid du Colombier 	case 5:		/* syscall */
8363e12c5d1SDavid du Colombier 		if(aflag)
8373e12c5d1SDavid du Colombier 			return 0;
8383e12c5d1SDavid du Colombier 		o1 = oprrr(p->as);
8393e12c5d1SDavid du Colombier 		break;
8403e12c5d1SDavid du Colombier 
8413e12c5d1SDavid du Colombier 	case 6:		/* beq r1,[r2],sbra */
8423e12c5d1SDavid du Colombier 		if(aflag)
8433e12c5d1SDavid du Colombier 			return 0;
8443e12c5d1SDavid du Colombier 		if(p->cond == P)
8453e12c5d1SDavid du Colombier 			v = -4 >> 2;
8463e12c5d1SDavid du Colombier 		else
8473e12c5d1SDavid du Colombier 			v = (p->cond->pc - pc-4) >> 2;
8487dd7cddfSDavid du Colombier 		if(((v << 16) >> 16) != v)
849406758d9SDavid du Colombier 			diag("short branch too far: %ld\n%P", v, p);
8503e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg);
8513e12c5d1SDavid du Colombier 		break;
8523e12c5d1SDavid du Colombier 
8533e12c5d1SDavid du Colombier 	case 7:		/* mov r, soreg ==> sw o(r) */
8543e12c5d1SDavid du Colombier 		r = p->to.reg;
8553e12c5d1SDavid du Colombier 		if(r == NREG)
8563e12c5d1SDavid du Colombier 			r = o->param;
8573e12c5d1SDavid du Colombier 		v = regoff(&p->to);
8583e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(p->as), v, r, p->from.reg);
8593e12c5d1SDavid du Colombier 		break;
8603e12c5d1SDavid du Colombier 
8613e12c5d1SDavid du Colombier 	case 8:		/* mov soreg, r ==> lw o(r) */
8623e12c5d1SDavid du Colombier 		r = p->from.reg;
8633e12c5d1SDavid du Colombier 		if(r == NREG)
8643e12c5d1SDavid du Colombier 			r = o->param;
8653e12c5d1SDavid du Colombier 		v = regoff(&p->from);
866219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg);
8673e12c5d1SDavid du Colombier 		break;
8683e12c5d1SDavid du Colombier 
8693e12c5d1SDavid du Colombier 	case 9:		/* asl r1,[r2],r3 */
8703e12c5d1SDavid du Colombier 		r = p->reg;
8713e12c5d1SDavid du Colombier 		if(r == NREG)
8723e12c5d1SDavid du Colombier 			r = p->to.reg;
8733e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
8743e12c5d1SDavid du Colombier 		break;
8753e12c5d1SDavid du Colombier 
8763e12c5d1SDavid du Colombier 	case 10:	/* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */
8773e12c5d1SDavid du Colombier 		v = regoff(&p->from);
8783e12c5d1SDavid du Colombier 		r = AOR;
8793e12c5d1SDavid du Colombier 		if(v < 0)
880219b2ee8SDavid du Colombier 			r = AADDU;
8813e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(r), v, 0, REGTMP);
8823e12c5d1SDavid du Colombier 		r = p->reg;
8833e12c5d1SDavid du Colombier 		if(r == NREG)
8843e12c5d1SDavid du Colombier 			r = p->to.reg;
8853e12c5d1SDavid du Colombier 		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
8863e12c5d1SDavid du Colombier 		break;
8873e12c5d1SDavid du Colombier 
8883e12c5d1SDavid du Colombier 	case 11:	/* jmp lbra */
8893e12c5d1SDavid du Colombier 		if(aflag)
8903e12c5d1SDavid du Colombier 			return 0;
8913e12c5d1SDavid du Colombier 		if(p->cond == P)
8923e12c5d1SDavid du Colombier 			v = p->pc >> 2;
8933e12c5d1SDavid du Colombier 		else
8943e12c5d1SDavid du Colombier 			v = p->cond->pc >> 2;
8953e12c5d1SDavid du Colombier 		o1 = OP_JMP(opirr(p->as), v);
896219b2ee8SDavid du Colombier 		if(!debug['Y'] && p->link && p->cond && isnop(p->link)) {
897219b2ee8SDavid du Colombier 			nop.branch.count--;
898219b2ee8SDavid du Colombier 			nop.branch.outof--;
899219b2ee8SDavid du Colombier 			nop.jump.outof++;
9003e12c5d1SDavid du Colombier 			o2 = asmout(p->cond, oplook(p->cond), 1);
9013e12c5d1SDavid du Colombier 			if(o2) {
9023e12c5d1SDavid du Colombier 				o1 += 1;
9033e12c5d1SDavid du Colombier 				if(debug['a'])
904a587111cSDavid du Colombier 					Bprint(&bso, " %.8llux: %.8lux %.8lux%P\n",
905219b2ee8SDavid du Colombier 						p->pc, o1, o2, p);
9063e12c5d1SDavid du Colombier 				LPUT(o1);
9073e12c5d1SDavid du Colombier 				LPUT(o2);
9083e12c5d1SDavid du Colombier 				return 1;
9093e12c5d1SDavid du Colombier 			}
9103e12c5d1SDavid du Colombier 		}
9113e12c5d1SDavid du Colombier 		break;
9123e12c5d1SDavid du Colombier 
9133e12c5d1SDavid du Colombier 	case 12:	/* movbs r,r */
9143e12c5d1SDavid du Colombier 		v = 16;
9153e12c5d1SDavid du Colombier 		if(p->as == AMOVB)
9163e12c5d1SDavid du Colombier 			v = 24;
9173e12c5d1SDavid du Colombier 		o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg);
9183e12c5d1SDavid du Colombier 		o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg);
9193e12c5d1SDavid du Colombier 		break;
9203e12c5d1SDavid du Colombier 
9213e12c5d1SDavid du Colombier 	case 13:	/* movbu r,r */
9223e12c5d1SDavid du Colombier 		if(p->as == AMOVBU)
9233e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg);
9243e12c5d1SDavid du Colombier 		else
9253e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg);
9263e12c5d1SDavid du Colombier 		break;
9273e12c5d1SDavid du Colombier 
9283e12c5d1SDavid du Colombier 	case 16:	/* sll $c,[r1],r2 */
9293e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9303e12c5d1SDavid du Colombier 		r = p->reg;
9313e12c5d1SDavid du Colombier 		if(r == NREG)
9323e12c5d1SDavid du Colombier 			r = p->to.reg;
933dc5a79c1SDavid du Colombier 
934dc5a79c1SDavid du Colombier 		/* OP_SRR will use only the low 5 bits of the shift value */
935dc5a79c1SDavid du Colombier 		if(v >= 32 && vshift(p->as))
936219b2ee8SDavid du Colombier 			o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg);
937219b2ee8SDavid du Colombier 		else
9383e12c5d1SDavid du Colombier 			o1 = OP_SRR(opirr(p->as), v, r, p->to.reg);
9393e12c5d1SDavid du Colombier 		break;
9403e12c5d1SDavid du Colombier 
9413e12c5d1SDavid du Colombier 	case 18:	/* jmp [r1],0(r2) */
9423e12c5d1SDavid du Colombier 		if(aflag)
9433e12c5d1SDavid du Colombier 			return 0;
9443e12c5d1SDavid du Colombier 		r = p->reg;
9453e12c5d1SDavid du Colombier 		if(r == NREG)
9463e12c5d1SDavid du Colombier 			r = o->param;
9473e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r);
9483e12c5d1SDavid du Colombier 		break;
9493e12c5d1SDavid du Colombier 
9503e12c5d1SDavid du Colombier 	case 19:	/* mov $lcon,r ==> lu+or */
9513e12c5d1SDavid du Colombier 		v = regoff(&p->from);
952219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9533e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg);
9543e12c5d1SDavid du Colombier 		break;
9553e12c5d1SDavid du Colombier 
956219b2ee8SDavid du Colombier 	case 20:	/* mov lohi,r */
957219b2ee8SDavid du Colombier 		r = OP(2,0);		/* mfhi */
9583e12c5d1SDavid du Colombier 		if(p->from.type == D_LO)
959219b2ee8SDavid du Colombier 			r = OP(2,2);	/* mflo */
960219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg);
9613e12c5d1SDavid du Colombier 		break;
9623e12c5d1SDavid du Colombier 
963219b2ee8SDavid du Colombier 	case 21:	/* mov r,lohi */
964219b2ee8SDavid du Colombier 		r = OP(2,1);		/* mthi */
9653e12c5d1SDavid du Colombier 		if(p->to.type == D_LO)
966219b2ee8SDavid du Colombier 			r = OP(2,3);	/* mtlo */
967219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO);
9683e12c5d1SDavid du Colombier 		break;
9693e12c5d1SDavid du Colombier 
9703e12c5d1SDavid du Colombier 	case 22:	/* mul r1,r2 */
9713e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO);
9723e12c5d1SDavid du Colombier 		break;
9733e12c5d1SDavid du Colombier 
9743e12c5d1SDavid du Colombier 	case 23:	/* add $lcon,r1,r2 ==> lu+or+add */
9753e12c5d1SDavid du Colombier 		v = regoff(&p->from);
9763e12c5d1SDavid du Colombier 		if(p->to.reg == REGTMP || p->reg == REGTMP)
9776b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
978219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9793e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
9803e12c5d1SDavid du Colombier 		r = p->reg;
9813e12c5d1SDavid du Colombier 		if(r == NREG)
9823e12c5d1SDavid du Colombier 			r = p->to.reg;
9833e12c5d1SDavid du Colombier 		o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
9843e12c5d1SDavid du Colombier 		break;
9853e12c5d1SDavid du Colombier 
9863e12c5d1SDavid du Colombier 	case 24:	/* mov $ucon,,r ==> lu r */
9873e12c5d1SDavid du Colombier 		v = regoff(&p->from);
988219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9893e12c5d1SDavid du Colombier 		break;
9903e12c5d1SDavid du Colombier 
9913e12c5d1SDavid du Colombier 	case 25:	/* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */
9923e12c5d1SDavid du Colombier 		v = regoff(&p->from);
993219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9943e12c5d1SDavid du Colombier 		r = p->reg;
9953e12c5d1SDavid du Colombier 		if(r == NREG)
9963e12c5d1SDavid du Colombier 			r = p->to.reg;
9973e12c5d1SDavid du Colombier 		o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
9983e12c5d1SDavid du Colombier 		break;
9993e12c5d1SDavid du Colombier 
10003e12c5d1SDavid du Colombier 	case 26:	/* mov $lsext/auto/oreg,,r2 ==> lu+or+add */
10013e12c5d1SDavid du Colombier 		v = regoff(&p->from);
10023e12c5d1SDavid du Colombier 		if(p->to.reg == REGTMP)
10036b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
1004219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
10053e12c5d1SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
10063e12c5d1SDavid du Colombier 		r = p->from.reg;
10073e12c5d1SDavid du Colombier 		if(r == NREG)
10083e12c5d1SDavid du Colombier 			r = o->param;
1009219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg);
10103e12c5d1SDavid du Colombier 		break;
10113e12c5d1SDavid du Colombier 
10123e12c5d1SDavid du Colombier 	case 27:		/* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
10133e12c5d1SDavid du Colombier 		r = p->from.reg;
10143e12c5d1SDavid du Colombier 		if(r == NREG)
10153e12c5d1SDavid du Colombier 			r = o->param;
10163e12c5d1SDavid du Colombier 		v = regoff(&p->from);
10173e12c5d1SDavid du Colombier 		switch(o->size) {
1018219b2ee8SDavid du Colombier 		case 20:
1019219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1020219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1021219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1022219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1);
1023219b2ee8SDavid du Colombier 			o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg);
10243e12c5d1SDavid du Colombier 			break;
1025219b2ee8SDavid du Colombier 		case 16:
1026219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1027219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1028219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1029219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg);
10303e12c5d1SDavid du Colombier 			break;
10313e12c5d1SDavid du Colombier 		case 8:
1032219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1);
1033219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg);
10343e12c5d1SDavid du Colombier 			break;
10353e12c5d1SDavid du Colombier 		case 4:
1036219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg);
10373e12c5d1SDavid du Colombier 			break;
10383e12c5d1SDavid du Colombier 		}
10393e12c5d1SDavid du Colombier 		break;
10403e12c5d1SDavid du Colombier 
10413e12c5d1SDavid du Colombier 	case 28:		/* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */
10423e12c5d1SDavid du Colombier 		r = p->to.reg;
10433e12c5d1SDavid du Colombier 		if(r == NREG)
10443e12c5d1SDavid du Colombier 			r = o->param;
10453e12c5d1SDavid du Colombier 		v = regoff(&p->to);
10463e12c5d1SDavid du Colombier 		switch(o->size) {
1047219b2ee8SDavid du Colombier 		case 20:
1048219b2ee8SDavid du Colombier 			if(r == REGTMP)
10496b6b9ac8SDavid du Colombier 				diag("cant synthesize large constant\n%P", p);
1050219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1051219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1052219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1053219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1);
1054219b2ee8SDavid du Colombier 			o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg);
10553e12c5d1SDavid du Colombier 			break;
1056219b2ee8SDavid du Colombier 		case 16:
1057219b2ee8SDavid du Colombier 			if(r == REGTMP)
10586b6b9ac8SDavid du Colombier 				diag("cant synthesize large constant\n%P", p);
1059219b2ee8SDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1060219b2ee8SDavid du Colombier 			o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1061219b2ee8SDavid du Colombier 			o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1062219b2ee8SDavid du Colombier 			o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg);
10633e12c5d1SDavid du Colombier 			break;
10643e12c5d1SDavid du Colombier 		case 8:
10653e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1);
10663e12c5d1SDavid du Colombier 			o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg);
10673e12c5d1SDavid du Colombier 			break;
10683e12c5d1SDavid du Colombier 		case 4:
10693e12c5d1SDavid du Colombier 			o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg);
10703e12c5d1SDavid du Colombier 			break;
10713e12c5d1SDavid du Colombier 		}
10723e12c5d1SDavid du Colombier 		break;
10733e12c5d1SDavid du Colombier 
10743e12c5d1SDavid du Colombier 	case 30:	/* movw r,fr */
1075219b2ee8SDavid du Colombier 		r = SP(2,1)|(4<<21);		/* mtc1 */
1076219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
10773e12c5d1SDavid du Colombier 		break;
10783e12c5d1SDavid du Colombier 
10793e12c5d1SDavid du Colombier 	case 31:	/* movw fr,r */
1080219b2ee8SDavid du Colombier 		r = SP(2,1)|(0<<21);		/* mfc1 */
1081219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
10823e12c5d1SDavid du Colombier 		break;
10833e12c5d1SDavid du Colombier 
10843e12c5d1SDavid du Colombier 	case 32:	/* fadd fr1,[fr2],fr3 */
10853e12c5d1SDavid du Colombier 		r = p->reg;
10863e12c5d1SDavid du Colombier 		if(r == NREG)
10873e12c5d1SDavid du Colombier 			o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg);
10883e12c5d1SDavid du Colombier 		else
10893e12c5d1SDavid du Colombier 			o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg);
10903e12c5d1SDavid du Colombier 		break;
10913e12c5d1SDavid du Colombier 
10923e12c5d1SDavid du Colombier 	case 33:	/* fabs fr1,fr3 */
10933e12c5d1SDavid du Colombier 		o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg);
10943e12c5d1SDavid du Colombier 		break;
10953e12c5d1SDavid du Colombier 
10963e12c5d1SDavid du Colombier 	case 34:	/* mov $con,fr ==> or/add $i,r,r2 */
10973e12c5d1SDavid du Colombier 		v = regoff(&p->from);
1098219b2ee8SDavid du Colombier 		r = AADDU;
10993e12c5d1SDavid du Colombier 		if(o->a1 == C_ANDCON)
11003e12c5d1SDavid du Colombier 			r = AOR;
11013e12c5d1SDavid du Colombier 		o1 = OP_IRR(opirr(r), v, 0, REGTMP);
1102219b2ee8SDavid du Colombier 		o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg);	/* mtc1 */
11033e12c5d1SDavid du Colombier 		break;
11043e12c5d1SDavid du Colombier 
11053e12c5d1SDavid du Colombier 	case 35:	/* mov r,lext/luto/oreg ==> sw o(r) */
1106219b2ee8SDavid du Colombier 		/*
1107219b2ee8SDavid du Colombier 		 * the lowbits of the constant cannot
1108219b2ee8SDavid du Colombier 		 * be moved into the offset of the load
1109219b2ee8SDavid du Colombier 		 * because the mips 4000 in 64-bit mode
1110219b2ee8SDavid du Colombier 		 * does a 64-bit add and it will screw up.
1111219b2ee8SDavid du Colombier 		 */
11123e12c5d1SDavid du Colombier 		v = regoff(&p->to);
11133e12c5d1SDavid du Colombier 		r = p->to.reg;
11143e12c5d1SDavid du Colombier 		if(r == NREG)
11153e12c5d1SDavid du Colombier 			r = o->param;
1116219b2ee8SDavid du Colombier 		if(r == REGTMP)
11176b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
1118219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1119219b2ee8SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1120219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1121219b2ee8SDavid du Colombier 		o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg);
11223e12c5d1SDavid du Colombier 		break;
11233e12c5d1SDavid du Colombier 
11243e12c5d1SDavid du Colombier 	case 36:	/* mov lext/lauto/lreg,r ==> lw o(r30) */
11253e12c5d1SDavid du Colombier 		v = regoff(&p->from);
11263e12c5d1SDavid du Colombier 		r = p->from.reg;
11273e12c5d1SDavid du Colombier 		if(r == NREG)
11283e12c5d1SDavid du Colombier 			r = o->param;
1129219b2ee8SDavid du Colombier 		if(r == REGTMP)
11306b6b9ac8SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
1131219b2ee8SDavid du Colombier 		o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1132219b2ee8SDavid du Colombier 		o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1133219b2ee8SDavid du Colombier 		o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1134219b2ee8SDavid du Colombier 		o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg);
11353e12c5d1SDavid du Colombier 		break;
11363e12c5d1SDavid du Colombier 
11373e12c5d1SDavid du Colombier 	case 37:	/* movw r,mr */
1138219b2ee8SDavid du Colombier 		r = SP(2,0)|(4<<21);		/* mtc0 */
1139219b2ee8SDavid du Colombier 		if(p->as == AMOVV)
1140219b2ee8SDavid du Colombier 			r = SP(2,0)|(5<<21);	/* dmtc0 */
1141219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
11423e12c5d1SDavid du Colombier 		break;
11433e12c5d1SDavid du Colombier 
11443e12c5d1SDavid du Colombier 	case 38:	/* movw mr,r */
1145219b2ee8SDavid du Colombier 		r = SP(2,0)|(0<<21);		/* mfc0 */
1146219b2ee8SDavid du Colombier 		if(p->as == AMOVV)
1147219b2ee8SDavid du Colombier 			r = SP(2,0)|(1<<21);	/* dmfc0 */
1148219b2ee8SDavid du Colombier 		o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
11493e12c5d1SDavid du Colombier 		break;
11503e12c5d1SDavid du Colombier 
11513e12c5d1SDavid du Colombier 	case 39:	/* rfe ==> jmp+rfe */
11523e12c5d1SDavid du Colombier 		if(aflag)
11533e12c5d1SDavid du Colombier 			return 0;
11543e12c5d1SDavid du Colombier 		o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO);
11553e12c5d1SDavid du Colombier 		o2 = oprrr(p->as);
11563e12c5d1SDavid du Colombier 		break;
11573e12c5d1SDavid du Colombier 
11583e12c5d1SDavid du Colombier 	case 40:	/* word */
11593e12c5d1SDavid du Colombier 		if(aflag)
11603e12c5d1SDavid du Colombier 			return 0;
11613e12c5d1SDavid du Colombier 		o1 = regoff(&p->to);
11623e12c5d1SDavid du Colombier 		break;
11633e12c5d1SDavid du Colombier 
11643e12c5d1SDavid du Colombier 	case 41:	/* movw r,fcr */
1165219b2ee8SDavid du Colombier 		o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); 	/* mfcc1 */
1166219b2ee8SDavid du Colombier 		o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */
11673e12c5d1SDavid du Colombier 		break;
11683e12c5d1SDavid du Colombier 
11693e12c5d1SDavid du Colombier 	case 42:	/* movw fcr,r */
1170219b2ee8SDavid du Colombier 		o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */
11713e12c5d1SDavid du Colombier 		break;
11727dd7cddfSDavid du Colombier 
11737dd7cddfSDavid du Colombier 	case 45:	/* case r */
11747dd7cddfSDavid du Colombier 		if(p->link == P)
11757dd7cddfSDavid du Colombier 			v = p->pc+28;
11767dd7cddfSDavid du Colombier 		else
11777dd7cddfSDavid du Colombier 			v = p->link->pc;
11787dd7cddfSDavid du Colombier 		if(v & (1<<15))
11797dd7cddfSDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP);
11807dd7cddfSDavid du Colombier 		else
11817dd7cddfSDavid du Colombier 			o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
11827dd7cddfSDavid du Colombier 		o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg);
11837dd7cddfSDavid du Colombier 		o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP);
11847dd7cddfSDavid du Colombier 		o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP);
11857dd7cddfSDavid du Colombier 		o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
11867dd7cddfSDavid du Colombier 		o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO);
11877dd7cddfSDavid du Colombier 		o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
11887dd7cddfSDavid du Colombier 		break;
11897dd7cddfSDavid du Colombier 
11907dd7cddfSDavid du Colombier 	case 46:	/* bcase $con,lbra */
11917dd7cddfSDavid du Colombier 		if(p->cond == P)
11927dd7cddfSDavid du Colombier 			v = p->pc;
11937dd7cddfSDavid du Colombier 		else
11947dd7cddfSDavid du Colombier 			v = p->cond->pc;
11957dd7cddfSDavid du Colombier 		o1 = v;
11967dd7cddfSDavid du Colombier 		break;
11973e12c5d1SDavid du Colombier 	}
11983e12c5d1SDavid du Colombier 	if(aflag)
11993e12c5d1SDavid du Colombier 		return o1;
12003e12c5d1SDavid du Colombier 	v = p->pc;
12013e12c5d1SDavid du Colombier 	switch(o->size) {
12023e12c5d1SDavid du Colombier 	default:
12033e12c5d1SDavid du Colombier 		if(debug['a'])
12043e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
12053e12c5d1SDavid du Colombier 		break;
12063e12c5d1SDavid du Colombier 	case 4:
12073e12c5d1SDavid du Colombier 		if(debug['a'])
12083e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
12093e12c5d1SDavid du Colombier 		LPUT(o1);
12103e12c5d1SDavid du Colombier 		break;
12113e12c5d1SDavid du Colombier 	case 8:
12123e12c5d1SDavid du Colombier 		if(debug['a'])
12133e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
12143e12c5d1SDavid du Colombier 		LPUT(o1);
12153e12c5d1SDavid du Colombier 		LPUT(o2);
12163e12c5d1SDavid du Colombier 		break;
12173e12c5d1SDavid du Colombier 	case 12:
12183e12c5d1SDavid du Colombier 		if(debug['a'])
12193e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
12203e12c5d1SDavid du Colombier 		LPUT(o1);
12213e12c5d1SDavid du Colombier 		LPUT(o2);
12223e12c5d1SDavid du Colombier 		LPUT(o3);
12233e12c5d1SDavid du Colombier 		break;
12243e12c5d1SDavid du Colombier 	case 16:
12253e12c5d1SDavid du Colombier 		if(debug['a'])
12263e12c5d1SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
12273e12c5d1SDavid du Colombier 				v, o1, o2, o3, o4, p);
12283e12c5d1SDavid du Colombier 		LPUT(o1);
12293e12c5d1SDavid du Colombier 		LPUT(o2);
12303e12c5d1SDavid du Colombier 		LPUT(o3);
12313e12c5d1SDavid du Colombier 		LPUT(o4);
12323e12c5d1SDavid du Colombier 		break;
1233219b2ee8SDavid du Colombier 	case 20:
1234219b2ee8SDavid du Colombier 		if(debug['a'])
1235219b2ee8SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
1236219b2ee8SDavid du Colombier 				v, o1, o2, o3, o4, o5, p);
1237219b2ee8SDavid du Colombier 		LPUT(o1);
1238219b2ee8SDavid du Colombier 		LPUT(o2);
1239219b2ee8SDavid du Colombier 		LPUT(o3);
1240219b2ee8SDavid du Colombier 		LPUT(o4);
1241219b2ee8SDavid du Colombier 		LPUT(o5);
1242219b2ee8SDavid du Colombier 		break;
12437dd7cddfSDavid du Colombier 
12447dd7cddfSDavid du Colombier 	case 28:
12457dd7cddfSDavid du Colombier 		if(debug['a'])
12467dd7cddfSDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
12477dd7cddfSDavid du Colombier 				v, o1, o2, o3, o4, o5, o6, o7, p);
12487dd7cddfSDavid du Colombier 		LPUT(o1);
12497dd7cddfSDavid du Colombier 		LPUT(o2);
12507dd7cddfSDavid du Colombier 		LPUT(o3);
12517dd7cddfSDavid du Colombier 		LPUT(o4);
12527dd7cddfSDavid du Colombier 		LPUT(o5);
12537dd7cddfSDavid du Colombier 		LPUT(o6);
12547dd7cddfSDavid du Colombier 		LPUT(o7);
12557dd7cddfSDavid du Colombier 		break;
12563e12c5d1SDavid du Colombier 	}
12573e12c5d1SDavid du Colombier 	return 0;
12583e12c5d1SDavid du Colombier }
12593e12c5d1SDavid du Colombier 
1260219b2ee8SDavid du Colombier int
isnop(Prog * p)1261219b2ee8SDavid du Colombier isnop(Prog *p)
1262219b2ee8SDavid du Colombier {
1263219b2ee8SDavid du Colombier 	if(p->as != ANOR)
1264219b2ee8SDavid du Colombier 		return 0;
1265219b2ee8SDavid du Colombier 	if(p->reg != REGZERO && p->reg != NREG)
1266219b2ee8SDavid du Colombier 		return 0;
1267219b2ee8SDavid du Colombier 	if(p->from.type != D_REG || p->from.reg != REGZERO)
1268219b2ee8SDavid du Colombier 		return 0;
1269219b2ee8SDavid du Colombier 	if(p->to.type != D_REG || p->to.reg != REGZERO)
1270219b2ee8SDavid du Colombier 		return 0;
1271219b2ee8SDavid du Colombier 	return 1;
1272219b2ee8SDavid du Colombier }
12733e12c5d1SDavid du Colombier 
12743e12c5d1SDavid du Colombier long
oprrr(int a)12753e12c5d1SDavid du Colombier oprrr(int a)
12763e12c5d1SDavid du Colombier {
12773e12c5d1SDavid du Colombier 	switch(a) {
12783e12c5d1SDavid du Colombier 	case AADD:	return OP(4,0);
12793e12c5d1SDavid du Colombier 	case AADDU:	return OP(4,1);
12803e12c5d1SDavid du Colombier 	case ASGT:	return OP(5,2);
12813e12c5d1SDavid du Colombier 	case ASGTU:	return OP(5,3);
12823e12c5d1SDavid du Colombier 	case AAND:	return OP(4,4);
12833e12c5d1SDavid du Colombier 	case AOR:	return OP(4,5);
12843e12c5d1SDavid du Colombier 	case AXOR:	return OP(4,6);
12853e12c5d1SDavid du Colombier 	case ASUB:	return OP(4,2);
12863e12c5d1SDavid du Colombier 	case ASUBU:	return OP(4,3);
12873e12c5d1SDavid du Colombier 	case ANOR:	return OP(4,7);
12883e12c5d1SDavid du Colombier 	case ASLL:	return OP(0,4);
12893e12c5d1SDavid du Colombier 	case ASRL:	return OP(0,6);
12903e12c5d1SDavid du Colombier 	case ASRA:	return OP(0,7);
12913e12c5d1SDavid du Colombier 
12923e12c5d1SDavid du Colombier 	case AREM:
12933e12c5d1SDavid du Colombier 	case ADIV:	return OP(3,2);
12943e12c5d1SDavid du Colombier 	case AREMU:
12953e12c5d1SDavid du Colombier 	case ADIVU:	return OP(3,3);
12963e12c5d1SDavid du Colombier 	case AMUL:	return OP(3,0);
12973e12c5d1SDavid du Colombier 	case AMULU:	return OP(3,1);
12983e12c5d1SDavid du Colombier 
12993e12c5d1SDavid du Colombier 	case AJMP:	return OP(1,0);
13003e12c5d1SDavid du Colombier 	case AJAL:	return OP(1,1);
13013e12c5d1SDavid du Colombier 
13023e12c5d1SDavid du Colombier 	case ABREAK:	return OP(1,5);
13033e12c5d1SDavid du Colombier 	case ASYSCALL:	return OP(1,4);
13043e12c5d1SDavid du Colombier 	case ATLBP:	return MMU(1,0);
13053e12c5d1SDavid du Colombier 	case ATLBR:	return MMU(0,1);
13063e12c5d1SDavid du Colombier 	case ATLBWI:	return MMU(0,2);
13073e12c5d1SDavid du Colombier 	case ATLBWR:	return MMU(0,6);
13083e12c5d1SDavid du Colombier 	case ARFE:	return MMU(2,0);
13093e12c5d1SDavid du Colombier 
13103e12c5d1SDavid du Colombier 	case ADIVF:	return FPF(0,3);
13113e12c5d1SDavid du Colombier 	case ADIVD:	return FPD(0,3);
13123e12c5d1SDavid du Colombier 	case AMULF:	return FPF(0,2);
13133e12c5d1SDavid du Colombier 	case AMULD:	return FPD(0,2);
13143e12c5d1SDavid du Colombier 	case ASUBF:	return FPF(0,1);
13153e12c5d1SDavid du Colombier 	case ASUBD:	return FPD(0,1);
13163e12c5d1SDavid du Colombier 	case AADDF:	return FPF(0,0);
13173e12c5d1SDavid du Colombier 	case AADDD:	return FPD(0,0);
13183e12c5d1SDavid du Colombier 
13193e12c5d1SDavid du Colombier 	case AMOVFW:	return FPF(4,4);
13203e12c5d1SDavid du Colombier 	case AMOVDW:	return FPD(4,4);
13213e12c5d1SDavid du Colombier 	case AMOVWF:	return FPW(4,0);
13223e12c5d1SDavid du Colombier 	case AMOVDF:	return FPD(4,0);
13233e12c5d1SDavid du Colombier 	case AMOVWD:	return FPW(4,1);
13243e12c5d1SDavid du Colombier 	case AMOVFD:	return FPF(4,1);
13253e12c5d1SDavid du Colombier 	case AABSF:	return FPF(0,5);
13263e12c5d1SDavid du Colombier 	case AABSD:	return FPD(0,5);
13273e12c5d1SDavid du Colombier 	case AMOVF:	return FPF(0,6);
13283e12c5d1SDavid du Colombier 	case AMOVD:	return FPD(0,6);
13293e12c5d1SDavid du Colombier 	case ANEGF:	return FPF(0,7);
13303e12c5d1SDavid du Colombier 	case ANEGD:	return FPD(0,7);
13313e12c5d1SDavid du Colombier 
13323e12c5d1SDavid du Colombier 	case ACMPEQF:	return FPF(6,2);
13333e12c5d1SDavid du Colombier 	case ACMPEQD:	return FPD(6,2);
13343e12c5d1SDavid du Colombier 	case ACMPGTF:	return FPF(7,4);
13353e12c5d1SDavid du Colombier 	case ACMPGTD:	return FPD(7,4);
13363e12c5d1SDavid du Colombier 	case ACMPGEF:	return FPF(7,6);
13373e12c5d1SDavid du Colombier 	case ACMPGED:	return FPD(7,6);
13387dd7cddfSDavid du Colombier 
13397dd7cddfSDavid du Colombier 	case ADIVV:	return OP(3,6);
13407dd7cddfSDavid du Colombier 	case ADIVVU:	return OP(3,7);
13417dd7cddfSDavid du Colombier 	case AADDV:	return OP(5,4);
13427dd7cddfSDavid du Colombier 	case AADDVU:	return OP(5,5);
13433e12c5d1SDavid du Colombier 	}
13446b6b9ac8SDavid du Colombier 	diag("bad rrr %d", a);
13453e12c5d1SDavid du Colombier 	return 0;
13463e12c5d1SDavid du Colombier }
13473e12c5d1SDavid du Colombier 
13483e12c5d1SDavid du Colombier long
opirr(int a)13493e12c5d1SDavid du Colombier opirr(int a)
13503e12c5d1SDavid du Colombier {
13513e12c5d1SDavid du Colombier 	switch(a) {
13523e12c5d1SDavid du Colombier 	case AADD:	return SP(1,0);
13533e12c5d1SDavid du Colombier 	case AADDU:	return SP(1,1);
13543e12c5d1SDavid du Colombier 	case ASGT:	return SP(1,2);
13553e12c5d1SDavid du Colombier 	case ASGTU:	return SP(1,3);
13563e12c5d1SDavid du Colombier 	case AAND:	return SP(1,4);
13573e12c5d1SDavid du Colombier 	case AOR:	return SP(1,5);
13583e12c5d1SDavid du Colombier 	case AXOR:	return SP(1,6);
1359219b2ee8SDavid du Colombier 	case ALAST:	return SP(1,7);
13603e12c5d1SDavid du Colombier 	case ASLL:	return OP(0,0);
13613e12c5d1SDavid du Colombier 	case ASRL:	return OP(0,2);
13623e12c5d1SDavid du Colombier 	case ASRA:	return OP(0,3);
13633e12c5d1SDavid du Colombier 
13643e12c5d1SDavid du Colombier 	case AJMP:	return SP(0,2);
13653e12c5d1SDavid du Colombier 	case AJAL:	return SP(0,3);
13663e12c5d1SDavid du Colombier 	case ABEQ:	return SP(0,4);
13673e12c5d1SDavid du Colombier 	case ABNE:	return SP(0,5);
13683e12c5d1SDavid du Colombier 
13693e12c5d1SDavid du Colombier 	case ABGEZ:	return SP(0,1)|BCOND(0,1);
13703e12c5d1SDavid du Colombier 	case ABGEZAL:	return SP(0,1)|BCOND(2,1);
13713e12c5d1SDavid du Colombier 	case ABGTZ:	return SP(0,7);
13723e12c5d1SDavid du Colombier 	case ABLEZ:	return SP(0,6);
13733e12c5d1SDavid du Colombier 	case ABLTZ:	return SP(0,1)|BCOND(0,0);
13743e12c5d1SDavid du Colombier 	case ABLTZAL:	return SP(0,1)|BCOND(2,0);
13753e12c5d1SDavid du Colombier 
13763e12c5d1SDavid du Colombier 	case ABFPT:	return SP(2,1)|(257<<16);
13773e12c5d1SDavid du Colombier 	case ABFPF:	return SP(2,1)|(256<<16);
13783e12c5d1SDavid du Colombier 
13793e12c5d1SDavid du Colombier 	case AMOVB:
13803e12c5d1SDavid du Colombier 	case AMOVBU:	return SP(5,0);
13813e12c5d1SDavid du Colombier 	case AMOVH:
13823e12c5d1SDavid du Colombier 	case AMOVHU:	return SP(5,1);
13833e12c5d1SDavid du Colombier 	case AMOVW:	return SP(5,3);
1384219b2ee8SDavid du Colombier 	case AMOVV:	return SP(7,7);
13853e12c5d1SDavid du Colombier 	case AMOVF:	return SP(7,1);
13863e12c5d1SDavid du Colombier 	case AMOVWL:	return SP(5,2);
13873e12c5d1SDavid du Colombier 	case AMOVWR:	return SP(5,6);
1388219b2ee8SDavid du Colombier 	case AMOVVL:	return SP(5,4);
1389219b2ee8SDavid du Colombier 	case AMOVVR:	return SP(5,5);
13903e12c5d1SDavid du Colombier 
1391bd389b36SDavid du Colombier 	case ABREAK:	return SP(5,7);
1392bd389b36SDavid du Colombier 
1393219b2ee8SDavid du Colombier 	case AMOVWL+ALAST:	return SP(4,2);
1394219b2ee8SDavid du Colombier 	case AMOVWR+ALAST:	return SP(4,6);
1395219b2ee8SDavid du Colombier 	case AMOVVL+ALAST:	return SP(3,2);
1396219b2ee8SDavid du Colombier 	case AMOVVR+ALAST:	return SP(3,3);
1397219b2ee8SDavid du Colombier 	case AMOVB+ALAST:	return SP(4,0);
1398219b2ee8SDavid du Colombier 	case AMOVBU+ALAST:	return SP(4,4);
1399219b2ee8SDavid du Colombier 	case AMOVH+ALAST:	return SP(4,1);
1400219b2ee8SDavid du Colombier 	case AMOVHU+ALAST:	return SP(4,5);
1401219b2ee8SDavid du Colombier 	case AMOVW+ALAST:	return SP(4,3);
1402219b2ee8SDavid du Colombier 	case AMOVV+ALAST:	return SP(6,7);
1403219b2ee8SDavid du Colombier 	case AMOVF+ALAST:	return SP(6,1);
14043e12c5d1SDavid du Colombier 
1405219b2ee8SDavid du Colombier 	case ASLLV:		return OP(7,0);
1406219b2ee8SDavid du Colombier 	case ASRLV:		return OP(7,2);
1407219b2ee8SDavid du Colombier 	case ASRAV:		return OP(7,3);
1408219b2ee8SDavid du Colombier 	case ASLLV+ALAST:	return OP(7,4);
1409219b2ee8SDavid du Colombier 	case ASRLV+ALAST:	return OP(7,6);
1410219b2ee8SDavid du Colombier 	case ASRAV+ALAST:	return OP(7,7);
14117dd7cddfSDavid du Colombier 
14127dd7cddfSDavid du Colombier 	case AADDV:		return SP(3,0);
14137dd7cddfSDavid du Colombier 	case AADDVU:		return SP(3,1);
14143e12c5d1SDavid du Colombier 	}
14156b6b9ac8SDavid du Colombier 	diag("bad irr %d", a);
1416dc5a79c1SDavid du Colombier abort();
1417dc5a79c1SDavid du Colombier 	return 0;
1418dc5a79c1SDavid du Colombier }
1419dc5a79c1SDavid du Colombier 
1420dc5a79c1SDavid du Colombier int
vshift(int a)1421dc5a79c1SDavid du Colombier vshift(int a)
1422dc5a79c1SDavid du Colombier {
1423dc5a79c1SDavid du Colombier 	switch(a){
1424dc5a79c1SDavid du Colombier 	case ASLLV:		return 1;
1425dc5a79c1SDavid du Colombier 	case ASRLV:		return 1;
1426dc5a79c1SDavid du Colombier 	case ASRAV:		return 1;
1427dc5a79c1SDavid du Colombier 	}
14283e12c5d1SDavid du Colombier 	return 0;
14293e12c5d1SDavid du Colombier }
1430