📄 decoder.h
字号:
gen_releasereg(DREG(TMPW)); } else { if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } gen_dop_word(op,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); }}static void dyn_mov_evgv(void) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_write_word_release(DREG(EA),rm_reg,decode.big_op); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); }}static void dyn_mov_gvev(void) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word_release(DREG(EA),rm_reg,decode.big_op); } else { gen_dop_word(DOP_MOV,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); }}static void dyn_mov_eviv(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(); gen_call_write(DREG(EA),decode.big_op ? decode_fetchd() : decode_fetchw(),decode.big_op?4:2); dyn_check_bool_exception_al(); } else { gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw()); }}static void dyn_mov_ev_gb(bool sign) { dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_byte_release(DREG(EA),DREG(TMPB),false); gen_extend_byte(sign,decode.big_op,rm_reg,DREG(TMPB),0); gen_releasereg(DREG(TMPB)); } else { gen_extend_byte(sign,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); }}static void dyn_mov_ev_gw(bool sign) { if (!decode.big_op) { dyn_mov_gvev(); return; } dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word_release(DREG(EA),DREG(TMPW),false); gen_extend_word(sign,rm_reg,DREG(TMPW)); gen_releasereg(DREG(TMPW)); } else { gen_extend_word(sign,rm_reg,&DynRegs[decode.modrm.rm]); }}static void dyn_dshift_ev_gv(bool left,bool immediate) { dyn_get_modrm(); DynReg * rm_reg=&DynRegs[decode.modrm.reg]; DynReg * ea_reg; if (decode.modrm.mod<3) { dyn_fill_ea();ea_reg=DREG(TMPW); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); } else ea_reg=&DynRegs[decode.modrm.rm]; gen_needflags(); if (immediate) gen_dshift_imm(decode.big_op,left,ea_reg,rm_reg,decode_fetchb()); else gen_dshift_cl(decode.big_op,left,ea_reg,rm_reg,DREG(ECX)); if (decode.modrm.mod<3) { dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); gen_releasereg(DREG(TMPW)); }}static DualOps grp1_table[8]={DOP_ADD,DOP_OR,DOP_ADC,DOP_SBB,DOP_AND,DOP_SUB,DOP_XOR,DOP_CMP};static void dyn_grp1_eb_ib(void) { dyn_get_modrm(); DualOps op=grp1_table[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_byte(DREG(EA),DREG(TMPB),false); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } gen_dop_byte_imm(op,DREG(TMPB),0,decode_fetchb()); if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPB)); } else { if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } dyn_dop_byte_imm(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); }}static void dyn_grp1_ev_ivx(bool withbyte) { dyn_get_modrm(); DualOps op=grp1_table[decode.modrm.reg]; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else set_skipflags(false); } if (!withbyte) { dyn_dop_word_imm(op,decode.big_op,DREG(TMPW)); } else { gen_dop_word_imm(op,decode.big_op,DREG(TMPW),(Bit8s)decode_fetchb()); } if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); else gen_releasereg(DREG(EA)); gen_releasereg(DREG(TMPW)); } else { if (op<=DOP_TEST) { if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); else gen_discardflags(); } if (!withbyte) { dyn_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm]); } else { gen_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm],(Bit8s)decode_fetchb()); } }}enum grp2_types { grp2_1,grp2_imm,grp2_cl,};static void dyn_grp2_eb(grp2_types type) { dyn_get_modrm();DynReg * src;Bit8u src_i; if (decode.modrm.mod<3) { dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); src=DREG(TMPB); src_i=0; } else { src=&DynRegs[decode.modrm.rm&3]; src_i=decode.modrm.rm&4; } switch (type) { case grp2_1: /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ if (decode.modrm.reg < 4) gen_needflags(); else gen_discardflags(); gen_shift_byte_imm(decode.modrm.reg,src,src_i,1); break; case grp2_imm: { Bit8u imm=decode_fetchb(); if (imm) { /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ if (decode.modrm.reg < 4) gen_needflags(); else gen_discardflags(); gen_shift_byte_imm(decode.modrm.reg,src,src_i,imm); } else return; } break; case grp2_cl: gen_needflags(); /* flags must not be changed on ecx==0 */ gen_shift_byte_cl (decode.modrm.reg,src,src_i,DREG(ECX)); break; } if (decode.modrm.mod<3) { dyn_write_byte_release(DREG(EA),src,false); gen_releasereg(src); }}static void dyn_grp2_ev(grp2_types type) { dyn_get_modrm();DynReg * src; if (decode.modrm.mod<3) { dyn_fill_ea();dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); src=DREG(TMPW); } else { src=&DynRegs[decode.modrm.rm]; } switch (type) { case grp2_1: /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ if (decode.modrm.reg < 4) gen_needflags(); else gen_discardflags(); gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,1); break; case grp2_imm: { Bitu val; if (decode_fetchb_imm(val)) { if (decode.modrm.reg < 4) gen_needflags(); else gen_discardflags(); gen_load_host((void*)val,DREG(TMPB),1); gen_shift_word_cl(decode.modrm.reg,decode.big_op,src,DREG(TMPB)); gen_releasereg(DREG(TMPB)); break; } Bit8u imm=(Bit8u)val; if (imm) { /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ if (decode.modrm.reg < 4) gen_needflags(); else gen_discardflags(); gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,imm); } else return; } break; case grp2_cl: gen_needflags(); /* flags must not be changed on ecx==0 */ gen_shift_word_cl (decode.modrm.reg,decode.big_op,src,DREG(ECX)); break; } if (decode.modrm.mod<3) { dyn_write_word_release(DREG(EA),src,decode.big_op); gen_releasereg(src); }}static void dyn_grp3_eb(void) { dyn_get_modrm();DynReg * src;Bit8u src_i; if (decode.modrm.mod<3) { dyn_fill_ea(); if ((decode.modrm.reg==0) || (decode.modrm.reg==3)) set_skipflags(true); dyn_read_byte(DREG(EA),DREG(TMPB),false); src=DREG(TMPB);src_i=0; } else { src=&DynRegs[decode.modrm.rm&3]; src_i=decode.modrm.rm&4; } switch (decode.modrm.reg) { case 0x0: /* test eb,ib */ set_skipflags(false);gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); goto skipsave; case 0x2: /* NOT Eb */ gen_sop_byte(SOP_NOT,src,src_i); break; case 0x3: /* NEG Eb */ set_skipflags(false);gen_sop_byte(SOP_NEG,src,src_i); break; case 0x4: /* mul Eb */ gen_needflags();gen_mul_byte(false,DREG(EAX),src,src_i); goto skipsave; case 0x5: /* imul Eb */ gen_needflags();gen_mul_byte(true,DREG(EAX),src,src_i); goto skipsave; case 0x6: /* div Eb */ case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) gen_dop_byte(DOP_MOV,DREG(TMPB),0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); gen_releasereg(DREG(EAX)); gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, "%Rd%Dd",DREG(TMPB),DREG(TMPB)); dyn_check_bool_exception(DREG(TMPB)); goto skipsave; } /* Save the result if memory op */ if (decode.modrm.mod<3) dyn_write_byte_release(DREG(EA),src,false);skipsave: gen_releasereg(DREG(TMPB));gen_releasereg(DREG(EA));}static void dyn_grp3_ev(void) { dyn_get_modrm();DynReg * src; if (decode.modrm.mod<3) { dyn_fill_ea();src=DREG(TMPW); if ((decode.modrm.reg==0) || (decode.modrm.reg==3)) set_skipflags(true); dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); } else src=&DynRegs[decode.modrm.rm]; switch (decode.modrm.reg) { case 0x0: /* test ev,iv */ set_skipflags(false);gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); goto skipsave; case 0x2: /* NOT Ev */ gen_sop_word(SOP_NOT,decode.big_op,src); break; case 0x3: /* NEG Eb */ set_skipflags(false);gen_sop_word(SOP_NEG,decode.big_op,src); break; case 0x4: /* mul Eb */ gen_needflags();gen_mul_word(false,DREG(EAX),DREG(EDX),decode.big_op,src); goto skipsave; case 0x5: /* imul Eb */ gen_needflags();gen_mul_word(true,DREG(EAX),DREG(EDX),decode.big_op,src); goto skipsave; case 0x6: /* div Eb */ case 0x7: /* idiv Eb */ /* EAX could be used, so precache it */ if (decode.modrm.mod==3) gen_dop_word(DOP_MOV,decode.big_op,DREG(TMPW),&DynRegs[decode.modrm.rm]); gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); void * func=(decode.modrm.reg==6) ? (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); gen_call_function(func,"%Rd%Dd",DREG(TMPB),DREG(TMPW)); dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); goto skipsave; } /* Save the result if memory op */ if (decode.modrm.mod<3) dyn_write_word_release(DREG(EA),src,decode.big_op);skipsave: gen_releasereg(DREG(TMPW));gen_releasereg(DREG(EA));}static void dyn_mov_ev_seg(void) { dyn_get_modrm(); gen_load_host(&Segs.val[decode.modrm.reg],DREG(TMPW),2); if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_write_word_release(DREG(EA),DREG(TMPW),false); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } gen_releasereg(DREG(TMPW));}static void dyn_load_seg(SegNames seg,DynReg * src) { if (cpu.pmode) { gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); } else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src); gen_releasereg(&DynRegs[G_ES+seg]);}static void dyn_load_seg_off_ea(SegNames seg) { dyn_get_modrm(); if (GCC_UNLIKELY(decode.modrm.mod<3)) { dyn_fill_ea(); gen_lea(DREG(TMPB),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPB),DREG(TMPB),false); dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); dyn_load_seg(seg,DREG(TMPB));gen_releasereg(DREG(TMPB)); gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(TMPW)); } else { IllegalOption("dyn_load_seg_off_ea"); }}static void dyn_mov_seg_ev(void) { dyn_get_modrm(); SegNames seg=(SegNames)decode.modrm.reg; if (GCC_UNLIKELY(seg==cs)) IllegalOption("dyn_mov_seg_ev"); if (decode.modrm.mod<3) { dyn_fill_ea(); dyn_read_word(DREG(EA),DREG(EA),false); dyn_load_seg(seg,DREG(EA)); gen_releasereg(DREG(EA)); } else { dyn_load_seg(seg,&DynRegs[decode.modrm.rm]); }}static void dyn_push_seg(SegNames seg) { gen_load_host(&Segs.val[seg],DREG(TMPW),2); dyn_push(DREG(TMPW)); gen_releasereg(DREG(TMPW));}static void dyn_pop_seg(SegNames seg) { if (!cpu.pmode) { dyn_pop(DREG(TMPW)); dyn_load_seg(seg,DREG(TMPW)); gen_releasereg(DREG(TMPW)); } else { gen_releasereg(DREG(ESP)); gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op); dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB)); gen_releasereg(&DynRegs[G_ES+seg]); gen_releasereg(DREG(ESP)); }}static void dyn_pop_ev(void) { dyn_pop(DREG(TMPW)); dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea();// dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); if (decode.big_op) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); } else { gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); } gen_releasereg(DREG(TMPW));}static void dyn_enter(void) { gen_releasereg(DREG(ESP)); gen_releasereg(DREG(EBP)); Bitu bytes=decode_fetchw(); Bitu level=decode_fetchb(); gen_call_function((void *)&CPU_ENTER,"%Id%Id%Id",decode.big_op,bytes,level);}static void dyn_leave(void) { gen_protectflags(); gen_dop_word_var(DOP_MOV,true,DREG(TMPW),&cpu.stack.mask); gen_sop_word(SOP_NOT,true,DREG(TMPW)); gen_dop_word(DOP_AND,true,DREG(ESP),DREG(TMPW)); gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EBP)); gen_dop_word_var(DOP_AND,true,DREG(TMPW),&cpu.stack.mask); gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -