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