?? translate.c
字號:
} } else { switch (opc) { case OPC_TEQ: case OPC_TEQI: gen_op_eq(); break; case OPC_TGE: case OPC_TGEI: gen_op_ge(); break; case OPC_TGEU: case OPC_TGEIU: gen_op_geu(); break; case OPC_TLT: case OPC_TLTI: gen_op_lt(); break; case OPC_TLTU: case OPC_TLTIU: gen_op_ltu(); break; case OPC_TNE: case OPC_TNEI: gen_op_ne(); break; default: MIPS_INVAL("trap"); generate_exception(ctx, EXCP_RI); return; } } save_cpu_state(ctx, 1); gen_op_trap(); ctx->bstate = BS_STOP;}static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest){ TranslationBlock *tb; tb = ctx->tb; if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { if (n == 0) gen_op_goto_tb0(TBPARAM(tb)); else gen_op_goto_tb1(TBPARAM(tb)); gen_save_pc(dest); gen_op_set_T0((long)tb + n); } else { gen_save_pc(dest); gen_op_reset_T0(); } gen_op_exit_tb();}/* Branches (before delay slot) */static void gen_compute_branch (DisasContext *ctx, uint32_t opc, int rs, int rt, int32_t offset){ target_ulong btarget = -1; int blink = 0; int bcond = 0; if (ctx->hflags & MIPS_HFLAG_BMASK) {#ifdef MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc); }#endif generate_exception(ctx, EXCP_RI); return; } /* Load needed operands */ switch (opc) { case OPC_BEQ: case OPC_BEQL: case OPC_BNE: case OPC_BNEL: /* Compare two registers */ if (rs != rt) { GEN_LOAD_REG_T0(rs); GEN_LOAD_REG_T1(rt); bcond = 1; } btarget = ctx->pc + 4 + offset; break; case OPC_BGEZ: case OPC_BGEZAL: case OPC_BGEZALL: case OPC_BGEZL: 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) | (uint32_t)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. */ MIPS_INVAL("jump hint"); generate_exception(ctx, EXCP_RI); return; } GEN_LOAD_REG_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 */ /* Treat as NOP. */ MIPS_DEBUG("bnever (NOP)"); return; case OPC_BLTZAL: /* 0 < 0 */ GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_T0_gpr(31); MIPS_DEBUG("bnever and link"); return; case OPC_BLTZALL: /* 0 < 0 likely */ GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_T0_gpr(31); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); 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"); ctx->pc += 4; return; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("j " TARGET_FMT_lx, btarget); break; case OPC_JAL: blink = 31; ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("jal " TARGET_FMT_lx, 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, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BEQL: gen_op_eq(); MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BNE: gen_op_ne(); MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BNEL: gen_op_ne(); MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BGEZ: gen_op_gez(); MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGEZL: gen_op_gez(); MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGEZAL: gen_op_gez(); MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget); blink = 31; goto not_likely; case OPC_BGEZALL: gen_op_gez(); blink = 31; MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGTZ: gen_op_gtz(); MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGTZL: gen_op_gtz(); MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLEZ: gen_op_lez(); MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLEZL: gen_op_lez(); MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZ: gen_op_ltz(); MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLTZL: gen_op_ltz(); MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZAL: gen_op_ltz(); blink = 31; MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget); not_likely: ctx->hflags |= MIPS_HFLAG_BC; gen_op_set_bcond(); break; case OPC_BLTZALL: gen_op_ltz(); blink = 31; MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget); likely: ctx->hflags |= MIPS_HFLAG_BL; gen_op_set_bcond(); gen_op_save_bcond(); break; default: MIPS_INVAL("conditional branch/jump"); generate_exception(ctx, EXCP_RI); return; } } MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, blink, ctx->hflags, btarget); ctx->btarget = btarget; if (blink > 0) { GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_T0_gpr(blink); }}/* special3 bitfield operations */static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, int rs, int lsb, int msb){ GEN_LOAD_REG_T1(rs); switch (opc) { case OPC_EXT: if (lsb + msb > 31) goto fail; gen_op_ext(lsb, msb + 1); break;#if defined(TARGET_MIPS64) case OPC_DEXTM: if (lsb + msb > 63) goto fail; gen_op_dext(lsb, msb + 1 + 32); break; case OPC_DEXTU: if (lsb + msb > 63) goto fail; gen_op_dext(lsb + 32, msb + 1); break; case OPC_DEXT: if (lsb + msb > 63) goto fail; gen_op_dext(lsb, msb + 1); break;#endif case OPC_INS: if (lsb > msb) goto fail; GEN_LOAD_REG_T0(rt); gen_op_ins(lsb, msb - lsb + 1); break;#if defined(TARGET_MIPS64) case OPC_DINSM: if (lsb > msb) goto fail; GEN_LOAD_REG_T0(rt); gen_op_dins(lsb, msb - lsb + 1 + 32); break; case OPC_DINSU: if (lsb > msb) goto fail; GEN_LOAD_REG_T0(rt); gen_op_dins(lsb + 32, msb - lsb + 1); break; case OPC_DINS: if (lsb > msb) goto fail; GEN_LOAD_REG_T0(rt); gen_op_dins(lsb, msb - lsb + 1); break;#endif default:fail: MIPS_INVAL("bitops"); generate_exception(ctx, EXCP_RI); return; } GEN_STORE_T0_REG(rt);}/* CP0 (MMU and control) */static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel){ const char *rn = "invalid"; if (sel != 0) check_insn(env, ctx, ISA_MIPS32); switch (reg) { case 0: switch (sel) { case 0: gen_op_mfc0_index(); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); gen_op_mfc0_mvpcontrol(); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); gen_op_mfc0_mvpconf0(); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); gen_op_mfc0_mvpconf1(); rn = "MVPConf1"; break; default: goto die; } break; case 1: switch (sel) { case 0: gen_op_mfc0_random(); rn = "Random"; break; case 1: check_insn(env, ctx, ASE_MT); gen_op_mfc0_vpecontrol(); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); gen_op_mfc0_vpeconf0(); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); gen_op_mfc0_vpeconf1(); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); gen_op_mfc0_yqmask(); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); gen_op_mfc0_vpeschedule(); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); gen_op_mfc0_vpeschefback(); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); gen_op_mfc0_vpeopt(); rn = "VPEOpt";
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -