static unsigned dasmr3k(char *buffer, unsigned pc, UINT32 op) { int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; int shift = (op >> 6) & 31; UINT32 flags = 0; switch (op >> 26) { case 0x00: /* SPECIAL */ switch (op & 63) { case 0x00: if (op == 0) sprintf(buffer, "nop"); else sprintf(buffer, "sll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x02: sprintf(buffer, "srl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x03: sprintf(buffer, "sra %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x04: sprintf(buffer, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: sprintf(buffer, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: sprintf(buffer, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x08: sprintf(buffer, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; case 0x09: if (rd == 31) sprintf(buffer, "jalr %s", reg[rs]); else sprintf(buffer, "jalr %s,%s", reg[rs], reg[rd]); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x0c: sprintf(buffer, "syscall"); flags = DASMFLAG_STEP_OVER; break; case 0x0d: sprintf(buffer, "break"); flags = DASMFLAG_STEP_OVER; break; case 0x0f: sprintf(buffer, "sync [invalid]"); break; case 0x10: sprintf(buffer, "mfhi %s", reg[rd]); break; case 0x11: sprintf(buffer, "mthi %s", reg[rs]); break; case 0x12: sprintf(buffer, "mflo %s", reg[rd]); break; case 0x13: sprintf(buffer, "mtlo %s", reg[rs]); break; case 0x18: sprintf(buffer, "mult %s,%s", reg[rs], reg[rt]); break; case 0x19: sprintf(buffer, "multu %s,%s", reg[rs], reg[rt]); break; case 0x1a: sprintf(buffer, "div %s,%s", reg[rs], reg[rt]); break; case 0x1b: sprintf(buffer, "divu %s,%s", reg[rs], reg[rt]); break; case 0x20: sprintf(buffer, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x21: sprintf(buffer, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x22: sprintf(buffer, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x23: sprintf(buffer, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x24: sprintf(buffer, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x25: sprintf(buffer, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x26: sprintf(buffer, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x27: sprintf(buffer, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2a: sprintf(buffer, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2b: sprintf(buffer, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x30: sprintf(buffer, "teq [invalid]"); break; case 0x31: sprintf(buffer, "tgeu [invalid]"); break; case 0x32: sprintf(buffer, "tlt [invalid]"); break; case 0x33: sprintf(buffer, "tltu [invalid]"); break; case 0x34: sprintf(buffer, "tge [invalid]"); break; case 0x36: sprintf(buffer, "tne [invalid]"); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x01: /* REGIMM */ switch ((op >> 16) & 31) { case 0x00: sprintf(buffer, "bltz %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x01: sprintf(buffer, "bgez %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x02: sprintf(buffer, "bltzl [invalid]"); break; case 0x03: sprintf(buffer, "bgezl [invalid]"); break; case 0x08: sprintf(buffer, "tgei [invalid]"); break; case 0x09: sprintf(buffer, "tgeiu [invalid]"); break; case 0x0a: sprintf(buffer, "tlti [invalid]"); break; case 0x0b: sprintf(buffer, "tltiu [invalid]"); break; case 0x0c: sprintf(buffer, "teqi [invalid]"); break; case 0x0e: sprintf(buffer, "tnei [invalid]"); break; case 0x10: sprintf(buffer, "bltzal %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x11: sprintf(buffer, "bgezal %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x12: sprintf(buffer, "bltzall [invalid]"); break; case 0x13: sprintf(buffer, "bgezall [invalid]"); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x02: sprintf(buffer, "j $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break; case 0x03: sprintf(buffer, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x04: if (rs == 0 && rt == 0) sprintf(buffer, "b $%08x", pc + 4 + ((INT16)op << 2)); else sprintf(buffer, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x05: sprintf(buffer, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x06: sprintf(buffer, "blez %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x07: sprintf(buffer, "bgtz %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x08: sprintf(buffer, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x09: sprintf(buffer, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0a: sprintf(buffer, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0b: sprintf(buffer, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0c: sprintf(buffer, "andi %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break; case 0x0d: sprintf(buffer, "ori %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break; case 0x0e: sprintf(buffer, "xori %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break; case 0x0f: sprintf(buffer, "lui %s,$%04x", reg[rt], (UINT16)op); break; case 0x10: flags = dasm_cop(pc, 0, op, buffer); break; case 0x11: flags = dasm_cop1(pc, op, buffer); break; case 0x12: flags = dasm_cop(pc, 2, op, buffer); break; case 0x13: flags = dasm_cop(pc, 3, op, buffer); break; case 0x14: sprintf(buffer, "beql [invalid]"); break; case 0x15: sprintf(buffer, "bnel [invalid]"); break; case 0x16: sprintf(buffer, "blezl [invalid]"); break; case 0x17: sprintf(buffer, "bgtzl [invalid]"); break; case 0x20: sprintf(buffer, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x21: sprintf(buffer, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x22: sprintf(buffer, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x23: sprintf(buffer, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x24: sprintf(buffer, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x25: sprintf(buffer, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x26: sprintf(buffer, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x28: sprintf(buffer, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x29: sprintf(buffer, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2a: sprintf(buffer, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2b: sprintf(buffer, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2e: sprintf(buffer, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2f: sprintf(buffer, "cache [invalid]"); break; case 0x30: sprintf(buffer, "ll [invalid]"); break; case 0x31: sprintf(buffer, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x32: sprintf(buffer, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x33: sprintf(buffer, "lwc3 %s,%s(%s)", cpreg[3][rt], signed_16bit(op), reg[rs]); break; case 0x34: sprintf(buffer, "ldc0 [invalid]"); break; case 0x35: sprintf(buffer, "ldc1 [invalid]"); break; case 0x36: sprintf(buffer, "ldc2 [invalid]"); break; case 0x37: sprintf(buffer, "ldc3 [invalid]"); break; case 0x38: sprintf(buffer, "sc [invalid]"); break; case 0x39: sprintf(buffer, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x3a: sprintf(buffer, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x3b: sprintf(buffer, "swc3 %s,%s(%s)", cpreg[3][rt], signed_16bit(op), reg[rs]); break; case 0x3c: sprintf(buffer, "sdc0 [invalid]"); break; case 0x3d: sprintf(buffer, "sdc1 [invalid]"); break; case 0x3e: sprintf(buffer, "sdc2 [invalid]"); break; case 0x3f: sprintf(buffer, "sdc3 [invalid]"); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } return 4 | flags | DASMFLAG_SUPPORTED; }
unsigned dasmmips3(char *buffer, unsigned pc) { UINT32 op = ROPCODE(pc); int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; int shift = (op >> 6) & 31; switch (op >> 26) { case 0x00: /* SPECIAL */ switch (op & 63) { case 0x00: if (op == 0) sprintf(buffer, "nop"); else sprintf(buffer, "sll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x01: sprintf(buffer, "mov%c %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', reg[rd], reg[rt], (op >> 18) & 7); break; case 0x02: sprintf(buffer, "srl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x03: sprintf(buffer, "sra %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x04: sprintf(buffer, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: sprintf(buffer, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: sprintf(buffer, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x08: sprintf(buffer, "jr %s", reg[rs]); break; case 0x09: if (rd == 31) sprintf(buffer, "jalr %s", reg[rs]); else sprintf(buffer, "jalr %s,%s", reg[rs], reg[rd]); break; case 0x0a: sprintf(buffer, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x0b: sprintf(buffer, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x0c: sprintf(buffer, "syscall"); break; case 0x0d: sprintf(buffer, "break"); break; case 0x0f: sprintf(buffer, "sync"); break; case 0x10: sprintf(buffer, "mfhi %s", reg[rd]); break; case 0x11: sprintf(buffer, "mthi %s", reg[rs]); break; case 0x12: sprintf(buffer, "mflo %s", reg[rd]); break; case 0x13: sprintf(buffer, "mtlo %s", reg[rs]); break; case 0x14: sprintf(buffer, "dsllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x16: sprintf(buffer, "dsrlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x17: sprintf(buffer, "dsrav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x18: sprintf(buffer, "mult %s,%s", reg[rs], reg[rt]); break; case 0x19: sprintf(buffer, "multu %s,%s", reg[rs], reg[rt]); break; case 0x1a: sprintf(buffer, "div %s,%s", reg[rs], reg[rt]); break; case 0x1b: sprintf(buffer, "divu %s,%s", reg[rs], reg[rt]); break; case 0x1c: sprintf(buffer, "dmult %s,%s", reg[rs], reg[rt]); break; case 0x1d: sprintf(buffer, "dmultu %s,%s", reg[rs], reg[rt]); break; case 0x1e: sprintf(buffer, "ddiv %s,%s", reg[rs], reg[rt]); break; case 0x1f: sprintf(buffer, "ddivu %s,%s", reg[rs], reg[rt]); break; case 0x20: sprintf(buffer, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x21: sprintf(buffer, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x22: sprintf(buffer, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x23: sprintf(buffer, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x24: sprintf(buffer, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x25: sprintf(buffer, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x26: sprintf(buffer, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x27: sprintf(buffer, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2a: sprintf(buffer, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2b: sprintf(buffer, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2c: sprintf(buffer, "dadd %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2d: sprintf(buffer, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2e: sprintf(buffer, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2f: sprintf(buffer, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x30: sprintf(buffer, "tge %s,%s", reg[rs], reg[rt]); break; case 0x31: sprintf(buffer, "tgeu %s,%s", reg[rs], reg[rt]); break; case 0x32: sprintf(buffer, "tlt %s,%s", reg[rs], reg[rt]); break; case 0x33: sprintf(buffer, "tltu %s,%s", reg[rs], reg[rt]); break; case 0x34: sprintf(buffer, "teq %s,%s", reg[rs], reg[rt]); break; case 0x36: sprintf(buffer, "tne %s,%s", reg[rs], reg[rt]); break; case 0x38: sprintf(buffer, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3a: sprintf(buffer, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3b: sprintf(buffer, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3c: sprintf(buffer, "dsll %s,%s,%d", reg[rd], reg[rt], shift+32); break; case 0x3e: sprintf(buffer, "dsrl %s,%s,%d", reg[rd], reg[rt], shift+32); break; case 0x3f: sprintf(buffer, "dsra %s,%s,%d", reg[rd], reg[rt], shift+32); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x01: /* REGIMM */ switch ((op >> 16) & 31) { case 0x00: sprintf(buffer, "bltz %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x01: sprintf(buffer, "bgez %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x02: sprintf(buffer, "bltzl %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x03: sprintf(buffer, "bgezl %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x08: sprintf(buffer, "tgei %s,%s", reg[rs], signed_16bit(op)); break; case 0x09: sprintf(buffer, "tgeiu %s,%s", reg[rs], signed_16bit(op)); break; case 0x0a: sprintf(buffer, "tlti %s,%s", reg[rs], signed_16bit(op)); break; case 0x0b: sprintf(buffer, "tltiu %s,%s", reg[rs], signed_16bit(op)); break; case 0x0c: sprintf(buffer, "teqi %s,%s", reg[rs], signed_16bit(op)); break; case 0x0e: sprintf(buffer, "tnei %s,%s", reg[rs], signed_16bit(op)); break; case 0x10: sprintf(buffer, "bltzal %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x11: sprintf(buffer, "bgezal %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x12: sprintf(buffer, "bltzall %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2));break; case 0x13: sprintf(buffer, "bgezall %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2));break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x02: sprintf(buffer, "j $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break; case 0x03: sprintf(buffer, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break; case 0x04: if (rs == 0 && rt == 0) sprintf(buffer, "b $%08x", pc + 4 + ((INT16)op << 2)); else sprintf(buffer, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x05: sprintf(buffer, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x06: sprintf(buffer, "blez %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x07: sprintf(buffer, "bgtz %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x08: sprintf(buffer, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x09: sprintf(buffer, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0a: sprintf(buffer, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0b: sprintf(buffer, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0c: sprintf(buffer, "andi %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break; case 0x0d: sprintf(buffer, "ori %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break; case 0x0e: sprintf(buffer, "xori %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break; case 0x0f: sprintf(buffer, "lui %s,$%04x", reg[rt], (UINT16)op); break; case 0x10: dasm_cop0(pc, op, buffer); break; case 0x11: dasm_cop1(pc, op, buffer); break; case 0x12: dasm_cop2(pc, op, buffer); break; case 0x13: dasm_cop1x(pc, op, buffer); break; case 0x14: sprintf(buffer, "beql %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x15: sprintf(buffer, "bnel %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x16: sprintf(buffer, "blezl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x17: sprintf(buffer, "bgtzl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break; case 0x18: sprintf(buffer, "daddi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x19: sprintf(buffer, "daddiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x1a: sprintf(buffer, "ldl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x1b: sprintf(buffer, "ldr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x20: sprintf(buffer, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x21: sprintf(buffer, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x22: sprintf(buffer, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x23: sprintf(buffer, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x24: sprintf(buffer, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x25: sprintf(buffer, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x26: sprintf(buffer, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x27: sprintf(buffer, "lwu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x28: sprintf(buffer, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x29: sprintf(buffer, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2a: sprintf(buffer, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2b: sprintf(buffer, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2c: sprintf(buffer, "sdl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2d: sprintf(buffer, "sdr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2e: sprintf(buffer, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2f: sprintf(buffer, "cache %s(%s)", reg[rs], signed_16bit(op)); break; case 0x30: sprintf(buffer, "ll %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x31: sprintf(buffer, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x32: sprintf(buffer, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x33: sprintf(buffer, "pref $%x,%s(%s)", rt, signed_16bit(op), reg[rs]); break; case 0x34: sprintf(buffer, "lld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x35: sprintf(buffer, "ldc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x36: sprintf(buffer, "ldc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x37: sprintf(buffer, "ld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x38: sprintf(buffer, "sc %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x39: sprintf(buffer, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x3a: sprintf(buffer, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x3c: sprintf(buffer, "scd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x3d: sprintf(buffer, "sdc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x3e: sprintf(buffer, "sdc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x3f: sprintf(buffer, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } return 4; }
unsigned dasmmips3(char *buffer, unsigned pc, uint32_t op) { int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; int shift = (op >> 6) & 31; uint32_t flags = 0; switch (op >> 26) { case 0x00: /* SPECIAL */ switch (op & 63) { case 0x00: if (op == 0) sprintf(buffer, "nop"); else sprintf(buffer, "sll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x01: sprintf(buffer, "mov%c %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', reg[rd], reg[rs], (op >> 18) & 7); break; case 0x02: sprintf(buffer, "srl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x03: sprintf(buffer, "sra %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x04: sprintf(buffer, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: sprintf(buffer, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: sprintf(buffer, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x08: sprintf(buffer, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; case 0x09: if (rd == 31) sprintf(buffer, "jalr %s", reg[rs]); else sprintf(buffer, "jalr %s,%s", reg[rs], reg[rd]); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x0a: sprintf(buffer, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x0b: sprintf(buffer, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x0c: sprintf(buffer, "syscall"); flags = DASMFLAG_STEP_OVER; break; case 0x0d: sprintf(buffer, "break"); flags = DASMFLAG_STEP_OVER; break; case 0x0f: sprintf(buffer, "sync"); break; case 0x10: sprintf(buffer, "mfhi %s", reg[rd]); break; case 0x11: sprintf(buffer, "mthi %s", reg[rs]); break; case 0x12: sprintf(buffer, "mflo %s", reg[rd]); break; case 0x13: sprintf(buffer, "mtlo %s", reg[rs]); break; case 0x14: sprintf(buffer, "dsllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x16: sprintf(buffer, "dsrlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x17: sprintf(buffer, "dsrav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x18: sprintf(buffer, "mult %s,%s", reg[rs], reg[rt]); break; case 0x19: sprintf(buffer, "multu %s,%s", reg[rs], reg[rt]); break; case 0x1a: sprintf(buffer, "div %s,%s", reg[rs], reg[rt]); break; case 0x1b: sprintf(buffer, "divu %s,%s", reg[rs], reg[rt]); break; case 0x1c: sprintf(buffer, "dmult %s,%s", reg[rs], reg[rt]); break; case 0x1d: sprintf(buffer, "dmultu %s,%s", reg[rs], reg[rt]); break; case 0x1e: sprintf(buffer, "ddiv %s,%s", reg[rs], reg[rt]); break; case 0x1f: sprintf(buffer, "ddivu %s,%s", reg[rs], reg[rt]); break; case 0x20: sprintf(buffer, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x21: sprintf(buffer, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x22: sprintf(buffer, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x23: sprintf(buffer, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x24: sprintf(buffer, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x25: sprintf(buffer, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x26: sprintf(buffer, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x27: sprintf(buffer, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2a: sprintf(buffer, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2b: sprintf(buffer, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2c: sprintf(buffer, "dadd %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2d: sprintf(buffer, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2e: sprintf(buffer, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2f: sprintf(buffer, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x30: sprintf(buffer, "tge %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; case 0x31: sprintf(buffer, "tgeu %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; case 0x32: sprintf(buffer, "tlt %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; case 0x33: sprintf(buffer, "tltu %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; case 0x34: sprintf(buffer, "teq %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; case 0x36: sprintf(buffer, "tne %s,%s", reg[rs], reg[rt]) ;flags = DASMFLAG_STEP_OVER; break; case 0x38: sprintf(buffer, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3a: sprintf(buffer, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3b: sprintf(buffer, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3c: sprintf(buffer, "dsll %s,%s,%d", reg[rd], reg[rt], shift+32); break; case 0x3e: sprintf(buffer, "dsrl %s,%s,%d", reg[rd], reg[rt], shift+32); break; case 0x3f: sprintf(buffer, "dsra %s,%s,%d", reg[rd], reg[rt], shift+32); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x01: /* REGIMM */ switch ((op >> 16) & 31) { case 0x00: sprintf(buffer, "bltz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x01: sprintf(buffer, "bgez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x02: sprintf(buffer, "bltzl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x03: sprintf(buffer, "bgezl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x08: sprintf(buffer, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; case 0x09: sprintf(buffer, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; case 0x0a: sprintf(buffer, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; case 0x0b: sprintf(buffer, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; case 0x0c: sprintf(buffer, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; case 0x0e: sprintf(buffer, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; case 0x10: sprintf(buffer, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x11: sprintf(buffer, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x12: sprintf(buffer, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x13: sprintf(buffer, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x02: sprintf(buffer, "j $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); break; case 0x03: sprintf(buffer, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; case 0x04: if (rs == 0 && rt == 0) sprintf(buffer, "b $%08x", pc + 4 + ((int16_t)op << 2)); else sprintf(buffer, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2)); break; case 0x05: sprintf(buffer, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break; case 0x06: sprintf(buffer, "blez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x07: sprintf(buffer, "bgtz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x08: sprintf(buffer, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x09: sprintf(buffer, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0a: sprintf(buffer, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0b: sprintf(buffer, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x0c: sprintf(buffer, "andi %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break; case 0x0d: sprintf(buffer, "ori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break; case 0x0e: sprintf(buffer, "xori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break; case 0x0f: sprintf(buffer, "lui %s,$%04x", reg[rt], (uint16_t)op); break; case 0x10: flags = dasm_cop0(pc, op, buffer); break; case 0x11: flags = dasm_cop1(pc, op, buffer); break; case 0x12: flags = dasm_cop2(pc, op, buffer); break; case 0x13: flags = dasm_cop1x(pc, op, buffer); break; case 0x14: sprintf(buffer, "beql %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break; case 0x15: sprintf(buffer, "bnel %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break; case 0x16: sprintf(buffer, "blezl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break; case 0x17: sprintf(buffer, "bgtzl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break; case 0x18: sprintf(buffer, "daddi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x19: sprintf(buffer, "daddiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break; case 0x1a: sprintf(buffer, "ldl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x1b: sprintf(buffer, "ldr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x1c: /* IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 */ switch (op & 0x1f) { case 0: sprintf(buffer, "mad %s,%s", reg[rs], reg[rt]); break; case 1: sprintf(buffer, "madu %s,%s", reg[rs], reg[rt]); break; case 2: sprintf(buffer, "mul %s,%s,%s", reg[rs], reg[rt], reg[rd]); break; case 4: sprintf(buffer, "msub %s,%s", reg[rs], reg[rt]); break; default:sprintf(buffer, "dc.l $%08x [invalid]", op); break; } break; case 0x20: sprintf(buffer, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x21: sprintf(buffer, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x22: sprintf(buffer, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x23: sprintf(buffer, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x24: sprintf(buffer, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x25: sprintf(buffer, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x26: sprintf(buffer, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x27: sprintf(buffer, "lwu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x28: sprintf(buffer, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x29: sprintf(buffer, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2a: sprintf(buffer, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2b: sprintf(buffer, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2c: sprintf(buffer, "sdl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2d: sprintf(buffer, "sdr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2e: sprintf(buffer, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x2f: sprintf(buffer, "cache %s,%s(%s)", cacheop[rt], reg[rs], signed_16bit(op)); break; case 0x30: sprintf(buffer, "ll %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x31: sprintf(buffer, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x32: sprintf(buffer, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x33: sprintf(buffer, "pref $%x,%s(%s)", rt, signed_16bit(op), reg[rs]); break; case 0x34: sprintf(buffer, "lld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x35: sprintf(buffer, "ldc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x36: sprintf(buffer, "ldc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x37: sprintf(buffer, "ld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x38: sprintf(buffer, "sc %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x39: sprintf(buffer, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x3a: sprintf(buffer, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x3c: sprintf(buffer, "scd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; case 0x3d: sprintf(buffer, "sdc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break; case 0x3e: sprintf(buffer, "sdc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break; case 0x3f: sprintf(buffer, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; default: sprintf(buffer, "dc.l $%08x [invalid]", op); break; } return 4 | flags | DASMFLAG_SUPPORTED; }