?? translate.c
字號:
gen_op_eval_xbg, gen_op_eval_xbge, gen_op_eval_xbgu, gen_op_eval_xbcc, gen_op_eval_xbpos, gen_op_eval_xbvc,#endif },};static GenOpFunc * const gen_fcond[4][16] = { { gen_op_eval_bn, gen_op_eval_fbne, gen_op_eval_fblg, gen_op_eval_fbul, gen_op_eval_fbl, gen_op_eval_fbug, gen_op_eval_fbg, gen_op_eval_fbu, gen_op_eval_ba, gen_op_eval_fbe, gen_op_eval_fbue, gen_op_eval_fbge, gen_op_eval_fbuge, gen_op_eval_fble, gen_op_eval_fbule, gen_op_eval_fbo, },#ifdef TARGET_SPARC64 { gen_op_eval_bn, gen_op_eval_fbne_fcc1, gen_op_eval_fblg_fcc1, gen_op_eval_fbul_fcc1, gen_op_eval_fbl_fcc1, gen_op_eval_fbug_fcc1, gen_op_eval_fbg_fcc1, gen_op_eval_fbu_fcc1, gen_op_eval_ba, gen_op_eval_fbe_fcc1, gen_op_eval_fbue_fcc1, gen_op_eval_fbge_fcc1, gen_op_eval_fbuge_fcc1, gen_op_eval_fble_fcc1, gen_op_eval_fbule_fcc1, gen_op_eval_fbo_fcc1, }, { gen_op_eval_bn, gen_op_eval_fbne_fcc2, gen_op_eval_fblg_fcc2, gen_op_eval_fbul_fcc2, gen_op_eval_fbl_fcc2, gen_op_eval_fbug_fcc2, gen_op_eval_fbg_fcc2, gen_op_eval_fbu_fcc2, gen_op_eval_ba, gen_op_eval_fbe_fcc2, gen_op_eval_fbue_fcc2, gen_op_eval_fbge_fcc2, gen_op_eval_fbuge_fcc2, gen_op_eval_fble_fcc2, gen_op_eval_fbule_fcc2, gen_op_eval_fbo_fcc2, }, { gen_op_eval_bn, gen_op_eval_fbne_fcc3, gen_op_eval_fblg_fcc3, gen_op_eval_fbul_fcc3, gen_op_eval_fbl_fcc3, gen_op_eval_fbug_fcc3, gen_op_eval_fbg_fcc3, gen_op_eval_fbu_fcc3, gen_op_eval_ba, gen_op_eval_fbe_fcc3, gen_op_eval_fbue_fcc3, gen_op_eval_fbge_fcc3, gen_op_eval_fbuge_fcc3, gen_op_eval_fble_fcc3, gen_op_eval_fbule_fcc3, gen_op_eval_fbo_fcc3, },#else {}, {}, {},#endif};#ifdef TARGET_SPARC64static void gen_cond_reg(int cond){ switch (cond) { case 0x1: gen_op_eval_brz(); break; case 0x2: gen_op_eval_brlez(); break; case 0x3: gen_op_eval_brlz(); break; case 0x5: gen_op_eval_brnz(); break; case 0x6: gen_op_eval_brgz(); break; default: case 0x7: gen_op_eval_brgez(); break; }}#endif/* XXX: potentially incorrect if dynamic npc */static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc){ unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); target_ulong target = dc->pc + offset; if (cond == 0x0) { /* unconditional not taken */ if (a) { dc->pc = dc->npc + 4; dc->npc = dc->pc + 4; } else { dc->pc = dc->npc; dc->npc = dc->pc + 4; } } else if (cond == 0x8) { /* unconditional taken */ if (a) { dc->pc = target; dc->npc = dc->pc + 4; } else { dc->pc = dc->npc; dc->npc = target; } } else { flush_T2(dc); gen_cond[cc][cond](); if (a) { gen_branch_a(dc, target, dc->npc); dc->is_br = 1; } else { dc->pc = dc->npc; dc->jump_pc[0] = target; dc->jump_pc[1] = dc->npc + 4; dc->npc = JUMP_PC; } }}/* XXX: potentially incorrect if dynamic npc */static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc){ unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); target_ulong target = dc->pc + offset; if (cond == 0x0) { /* unconditional not taken */ if (a) { dc->pc = dc->npc + 4; dc->npc = dc->pc + 4; } else { dc->pc = dc->npc; dc->npc = dc->pc + 4; } } else if (cond == 0x8) { /* unconditional taken */ if (a) { dc->pc = target; dc->npc = dc->pc + 4; } else { dc->pc = dc->npc; dc->npc = target; } } else { flush_T2(dc); gen_fcond[cc][cond](); if (a) { gen_branch_a(dc, target, dc->npc); dc->is_br = 1; } else { dc->pc = dc->npc; dc->jump_pc[0] = target; dc->jump_pc[1] = dc->npc + 4; dc->npc = JUMP_PC; } }}#ifdef TARGET_SPARC64/* XXX: potentially incorrect if dynamic npc */static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn){ unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29)); target_ulong target = dc->pc + offset; flush_T2(dc); gen_cond_reg(cond); if (a) { gen_branch_a(dc, target, dc->npc); dc->is_br = 1; } else { dc->pc = dc->npc; dc->jump_pc[0] = target; dc->jump_pc[1] = dc->npc + 4; dc->npc = JUMP_PC; }}static GenOpFunc * const gen_fcmps[4] = { gen_op_fcmps, gen_op_fcmps_fcc1, gen_op_fcmps_fcc2, gen_op_fcmps_fcc3,};static GenOpFunc * const gen_fcmpd[4] = { gen_op_fcmpd, gen_op_fcmpd_fcc1, gen_op_fcmpd_fcc2, gen_op_fcmpd_fcc3,};#if defined(CONFIG_USER_ONLY)static GenOpFunc * const gen_fcmpq[4] = { gen_op_fcmpq, gen_op_fcmpq_fcc1, gen_op_fcmpq_fcc2, gen_op_fcmpq_fcc3,};#endifstatic GenOpFunc * const gen_fcmpes[4] = { gen_op_fcmpes, gen_op_fcmpes_fcc1, gen_op_fcmpes_fcc2, gen_op_fcmpes_fcc3,};static GenOpFunc * const gen_fcmped[4] = { gen_op_fcmped, gen_op_fcmped_fcc1, gen_op_fcmped_fcc2, gen_op_fcmped_fcc3,};#if defined(CONFIG_USER_ONLY)static GenOpFunc * const gen_fcmpeq[4] = { gen_op_fcmpeq, gen_op_fcmpeq_fcc1, gen_op_fcmpeq_fcc2, gen_op_fcmpeq_fcc3,};#endif#endifstatic int gen_trap_ifnofpu(DisasContext * dc){#if !defined(CONFIG_USER_ONLY) if (!dc->fpu_enabled) { save_state(dc); gen_op_exception(TT_NFPU_INSN); dc->is_br = 1; return 1; }#endif return 0;}/* before an instruction, dc->pc must be static */static void disas_sparc_insn(DisasContext * dc){ unsigned int insn, opc, rs1, rs2, rd; insn = ldl_code(dc->pc); opc = GET_FIELD(insn, 0, 1); rd = GET_FIELD(insn, 2, 6); switch (opc) { case 0: /* branches/sethi */ { unsigned int xop = GET_FIELD(insn, 7, 9); int32_t target; switch (xop) {#ifdef TARGET_SPARC64 case 0x1: /* V9 BPcc */ { int cc; target = GET_FIELD_SP(insn, 0, 18); target = sign_extend(target, 18); target <<= 2; cc = GET_FIELD_SP(insn, 20, 21); if (cc == 0) do_branch(dc, target, insn, 0); else if (cc == 2) do_branch(dc, target, insn, 1); else goto illegal_insn; goto jmp_insn; } case 0x3: /* V9 BPr */ { target = GET_FIELD_SP(insn, 0, 13) | (GET_FIELD_SP(insn, 20, 21) << 14); target = sign_extend(target, 16); target <<= 2; rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); do_branch_reg(dc, target, insn); goto jmp_insn; } case 0x5: /* V9 FBPcc */ { int cc = GET_FIELD_SP(insn, 20, 21); if (gen_trap_ifnofpu(dc)) goto jmp_insn; target = GET_FIELD_SP(insn, 0, 18); target = sign_extend(target, 19); target <<= 2; do_fbranch(dc, target, insn, cc); goto jmp_insn; }#else case 0x7: /* CBN+x */ { goto ncp_insn; }#endif case 0x2: /* BN+x */ { target = GET_FIELD(insn, 10, 31); target = sign_extend(target, 22); target <<= 2; do_branch(dc, target, insn, 0); goto jmp_insn; } case 0x6: /* FBN+x */ { if (gen_trap_ifnofpu(dc)) goto jmp_insn; target = GET_FIELD(insn, 10, 31); target = sign_extend(target, 22); target <<= 2; do_fbranch(dc, target, insn, 0); goto jmp_insn; } case 0x4: /* SETHI */#define OPTIM#if defined(OPTIM) if (rd) { // nop#endif uint32_t value = GET_FIELD(insn, 10, 31); gen_movl_imm_T0(value << 10); gen_movl_T0_reg(rd);#if defined(OPTIM) }#endif break; case 0x0: /* UNIMPL */ default: goto illegal_insn; } break; } break; case 1: /*CALL*/ { target_long target = GET_FIELDs(insn, 2, 31) << 2;#ifdef TARGET_SPARC64 if (dc->pc == (uint32_t)dc->pc) { gen_op_movl_T0_im(dc->pc); } else { gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); }#else gen_op_movl_T0_im(dc->pc);#endif gen_movl_T0_reg(15); target += dc->pc; gen_mov_pc_npc(dc); dc->npc = target; } goto jmp_insn; case 2: /* FPU & Logical Operations */ { unsigned int xop = GET_FIELD(insn, 7, 12); if (xop == 0x3a) { /* generate trap */ int cond; rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { rs2 = GET_FIELD(insn, 25, 31);#if defined(OPTIM) if (rs2 != 0) {#endif gen_movl_simm_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } else { rs2 = GET_FIELD(insn, 27, 31);#if defined(OPTIM) if (rs2 != 0) {#endif gen_movl_reg_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } cond = GET_FIELD(insn, 3, 6);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -