📄 translate.c
字号:
gen_op_mov_TN_reg[OT_LONG][0][R_EAX](); gen_string_movl_A0_EDI(s); gen_op_st_T0_A0[ot + s->mem_index](); gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_addq_EDI_T0(); } else #endif if (s->aflag) { gen_op_addl_EDI_T0(); } else { gen_op_addw_EDI_T0(); }}static inline void gen_lods(DisasContext *s, int ot){ gen_string_movl_A0_ESI(s); gen_op_ld_T0_A0[ot + s->mem_index](); gen_op_mov_reg_T0[ot][R_EAX](); gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_addq_ESI_T0(); } else #endif if (s->aflag) { gen_op_addl_ESI_T0(); } else { gen_op_addw_ESI_T0(); }}static inline void gen_scas(DisasContext *s, int ot){ gen_op_mov_TN_reg[OT_LONG][0][R_EAX](); gen_string_movl_A0_EDI(s); gen_op_ld_T1_A0[ot + s->mem_index](); gen_op_cmpl_T0_T1_cc(); gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_addq_EDI_T0(); } else #endif if (s->aflag) { gen_op_addl_EDI_T0(); } else { gen_op_addw_EDI_T0(); }}static inline void gen_cmps(DisasContext *s, int ot){ gen_string_movl_A0_ESI(s); gen_op_ld_T0_A0[ot + s->mem_index](); gen_string_movl_A0_EDI(s); gen_op_ld_T1_A0[ot + s->mem_index](); gen_op_cmpl_T0_T1_cc(); gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_addq_ESI_T0(); gen_op_addq_EDI_T0(); } else #endif if (s->aflag) { gen_op_addl_ESI_T0(); gen_op_addl_EDI_T0(); } else { gen_op_addw_ESI_T0(); gen_op_addw_EDI_T0(); }}static inline void gen_ins(DisasContext *s, int ot){ gen_string_movl_A0_EDI(s); gen_op_movl_T0_0(); gen_op_st_T0_A0[ot + s->mem_index](); gen_op_in_DX_T0[ot](); gen_op_st_T0_A0[ot + s->mem_index](); gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_addq_EDI_T0(); } else #endif if (s->aflag) { gen_op_addl_EDI_T0(); } else { gen_op_addw_EDI_T0(); }}static inline void gen_outs(DisasContext *s, int ot){ gen_string_movl_A0_ESI(s); gen_op_ld_T0_A0[ot + s->mem_index](); gen_op_out_DX_T0[ot](); gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_addq_ESI_T0(); } else #endif if (s->aflag) { gen_op_addl_ESI_T0(); } else { gen_op_addw_ESI_T0(); }}/* same method as Valgrind : we generate jumps to current or next instruction */#define GEN_REPZ(op) \static inline void gen_repz_ ## op(DisasContext *s, int ot, \ target_ulong cur_eip, target_ulong next_eip) \{ \ int l2;\ gen_update_cc_op(s); \ l2 = gen_jz_ecx_string(s, next_eip); \ gen_ ## op(s, ot); \ gen_op_dec_ECX[s->aflag](); \ /* a loop would cause two single step exceptions if ECX = 1 \ before rep string_insn */ \ if (!s->jmp_opt) \ gen_op_jz_ecx[s->aflag](l2); \ gen_jmp(s, cur_eip); \}#define GEN_REPZ2(op) \static inline void gen_repz_ ## op(DisasContext *s, int ot, \ target_ulong cur_eip, \ target_ulong next_eip, \ int nz) \{ \ int l2;\ gen_update_cc_op(s); \ l2 = gen_jz_ecx_string(s, next_eip); \ gen_ ## op(s, ot); \ gen_op_dec_ECX[s->aflag](); \ gen_op_set_cc_op(CC_OP_SUBB + ot); \ gen_op_string_jnz_sub[nz][ot](l2);\ if (!s->jmp_opt) \ gen_op_jz_ecx[s->aflag](l2); \ gen_jmp(s, cur_eip); \}GEN_REPZ(movs)GEN_REPZ(stos)GEN_REPZ(lods)GEN_REPZ(ins)GEN_REPZ(outs)GEN_REPZ2(scas)GEN_REPZ2(cmps)enum { JCC_O, JCC_B, JCC_Z, JCC_BE, JCC_S, JCC_P, JCC_L, JCC_LE,};static GenOpFunc1 *gen_jcc_sub[4][8] = { [OT_BYTE] = { NULL, gen_op_jb_subb, gen_op_jz_subb, gen_op_jbe_subb, gen_op_js_subb, NULL, gen_op_jl_subb, gen_op_jle_subb, }, [OT_WORD] = { NULL, gen_op_jb_subw, gen_op_jz_subw, gen_op_jbe_subw, gen_op_js_subw, NULL, gen_op_jl_subw, gen_op_jle_subw, }, [OT_LONG] = { NULL, gen_op_jb_subl, gen_op_jz_subl, gen_op_jbe_subl, gen_op_js_subl, NULL, gen_op_jl_subl, gen_op_jle_subl, },#ifdef TARGET_X86_64 [OT_QUAD] = { NULL, BUGGY_64(gen_op_jb_subq), gen_op_jz_subq, BUGGY_64(gen_op_jbe_subq), gen_op_js_subq, NULL, BUGGY_64(gen_op_jl_subq), BUGGY_64(gen_op_jle_subq), },#endif};static GenOpFunc1 *gen_op_loop[3][4] = { [0] = { gen_op_loopnzw, gen_op_loopzw, gen_op_jnz_ecxw, }, [1] = { gen_op_loopnzl, gen_op_loopzl, gen_op_jnz_ecxl, },#ifdef TARGET_X86_64 [2] = { gen_op_loopnzq, gen_op_loopzq, gen_op_jnz_ecxq, },#endif};static GenOpFunc *gen_setcc_slow[8] = { gen_op_seto_T0_cc, gen_op_setb_T0_cc, gen_op_setz_T0_cc, gen_op_setbe_T0_cc, gen_op_sets_T0_cc, gen_op_setp_T0_cc, gen_op_setl_T0_cc, gen_op_setle_T0_cc,};static GenOpFunc *gen_setcc_sub[4][8] = { [OT_BYTE] = { NULL, gen_op_setb_T0_subb, gen_op_setz_T0_subb, gen_op_setbe_T0_subb, gen_op_sets_T0_subb, NULL, gen_op_setl_T0_subb, gen_op_setle_T0_subb, }, [OT_WORD] = { NULL, gen_op_setb_T0_subw, gen_op_setz_T0_subw, gen_op_setbe_T0_subw, gen_op_sets_T0_subw, NULL, gen_op_setl_T0_subw, gen_op_setle_T0_subw, }, [OT_LONG] = { NULL, gen_op_setb_T0_subl, gen_op_setz_T0_subl, gen_op_setbe_T0_subl, gen_op_sets_T0_subl, NULL, gen_op_setl_T0_subl, gen_op_setle_T0_subl, },#ifdef TARGET_X86_64 [OT_QUAD] = { NULL, gen_op_setb_T0_subq, gen_op_setz_T0_subq, gen_op_setbe_T0_subq, gen_op_sets_T0_subq, NULL, gen_op_setl_T0_subq, gen_op_setle_T0_subq, },#endif};static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = { gen_op_fadd_ST0_FT0, gen_op_fmul_ST0_FT0, gen_op_fcom_ST0_FT0, gen_op_fcom_ST0_FT0, gen_op_fsub_ST0_FT0, gen_op_fsubr_ST0_FT0, gen_op_fdiv_ST0_FT0, gen_op_fdivr_ST0_FT0,};/* NOTE the exception in "r" op ordering */static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = { gen_op_fadd_STN_ST0, gen_op_fmul_STN_ST0, NULL, NULL, gen_op_fsubr_STN_ST0, gen_op_fsub_STN_ST0, gen_op_fdivr_STN_ST0, gen_op_fdiv_STN_ST0,};/* if d == OR_TMP0, it means memory operand (address in A0) */static void gen_op(DisasContext *s1, int op, int ot, int d){ GenOpFunc *gen_update_cc; if (d != OR_TMP0) { gen_op_mov_TN_reg[ot][0][d](); } else { gen_op_ld_T0_A0[ot + s1->mem_index](); } switch(op) { case OP_ADCL: case OP_SBBL: if (s1->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s1->cc_op); if (d != OR_TMP0) { gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); gen_op_mov_reg_T0[ot][d](); } else { gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL](); } s1->cc_op = CC_OP_DYNAMIC; goto the_end; case OP_ADDL: gen_op_addl_T0_T1(); s1->cc_op = CC_OP_ADDB + ot; gen_update_cc = gen_op_update2_cc; break; case OP_SUBL: gen_op_subl_T0_T1(); s1->cc_op = CC_OP_SUBB + ot; gen_update_cc = gen_op_update2_cc; break; default: case OP_ANDL: case OP_ORL: case OP_XORL: gen_op_arith_T0_T1_cc[op](); s1->cc_op = CC_OP_LOGICB + ot; gen_update_cc = gen_op_update1_cc; break; case OP_CMPL: gen_op_cmpl_T0_T1_cc(); s1->cc_op = CC_OP_SUBB + ot; gen_update_cc = NULL; break; } if (op != OP_CMPL) { if (d != OR_TMP0) gen_op_mov_reg_T0[ot][d](); else gen_op_st_T0_A0[ot + s1->mem_index](); } /* the flags update must happen after the memory write (precise exception support) */ if (gen_update_cc) gen_update_cc(); the_end: ;}/* if d == OR_TMP0, it means memory operand (address in A0) */static void gen_inc(DisasContext *s1, int ot, int d, int c){ if (d != OR_TMP0) gen_op_mov_TN_reg[ot][0][d](); else gen_op_ld_T0_A0[ot + s1->mem_index](); if (s1->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s1->cc_op); if (c > 0) { gen_op_incl_T0(); s1->cc_op = CC_OP_INCB + ot; } else { gen_op_decl_T0(); s1->cc_op = CC_OP_DECB + ot; } if (d != OR_TMP0) gen_op_mov_reg_T0[ot][d](); else gen_op_st_T0_A0[ot + s1->mem_index](); gen_op_update_inc_cc();}static void gen_shift(DisasContext *s1, int op, int ot, int d, int s){ if (d != OR_TMP0) gen_op_mov_TN_reg[ot][0][d](); else gen_op_ld_T0_A0[ot + s1->mem_index](); if (s != OR_TMP1) gen_op_mov_TN_reg[ot][1][s](); /* for zero counts, flags are not updated, so must do it dynamically */ if (s1->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s1->cc_op); if (d != OR_TMP0) gen_op_shift_T0_T1_cc[ot][op](); else gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op](); if (d != OR_TMP0) gen_op_mov_reg_T0[ot][d](); s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */}static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c){ /* currently not optimized */ gen_op_movl_T1_im(c); gen_shift(s1, op, ot, d, OR_TMP1);}static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr){ target_long disp; int havesib; int base; int index; int scale; int opreg; int mod, rm, code, override, must_add_seg; override = s->override; must_add_seg = s->addseg; if (override >= 0) must_add_seg = 1; mod = (modrm >> 6) & 3; rm = modrm & 7; if (s->aflag) { havesib = 0; base = rm; index = 0; scale = 0; if (base == 4) { havesib = 1; code = ldub_code(s->pc++); scale = (code >> 6) & 3; index = ((code >> 3) & 7) | REX_X(s); base = (code & 7); } base |= REX_B(s); switch (mod) { case 0: if ((base & 7) == 5) { base = -1; disp = (int32_t)ldl_code(s->pc); s->pc += 4; if (CODE64(s) && !havesib) { disp += s->pc + s->rip_offset; } } else { disp = 0; } break; case 1: disp = (int8_t)ldub_code(s->pc++); break; default: case 2: disp = ldl_code(s->pc); s->pc += 4; break; } if (base >= 0) { /* for correct popl handling with esp */ if (base == 4 && s->popl_esp_hack) disp += s->popl_esp_hack;#ifdef TARGET_X86_64 if (s->aflag == 2) { gen_op_movq_A0_reg[base](); if (disp != 0) { if ((int32_t)disp == disp) gen_op_addq_A0_im(disp); else gen_op_addq_A0_im64(disp >> 32, disp); } } else #endif { gen_op_movl_A0_reg[base](); if (disp != 0) gen_op_addl_A0_im(disp); } } else {#ifdef TARGET_X86_64 if (s->aflag == 2) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -