📄 op.c
字号:
#endif/* string ops helpers */void OPPROTO op_addl_ESI_T0(void){ ESI = (uint32_t)(ESI + T0);}void OPPROTO op_addw_ESI_T0(void){ ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);}void OPPROTO op_addl_EDI_T0(void){ EDI = (uint32_t)(EDI + T0);}void OPPROTO op_addw_EDI_T0(void){ EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);}void OPPROTO op_decl_ECX(void){ ECX = (uint32_t)(ECX - 1);}void OPPROTO op_decw_ECX(void){ ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);}#ifdef TARGET_X86_64void OPPROTO op_addq_ESI_T0(void){ ESI = (ESI + T0);}void OPPROTO op_addq_EDI_T0(void){ EDI = (EDI + T0);}void OPPROTO op_decq_ECX(void){ ECX--;}#endif/* push/pop utils */void op_addl_A0_SS(void){ A0 = (uint32_t)(A0 + env->segs[R_SS].base);}void op_subl_A0_2(void){ A0 = (uint32_t)(A0 - 2);}void op_subl_A0_4(void){ A0 = (uint32_t)(A0 - 4);}void op_addl_ESP_4(void){ ESP = (uint32_t)(ESP + 4);}void op_addl_ESP_2(void){ ESP = (uint32_t)(ESP + 2);}void op_addw_ESP_4(void){ ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);}void op_addw_ESP_2(void){ ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);}void op_addl_ESP_im(void){ ESP = (uint32_t)(ESP + PARAM1);}void op_addw_ESP_im(void){ ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);}#ifdef TARGET_X86_64void op_subq_A0_2(void){ A0 -= 2;}void op_subq_A0_8(void){ A0 -= 8;}void op_addq_ESP_8(void){ ESP += 8;}void op_addq_ESP_im(void){ ESP += PARAM1;}#endifvoid OPPROTO op_rdtsc(void){ helper_rdtsc();}void OPPROTO op_cpuid(void){ helper_cpuid();}void OPPROTO op_enter_level(void){ helper_enter_level(PARAM1, PARAM2);}#ifdef TARGET_X86_64void OPPROTO op_enter64_level(void){ helper_enter64_level(PARAM1, PARAM2);}#endifvoid OPPROTO op_sysenter(void){ helper_sysenter();}void OPPROTO op_sysexit(void){ helper_sysexit();}#ifdef TARGET_X86_64void OPPROTO op_syscall(void){ helper_syscall(PARAM1);}void OPPROTO op_sysret(void){ helper_sysret(PARAM1);}#endifvoid OPPROTO op_rdmsr(void){ helper_rdmsr();}void OPPROTO op_wrmsr(void){ helper_wrmsr();}/* bcd *//* XXX: exception */void OPPROTO op_aam(void){ int base = PARAM1; int al, ah; al = EAX & 0xff; ah = al / base; al = al % base; EAX = (EAX & ~0xffff) | al | (ah << 8); CC_DST = al;}void OPPROTO op_aad(void){ int base = PARAM1; int al, ah; al = EAX & 0xff; ah = (EAX >> 8) & 0xff; al = ((ah * base) + al) & 0xff; EAX = (EAX & ~0xffff) | al; CC_DST = al;}void OPPROTO op_aaa(void){ int icarry; int al, ah, af; int eflags; eflags = cc_table[CC_OP].compute_all(); af = eflags & CC_A; al = EAX & 0xff; ah = (EAX >> 8) & 0xff; icarry = (al > 0xf9); if (((al & 0x0f) > 9 ) || af) { al = (al + 6) & 0x0f; ah = (ah + 1 + icarry) & 0xff; eflags |= CC_C | CC_A; } else { eflags &= ~(CC_C | CC_A); al &= 0x0f; } EAX = (EAX & ~0xffff) | al | (ah << 8); CC_SRC = eflags; FORCE_RET();}void OPPROTO op_aas(void){ int icarry; int al, ah, af; int eflags; eflags = cc_table[CC_OP].compute_all(); af = eflags & CC_A; al = EAX & 0xff; ah = (EAX >> 8) & 0xff; icarry = (al < 6); if (((al & 0x0f) > 9 ) || af) { al = (al - 6) & 0x0f; ah = (ah - 1 - icarry) & 0xff; eflags |= CC_C | CC_A; } else { eflags &= ~(CC_C | CC_A); al &= 0x0f; } EAX = (EAX & ~0xffff) | al | (ah << 8); CC_SRC = eflags; FORCE_RET();}void OPPROTO op_daa(void){ int al, af, cf; int eflags; eflags = cc_table[CC_OP].compute_all(); cf = eflags & CC_C; af = eflags & CC_A; al = EAX & 0xff; eflags = 0; if (((al & 0x0f) > 9 ) || af) { al = (al + 6) & 0xff; eflags |= CC_A; } if ((al > 0x9f) || cf) { al = (al + 0x60) & 0xff; eflags |= CC_C; } EAX = (EAX & ~0xff) | al; /* well, speed is not an issue here, so we compute the flags by hand */ eflags |= (al == 0) << 6; /* zf */ eflags |= parity_table[al]; /* pf */ eflags |= (al & 0x80); /* sf */ CC_SRC = eflags; FORCE_RET();}void OPPROTO op_das(void){ int al, al1, af, cf; int eflags; eflags = cc_table[CC_OP].compute_all(); cf = eflags & CC_C; af = eflags & CC_A; al = EAX & 0xff; eflags = 0; al1 = al; if (((al & 0x0f) > 9 ) || af) { eflags |= CC_A; if (al < 6 || cf) eflags |= CC_C; al = (al - 6) & 0xff; } if ((al1 > 0x99) || cf) { al = (al - 0x60) & 0xff; eflags |= CC_C; } EAX = (EAX & ~0xff) | al; /* well, speed is not an issue here, so we compute the flags by hand */ eflags |= (al == 0) << 6; /* zf */ eflags |= parity_table[al]; /* pf */ eflags |= (al & 0x80); /* sf */ CC_SRC = eflags; FORCE_RET();}/* segment handling *//* never use it with R_CS */void OPPROTO op_movl_seg_T0(void){ load_seg(PARAM1, T0);}/* faster VM86 version */void OPPROTO op_movl_seg_T0_vm(void){ int selector; SegmentCache *sc; selector = T0 & 0xffff; /* env->segs[] access */ sc = (SegmentCache *)((char *)env + PARAM1); sc->selector = selector; sc->base = (selector << 4);}void OPPROTO op_movl_T0_seg(void){ T0 = env->segs[PARAM1].selector;}void OPPROTO op_lsl(void){ helper_lsl();}void OPPROTO op_lar(void){ helper_lar();}void OPPROTO op_verr(void){ helper_verr();}void OPPROTO op_verw(void){ helper_verw();}void OPPROTO op_arpl(void){ if ((T0 & 3) < (T1 & 3)) { /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */ T0 = (T0 & ~3) | (T1 & 3); T1 = CC_Z; } else { T1 = 0; } FORCE_RET();} void OPPROTO op_arpl_update(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); CC_SRC = (eflags & ~CC_Z) | T1;} /* T0: segment, T1:eip */void OPPROTO op_ljmp_protected_T0_T1(void){ helper_ljmp_protected_T0_T1(PARAM1);}void OPPROTO op_lcall_real_T0_T1(void){ helper_lcall_real_T0_T1(PARAM1, PARAM2);}void OPPROTO op_lcall_protected_T0_T1(void){ helper_lcall_protected_T0_T1(PARAM1, PARAM2);}void OPPROTO op_iret_real(void){ helper_iret_real(PARAM1);}void OPPROTO op_iret_protected(void){ helper_iret_protected(PARAM1, PARAM2);}void OPPROTO op_lret_protected(void){ helper_lret_protected(PARAM1, PARAM2);}void OPPROTO op_lldt_T0(void){ helper_lldt_T0();}void OPPROTO op_ltr_T0(void){ helper_ltr_T0();}/* CR registers access */void OPPROTO op_movl_crN_T0(void){ helper_movl_crN_T0(PARAM1);}#if !defined(CONFIG_USER_ONLY) void OPPROTO op_movtl_T0_cr8(void){ T0 = cpu_get_apic_tpr(env);}#endif/* DR registers access */void OPPROTO op_movl_drN_T0(void){ helper_movl_drN_T0(PARAM1);}void OPPROTO op_lmsw_T0(void){ /* only 4 lower bits of CR0 are modified. PE cannot be set to zero if already set to one. */ T0 = (env->cr[0] & ~0xe) | (T0 & 0xf); helper_movl_crN_T0(0);}void OPPROTO op_invlpg_A0(void){ helper_invlpg(A0);}void OPPROTO op_movl_T0_env(void){ T0 = *(uint32_t *)((char *)env + PARAM1);}void OPPROTO op_movl_env_T0(void){ *(uint32_t *)((char *)env + PARAM1) = T0;}void OPPROTO op_movl_env_T1(void){ *(uint32_t *)((char *)env + PARAM1) = T1;}void OPPROTO op_movtl_T0_env(void){ T0 = *(target_ulong *)((char *)env + PARAM1);}void OPPROTO op_movtl_env_T0(void){ *(target_ulong *)((char *)env + PARAM1) = T0;}void OPPROTO op_movtl_T1_env(void){ T1 = *(target_ulong *)((char *)env + PARAM1);}void OPPROTO op_movtl_env_T1(void){ *(target_ulong *)((char *)env + PARAM1) = T1;}void OPPROTO op_clts(void){ env->cr[0] &= ~CR0_TS_MASK; env->hflags &= ~HF_TS_MASK;}/* flags handling */void OPPROTO op_goto_tb0(void){ GOTO_TB(op_goto_tb0, PARAM1, 0);}void OPPROTO op_goto_tb1(void){ GOTO_TB(op_goto_tb1, PARAM1, 1);}void OPPROTO op_jmp_label(void){ GOTO_LABEL_PARAM(1);}void OPPROTO op_jnz_T0_label(void){ if (T0) GOTO_LABEL_PARAM(1); FORCE_RET();}void OPPROTO op_jz_T0_label(void){ if (!T0) GOTO_LABEL_PARAM(1); FORCE_RET();}/* slow set cases (compute x86 flags) */void OPPROTO op_seto_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = (eflags >> 11) & 1;}void OPPROTO op_setb_T0_cc(void){ T0 = cc_table[CC_OP].compute_c();}void OPPROTO op_setz_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = (eflags >> 6) & 1;}void OPPROTO op_setbe_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = (eflags & (CC_Z | CC_C)) != 0;}void OPPROTO op_sets_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = (eflags >> 7) & 1;}void OPPROTO op_setp_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = (eflags >> 2) & 1;}void OPPROTO op_setl_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;}void OPPROTO op_setle_T0_cc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;}void OPPROTO op_xor_T0_1(void){ T0 ^= 1;}void OPPROTO op_set_cc_op(void){ CC_OP = PARAM1;}void OPPROTO op_mov_T0_cc(void){ T0 = cc_table[CC_OP].compute_all();}/* XXX: clear VIF/VIP in all ops ? */void OPPROTO op_movl_eflags_T0(void){ load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));}void OPPROTO op_movw_eflags_T0(void){ load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);}void OPPROTO op_movl_eflags_T0_io(void){ load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));}void OPPROTO op_movw_eflags_T0_io(void){ load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);}void OPPROTO op_movl_eflags_T0_cpl0(void){ load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));}void OPPROTO op_movw_eflags_T0_cpl0(void){ load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);}#if 0/* vm86plus version */void OPPROTO op_movw_eflags_T0_vm(void){ int eflags; eflags = T0; CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); DF = 1 - (2 * ((eflags >> 10) & 1)); /* we also update some system flags as in user mode */ env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) | (eflags & FL_UPDATE_MASK16); if (eflags & IF_MASK) { env->eflags |= VIF_MASK; if (env->eflags & VIP_MASK) { EIP = PARAM1; raise_exception(EXCP0D_GPF); } } FORCE_RET();}void OPPROTO op_movl_eflags_T0_vm(void){ int eflags; eflags = T0; CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); DF = 1 - (2 * ((eflags >> 10) & 1)); /* we also update some system flags as in user mode */ env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) | (eflags & FL_UPDATE_MASK32); if (eflags & IF_MASK) { env->eflags |= VIF_MASK; if (env->eflags & VIP_MASK) { EIP = PARAM1; raise_exception(EXCP0D_GPF); } } FORCE_RET();}#endif/* XXX: compute only O flag */void OPPROTO op_movb_eflags_T0(void){ int of; of = cc_table[CC_OP].compute_all() & CC_O; CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;}void OPPROTO op_movl_T0_eflags(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); eflags |= (DF & DF_MASK); eflags |= env->eflags & ~(VM_MASK | RF_MASK); T0 = eflags;}/* vm86plus version */#if 0void OPPROTO op_movl_T0_eflags_vm(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); eflags |= (DF & DF_MASK); eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK); if (env->eflags & VIF_MASK) eflags |= IF_MASK; T0 = eflags;}#endifvoid OPPROTO op_cld(void){ DF = 1;}void OPPROTO op_std(void){ DF = -1;}void OPPROTO op_clc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); eflags &= ~CC_C; CC_SRC = eflags;}void OPPROTO op_stc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); eflags |= CC_C; CC_SRC = eflags;}void OPPROTO op_cmc(void){ int eflags; eflags = cc_table[CC_OP].compute_all(); eflags ^= CC_C; CC_SRC = eflags;}void OPPROTO op_salc(void){ int cf; cf = cc_table[CC_OP].compute_c(); EAX = (EAX & ~0xff) | ((-cf) & 0xff);}static int compute_all_eflags(void){ return CC_SRC;}static int compute_c_eflags(void){ return CC_SRC & CC_C;}CCTable cc_table[CC_OP_NB] = { [CC_OP_DYNAMIC] = { /* should never happen */ }, [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags }, [CC_OP_MULB] = { compute_all_mulb, compute_c_mull }, [CC_OP_MULW] = { compute_all_mulw, compute_c_mull }, [CC_OP_MULL] = { compute_all_mull, compute_c_mull }, [CC_OP_ADDB] = { compute_all_addb, compute_c_addb }, [CC_OP_ADDW] = { compute_all_addw, compute_c_addw }, [CC_OP_ADDL] = { compute_all_addl, compute_c_addl }, [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb }, [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw }, [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl }, [CC_OP_SUBB] = { compute_all_subb, compute_c_subb }, [CC_OP_SUBW] = { compute_all_subw, compute_c_subw }, [CC_OP_SUBL] = { compute_all_subl, compute_c_subl }, [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb }, [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw }, [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl }, [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb }, [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw }, [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl }, [CC_OP_INCB] = { compute_all_incb, compute_c_incl }, [CC_OP_INCW] = { compute_all_incw, compute_c_incl }, [CC_OP_INCL] = { compute_all_incl, compute_c_incl }, [CC_OP_DECB] = { compute_all_decb, compute_c_incl }, [CC_OP_DECW] = { compute_all_decw, compute_c_incl }, [CC_OP_DECL] = { compute_all_decl, compute_c_incl }, [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb }, [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw }, [CC_OP_SHLL] = { compute_all_shll, compute_c_shll }, [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl }, [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl }, [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl },#ifdef TARGET_X86_64 [CC_OP_MULQ] = { compute_all_mulq, compute_c_mull }, [CC_OP_ADDQ] = { compute_all_addq, compute_c_addq }, [CC_OP_ADCQ] = { compute_all_adcq, compute_c_adcq }, [CC_OP_SUBQ] = { compute_all_subq, compute_c_subq }, [CC_OP_SBBQ] = { compute_all_sbbq, compute_c_sbbq }, [CC_OP_LOGICQ] = { compute_all_logicq, compute_c_logicq }, [CC_OP_INCQ] = { compute_all_incq, compute_c_incl }, [CC_OP_DECQ] = { compute_all_decq, compute_c_incl }, [CC_OP_SHLQ] = { compute_all_shlq, compute_c_shlq }, [CC_OP_SARQ] = { compute_all_sarq, compute_c_sarl },#endif};/* floating point support. Some of the code for complicated x87 functions comes from the LGPL'ed x86 emulator found in the Willows
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -