13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4*bd389b36SDavid du Colombier #include <mach.h>
53e12c5d1SDavid du Colombier #define Extern extern
63e12c5d1SDavid du Colombier #include "sparc.h"
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier void add(ulong);
93e12c5d1SDavid du Colombier void and(ulong);
103e12c5d1SDavid du Colombier void or(ulong);
113e12c5d1SDavid du Colombier void xor(ulong);
123e12c5d1SDavid du Colombier void sub(ulong);
133e12c5d1SDavid du Colombier void andn(ulong);
143e12c5d1SDavid du Colombier void xnor(ulong);
153e12c5d1SDavid du Colombier void subcc(ulong);
163e12c5d1SDavid du Colombier void sll(ulong);
173e12c5d1SDavid du Colombier void srl(ulong);
183e12c5d1SDavid du Colombier void sra(ulong);
193e12c5d1SDavid du Colombier void jmpl(ulong);
203e12c5d1SDavid du Colombier void andcc(ulong);
213e12c5d1SDavid du Colombier void xorcc(ulong);
223e12c5d1SDavid du Colombier void andncc(ulong);
233e12c5d1SDavid du Colombier void wry(ulong);
243e12c5d1SDavid du Colombier void rdy(ulong);
253e12c5d1SDavid du Colombier void mulscc(ulong);
263e12c5d1SDavid du Colombier void fcmp(ulong);
273e12c5d1SDavid du Colombier void farith(ulong);
283e12c5d1SDavid du Colombier void addcc(ulong);
293e12c5d1SDavid du Colombier void addx(ulong);
303e12c5d1SDavid du Colombier void addxcc(ulong);
313e12c5d1SDavid du Colombier void orcc(ulong);
323e12c5d1SDavid du Colombier void orncc(ulong);
333e12c5d1SDavid du Colombier void xnorcc(ulong);
343e12c5d1SDavid du Colombier void orn(ulong);
353e12c5d1SDavid du Colombier
363e12c5d1SDavid du Colombier Inst op2[] = {
373e12c5d1SDavid du Colombier { add, "add", Iarith },
383e12c5d1SDavid du Colombier { and, "and", Iarith },
393e12c5d1SDavid du Colombier { or, "or", Iarith },
403e12c5d1SDavid du Colombier { xor, "xor", Iarith },
413e12c5d1SDavid du Colombier { sub, "sub", Iarith },
423e12c5d1SDavid du Colombier { andn, "andn", Iarith },
433e12c5d1SDavid du Colombier { orn, "orn", Inop },
443e12c5d1SDavid du Colombier { xnor, "xnor", Iarith },
453e12c5d1SDavid du Colombier { addx, "addx", Iarith },
463e12c5d1SDavid du Colombier { undef, "" },
473e12c5d1SDavid du Colombier { undef, "" },
483e12c5d1SDavid du Colombier { undef, "" },
493e12c5d1SDavid du Colombier { undef, "" },
503e12c5d1SDavid du Colombier { undef, "" },
513e12c5d1SDavid du Colombier { undef, "" },
523e12c5d1SDavid du Colombier { undef, "" },
533e12c5d1SDavid du Colombier { addcc, "addcc", Iarith },
543e12c5d1SDavid du Colombier { andcc, "andcc", Iarith },
553e12c5d1SDavid du Colombier { orcc, "orcc", Iarith },
563e12c5d1SDavid du Colombier { xorcc, "xorcc", Iarith },
573e12c5d1SDavid du Colombier { subcc, "subcc", Iarith },
583e12c5d1SDavid du Colombier { andncc, "andncc",Iarith },
593e12c5d1SDavid du Colombier { orncc, "orncc", Iarith },
603e12c5d1SDavid du Colombier { xnorcc, "xnorcc",Iarith },
613e12c5d1SDavid du Colombier { addxcc, "addxcc",Iarith },
623e12c5d1SDavid du Colombier { undef, "" },
633e12c5d1SDavid du Colombier { undef, "" },
643e12c5d1SDavid du Colombier { undef, "" },
653e12c5d1SDavid du Colombier { undef, "" },
663e12c5d1SDavid du Colombier { undef, "" },
673e12c5d1SDavid du Colombier { undef, "" },
683e12c5d1SDavid du Colombier { undef, "" },
693e12c5d1SDavid du Colombier { undef, "" },
703e12c5d1SDavid du Colombier { undef, "" },
713e12c5d1SDavid du Colombier { undef, "" },
723e12c5d1SDavid du Colombier { undef, "" },
733e12c5d1SDavid du Colombier { mulscc, "mulscc", Iarith },
743e12c5d1SDavid du Colombier { sll, "sll", Iarith },
753e12c5d1SDavid du Colombier { srl, "srl", Iarith },
763e12c5d1SDavid du Colombier { sra, "sra", Iarith },
773e12c5d1SDavid du Colombier { rdy, "rdy", Ireg },
783e12c5d1SDavid du Colombier { undef, "" },
793e12c5d1SDavid du Colombier { undef, "" },
803e12c5d1SDavid du Colombier { undef, "" },
813e12c5d1SDavid du Colombier { undef, "" },
823e12c5d1SDavid du Colombier { undef, "" },
833e12c5d1SDavid du Colombier { undef, "" },
843e12c5d1SDavid du Colombier { undef, "" },
853e12c5d1SDavid du Colombier { wry, "wry", Ireg },
863e12c5d1SDavid du Colombier { undef, "" },
873e12c5d1SDavid du Colombier { undef, "" },
883e12c5d1SDavid du Colombier { undef, "" },
893e12c5d1SDavid du Colombier { farith, "farith", Ifloat },
903e12c5d1SDavid du Colombier { fcmp, "fcmp", Ifloat },
913e12c5d1SDavid du Colombier { undef, "" },
923e12c5d1SDavid du Colombier { undef, "" },
933e12c5d1SDavid du Colombier { jmpl, "jmpl", Ibranch },
943e12c5d1SDavid du Colombier { undef, "" },
953e12c5d1SDavid du Colombier { ta, "ta", Isyscall },
963e12c5d1SDavid du Colombier { undef, "" },
973e12c5d1SDavid du Colombier { undef, "" },
983e12c5d1SDavid du Colombier { undef, "" },
993e12c5d1SDavid du Colombier { undef, "" },
1003e12c5d1SDavid du Colombier { undef, "" },
1013e12c5d1SDavid du Colombier { 0 }
1023e12c5d1SDavid du Colombier };
1033e12c5d1SDavid du Colombier
1043e12c5d1SDavid du Colombier void st(ulong);
1053e12c5d1SDavid du Colombier void stb(ulong);
1063e12c5d1SDavid du Colombier void sth(ulong);
1073e12c5d1SDavid du Colombier void ld(ulong);
1083e12c5d1SDavid du Colombier void ldub(ulong);
1093e12c5d1SDavid du Colombier void ldsb(ulong);
1103e12c5d1SDavid du Colombier void lduh(ulong);
1113e12c5d1SDavid du Colombier void stf(ulong);
1123e12c5d1SDavid du Colombier void ldf(ulong);
1133e12c5d1SDavid du Colombier void ldsh(ulong);
1143e12c5d1SDavid du Colombier void std(ulong);
1153e12c5d1SDavid du Colombier void ldd(ulong);
1163e12c5d1SDavid du Colombier void ldstub(ulong);
1173e12c5d1SDavid du Colombier void swap(ulong);
1183e12c5d1SDavid du Colombier void lddf(ulong);
1193e12c5d1SDavid du Colombier void stdf(ulong);
1203e12c5d1SDavid du Colombier
1213e12c5d1SDavid du Colombier Inst op3[] = {
1223e12c5d1SDavid du Colombier { ld, "ld", Iload },
1233e12c5d1SDavid du Colombier { ldub, "ldub", Iload },
1243e12c5d1SDavid du Colombier { lduh, "lduh", Iload },
1253e12c5d1SDavid du Colombier { ldd, "ldd", Iload },
1263e12c5d1SDavid du Colombier { st, "st", Istore },
1273e12c5d1SDavid du Colombier { stb, "stb", Istore },
1283e12c5d1SDavid du Colombier { sth, "sth", Istore },
1293e12c5d1SDavid du Colombier { std, "std", Istore },
1303e12c5d1SDavid du Colombier { undef, "" },
1313e12c5d1SDavid du Colombier { ldsb, "ldsb", Iload },
1323e12c5d1SDavid du Colombier { ldsh, "ldsh", Iload },
1333e12c5d1SDavid du Colombier { undef, "" },
1343e12c5d1SDavid du Colombier { undef, "" },
1353e12c5d1SDavid du Colombier { ldstub, "ldstub", Iload },
1363e12c5d1SDavid du Colombier { undef, "" },
1373e12c5d1SDavid du Colombier { swap, "swap", Iload },
1383e12c5d1SDavid du Colombier { undef, "" },
1393e12c5d1SDavid du Colombier { undef, "" },
1403e12c5d1SDavid du Colombier { undef, "" },
1413e12c5d1SDavid du Colombier { undef, "" },
1423e12c5d1SDavid du Colombier { undef, "" },
1433e12c5d1SDavid du Colombier { undef, "" },
1443e12c5d1SDavid du Colombier { undef, "" },
1453e12c5d1SDavid du Colombier { undef, "" },
1463e12c5d1SDavid du Colombier { undef, "" },
1473e12c5d1SDavid du Colombier { undef, "" },
1483e12c5d1SDavid du Colombier { undef, "" },
1493e12c5d1SDavid du Colombier { undef, "" },
1503e12c5d1SDavid du Colombier { undef, "" },
1513e12c5d1SDavid du Colombier { undef, "" },
1523e12c5d1SDavid du Colombier { undef, "" },
1533e12c5d1SDavid du Colombier { undef, "" },
1543e12c5d1SDavid du Colombier { ldf, "ldf", Ifloat },
1553e12c5d1SDavid du Colombier { undef, "" },
1563e12c5d1SDavid du Colombier { undef, "" },
1573e12c5d1SDavid du Colombier { lddf, "lddf", Ifloat },
1583e12c5d1SDavid du Colombier { stf, "stf", Ifloat },
1593e12c5d1SDavid du Colombier { undef, "" },
1603e12c5d1SDavid du Colombier { undef, "" },
1613e12c5d1SDavid du Colombier { stdf, "stdf", Ifloat },
1623e12c5d1SDavid du Colombier { undef, "" },
1633e12c5d1SDavid du Colombier { undef, "" },
1643e12c5d1SDavid du Colombier { undef, "" },
1653e12c5d1SDavid du Colombier { undef, "" },
1663e12c5d1SDavid du Colombier { undef, "" },
1673e12c5d1SDavid du Colombier { undef, "" },
1683e12c5d1SDavid du Colombier { undef, "" },
1693e12c5d1SDavid du Colombier { undef, "" },
1703e12c5d1SDavid du Colombier { undef, "" },
1713e12c5d1SDavid du Colombier { undef, "" },
1723e12c5d1SDavid du Colombier { undef, "" },
1733e12c5d1SDavid du Colombier { undef, "" },
1743e12c5d1SDavid du Colombier { undef, "" },
1753e12c5d1SDavid du Colombier { undef, "" },
1763e12c5d1SDavid du Colombier { undef, "" },
1773e12c5d1SDavid du Colombier { undef, "" },
1783e12c5d1SDavid du Colombier { undef, "" },
1793e12c5d1SDavid du Colombier { undef, "" },
1803e12c5d1SDavid du Colombier { undef, "" },
1813e12c5d1SDavid du Colombier { undef, "" },
1823e12c5d1SDavid du Colombier { undef, "" },
1833e12c5d1SDavid du Colombier { undef, "" },
1843e12c5d1SDavid du Colombier { undef, "" },
1853e12c5d1SDavid du Colombier { undef, "" },
1863e12c5d1SDavid du Colombier { 0 }
1873e12c5d1SDavid du Colombier };
1883e12c5d1SDavid du Colombier
1893e12c5d1SDavid du Colombier void sethi(ulong);
1903e12c5d1SDavid du Colombier void bicc(ulong);
1913e12c5d1SDavid du Colombier void fbcc(ulong);
1923e12c5d1SDavid du Colombier void call(ulong);
1933e12c5d1SDavid du Colombier
1943e12c5d1SDavid du Colombier Inst op0[] = {
1953e12c5d1SDavid du Colombier { undef, "" },
1963e12c5d1SDavid du Colombier { undef, "" },
1973e12c5d1SDavid du Colombier { bicc, "bicc", Ibranch },
1983e12c5d1SDavid du Colombier { undef, "" },
1993e12c5d1SDavid du Colombier { sethi, "sethi",Iarith },
2003e12c5d1SDavid du Colombier { undef, "" },
2013e12c5d1SDavid du Colombier { fbcc, "fbcc", Ibranch },
2023e12c5d1SDavid du Colombier { undef, "" },
2033e12c5d1SDavid du Colombier /* This is a fake and connot be reached by op0 decode */
2043e12c5d1SDavid du Colombier { call, "call", Ibranch },
2053e12c5d1SDavid du Colombier { 0 }
2063e12c5d1SDavid du Colombier };
2073e12c5d1SDavid du Colombier
2083e12c5d1SDavid du Colombier void call(ulong);
2093e12c5d1SDavid du Colombier
2103e12c5d1SDavid du Colombier void
run(void)2113e12c5d1SDavid du Colombier run(void)
2123e12c5d1SDavid du Colombier {
2133e12c5d1SDavid du Colombier do {
2143e12c5d1SDavid du Colombier reg.r[0] = 0;
2153e12c5d1SDavid du Colombier reg.ir = ifetch(reg.pc);
2163e12c5d1SDavid du Colombier switch(reg.ir>>30) {
2173e12c5d1SDavid du Colombier case 0:
2183e12c5d1SDavid du Colombier ci = &op0[(reg.ir>>22)&0x07];
2193e12c5d1SDavid du Colombier ci->count++;
2203e12c5d1SDavid du Colombier (*ci->func)(reg.ir);
2213e12c5d1SDavid du Colombier break;
2223e12c5d1SDavid du Colombier case 1:
2233e12c5d1SDavid du Colombier ci = &op0[8];
2243e12c5d1SDavid du Colombier ci->count++;
2253e12c5d1SDavid du Colombier call(reg.ir);
2263e12c5d1SDavid du Colombier break;
2273e12c5d1SDavid du Colombier case 2:
2283e12c5d1SDavid du Colombier ci = &op2[(reg.ir>>19)&0x3f];
2293e12c5d1SDavid du Colombier ci->count++;
2303e12c5d1SDavid du Colombier (*ci->func)(reg.ir);
2313e12c5d1SDavid du Colombier break;
2323e12c5d1SDavid du Colombier case 3:
2333e12c5d1SDavid du Colombier ci = &op3[(reg.ir>>19)&0x3f];
2343e12c5d1SDavid du Colombier ci->count++;
2353e12c5d1SDavid du Colombier (*ci->func)(reg.ir);
2363e12c5d1SDavid du Colombier break;
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier reg.pc += 4;
2393e12c5d1SDavid du Colombier if(bplist)
2403e12c5d1SDavid du Colombier brkchk(reg.pc, Instruction);
2413e12c5d1SDavid du Colombier }while(--count);
2423e12c5d1SDavid du Colombier }
2433e12c5d1SDavid du Colombier
2443e12c5d1SDavid du Colombier void
ilock(int rd)2453e12c5d1SDavid du Colombier ilock(int rd)
2463e12c5d1SDavid du Colombier {
2473e12c5d1SDavid du Colombier ulong ir;
2483e12c5d1SDavid du Colombier
2493e12c5d1SDavid du Colombier ir = getmem_4(reg.pc+4);
2503e12c5d1SDavid du Colombier switch(ir>>30) {
2513e12c5d1SDavid du Colombier case 0:
2523e12c5d1SDavid du Colombier case 1:
2533e12c5d1SDavid du Colombier break;
2543e12c5d1SDavid du Colombier case 2:
2553e12c5d1SDavid du Colombier if(((ir>>20)&0x1f) == 0x1a) /* floating point */
2563e12c5d1SDavid du Colombier break;
2573e12c5d1SDavid du Colombier case 3:
2583e12c5d1SDavid du Colombier if(rd == ((ir>>14)&0x1f)) {
2593e12c5d1SDavid du Colombier loadlock++;
2603e12c5d1SDavid du Colombier break;
2613e12c5d1SDavid du Colombier }
2623e12c5d1SDavid du Colombier if(ir&IMMBIT)
2633e12c5d1SDavid du Colombier break;
2643e12c5d1SDavid du Colombier if(rd == (ir&0x1f))
2653e12c5d1SDavid du Colombier loadlock++;
2663e12c5d1SDavid du Colombier break;
2673e12c5d1SDavid du Colombier }
2683e12c5d1SDavid du Colombier }
2693e12c5d1SDavid du Colombier
2703e12c5d1SDavid du Colombier void
delay(ulong npc)271*bd389b36SDavid du Colombier delay(ulong npc)
2723e12c5d1SDavid du Colombier {
273*bd389b36SDavid du Colombier ulong opc;
274*bd389b36SDavid du Colombier
2753e12c5d1SDavid du Colombier reg.r[0] = 0;
2763e12c5d1SDavid du Colombier if(reg.ir != NOP)
2773e12c5d1SDavid du Colombier ci->useddelay++;
2783e12c5d1SDavid du Colombier switch(reg.ir>>30) {
2793e12c5d1SDavid du Colombier case 0:
2803e12c5d1SDavid du Colombier ci = &op0[(reg.ir>>22)&0x07];
2813e12c5d1SDavid du Colombier ci->count++;
2823e12c5d1SDavid du Colombier (*ci->func)(reg.ir);
2833e12c5d1SDavid du Colombier break;
2843e12c5d1SDavid du Colombier case 1:
2853e12c5d1SDavid du Colombier ci = &op0[8];
2863e12c5d1SDavid du Colombier ci->count++;
2873e12c5d1SDavid du Colombier call(reg.ir);
2883e12c5d1SDavid du Colombier break;
2893e12c5d1SDavid du Colombier case 2:
2903e12c5d1SDavid du Colombier ci = &op2[(reg.ir>>19)&0x3f];
2913e12c5d1SDavid du Colombier ci->count++;
292*bd389b36SDavid du Colombier opc = reg.pc;
293*bd389b36SDavid du Colombier reg.pc = npc-4;
2943e12c5d1SDavid du Colombier (*ci->func)(reg.ir);
295*bd389b36SDavid du Colombier reg.pc = opc;
2963e12c5d1SDavid du Colombier break;
2973e12c5d1SDavid du Colombier case 3:
2983e12c5d1SDavid du Colombier ci = &op3[(reg.ir>>19)&0x3f];
2993e12c5d1SDavid du Colombier ci->count++;
300*bd389b36SDavid du Colombier opc = reg.pc;
301*bd389b36SDavid du Colombier reg.pc = npc-4;
3023e12c5d1SDavid du Colombier (*ci->func)(reg.ir);
303*bd389b36SDavid du Colombier reg.pc = opc;
3043e12c5d1SDavid du Colombier break;
3053e12c5d1SDavid du Colombier }
3063e12c5d1SDavid du Colombier }
3073e12c5d1SDavid du Colombier
3083e12c5d1SDavid du Colombier void
undef(ulong ir)3093e12c5d1SDavid du Colombier undef(ulong ir)
3103e12c5d1SDavid du Colombier {
3113e12c5d1SDavid du Colombier /* Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
3123e12c5d1SDavid du Colombier Bprint(bioout, "illegal_instruction IR #%.8lux\n", ir);
3133e12c5d1SDavid du Colombier longjmp(errjmp, 0);
3143e12c5d1SDavid du Colombier }
3153e12c5d1SDavid du Colombier
3163e12c5d1SDavid du Colombier void
sub(ulong ir)3173e12c5d1SDavid du Colombier sub(ulong ir)
3183e12c5d1SDavid du Colombier {
3193e12c5d1SDavid du Colombier long v;
3203e12c5d1SDavid du Colombier int rd, rs1, rs2;
3213e12c5d1SDavid du Colombier
3223e12c5d1SDavid du Colombier getrop23(ir);
3233e12c5d1SDavid du Colombier if(ir&IMMBIT) {
3243e12c5d1SDavid du Colombier ximm(v, ir);
3253e12c5d1SDavid du Colombier if(trace)
3263e12c5d1SDavid du Colombier itrace("sub\tr%d,#0x%x,r%d", rs1, v, rd);
3273e12c5d1SDavid du Colombier }
3283e12c5d1SDavid du Colombier else {
3293e12c5d1SDavid du Colombier v = reg.r[rs2];
3303e12c5d1SDavid du Colombier if(trace)
3313e12c5d1SDavid du Colombier itrace("sub\tr%d,r%d,r%d", rs1, rs2, rd);
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] - v;
3343e12c5d1SDavid du Colombier }
3353e12c5d1SDavid du Colombier
3363e12c5d1SDavid du Colombier void
sll(ulong ir)3373e12c5d1SDavid du Colombier sll(ulong ir)
3383e12c5d1SDavid du Colombier {
3393e12c5d1SDavid du Colombier long v;
3403e12c5d1SDavid du Colombier int rd, rs1, rs2;
3413e12c5d1SDavid du Colombier
3423e12c5d1SDavid du Colombier getrop23(ir);
3433e12c5d1SDavid du Colombier if(ir&IMMBIT) {
3443e12c5d1SDavid du Colombier ximm(v, ir);
3453e12c5d1SDavid du Colombier if(trace)
3463e12c5d1SDavid du Colombier itrace("sll\tr%d,#0x%x,r%d", rs1, v, rd);
3473e12c5d1SDavid du Colombier }
3483e12c5d1SDavid du Colombier else {
3493e12c5d1SDavid du Colombier v = reg.r[rs2]&0x1F;
3503e12c5d1SDavid du Colombier if(trace)
3513e12c5d1SDavid du Colombier itrace("sll\tr%d,r%d,r%d", rs1, rs2, rd);
3523e12c5d1SDavid du Colombier }
3533e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] << v;
3543e12c5d1SDavid du Colombier }
3553e12c5d1SDavid du Colombier
3563e12c5d1SDavid du Colombier void
srl(ulong ir)3573e12c5d1SDavid du Colombier srl(ulong ir)
3583e12c5d1SDavid du Colombier {
3593e12c5d1SDavid du Colombier long v;
3603e12c5d1SDavid du Colombier int rd, rs1, rs2;
3613e12c5d1SDavid du Colombier
3623e12c5d1SDavid du Colombier getrop23(ir);
3633e12c5d1SDavid du Colombier if(ir&IMMBIT) {
3643e12c5d1SDavid du Colombier ximm(v, ir);
3653e12c5d1SDavid du Colombier if(trace)
3663e12c5d1SDavid du Colombier itrace("srl\tr%d,#0x%x,r%d", rs1, v, rd);
3673e12c5d1SDavid du Colombier }
3683e12c5d1SDavid du Colombier else {
3693e12c5d1SDavid du Colombier v = reg.r[rs2];
3703e12c5d1SDavid du Colombier if(trace)
3713e12c5d1SDavid du Colombier itrace("srl\tr%d,r%d,r%d", rs1, rs2, rd);
3723e12c5d1SDavid du Colombier }
3733e12c5d1SDavid du Colombier reg.r[rd] = (ulong)reg.r[rs1] >> v;
3743e12c5d1SDavid du Colombier }
3753e12c5d1SDavid du Colombier
3763e12c5d1SDavid du Colombier void
sra(ulong ir)3773e12c5d1SDavid du Colombier sra(ulong ir)
3783e12c5d1SDavid du Colombier {
3793e12c5d1SDavid du Colombier long v;
3803e12c5d1SDavid du Colombier int rd, rs1, rs2;
3813e12c5d1SDavid du Colombier
3823e12c5d1SDavid du Colombier getrop23(ir);
3833e12c5d1SDavid du Colombier if(ir&IMMBIT) {
3843e12c5d1SDavid du Colombier ximm(v, ir);
3853e12c5d1SDavid du Colombier if(trace)
3863e12c5d1SDavid du Colombier itrace("sra\tr%d,#0x%x,r%d", rs1, v, rd);
3873e12c5d1SDavid du Colombier }
3883e12c5d1SDavid du Colombier else {
3893e12c5d1SDavid du Colombier v = reg.r[rs2];
3903e12c5d1SDavid du Colombier if(trace)
3913e12c5d1SDavid du Colombier itrace("sra\tr%d,r%d,r%d", rs1, rs2, rd);
3923e12c5d1SDavid du Colombier }
3933e12c5d1SDavid du Colombier if(reg.r[rs1]&SIGNBIT)
3943e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1]>>v | ~((1<<(32-v))-1);
3953e12c5d1SDavid du Colombier else
3963e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1]>>v;
3973e12c5d1SDavid du Colombier }
3983e12c5d1SDavid du Colombier
3993e12c5d1SDavid du Colombier void
subcc(ulong ir)4003e12c5d1SDavid du Colombier subcc(ulong ir)
4013e12c5d1SDavid du Colombier {
4023e12c5d1SDavid du Colombier long v;
4033e12c5d1SDavid du Colombier int b31rs1, b31op2, b31res, r, rd, rs1, rs2;
4043e12c5d1SDavid du Colombier
4053e12c5d1SDavid du Colombier getrop23(ir);
4063e12c5d1SDavid du Colombier if(ir&IMMBIT) {
4073e12c5d1SDavid du Colombier ximm(v, ir);
4083e12c5d1SDavid du Colombier if(trace)
4093e12c5d1SDavid du Colombier itrace("subcc\tr%d,#0x%x,r%d", rs1, v, rd);
4103e12c5d1SDavid du Colombier }
4113e12c5d1SDavid du Colombier else {
4123e12c5d1SDavid du Colombier v = reg.r[rs2];
4133e12c5d1SDavid du Colombier if(trace)
4143e12c5d1SDavid du Colombier itrace("subcc\tr%d,r%d,r%d", rs1, rs2, rd);
4153e12c5d1SDavid du Colombier }
4163e12c5d1SDavid du Colombier r = reg.r[rs1] - v;
4173e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
4183e12c5d1SDavid du Colombier if(r == 0)
4193e12c5d1SDavid du Colombier reg.psr |= PSR_z;
4203e12c5d1SDavid du Colombier if(r < 0)
4213e12c5d1SDavid du Colombier reg.psr |= PSR_n;
4223e12c5d1SDavid du Colombier
4233e12c5d1SDavid du Colombier b31rs1 = reg.r[rs1]>>31;
4243e12c5d1SDavid du Colombier b31op2 = v>>31;
4253e12c5d1SDavid du Colombier b31res = r>>31;
4263e12c5d1SDavid du Colombier
4273e12c5d1SDavid du Colombier if((b31rs1 & ~b31op2 & ~b31res)|(~b31rs1 & b31op2 & b31res))
4283e12c5d1SDavid du Colombier reg.psr |= PSR_v;
4293e12c5d1SDavid du Colombier
4303e12c5d1SDavid du Colombier if((~b31rs1 & b31op2)|(b31res & (~b31rs1|b31op2)))
4313e12c5d1SDavid du Colombier reg.psr |= PSR_c;
4323e12c5d1SDavid du Colombier
4333e12c5d1SDavid du Colombier reg.r[rd] = r;
4343e12c5d1SDavid du Colombier
4353e12c5d1SDavid du Colombier }
4363e12c5d1SDavid du Colombier
4373e12c5d1SDavid du Colombier void
add(ulong ir)4383e12c5d1SDavid du Colombier add(ulong ir)
4393e12c5d1SDavid du Colombier {
4403e12c5d1SDavid du Colombier long v;
4413e12c5d1SDavid du Colombier int rd, rs1, rs2;
4423e12c5d1SDavid du Colombier
4433e12c5d1SDavid du Colombier getrop23(ir);
4443e12c5d1SDavid du Colombier if(ir&IMMBIT) {
4453e12c5d1SDavid du Colombier ximm(v, ir);
4463e12c5d1SDavid du Colombier if(trace)
4473e12c5d1SDavid du Colombier itrace("add\tr%d,#0x%x,r%d", rs1, v, rd);
4483e12c5d1SDavid du Colombier }
4493e12c5d1SDavid du Colombier else {
4503e12c5d1SDavid du Colombier v = reg.r[rs2];
4513e12c5d1SDavid du Colombier if(trace)
4523e12c5d1SDavid du Colombier itrace("add\tr%d,r%d,r%d", rs1, rs2, rd);
4533e12c5d1SDavid du Colombier }
4543e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] + v;
4553e12c5d1SDavid du Colombier }
4563e12c5d1SDavid du Colombier
4573e12c5d1SDavid du Colombier void
addcc(ulong ir)4583e12c5d1SDavid du Colombier addcc(ulong ir)
4593e12c5d1SDavid du Colombier {
4603e12c5d1SDavid du Colombier long v, r;
4613e12c5d1SDavid du Colombier int rd, rs1, rs2, b31rs1, b31op2, b31r;
4623e12c5d1SDavid du Colombier
4633e12c5d1SDavid du Colombier getrop23(ir);
4643e12c5d1SDavid du Colombier if(ir&IMMBIT) {
4653e12c5d1SDavid du Colombier ximm(v, ir);
4663e12c5d1SDavid du Colombier if(trace)
4673e12c5d1SDavid du Colombier itrace("addcc\tr%d,#0x%x,r%d", rs1, v, rd);
4683e12c5d1SDavid du Colombier }
4693e12c5d1SDavid du Colombier else {
4703e12c5d1SDavid du Colombier v = reg.r[rs2];
4713e12c5d1SDavid du Colombier if(trace)
4723e12c5d1SDavid du Colombier itrace("addcc\tr%d,r%d,r%d", rs1, rs2, rd);
4733e12c5d1SDavid du Colombier }
4743e12c5d1SDavid du Colombier r = reg.r[rs1] + v;
4753e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
4763e12c5d1SDavid du Colombier if(r == 0)
4773e12c5d1SDavid du Colombier reg.psr |= PSR_z;
4783e12c5d1SDavid du Colombier if(r < 0)
4793e12c5d1SDavid du Colombier reg.psr |= PSR_n;
4803e12c5d1SDavid du Colombier
4813e12c5d1SDavid du Colombier b31rs1 = reg.r[rs1]>>31;
4823e12c5d1SDavid du Colombier b31op2 = v>>31;
4833e12c5d1SDavid du Colombier b31r = r>>31;
4843e12c5d1SDavid du Colombier if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r))
4853e12c5d1SDavid du Colombier reg.psr |= PSR_v;
4863e12c5d1SDavid du Colombier if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2)))
4873e12c5d1SDavid du Colombier reg.psr |= PSR_c;
4883e12c5d1SDavid du Colombier
4893e12c5d1SDavid du Colombier reg.r[rd] = r;
4903e12c5d1SDavid du Colombier }
4913e12c5d1SDavid du Colombier
4923e12c5d1SDavid du Colombier void
addx(ulong ir)4933e12c5d1SDavid du Colombier addx(ulong ir)
4943e12c5d1SDavid du Colombier {
4953e12c5d1SDavid du Colombier long v;
4963e12c5d1SDavid du Colombier int rd, rs1, rs2;
4973e12c5d1SDavid du Colombier
4983e12c5d1SDavid du Colombier getrop23(ir);
4993e12c5d1SDavid du Colombier if(ir&IMMBIT) {
5003e12c5d1SDavid du Colombier ximm(v, ir);
5013e12c5d1SDavid du Colombier if(trace)
5023e12c5d1SDavid du Colombier itrace("addx\tr%d,#0x%x,r%d", rs1, v, rd);
5033e12c5d1SDavid du Colombier }
5043e12c5d1SDavid du Colombier else {
5053e12c5d1SDavid du Colombier v = reg.r[rs2];
5063e12c5d1SDavid du Colombier if(trace)
5073e12c5d1SDavid du Colombier itrace("addx\tr%d,r%d,r%d", rs1, rs2, rd);
5083e12c5d1SDavid du Colombier }
5093e12c5d1SDavid du Colombier if(reg.psr&PSR_c)
5103e12c5d1SDavid du Colombier v++;
5113e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] + v;
5123e12c5d1SDavid du Colombier }
5133e12c5d1SDavid du Colombier
5143e12c5d1SDavid du Colombier void
addxcc(ulong ir)5153e12c5d1SDavid du Colombier addxcc(ulong ir)
5163e12c5d1SDavid du Colombier {
5173e12c5d1SDavid du Colombier long r, v;
5183e12c5d1SDavid du Colombier int rd, rs1, rs2, b31rs1, b31op2, b31r;
5193e12c5d1SDavid du Colombier
5203e12c5d1SDavid du Colombier getrop23(ir);
5213e12c5d1SDavid du Colombier if(ir&IMMBIT) {
5223e12c5d1SDavid du Colombier ximm(v, ir);
5233e12c5d1SDavid du Colombier if(trace)
5243e12c5d1SDavid du Colombier itrace("addxcc\tr%d,#0x%x,r%d", rs1, v, rd);
5253e12c5d1SDavid du Colombier }
5263e12c5d1SDavid du Colombier else {
5273e12c5d1SDavid du Colombier v = reg.r[rs2];
5283e12c5d1SDavid du Colombier if(trace)
5293e12c5d1SDavid du Colombier itrace("addxcc\tr%d,r%d,r%d", rs1, rs2, rd);
5303e12c5d1SDavid du Colombier }
5313e12c5d1SDavid du Colombier if(reg.psr&PSR_c)
5323e12c5d1SDavid du Colombier v++;
5333e12c5d1SDavid du Colombier
5343e12c5d1SDavid du Colombier r = reg.r[rs1] + v;
5353e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
5363e12c5d1SDavid du Colombier if(r == 0)
5373e12c5d1SDavid du Colombier reg.psr |= PSR_z;
5383e12c5d1SDavid du Colombier if(r < 0)
5393e12c5d1SDavid du Colombier reg.psr |= PSR_n;
5403e12c5d1SDavid du Colombier
5413e12c5d1SDavid du Colombier b31rs1 = reg.r[rs1]>>31;
5423e12c5d1SDavid du Colombier b31op2 = v>>31;
5433e12c5d1SDavid du Colombier b31r = r>>31;
5443e12c5d1SDavid du Colombier if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r))
5453e12c5d1SDavid du Colombier reg.psr |= PSR_v;
5463e12c5d1SDavid du Colombier if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2)))
5473e12c5d1SDavid du Colombier reg.psr |= PSR_c;
5483e12c5d1SDavid du Colombier
5493e12c5d1SDavid du Colombier reg.r[rd] = r;
5503e12c5d1SDavid du Colombier }
5513e12c5d1SDavid du Colombier
5523e12c5d1SDavid du Colombier void
wry(ulong ir)5533e12c5d1SDavid du Colombier wry(ulong ir)
5543e12c5d1SDavid du Colombier {
5553e12c5d1SDavid du Colombier long v;
5563e12c5d1SDavid du Colombier int rd, rs1, rs2;
5573e12c5d1SDavid du Colombier
5583e12c5d1SDavid du Colombier getrop23(ir);
5593e12c5d1SDavid du Colombier if(rd != 0)
5603e12c5d1SDavid du Colombier undef(ir);
5613e12c5d1SDavid du Colombier if(ir&IMMBIT) {
5623e12c5d1SDavid du Colombier ximm(v, ir);
5633e12c5d1SDavid du Colombier if(trace)
5643e12c5d1SDavid du Colombier itrace("wry\tr%d,#0x%x,Y", rs1, v);
5653e12c5d1SDavid du Colombier }
5663e12c5d1SDavid du Colombier else {
5673e12c5d1SDavid du Colombier v = reg.r[rs2];
5683e12c5d1SDavid du Colombier if(trace)
5693e12c5d1SDavid du Colombier itrace("wry\tr%d,r%d,Y", rs1, rs2);
5703e12c5d1SDavid du Colombier }
5713e12c5d1SDavid du Colombier reg.Y = reg.r[rs1] + v;
5723e12c5d1SDavid du Colombier }
5733e12c5d1SDavid du Colombier
5743e12c5d1SDavid du Colombier void
rdy(ulong ir)5753e12c5d1SDavid du Colombier rdy(ulong ir)
5763e12c5d1SDavid du Colombier {
5773e12c5d1SDavid du Colombier int rd, rs1, rs2;
5783e12c5d1SDavid du Colombier
5793e12c5d1SDavid du Colombier getrop23(ir);
5803e12c5d1SDavid du Colombier USED(rs2);
5813e12c5d1SDavid du Colombier if(rs1 != 0)
5823e12c5d1SDavid du Colombier undef(ir);
5833e12c5d1SDavid du Colombier
5843e12c5d1SDavid du Colombier if(trace)
5853e12c5d1SDavid du Colombier itrace("rdy\tY,r%d", rd);
5863e12c5d1SDavid du Colombier
5873e12c5d1SDavid du Colombier reg.r[rd] = reg.Y;
5883e12c5d1SDavid du Colombier }
5893e12c5d1SDavid du Colombier
5903e12c5d1SDavid du Colombier void
and(ulong ir)5913e12c5d1SDavid du Colombier and(ulong ir)
5923e12c5d1SDavid du Colombier {
5933e12c5d1SDavid du Colombier long v;
5943e12c5d1SDavid du Colombier int rd, rs1, rs2;
5953e12c5d1SDavid du Colombier
5963e12c5d1SDavid du Colombier getrop23(ir);
5973e12c5d1SDavid du Colombier if(ir&IMMBIT) {
5983e12c5d1SDavid du Colombier ximm(v, ir);
5993e12c5d1SDavid du Colombier if(trace)
6003e12c5d1SDavid du Colombier itrace("and\tr%d,#0x%x,r%d", rs1, v, rd);
6013e12c5d1SDavid du Colombier }
6023e12c5d1SDavid du Colombier else {
6033e12c5d1SDavid du Colombier v = reg.r[rs2];
6043e12c5d1SDavid du Colombier if(trace)
6053e12c5d1SDavid du Colombier itrace("and\tr%d,r%d,r%d", rs1, rs2, rd);
6063e12c5d1SDavid du Colombier }
6073e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] & v;
6083e12c5d1SDavid du Colombier }
6093e12c5d1SDavid du Colombier
6103e12c5d1SDavid du Colombier void
andcc(ulong ir)6113e12c5d1SDavid du Colombier andcc(ulong ir)
6123e12c5d1SDavid du Colombier {
6133e12c5d1SDavid du Colombier long v, r;
6143e12c5d1SDavid du Colombier int rd, rs1, rs2;
6153e12c5d1SDavid du Colombier
6163e12c5d1SDavid du Colombier getrop23(ir);
6173e12c5d1SDavid du Colombier if(ir&IMMBIT) {
6183e12c5d1SDavid du Colombier ximm(v, ir);
6193e12c5d1SDavid du Colombier if(trace)
6203e12c5d1SDavid du Colombier itrace("andcc\tr%d,#0x%x,r%d", rs1, v, rd);
6213e12c5d1SDavid du Colombier }
6223e12c5d1SDavid du Colombier else {
6233e12c5d1SDavid du Colombier v = reg.r[rs2];
6243e12c5d1SDavid du Colombier if(trace)
6253e12c5d1SDavid du Colombier itrace("andcc\tr%d,r%d,r%d", rs1, rs2, rd);
6263e12c5d1SDavid du Colombier }
6273e12c5d1SDavid du Colombier r = reg.r[rs1] & v;
6283e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
6293e12c5d1SDavid du Colombier if(r == 0)
6303e12c5d1SDavid du Colombier reg.psr |= PSR_z;
6313e12c5d1SDavid du Colombier if(r < 0)
6323e12c5d1SDavid du Colombier reg.psr |= PSR_n;
6333e12c5d1SDavid du Colombier
6343e12c5d1SDavid du Colombier reg.r[rd] = r;
6353e12c5d1SDavid du Colombier }
6363e12c5d1SDavid du Colombier
6373e12c5d1SDavid du Colombier void
orcc(ulong ir)6383e12c5d1SDavid du Colombier orcc(ulong ir)
6393e12c5d1SDavid du Colombier {
6403e12c5d1SDavid du Colombier long v, r;
6413e12c5d1SDavid du Colombier int rd, rs1, rs2;
6423e12c5d1SDavid du Colombier
6433e12c5d1SDavid du Colombier getrop23(ir);
6443e12c5d1SDavid du Colombier if(ir&IMMBIT) {
6453e12c5d1SDavid du Colombier ximm(v, ir);
6463e12c5d1SDavid du Colombier if(trace)
6473e12c5d1SDavid du Colombier itrace("orcc\tr%d,#0x%x,r%d", rs1, v, rd);
6483e12c5d1SDavid du Colombier }
6493e12c5d1SDavid du Colombier else {
6503e12c5d1SDavid du Colombier v = reg.r[rs2];
6513e12c5d1SDavid du Colombier if(trace)
6523e12c5d1SDavid du Colombier itrace("orcc\tr%d,r%d,r%d", rs1, rs2, rd);
6533e12c5d1SDavid du Colombier }
6543e12c5d1SDavid du Colombier r = reg.r[rs1] | v;
6553e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
6563e12c5d1SDavid du Colombier if(r == 0)
6573e12c5d1SDavid du Colombier reg.psr |= PSR_z;
6583e12c5d1SDavid du Colombier if(r < 0)
6593e12c5d1SDavid du Colombier reg.psr |= PSR_n;
6603e12c5d1SDavid du Colombier
6613e12c5d1SDavid du Colombier reg.r[rd] = r;
6623e12c5d1SDavid du Colombier }
6633e12c5d1SDavid du Colombier
6643e12c5d1SDavid du Colombier void
mulscc(ulong ir)6653e12c5d1SDavid du Colombier mulscc(ulong ir)
6663e12c5d1SDavid du Colombier {
6673e12c5d1SDavid du Colombier int b, n, v, rd, rs1, rs2;
6683e12c5d1SDavid du Colombier long o1, o2, r, b31o1, b31o2, b31r;
6693e12c5d1SDavid du Colombier
6703e12c5d1SDavid du Colombier getrop23(ir);
6713e12c5d1SDavid du Colombier if(ir&IMMBIT) {
6723e12c5d1SDavid du Colombier ximm(o2, ir);
6733e12c5d1SDavid du Colombier if(trace)
6743e12c5d1SDavid du Colombier itrace("mulscc\tr%d,#0x%x,r%d", rs1, o2, rd);
6753e12c5d1SDavid du Colombier }
6763e12c5d1SDavid du Colombier else {
6773e12c5d1SDavid du Colombier o2 = reg.r[rs2];
6783e12c5d1SDavid du Colombier if(trace)
6793e12c5d1SDavid du Colombier itrace("mulscc\tr%d,r%d,r%d", rs1, rs2, rd);
6803e12c5d1SDavid du Colombier }
6813e12c5d1SDavid du Colombier o1 = reg.r[rs1]>>1;
6823e12c5d1SDavid du Colombier n = reg.psr&PSR_n ? 1 : 0;
6833e12c5d1SDavid du Colombier v = reg.psr&PSR_v ? 1 : 0;
6843e12c5d1SDavid du Colombier
6853e12c5d1SDavid du Colombier o1 |= (n ^ v)<<31;
6863e12c5d1SDavid du Colombier if((reg.Y&1) == 0)
6873e12c5d1SDavid du Colombier o2 = 0;
6883e12c5d1SDavid du Colombier
6893e12c5d1SDavid du Colombier r = o1 + o2;
6903e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
6913e12c5d1SDavid du Colombier if(r == 0)
6923e12c5d1SDavid du Colombier reg.psr |= PSR_z;
6933e12c5d1SDavid du Colombier if(r < 0)
6943e12c5d1SDavid du Colombier reg.psr |= PSR_n;
6953e12c5d1SDavid du Colombier
6963e12c5d1SDavid du Colombier b31o1 = o1>>31;
6973e12c5d1SDavid du Colombier b31o2 = o2>>31;
6983e12c5d1SDavid du Colombier b31r = r>>31;
6993e12c5d1SDavid du Colombier if((b31o1 & b31o2 & ~b31r) | (~b31o1 & ~b31o2 & b31r))
7003e12c5d1SDavid du Colombier reg.psr |= PSR_v;
7013e12c5d1SDavid du Colombier if((b31o1 & b31o2) | (~b31r & (b31o1 | b31o2)))
7023e12c5d1SDavid du Colombier reg.psr |= PSR_c;
7033e12c5d1SDavid du Colombier
7043e12c5d1SDavid du Colombier b = reg.r[rs1]&1;
7053e12c5d1SDavid du Colombier reg.Y = (reg.Y>>1)|(b<<31);
7063e12c5d1SDavid du Colombier reg.r[rd] = r;
7073e12c5d1SDavid du Colombier }
7083e12c5d1SDavid du Colombier
7093e12c5d1SDavid du Colombier void
or(ulong ir)7103e12c5d1SDavid du Colombier or(ulong ir)
7113e12c5d1SDavid du Colombier {
7123e12c5d1SDavid du Colombier long v;
7133e12c5d1SDavid du Colombier int rd, rs1, rs2;
7143e12c5d1SDavid du Colombier
7153e12c5d1SDavid du Colombier getrop23(ir);
7163e12c5d1SDavid du Colombier if(ir&IMMBIT) {
7173e12c5d1SDavid du Colombier ximm(v, ir);
7183e12c5d1SDavid du Colombier if(trace)
7193e12c5d1SDavid du Colombier itrace("or\tr%d,#0x%x,r%d", rs1, v, rd);
7203e12c5d1SDavid du Colombier }
7213e12c5d1SDavid du Colombier else {
7223e12c5d1SDavid du Colombier v = reg.r[rs2];
7233e12c5d1SDavid du Colombier if(trace)
7243e12c5d1SDavid du Colombier itrace("or\tr%d,r%d,r%d", rs1, rs2, rd);
7253e12c5d1SDavid du Colombier }
7263e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] | v;
7273e12c5d1SDavid du Colombier }
7283e12c5d1SDavid du Colombier
7293e12c5d1SDavid du Colombier void
xor(ulong ir)7303e12c5d1SDavid du Colombier xor(ulong ir)
7313e12c5d1SDavid du Colombier {
7323e12c5d1SDavid du Colombier long v;
7333e12c5d1SDavid du Colombier int rd, rs1, rs2;
7343e12c5d1SDavid du Colombier
7353e12c5d1SDavid du Colombier getrop23(ir);
7363e12c5d1SDavid du Colombier if(ir&IMMBIT) {
7373e12c5d1SDavid du Colombier ximm(v, ir);
7383e12c5d1SDavid du Colombier if(trace)
7393e12c5d1SDavid du Colombier itrace("xor\tr%d,#0x%x,r%d", rs1, v, rd);
7403e12c5d1SDavid du Colombier }
7413e12c5d1SDavid du Colombier else {
7423e12c5d1SDavid du Colombier v = reg.r[rs2];
7433e12c5d1SDavid du Colombier if(trace)
7443e12c5d1SDavid du Colombier itrace("xor\tr%d,r%d,r%d", rs1, rs2, rd);
7453e12c5d1SDavid du Colombier }
7463e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] ^ v;
7473e12c5d1SDavid du Colombier }
7483e12c5d1SDavid du Colombier
7493e12c5d1SDavid du Colombier void
xorcc(ulong ir)7503e12c5d1SDavid du Colombier xorcc(ulong ir)
7513e12c5d1SDavid du Colombier {
7523e12c5d1SDavid du Colombier long v, r;
7533e12c5d1SDavid du Colombier int rd, rs1, rs2;
7543e12c5d1SDavid du Colombier
7553e12c5d1SDavid du Colombier getrop23(ir);
7563e12c5d1SDavid du Colombier if(ir&IMMBIT) {
7573e12c5d1SDavid du Colombier ximm(v, ir);
7583e12c5d1SDavid du Colombier if(trace)
7593e12c5d1SDavid du Colombier itrace("xorcc\tr%d,#0x%x,r%d", rs1, v, rd);
7603e12c5d1SDavid du Colombier }
7613e12c5d1SDavid du Colombier else {
7623e12c5d1SDavid du Colombier v = reg.r[rs2];
7633e12c5d1SDavid du Colombier if(trace)
7643e12c5d1SDavid du Colombier itrace("xorcc\tr%d,r%d,r%d", rs1, rs2, rd);
7653e12c5d1SDavid du Colombier }
7663e12c5d1SDavid du Colombier r = reg.r[rs1] ^ v;
7673e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
7683e12c5d1SDavid du Colombier if(r == 0)
7693e12c5d1SDavid du Colombier reg.psr |= PSR_z;
7703e12c5d1SDavid du Colombier if(r < 0)
7713e12c5d1SDavid du Colombier reg.psr |= PSR_n;
7723e12c5d1SDavid du Colombier
7733e12c5d1SDavid du Colombier reg.r[rd] = r;
7743e12c5d1SDavid du Colombier }
7753e12c5d1SDavid du Colombier
7763e12c5d1SDavid du Colombier void
andn(ulong ir)7773e12c5d1SDavid du Colombier andn(ulong ir)
7783e12c5d1SDavid du Colombier {
7793e12c5d1SDavid du Colombier long v;
7803e12c5d1SDavid du Colombier int rd, rs1, rs2;
7813e12c5d1SDavid du Colombier
7823e12c5d1SDavid du Colombier getrop23(ir);
7833e12c5d1SDavid du Colombier if(ir&IMMBIT) {
7843e12c5d1SDavid du Colombier ximm(v, ir);
7853e12c5d1SDavid du Colombier if(trace)
7863e12c5d1SDavid du Colombier itrace("andn\tr%d,#0x%x,r%d", rs1, v, rd);
7873e12c5d1SDavid du Colombier }
7883e12c5d1SDavid du Colombier else {
7893e12c5d1SDavid du Colombier v = reg.r[rs2];
7903e12c5d1SDavid du Colombier if(trace)
7913e12c5d1SDavid du Colombier itrace("andn\tr%d,r%d,r%d", rs1, rs2, rd);
7923e12c5d1SDavid du Colombier }
7933e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] & ~v;
7943e12c5d1SDavid du Colombier }
7953e12c5d1SDavid du Colombier
7963e12c5d1SDavid du Colombier void
andncc(ulong ir)7973e12c5d1SDavid du Colombier andncc(ulong ir)
7983e12c5d1SDavid du Colombier {
7993e12c5d1SDavid du Colombier long v, r;
8003e12c5d1SDavid du Colombier int rd, rs1, rs2;
8013e12c5d1SDavid du Colombier
8023e12c5d1SDavid du Colombier getrop23(ir);
8033e12c5d1SDavid du Colombier if(ir&IMMBIT) {
8043e12c5d1SDavid du Colombier ximm(v, ir);
8053e12c5d1SDavid du Colombier if(trace)
8063e12c5d1SDavid du Colombier itrace("andncc\tr%d,#0x%x,r%d", rs1, v, rd);
8073e12c5d1SDavid du Colombier }
8083e12c5d1SDavid du Colombier else {
8093e12c5d1SDavid du Colombier v = reg.r[rs2];
8103e12c5d1SDavid du Colombier if(trace)
8113e12c5d1SDavid du Colombier itrace("andncc\tr%d,r%d,r%d", rs1, rs2, rd);
8123e12c5d1SDavid du Colombier }
8133e12c5d1SDavid du Colombier r = reg.r[rs1] & ~v;
8143e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
8153e12c5d1SDavid du Colombier if(r == 0)
8163e12c5d1SDavid du Colombier reg.psr |= PSR_z;
8173e12c5d1SDavid du Colombier if(r < 0)
8183e12c5d1SDavid du Colombier reg.psr |= PSR_n;
8193e12c5d1SDavid du Colombier
8203e12c5d1SDavid du Colombier reg.r[rd] = r;
8213e12c5d1SDavid du Colombier }
8223e12c5d1SDavid du Colombier
8233e12c5d1SDavid du Colombier void
orn(ulong ir)8243e12c5d1SDavid du Colombier orn(ulong ir)
8253e12c5d1SDavid du Colombier {
8263e12c5d1SDavid du Colombier long v;
8273e12c5d1SDavid du Colombier int rd, rs1, rs2;
8283e12c5d1SDavid du Colombier
8293e12c5d1SDavid du Colombier getrop23(ir);
8303e12c5d1SDavid du Colombier if(rd == 0 && rs1 == 0) /* ken used orn r0,r0,r0 as nop */
8313e12c5d1SDavid du Colombier nopcount++;
8323e12c5d1SDavid du Colombier
8333e12c5d1SDavid du Colombier if(ir&IMMBIT) {
8343e12c5d1SDavid du Colombier ximm(v, ir);
8353e12c5d1SDavid du Colombier if(trace)
8363e12c5d1SDavid du Colombier itrace("orn\tr%d,#0x%x,r%d", rs1, v, rd);
8373e12c5d1SDavid du Colombier }
8383e12c5d1SDavid du Colombier else {
8393e12c5d1SDavid du Colombier v = reg.r[rs2];
8403e12c5d1SDavid du Colombier if(trace)
8413e12c5d1SDavid du Colombier itrace("orn\tr%d,r%d,r%d", rs1, rs2, rd);
8423e12c5d1SDavid du Colombier }
8433e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] | ~v;
8443e12c5d1SDavid du Colombier }
8453e12c5d1SDavid du Colombier
8463e12c5d1SDavid du Colombier void
orncc(ulong ir)8473e12c5d1SDavid du Colombier orncc(ulong ir)
8483e12c5d1SDavid du Colombier {
8493e12c5d1SDavid du Colombier long r, v;
8503e12c5d1SDavid du Colombier int rd, rs1, rs2;
8513e12c5d1SDavid du Colombier
8523e12c5d1SDavid du Colombier getrop23(ir);
8533e12c5d1SDavid du Colombier if(ir&IMMBIT) {
8543e12c5d1SDavid du Colombier ximm(v, ir);
8553e12c5d1SDavid du Colombier if(trace)
8563e12c5d1SDavid du Colombier itrace("orncc\tr%d,#0x%x,r%d", rs1, v, rd);
8573e12c5d1SDavid du Colombier }
8583e12c5d1SDavid du Colombier else {
8593e12c5d1SDavid du Colombier v = reg.r[rs2];
8603e12c5d1SDavid du Colombier if(trace)
8613e12c5d1SDavid du Colombier itrace("orncc\tr%d,r%d,r%d", rs1, rs2, rd);
8623e12c5d1SDavid du Colombier }
8633e12c5d1SDavid du Colombier r = reg.r[rs1] | ~v;
8643e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
8653e12c5d1SDavid du Colombier if(r == 0)
8663e12c5d1SDavid du Colombier reg.psr |= PSR_z;
8673e12c5d1SDavid du Colombier if(r < 0)
8683e12c5d1SDavid du Colombier reg.psr |= PSR_n;
8693e12c5d1SDavid du Colombier
8703e12c5d1SDavid du Colombier reg.r[rd] = r;
8713e12c5d1SDavid du Colombier }
8723e12c5d1SDavid du Colombier
8733e12c5d1SDavid du Colombier void
xnor(ulong ir)8743e12c5d1SDavid du Colombier xnor(ulong ir)
8753e12c5d1SDavid du Colombier {
8763e12c5d1SDavid du Colombier long v;
8773e12c5d1SDavid du Colombier int rd, rs1, rs2;
8783e12c5d1SDavid du Colombier
8793e12c5d1SDavid du Colombier getrop23(ir);
8803e12c5d1SDavid du Colombier if(ir&IMMBIT) {
8813e12c5d1SDavid du Colombier ximm(v, ir);
8823e12c5d1SDavid du Colombier if(trace)
8833e12c5d1SDavid du Colombier itrace("xnor\tr%d,#0x%x,r%d", rs1, v, rd);
8843e12c5d1SDavid du Colombier }
8853e12c5d1SDavid du Colombier else {
8863e12c5d1SDavid du Colombier v = reg.r[rs2];
8873e12c5d1SDavid du Colombier if(trace)
8883e12c5d1SDavid du Colombier itrace("xnor\tr%d,r%d,r%d", rs1, rs2, rd);
8893e12c5d1SDavid du Colombier }
8903e12c5d1SDavid du Colombier reg.r[rd] = reg.r[rs1] ^ ~v;
8913e12c5d1SDavid du Colombier }
8923e12c5d1SDavid du Colombier
8933e12c5d1SDavid du Colombier void
xnorcc(ulong ir)8943e12c5d1SDavid du Colombier xnorcc(ulong ir)
8953e12c5d1SDavid du Colombier {
8963e12c5d1SDavid du Colombier long v, r;
8973e12c5d1SDavid du Colombier int rd, rs1, rs2;
8983e12c5d1SDavid du Colombier
8993e12c5d1SDavid du Colombier getrop23(ir);
9003e12c5d1SDavid du Colombier if(ir&IMMBIT) {
9013e12c5d1SDavid du Colombier ximm(v, ir);
9023e12c5d1SDavid du Colombier if(trace)
9033e12c5d1SDavid du Colombier itrace("xnorcc\tr%d,#0x%x,r%d", rs1, v, rd);
9043e12c5d1SDavid du Colombier }
9053e12c5d1SDavid du Colombier else {
9063e12c5d1SDavid du Colombier v = reg.r[rs2];
9073e12c5d1SDavid du Colombier if(trace)
9083e12c5d1SDavid du Colombier itrace("xnorcc\tr%d,r%d,r%d", rs1, rs2, rd);
9093e12c5d1SDavid du Colombier }
9103e12c5d1SDavid du Colombier r = reg.r[rs1] ^ ~v;
9113e12c5d1SDavid du Colombier reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
9123e12c5d1SDavid du Colombier if(r == 0)
9133e12c5d1SDavid du Colombier reg.psr |= PSR_z;
9143e12c5d1SDavid du Colombier if(r < 0)
9153e12c5d1SDavid du Colombier reg.psr |= PSR_n;
9163e12c5d1SDavid du Colombier
9173e12c5d1SDavid du Colombier reg.r[rd] = r;
9183e12c5d1SDavid du Colombier }
9193e12c5d1SDavid du Colombier
9203e12c5d1SDavid du Colombier void
st(ulong ir)9213e12c5d1SDavid du Colombier st(ulong ir)
9223e12c5d1SDavid du Colombier {
9233e12c5d1SDavid du Colombier ulong ea;
9243e12c5d1SDavid du Colombier int rd, rs1, rs2;
9253e12c5d1SDavid du Colombier
9263e12c5d1SDavid du Colombier getrop23(ir);
9273e12c5d1SDavid du Colombier if(ir&IMMBIT) {
9283e12c5d1SDavid du Colombier ximm(ea, ir);
9293e12c5d1SDavid du Colombier if(trace)
9303e12c5d1SDavid du Colombier itrace("st\tr%d,0x%lux(r%d) %lux=%lux",
9313e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]);
9323e12c5d1SDavid du Colombier ea += reg.r[rs1];
9333e12c5d1SDavid du Colombier }
9343e12c5d1SDavid du Colombier else {
9353e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
9363e12c5d1SDavid du Colombier if(trace)
9373e12c5d1SDavid du Colombier itrace("st\tr%d,[r%d+r%d] %lux=%lux",
9383e12c5d1SDavid du Colombier rd, rs1, rs2, ea, reg.r[rd]);
9393e12c5d1SDavid du Colombier }
9403e12c5d1SDavid du Colombier
9413e12c5d1SDavid du Colombier putmem_w(ea, reg.r[rd]);
9423e12c5d1SDavid du Colombier }
9433e12c5d1SDavid du Colombier
9443e12c5d1SDavid du Colombier void
std(ulong ir)9453e12c5d1SDavid du Colombier std(ulong ir)
9463e12c5d1SDavid du Colombier {
9473e12c5d1SDavid du Colombier ulong ea;
9483e12c5d1SDavid du Colombier int rd, rs1, rs2;
9493e12c5d1SDavid du Colombier
9503e12c5d1SDavid du Colombier getrop23(ir);
9513e12c5d1SDavid du Colombier if(ir&IMMBIT) {
9523e12c5d1SDavid du Colombier ximm(ea, ir);
9533e12c5d1SDavid du Colombier if(trace)
9543e12c5d1SDavid du Colombier itrace("std\tr%d,0x%lux(r%d) %lux=%lux",
9553e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]);
9563e12c5d1SDavid du Colombier ea += reg.r[rs1];
9573e12c5d1SDavid du Colombier }
9583e12c5d1SDavid du Colombier else {
9593e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
9603e12c5d1SDavid du Colombier if(trace)
9613e12c5d1SDavid du Colombier itrace("std\tr%d,[r%d+r%d] %lux=%lux",
9623e12c5d1SDavid du Colombier rd, rs1, rs2, ea, reg.r[rd]);
9633e12c5d1SDavid du Colombier }
9643e12c5d1SDavid du Colombier
9653e12c5d1SDavid du Colombier putmem_w(ea, reg.r[rd]);
9663e12c5d1SDavid du Colombier putmem_w(ea+4, reg.r[rd+1]);
9673e12c5d1SDavid du Colombier }
9683e12c5d1SDavid du Colombier
9693e12c5d1SDavid du Colombier void
stb(ulong ir)9703e12c5d1SDavid du Colombier stb(ulong ir)
9713e12c5d1SDavid du Colombier {
9723e12c5d1SDavid du Colombier ulong ea;
9733e12c5d1SDavid du Colombier int rd, rs1, rs2;
9743e12c5d1SDavid du Colombier
9753e12c5d1SDavid du Colombier getrop23(ir);
9763e12c5d1SDavid du Colombier if(ir&IMMBIT) {
9773e12c5d1SDavid du Colombier ximm(ea, ir);
9783e12c5d1SDavid du Colombier if(trace)
9793e12c5d1SDavid du Colombier itrace("stb\tr%d,0x%lux(r%d) %lux=%lux",
9803e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xff);
9813e12c5d1SDavid du Colombier ea += reg.r[rs1];
9823e12c5d1SDavid du Colombier }
9833e12c5d1SDavid du Colombier else {
9843e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
9853e12c5d1SDavid du Colombier if(trace)
9863e12c5d1SDavid du Colombier itrace("stb\tr%d,[r%d+r%d] %lux=%lux",
9873e12c5d1SDavid du Colombier rd, rs1, rs2, ea, reg.r[rd]&0xff);
9883e12c5d1SDavid du Colombier }
9893e12c5d1SDavid du Colombier
9903e12c5d1SDavid du Colombier putmem_b(ea, reg.r[rd]);
9913e12c5d1SDavid du Colombier }
9923e12c5d1SDavid du Colombier
9933e12c5d1SDavid du Colombier void
sth(ulong ir)9943e12c5d1SDavid du Colombier sth(ulong ir)
9953e12c5d1SDavid du Colombier {
9963e12c5d1SDavid du Colombier ulong ea;
9973e12c5d1SDavid du Colombier int rd, rs1, rs2;
9983e12c5d1SDavid du Colombier
9993e12c5d1SDavid du Colombier getrop23(ir);
10003e12c5d1SDavid du Colombier if(ir&IMMBIT) {
10013e12c5d1SDavid du Colombier ximm(ea, ir);
10023e12c5d1SDavid du Colombier if(trace)
10033e12c5d1SDavid du Colombier itrace("sth\tr%d,0x%lux(r%d) %lux=%lux",
10043e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xffff);
10053e12c5d1SDavid du Colombier ea += reg.r[rs1];
10063e12c5d1SDavid du Colombier }
10073e12c5d1SDavid du Colombier else {
10083e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
10093e12c5d1SDavid du Colombier if(trace)
10103e12c5d1SDavid du Colombier itrace("sth\tr%d,[r%d+r%d] %lux=%lux",
10113e12c5d1SDavid du Colombier rd, rs1, rs2, ea, reg.r[rd]&0xffff);
10123e12c5d1SDavid du Colombier }
10133e12c5d1SDavid du Colombier
10143e12c5d1SDavid du Colombier putmem_h(ea, reg.r[rd]);
10153e12c5d1SDavid du Colombier }
10163e12c5d1SDavid du Colombier
10173e12c5d1SDavid du Colombier void
ld(ulong ir)10183e12c5d1SDavid du Colombier ld(ulong ir)
10193e12c5d1SDavid du Colombier {
10203e12c5d1SDavid du Colombier ulong ea;
10213e12c5d1SDavid du Colombier int rd, rs1, rs2;
10223e12c5d1SDavid du Colombier
10233e12c5d1SDavid du Colombier getrop23(ir);
10243e12c5d1SDavid du Colombier if(ir&IMMBIT) {
10253e12c5d1SDavid du Colombier ximm(ea, ir);
10263e12c5d1SDavid du Colombier if(trace)
10273e12c5d1SDavid du Colombier itrace("ld\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
10283e12c5d1SDavid du Colombier ea += reg.r[rs1];
10293e12c5d1SDavid du Colombier }
10303e12c5d1SDavid du Colombier else {
10313e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
10323e12c5d1SDavid du Colombier if(trace)
10333e12c5d1SDavid du Colombier itrace("ld\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
10343e12c5d1SDavid du Colombier }
10353e12c5d1SDavid du Colombier
10363e12c5d1SDavid du Colombier reg.r[rd] = getmem_w(ea);
10373e12c5d1SDavid du Colombier ilock(rd);
10383e12c5d1SDavid du Colombier }
10393e12c5d1SDavid du Colombier
10403e12c5d1SDavid du Colombier void
swap(ulong ir)10413e12c5d1SDavid du Colombier swap(ulong ir)
10423e12c5d1SDavid du Colombier {
10433e12c5d1SDavid du Colombier ulong t, ea;
10443e12c5d1SDavid du Colombier int rd, rs1, rs2;
10453e12c5d1SDavid du Colombier
10463e12c5d1SDavid du Colombier getrop23(ir);
10473e12c5d1SDavid du Colombier if(ir&IMMBIT) {
10483e12c5d1SDavid du Colombier ximm(ea, ir);
10493e12c5d1SDavid du Colombier if(trace)
10503e12c5d1SDavid du Colombier itrace("swap\tr%d,0x%lux(r%d) ea=%lux",
10513e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1]);
10523e12c5d1SDavid du Colombier ea += reg.r[rs1];
10533e12c5d1SDavid du Colombier }
10543e12c5d1SDavid du Colombier else {
10553e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
10563e12c5d1SDavid du Colombier if(trace)
10573e12c5d1SDavid du Colombier itrace("swap\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
10583e12c5d1SDavid du Colombier }
10593e12c5d1SDavid du Colombier
10603e12c5d1SDavid du Colombier t = reg.r[rd];
10613e12c5d1SDavid du Colombier reg.r[rd] = getmem_w(ea);
10623e12c5d1SDavid du Colombier putmem_w(ea, t);
10633e12c5d1SDavid du Colombier }
10643e12c5d1SDavid du Colombier
10653e12c5d1SDavid du Colombier void
ldd(ulong ir)10663e12c5d1SDavid du Colombier ldd(ulong ir)
10673e12c5d1SDavid du Colombier {
10683e12c5d1SDavid du Colombier ulong ea;
10693e12c5d1SDavid du Colombier int rd, rs1, rs2;
10703e12c5d1SDavid du Colombier
10713e12c5d1SDavid du Colombier getrop23(ir);
10723e12c5d1SDavid du Colombier if(ir&IMMBIT) {
10733e12c5d1SDavid du Colombier ximm(ea, ir);
10743e12c5d1SDavid du Colombier if(trace)
10753e12c5d1SDavid du Colombier itrace("ldd\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
10763e12c5d1SDavid du Colombier ea += reg.r[rs1];
10773e12c5d1SDavid du Colombier }
10783e12c5d1SDavid du Colombier else {
10793e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
10803e12c5d1SDavid du Colombier if(trace)
10813e12c5d1SDavid du Colombier itrace("ldd\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
10823e12c5d1SDavid du Colombier }
10833e12c5d1SDavid du Colombier
10843e12c5d1SDavid du Colombier reg.r[rd] = getmem_w(ea);
10853e12c5d1SDavid du Colombier reg.r[rd+1] = getmem_w(ea+4);
10863e12c5d1SDavid du Colombier }
10873e12c5d1SDavid du Colombier
10883e12c5d1SDavid du Colombier void
ldub(ulong ir)10893e12c5d1SDavid du Colombier ldub(ulong ir)
10903e12c5d1SDavid du Colombier {
10913e12c5d1SDavid du Colombier ulong ea;
10923e12c5d1SDavid du Colombier int rd, rs1, rs2;
10933e12c5d1SDavid du Colombier
10943e12c5d1SDavid du Colombier getrop23(ir);
10953e12c5d1SDavid du Colombier if(ir&IMMBIT) {
10963e12c5d1SDavid du Colombier ximm(ea, ir);
10973e12c5d1SDavid du Colombier if(trace)
10983e12c5d1SDavid du Colombier itrace("ldub\tr%d,0x%lux(r%d) ea=%lux",
10993e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1]);
11003e12c5d1SDavid du Colombier ea += reg.r[rs1];
11013e12c5d1SDavid du Colombier }
11023e12c5d1SDavid du Colombier else {
11033e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
11043e12c5d1SDavid du Colombier if(trace)
11053e12c5d1SDavid du Colombier itrace("ldub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
11063e12c5d1SDavid du Colombier }
11073e12c5d1SDavid du Colombier
11083e12c5d1SDavid du Colombier reg.r[rd] = getmem_b(ea) & 0xff;
11093e12c5d1SDavid du Colombier ilock(rd);
11103e12c5d1SDavid du Colombier }
11113e12c5d1SDavid du Colombier
11123e12c5d1SDavid du Colombier void
ldstub(ulong ir)11133e12c5d1SDavid du Colombier ldstub(ulong ir)
11143e12c5d1SDavid du Colombier {
11153e12c5d1SDavid du Colombier ulong ea;
11163e12c5d1SDavid du Colombier int rd, rs1, rs2;
11173e12c5d1SDavid du Colombier
11183e12c5d1SDavid du Colombier getrop23(ir);
11193e12c5d1SDavid du Colombier if(ir&IMMBIT) {
11203e12c5d1SDavid du Colombier ximm(ea, ir);
11213e12c5d1SDavid du Colombier if(trace)
11223e12c5d1SDavid du Colombier itrace("ldstub\tr%d,0x%lux(r%d) ea=%lux",
11233e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1]);
11243e12c5d1SDavid du Colombier ea += reg.r[rs1];
11253e12c5d1SDavid du Colombier }
11263e12c5d1SDavid du Colombier else {
11273e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
11283e12c5d1SDavid du Colombier if(trace)
11293e12c5d1SDavid du Colombier itrace("ldstub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
11303e12c5d1SDavid du Colombier }
11313e12c5d1SDavid du Colombier
11323e12c5d1SDavid du Colombier reg.r[rd] = getmem_b(ea) & 0xff;
11333e12c5d1SDavid du Colombier putmem_b(ea, 0xff);
11343e12c5d1SDavid du Colombier }
11353e12c5d1SDavid du Colombier
11363e12c5d1SDavid du Colombier void
ldsb(ulong ir)11373e12c5d1SDavid du Colombier ldsb(ulong ir)
11383e12c5d1SDavid du Colombier {
11393e12c5d1SDavid du Colombier ulong ea;
11403e12c5d1SDavid du Colombier int rd, rs1, rs2;
11413e12c5d1SDavid du Colombier
11423e12c5d1SDavid du Colombier getrop23(ir);
11433e12c5d1SDavid du Colombier if(ir&IMMBIT) {
11443e12c5d1SDavid du Colombier ximm(ea, ir);
11453e12c5d1SDavid du Colombier if(trace)
11463e12c5d1SDavid du Colombier itrace("ldsb\tr%d,0x%lux(r%d) ea=%lux",
11473e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1]);
11483e12c5d1SDavid du Colombier ea += reg.r[rs1];
11493e12c5d1SDavid du Colombier }
11503e12c5d1SDavid du Colombier else {
11513e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
11523e12c5d1SDavid du Colombier if(trace)
11533e12c5d1SDavid du Colombier itrace("ldsb\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
11543e12c5d1SDavid du Colombier }
11553e12c5d1SDavid du Colombier
11563e12c5d1SDavid du Colombier reg.r[rd] = (schar)getmem_b(ea);
11573e12c5d1SDavid du Colombier ilock(rd);
11583e12c5d1SDavid du Colombier }
11593e12c5d1SDavid du Colombier
11603e12c5d1SDavid du Colombier void
lduh(ulong ir)11613e12c5d1SDavid du Colombier lduh(ulong ir)
11623e12c5d1SDavid du Colombier {
11633e12c5d1SDavid du Colombier ulong ea;
11643e12c5d1SDavid du Colombier int rd, rs1, rs2;
11653e12c5d1SDavid du Colombier
11663e12c5d1SDavid du Colombier getrop23(ir);
11673e12c5d1SDavid du Colombier if(ir&IMMBIT) {
11683e12c5d1SDavid du Colombier ximm(ea, ir);
11693e12c5d1SDavid du Colombier if(trace)
11703e12c5d1SDavid du Colombier itrace("lduh\tr%d,0x%lux(r%d) ea=%lux",
11713e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1]);
11723e12c5d1SDavid du Colombier ea += reg.r[rs1];
11733e12c5d1SDavid du Colombier }
11743e12c5d1SDavid du Colombier else {
11753e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
11763e12c5d1SDavid du Colombier if(trace)
11773e12c5d1SDavid du Colombier itrace("lduh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
11783e12c5d1SDavid du Colombier }
11793e12c5d1SDavid du Colombier
11803e12c5d1SDavid du Colombier reg.r[rd] = getmem_h(ea) & 0xffff;
11813e12c5d1SDavid du Colombier ilock(rd);
11823e12c5d1SDavid du Colombier }
11833e12c5d1SDavid du Colombier
11843e12c5d1SDavid du Colombier void
ldsh(ulong ir)11853e12c5d1SDavid du Colombier ldsh(ulong ir)
11863e12c5d1SDavid du Colombier {
11873e12c5d1SDavid du Colombier ulong ea;
11883e12c5d1SDavid du Colombier int rd, rs1, rs2;
11893e12c5d1SDavid du Colombier
11903e12c5d1SDavid du Colombier getrop23(ir);
11913e12c5d1SDavid du Colombier if(ir&IMMBIT) {
11923e12c5d1SDavid du Colombier ximm(ea, ir);
11933e12c5d1SDavid du Colombier if(trace)
11943e12c5d1SDavid du Colombier itrace("ldsh\tr%d,0x%lux(r%d) ea=%lux",
11953e12c5d1SDavid du Colombier rd, ea, rs1, ea+reg.r[rs1]);
11963e12c5d1SDavid du Colombier ea += reg.r[rs1];
11973e12c5d1SDavid du Colombier }
11983e12c5d1SDavid du Colombier else {
11993e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
12003e12c5d1SDavid du Colombier if(trace)
12013e12c5d1SDavid du Colombier itrace("ldsh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
12023e12c5d1SDavid du Colombier }
12033e12c5d1SDavid du Colombier
12043e12c5d1SDavid du Colombier reg.r[rd] = (short)getmem_h(ea);
12053e12c5d1SDavid du Colombier ilock(rd);
12063e12c5d1SDavid du Colombier }
12073e12c5d1SDavid du Colombier
12083e12c5d1SDavid du Colombier void
sethi(ulong ir)12093e12c5d1SDavid du Colombier sethi(ulong ir)
12103e12c5d1SDavid du Colombier {
12113e12c5d1SDavid du Colombier int rd;
12123e12c5d1SDavid du Colombier ulong v;
12133e12c5d1SDavid du Colombier
12143e12c5d1SDavid du Colombier rd = (ir>>25)&0x1f;
12153e12c5d1SDavid du Colombier v = (ir&0x3FFFFF)<<10;
12163e12c5d1SDavid du Colombier
12173e12c5d1SDavid du Colombier if(rd == 0)
12183e12c5d1SDavid du Colombier nopcount++;
12193e12c5d1SDavid du Colombier
12203e12c5d1SDavid du Colombier if(trace)
12213e12c5d1SDavid du Colombier itrace("sethi\t0x%lux,r%d", v, rd);
12223e12c5d1SDavid du Colombier
12233e12c5d1SDavid du Colombier reg.r[rd] = v;
12243e12c5d1SDavid du Colombier }
12253e12c5d1SDavid du Colombier
12263e12c5d1SDavid du Colombier void
call(ulong ir)12273e12c5d1SDavid du Colombier call(ulong ir)
12283e12c5d1SDavid du Colombier {
12293e12c5d1SDavid du Colombier Symbol s;
12303e12c5d1SDavid du Colombier ulong npc;
12313e12c5d1SDavid du Colombier
12323e12c5d1SDavid du Colombier npc = (ir<<2) + reg.pc;
12333e12c5d1SDavid du Colombier if(trace)
12343e12c5d1SDavid du Colombier itrace("call\t%lux", npc);
12353e12c5d1SDavid du Colombier
12363e12c5d1SDavid du Colombier ci->taken++;
12373e12c5d1SDavid du Colombier reg.r[15] = reg.pc;
12383e12c5d1SDavid du Colombier reg.ir = ifetch(reg.pc+4);
1239*bd389b36SDavid du Colombier delay(npc);
12403e12c5d1SDavid du Colombier
12413e12c5d1SDavid du Colombier if(calltree) {
12423e12c5d1SDavid du Colombier findsym(npc, CTEXT, &s);
12433e12c5d1SDavid du Colombier Bprint(bioout, "%8lux %s(", reg.pc, s.name);
12443e12c5d1SDavid du Colombier printparams(&s, reg.r[1]);
12453e12c5d1SDavid du Colombier Bprint(bioout, "from ");
12463e12c5d1SDavid du Colombier printsource(reg.pc);
12473e12c5d1SDavid du Colombier Bputc(bioout, '\n');
12483e12c5d1SDavid du Colombier }
12493e12c5d1SDavid du Colombier npc -= 4;
12503e12c5d1SDavid du Colombier reg.pc = npc;
12513e12c5d1SDavid du Colombier }
12523e12c5d1SDavid du Colombier
12533e12c5d1SDavid du Colombier void
jmpl(ulong ir)12543e12c5d1SDavid du Colombier jmpl(ulong ir)
12553e12c5d1SDavid du Colombier {
12563e12c5d1SDavid du Colombier ulong ea, o;
12573e12c5d1SDavid du Colombier Symbol s;
12583e12c5d1SDavid du Colombier int rd, rs1, rs2;
12593e12c5d1SDavid du Colombier
12603e12c5d1SDavid du Colombier getrop23(ir);
12613e12c5d1SDavid du Colombier if(ir&IMMBIT) {
12623e12c5d1SDavid du Colombier ximm(ea, ir);
12633e12c5d1SDavid du Colombier o = ea;
12643e12c5d1SDavid du Colombier if(trace)
12653e12c5d1SDavid du Colombier itrace("jmpl\t0x%lux(r%d),r%d", ea, rs1, rd);
12663e12c5d1SDavid du Colombier
12673e12c5d1SDavid du Colombier ea += reg.r[rs1];
12683e12c5d1SDavid du Colombier if(calltree && rd == 0 && o == 8) {
12693e12c5d1SDavid du Colombier findsym(ea-4, CTEXT, &s);
12703e12c5d1SDavid du Colombier Bprint(bioout, "%8lux return to %lux %s r7=%lux\n",
12713e12c5d1SDavid du Colombier reg.pc, ea-4, s.name, reg.r[7]);
12723e12c5d1SDavid du Colombier }
12733e12c5d1SDavid du Colombier }
12743e12c5d1SDavid du Colombier else {
12753e12c5d1SDavid du Colombier ea = reg.r[rs1] + reg.r[rs2];
12763e12c5d1SDavid du Colombier if(trace)
12773e12c5d1SDavid du Colombier itrace("jmpl\t[r%d+r%d],r%d", rs1, rs2, rd);
12783e12c5d1SDavid du Colombier }
12793e12c5d1SDavid du Colombier
12803e12c5d1SDavid du Colombier ci->taken++;
12813e12c5d1SDavid du Colombier reg.r[rd] = reg.pc;
12823e12c5d1SDavid du Colombier reg.ir = ifetch(reg.pc+4);
1283*bd389b36SDavid du Colombier delay(ea);
12843e12c5d1SDavid du Colombier reg.pc = ea-4;
12853e12c5d1SDavid du Colombier }
12863e12c5d1SDavid du Colombier
12873e12c5d1SDavid du Colombier void
bicc(ulong ir)12883e12c5d1SDavid du Colombier bicc(ulong ir)
12893e12c5d1SDavid du Colombier {
12903e12c5d1SDavid du Colombier char *op;
12913e12c5d1SDavid du Colombier ulong npc, anul, ba;
12923e12c5d1SDavid du Colombier int takeit, z, v, n, c;
12933e12c5d1SDavid du Colombier
12943e12c5d1SDavid du Colombier SET(op, takeit);
12953e12c5d1SDavid du Colombier ba = 0;
12963e12c5d1SDavid du Colombier switch((ir>>25)&0x0F) {
12973e12c5d1SDavid du Colombier case 0:
12983e12c5d1SDavid du Colombier op = "bn";
12993e12c5d1SDavid du Colombier takeit = 0;
13003e12c5d1SDavid du Colombier break;
13013e12c5d1SDavid du Colombier case 1:
13023e12c5d1SDavid du Colombier op = "be";
13033e12c5d1SDavid du Colombier takeit = reg.psr&PSR_z;
13043e12c5d1SDavid du Colombier break;
13053e12c5d1SDavid du Colombier case 2:
13063e12c5d1SDavid du Colombier op = "ble";
13073e12c5d1SDavid du Colombier z = reg.psr&PSR_z ? 1 : 0;
13083e12c5d1SDavid du Colombier v = reg.psr&PSR_v ? 1 : 0;
13093e12c5d1SDavid du Colombier n = reg.psr&PSR_n ? 1 : 0;
13103e12c5d1SDavid du Colombier takeit = z | (n ^ v);
13113e12c5d1SDavid du Colombier break;
13123e12c5d1SDavid du Colombier case 3:
13133e12c5d1SDavid du Colombier op = "bl";
13143e12c5d1SDavid du Colombier v = reg.psr&PSR_v ? 1 : 0;
13153e12c5d1SDavid du Colombier n = reg.psr&PSR_n ? 1 : 0;
13163e12c5d1SDavid du Colombier takeit = n ^ v;
13173e12c5d1SDavid du Colombier break;
13183e12c5d1SDavid du Colombier case 4:
13193e12c5d1SDavid du Colombier op = "bleu";
13203e12c5d1SDavid du Colombier z = reg.psr&PSR_z ? 1 : 0;
13213e12c5d1SDavid du Colombier c = reg.psr&PSR_c ? 1 : 0;
13223e12c5d1SDavid du Colombier takeit = c | z;
13233e12c5d1SDavid du Colombier break;
13243e12c5d1SDavid du Colombier case 5:
13253e12c5d1SDavid du Colombier op = "bcs";
13263e12c5d1SDavid du Colombier takeit = reg.psr&PSR_c;
13273e12c5d1SDavid du Colombier break;
13283e12c5d1SDavid du Colombier case 6:
13293e12c5d1SDavid du Colombier op = "bneg";
13303e12c5d1SDavid du Colombier takeit = reg.psr&PSR_n;
13313e12c5d1SDavid du Colombier break;
13323e12c5d1SDavid du Colombier case 7:
13333e12c5d1SDavid du Colombier op = "bvs";
13343e12c5d1SDavid du Colombier takeit = reg.psr&PSR_v;
13353e12c5d1SDavid du Colombier break;
13363e12c5d1SDavid du Colombier case 8:
13373e12c5d1SDavid du Colombier op = "ba";
13383e12c5d1SDavid du Colombier ba = 1;
13393e12c5d1SDavid du Colombier takeit = 1;
13403e12c5d1SDavid du Colombier break;
13413e12c5d1SDavid du Colombier case 9:
13423e12c5d1SDavid du Colombier op = "bne";
13433e12c5d1SDavid du Colombier takeit = !(reg.psr&PSR_z);
13443e12c5d1SDavid du Colombier break;
13453e12c5d1SDavid du Colombier case 10:
13463e12c5d1SDavid du Colombier op = "bg";
13473e12c5d1SDavid du Colombier z = reg.psr&PSR_z ? 1 : 0;
13483e12c5d1SDavid du Colombier v = reg.psr&PSR_v ? 1 : 0;
13493e12c5d1SDavid du Colombier n = reg.psr&PSR_n ? 1 : 0;
13503e12c5d1SDavid du Colombier takeit = !(z | (n ^ v));
13513e12c5d1SDavid du Colombier break;
13523e12c5d1SDavid du Colombier case 11:
13533e12c5d1SDavid du Colombier op = "bge";
13543e12c5d1SDavid du Colombier v = reg.psr&PSR_v ? 1 : 0;
13553e12c5d1SDavid du Colombier n = reg.psr&PSR_n ? 1 : 0;
13563e12c5d1SDavid du Colombier takeit = !(n ^ v);
13573e12c5d1SDavid du Colombier break;
13583e12c5d1SDavid du Colombier case 12:
13593e12c5d1SDavid du Colombier op = "bgu";
13603e12c5d1SDavid du Colombier z = reg.psr&PSR_z ? 1 : 0;
13613e12c5d1SDavid du Colombier c = reg.psr&PSR_c ? 1 : 0;
13623e12c5d1SDavid du Colombier takeit = !(c | z);
13633e12c5d1SDavid du Colombier break;
13643e12c5d1SDavid du Colombier case 13:
13653e12c5d1SDavid du Colombier op = "bcc";
13663e12c5d1SDavid du Colombier takeit = !(reg.psr&PSR_c);
13673e12c5d1SDavid du Colombier break;
13683e12c5d1SDavid du Colombier case 14:
13693e12c5d1SDavid du Colombier op = "bpos";
13703e12c5d1SDavid du Colombier takeit = !(reg.psr&PSR_n);
13713e12c5d1SDavid du Colombier break;
13723e12c5d1SDavid du Colombier case 15:
13733e12c5d1SDavid du Colombier op = "bvc";
13743e12c5d1SDavid du Colombier takeit = !(reg.psr&PSR_v);
13753e12c5d1SDavid du Colombier break;
13763e12c5d1SDavid du Colombier }
13773e12c5d1SDavid du Colombier
13783e12c5d1SDavid du Colombier npc = ir & 0x3FFFFF;
13793e12c5d1SDavid du Colombier if(npc & (1<<21))
13803e12c5d1SDavid du Colombier npc |= ~((1<<22)-1);
13813e12c5d1SDavid du Colombier npc = (npc<<2) + reg.pc;
13823e12c5d1SDavid du Colombier
13833e12c5d1SDavid du Colombier anul = ir&ANUL;
13843e12c5d1SDavid du Colombier if(trace) {
13853e12c5d1SDavid du Colombier if(anul)
13863e12c5d1SDavid du Colombier itrace("%s,a\t%lux", op, npc);
13873e12c5d1SDavid du Colombier else
13883e12c5d1SDavid du Colombier itrace("%s\t%lux", op, npc);
13893e12c5d1SDavid du Colombier }
13903e12c5d1SDavid du Colombier
13913e12c5d1SDavid du Colombier if(takeit == 0) {
13923e12c5d1SDavid du Colombier reg.pc += 4;
13933e12c5d1SDavid du Colombier if(anul == 0) {
13943e12c5d1SDavid du Colombier reg.ir = ifetch(reg.pc);
1395*bd389b36SDavid du Colombier delay(reg.pc+4);
13963e12c5d1SDavid du Colombier }
13973e12c5d1SDavid du Colombier else
13983e12c5d1SDavid du Colombier anulled++;
13993e12c5d1SDavid du Colombier return;
14003e12c5d1SDavid du Colombier }
14013e12c5d1SDavid du Colombier
14023e12c5d1SDavid du Colombier ci->taken++;
14033e12c5d1SDavid du Colombier if(ba && anul) {
14043e12c5d1SDavid du Colombier anulled++;
14053e12c5d1SDavid du Colombier reg.pc = npc-4;
14063e12c5d1SDavid du Colombier return;
14073e12c5d1SDavid du Colombier }
14083e12c5d1SDavid du Colombier reg.ir = ifetch(reg.pc+4);
1409*bd389b36SDavid du Colombier delay(npc);
14103e12c5d1SDavid du Colombier reg.pc = npc-4;
14113e12c5d1SDavid du Colombier }
1412