diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-12 19:10:44 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-12 19:10:44 +0000 |
commit | 19e6c4b8bc0d692cd31900657714102a418f75e7 (patch) | |
tree | 4f8a674c11b3a30edc6e64bfa93485fbb8837b8d /target-i386/op.c | |
parent | 4da450e6167830c88225915eb7e75b582b634215 (diff) |
converted x87 FPU ops to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4444 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/op.c')
-rw-r--r-- | target-i386/op.c | 740 |
1 files changed, 2 insertions, 738 deletions
diff --git a/target-i386/op.c b/target-i386/op.c index c87a600332..e184a8dcf1 100644 --- a/target-i386/op.c +++ b/target-i386/op.c @@ -1401,735 +1401,9 @@ CCTable cc_table[CC_OP_NB] = { #endif }; -/* floating point support. Some of the code for complicated x87 - functions comes from the LGPL'ed x86 emulator found in the Willows - TWIN windows emulator. */ - -/* fp load FT0 */ - -void OPPROTO op_flds_FT0_A0(void) -{ -#ifdef USE_FP_CONVERT - FP_CONVERT.i32 = ldl(A0); - FT0 = FP_CONVERT.f; -#else - FT0 = ldfl(A0); -#endif -} - -void OPPROTO op_fldl_FT0_A0(void) -{ -#ifdef USE_FP_CONVERT - FP_CONVERT.i64 = ldq(A0); - FT0 = FP_CONVERT.d; -#else - FT0 = ldfq(A0); -#endif -} - -/* helpers are needed to avoid static constant reference. XXX: find a better way */ -#ifdef USE_INT_TO_FLOAT_HELPERS - -void helper_fild_FT0_A0(void) -{ - FT0 = (CPU86_LDouble)ldsw(A0); -} - -void helper_fildl_FT0_A0(void) -{ - FT0 = (CPU86_LDouble)((int32_t)ldl(A0)); -} - -void helper_fildll_FT0_A0(void) -{ - FT0 = (CPU86_LDouble)((int64_t)ldq(A0)); -} - -void OPPROTO op_fild_FT0_A0(void) -{ - helper_fild_FT0_A0(); -} - -void OPPROTO op_fildl_FT0_A0(void) -{ - helper_fildl_FT0_A0(); -} - -void OPPROTO op_fildll_FT0_A0(void) -{ - helper_fildll_FT0_A0(); -} - -#else - -void OPPROTO op_fild_FT0_A0(void) -{ -#ifdef USE_FP_CONVERT - FP_CONVERT.i32 = ldsw(A0); - FT0 = (CPU86_LDouble)FP_CONVERT.i32; -#else - FT0 = (CPU86_LDouble)ldsw(A0); -#endif -} - -void OPPROTO op_fildl_FT0_A0(void) -{ -#ifdef USE_FP_CONVERT - FP_CONVERT.i32 = (int32_t) ldl(A0); - FT0 = (CPU86_LDouble)FP_CONVERT.i32; -#else - FT0 = (CPU86_LDouble)((int32_t)ldl(A0)); -#endif -} - -void OPPROTO op_fildll_FT0_A0(void) -{ -#ifdef USE_FP_CONVERT - FP_CONVERT.i64 = (int64_t) ldq(A0); - FT0 = (CPU86_LDouble)FP_CONVERT.i64; -#else - FT0 = (CPU86_LDouble)((int64_t)ldq(A0)); -#endif -} -#endif - -/* fp load ST0 */ - -void OPPROTO op_flds_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; -#ifdef USE_FP_CONVERT - FP_CONVERT.i32 = ldl(A0); - env->fpregs[new_fpstt].d = FP_CONVERT.f; -#else - env->fpregs[new_fpstt].d = ldfl(A0); -#endif - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void OPPROTO op_fldl_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; -#ifdef USE_FP_CONVERT - FP_CONVERT.i64 = ldq(A0); - env->fpregs[new_fpstt].d = FP_CONVERT.d; -#else - env->fpregs[new_fpstt].d = ldfq(A0); -#endif - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void OPPROTO op_fldt_ST0_A0(void) -{ - helper_fldt_ST0_A0(); -} - -/* helpers are needed to avoid static constant reference. XXX: find a better way */ -#ifdef USE_INT_TO_FLOAT_HELPERS - -void helper_fild_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; - env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void helper_fildl_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0)); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void helper_fildll_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0)); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void OPPROTO op_fild_ST0_A0(void) -{ - helper_fild_ST0_A0(); -} - -void OPPROTO op_fildl_ST0_A0(void) -{ - helper_fildl_ST0_A0(); -} - -void OPPROTO op_fildll_ST0_A0(void) -{ - helper_fildll_ST0_A0(); -} - -#else - -void OPPROTO op_fild_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; -#ifdef USE_FP_CONVERT - FP_CONVERT.i32 = ldsw(A0); - env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32; -#else - env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0); -#endif - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void OPPROTO op_fildl_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; -#ifdef USE_FP_CONVERT - FP_CONVERT.i32 = (int32_t) ldl(A0); - env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32; -#else - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0)); -#endif - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void OPPROTO op_fildll_ST0_A0(void) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; -#ifdef USE_FP_CONVERT - FP_CONVERT.i64 = (int64_t) ldq(A0); - env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i64; -#else - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0)); -#endif - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -#endif - -/* fp store */ - -void OPPROTO op_fsts_ST0_A0(void) -{ -#ifdef USE_FP_CONVERT - FP_CONVERT.f = (float)ST0; - stfl(A0, FP_CONVERT.f); -#else - stfl(A0, (float)ST0); -#endif - FORCE_RET(); -} - -void OPPROTO op_fstl_ST0_A0(void) -{ - stfq(A0, (double)ST0); - FORCE_RET(); -} - -void OPPROTO op_fstt_ST0_A0(void) -{ - helper_fstt_ST0_A0(); -} - -void OPPROTO op_fist_ST0_A0(void) -{ -#if defined(__sparc__) && !defined(__sparc_v9__) - register CPU86_LDouble d asm("o0"); -#else - CPU86_LDouble d; -#endif - int val; - - d = ST0; - val = floatx_to_int32(d, &env->fp_status); - if (val != (int16_t)val) - val = -32768; - stw(A0, val); - FORCE_RET(); -} - -void OPPROTO op_fistl_ST0_A0(void) -{ -#if defined(__sparc__) && !defined(__sparc_v9__) - register CPU86_LDouble d asm("o0"); -#else - CPU86_LDouble d; -#endif - int val; - - d = ST0; - val = floatx_to_int32(d, &env->fp_status); - stl(A0, val); - FORCE_RET(); -} - -void OPPROTO op_fistll_ST0_A0(void) -{ -#if defined(__sparc__) && !defined(__sparc_v9__) - register CPU86_LDouble d asm("o0"); -#else - CPU86_LDouble d; -#endif - int64_t val; - - d = ST0; - val = floatx_to_int64(d, &env->fp_status); - stq(A0, val); - FORCE_RET(); -} - -void OPPROTO op_fistt_ST0_A0(void) -{ -#if defined(__sparc__) && !defined(__sparc_v9__) - register CPU86_LDouble d asm("o0"); -#else - CPU86_LDouble d; -#endif - int val; - - d = ST0; - val = floatx_to_int32_round_to_zero(d, &env->fp_status); - if (val != (int16_t)val) - val = -32768; - stw(A0, val); - FORCE_RET(); -} - -void OPPROTO op_fisttl_ST0_A0(void) -{ -#if defined(__sparc__) && !defined(__sparc_v9__) - register CPU86_LDouble d asm("o0"); -#else - CPU86_LDouble d; -#endif - int val; - - d = ST0; - val = floatx_to_int32_round_to_zero(d, &env->fp_status); - stl(A0, val); - FORCE_RET(); -} - -void OPPROTO op_fisttll_ST0_A0(void) -{ -#if defined(__sparc__) && !defined(__sparc_v9__) - register CPU86_LDouble d asm("o0"); -#else - CPU86_LDouble d; -#endif - int64_t val; - - d = ST0; - val = floatx_to_int64_round_to_zero(d, &env->fp_status); - stq(A0, val); - FORCE_RET(); -} - -void OPPROTO op_fbld_ST0_A0(void) -{ - helper_fbld_ST0_A0(); -} - -void OPPROTO op_fbst_ST0_A0(void) -{ - helper_fbst_ST0_A0(); -} - -/* FPU move */ - -void OPPROTO op_fpush(void) -{ - fpush(); -} - -void OPPROTO op_fpop(void) -{ - fpop(); -} - -void OPPROTO op_fdecstp(void) -{ - env->fpstt = (env->fpstt - 1) & 7; - env->fpus &= (~0x4700); -} - -void OPPROTO op_fincstp(void) -{ - env->fpstt = (env->fpstt + 1) & 7; - env->fpus &= (~0x4700); -} - -void OPPROTO op_ffree_STN(void) -{ - env->fptags[(env->fpstt + PARAM1) & 7] = 1; -} - -void OPPROTO op_fmov_ST0_FT0(void) -{ - ST0 = FT0; -} - -void OPPROTO op_fmov_FT0_STN(void) -{ - FT0 = ST(PARAM1); -} - -void OPPROTO op_fmov_ST0_STN(void) -{ - ST0 = ST(PARAM1); -} - -void OPPROTO op_fmov_STN_ST0(void) -{ - ST(PARAM1) = ST0; -} - -void OPPROTO op_fxchg_ST0_STN(void) +void OPPROTO op_fcomi_dummy(void) { - CPU86_LDouble tmp; - tmp = ST(PARAM1); - ST(PARAM1) = ST0; - ST0 = tmp; -} - -/* FPU operations */ - -const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; - -void OPPROTO op_fcom_ST0_FT0(void) -{ - int ret; - - ret = floatx_compare(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; - FORCE_RET(); -} - -void OPPROTO op_fucom_ST0_FT0(void) -{ - int ret; - - ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; - FORCE_RET(); -} - -const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; - -void OPPROTO op_fcomi_ST0_FT0(void) -{ - int eflags; - int ret; - - ret = floatx_compare(ST0, FT0, &env->fp_status); - eflags = cc_table[CC_OP].compute_all(); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; - CC_SRC = eflags; - FORCE_RET(); -} - -void OPPROTO op_fucomi_ST0_FT0(void) -{ - int eflags; - int ret; - - ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); - eflags = cc_table[CC_OP].compute_all(); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; - CC_SRC = eflags; - FORCE_RET(); -} - -void OPPROTO op_fcmov_ST0_STN_T0(void) -{ - if (T0) { - ST0 = ST(PARAM1); - } - FORCE_RET(); -} - -void OPPROTO op_fadd_ST0_FT0(void) -{ - ST0 += FT0; -} - -void OPPROTO op_fmul_ST0_FT0(void) -{ - ST0 *= FT0; -} - -void OPPROTO op_fsub_ST0_FT0(void) -{ - ST0 -= FT0; -} - -void OPPROTO op_fsubr_ST0_FT0(void) -{ - ST0 = FT0 - ST0; -} - -void OPPROTO op_fdiv_ST0_FT0(void) -{ - ST0 = helper_fdiv(ST0, FT0); -} - -void OPPROTO op_fdivr_ST0_FT0(void) -{ - ST0 = helper_fdiv(FT0, ST0); -} - -/* fp operations between STN and ST0 */ - -void OPPROTO op_fadd_STN_ST0(void) -{ - ST(PARAM1) += ST0; -} - -void OPPROTO op_fmul_STN_ST0(void) -{ - ST(PARAM1) *= ST0; -} - -void OPPROTO op_fsub_STN_ST0(void) -{ - ST(PARAM1) -= ST0; -} - -void OPPROTO op_fsubr_STN_ST0(void) -{ - CPU86_LDouble *p; - p = &ST(PARAM1); - *p = ST0 - *p; -} - -void OPPROTO op_fdiv_STN_ST0(void) -{ - CPU86_LDouble *p; - p = &ST(PARAM1); - *p = helper_fdiv(*p, ST0); -} - -void OPPROTO op_fdivr_STN_ST0(void) -{ - CPU86_LDouble *p; - p = &ST(PARAM1); - *p = helper_fdiv(ST0, *p); -} - -/* misc FPU operations */ -void OPPROTO op_fchs_ST0(void) -{ - ST0 = floatx_chs(ST0); -} - -void OPPROTO op_fabs_ST0(void) -{ - ST0 = floatx_abs(ST0); -} - -void OPPROTO op_fxam_ST0(void) -{ - helper_fxam_ST0(); -} - -void OPPROTO op_fld1_ST0(void) -{ - ST0 = f15rk[1]; -} - -void OPPROTO op_fldl2t_ST0(void) -{ - ST0 = f15rk[6]; -} - -void OPPROTO op_fldl2e_ST0(void) -{ - ST0 = f15rk[5]; -} - -void OPPROTO op_fldpi_ST0(void) -{ - ST0 = f15rk[2]; -} - -void OPPROTO op_fldlg2_ST0(void) -{ - ST0 = f15rk[3]; -} - -void OPPROTO op_fldln2_ST0(void) -{ - ST0 = f15rk[4]; -} - -void OPPROTO op_fldz_ST0(void) -{ - ST0 = f15rk[0]; -} - -void OPPROTO op_fldz_FT0(void) -{ - FT0 = f15rk[0]; -} - -/* associated heplers to reduce generated code length and to simplify - relocation (FP constants are usually stored in .rodata section) */ - -void OPPROTO op_f2xm1(void) -{ - helper_f2xm1(); -} - -void OPPROTO op_fyl2x(void) -{ - helper_fyl2x(); -} - -void OPPROTO op_fptan(void) -{ - helper_fptan(); -} - -void OPPROTO op_fpatan(void) -{ - helper_fpatan(); -} - -void OPPROTO op_fxtract(void) -{ - helper_fxtract(); -} - -void OPPROTO op_fprem1(void) -{ - helper_fprem1(); -} - - -void OPPROTO op_fprem(void) -{ - helper_fprem(); -} - -void OPPROTO op_fyl2xp1(void) -{ - helper_fyl2xp1(); -} - -void OPPROTO op_fsqrt(void) -{ - helper_fsqrt(); -} - -void OPPROTO op_fsincos(void) -{ - helper_fsincos(); -} - -void OPPROTO op_frndint(void) -{ - helper_frndint(); -} - -void OPPROTO op_fscale(void) -{ - helper_fscale(); -} - -void OPPROTO op_fsin(void) -{ - helper_fsin(); -} - -void OPPROTO op_fcos(void) -{ - helper_fcos(); -} - -void OPPROTO op_fnstsw_A0(void) -{ - int fpus; - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - stw(A0, fpus); - FORCE_RET(); -} - -void OPPROTO op_fnstsw_EAX(void) -{ - int fpus; - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - EAX = (EAX & ~0xffff) | fpus; -} - -void OPPROTO op_fnstcw_A0(void) -{ - stw(A0, env->fpuc); - FORCE_RET(); -} - -void OPPROTO op_fldcw_A0(void) -{ - env->fpuc = lduw(A0); - update_fp_status(); -} - -void OPPROTO op_fclex(void) -{ - env->fpus &= 0x7f00; -} - -void OPPROTO op_fwait(void) -{ - if (env->fpus & FPUS_SE) - fpu_raise_exception(); - FORCE_RET(); -} - -void OPPROTO op_fninit(void) -{ - env->fpus = 0; - env->fpstt = 0; - env->fpuc = 0x37f; - env->fptags[0] = 1; - env->fptags[1] = 1; - env->fptags[2] = 1; - env->fptags[3] = 1; - env->fptags[4] = 1; - env->fptags[5] = 1; - env->fptags[6] = 1; - env->fptags[7] = 1; -} - -void OPPROTO op_fnstenv_A0(void) -{ - helper_fstenv(A0, PARAM1); -} - -void OPPROTO op_fldenv_A0(void) -{ - helper_fldenv(A0, PARAM1); -} - -void OPPROTO op_fnsave_A0(void) -{ - helper_fsave(A0, PARAM1); -} - -void OPPROTO op_frstor_A0(void) -{ - helper_frstor(A0, PARAM1); + T0 = 0; } /* threading support */ @@ -2149,16 +1423,6 @@ void OPPROTO op_com_dummy(void) T0 = 0; } -void OPPROTO op_fxsave_A0(void) -{ - helper_fxsave(A0, PARAM1); -} - -void OPPROTO op_fxrstor_A0(void) -{ - helper_fxrstor(A0, PARAM1); -} - /* Secure Virtual Machine ops */ void OPPROTO op_vmrun(void) |