void mips_disp_inst(uint32_t inst) { enum inst_type t = mips_opcode_to_type[INST_OPCODE(inst)]; printf("Inst: 0x%08x(%s)\n- ", inst, mips_opcode_names[INST_OPCODE(inst)]); if (t == R_FORMAT) { int rs = INST_R_RS(inst); int rt = INST_R_RT(inst); int rd = INST_R_RD(inst); int sa = INST_R_SA(inst); int func = INST_R_FUNC(inst); printf("R_FMT: rs: 0x%02x($%s), rt: 0x%02x($%s)\n rd: 0x%02x($%s), sa: 0x%02x($%s), func: 0x%02x(%s)\n" , rs, mips_reg_names_strs[rs] , rt, mips_reg_names_strs[rt] , rd, mips_reg_names_strs[rd] , sa, mips_reg_names_strs[sa] , func, mips_function_names[func]); } else if (t == I_FORMAT) { int rs = INST_I_RS(inst); int rt = INST_I_RT(inst); int off = INST_I_OFFSET(inst); printf("I_FMT: rs: 0x%02x($%s), rt: 0x%02x($%s), off: 0x%04x(%d)\n" , rs, mips_reg_names_strs[rs] , rt, mips_reg_names_strs[rt] , off, off); } else if (t == J_FORMAT) { int addr = INST_J_INDEX(inst); printf("J_FMT: Jmp Addr: 0x%08x(%d) - Aligned: 0x%08x(%d)\n" , addr, addr , addr << 2, addr << 2); } }
void mips_disassemble_inst(uint32_t inst, char *buf) { const struct inst_desc *desc; int op = INST_OPCODE(inst); if (inst == 0) { strcpy(buf, "nop"); return ; } if (op == 0) { int op = INST_R_FUNC(inst); for (desc = inst_ids; desc->g.ident != NULL; desc++) { if (op == desc->func) { dis_reg_inst(inst, desc, buf); return ; } } } for (desc = inst_ids; desc->g.ident != NULL; desc++) { if (op == desc->opcode) { switch (mips_opcode_to_type[op]) { case I_FORMAT: dis_imm_inst(inst, desc, buf); return ; case J_FORMAT: dis_jmp_inst(inst, desc, buf); return ; default: break; } } } }
void emulator_run_inst(struct emulator *emu, uint32_t inst) { int op = INST_OPCODE(inst); void (*f)() = op_jmp_table[op]; if (!f) return ; switch (mips_opcode_to_type[op]) { case R_FORMAT: { int rs = INST_R_RS(inst); int rt = INST_R_RT(inst); int rd = INST_R_RD(inst); int sa = INST_R_SA(inst); int func = INST_R_FUNC(inst); (f) (emu, rs, rt, rd, sa, func); } break; case I_FORMAT: { int rs = INST_I_RS(inst); int rt = INST_I_RT(inst); int off = INST_I_OFFSET(inst); (f) (emu, rs, rt, off); } break; case J_FORMAT: { int addr = INST_J_INDEX(inst); (f) (emu, addr); } break; } }
void JumpPatch::apply(char* pcode) { char* plocal = pcode + pos; // to block contains pointer to position in code // offset -1 instruction, as the jump instruction has been read already int opcode = INST_OPCODE(*((int*)plocal)); int offset = to->codepos - pos - sizeof(int); int arg = (abs(offset) << 1); if ( offset < 0 ) arg |= 1; *((int*)plocal) = MAKE_INST(opcode,arg); }