📄 translate.c
字号:
case OPC_BGTZ: case OPC_BGTZL: case OPC_BLEZ: case OPC_BLEZL: case OPC_BLTZ: case OPC_BLTZAL: case OPC_BLTZALL: case OPC_BLTZL: /* Compare to zero */ if (rs != 0) { gen_op_load_gpr_T0(rs); bcond = 1; } btarget = ctx->pc + 4 + offset; break; case OPC_J: case OPC_JAL: /* Jump to immediate */ btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset; break; case OPC_JR: case OPC_JALR: /* Jump to register */ if (offset != 0 && offset != 16) { /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the others are reserved. */ generate_exception(ctx, EXCP_RI); return; } GEN_LOAD_REG_TN(T2, rs); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); return; } if (bcond == 0) { /* No condition to be computed */ switch (opc) { case OPC_BEQ: /* rx == rx */ case OPC_BEQL: /* rx == rx likely */ case OPC_BGEZ: /* 0 >= 0 */ case OPC_BGEZL: /* 0 >= 0 likely */ case OPC_BLEZ: /* 0 <= 0 */ case OPC_BLEZL: /* 0 <= 0 likely */ /* Always take */ ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("balways"); break; case OPC_BGEZAL: /* 0 >= 0 */ case OPC_BGEZALL: /* 0 >= 0 likely */ /* Always take and link */ blink = 31; ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("balways and link"); break; case OPC_BNE: /* rx != rx */ case OPC_BGTZ: /* 0 > 0 */ case OPC_BLTZ: /* 0 < 0 */ /* Treated as NOP */ MIPS_DEBUG("bnever (NOP)"); return; case OPC_BLTZAL: /* 0 < 0 */ gen_op_set_T0(ctx->pc + 8); gen_op_store_T0_gpr(31); return; case OPC_BLTZALL: /* 0 < 0 likely */ gen_op_set_T0(ctx->pc + 8); gen_op_store_T0_gpr(31); gen_goto_tb(ctx, 0, ctx->pc + 4); return; case OPC_BNEL: /* rx != rx likely */ case OPC_BGTZL: /* 0 > 0 likely */ case OPC_BLTZL: /* 0 < 0 likely */ /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever and skip"); gen_goto_tb(ctx, 0, ctx->pc + 4); return; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("j %08x", btarget); break; case OPC_JAL: blink = 31; ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("jal %08x", btarget); break; case OPC_JR: ctx->hflags |= MIPS_HFLAG_BR; MIPS_DEBUG("jr %s", regnames[rs]); break; case OPC_JALR: blink = rt; ctx->hflags |= MIPS_HFLAG_BR; MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); return; } } else { switch (opc) { case OPC_BEQ: gen_op_eq(); MIPS_DEBUG("beq %s, %s, %08x", regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BEQL: gen_op_eq(); MIPS_DEBUG("beql %s, %s, %08x", regnames[rs], regnames[rt], btarget); goto likely; case OPC_BNE: gen_op_ne(); MIPS_DEBUG("bne %s, %s, %08x", regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BNEL: gen_op_ne(); MIPS_DEBUG("bnel %s, %s, %08x", regnames[rs], regnames[rt], btarget); goto likely; case OPC_BGEZ: gen_op_gez(); MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget); goto not_likely; case OPC_BGEZL: gen_op_gez(); MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget); goto likely; case OPC_BGEZAL: gen_op_gez(); MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget); blink = 31; goto not_likely; case OPC_BGEZALL: gen_op_gez(); blink = 31; MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget); goto likely; case OPC_BGTZ: gen_op_gtz(); MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget); goto not_likely; case OPC_BGTZL: gen_op_gtz(); MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget); goto likely; case OPC_BLEZ: gen_op_lez(); MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget); goto not_likely; case OPC_BLEZL: gen_op_lez(); MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget); goto likely; case OPC_BLTZ: gen_op_ltz(); MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget); goto not_likely; case OPC_BLTZL: gen_op_ltz(); MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget); goto likely; case OPC_BLTZAL: gen_op_ltz(); blink = 31; MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget); not_likely: ctx->hflags |= MIPS_HFLAG_BC; break; case OPC_BLTZALL: gen_op_ltz(); blink = 31; MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget); likely: ctx->hflags |= MIPS_HFLAG_BL; break; } gen_op_set_bcond(); } MIPS_DEBUG("enter ds: link %d cond %02x target %08x", blink, ctx->hflags, btarget); ctx->btarget = btarget; if (blink > 0) { gen_op_set_T0(ctx->pc + 8); gen_op_store_T0_gpr(blink); } return;}/* special3 bitfield operations */static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, int rs, int lsb, int msb){ GEN_LOAD_REG_TN(T1, rs); switch (opc) { case OPC_EXT: if (lsb + msb > 31) goto fail; gen_op_ext(lsb, msb + 1); break; case OPC_DEXTM: if (lsb + msb > 63) goto fail; gen_op_ext(lsb, msb + 1 + 32); break; case OPC_DEXTU: if (lsb + msb > 63) goto fail; gen_op_ext(lsb + 32, msb + 1); break; case OPC_DEXT: gen_op_ext(lsb, msb + 1); break; case OPC_INS: if (lsb > msb) goto fail; GEN_LOAD_REG_TN(T2, rt); gen_op_ins(lsb, msb - lsb + 1); break; case OPC_DINSM: if (lsb > msb) goto fail; GEN_LOAD_REG_TN(T2, rt); gen_op_ins(lsb, msb - lsb + 1 + 32); break; case OPC_DINSU: if (lsb > msb) goto fail; GEN_LOAD_REG_TN(T2, rt); gen_op_ins(lsb + 32, msb - lsb + 1); break; case OPC_DINS: if (lsb > msb) goto fail; GEN_LOAD_REG_TN(T2, rt); gen_op_ins(lsb, msb - lsb + 1); break; default:fail: MIPS_INVAL("bitops"); generate_exception(ctx, EXCP_RI); return; } GEN_STORE_TN_REG(rt, T0);}/* CP0 (MMU and control) */static void gen_mfc0 (DisasContext *ctx, int reg, int sel){ const char *rn = "invalid"; switch (reg) { case 0: switch (sel) { case 0: gen_op_mfc0_index(); rn = "Index"; break; case 1:// gen_op_mfc0_mvpcontrol(); /* MT ASE */ rn = "MVPControl";// break; case 2:// gen_op_mfc0_mvpconf0(); /* MT ASE */ rn = "MVPConf0";// break; case 3:// gen_op_mfc0_mvpconf1(); /* MT ASE */ rn = "MVPConf1";// break; default: goto die; } break; case 1: switch (sel) { case 0: gen_op_mfc0_random(); rn = "Random"; break; case 1:// gen_op_mfc0_vpecontrol(); /* MT ASE */ rn = "VPEControl";// break; case 2:// gen_op_mfc0_vpeconf0(); /* MT ASE */ rn = "VPEConf0";// break; case 3:// gen_op_mfc0_vpeconf1(); /* MT ASE */ rn = "VPEConf1";// break; case 4:// gen_op_mfc0_YQMask(); /* MT ASE */ rn = "YQMask";// break; case 5:// gen_op_mfc0_vpeschedule(); /* MT ASE */ rn = "VPESchedule";// break; case 6:// gen_op_mfc0_vpeschefback(); /* MT ASE */ rn = "VPEScheFBack";// break; case 7:// gen_op_mfc0_vpeopt(); /* MT ASE */ rn = "VPEOpt";// break; default: goto die; } break; case 2: switch (sel) { case 0: gen_op_mfc0_entrylo0(); rn = "EntryLo0"; break; case 1:// gen_op_mfc0_tcstatus(); /* MT ASE */ rn = "TCStatus";// break; case 2:// gen_op_mfc0_tcbind(); /* MT ASE */ rn = "TCBind";// break; case 3:// gen_op_mfc0_tcrestart(); /* MT ASE */ rn = "TCRestart";// break; case 4:// gen_op_mfc0_tchalt(); /* MT ASE */ rn = "TCHalt";// break; case 5:// gen_op_mfc0_tccontext(); /* MT ASE */ rn = "TCContext";// break; case 6:// gen_op_mfc0_tcschedule(); /* MT ASE */ rn = "TCSchedule";// break; case 7:// gen_op_mfc0_tcschefback(); /* MT ASE */ rn = "TCScheFBack";// break; default: goto die; } break; case 3: switch (sel) { case 0: gen_op_mfc0_entrylo1(); rn = "EntryLo1"; break; default: goto die; } break; case 4: switch (sel) { case 0: gen_op_mfc0_context(); rn = "Context"; break; case 1:// gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */ rn = "ContextConfig";// break; default: goto die; } break; case 5: switch (sel) { case 0: gen_op_mfc0_pagemask(); rn = "PageMask"; break; case 1: gen_op_mfc0_pagegrain(); rn = "PageGrain"; break; default: goto die; } break; case 6: switch (sel) { case 0: gen_op_mfc0_wired(); rn = "Wired"; break; case 1:// gen_op_mfc0_srsconf0(); /* shadow registers */ rn = "SRSConf0";// break; case 2:// gen_op_mfc0_srsconf1(); /* shadow registers */ rn = "SRSConf1";// break; case 3:// gen_op_mfc0_srsconf2(); /* shadow registers */ rn = "SRSConf2";// break; case 4:// gen_op_mfc0_srsconf3(); /* shadow registers */ rn = "SRSConf3";// break; case 5:// gen_op_mfc0_srsconf4(); /* shadow registers */ rn = "SRSConf4";// break; default: goto die; } break; case 7: switch (sel) { case 0: gen_op_mfc0_hwrena(); rn = "HWREna"; break; default: goto die; } break; case 8: switch (sel) { case 0: gen_op_mfc0_badvaddr(); rn = "BadVaddr"; break; default: goto die; } break; case 9: switch (sel) { case 0: gen_op_mfc0_count(); rn = "Count"; break; /* 6,7 are implementation dependent */ default: goto die; } break; case 10: switch (sel) { case 0: gen_op_mfc0_entryhi(); rn = "EntryHi"; break; default: goto die; } break; case 11: switch (sel) { case 0: gen_op_mfc0_compare(); rn = "Compare"; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -