static void disasm_swc2(UINT32 op) { int dest = (op >> 16) & 0x1f; int base = (op >> 21) & 0x1f; int del = (op >> 7) & 0xf; int offset = (op & 0x7f); if (offset & 0x40) offset |= 0xffffff80; switch ((op >> 11) & 0x1f) { case 0x00: print("sbv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 1), reg[base]); break; case 0x01: print("ssv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 2), reg[base]); break; case 0x02: print("slv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 4), reg[base]); break; case 0x03: print("sdv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 8), reg[base]); break; case 0x04: print("sqv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x05: print("srv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x06: print("spv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 8), reg[base]); break; case 0x07: print("suv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 8), reg[base]); break; case 0x08: print("shv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x09: print("sfv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x0a: print("swv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x0b: print("stv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; default: print("??? (SWC2)"); break; } }
offs_t rsp_dasm_one(char *buffer, offs_t 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; output = buffer; switch (op >> 26) { case 0x00: // SPECIAL { switch (op & 0x3f) { case 0x00: { if (op == 0) { print("nop"); } else { print("sll %s, %s, %d", reg[rd], reg[rt], shift); } break; } case 0x02: print("srl %s, %s, %d", reg[rd], reg[rt], shift); break; case 0x03: print("sra %s, %s, %d", reg[rd], reg[rt], shift); break; case 0x04: print("sllv %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x06: print("srlv %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x07: print("srav %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x08: print("jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; case 0x09: { if (rd == 31) { print("jalr %s", reg[rs]); } else { print("jalr %s, %s", reg[rs], reg[rd]); } flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; } case 0x0d: print("break"); flags = DASMFLAG_STEP_OVER; break; case 0x20: print("add %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x21: print("addu %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x22: print("sub %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x23: print("subu %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x24: print("and %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x25: print("or %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x26: print("xor %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x27: print("nor %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x2a: print("slt %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x2b: print("sltu %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; default: print("???"); break; } break; } case 0x01: // REGIMM { switch ((op >> 16) & 0x1f) { case 0x00: print("bltz %s, $%08X", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x01: print("bgez %s, $%08X", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x10: print("bltzal %s, $%08X", reg[rs], pc + 4 + ((INT16)op << 2)); break; case 0x11: print("bgezal %s, $%08X", reg[rs], pc + 4 + ((INT16)op << 2)); break; default: print("???"); break; } break; } case 0x02: print("j $%08X", (op & 0x03ffffff) << 2); break; case 0x03: print("jal $%08X", (op & 0x03ffffff) << 2); break; case 0x04: print("beq %s, %s, $%08X", reg[rs], reg[rt], pc + 4 + ((INT16)(op) << 2)); break; case 0x05: print("bne %s, %s, $%08X", reg[rs], reg[rt], pc + 4 + ((INT16)(op) << 2)); break; case 0x06: print("blez %s, $%08X", reg[rs], pc + 4 + ((INT16)(op) << 2)); break; case 0x07: print("bgtz %s, $%08X", reg[rs], pc + 4 + ((INT16)(op) << 2)); break; case 0x08: print("addi %s, %s, %s", reg[rt], reg[rs], signed_imm16(op)); break; case 0x09: print("addiu %s, %s, %s", reg[rt], reg[rs], signed_imm16(op)); break; case 0x0a: print("slti %s, %s, %s", reg[rt], reg[rs], signed_imm16(op)); break; case 0x0b: print("sltiu %s, %s, %s", reg[rt], reg[rs], signed_imm16(op)); break; case 0x0c: print("andi %s, %s, $%04X", reg[rt], reg[rs], (UINT16)(op)); break; case 0x0d: print("ori %s, %s, $%04X", reg[rt], reg[rs], (UINT16)(op)); break; case 0x0e: print("xori %s, %s, $%04X", reg[rt], reg[rs], (UINT16)(op)); break; case 0x0f: print("lui %s, %s, $%04X", reg[rt], reg[rs], (UINT16)(op)); break; case 0x10: disasm_cop0(op); break; case 0x12: disasm_cop2(op); break; case 0x20: print("lb %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x21: print("lh %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x23: print("lw %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x24: print("lbu %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x25: print("lhu %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x28: print("sb %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x29: print("sh %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x2b: print("sw %s, %s(%s)", reg[rt], signed_imm16(op), reg[rs]); break; case 0x32: disasm_lwc2(op); break; case 0x3a: disasm_swc2(op); break; default: print("???"); break; } return 4 | flags | DASMFLAG_SUPPORTED; }
static void disasm_lwc2(uint32_t op) { int dest = (op >> 16) & 0x1f; int base = (op >> 21) & 0x1f; int del = (op >> 7) & 0xf; int offset = (op & 0x7f); if (offset & 0x40) offset |= 0xffffff80; switch ((op >> 11) & 0x1f) { case 0x00: print("lbv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 1), reg[base]); break; case 0x01: print("lsv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 2), reg[base]); break; case 0x02: print("llv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 4), reg[base]); break; case 0x03: print("ldv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 8), reg[base]); break; case 0x04: print("lqv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x05: print("lrv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x06: print("lpv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 8), reg[base]); break; case 0x07: print("luv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 8), reg[base]); break; case 0x08: print("lhv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x09: print("lfv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x0a: print("lwv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; case 0x0b: print("ltv %s[%d], %s(%s)", vreg[dest], del, signed_imm16(offset * 16), reg[base]); break; default: print("??? (LWC2)"); break; } }