diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-12 22:05:13 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-12 22:05:13 +0000 |
commit | b5b38f61b8d5f4fb900472bade38e7ff610223aa (patch) | |
tree | 4be7549d8eb4cefe86c83db5995fbf220f9cedb1 | |
parent | dbd02bdf797ea006d0c509439fc550939112e635 (diff) | |
download | qemu-b5b38f61b8d5f4fb900472bade38e7ff610223aa.zip qemu-b5b38f61b8d5f4fb900472bade38e7ff610223aa.tar.gz qemu-b5b38f61b8d5f4fb900472bade38e7ff610223aa.tar.bz2 |
converted more helpers to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4447 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | target-i386/exec.h | 82 | ||||
-rw-r--r-- | target-i386/helper.c | 426 | ||||
-rw-r--r-- | target-i386/helper.h | 75 | ||||
-rw-r--r-- | target-i386/op.c | 442 | ||||
-rw-r--r-- | target-i386/translate.c | 120 |
5 files changed, 498 insertions, 647 deletions
diff --git a/target-i386/exec.h b/target-i386/exec.h index 3dee6c3..72dc016 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -95,10 +95,6 @@ extern int loglevel; #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) #define ST1 ST(1) -#ifdef USE_FP_CONVERT -#define FP_CONVERT (env->fp_convert) -#endif - #include "cpu.h" #include "exec-all.h" @@ -109,15 +105,13 @@ typedef struct CCTable { extern CCTable cc_table[]; -void load_seg(int seg_reg, int selector); +void helper_load_seg(int seg_reg, int selector); void helper_ljmp_protected_T0_T1(int next_eip); void helper_lcall_real_T0_T1(int shift, int next_eip); void helper_lcall_protected_T0_T1(int shift, int next_eip); void helper_iret_real(int shift); void helper_iret_protected(int shift, int next_eip); void helper_lret_protected(int shift, int addend); -void helper_lldt_T0(void); -void helper_ltr_T0(void); void helper_movl_crN_T0(int reg); void helper_movl_drN_T0(int reg); void helper_invlpg(target_ulong addr); @@ -150,27 +144,7 @@ void OPPROTO op_movl_T0_eflags(void); void helper_mulq_EAX_T0(void); void helper_imulq_EAX_T0(void); void helper_imulq_T0_T1(void); -void helper_divq_EAX_T0(void); -void helper_idivq_EAX_T0(void); -void helper_bswapq_T0(void); void helper_cmpxchg8b(void); -void helper_single_step(void); -void helper_cpuid(void); -void helper_enter_level(int level, int data32); -void helper_enter64_level(int level, int data64); -void helper_sysenter(void); -void helper_sysexit(void); -void helper_syscall(int next_eip_addend); -void helper_sysret(int dflag); -void helper_rdtsc(void); -void helper_rdpmc(void); -void helper_rdmsr(void); -void helper_wrmsr(void); -void helper_lsl(void); -void helper_lar(void); -void helper_verr(void); -void helper_verw(void); -void helper_rsm(void); void check_iob_T0(void); void check_iow_T0(void); @@ -183,46 +157,6 @@ void check_iol_DX(void); #include "softmmu_exec.h" -static inline double ldfq(target_ulong ptr) -{ - union { - double d; - uint64_t i; - } u; - u.i = ldq(ptr); - return u.d; -} - -static inline void stfq(target_ulong ptr, double v) -{ - union { - double d; - uint64_t i; - } u; - u.d = v; - stq(ptr, u.i); -} - -static inline float ldfl(target_ulong ptr) -{ - union { - float f; - uint32_t i; - } u; - u.i = ldl(ptr); - return u.f; -} - -static inline void stfl(target_ulong ptr, float v) -{ - union { - float f; - uint32_t i; - } u; - u.f = v; - stl(ptr, u.i); -} - #endif /* !defined(CONFIG_USER_ONLY) */ #ifdef USE_X86LDOUBLE @@ -429,20 +363,6 @@ extern const CPU86_LDouble f15rk[7]; void fpu_raise_exception(void); void restore_native_fp_state(CPUState *env); void save_native_fp_state(CPUState *env); -float approx_rsqrt(float a); -float approx_rcp(float a); -void update_fp_status(void); -void helper_hlt(void); -void helper_monitor(void); -void helper_mwait(void); -void helper_vmrun(target_ulong addr); -void helper_vmmcall(void); -void helper_vmload(target_ulong addr); -void helper_vmsave(target_ulong addr); -void helper_stgi(void); -void helper_clgi(void); -void helper_skinit(void); -void helper_invlpga(void); void vmexit(uint64_t exit_code, uint64_t exit_info_1); extern const uint8_t parity_table[256]; diff --git a/target-i386/helper.c b/target-i386/helper.c index aa79e51..0d0f5ff 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1609,7 +1609,79 @@ int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den) } #endif -void helper_divl_EAX_T0(target_ulong t0) +/* division, flags are undefined */ + +void helper_divb_AL(target_ulong t0) +{ + unsigned int num, den, q, r; + + num = (EAX & 0xffff); + den = (t0 & 0xff); + if (den == 0) { + raise_exception(EXCP00_DIVZ); + } + q = (num / den); + if (q > 0xff) + raise_exception(EXCP00_DIVZ); + q &= 0xff; + r = (num % den) & 0xff; + EAX = (EAX & ~0xffff) | (r << 8) | q; +} + +void helper_idivb_AL(target_ulong t0) +{ + int num, den, q, r; + + num = (int16_t)EAX; + den = (int8_t)t0; + if (den == 0) { + raise_exception(EXCP00_DIVZ); + } + q = (num / den); + if (q != (int8_t)q) + raise_exception(EXCP00_DIVZ); + q &= 0xff; + r = (num % den) & 0xff; + EAX = (EAX & ~0xffff) | (r << 8) | q; +} + +void helper_divw_AX(target_ulong t0) +{ + unsigned int num, den, q, r; + + num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); + den = (t0 & 0xffff); + if (den == 0) { + raise_exception(EXCP00_DIVZ); + } + q = (num / den); + if (q > 0xffff) + raise_exception(EXCP00_DIVZ); + q &= 0xffff; + r = (num % den) & 0xffff; + EAX = (EAX & ~0xffff) | q; + EDX = (EDX & ~0xffff) | r; +} + +void helper_idivw_AX(target_ulong t0) +{ + int num, den, q, r; + + num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); + den = (int16_t)t0; + if (den == 0) { + raise_exception(EXCP00_DIVZ); + } + q = (num / den); + if (q != (int16_t)q) + raise_exception(EXCP00_DIVZ); + q &= 0xffff; + r = (num % den) & 0xffff; + EAX = (EAX & ~0xffff) | q; + EDX = (EDX & ~0xffff) | r; +} + +void helper_divl_EAX(target_ulong t0) { unsigned int den, r; uint64_t num, q; @@ -1631,7 +1703,7 @@ void helper_divl_EAX_T0(target_ulong t0) EDX = (uint32_t)r; } -void helper_idivl_EAX_T0(target_ulong t0) +void helper_idivl_EAX(target_ulong t0) { int den, r; int64_t num, q; @@ -1653,6 +1725,138 @@ void helper_idivl_EAX_T0(target_ulong t0) EDX = (uint32_t)r; } +/* bcd */ + +/* XXX: exception */ +void helper_aam(int base) +{ + int al, ah; + al = EAX & 0xff; + ah = al / base; + al = al % base; + EAX = (EAX & ~0xffff) | al | (ah << 8); + CC_DST = al; +} + +void helper_aad(int base) +{ + int al, ah; + al = EAX & 0xff; + ah = (EAX >> 8) & 0xff; + al = ((ah * base) + al) & 0xff; + EAX = (EAX & ~0xffff) | al; + CC_DST = al; +} + +void helper_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 helper_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 helper_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 helper_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(); +} + void helper_cmpxchg8b(void) { uint64_t d; @@ -1845,15 +2049,14 @@ void helper_enter64_level(int level, int data64) } #endif -void helper_lldt_T0(void) +void helper_lldt(int selector) { - int selector; SegmentCache *dt; uint32_t e1, e2; int index, entry_limit; target_ulong ptr; - selector = T0 & 0xffff; + selector &= 0xffff; if ((selector & 0xfffc) == 0) { /* XXX: NULL selector case: invalid LDT */ env->ldt.base = 0; @@ -1893,15 +2096,14 @@ void helper_lldt_T0(void) env->ldt.selector = selector; } -void helper_ltr_T0(void) +void helper_ltr(int selector) { - int selector; SegmentCache *dt; uint32_t e1, e2; int index, type, entry_limit; target_ulong ptr; - selector = T0 & 0xffff; + selector &= 0xffff; if ((selector & 0xfffc) == 0) { /* NULL selector case: invalid TR */ env->tr.base = 0; @@ -1950,7 +2152,7 @@ void helper_ltr_T0(void) } /* only works if protected mode and not VM86. seg_reg must be != R_CS */ -void load_seg(int seg_reg, int selector) +void helper_load_seg(int seg_reg, int selector) { uint32_t e1, e2; int cpl, dpl, rpl; @@ -2916,14 +3118,14 @@ void helper_rdmsr(void) } #endif -void helper_lsl(void) +void helper_lsl(uint32_t selector) { - unsigned int selector, limit; + unsigned int limit; uint32_t e1, e2, eflags; int rpl, dpl, cpl, type; + selector &= 0xffff; eflags = cc_table[CC_OP].compute_all(); - selector = T0 & 0xffff; if (load_segment(&e1, &e2, selector) != 0) goto fail; rpl = selector & 3; @@ -2959,14 +3161,13 @@ void helper_lsl(void) CC_SRC = eflags | CC_Z; } -void helper_lar(void) +void helper_lar(uint32_t selector) { - unsigned int selector; uint32_t e1, e2, eflags; int rpl, dpl, cpl, type; + selector &= 0xffff; eflags = cc_table[CC_OP].compute_all(); - selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) goto fail; if (load_segment(&e1, &e2, selector) != 0) @@ -3006,14 +3207,13 @@ void helper_lar(void) CC_SRC = eflags | CC_Z; } -void helper_verr(void) +void helper_verr(uint32_t selector) { - unsigned int selector; uint32_t e1, e2, eflags; int rpl, dpl, cpl; + selector &= 0xffff; eflags = cc_table[CC_OP].compute_all(); - selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) goto fail; if (load_segment(&e1, &e2, selector) != 0) @@ -3040,14 +3240,13 @@ void helper_verr(void) CC_SRC = eflags | CC_Z; } -void helper_verw(void) +void helper_verw(uint32_t selector) { - unsigned int selector; uint32_t e1, e2, eflags; int rpl, dpl, cpl; + selector &= 0xffff; eflags = cc_table[CC_OP].compute_all(); - selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) goto fail; if (load_segment(&e1, &e2, selector) != 0) @@ -3484,6 +3683,44 @@ uint32_t helper_fnstcw(void) return env->fpuc; } +static void update_fp_status(void) +{ + int rnd_type; + + /* set rounding mode */ + switch(env->fpuc & RC_MASK) { + default: + case RC_NEAR: + rnd_type = float_round_nearest_even; + break; + case RC_DOWN: + rnd_type = float_round_down; + break; + case RC_UP: + rnd_type = float_round_up; + break; + case RC_CHOP: + rnd_type = float_round_to_zero; + break; + } + set_float_rounding_mode(rnd_type, &env->fp_status); +#ifdef FLOATX80 + switch((env->fpuc >> 8) & 3) { + case 0: + rnd_type = 32; + break; + case 2: + rnd_type = 64; + break; + case 3: + default: + rnd_type = 80; + break; + } + set_floatx80_rounding_precision(rnd_type, &env->fp_status); +#endif +} + void helper_fldcw(uint32_t val) { env->fpuc = val; @@ -4207,38 +4444,33 @@ void helper_imulq_T0_T1(void) CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); } -void helper_divq_EAX_T0(void) +void helper_divq_EAX(target_ulong t0) { uint64_t r0, r1; - if (T0 == 0) { + if (t0 == 0) { raise_exception(EXCP00_DIVZ); } r0 = EAX; r1 = EDX; - if (div64(&r0, &r1, T0)) + if (div64(&r0, &r1, t0)) raise_exception(EXCP00_DIVZ); EAX = r0; EDX = r1; } -void helper_idivq_EAX_T0(void) +void helper_idivq_EAX(target_ulong t0) { uint64_t r0, r1; - if (T0 == 0) { + if (t0 == 0) { raise_exception(EXCP00_DIVZ); } r0 = EAX; r1 = EDX; - if (idiv64(&r0, &r1, T0)) + if (idiv64(&r0, &r1, t0)) raise_exception(EXCP00_DIVZ); EAX = r0; EDX = r1; } - -void helper_bswapq_T0(void) -{ - T0 = bswap64(T0); -} #endif void helper_hlt(void) @@ -4249,7 +4481,7 @@ void helper_hlt(void) cpu_loop_exit(); } -void helper_monitor(void) +void helper_monitor(target_ulong ptr) { if ((uint32_t)ECX != 0) raise_exception(EXCP0D_GPF); @@ -4269,52 +4501,90 @@ void helper_mwait(void) } } -float approx_rsqrt(float a) +void helper_debug(void) { - return 1.0 / sqrt(a); + env->exception_index = EXCP_DEBUG; + cpu_loop_exit(); } -float approx_rcp(float a) +void helper_raise_interrupt(int intno, int next_eip_addend) { - return 1.0 / a; + raise_interrupt(intno, 1, 0, next_eip_addend); } -void update_fp_status(void) +void helper_raise_exception(int exception_index) { - int rnd_type; + raise_exception(exception_index); +} - /* set rounding mode */ - switch(env->fpuc & RC_MASK) { - default: - case RC_NEAR: - rnd_type = float_round_nearest_even; - break; - case RC_DOWN: - rnd_type = float_round_down; - break; - case RC_UP: - rnd_type = float_round_up; - break; - case RC_CHOP: - rnd_type = float_round_to_zero; - break; - } - set_float_rounding_mode(rnd_type, &env->fp_status); -#ifdef FLOATX80 - switch((env->fpuc >> 8) & 3) { - case 0: - rnd_type = 32; - break; - case 2: - rnd_type = 64; - break; - case 3: - default: - rnd_type = 80; - break; +void helper_cli(void) +{ + env->eflags &= ~IF_MASK; +} + +void helper_sti(void) +{ + env->eflags |= IF_MASK; +} + +#if 0 +/* vm86plus instructions */ +void helper_cli_vm(void) +{ + env->eflags &= ~VIF_MASK; +} + +void helper_sti_vm(void) +{ + env->eflags |= VIF_MASK; + if (env->eflags & VIP_MASK) { + raise_exception(EXCP0D_GPF); } - set_floatx80_rounding_precision(rnd_type, &env->fp_status); +} #endif + +void helper_set_inhibit_irq(void) +{ + env->hflags |= HF_INHIBIT_IRQ_MASK; +} + +void helper_reset_inhibit_irq(void) +{ + env->hflags &= ~HF_INHIBIT_IRQ_MASK; +} + +void helper_boundw(void) +{ + int low, high, v; + low = ldsw(A0); + high = ldsw(A0 + 2); + v = (int16_t)T0; + if (v < low || v > high) { + raise_exception(EXCP05_BOUND); + } + FORCE_RET(); +} + +void helper_boundl(void) +{ + int low, high, v; + low = ldl(A0); + high = ldl(A0 + 4); + v = T0; + if (v < low || v > high) { + raise_exception(EXCP05_BOUND); + } + FORCE_RET(); +} + +static float approx_rsqrt(float a) +{ + return 1.0 / sqrt(a); +} + +static float approx_rcp(float a) +{ + return 1.0 / a; } #if !defined(CONFIG_USER_ONLY) @@ -4391,10 +4661,10 @@ void helper_clgi(void) #if defined(CONFIG_USER_ONLY) -void helper_vmrun(target_ulong addr) { } +void helper_vmrun(void) { } void helper_vmmcall(void) { } -void helper_vmload(target_ulong addr) { } -void helper_vmsave(target_ulong addr) { } +void helper_vmload(void) { } +void helper_vmsave(void) { } void helper_skinit(void) { } void helper_invlpga(void) { } void vmexit(uint64_t exit_code, uint64_t exit_info_1) { } @@ -4421,11 +4691,13 @@ static inline uint16_t cpu2vmcb_attrib(uint32_t cpu_attrib) | ((cpu_attrib & 0xf00000) >> 12); /* AVL, L, DB, G */ } -void helper_vmrun(target_ulong addr) +void helper_vmrun(void) { + target_ulong addr; uint32_t event_inj; uint32_t int_ctl; + addr = EAX; if (loglevel & CPU_LOG_TB_IN_ASM) fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr); @@ -4592,8 +4864,10 @@ void helper_vmmcall(void) fprintf(logfile,"vmmcall!\n"); } -void helper_vmload(target_ulong addr) +void helper_vmload(void) { + target_ulong addr; + addr = EAX; if (loglevel & CPU_LOG_TB_IN_ASM) fprintf(logfile,"vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), @@ -4616,8 +4890,10 @@ void helper_vmload(target_ulong addr) env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_eip)); } -void helper_vmsave(target_ulong addr) +void helper_vmsave(void) { + target_ulong addr; + addr = EAX; if (loglevel & CPU_LOG_TB_IN_ASM) fprintf(logfile,"vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), diff --git a/target-i386/helper.h b/target-i386/helper.h index 4371c83..3bce500 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -1,7 +1,78 @@ #define TCG_HELPER_PROTO -void TCG_HELPER_PROTO helper_divl_EAX_T0(target_ulong t0); -void TCG_HELPER_PROTO helper_idivl_EAX_T0(target_ulong t0); +void helper_divb_AL(target_ulong t0); +void helper_idivb_AL(target_ulong t0); +void helper_divw_AX(target_ulong t0); +void helper_idivw_AX(target_ulong t0); +void helper_divl_EAX(target_ulong t0); +void helper_idivl_EAX(target_ulong t0); +#ifdef TARGET_X86_64 +void helper_divq_EAX(target_ulong t0); +void helper_idivq_EAX(target_ulong t0); +#endif + +void helper_aam(int base); +void helper_aad(int base); +void helper_aaa(void); +void helper_aas(void); +void helper_daa(void); +void helper_das(void); + +void helper_lsl(uint32_t selector); +void helper_lar(uint32_t selector); +void helper_verr(uint32_t selector); +void helper_verw(uint32_t selector); +void helper_lldt(int selector); +void helper_ltr(int selector); +void helper_load_seg(int seg_reg, int selector); +void helper_ljmp_protected_T0_T1(int next_eip); +void helper_lcall_real_T0_T1(int shift, int next_eip); +void helper_lcall_protected_T0_T1(int shift, int next_eip); +void helper_iret_real(int shift); +void helper_iret_protected(int shift, int next_eip); +void helper_lret_protected(int shift, int addend); +void helper_movl_crN_T0(int reg); +void helper_movl_drN_T0(int reg); +void helper_invlpg(target_ulong addr); + +void helper_enter_level(int level, int data32); +#ifdef TARGET_X86_64 +void helper_enter64_level(int level, int data64); +#endif +void helper_sysenter(void); +void helper_sysexit(void); +#ifdef TARGET_X86_64 +void helper_syscall(int next_eip_addend); +void helper_sysret(int dflag); +#endif +void helper_hlt(void); +void helper_monitor(target_ulong ptr); +void helper_mwait(void); +void helper_debug(void); +void helper_raise_interrupt(int intno, int next_eip_addend); +void helper_raise_exception(int exception_index); +void helper_cli(void); +void helper_sti(void); +void helper_set_inhibit_irq(void); +void helper_reset_inhibit_irq(void); +void helper_boundw(void); +void helper_boundl(void); +void helper_rsm(void); +void helper_single_step(void); +void helper_cpuid(void); +void helper_rdtsc(void); +void helper_rdpmc(void); +void helper_rdmsr(void); +void helper_wrmsr(void); + +void helper_vmrun(void); +void helper_vmmcall(void); +void helper_vmload(void); +void helper_vmsave(void); +void helper_stgi(void); +void helper_clgi(void); +void helper_skinit(void); +void helper_invlpga(void); /* x86 FPU */ diff --git a/target-i386/op.c b/target-i386/op.c index e184a8d..69f3aae 100644 --- a/target-i386/op.c +++ b/target-i386/op.c @@ -290,90 +290,6 @@ void OPPROTO op_imulq_T0_T1(void) } #endif -/* division, flags are undefined */ - -void OPPROTO op_divb_AL_T0(void) -{ - unsigned int num, den, q, r; - - num = (EAX & 0xffff); - den = (T0 & 0xff); - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q > 0xff) - raise_exception(EXCP00_DIVZ); - q &= 0xff; - r = (num % den) & 0xff; - EAX = (EAX & ~0xffff) | (r << 8) | q; -} - -void OPPROTO op_idivb_AL_T0(void) -{ - int num, den, q, r; - - num = (int16_t)EAX; - den = (int8_t)T0; - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q != (int8_t)q) - raise_exception(EXCP00_DIVZ); - q &= 0xff; - r = (num % den) & 0xff; - EAX = (EAX & ~0xffff) | (r << 8) | q; -} - -void OPPROTO op_divw_AX_T0(void) -{ - unsigned int num, den, q, r; - - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); - den = (T0 & 0xffff); - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q > 0xffff) - raise_exception(EXCP00_DIVZ); - q &= 0xffff; - r = (num % den) & 0xffff; - EAX = (EAX & ~0xffff) | q; - EDX = (EDX & ~0xffff) | r; -} - -void OPPROTO op_idivw_AX_T0(void) -{ - int num, den, q, r; - - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); - den = (int16_t)T0; - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q != (int16_t)q) - raise_exception(EXCP00_DIVZ); - q &= 0xffff; - r = (num % den) & 0xffff; - EAX = (EAX & ~0xffff) | q; - EDX = (EDX & ~0xffff) | r; -} - -#ifdef TARGET_X86_64 -void OPPROTO op_divq_EAX_T0(void) -{ - helper_divq_EAX_T0(); -} - -void OPPROTO op_idivq_EAX_T0(void) -{ - helper_idivq_EAX_T0(); -} -#endif - /* constant load & misc op */ /* XXX: consistent names */ @@ -423,42 +339,6 @@ void OPPROTO op_addq_A0_AL(void) #endif -void OPPROTO op_hlt(void) -{ - helper_hlt(); -} - -void OPPROTO op_monitor(void) -{ - helper_monitor(); -} - -void OPPROTO op_mwait(void) -{ - helper_mwait(); -} - -void OPPROTO op_debug(void) -{ - env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); -} - -void OPPROTO op_raise_interrupt(void) -{ - int intno, next_eip_addend; - intno = PARAM1; - next_eip_addend = PARAM2; - raise_interrupt(intno, 1, 0, next_eip_addend); -} - -void OPPROTO op_raise_exception(void) -{ - int exception_index; - exception_index = PARAM1; - raise_exception(exception_index); -} - void OPPROTO op_into(void) { int eflags; @@ -469,83 +349,11 @@ void OPPROTO op_into(void) FORCE_RET(); } -void OPPROTO op_cli(void) -{ - env->eflags &= ~IF_MASK; -} - -void OPPROTO op_sti(void) -{ - env->eflags |= IF_MASK; -} - -void OPPROTO op_set_inhibit_irq(void) -{ - env->hflags |= HF_INHIBIT_IRQ_MASK; -} - -void OPPROTO op_reset_inhibit_irq(void) -{ - env->hflags &= ~HF_INHIBIT_IRQ_MASK; -} - -void OPPROTO op_rsm(void) -{ - helper_rsm(); -} - -#if 0 -/* vm86plus instructions */ -void OPPROTO op_cli_vm(void) -{ - env->eflags &= ~VIF_MASK; -} - -void OPPROTO op_sti_vm(void) -{ - env->eflags |= VIF_MASK; - if (env->eflags & VIP_MASK) { - EIP = PARAM1; - raise_exception(EXCP0D_GPF); - } - FORCE_RET(); -} -#endif - -void OPPROTO op_boundw(void) -{ - int low, high, v; - low = ldsw(A0); - high = ldsw(A0 + 2); - v = (int16_t)T0; - if (v < low || v > high) { - raise_exception(EXCP05_BOUND); - } - FORCE_RET(); -} - -void OPPROTO op_boundl(void) -{ - int low, high, v; - low = ldl(A0); - high = ldl(A0 + 4); - v = T0; - if (v < low || v > high) { - raise_exception(EXCP05_BOUND); - } - FORCE_RET(); -} - void OPPROTO op_cmpxchg8b(void) { helper_cmpxchg8b(); } -void OPPROTO op_single_step(void) -{ - helper_single_step(); -} - /* multiple size ops */ #define ldul ldl @@ -680,197 +488,36 @@ void OPPROTO op_decq_ECX(void) } #endif -void OPPROTO op_rdtsc(void) -{ - helper_rdtsc(); -} - -void OPPROTO op_rdpmc(void) -{ - helper_rdpmc(); -} - -void OPPROTO op_cpuid(void) -{ - helper_cpuid(); -} - -void OPPROTO op_enter_level(void) -{ - helper_enter_level(PARAM1, PARAM2); -} - -#ifdef TARGET_X86_64 -void OPPROTO op_enter64_level(void) -{ - helper_enter64_level(PARAM1, PARAM2); -} -#endif - -void OPPROTO op_sysenter(void) -{ - helper_sysenter(); -} - -void OPPROTO op_sysexit(void) -{ - helper_sysexit(); -} - -#ifdef TARGET_X86_64 -void OPPROTO op_syscall(void) -{ - helper_syscall(PARAM1); -} - -void OPPROTO op_sysret(void) -{ - helper_sysret(PARAM1); -} -#endif - -void 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; + helper_aam(PARAM1); } 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; + helper_aad(PARAM1); } 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(); + helper_aaa(); } 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(); + helper_aas(); } 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(); + helper_daa(); } 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(); + helper_das(); } /* segment handling */ @@ -878,7 +525,7 @@ void OPPROTO op_das(void) /* never use it with R_CS */ void OPPROTO op_movl_seg_T0(void) { - load_seg(PARAM1, T0); + helper_load_seg(PARAM1, T0); } /* faster VM86 version */ @@ -901,22 +548,22 @@ void OPPROTO op_movl_T0_seg(void) void OPPROTO op_lsl(void) { - helper_lsl(); + helper_lsl(T0); } void OPPROTO op_lar(void) { - helper_lar(); + helper_lar(T0); } void OPPROTO op_verr(void) { - helper_verr(); + helper_verr(T0); } void OPPROTO op_verw(void) { - helper_verw(); + helper_verw(T0); } void OPPROTO op_arpl(void) @@ -969,16 +616,6 @@ 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) { @@ -1046,11 +683,6 @@ void OPPROTO op_lmsw_T0(void) 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); @@ -1282,16 +914,6 @@ void OPPROTO op_movl_T0_eflags_vm(void) } #endif -void OPPROTO op_cld(void) -{ - DF = 1; -} - -void OPPROTO op_std(void) -{ - DF = -1; -} - void OPPROTO op_clc(void) { int eflags; @@ -1422,45 +1044,3 @@ void OPPROTO op_com_dummy(void) { T0 = 0; } - -/* Secure Virtual Machine ops */ - -void OPPROTO op_vmrun(void) -{ - helper_vmrun(EAX); -} - -void OPPROTO op_vmmcall(void) -{ - helper_vmmcall(); -} - -void OPPROTO op_vmload(void) -{ - helper_vmload(EAX); -} - -void OPPROTO op_vmsave(void) -{ - helper_vmsave(EAX); -} - -void OPPROTO op_stgi(void) -{ - helper_stgi(); -} - -void OPPROTO op_clgi(void) -{ - helper_clgi(); -} - -void OPPROTO op_skinit(void) -{ - helper_skinit(); -} - -void OPPROTO op_invlpga(void) -{ - helper_invlpga(); -} diff --git a/target-i386/translate.c b/target-i386/translate.c index 0abee6a..5c96f89 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2275,7 +2275,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); gen_op_st_T0_A0(ot + s->mem_index); if (level) { - gen_op_enter64_level(level, (ot == OT_QUAD)); + /* XXX: must save state */ + tcg_gen_helper_0_2(helper_enter64_level, + tcg_const_i32(level), + tcg_const_i32((ot == OT_QUAD))); } gen_op_mov_reg_T1(ot, R_EBP); gen_op_addl_T1_im( -esp_addend + (-opsize * level) ); @@ -2297,7 +2300,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); gen_op_st_T0_A0(ot + s->mem_index); if (level) { - gen_op_enter_level(level, s->dflag); + /* XXX: must save state */ + tcg_gen_helper_0_2(helper_enter_level, + tcg_const_i32(level), + tcg_const_i32(s->dflag)); } gen_op_mov_reg_T1(ot, R_EBP); gen_op_addl_T1_im( -esp_addend + (-opsize * level) ); @@ -2310,7 +2316,7 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(cur_eip); - gen_op_raise_exception(trapno); + tcg_gen_helper_0_1(helper_raise_exception, tcg_const_i32(trapno)); s->is_jmp = 3; } @@ -2322,7 +2328,9 @@ static void gen_interrupt(DisasContext *s, int intno, if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(cur_eip); - gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip)); + tcg_gen_helper_0_2(helper_raise_interrupt, + tcg_const_i32(intno), + tcg_const_i32(next_eip - cur_eip)); s->is_jmp = 3; } @@ -2331,7 +2339,7 @@ static void gen_debug(DisasContext *s, target_ulong cur_eip) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(cur_eip); - gen_op_debug(); + tcg_gen_helper_0_0(helper_debug); s->is_jmp = 3; } @@ -2342,12 +2350,12 @@ static void gen_eob(DisasContext *s) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); if (s->tb->flags & HF_INHIBIT_IRQ_MASK) { - gen_op_reset_inhibit_irq(); + tcg_gen_helper_0_0(helper_reset_inhibit_irq); } if (s->singlestep_enabled) { - gen_op_debug(); + tcg_gen_helper_0_0(helper_debug); } else if (s->tf) { - gen_op_single_step(); + tcg_gen_helper_0_0(helper_single_step); } else { tcg_gen_exit_tb(0); } @@ -3659,26 +3667,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) switch(ot) { case OT_BYTE: gen_jmp_im(pc_start - s->cs_base); - gen_op_divb_AL_T0(); + tcg_gen_helper_0_1(helper_divb_AL, cpu_T[0]); break; case OT_WORD: gen_jmp_im(pc_start - s->cs_base); - gen_op_divw_AX_T0(); + tcg_gen_helper_0_1(helper_divw_AX, cpu_T[0]); break; default: case OT_LONG: gen_jmp_im(pc_start - s->cs_base); -#ifdef MACRO_TEST - /* XXX: this is just a test */ - tcg_gen_macro_2(cpu_T[0], cpu_T[0], MACRO_TEST); -#else - tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]); -#endif + tcg_gen_helper_0_1(helper_divl_EAX, cpu_T[0]); break; #ifdef TARGET_X86_64 case OT_QUAD: gen_jmp_im(pc_start - s->cs_base); - gen_op_divq_EAX_T0(); + tcg_gen_helper_0_1(helper_divq_EAX, cpu_T[0]); break; #endif } @@ -3687,21 +3690,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) switch(ot) { case OT_BYTE: gen_jmp_im(pc_start - s->cs_base); - gen_op_idivb_AL_T0(); + tcg_gen_helper_0_1(helper_idivb_AL, cpu_T[0]); break; case OT_WORD: gen_jmp_im(pc_start - s->cs_base); - gen_op_idivw_AX_T0(); + tcg_gen_helper_0_1(helper_idivw_AX, cpu_T[0]); break; default: case OT_LONG: gen_jmp_im(pc_start - s->cs_base); - tcg_gen_helper_0_1(helper_idivl_EAX_T0, cpu_T[0]); + tcg_gen_helper_0_1(helper_idivl_EAX, cpu_T[0]); break; #ifdef TARGET_X86_64 case OT_QUAD: gen_jmp_im(pc_start - s->cs_base); - gen_op_idivq_EAX_T0(); + tcg_gen_helper_0_1(helper_idivq_EAX, cpu_T[0]); break; #endif } @@ -4088,7 +4091,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) /* If several instructions disable interrupts, only the _first_ does it */ if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) - gen_op_set_inhibit_irq(); + tcg_gen_helper_0_0(helper_set_inhibit_irq); s->tf = 0; } if (s->is_jmp) { @@ -4164,7 +4167,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) /* If several instructions disable interrupts, only the _first_ does it */ if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) - gen_op_set_inhibit_irq(); + tcg_gen_helper_0_0(helper_set_inhibit_irq); s->tf = 0; } if (s->is_jmp) { @@ -5471,10 +5474,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) s->cc_op = CC_OP_EFLAGS; break; case 0xfc: /* cld */ - gen_op_cld(); + tcg_gen_movi_i32(cpu_tmp2, 1); + tcg_gen_st_i32(cpu_tmp2, cpu_env, offsetof(CPUState, df)); break; case 0xfd: /* std */ - gen_op_std(); + tcg_gen_movi_i32(cpu_tmp2, -1); + tcg_gen_st_i32(cpu_tmp2, cpu_env, offsetof(CPUState, df)); break; /************************/ @@ -5670,13 +5675,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) case 0xfa: /* cli */ if (!s->vm86) { if (s->cpl <= s->iopl) { - gen_op_cli(); + tcg_gen_helper_0_0(helper_cli); } else { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } } else { if (s->iopl == 3) { - gen_op_cli(); + tcg_gen_helper_0_0(helper_cli); } else { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } @@ -5686,12 +5691,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (!s->vm86) { if (s->cpl <= s->iopl) { gen_sti: - gen_op_sti(); + tcg_gen_helper_0_0(helper_sti); /* interruptions are enabled only the first insn after sti */ /* If several instructions disable interrupts, only the _first_ does it */ if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) - gen_op_set_inhibit_irq(); + tcg_gen_helper_0_0(helper_set_inhibit_irq); /* give a chance to handle pending irqs */ gen_jmp_im(s->pc - s->cs_base); gen_eob(s); @@ -5719,9 +5724,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_lea_modrm(s, modrm, ®_addr, &offset_addr); gen_jmp_im(pc_start - s->cs_base); if (ot == OT_WORD) - gen_op_boundw(); + tcg_gen_helper_0_0(helper_boundw); else - gen_op_boundl(); + tcg_gen_helper_0_0(helper_boundl); break; case 0x1c8 ... 0x1cf: /* bswap reg */ reg = (b & 7) | REX_B(s); @@ -5800,10 +5805,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) int retval = 0; if (b & 2) { retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 0); - gen_op_rdmsr(); + tcg_gen_helper_0_0(helper_rdmsr); } else { retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 1); - gen_op_wrmsr(); + tcg_gen_helper_0_0(helper_wrmsr); } if(retval) gen_eob(s); @@ -5813,11 +5818,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RDTSC)) break; gen_jmp_im(pc_start - s->cs_base); - gen_op_rdtsc(); + tcg_gen_helper_0_0(helper_rdtsc); break; case 0x133: /* rdpmc */ gen_jmp_im(pc_start - s->cs_base); - gen_op_rdpmc(); + tcg_gen_helper_0_0(helper_rdpmc); break; case 0x134: /* sysenter */ if (CODE64(s)) @@ -5830,7 +5835,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) s->cc_op = CC_OP_DYNAMIC; } gen_jmp_im(pc_start - s->cs_base); - gen_op_sysenter(); + tcg_gen_helper_0_0(helper_sysenter); gen_eob(s); } break; @@ -5845,7 +5850,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) s->cc_op = CC_OP_DYNAMIC; } gen_jmp_im(pc_start - s->cs_base); - gen_op_sysexit(); + tcg_gen_helper_0_0(helper_sysexit); gen_eob(s); } break; @@ -5857,7 +5862,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) s->cc_op = CC_OP_DYNAMIC; } gen_jmp_im(pc_start - s->cs_base); - gen_op_syscall(s->pc - pc_start); + tcg_gen_helper_0_1(helper_syscall, tcg_const_i32(s->pc - pc_start)); gen_eob(s); break; case 0x107: /* sysret */ @@ -5869,7 +5874,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) s->cc_op = CC_OP_DYNAMIC; } gen_jmp_im(pc_start - s->cs_base); - gen_op_sysret(s->dflag); + tcg_gen_helper_0_1(helper_sysret, tcg_const_i32(s->dflag)); /* condition codes are modified only in long mode */ if (s->lma) s->cc_op = CC_OP_EFLAGS; @@ -5880,7 +5885,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) case 0x1a2: /* cpuid */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CPUID)) break; - gen_op_cpuid(); + tcg_gen_helper_0_0(helper_cpuid); break; case 0xf4: /* hlt */ if (s->cpl != 0) { @@ -5891,7 +5896,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(s->pc - s->cs_base); - gen_op_hlt(); + tcg_gen_helper_0_0(helper_hlt); s->is_jmp = 3; } break; @@ -5921,7 +5926,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0); gen_jmp_im(pc_start - s->cs_base); - gen_op_lldt_T0(); + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); + tcg_gen_helper_0_1(helper_lldt, cpu_tmp2); } break; case 1: /* str */ @@ -5945,7 +5951,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0); gen_jmp_im(pc_start - s->cs_base); - gen_op_ltr_T0(); + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); + tcg_gen_helper_0_1(helper_ltr, cpu_tmp2); } break; case 4: /* verr */ @@ -6008,7 +6015,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_op_andl_A0_ffff(); } gen_add_A0_ds_seg(s); - gen_op_monitor(); + tcg_gen_helper_0_1(helper_monitor, cpu_A0); break; case 1: /* mwait */ if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || @@ -6021,7 +6028,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MWAIT)) break; gen_jmp_im(s->pc - s->cs_base); - gen_op_mwait(); + tcg_gen_helper_0_0(helper_mwait); gen_eob(s); break; default: @@ -6050,7 +6057,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(s->pc - s->cs_base); - gen_op_vmrun(); + tcg_gen_helper_0_0(helper_vmrun); s->cc_op = CC_OP_EFLAGS; gen_eob(s); break; @@ -6058,37 +6065,37 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMMCALL)) break; /* FIXME: cause #UD if hflags & SVM */ - gen_op_vmmcall(); + tcg_gen_helper_0_0(helper_vmmcall); break; case 2: /* VMLOAD */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMLOAD)) break; - gen_op_vmload(); + tcg_gen_helper_0_0(helper_vmload); break; case 3: /* VMSAVE */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMSAVE)) break; - gen_op_vmsave(); + tcg_gen_helper_0_0(helper_vmsave); break; case 4: /* STGI */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_STGI)) break; - gen_op_stgi(); + tcg_gen_helper_0_0(helper_stgi); break; case 5: /* CLGI */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CLGI)) break; - gen_op_clgi(); + tcg_gen_helper_0_0(helper_clgi); break; case 6: /* SKINIT */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT)) break; - gen_op_skinit(); + tcg_gen_helper_0_0(helper_skinit); break; case 7: /* INVLPGA */ if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPGA)) break; - gen_op_invlpga(); + tcg_gen_helper_0_0(helper_invlpga); break; default: goto illegal_op; @@ -6153,7 +6160,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPG)) break; gen_lea_modrm(s, modrm, ®_addr, &offset_addr); - gen_op_invlpg_A0(); + tcg_gen_helper_0_1(helper_invlpg, cpu_A0); gen_jmp_im(s->pc - s->cs_base); gen_eob(s); } @@ -6458,7 +6465,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) s->cc_op = CC_OP_DYNAMIC; } gen_jmp_im(s->pc - s->cs_base); - gen_op_rsm(); + tcg_gen_helper_0_0(helper_rsm); gen_eob(s); break; case 0x10e ... 0x10f: @@ -6855,9 +6862,6 @@ void optimize_flags_init(void) cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0"); cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1"); #endif - /* the helpers are only registered to print debug info */ - TCG_HELPER(helper_divl_EAX_T0); - TCG_HELPER(helper_idivl_EAX_T0); } /* CPU flags computation optimization: we move backward thru the |