xref: /plan9/sys/src/cmd/vi/run.c (revision 0cc39a83e201996cab5ee319ea497ce6109e8d23)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <mach.h>
53e12c5d1SDavid du Colombier #define Extern extern
63e12c5d1SDavid du Colombier #include "mips.h"
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier void	Iaddi(ulong);
93e12c5d1SDavid du Colombier void	Isw(ulong);
103e12c5d1SDavid du Colombier void	Ilui(ulong);
113e12c5d1SDavid du Colombier void	Iori(ulong);
123e12c5d1SDavid du Colombier void	Ixori(ulong);
133e12c5d1SDavid du Colombier void	Ilw(ulong);
143e12c5d1SDavid du Colombier void	Ijal(ulong);
153e12c5d1SDavid du Colombier void	Ispecial(ulong);
163e12c5d1SDavid du Colombier void	Ibeq(ulong);
177dd7cddfSDavid du Colombier void	Ibeql(ulong);
183e12c5d1SDavid du Colombier void	Iaddiu(ulong);
193e12c5d1SDavid du Colombier void	Ilb(ulong);
203e12c5d1SDavid du Colombier void	Iandi(ulong);
213e12c5d1SDavid du Colombier void	Ij(ulong);
223e12c5d1SDavid du Colombier void	Ibne(ulong);
237dd7cddfSDavid du Colombier void	Ibnel(ulong);
243e12c5d1SDavid du Colombier void	Isb(ulong);
253e12c5d1SDavid du Colombier void	Islti(ulong);
263e12c5d1SDavid du Colombier void	Ibcond(ulong);
273e12c5d1SDavid du Colombier void	Ibgtz(ulong);
287dd7cddfSDavid du Colombier void	Ibgtzl(ulong);
293e12c5d1SDavid du Colombier void	Ilbu(ulong);
303e12c5d1SDavid du Colombier void	Ilhu(ulong);
313e12c5d1SDavid du Colombier void	Ish(ulong);
323e12c5d1SDavid du Colombier void	Ilh(ulong);
333e12c5d1SDavid du Colombier void	Iblez(ulong);
347dd7cddfSDavid du Colombier void	Iblezl(ulong);
353e12c5d1SDavid du Colombier void	Isltiu(ulong);
363e12c5d1SDavid du Colombier void	Iswc1(ulong);
373e12c5d1SDavid du Colombier void	Ilwc1(ulong);
383e12c5d1SDavid du Colombier void	Icop1(ulong);
397dd7cddfSDavid du Colombier void	Ilwl(ulong);
407dd7cddfSDavid du Colombier void	Ilwr(ulong);
419a747e4fSDavid du Colombier void	Ill(ulong);
429a747e4fSDavid du Colombier void	Isc(ulong);
433e12c5d1SDavid du Colombier 
443e12c5d1SDavid du Colombier Inst itab[] = {
453e12c5d1SDavid du Colombier 	{ Ispecial,	0 },
463e12c5d1SDavid du Colombier 	{ Ibcond,	"bcond",	Ibranch },
473e12c5d1SDavid du Colombier 	{ Ij,		"j",		Ibranch },
483e12c5d1SDavid du Colombier 	{ Ijal,		"jal",		Ibranch },
493e12c5d1SDavid du Colombier 	{ Ibeq,		"beq",		Ibranch },
503e12c5d1SDavid du Colombier 	{ Ibne,		"bne",		Ibranch },
513e12c5d1SDavid du Colombier 	{ Iblez,	"blez",		Ibranch },
523e12c5d1SDavid du Colombier 	{ Ibgtz,	"bgtz",		Ibranch },
533e12c5d1SDavid du Colombier 	{ Iaddi,	"addi",		Iarith },	/* 8 */
543e12c5d1SDavid du Colombier 	{ Iaddiu,	"addiu",	Iarith },
553e12c5d1SDavid du Colombier 	{ Islti,	"slti",		Iarith },
563e12c5d1SDavid du Colombier 	{ Isltiu,	"sltiu",	Iarith },
573e12c5d1SDavid du Colombier 	{ Iandi,	"andi",		Iarith },
583e12c5d1SDavid du Colombier 	{ Iori,		"ori",		Iarith },
593e12c5d1SDavid du Colombier 	{ Ixori,	"xori",		Iarith },
603e12c5d1SDavid du Colombier 	{ Ilui,		"lui",		Iload },	/* 15 */
613e12c5d1SDavid du Colombier 	{ undef,	"" },
623e12c5d1SDavid du Colombier 	{ Icop1,	"cop1",		Ifloat },
633e12c5d1SDavid du Colombier 	{ undef,	"" },
643e12c5d1SDavid du Colombier 	{ undef,	"" },
657dd7cddfSDavid du Colombier 	{ Ibeql,	"beql" },
667dd7cddfSDavid du Colombier 	{ Ibnel,	"bnel" },
677dd7cddfSDavid du Colombier 	{ Iblezl,	"blezl" },
687dd7cddfSDavid du Colombier 	{ Ibgtzl,	"bgtzl" },
693e12c5d1SDavid du Colombier 	{ undef,	"" },
703e12c5d1SDavid du Colombier 	{ undef,	"" },
713e12c5d1SDavid du Colombier 	{ undef,	"" },
723e12c5d1SDavid du Colombier 	{ undef,	"" },
733e12c5d1SDavid du Colombier 	{ undef,	"" },
743e12c5d1SDavid du Colombier 	{ undef,	"" },
753e12c5d1SDavid du Colombier 	{ undef,	"" },
763e12c5d1SDavid du Colombier 	{ undef,	"" },
773e12c5d1SDavid du Colombier 	{ Ilb,		"lb",		Iload },
783e12c5d1SDavid du Colombier 	{ Ilh,		"lh",		Iload },
797dd7cddfSDavid du Colombier 	{ Ilwl,		"lwl", 		Iload },
803e12c5d1SDavid du Colombier 	{ Ilw,		"lw",		Iload },
813e12c5d1SDavid du Colombier 	{ Ilbu,		"lbu",		Iload },
823e12c5d1SDavid du Colombier 	{ Ilhu,		"lhu",		Iload },
837dd7cddfSDavid du Colombier 	{ Ilwr,		"lwr",		Iload },
843e12c5d1SDavid du Colombier 	{ undef,	"" },
853e12c5d1SDavid du Colombier 	{ Isb,		"sb",		Istore },
863e12c5d1SDavid du Colombier 	{ Ish,		"sh",		Istore },
873e12c5d1SDavid du Colombier 	{ undef,	"" },
883e12c5d1SDavid du Colombier 	{ Isw,		"sw",		Istore },	/* 43 */
893e12c5d1SDavid du Colombier 	{ undef,	"" },
903e12c5d1SDavid du Colombier 	{ undef,	"" },
913e12c5d1SDavid du Colombier 	{ undef,	"" },
923e12c5d1SDavid du Colombier 	{ undef,	"" },
939a747e4fSDavid du Colombier 	{ Ill,			"ll",			Iload},
943e12c5d1SDavid du Colombier 	{ Ilwc1,		"lwc1",		Ifloat },
953e12c5d1SDavid du Colombier 	{ undef,	"" },
963e12c5d1SDavid du Colombier 	{ undef,	"" },
973e12c5d1SDavid du Colombier 	{ undef,	"" },
983e12c5d1SDavid du Colombier 	{ undef,	"" },
993e12c5d1SDavid du Colombier 	{ undef,	"" },
1003e12c5d1SDavid du Colombier 	{ undef,	"" },
1019a747e4fSDavid du Colombier 	{ Isc,		"sc",		Istore },
1023e12c5d1SDavid du Colombier 	{ Iswc1,	"swc1",		Ifloat },
1033e12c5d1SDavid du Colombier 	{ undef,	"" },
1043e12c5d1SDavid du Colombier 	{ undef,	"" },
1053e12c5d1SDavid du Colombier 	{ undef,	"" },
1063e12c5d1SDavid du Colombier 	{ undef,	"" },
1073e12c5d1SDavid du Colombier 	{ undef,	"" },
1083e12c5d1SDavid du Colombier 	{ undef,	"" },
1093e12c5d1SDavid du Colombier 	{ 0 }
1103e12c5d1SDavid du Colombier };
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier void
dortrace(void)1137dd7cddfSDavid du Colombier dortrace(void)
1147dd7cddfSDavid du Colombier {
1157dd7cddfSDavid du Colombier 	int i;
1167dd7cddfSDavid du Colombier 
1177dd7cddfSDavid du Colombier 	for(i = 0; i < 32; i++)
1187dd7cddfSDavid du Colombier 		if(rtrace & (1<<i))
1197dd7cddfSDavid du Colombier 			Bprint(bioout, "R%.2d %.8lux\n", i, reg.r[i]);
1207dd7cddfSDavid du Colombier }
1217dd7cddfSDavid du Colombier 
1227dd7cddfSDavid du Colombier void
run(void)1233e12c5d1SDavid du Colombier run(void)
1243e12c5d1SDavid du Colombier {
1253e12c5d1SDavid du Colombier 	do {
1263e12c5d1SDavid du Colombier 		reg.r[0] = 0;
1273e12c5d1SDavid du Colombier 		reg.ir = ifetch(reg.pc);
1283e12c5d1SDavid du Colombier 		Iexec(reg.ir);
1293e12c5d1SDavid du Colombier 		reg.pc += 4;
1303e12c5d1SDavid du Colombier 		if(bplist)
1313e12c5d1SDavid du Colombier 			brkchk(reg.pc, Instruction);
1327dd7cddfSDavid du Colombier 		if(rtrace)
1337dd7cddfSDavid du Colombier 			dortrace();
1347dd7cddfSDavid du Colombier Bflush(bioout);
1353e12c5d1SDavid du Colombier 	}while(--count);
1363e12c5d1SDavid du Colombier }
1373e12c5d1SDavid du Colombier 
1383e12c5d1SDavid du Colombier void
undef(ulong inst)1393e12c5d1SDavid du Colombier undef(ulong inst)
1403e12c5d1SDavid du Colombier {
1419a747e4fSDavid du Colombier 
1423e12c5d1SDavid du Colombier /*
1433e12c5d1SDavid du Colombier 	if((reg.ir>>26) == 0)
1443e12c5d1SDavid du Colombier 		Bprint(bioout, "special=%d,%d table=%d\n",
1453e12c5d1SDavid du Colombier 		(reg.ir>>3)&0x7, reg.ir&0x7, reg.ir&0x3f);
1463e12c5d1SDavid du Colombier 	else
1473e12c5d1SDavid du Colombier 		Bprint(bioout, "code=%d,%d table=%d\n",
1483e12c5d1SDavid du Colombier 		reg.ir>>29, (reg.ir>>26)&0x7, reg.ir>>26);
1493e12c5d1SDavid du Colombier */
1509a747e4fSDavid du Colombier 
1513e12c5d1SDavid du Colombier 	Bprint(bioout, "Undefined Instruction Trap IR %.8lux\n", inst);
1523e12c5d1SDavid du Colombier 	longjmp(errjmp, 0);
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier 
1553e12c5d1SDavid du Colombier void
Iaddi(ulong inst)1563e12c5d1SDavid du Colombier Iaddi(ulong inst)
1573e12c5d1SDavid du Colombier {
1583e12c5d1SDavid du Colombier 	int rs, rt;
1593e12c5d1SDavid du Colombier 	int imm;
1603e12c5d1SDavid du Colombier 
1613e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
1623e12c5d1SDavid du Colombier 	imm = (short)(inst&0xffff);
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 	if(trace)
1653e12c5d1SDavid du Colombier 		itrace("addi\tr%d,r%d,#0x%x", rt, rs, imm);
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier 	reg.r[rt] = reg.r[rs] + imm;
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier 
1703e12c5d1SDavid du Colombier void
Iandi(ulong inst)1713e12c5d1SDavid du Colombier Iandi(ulong inst)
1723e12c5d1SDavid du Colombier {
1733e12c5d1SDavid du Colombier 	int rs, rt;
1743e12c5d1SDavid du Colombier 	int imm;
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
1773e12c5d1SDavid du Colombier 	imm = inst&0xffff;
1783e12c5d1SDavid du Colombier 
1793e12c5d1SDavid du Colombier 	if(trace)
1803e12c5d1SDavid du Colombier 		itrace("andi\tr%d,r%d,#0x%x", rt, rs, imm);
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier 	reg.r[rt] = reg.r[rs] & imm;
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier 
1853e12c5d1SDavid du Colombier void
Isw(ulong inst)1863e12c5d1SDavid du Colombier Isw(ulong inst)
1873e12c5d1SDavid du Colombier {
1883e12c5d1SDavid du Colombier 	int rt, rb;
1893e12c5d1SDavid du Colombier 	int off;
1907dd7cddfSDavid du Colombier 	ulong v;
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	Getrbrt(rb, rt, inst);
1933e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
1943e12c5d1SDavid du Colombier 
1957dd7cddfSDavid du Colombier 	v = reg.r[rt];
1963e12c5d1SDavid du Colombier 	if(trace)
1973e12c5d1SDavid du Colombier 		itrace("sw\tr%d,0x%x(r%d) %lux=%lux",
1987dd7cddfSDavid du Colombier 				rt, off, rb, reg.r[rb]+off, v);
1993e12c5d1SDavid du Colombier 
2007dd7cddfSDavid du Colombier 	putmem_w(reg.r[rb]+off, v);
2013e12c5d1SDavid du Colombier }
2023e12c5d1SDavid du Colombier 
2033e12c5d1SDavid du Colombier void
Isb(ulong inst)2043e12c5d1SDavid du Colombier Isb(ulong inst)
2053e12c5d1SDavid du Colombier {
2063e12c5d1SDavid du Colombier 	int rt, rb;
2073e12c5d1SDavid du Colombier 	int off;
2083e12c5d1SDavid du Colombier 	uchar value;
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier 	Getrbrt(rb, rt, inst);
2113e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
2123e12c5d1SDavid du Colombier 
2133e12c5d1SDavid du Colombier 	value = reg.r[rt];
2143e12c5d1SDavid du Colombier 	if(trace)
2153e12c5d1SDavid du Colombier 		itrace("sb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, reg.r[rb]+off, value);
2163e12c5d1SDavid du Colombier 
2173e12c5d1SDavid du Colombier 	putmem_b(reg.r[rb]+off, value);
2183e12c5d1SDavid du Colombier }
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier void
Ish(ulong inst)2213e12c5d1SDavid du Colombier Ish(ulong inst)
2223e12c5d1SDavid du Colombier {
2233e12c5d1SDavid du Colombier 	int rt, rb;
2243e12c5d1SDavid du Colombier 	int off;
2253e12c5d1SDavid du Colombier 	ushort value;
2263e12c5d1SDavid du Colombier 
2273e12c5d1SDavid du Colombier 	Getrbrt(rb, rt, inst);
2283e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
2293e12c5d1SDavid du Colombier 
2303e12c5d1SDavid du Colombier 	value = reg.r[rt];
2313e12c5d1SDavid du Colombier 	if(trace)
2323e12c5d1SDavid du Colombier 		itrace("sh\tr%d,0x%x(r%d) %lux=%lux",
2333e12c5d1SDavid du Colombier 				rt, off, rb, reg.r[rb]+off, value&0xffff);
2343e12c5d1SDavid du Colombier 
2353e12c5d1SDavid du Colombier 	putmem_h(reg.r[rb]+off, value);
2363e12c5d1SDavid du Colombier }
2373e12c5d1SDavid du Colombier 
2383e12c5d1SDavid du Colombier void
Ilui(ulong inst)2393e12c5d1SDavid du Colombier Ilui(ulong inst)
2403e12c5d1SDavid du Colombier {
2413e12c5d1SDavid du Colombier 	int rs, rt;
2423e12c5d1SDavid du Colombier 	int imm;
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
2453e12c5d1SDavid du Colombier 	USED(rs);
2463e12c5d1SDavid du Colombier 	imm = inst<<16;
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier 	if(trace)
2493e12c5d1SDavid du Colombier 		itrace("lui\tr%d,#0x%x", rt, imm);
2503e12c5d1SDavid du Colombier 
2513e12c5d1SDavid du Colombier 	reg.r[rt] = imm;
2523e12c5d1SDavid du Colombier }
2533e12c5d1SDavid du Colombier 
2543e12c5d1SDavid du Colombier void
Iori(ulong inst)2553e12c5d1SDavid du Colombier Iori(ulong inst)
2563e12c5d1SDavid du Colombier {
2573e12c5d1SDavid du Colombier 	int rs, rt;
2583e12c5d1SDavid du Colombier 	int imm;
2593e12c5d1SDavid du Colombier 
2603e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
2613e12c5d1SDavid du Colombier 	imm = inst&0xffff;
2623e12c5d1SDavid du Colombier 
2633e12c5d1SDavid du Colombier 	if(trace)
2643e12c5d1SDavid du Colombier 		itrace("ori\tr%d,r%d,#0x%x", rt, rs, imm);
2653e12c5d1SDavid du Colombier 
2663e12c5d1SDavid du Colombier 	reg.r[rt] = reg.r[rs] | imm;
2673e12c5d1SDavid du Colombier }
2683e12c5d1SDavid du Colombier 
2693e12c5d1SDavid du Colombier void
Ixori(ulong inst)2703e12c5d1SDavid du Colombier Ixori(ulong inst)
2713e12c5d1SDavid du Colombier {
2723e12c5d1SDavid du Colombier 	int rs, rt;
2733e12c5d1SDavid du Colombier 	int imm;
2743e12c5d1SDavid du Colombier 
2753e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
2763e12c5d1SDavid du Colombier 	imm = inst&0xffff;
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier 	if(trace)
2793e12c5d1SDavid du Colombier 		itrace("xori\tr%d,r%d,#0x%x", rt, rs, imm);
2803e12c5d1SDavid du Colombier 
2813e12c5d1SDavid du Colombier 	reg.r[rt] = reg.r[rs] ^ imm;
2823e12c5d1SDavid du Colombier }
2833e12c5d1SDavid du Colombier 
2843e12c5d1SDavid du Colombier void
Ilw(ulong inst)2853e12c5d1SDavid du Colombier Ilw(ulong inst)
2863e12c5d1SDavid du Colombier {
2873e12c5d1SDavid du Colombier 	int rt, rb;
2883e12c5d1SDavid du Colombier 	int off;
2897dd7cddfSDavid du Colombier 	ulong v, va;
2903e12c5d1SDavid du Colombier 
2913e12c5d1SDavid du Colombier 	Getrbrt(rb, rt, inst);
2923e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
2933e12c5d1SDavid du Colombier 
2947dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
2953e12c5d1SDavid du Colombier 
2967dd7cddfSDavid du Colombier 	if(trace) {
2977dd7cddfSDavid du Colombier 		v = 0;
2987dd7cddfSDavid du Colombier 		if(!badvaddr(va, 4))
2997dd7cddfSDavid du Colombier 			v = getmem_w(va);
3007dd7cddfSDavid du Colombier 		itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
3017dd7cddfSDavid du Colombier 	}
3027dd7cddfSDavid du Colombier 
3037dd7cddfSDavid du Colombier 	reg.r[rt] = getmem_w(va);
3047dd7cddfSDavid du Colombier }
3057dd7cddfSDavid du Colombier 
3067dd7cddfSDavid du Colombier void
Ilwl(ulong inst)3077dd7cddfSDavid du Colombier Ilwl(ulong inst)
3087dd7cddfSDavid du Colombier {
3097dd7cddfSDavid du Colombier 	int rt, rb;
3107dd7cddfSDavid du Colombier 	int off;
3117dd7cddfSDavid du Colombier 	ulong v, va;
3127dd7cddfSDavid du Colombier 
3137dd7cddfSDavid du Colombier 	Getrbrt(rb, rt, inst);
3147dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
3157dd7cddfSDavid du Colombier 
3167dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
3177dd7cddfSDavid du Colombier 
3187dd7cddfSDavid du Colombier 	if(trace) {
3197dd7cddfSDavid du Colombier 		v = 0;
3207dd7cddfSDavid du Colombier 		if(!badvaddr(va, 4))
3217dd7cddfSDavid du Colombier 			v = getmem_w(va & ~3) << ((va & 3) << 3);
3227dd7cddfSDavid du Colombier 		itrace("lwl\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
3237dd7cddfSDavid du Colombier 	}
3247dd7cddfSDavid du Colombier 
3257dd7cddfSDavid du Colombier 	v = getmem_w(va & ~3);
3267dd7cddfSDavid du Colombier 	switch(va & 3) {
3277dd7cddfSDavid du Colombier 	case 0:
3287dd7cddfSDavid du Colombier 		reg.r[rt] = v;
3297dd7cddfSDavid du Colombier 		break;
3307dd7cddfSDavid du Colombier 	case 1:
3317dd7cddfSDavid du Colombier 		reg.r[rt] = (v<<8) | (reg.r[rt] & 0xff);
3327dd7cddfSDavid du Colombier 		break;
3337dd7cddfSDavid du Colombier 	case 2:
3347dd7cddfSDavid du Colombier 		reg.r[rt] = (v<<16) | (reg.r[rt] & 0xffff);
3357dd7cddfSDavid du Colombier 		break;
3367dd7cddfSDavid du Colombier 	case 3:
3377dd7cddfSDavid du Colombier 		reg.r[rt] = (v<<24) | (reg.r[rt] & 0xffffff);
3387dd7cddfSDavid du Colombier 		break;
3397dd7cddfSDavid du Colombier 	}
3407dd7cddfSDavid du Colombier }
3417dd7cddfSDavid du Colombier 
3427dd7cddfSDavid du Colombier void
Ilwr(ulong inst)3437dd7cddfSDavid du Colombier Ilwr(ulong inst)
3447dd7cddfSDavid du Colombier {
3457dd7cddfSDavid du Colombier 	int rt, rb;
3467dd7cddfSDavid du Colombier 	int off;
3477dd7cddfSDavid du Colombier 	ulong v, va;
3487dd7cddfSDavid du Colombier 
3497dd7cddfSDavid du Colombier 	Getrbrt(rb, rt, inst);
3507dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
3517dd7cddfSDavid du Colombier 
3527dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
3537dd7cddfSDavid du Colombier 
3547dd7cddfSDavid du Colombier 	if(trace) {
3557dd7cddfSDavid du Colombier 		v = 0;
3567dd7cddfSDavid du Colombier 		if(!badvaddr(va, 4))
3577dd7cddfSDavid du Colombier 			v = getmem_w(va & ~3) << ((va & 3) << 3);
3587dd7cddfSDavid du Colombier 		itrace("lwr\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
3597dd7cddfSDavid du Colombier 	}
3607dd7cddfSDavid du Colombier 
3617dd7cddfSDavid du Colombier 	v = getmem_w(va & ~3);
3627dd7cddfSDavid du Colombier 	switch(va & 3) {
3637dd7cddfSDavid du Colombier 	case 0:
3647dd7cddfSDavid du Colombier 		break;
3657dd7cddfSDavid du Colombier 	case 1:
3667dd7cddfSDavid du Colombier 		reg.r[rt] = (v>>24) | (reg.r[rt] & 0xffffff00);
3677dd7cddfSDavid du Colombier 		break;
3687dd7cddfSDavid du Colombier 	case 2:
3697dd7cddfSDavid du Colombier 		reg.r[rt] = (v>>16) | (reg.r[rt] & 0xffff0000);
3707dd7cddfSDavid du Colombier 		break;
3717dd7cddfSDavid du Colombier 	case 3:
372*0cc39a83SDavid du Colombier 		reg.r[rt] = (v>>8) | (reg.r[rt] & 0xff000000);
3737dd7cddfSDavid du Colombier 		break;
3747dd7cddfSDavid du Colombier 	}
3753e12c5d1SDavid du Colombier }
3763e12c5d1SDavid du Colombier 
3773e12c5d1SDavid du Colombier void
Ilh(ulong inst)3783e12c5d1SDavid du Colombier Ilh(ulong inst)
3793e12c5d1SDavid du Colombier {
3803e12c5d1SDavid du Colombier 	int rt, rb;
3813e12c5d1SDavid du Colombier 	int off;
3827dd7cddfSDavid du Colombier 	ulong v, va;
3833e12c5d1SDavid du Colombier 
3843e12c5d1SDavid du Colombier 	Getrbrt(rb, rt, inst);
3853e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
3863e12c5d1SDavid du Colombier 
3877dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
3883e12c5d1SDavid du Colombier 
3897dd7cddfSDavid du Colombier 	if(trace) {
3907dd7cddfSDavid du Colombier 		v = 0;
3917dd7cddfSDavid du Colombier 		if(!badvaddr(va, 2))
3927dd7cddfSDavid du Colombier 			v = (short)getmem_h(va);
3937dd7cddfSDavid du Colombier 		itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
3947dd7cddfSDavid du Colombier 	}
3957dd7cddfSDavid du Colombier 
3967dd7cddfSDavid du Colombier 	reg.r[rt] = (short)getmem_h(va);
3977dd7cddfSDavid du Colombier }
3987dd7cddfSDavid du Colombier 
3997dd7cddfSDavid du Colombier void
Ilhu(ulong inst)4007dd7cddfSDavid du Colombier Ilhu(ulong inst)
4017dd7cddfSDavid du Colombier {
4027dd7cddfSDavid du Colombier 	int rt, rb;
4037dd7cddfSDavid du Colombier 	int off;
4047dd7cddfSDavid du Colombier 	ulong v, va;
4057dd7cddfSDavid du Colombier 
4067dd7cddfSDavid du Colombier 	Getrbrt(rb, rt, inst);
4077dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
4087dd7cddfSDavid du Colombier 
4097dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
4107dd7cddfSDavid du Colombier 
4117dd7cddfSDavid du Colombier 	if(trace) {
4127dd7cddfSDavid du Colombier 		v = 0;
4137dd7cddfSDavid du Colombier 		if(!badvaddr(va, 2))
4147dd7cddfSDavid du Colombier 			v = getmem_h(va) & 0xffff;
4157dd7cddfSDavid du Colombier 		itrace("lhu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
4167dd7cddfSDavid du Colombier 	}
4177dd7cddfSDavid du Colombier 
4187dd7cddfSDavid du Colombier 	reg.r[rt] = getmem_h(va) & 0xffff;
4197dd7cddfSDavid du Colombier }
4207dd7cddfSDavid du Colombier 
4217dd7cddfSDavid du Colombier void
Ilb(ulong inst)4227dd7cddfSDavid du Colombier Ilb(ulong inst)
4237dd7cddfSDavid du Colombier {
4247dd7cddfSDavid du Colombier 	int rt, rb;
4257dd7cddfSDavid du Colombier 	int off;
4267dd7cddfSDavid du Colombier 	ulong v, va;
4277dd7cddfSDavid du Colombier 
4287dd7cddfSDavid du Colombier 	Getrbrt(rb, rt, inst);
4297dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
4307dd7cddfSDavid du Colombier 
4317dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
4327dd7cddfSDavid du Colombier 
4337dd7cddfSDavid du Colombier 	if(trace) {
4347dd7cddfSDavid du Colombier 		v = 0;
4357dd7cddfSDavid du Colombier 		if(!badvaddr(va, 1))
4367dd7cddfSDavid du Colombier 			v = (schar)getmem_b(va);
4377dd7cddfSDavid du Colombier 		itrace("lb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
4387dd7cddfSDavid du Colombier 	}
4397dd7cddfSDavid du Colombier 
4407dd7cddfSDavid du Colombier 	reg.r[rt] = (schar)getmem_b(va);
4417dd7cddfSDavid du Colombier }
4427dd7cddfSDavid du Colombier 
4437dd7cddfSDavid du Colombier void
Ilbu(ulong inst)4447dd7cddfSDavid du Colombier Ilbu(ulong inst)
4457dd7cddfSDavid du Colombier {
4467dd7cddfSDavid du Colombier 	int rt, rb;
4477dd7cddfSDavid du Colombier 	int off;
4487dd7cddfSDavid du Colombier 	ulong v, va;
4497dd7cddfSDavid du Colombier 
4507dd7cddfSDavid du Colombier 	Getrbrt(rb, rt, inst);
4517dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
4527dd7cddfSDavid du Colombier 
4537dd7cddfSDavid du Colombier 	va = reg.r[rb]+off;
4547dd7cddfSDavid du Colombier 
4557dd7cddfSDavid du Colombier 	if(trace) {
4567dd7cddfSDavid du Colombier 		v = 0;
4577dd7cddfSDavid du Colombier 		if(!badvaddr(va, 1))
4587dd7cddfSDavid du Colombier 			v = getmem_b(va) & 0xff;
4597dd7cddfSDavid du Colombier 		itrace("lbu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
4607dd7cddfSDavid du Colombier 	}
4617dd7cddfSDavid du Colombier 
4627dd7cddfSDavid du Colombier 	reg.r[rt] = getmem_b(va) & 0xff;
4633e12c5d1SDavid du Colombier }
4643e12c5d1SDavid du Colombier 
4653e12c5d1SDavid du Colombier void
Ijal(ulong inst)4663e12c5d1SDavid du Colombier Ijal(ulong inst)
4673e12c5d1SDavid du Colombier {
4683e12c5d1SDavid du Colombier 	ulong npc;
4693e12c5d1SDavid du Colombier 	Symbol s;
4703e12c5d1SDavid du Colombier 
4713e12c5d1SDavid du Colombier 	npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
4723e12c5d1SDavid du Colombier 	if(trace)
4733e12c5d1SDavid du Colombier 		itrace("jal\t0x%lux", npc);
4743e12c5d1SDavid du Colombier 
4753e12c5d1SDavid du Colombier 	reg.r[31] = reg.pc+8;
4763e12c5d1SDavid du Colombier 	/* Do the delay slot */
4773e12c5d1SDavid du Colombier 	reg.ir = ifetch(reg.pc+4);
4783e12c5d1SDavid du Colombier 	Statbra();
4793e12c5d1SDavid du Colombier 	Iexec(reg.ir);
4803e12c5d1SDavid du Colombier 
4813e12c5d1SDavid du Colombier 	if(calltree) {
4823e12c5d1SDavid du Colombier 		findsym(npc, CTEXT, &s);
4833e12c5d1SDavid du Colombier 		Bprint(bioout, "%8lux %s(", reg.pc, s.name);
4843e12c5d1SDavid du Colombier 		printparams(&s, reg.r[29]);
4853e12c5d1SDavid du Colombier 		Bprint(bioout, "from ");
4863e12c5d1SDavid du Colombier 		printsource(reg.pc);
4873e12c5d1SDavid du Colombier 		Bputc(bioout, '\n');
4883e12c5d1SDavid du Colombier 	}
4893e12c5d1SDavid du Colombier 
4903e12c5d1SDavid du Colombier 	reg.pc = npc-4;
4913e12c5d1SDavid du Colombier }
4923e12c5d1SDavid du Colombier 
4933e12c5d1SDavid du Colombier void
Ij(ulong inst)4943e12c5d1SDavid du Colombier Ij(ulong inst)
4953e12c5d1SDavid du Colombier {
4963e12c5d1SDavid du Colombier 	ulong npc;
4973e12c5d1SDavid du Colombier 
4983e12c5d1SDavid du Colombier 	npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
4993e12c5d1SDavid du Colombier 	if(trace)
5003e12c5d1SDavid du Colombier 		itrace("j\t0x%lux", npc);
5013e12c5d1SDavid du Colombier 
5023e12c5d1SDavid du Colombier 	/* Do the delay slot */
5033e12c5d1SDavid du Colombier 	reg.ir = ifetch(reg.pc+4);
5043e12c5d1SDavid du Colombier 	Statbra();
5053e12c5d1SDavid du Colombier 	Iexec(reg.ir);
5063e12c5d1SDavid du Colombier 	reg.pc = npc-4;
5073e12c5d1SDavid du Colombier }
5083e12c5d1SDavid du Colombier 
5093e12c5d1SDavid du Colombier void
Ibeq(ulong inst)5103e12c5d1SDavid du Colombier Ibeq(ulong inst)
5113e12c5d1SDavid du Colombier {
5123e12c5d1SDavid du Colombier 	int rt, rs;
5133e12c5d1SDavid du Colombier 	int off;
5143e12c5d1SDavid du Colombier 	ulong npc;
5153e12c5d1SDavid du Colombier 
5163e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
5173e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
5183e12c5d1SDavid du Colombier 
5193e12c5d1SDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
5203e12c5d1SDavid du Colombier 	if(trace)
5213e12c5d1SDavid du Colombier 		itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
5223e12c5d1SDavid du Colombier 
5233e12c5d1SDavid du Colombier 	if(reg.r[rs] == reg.r[rt]) {
5243e12c5d1SDavid du Colombier 		/* Do the delay slot */
5253e12c5d1SDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
5263e12c5d1SDavid du Colombier 		Statbra();
5273e12c5d1SDavid du Colombier 		Iexec(reg.ir);
5283e12c5d1SDavid du Colombier 		reg.pc = npc-4;
5293e12c5d1SDavid du Colombier 	}
5303e12c5d1SDavid du Colombier }
5313e12c5d1SDavid du Colombier 
5323e12c5d1SDavid du Colombier void
Ibeql(ulong inst)5337dd7cddfSDavid du Colombier Ibeql(ulong inst)
5347dd7cddfSDavid du Colombier {
5357dd7cddfSDavid du Colombier 	int rt, rs;
5367dd7cddfSDavid du Colombier 	int off;
5377dd7cddfSDavid du Colombier 	ulong npc;
5387dd7cddfSDavid du Colombier 
5397dd7cddfSDavid du Colombier 	Getrsrt(rs, rt, inst);
5407dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
5417dd7cddfSDavid du Colombier 
5427dd7cddfSDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
5437dd7cddfSDavid du Colombier 	if(trace)
5447dd7cddfSDavid du Colombier 		itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
5457dd7cddfSDavid du Colombier 
5467dd7cddfSDavid du Colombier 	if(reg.r[rs] == reg.r[rt]) {
5477dd7cddfSDavid du Colombier 		/* Do the delay slot */
5487dd7cddfSDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
5497dd7cddfSDavid du Colombier 		Statbra();
5507dd7cddfSDavid du Colombier 		Iexec(reg.ir);
5517dd7cddfSDavid du Colombier 		reg.pc = npc-4;
5527dd7cddfSDavid du Colombier 	} else
5537dd7cddfSDavid du Colombier 		reg.pc += 4;
5547dd7cddfSDavid du Colombier }
5557dd7cddfSDavid du Colombier 
5567dd7cddfSDavid du Colombier void
Ibgtz(ulong inst)5573e12c5d1SDavid du Colombier Ibgtz(ulong inst)
5583e12c5d1SDavid du Colombier {
5593e12c5d1SDavid du Colombier 	int rs;
5603e12c5d1SDavid du Colombier 	int off;
5613e12c5d1SDavid du Colombier 	ulong npc, r;
5623e12c5d1SDavid du Colombier 
5633e12c5d1SDavid du Colombier 	rs = (inst>>21)&0x1f;
5643e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
5653e12c5d1SDavid du Colombier 
5663e12c5d1SDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
5673e12c5d1SDavid du Colombier 	if(trace)
5683e12c5d1SDavid du Colombier 		itrace("bgtz\tr%d,0x%lux", rs, npc);
5693e12c5d1SDavid du Colombier 
5703e12c5d1SDavid du Colombier 	r = reg.r[rs];
5713e12c5d1SDavid du Colombier 	if(!(r&SIGNBIT) && r != 0) {
5723e12c5d1SDavid du Colombier 		/* Do the delay slot */
5733e12c5d1SDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
5743e12c5d1SDavid du Colombier 		Iexec(reg.ir);
5753e12c5d1SDavid du Colombier 		reg.pc = npc-4;
5763e12c5d1SDavid du Colombier 	}
5773e12c5d1SDavid du Colombier }
5783e12c5d1SDavid du Colombier 
5793e12c5d1SDavid du Colombier void
Ibgtzl(ulong inst)5807dd7cddfSDavid du Colombier Ibgtzl(ulong inst)
5817dd7cddfSDavid du Colombier {
5827dd7cddfSDavid du Colombier 	int rs;
5837dd7cddfSDavid du Colombier 	int off;
5847dd7cddfSDavid du Colombier 	ulong npc, r;
5857dd7cddfSDavid du Colombier 
5867dd7cddfSDavid du Colombier 	rs = (inst>>21)&0x1f;
5877dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
5887dd7cddfSDavid du Colombier 
5897dd7cddfSDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
5907dd7cddfSDavid du Colombier 	if(trace)
5917dd7cddfSDavid du Colombier 		itrace("bgtz\tr%d,0x%lux", rs, npc);
5927dd7cddfSDavid du Colombier 
5937dd7cddfSDavid du Colombier 	r = reg.r[rs];
5947dd7cddfSDavid du Colombier 	if(!(r&SIGNBIT) && r != 0) {
5957dd7cddfSDavid du Colombier 		/* Do the delay slot */
5967dd7cddfSDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
5977dd7cddfSDavid du Colombier 		Iexec(reg.ir);
5987dd7cddfSDavid du Colombier 		reg.pc = npc-4;
5997dd7cddfSDavid du Colombier 	} else
6007dd7cddfSDavid du Colombier 		reg.pc += 4;
6017dd7cddfSDavid du Colombier }
6027dd7cddfSDavid du Colombier 
6037dd7cddfSDavid du Colombier void
Iblez(ulong inst)6043e12c5d1SDavid du Colombier Iblez(ulong inst)
6053e12c5d1SDavid du Colombier {
6063e12c5d1SDavid du Colombier 	int rs;
6073e12c5d1SDavid du Colombier 	int off;
6083e12c5d1SDavid du Colombier 	ulong npc, r;
6093e12c5d1SDavid du Colombier 
6103e12c5d1SDavid du Colombier 	rs = (inst>>21)&0x1f;
6113e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
6123e12c5d1SDavid du Colombier 
6133e12c5d1SDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
6143e12c5d1SDavid du Colombier 	if(trace)
6153e12c5d1SDavid du Colombier 		itrace("blez\tr%d,0x%lux", rs, npc);
6163e12c5d1SDavid du Colombier 
6173e12c5d1SDavid du Colombier 	r = reg.r[rs];
6183e12c5d1SDavid du Colombier 	if((r&SIGNBIT) || r == 0) {
6193e12c5d1SDavid du Colombier 		/* Do the delay slot */
6203e12c5d1SDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
6213e12c5d1SDavid du Colombier 		Statbra();
6223e12c5d1SDavid du Colombier 		Iexec(reg.ir);
6233e12c5d1SDavid du Colombier 		reg.pc = npc-4;
6243e12c5d1SDavid du Colombier 	}
6253e12c5d1SDavid du Colombier }
6263e12c5d1SDavid du Colombier 
6273e12c5d1SDavid du Colombier void
Iblezl(ulong inst)6287dd7cddfSDavid du Colombier Iblezl(ulong inst)
6297dd7cddfSDavid du Colombier {
6307dd7cddfSDavid du Colombier 	int rs;
6317dd7cddfSDavid du Colombier 	int off;
6327dd7cddfSDavid du Colombier 	ulong npc, r;
6337dd7cddfSDavid du Colombier 
6347dd7cddfSDavid du Colombier 	rs = (inst>>21)&0x1f;
6357dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
6367dd7cddfSDavid du Colombier 
6377dd7cddfSDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
6387dd7cddfSDavid du Colombier 	if(trace)
6397dd7cddfSDavid du Colombier 		itrace("blez\tr%d,0x%lux", rs, npc);
6407dd7cddfSDavid du Colombier 
6417dd7cddfSDavid du Colombier 	r = reg.r[rs];
6427dd7cddfSDavid du Colombier 	if((r&SIGNBIT) || r == 0) {
6437dd7cddfSDavid du Colombier 		/* Do the delay slot */
6447dd7cddfSDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
6457dd7cddfSDavid du Colombier 		Statbra();
6467dd7cddfSDavid du Colombier 		Iexec(reg.ir);
6477dd7cddfSDavid du Colombier 		reg.pc = npc-4;
6487dd7cddfSDavid du Colombier 	} else
6497dd7cddfSDavid du Colombier 		reg.pc += 4;
6507dd7cddfSDavid du Colombier }
6517dd7cddfSDavid du Colombier 
6527dd7cddfSDavid du Colombier void
Ibne(ulong inst)6533e12c5d1SDavid du Colombier Ibne(ulong inst)
6543e12c5d1SDavid du Colombier {
6553e12c5d1SDavid du Colombier 	int rt, rs;
6563e12c5d1SDavid du Colombier 	int off;
6573e12c5d1SDavid du Colombier 	ulong npc;
6583e12c5d1SDavid du Colombier 
6593e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
6603e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
6613e12c5d1SDavid du Colombier 
6623e12c5d1SDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
6633e12c5d1SDavid du Colombier 	if(trace)
6643e12c5d1SDavid du Colombier 		itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
6653e12c5d1SDavid du Colombier 
6663e12c5d1SDavid du Colombier 	if(reg.r[rs] != reg.r[rt]) {
6673e12c5d1SDavid du Colombier 		/* Do the delay slot */
6683e12c5d1SDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
6693e12c5d1SDavid du Colombier 		Statbra();
6703e12c5d1SDavid du Colombier 		Iexec(reg.ir);
6713e12c5d1SDavid du Colombier 		reg.pc = npc-4;
6723e12c5d1SDavid du Colombier 	}
6733e12c5d1SDavid du Colombier }
6743e12c5d1SDavid du Colombier 
6753e12c5d1SDavid du Colombier void
Ibnel(ulong inst)6767dd7cddfSDavid du Colombier Ibnel(ulong inst)
6777dd7cddfSDavid du Colombier {
6787dd7cddfSDavid du Colombier 	int rt, rs;
6797dd7cddfSDavid du Colombier 	int off;
6807dd7cddfSDavid du Colombier 	ulong npc;
6817dd7cddfSDavid du Colombier 
6827dd7cddfSDavid du Colombier 	Getrsrt(rs, rt, inst);
6837dd7cddfSDavid du Colombier 	off = (short)(inst&0xffff);
6847dd7cddfSDavid du Colombier 
6857dd7cddfSDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
6867dd7cddfSDavid du Colombier 	if(trace)
6877dd7cddfSDavid du Colombier 		itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
6887dd7cddfSDavid du Colombier 
6897dd7cddfSDavid du Colombier 	if(reg.r[rs] != reg.r[rt]) {
6907dd7cddfSDavid du Colombier 		/* Do the delay slot */
6917dd7cddfSDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
6927dd7cddfSDavid du Colombier 		Statbra();
6937dd7cddfSDavid du Colombier 		Iexec(reg.ir);
6947dd7cddfSDavid du Colombier 		reg.pc = npc-4;
6957dd7cddfSDavid du Colombier 	} else
6967dd7cddfSDavid du Colombier 		reg.pc += 4;
6977dd7cddfSDavid du Colombier }
6987dd7cddfSDavid du Colombier 
6997dd7cddfSDavid du Colombier void
Iaddiu(ulong inst)7003e12c5d1SDavid du Colombier Iaddiu(ulong inst)
7013e12c5d1SDavid du Colombier {
7023e12c5d1SDavid du Colombier 	int rs, rt;
7033e12c5d1SDavid du Colombier 	int imm;
7043e12c5d1SDavid du Colombier 
7053e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
7063e12c5d1SDavid du Colombier 	imm = (short)(inst&0xffff);
7073e12c5d1SDavid du Colombier 
7083e12c5d1SDavid du Colombier 	if(trace)
7093e12c5d1SDavid du Colombier 		itrace("addiu\tr%d,r%d,#0x%x", rt, rs, imm);
7103e12c5d1SDavid du Colombier 
7113e12c5d1SDavid du Colombier 	reg.r[rt] = reg.r[rs]+imm;
7123e12c5d1SDavid du Colombier }
7133e12c5d1SDavid du Colombier 
7143e12c5d1SDavid du Colombier void
Islti(ulong inst)7153e12c5d1SDavid du Colombier Islti(ulong inst)
7163e12c5d1SDavid du Colombier {
7173e12c5d1SDavid du Colombier 	int rs, rt;
7183e12c5d1SDavid du Colombier 	int imm;
7193e12c5d1SDavid du Colombier 
7203e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
7213e12c5d1SDavid du Colombier 	imm = (short)(inst&0xffff);
7223e12c5d1SDavid du Colombier 
7233e12c5d1SDavid du Colombier 	if(trace)
7243e12c5d1SDavid du Colombier 		itrace("slti\tr%d,r%d,#0x%x", rt, rs, imm);
7253e12c5d1SDavid du Colombier 
7263e12c5d1SDavid du Colombier 	reg.r[rt] = reg.r[rs] < imm ? 1 : 0;
7273e12c5d1SDavid du Colombier }
7283e12c5d1SDavid du Colombier 
7293e12c5d1SDavid du Colombier void
Isltiu(ulong inst)7303e12c5d1SDavid du Colombier Isltiu(ulong inst)
7313e12c5d1SDavid du Colombier {
7323e12c5d1SDavid du Colombier 	int rs, rt;
7333e12c5d1SDavid du Colombier 	int imm;
7343e12c5d1SDavid du Colombier 
7353e12c5d1SDavid du Colombier 	Getrsrt(rs, rt, inst);
7363e12c5d1SDavid du Colombier 	imm = (short)(inst&0xffff);
7373e12c5d1SDavid du Colombier 
7383e12c5d1SDavid du Colombier 	if(trace)
7393e12c5d1SDavid du Colombier 		itrace("sltiu\tr%d,r%d,#0x%x", rt, rs, imm);
7403e12c5d1SDavid du Colombier 
7413e12c5d1SDavid du Colombier 	reg.r[rt] = (ulong)reg.r[rs] < (ulong)imm ? 1 : 0;
7423e12c5d1SDavid du Colombier }
7433e12c5d1SDavid du Colombier 
7449a747e4fSDavid du Colombier /* ll and sc are implemented as lw and sw, since we simulate a uniprocessor */
7459a747e4fSDavid du Colombier 
7469a747e4fSDavid du Colombier void
Ill(ulong inst)7479a747e4fSDavid du Colombier Ill(ulong inst)
7489a747e4fSDavid du Colombier {
7499a747e4fSDavid du Colombier 	int rt, rb;
7509a747e4fSDavid du Colombier 	int off;
7519a747e4fSDavid du Colombier 	ulong v, va;
7529a747e4fSDavid du Colombier 
7539a747e4fSDavid du Colombier 	Getrbrt(rb, rt, inst);
7549a747e4fSDavid du Colombier 	off = (short)(inst&0xffff);
7559a747e4fSDavid du Colombier 
7569a747e4fSDavid du Colombier 	va = reg.r[rb]+off;
7579a747e4fSDavid du Colombier 
7589a747e4fSDavid du Colombier 	if(trace) {
7599a747e4fSDavid du Colombier 		v = 0;
7609a747e4fSDavid du Colombier 		if(!badvaddr(va, 4))
7619a747e4fSDavid du Colombier 			v = getmem_w(va);
7629a747e4fSDavid du Colombier 		itrace("ll\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
7639a747e4fSDavid du Colombier 	}
7649a747e4fSDavid du Colombier 
7659a747e4fSDavid du Colombier 	reg.r[rt] = getmem_w(va);
7669a747e4fSDavid du Colombier }
7679a747e4fSDavid du Colombier 
7689a747e4fSDavid du Colombier void
Isc(ulong inst)7699a747e4fSDavid du Colombier Isc(ulong inst)
7709a747e4fSDavid du Colombier {
7719a747e4fSDavid du Colombier 	int rt, rb;
7729a747e4fSDavid du Colombier 	int off;
7739a747e4fSDavid du Colombier 	ulong v;
7749a747e4fSDavid du Colombier 
7759a747e4fSDavid du Colombier 	Getrbrt(rb, rt, inst);
7769a747e4fSDavid du Colombier 	off = (short)(inst&0xffff);
7779a747e4fSDavid du Colombier 
7789a747e4fSDavid du Colombier 	v = reg.r[rt];
7799a747e4fSDavid du Colombier 	if(trace)
7809a747e4fSDavid du Colombier 		itrace("sc\tr%d,0x%x(r%d) %lux=%lux",
7819a747e4fSDavid du Colombier 				rt, off, rb, reg.r[rb]+off, v);
7829a747e4fSDavid du Colombier 
7839a747e4fSDavid du Colombier 	putmem_w(reg.r[rb]+off, v);
7849a747e4fSDavid du Colombier }
7859a747e4fSDavid du Colombier 
7863e12c5d1SDavid du Colombier enum
7873e12c5d1SDavid du Colombier {
7883e12c5d1SDavid du Colombier 	Bltz	= 0,
7893e12c5d1SDavid du Colombier 	Bgez	= 1,
7903e12c5d1SDavid du Colombier 	Bltzal	= 0x10,
7913e12c5d1SDavid du Colombier 	Bgezal	= 0x11,
7927dd7cddfSDavid du Colombier 	Bltzl	= 2,
7937dd7cddfSDavid du Colombier 	Bgezl	= 3,
7947dd7cddfSDavid du Colombier 	Bltzall	= 0x12,
7957dd7cddfSDavid du Colombier 	Bgezall	= 0x13,
7963e12c5d1SDavid du Colombier };
7973e12c5d1SDavid du Colombier 
7983e12c5d1SDavid du Colombier static char *sbcond[] =
7993e12c5d1SDavid du Colombier {
8003e12c5d1SDavid du Colombier 	[Bltz]		"ltz",
8013e12c5d1SDavid du Colombier 	[Bgez]		"gez",
8023e12c5d1SDavid du Colombier 	[Bltzal]	"ltzal",
8033e12c5d1SDavid du Colombier 	[Bgezal]	"gezal",
8047dd7cddfSDavid du Colombier 	[Bltzl]		"ltzl",
8057dd7cddfSDavid du Colombier 	[Bgezl]		"gezl",
8067dd7cddfSDavid du Colombier 	[Bltzall]	"ltzall",
8077dd7cddfSDavid du Colombier 	[Bgezall]	"gezall",
8083e12c5d1SDavid du Colombier };
8093e12c5d1SDavid du Colombier 
8103e12c5d1SDavid du Colombier void
Ibcond(ulong inst)8113e12c5d1SDavid du Colombier Ibcond(ulong inst)
8123e12c5d1SDavid du Colombier {
8133e12c5d1SDavid du Colombier 	int rs, bran;
8147dd7cddfSDavid du Colombier 	int off, doit, likely;
8153e12c5d1SDavid du Colombier 	ulong npc;
8163e12c5d1SDavid du Colombier 
8173e12c5d1SDavid du Colombier 	rs = (inst>>21)&0x1f;
8183e12c5d1SDavid du Colombier 	bran = (inst>>16)&0x1f;
8193e12c5d1SDavid du Colombier 	off = (short)(inst&0xffff);
8203e12c5d1SDavid du Colombier 	doit = 0;
8217dd7cddfSDavid du Colombier 	likely = 0;
8223e12c5d1SDavid du Colombier 
8233e12c5d1SDavid du Colombier 	npc = reg.pc + (off<<2) + 4;
8243e12c5d1SDavid du Colombier 	switch(bran) {
8253e12c5d1SDavid du Colombier 	default:
8263e12c5d1SDavid du Colombier 		Bprint(bioout, "bcond=%d\n", bran);
8273e12c5d1SDavid du Colombier 		undef(inst);
8287dd7cddfSDavid du Colombier 	case Bltzl:
8297dd7cddfSDavid du Colombier 		likely = 1;
8303e12c5d1SDavid du Colombier 	case Bltz:
8313e12c5d1SDavid du Colombier 		if(reg.r[rs]&SIGNBIT)
8323e12c5d1SDavid du Colombier 			doit = 1;
8333e12c5d1SDavid du Colombier 		break;
8347dd7cddfSDavid du Colombier 	case Bgezl:
8357dd7cddfSDavid du Colombier 		likely = 1;
8363e12c5d1SDavid du Colombier 	case Bgez:
8373e12c5d1SDavid du Colombier 		if(!(reg.r[rs]&SIGNBIT))
8383e12c5d1SDavid du Colombier 			doit = 1;
8393e12c5d1SDavid du Colombier 		break;
8407dd7cddfSDavid du Colombier 	case Bltzall:
8417dd7cddfSDavid du Colombier 		likely = 1;
8423e12c5d1SDavid du Colombier 	case Bltzal:
8433e12c5d1SDavid du Colombier 		reg.r[31] = reg.pc+8;
8447dd7cddfSDavid du Colombier 		if(reg.r[rs]&SIGNBIT)
8457dd7cddfSDavid du Colombier 			doit = 1;
8463e12c5d1SDavid du Colombier 		break;
8477dd7cddfSDavid du Colombier 	case Bgezall:
8487dd7cddfSDavid du Colombier 		likely = 1;
8493e12c5d1SDavid du Colombier 	case Bgezal:
8503e12c5d1SDavid du Colombier 		reg.r[31] = reg.pc+8;
8517dd7cddfSDavid du Colombier 		if(!(reg.r[rs]&SIGNBIT))
8527dd7cddfSDavid du Colombier 			doit = 1;
8533e12c5d1SDavid du Colombier 		break;
8543e12c5d1SDavid du Colombier 	}
8553e12c5d1SDavid du Colombier 
8563e12c5d1SDavid du Colombier 	if(trace)
8573e12c5d1SDavid du Colombier 		itrace("b%s\tr%d,0x%lux", sbcond[bran], rs, npc);
8583e12c5d1SDavid du Colombier 
8593e12c5d1SDavid du Colombier 	if(doit) {
8603e12c5d1SDavid du Colombier 		/* Do the delay slot */
8613e12c5d1SDavid du Colombier 		reg.ir = ifetch(reg.pc+4);
8623e12c5d1SDavid du Colombier 		Statbra();
8633e12c5d1SDavid du Colombier 		Iexec(reg.ir);
8643e12c5d1SDavid du Colombier 		reg.pc = npc-4;
8657dd7cddfSDavid du Colombier 	} else
8667dd7cddfSDavid du Colombier 	if(likely)
8677dd7cddfSDavid du Colombier 		reg.pc += 4;
8683e12c5d1SDavid du Colombier 
8693e12c5d1SDavid du Colombier }
870