Commit 19e6c4b8bc0d692cd31900657714102a418f75e7
1 parent
4da450e6
converted x87 FPU ops to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4444 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
756 additions
and
945 deletions
target-i386/exec.h
... | ... | @@ -231,6 +231,12 @@ static inline void stfl(target_ulong ptr, float v) |
231 | 231 | #define floatx_to_int64 floatx80_to_int64 |
232 | 232 | #define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero |
233 | 233 | #define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero |
234 | +#define int32_to_floatx int32_to_floatx80 | |
235 | +#define int64_to_floatx int64_to_floatx80 | |
236 | +#define float32_to_floatx float32_to_floatx80 | |
237 | +#define float64_to_floatx float64_to_floatx80 | |
238 | +#define floatx_to_float32 floatx80_to_float32 | |
239 | +#define floatx_to_float64 floatx80_to_float64 | |
234 | 240 | #define floatx_abs floatx80_abs |
235 | 241 | #define floatx_chs floatx80_chs |
236 | 242 | #define floatx_round_to_int floatx80_round_to_int |
... | ... | @@ -251,6 +257,12 @@ static inline void stfl(target_ulong ptr, float v) |
251 | 257 | #define floatx_to_int64 float64_to_int64 |
252 | 258 | #define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero |
253 | 259 | #define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero |
260 | +#define int32_to_floatx int32_to_float64 | |
261 | +#define int64_to_floatx int64_to_float64 | |
262 | +#define float32_to_floatx float32_to_float64 | |
263 | +#define float64_to_floatx(x, e) (x) | |
264 | +#define floatx_to_float32 float64_to_float32 | |
265 | +#define floatx_to_float64(x, e) (x) | |
254 | 266 | #define floatx_abs float64_abs |
255 | 267 | #define floatx_chs float64_chs |
256 | 268 | #define floatx_round_to_int float64_round_to_int |
... | ... | @@ -378,22 +390,6 @@ static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) |
378 | 390 | } |
379 | 391 | #else |
380 | 392 | |
381 | -/* XXX: same endianness assumed */ | |
382 | - | |
383 | -#ifdef CONFIG_USER_ONLY | |
384 | - | |
385 | -static inline CPU86_LDouble helper_fldt(target_ulong ptr) | |
386 | -{ | |
387 | - return *(CPU86_LDouble *)(unsigned long)ptr; | |
388 | -} | |
389 | - | |
390 | -static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) | |
391 | -{ | |
392 | - *(CPU86_LDouble *)(unsigned long)ptr = f; | |
393 | -} | |
394 | - | |
395 | -#else | |
396 | - | |
397 | 393 | /* we use memory access macros */ |
398 | 394 | |
399 | 395 | static inline CPU86_LDouble helper_fldt(target_ulong ptr) |
... | ... | @@ -414,8 +410,6 @@ static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) |
414 | 410 | stw(ptr + 8, temp.l.upper); |
415 | 411 | } |
416 | 412 | |
417 | -#endif /* !CONFIG_USER_ONLY */ | |
418 | - | |
419 | 413 | #endif /* USE_X86LDOUBLE */ |
420 | 414 | |
421 | 415 | #define FPUS_IE (1 << 0) |
... | ... | @@ -432,33 +426,7 @@ static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) |
432 | 426 | |
433 | 427 | extern const CPU86_LDouble f15rk[7]; |
434 | 428 | |
435 | -void helper_fldt_ST0_A0(void); | |
436 | -void helper_fstt_ST0_A0(void); | |
437 | 429 | void fpu_raise_exception(void); |
438 | -CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b); | |
439 | -void helper_fbld_ST0_A0(void); | |
440 | -void helper_fbst_ST0_A0(void); | |
441 | -void helper_f2xm1(void); | |
442 | -void helper_fyl2x(void); | |
443 | -void helper_fptan(void); | |
444 | -void helper_fpatan(void); | |
445 | -void helper_fxtract(void); | |
446 | -void helper_fprem1(void); | |
447 | -void helper_fprem(void); | |
448 | -void helper_fyl2xp1(void); | |
449 | -void helper_fsqrt(void); | |
450 | -void helper_fsincos(void); | |
451 | -void helper_frndint(void); | |
452 | -void helper_fscale(void); | |
453 | -void helper_fsin(void); | |
454 | -void helper_fcos(void); | |
455 | -void helper_fxam_ST0(void); | |
456 | -void helper_fstenv(target_ulong ptr, int data32); | |
457 | -void helper_fldenv(target_ulong ptr, int data32); | |
458 | -void helper_fsave(target_ulong ptr, int data32); | |
459 | -void helper_frstor(target_ulong ptr, int data32); | |
460 | -void helper_fxsave(target_ulong ptr, int data64); | |
461 | -void helper_fxrstor(target_ulong ptr, int data64); | |
462 | 430 | void restore_native_fp_state(CPUState *env); |
463 | 431 | void save_native_fp_state(CPUState *env); |
464 | 432 | float approx_rsqrt(float a); | ... | ... |
target-i386/helper.c
... | ... | @@ -3071,21 +3071,7 @@ void helper_verw(void) |
3071 | 3071 | CC_SRC = eflags | CC_Z; |
3072 | 3072 | } |
3073 | 3073 | |
3074 | -/* FPU helpers */ | |
3075 | - | |
3076 | -void helper_fldt_ST0_A0(void) | |
3077 | -{ | |
3078 | - int new_fpstt; | |
3079 | - new_fpstt = (env->fpstt - 1) & 7; | |
3080 | - env->fpregs[new_fpstt].d = helper_fldt(A0); | |
3081 | - env->fpstt = new_fpstt; | |
3082 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
3083 | -} | |
3084 | - | |
3085 | -void helper_fstt_ST0_A0(void) | |
3086 | -{ | |
3087 | - helper_fstt(ST0, A0); | |
3088 | -} | |
3074 | +/* x87 FPU helpers */ | |
3089 | 3075 | |
3090 | 3076 | static void fpu_set_exception(int mask) |
3091 | 3077 | { |
... | ... | @@ -3094,7 +3080,7 @@ static void fpu_set_exception(int mask) |
3094 | 3080 | env->fpus |= FPUS_SE | FPUS_B; |
3095 | 3081 | } |
3096 | 3082 | |
3097 | -CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b) | |
3083 | +static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b) | |
3098 | 3084 | { |
3099 | 3085 | if (b == 0.0) |
3100 | 3086 | fpu_set_exception(FPUS_ZE); |
... | ... | @@ -3113,9 +3099,427 @@ void fpu_raise_exception(void) |
3113 | 3099 | #endif |
3114 | 3100 | } |
3115 | 3101 | |
3102 | +void helper_flds_FT0(uint32_t val) | |
3103 | +{ | |
3104 | + union { | |
3105 | + float32 f; | |
3106 | + uint32_t i; | |
3107 | + } u; | |
3108 | + u.i = val; | |
3109 | + FT0 = float32_to_floatx(u.f, &env->fp_status); | |
3110 | +} | |
3111 | + | |
3112 | +void helper_fldl_FT0(uint64_t val) | |
3113 | +{ | |
3114 | + union { | |
3115 | + float64 f; | |
3116 | + uint64_t i; | |
3117 | + } u; | |
3118 | + u.i = val; | |
3119 | + FT0 = float64_to_floatx(u.f, &env->fp_status); | |
3120 | +} | |
3121 | + | |
3122 | +void helper_fildl_FT0(int32_t val) | |
3123 | +{ | |
3124 | + FT0 = int32_to_floatx(val, &env->fp_status); | |
3125 | +} | |
3126 | + | |
3127 | +void helper_flds_ST0(uint32_t val) | |
3128 | +{ | |
3129 | + int new_fpstt; | |
3130 | + union { | |
3131 | + float32 f; | |
3132 | + uint32_t i; | |
3133 | + } u; | |
3134 | + new_fpstt = (env->fpstt - 1) & 7; | |
3135 | + u.i = val; | |
3136 | + env->fpregs[new_fpstt].d = float32_to_floatx(u.f, &env->fp_status); | |
3137 | + env->fpstt = new_fpstt; | |
3138 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
3139 | +} | |
3140 | + | |
3141 | +void helper_fldl_ST0(uint64_t val) | |
3142 | +{ | |
3143 | + int new_fpstt; | |
3144 | + union { | |
3145 | + float64 f; | |
3146 | + uint64_t i; | |
3147 | + } u; | |
3148 | + new_fpstt = (env->fpstt - 1) & 7; | |
3149 | + u.i = val; | |
3150 | + env->fpregs[new_fpstt].d = float64_to_floatx(u.f, &env->fp_status); | |
3151 | + env->fpstt = new_fpstt; | |
3152 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
3153 | +} | |
3154 | + | |
3155 | +void helper_fildl_ST0(int32_t val) | |
3156 | +{ | |
3157 | + int new_fpstt; | |
3158 | + new_fpstt = (env->fpstt - 1) & 7; | |
3159 | + env->fpregs[new_fpstt].d = int32_to_floatx(val, &env->fp_status); | |
3160 | + env->fpstt = new_fpstt; | |
3161 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
3162 | +} | |
3163 | + | |
3164 | +void helper_fildll_ST0(int64_t val) | |
3165 | +{ | |
3166 | + int new_fpstt; | |
3167 | + new_fpstt = (env->fpstt - 1) & 7; | |
3168 | + env->fpregs[new_fpstt].d = int64_to_floatx(val, &env->fp_status); | |
3169 | + env->fpstt = new_fpstt; | |
3170 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
3171 | +} | |
3172 | + | |
3173 | +uint32_t helper_fsts_ST0(void) | |
3174 | +{ | |
3175 | + union { | |
3176 | + float32 f; | |
3177 | + uint32_t i; | |
3178 | + } u; | |
3179 | + u.f = floatx_to_float32(ST0, &env->fp_status); | |
3180 | + return u.i; | |
3181 | +} | |
3182 | + | |
3183 | +uint64_t helper_fstl_ST0(void) | |
3184 | +{ | |
3185 | + union { | |
3186 | + float64 f; | |
3187 | + uint64_t i; | |
3188 | + } u; | |
3189 | + u.f = floatx_to_float64(ST0, &env->fp_status); | |
3190 | + return u.i; | |
3191 | +} | |
3192 | + | |
3193 | +int32_t helper_fist_ST0(void) | |
3194 | +{ | |
3195 | + int32_t val; | |
3196 | + val = floatx_to_int32(ST0, &env->fp_status); | |
3197 | + if (val != (int16_t)val) | |
3198 | + val = -32768; | |
3199 | + return val; | |
3200 | +} | |
3201 | + | |
3202 | +int32_t helper_fistl_ST0(void) | |
3203 | +{ | |
3204 | + int32_t val; | |
3205 | + val = floatx_to_int32(ST0, &env->fp_status); | |
3206 | + return val; | |
3207 | +} | |
3208 | + | |
3209 | +int64_t helper_fistll_ST0(void) | |
3210 | +{ | |
3211 | + int64_t val; | |
3212 | + val = floatx_to_int64(ST0, &env->fp_status); | |
3213 | + return val; | |
3214 | +} | |
3215 | + | |
3216 | +int32_t helper_fistt_ST0(void) | |
3217 | +{ | |
3218 | + int32_t val; | |
3219 | + val = floatx_to_int32_round_to_zero(ST0, &env->fp_status); | |
3220 | + if (val != (int16_t)val) | |
3221 | + val = -32768; | |
3222 | + return val; | |
3223 | +} | |
3224 | + | |
3225 | +int32_t helper_fisttl_ST0(void) | |
3226 | +{ | |
3227 | + int32_t val; | |
3228 | + val = floatx_to_int32_round_to_zero(ST0, &env->fp_status); | |
3229 | + return val; | |
3230 | +} | |
3231 | + | |
3232 | +int64_t helper_fisttll_ST0(void) | |
3233 | +{ | |
3234 | + int64_t val; | |
3235 | + val = floatx_to_int64_round_to_zero(ST0, &env->fp_status); | |
3236 | + return val; | |
3237 | +} | |
3238 | + | |
3239 | +void helper_fldt_ST0(target_ulong ptr) | |
3240 | +{ | |
3241 | + int new_fpstt; | |
3242 | + new_fpstt = (env->fpstt - 1) & 7; | |
3243 | + env->fpregs[new_fpstt].d = helper_fldt(ptr); | |
3244 | + env->fpstt = new_fpstt; | |
3245 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
3246 | +} | |
3247 | + | |
3248 | +void helper_fstt_ST0(target_ulong ptr) | |
3249 | +{ | |
3250 | + helper_fstt(ST0, ptr); | |
3251 | +} | |
3252 | + | |
3253 | +void helper_fpush(void) | |
3254 | +{ | |
3255 | + fpush(); | |
3256 | +} | |
3257 | + | |
3258 | +void helper_fpop(void) | |
3259 | +{ | |
3260 | + fpop(); | |
3261 | +} | |
3262 | + | |
3263 | +void helper_fdecstp(void) | |
3264 | +{ | |
3265 | + env->fpstt = (env->fpstt - 1) & 7; | |
3266 | + env->fpus &= (~0x4700); | |
3267 | +} | |
3268 | + | |
3269 | +void helper_fincstp(void) | |
3270 | +{ | |
3271 | + env->fpstt = (env->fpstt + 1) & 7; | |
3272 | + env->fpus &= (~0x4700); | |
3273 | +} | |
3274 | + | |
3275 | +/* FPU move */ | |
3276 | + | |
3277 | +void helper_ffree_STN(int st_index) | |
3278 | +{ | |
3279 | + env->fptags[(env->fpstt + st_index) & 7] = 1; | |
3280 | +} | |
3281 | + | |
3282 | +void helper_fmov_ST0_FT0(void) | |
3283 | +{ | |
3284 | + ST0 = FT0; | |
3285 | +} | |
3286 | + | |
3287 | +void helper_fmov_FT0_STN(int st_index) | |
3288 | +{ | |
3289 | + FT0 = ST(st_index); | |
3290 | +} | |
3291 | + | |
3292 | +void helper_fmov_ST0_STN(int st_index) | |
3293 | +{ | |
3294 | + ST0 = ST(st_index); | |
3295 | +} | |
3296 | + | |
3297 | +void helper_fmov_STN_ST0(int st_index) | |
3298 | +{ | |
3299 | + ST(st_index) = ST0; | |
3300 | +} | |
3301 | + | |
3302 | +void helper_fxchg_ST0_STN(int st_index) | |
3303 | +{ | |
3304 | + CPU86_LDouble tmp; | |
3305 | + tmp = ST(st_index); | |
3306 | + ST(st_index) = ST0; | |
3307 | + ST0 = tmp; | |
3308 | +} | |
3309 | + | |
3310 | +/* FPU operations */ | |
3311 | + | |
3312 | +static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; | |
3313 | + | |
3314 | +void helper_fcom_ST0_FT0(void) | |
3315 | +{ | |
3316 | + int ret; | |
3317 | + | |
3318 | + ret = floatx_compare(ST0, FT0, &env->fp_status); | |
3319 | + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; | |
3320 | + FORCE_RET(); | |
3321 | +} | |
3322 | + | |
3323 | +void helper_fucom_ST0_FT0(void) | |
3324 | +{ | |
3325 | + int ret; | |
3326 | + | |
3327 | + ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); | |
3328 | + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; | |
3329 | + FORCE_RET(); | |
3330 | +} | |
3331 | + | |
3332 | +static const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; | |
3333 | + | |
3334 | +void helper_fcomi_ST0_FT0(void) | |
3335 | +{ | |
3336 | + int eflags; | |
3337 | + int ret; | |
3338 | + | |
3339 | + ret = floatx_compare(ST0, FT0, &env->fp_status); | |
3340 | + eflags = cc_table[CC_OP].compute_all(); | |
3341 | + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; | |
3342 | + CC_SRC = eflags; | |
3343 | + FORCE_RET(); | |
3344 | +} | |
3345 | + | |
3346 | +void helper_fucomi_ST0_FT0(void) | |
3347 | +{ | |
3348 | + int eflags; | |
3349 | + int ret; | |
3350 | + | |
3351 | + ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); | |
3352 | + eflags = cc_table[CC_OP].compute_all(); | |
3353 | + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; | |
3354 | + CC_SRC = eflags; | |
3355 | + FORCE_RET(); | |
3356 | +} | |
3357 | + | |
3358 | +void helper_fadd_ST0_FT0(void) | |
3359 | +{ | |
3360 | + ST0 += FT0; | |
3361 | +} | |
3362 | + | |
3363 | +void helper_fmul_ST0_FT0(void) | |
3364 | +{ | |
3365 | + ST0 *= FT0; | |
3366 | +} | |
3367 | + | |
3368 | +void helper_fsub_ST0_FT0(void) | |
3369 | +{ | |
3370 | + ST0 -= FT0; | |
3371 | +} | |
3372 | + | |
3373 | +void helper_fsubr_ST0_FT0(void) | |
3374 | +{ | |
3375 | + ST0 = FT0 - ST0; | |
3376 | +} | |
3377 | + | |
3378 | +void helper_fdiv_ST0_FT0(void) | |
3379 | +{ | |
3380 | + ST0 = helper_fdiv(ST0, FT0); | |
3381 | +} | |
3382 | + | |
3383 | +void helper_fdivr_ST0_FT0(void) | |
3384 | +{ | |
3385 | + ST0 = helper_fdiv(FT0, ST0); | |
3386 | +} | |
3387 | + | |
3388 | +/* fp operations between STN and ST0 */ | |
3389 | + | |
3390 | +void helper_fadd_STN_ST0(int st_index) | |
3391 | +{ | |
3392 | + ST(st_index) += ST0; | |
3393 | +} | |
3394 | + | |
3395 | +void helper_fmul_STN_ST0(int st_index) | |
3396 | +{ | |
3397 | + ST(st_index) *= ST0; | |
3398 | +} | |
3399 | + | |
3400 | +void helper_fsub_STN_ST0(int st_index) | |
3401 | +{ | |
3402 | + ST(st_index) -= ST0; | |
3403 | +} | |
3404 | + | |
3405 | +void helper_fsubr_STN_ST0(int st_index) | |
3406 | +{ | |
3407 | + CPU86_LDouble *p; | |
3408 | + p = &ST(st_index); | |
3409 | + *p = ST0 - *p; | |
3410 | +} | |
3411 | + | |
3412 | +void helper_fdiv_STN_ST0(int st_index) | |
3413 | +{ | |
3414 | + CPU86_LDouble *p; | |
3415 | + p = &ST(st_index); | |
3416 | + *p = helper_fdiv(*p, ST0); | |
3417 | +} | |
3418 | + | |
3419 | +void helper_fdivr_STN_ST0(int st_index) | |
3420 | +{ | |
3421 | + CPU86_LDouble *p; | |
3422 | + p = &ST(st_index); | |
3423 | + *p = helper_fdiv(ST0, *p); | |
3424 | +} | |
3425 | + | |
3426 | +/* misc FPU operations */ | |
3427 | +void helper_fchs_ST0(void) | |
3428 | +{ | |
3429 | + ST0 = floatx_chs(ST0); | |
3430 | +} | |
3431 | + | |
3432 | +void helper_fabs_ST0(void) | |
3433 | +{ | |
3434 | + ST0 = floatx_abs(ST0); | |
3435 | +} | |
3436 | + | |
3437 | +void helper_fld1_ST0(void) | |
3438 | +{ | |
3439 | + ST0 = f15rk[1]; | |
3440 | +} | |
3441 | + | |
3442 | +void helper_fldl2t_ST0(void) | |
3443 | +{ | |
3444 | + ST0 = f15rk[6]; | |
3445 | +} | |
3446 | + | |
3447 | +void helper_fldl2e_ST0(void) | |
3448 | +{ | |
3449 | + ST0 = f15rk[5]; | |
3450 | +} | |
3451 | + | |
3452 | +void helper_fldpi_ST0(void) | |
3453 | +{ | |
3454 | + ST0 = f15rk[2]; | |
3455 | +} | |
3456 | + | |
3457 | +void helper_fldlg2_ST0(void) | |
3458 | +{ | |
3459 | + ST0 = f15rk[3]; | |
3460 | +} | |
3461 | + | |
3462 | +void helper_fldln2_ST0(void) | |
3463 | +{ | |
3464 | + ST0 = f15rk[4]; | |
3465 | +} | |
3466 | + | |
3467 | +void helper_fldz_ST0(void) | |
3468 | +{ | |
3469 | + ST0 = f15rk[0]; | |
3470 | +} | |
3471 | + | |
3472 | +void helper_fldz_FT0(void) | |
3473 | +{ | |
3474 | + FT0 = f15rk[0]; | |
3475 | +} | |
3476 | + | |
3477 | +uint32_t helper_fnstsw(void) | |
3478 | +{ | |
3479 | + return (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | |
3480 | +} | |
3481 | + | |
3482 | +uint32_t helper_fnstcw(void) | |
3483 | +{ | |
3484 | + return env->fpuc; | |
3485 | +} | |
3486 | + | |
3487 | +void helper_fldcw(uint32_t val) | |
3488 | +{ | |
3489 | + env->fpuc = val; | |
3490 | + update_fp_status(); | |
3491 | +} | |
3492 | + | |
3493 | +void helper_fclex(void) | |
3494 | +{ | |
3495 | + env->fpus &= 0x7f00; | |
3496 | +} | |
3497 | + | |
3498 | +void helper_fwait(void) | |
3499 | +{ | |
3500 | + if (env->fpus & FPUS_SE) | |
3501 | + fpu_raise_exception(); | |
3502 | + FORCE_RET(); | |
3503 | +} | |
3504 | + | |
3505 | +void helper_fninit(void) | |
3506 | +{ | |
3507 | + env->fpus = 0; | |
3508 | + env->fpstt = 0; | |
3509 | + env->fpuc = 0x37f; | |
3510 | + env->fptags[0] = 1; | |
3511 | + env->fptags[1] = 1; | |
3512 | + env->fptags[2] = 1; | |
3513 | + env->fptags[3] = 1; | |
3514 | + env->fptags[4] = 1; | |
3515 | + env->fptags[5] = 1; | |
3516 | + env->fptags[6] = 1; | |
3517 | + env->fptags[7] = 1; | |
3518 | +} | |
3519 | + | |
3116 | 3520 | /* BCD ops */ |
3117 | 3521 | |
3118 | -void helper_fbld_ST0_A0(void) | |
3522 | +void helper_fbld_ST0(target_ulong ptr) | |
3119 | 3523 | { |
3120 | 3524 | CPU86_LDouble tmp; |
3121 | 3525 | uint64_t val; |
... | ... | @@ -3124,24 +3528,24 @@ void helper_fbld_ST0_A0(void) |
3124 | 3528 | |
3125 | 3529 | val = 0; |
3126 | 3530 | for(i = 8; i >= 0; i--) { |
3127 | - v = ldub(A0 + i); | |
3531 | + v = ldub(ptr + i); | |
3128 | 3532 | val = (val * 100) + ((v >> 4) * 10) + (v & 0xf); |
3129 | 3533 | } |
3130 | 3534 | tmp = val; |
3131 | - if (ldub(A0 + 9) & 0x80) | |
3535 | + if (ldub(ptr + 9) & 0x80) | |
3132 | 3536 | tmp = -tmp; |
3133 | 3537 | fpush(); |
3134 | 3538 | ST0 = tmp; |
3135 | 3539 | } |
3136 | 3540 | |
3137 | -void helper_fbst_ST0_A0(void) | |
3541 | +void helper_fbst_ST0(target_ulong ptr) | |
3138 | 3542 | { |
3139 | 3543 | int v; |
3140 | 3544 | target_ulong mem_ref, mem_end; |
3141 | 3545 | int64_t val; |
3142 | 3546 | |
3143 | 3547 | val = floatx_to_int64(ST0, &env->fp_status); |
3144 | - mem_ref = A0; | |
3548 | + mem_ref = ptr; | |
3145 | 3549 | mem_end = mem_ref + 9; |
3146 | 3550 | if (val < 0) { |
3147 | 3551 | stb(mem_end, 0x80); | ... | ... |
target-i386/helper.h
... | ... | @@ -2,6 +2,95 @@ |
2 | 2 | |
3 | 3 | void TCG_HELPER_PROTO helper_divl_EAX_T0(target_ulong t0); |
4 | 4 | void TCG_HELPER_PROTO helper_idivl_EAX_T0(target_ulong t0); |
5 | + | |
6 | +/* x86 FPU */ | |
7 | + | |
8 | +void helper_flds_FT0(uint32_t val); | |
9 | +void helper_fldl_FT0(uint64_t val); | |
10 | +void helper_fildl_FT0(int32_t val); | |
11 | +void helper_flds_ST0(uint32_t val); | |
12 | +void helper_fldl_ST0(uint64_t val); | |
13 | +void helper_fildl_ST0(int32_t val); | |
14 | +void helper_fildll_ST0(int64_t val); | |
15 | +uint32_t helper_fsts_ST0(void); | |
16 | +uint64_t helper_fstl_ST0(void); | |
17 | +int32_t helper_fist_ST0(void); | |
18 | +int32_t helper_fistl_ST0(void); | |
19 | +int64_t helper_fistll_ST0(void); | |
20 | +int32_t helper_fistt_ST0(void); | |
21 | +int32_t helper_fisttl_ST0(void); | |
22 | +int64_t helper_fisttll_ST0(void); | |
23 | +void helper_fldt_ST0(target_ulong ptr); | |
24 | +void helper_fstt_ST0(target_ulong ptr); | |
25 | +void helper_fpush(void); | |
26 | +void helper_fpop(void); | |
27 | +void helper_fdecstp(void); | |
28 | +void helper_fincstp(void); | |
29 | +void helper_ffree_STN(int st_index); | |
30 | +void helper_fmov_ST0_FT0(void); | |
31 | +void helper_fmov_FT0_STN(int st_index); | |
32 | +void helper_fmov_ST0_STN(int st_index); | |
33 | +void helper_fmov_STN_ST0(int st_index); | |
34 | +void helper_fxchg_ST0_STN(int st_index); | |
35 | +void helper_fcom_ST0_FT0(void); | |
36 | +void helper_fucom_ST0_FT0(void); | |
37 | +void helper_fcomi_ST0_FT0(void); | |
38 | +void helper_fucomi_ST0_FT0(void); | |
39 | +void helper_fadd_ST0_FT0(void); | |
40 | +void helper_fmul_ST0_FT0(void); | |
41 | +void helper_fsub_ST0_FT0(void); | |
42 | +void helper_fsubr_ST0_FT0(void); | |
43 | +void helper_fdiv_ST0_FT0(void); | |
44 | +void helper_fdivr_ST0_FT0(void); | |
45 | +void helper_fadd_STN_ST0(int st_index); | |
46 | +void helper_fmul_STN_ST0(int st_index); | |
47 | +void helper_fsub_STN_ST0(int st_index); | |
48 | +void helper_fsubr_STN_ST0(int st_index); | |
49 | +void helper_fdiv_STN_ST0(int st_index); | |
50 | +void helper_fdivr_STN_ST0(int st_index); | |
51 | +void helper_fchs_ST0(void); | |
52 | +void helper_fabs_ST0(void); | |
53 | +void helper_fxam_ST0(void); | |
54 | +void helper_fld1_ST0(void); | |
55 | +void helper_fldl2t_ST0(void); | |
56 | +void helper_fldl2e_ST0(void); | |
57 | +void helper_fldpi_ST0(void); | |
58 | +void helper_fldlg2_ST0(void); | |
59 | +void helper_fldln2_ST0(void); | |
60 | +void helper_fldz_ST0(void); | |
61 | +void helper_fldz_FT0(void); | |
62 | +uint32_t helper_fnstsw(void); | |
63 | +uint32_t helper_fnstcw(void); | |
64 | +void helper_fldcw(uint32_t val); | |
65 | +void helper_fclex(void); | |
66 | +void helper_fwait(void); | |
67 | +void helper_fninit(void); | |
68 | +void helper_fbld_ST0(target_ulong ptr); | |
69 | +void helper_fbst_ST0(target_ulong ptr); | |
70 | +void helper_f2xm1(void); | |
71 | +void helper_fyl2x(void); | |
72 | +void helper_fptan(void); | |
73 | +void helper_fpatan(void); | |
74 | +void helper_fxtract(void); | |
75 | +void helper_fprem1(void); | |
76 | +void helper_fprem(void); | |
77 | +void helper_fyl2xp1(void); | |
78 | +void helper_fsqrt(void); | |
79 | +void helper_fsincos(void); | |
80 | +void helper_frndint(void); | |
81 | +void helper_fscale(void); | |
82 | +void helper_fsin(void); | |
83 | +void helper_fcos(void); | |
84 | +void helper_fxam_ST0(void); | |
85 | +void helper_fstenv(target_ulong ptr, int data32); | |
86 | +void helper_fldenv(target_ulong ptr, int data32); | |
87 | +void helper_fsave(target_ulong ptr, int data32); | |
88 | +void helper_frstor(target_ulong ptr, int data32); | |
89 | +void helper_fxsave(target_ulong ptr, int data64); | |
90 | +void helper_fxrstor(target_ulong ptr, int data64); | |
91 | + | |
92 | +/* MMX/SSE */ | |
93 | + | |
5 | 94 | void TCG_HELPER_PROTO helper_enter_mmx(void); |
6 | 95 | void TCG_HELPER_PROTO helper_emms(void); |
7 | 96 | void TCG_HELPER_PROTO helper_movq(uint64_t *d, uint64_t *s); | ... | ... |
target-i386/op.c
... | ... | @@ -1401,735 +1401,9 @@ CCTable cc_table[CC_OP_NB] = { |
1401 | 1401 | #endif |
1402 | 1402 | }; |
1403 | 1403 | |
1404 | -/* floating point support. Some of the code for complicated x87 | |
1405 | - functions comes from the LGPL'ed x86 emulator found in the Willows | |
1406 | - TWIN windows emulator. */ | |
1407 | - | |
1408 | -/* fp load FT0 */ | |
1409 | - | |
1410 | -void OPPROTO op_flds_FT0_A0(void) | |
1411 | -{ | |
1412 | -#ifdef USE_FP_CONVERT | |
1413 | - FP_CONVERT.i32 = ldl(A0); | |
1414 | - FT0 = FP_CONVERT.f; | |
1415 | -#else | |
1416 | - FT0 = ldfl(A0); | |
1417 | -#endif | |
1418 | -} | |
1419 | - | |
1420 | -void OPPROTO op_fldl_FT0_A0(void) | |
1421 | -{ | |
1422 | -#ifdef USE_FP_CONVERT | |
1423 | - FP_CONVERT.i64 = ldq(A0); | |
1424 | - FT0 = FP_CONVERT.d; | |
1425 | -#else | |
1426 | - FT0 = ldfq(A0); | |
1427 | -#endif | |
1428 | -} | |
1429 | - | |
1430 | -/* helpers are needed to avoid static constant reference. XXX: find a better way */ | |
1431 | -#ifdef USE_INT_TO_FLOAT_HELPERS | |
1432 | - | |
1433 | -void helper_fild_FT0_A0(void) | |
1434 | -{ | |
1435 | - FT0 = (CPU86_LDouble)ldsw(A0); | |
1436 | -} | |
1437 | - | |
1438 | -void helper_fildl_FT0_A0(void) | |
1439 | -{ | |
1440 | - FT0 = (CPU86_LDouble)((int32_t)ldl(A0)); | |
1441 | -} | |
1442 | - | |
1443 | -void helper_fildll_FT0_A0(void) | |
1444 | -{ | |
1445 | - FT0 = (CPU86_LDouble)((int64_t)ldq(A0)); | |
1446 | -} | |
1447 | - | |
1448 | -void OPPROTO op_fild_FT0_A0(void) | |
1449 | -{ | |
1450 | - helper_fild_FT0_A0(); | |
1451 | -} | |
1452 | - | |
1453 | -void OPPROTO op_fildl_FT0_A0(void) | |
1454 | -{ | |
1455 | - helper_fildl_FT0_A0(); | |
1456 | -} | |
1457 | - | |
1458 | -void OPPROTO op_fildll_FT0_A0(void) | |
1459 | -{ | |
1460 | - helper_fildll_FT0_A0(); | |
1461 | -} | |
1462 | - | |
1463 | -#else | |
1464 | - | |
1465 | -void OPPROTO op_fild_FT0_A0(void) | |
1466 | -{ | |
1467 | -#ifdef USE_FP_CONVERT | |
1468 | - FP_CONVERT.i32 = ldsw(A0); | |
1469 | - FT0 = (CPU86_LDouble)FP_CONVERT.i32; | |
1470 | -#else | |
1471 | - FT0 = (CPU86_LDouble)ldsw(A0); | |
1472 | -#endif | |
1473 | -} | |
1474 | - | |
1475 | -void OPPROTO op_fildl_FT0_A0(void) | |
1476 | -{ | |
1477 | -#ifdef USE_FP_CONVERT | |
1478 | - FP_CONVERT.i32 = (int32_t) ldl(A0); | |
1479 | - FT0 = (CPU86_LDouble)FP_CONVERT.i32; | |
1480 | -#else | |
1481 | - FT0 = (CPU86_LDouble)((int32_t)ldl(A0)); | |
1482 | -#endif | |
1483 | -} | |
1484 | - | |
1485 | -void OPPROTO op_fildll_FT0_A0(void) | |
1486 | -{ | |
1487 | -#ifdef USE_FP_CONVERT | |
1488 | - FP_CONVERT.i64 = (int64_t) ldq(A0); | |
1489 | - FT0 = (CPU86_LDouble)FP_CONVERT.i64; | |
1490 | -#else | |
1491 | - FT0 = (CPU86_LDouble)((int64_t)ldq(A0)); | |
1492 | -#endif | |
1493 | -} | |
1494 | -#endif | |
1495 | - | |
1496 | -/* fp load ST0 */ | |
1497 | - | |
1498 | -void OPPROTO op_flds_ST0_A0(void) | |
1499 | -{ | |
1500 | - int new_fpstt; | |
1501 | - new_fpstt = (env->fpstt - 1) & 7; | |
1502 | -#ifdef USE_FP_CONVERT | |
1503 | - FP_CONVERT.i32 = ldl(A0); | |
1504 | - env->fpregs[new_fpstt].d = FP_CONVERT.f; | |
1505 | -#else | |
1506 | - env->fpregs[new_fpstt].d = ldfl(A0); | |
1507 | -#endif | |
1508 | - env->fpstt = new_fpstt; | |
1509 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1510 | -} | |
1511 | - | |
1512 | -void OPPROTO op_fldl_ST0_A0(void) | |
1513 | -{ | |
1514 | - int new_fpstt; | |
1515 | - new_fpstt = (env->fpstt - 1) & 7; | |
1516 | -#ifdef USE_FP_CONVERT | |
1517 | - FP_CONVERT.i64 = ldq(A0); | |
1518 | - env->fpregs[new_fpstt].d = FP_CONVERT.d; | |
1519 | -#else | |
1520 | - env->fpregs[new_fpstt].d = ldfq(A0); | |
1521 | -#endif | |
1522 | - env->fpstt = new_fpstt; | |
1523 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1524 | -} | |
1525 | - | |
1526 | -void OPPROTO op_fldt_ST0_A0(void) | |
1527 | -{ | |
1528 | - helper_fldt_ST0_A0(); | |
1529 | -} | |
1530 | - | |
1531 | -/* helpers are needed to avoid static constant reference. XXX: find a better way */ | |
1532 | -#ifdef USE_INT_TO_FLOAT_HELPERS | |
1533 | - | |
1534 | -void helper_fild_ST0_A0(void) | |
1535 | -{ | |
1536 | - int new_fpstt; | |
1537 | - new_fpstt = (env->fpstt - 1) & 7; | |
1538 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0); | |
1539 | - env->fpstt = new_fpstt; | |
1540 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1541 | -} | |
1542 | - | |
1543 | -void helper_fildl_ST0_A0(void) | |
1544 | -{ | |
1545 | - int new_fpstt; | |
1546 | - new_fpstt = (env->fpstt - 1) & 7; | |
1547 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0)); | |
1548 | - env->fpstt = new_fpstt; | |
1549 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1550 | -} | |
1551 | - | |
1552 | -void helper_fildll_ST0_A0(void) | |
1553 | -{ | |
1554 | - int new_fpstt; | |
1555 | - new_fpstt = (env->fpstt - 1) & 7; | |
1556 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0)); | |
1557 | - env->fpstt = new_fpstt; | |
1558 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1559 | -} | |
1560 | - | |
1561 | -void OPPROTO op_fild_ST0_A0(void) | |
1562 | -{ | |
1563 | - helper_fild_ST0_A0(); | |
1564 | -} | |
1565 | - | |
1566 | -void OPPROTO op_fildl_ST0_A0(void) | |
1567 | -{ | |
1568 | - helper_fildl_ST0_A0(); | |
1569 | -} | |
1570 | - | |
1571 | -void OPPROTO op_fildll_ST0_A0(void) | |
1572 | -{ | |
1573 | - helper_fildll_ST0_A0(); | |
1574 | -} | |
1575 | - | |
1576 | -#else | |
1577 | - | |
1578 | -void OPPROTO op_fild_ST0_A0(void) | |
1579 | -{ | |
1580 | - int new_fpstt; | |
1581 | - new_fpstt = (env->fpstt - 1) & 7; | |
1582 | -#ifdef USE_FP_CONVERT | |
1583 | - FP_CONVERT.i32 = ldsw(A0); | |
1584 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32; | |
1585 | -#else | |
1586 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0); | |
1587 | -#endif | |
1588 | - env->fpstt = new_fpstt; | |
1589 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1590 | -} | |
1591 | - | |
1592 | -void OPPROTO op_fildl_ST0_A0(void) | |
1593 | -{ | |
1594 | - int new_fpstt; | |
1595 | - new_fpstt = (env->fpstt - 1) & 7; | |
1596 | -#ifdef USE_FP_CONVERT | |
1597 | - FP_CONVERT.i32 = (int32_t) ldl(A0); | |
1598 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32; | |
1599 | -#else | |
1600 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0)); | |
1601 | -#endif | |
1602 | - env->fpstt = new_fpstt; | |
1603 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1604 | -} | |
1605 | - | |
1606 | -void OPPROTO op_fildll_ST0_A0(void) | |
1607 | -{ | |
1608 | - int new_fpstt; | |
1609 | - new_fpstt = (env->fpstt - 1) & 7; | |
1610 | -#ifdef USE_FP_CONVERT | |
1611 | - FP_CONVERT.i64 = (int64_t) ldq(A0); | |
1612 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i64; | |
1613 | -#else | |
1614 | - env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0)); | |
1615 | -#endif | |
1616 | - env->fpstt = new_fpstt; | |
1617 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
1618 | -} | |
1619 | - | |
1620 | -#endif | |
1621 | - | |
1622 | -/* fp store */ | |
1623 | - | |
1624 | -void OPPROTO op_fsts_ST0_A0(void) | |
1625 | -{ | |
1626 | -#ifdef USE_FP_CONVERT | |
1627 | - FP_CONVERT.f = (float)ST0; | |
1628 | - stfl(A0, FP_CONVERT.f); | |
1629 | -#else | |
1630 | - stfl(A0, (float)ST0); | |
1631 | -#endif | |
1632 | - FORCE_RET(); | |
1633 | -} | |
1634 | - | |
1635 | -void OPPROTO op_fstl_ST0_A0(void) | |
1636 | -{ | |
1637 | - stfq(A0, (double)ST0); | |
1638 | - FORCE_RET(); | |
1639 | -} | |
1640 | - | |
1641 | -void OPPROTO op_fstt_ST0_A0(void) | |
1642 | -{ | |
1643 | - helper_fstt_ST0_A0(); | |
1644 | -} | |
1645 | - | |
1646 | -void OPPROTO op_fist_ST0_A0(void) | |
1647 | -{ | |
1648 | -#if defined(__sparc__) && !defined(__sparc_v9__) | |
1649 | - register CPU86_LDouble d asm("o0"); | |
1650 | -#else | |
1651 | - CPU86_LDouble d; | |
1652 | -#endif | |
1653 | - int val; | |
1654 | - | |
1655 | - d = ST0; | |
1656 | - val = floatx_to_int32(d, &env->fp_status); | |
1657 | - if (val != (int16_t)val) | |
1658 | - val = -32768; | |
1659 | - stw(A0, val); | |
1660 | - FORCE_RET(); | |
1661 | -} | |
1662 | - | |
1663 | -void OPPROTO op_fistl_ST0_A0(void) | |
1664 | -{ | |
1665 | -#if defined(__sparc__) && !defined(__sparc_v9__) | |
1666 | - register CPU86_LDouble d asm("o0"); | |
1667 | -#else | |
1668 | - CPU86_LDouble d; | |
1669 | -#endif | |
1670 | - int val; | |
1671 | - | |
1672 | - d = ST0; | |
1673 | - val = floatx_to_int32(d, &env->fp_status); | |
1674 | - stl(A0, val); | |
1675 | - FORCE_RET(); | |
1676 | -} | |
1677 | - | |
1678 | -void OPPROTO op_fistll_ST0_A0(void) | |
1679 | -{ | |
1680 | -#if defined(__sparc__) && !defined(__sparc_v9__) | |
1681 | - register CPU86_LDouble d asm("o0"); | |
1682 | -#else | |
1683 | - CPU86_LDouble d; | |
1684 | -#endif | |
1685 | - int64_t val; | |
1686 | - | |
1687 | - d = ST0; | |
1688 | - val = floatx_to_int64(d, &env->fp_status); | |
1689 | - stq(A0, val); | |
1690 | - FORCE_RET(); | |
1691 | -} | |
1692 | - | |
1693 | -void OPPROTO op_fistt_ST0_A0(void) | |
1694 | -{ | |
1695 | -#if defined(__sparc__) && !defined(__sparc_v9__) | |
1696 | - register CPU86_LDouble d asm("o0"); | |
1697 | -#else | |
1698 | - CPU86_LDouble d; | |
1699 | -#endif | |
1700 | - int val; | |
1701 | - | |
1702 | - d = ST0; | |
1703 | - val = floatx_to_int32_round_to_zero(d, &env->fp_status); | |
1704 | - if (val != (int16_t)val) | |
1705 | - val = -32768; | |
1706 | - stw(A0, val); | |
1707 | - FORCE_RET(); | |
1708 | -} | |
1709 | - | |
1710 | -void OPPROTO op_fisttl_ST0_A0(void) | |
1711 | -{ | |
1712 | -#if defined(__sparc__) && !defined(__sparc_v9__) | |
1713 | - register CPU86_LDouble d asm("o0"); | |
1714 | -#else | |
1715 | - CPU86_LDouble d; | |
1716 | -#endif | |
1717 | - int val; | |
1718 | - | |
1719 | - d = ST0; | |
1720 | - val = floatx_to_int32_round_to_zero(d, &env->fp_status); | |
1721 | - stl(A0, val); | |
1722 | - FORCE_RET(); | |
1723 | -} | |
1724 | - | |
1725 | -void OPPROTO op_fisttll_ST0_A0(void) | |
1726 | -{ | |
1727 | -#if defined(__sparc__) && !defined(__sparc_v9__) | |
1728 | - register CPU86_LDouble d asm("o0"); | |
1729 | -#else | |
1730 | - CPU86_LDouble d; | |
1731 | -#endif | |
1732 | - int64_t val; | |
1733 | - | |
1734 | - d = ST0; | |
1735 | - val = floatx_to_int64_round_to_zero(d, &env->fp_status); | |
1736 | - stq(A0, val); | |
1737 | - FORCE_RET(); | |
1738 | -} | |
1739 | - | |
1740 | -void OPPROTO op_fbld_ST0_A0(void) | |
1741 | -{ | |
1742 | - helper_fbld_ST0_A0(); | |
1743 | -} | |
1744 | - | |
1745 | -void OPPROTO op_fbst_ST0_A0(void) | |
1746 | -{ | |
1747 | - helper_fbst_ST0_A0(); | |
1748 | -} | |
1749 | - | |
1750 | -/* FPU move */ | |
1751 | - | |
1752 | -void OPPROTO op_fpush(void) | |
1753 | -{ | |
1754 | - fpush(); | |
1755 | -} | |
1756 | - | |
1757 | -void OPPROTO op_fpop(void) | |
1758 | -{ | |
1759 | - fpop(); | |
1760 | -} | |
1761 | - | |
1762 | -void OPPROTO op_fdecstp(void) | |
1763 | -{ | |
1764 | - env->fpstt = (env->fpstt - 1) & 7; | |
1765 | - env->fpus &= (~0x4700); | |
1766 | -} | |
1767 | - | |
1768 | -void OPPROTO op_fincstp(void) | |
1769 | -{ | |
1770 | - env->fpstt = (env->fpstt + 1) & 7; | |
1771 | - env->fpus &= (~0x4700); | |
1772 | -} | |
1773 | - | |
1774 | -void OPPROTO op_ffree_STN(void) | |
1775 | -{ | |
1776 | - env->fptags[(env->fpstt + PARAM1) & 7] = 1; | |
1777 | -} | |
1778 | - | |
1779 | -void OPPROTO op_fmov_ST0_FT0(void) | |
1780 | -{ | |
1781 | - ST0 = FT0; | |
1782 | -} | |
1783 | - | |
1784 | -void OPPROTO op_fmov_FT0_STN(void) | |
1785 | -{ | |
1786 | - FT0 = ST(PARAM1); | |
1787 | -} | |
1788 | - | |
1789 | -void OPPROTO op_fmov_ST0_STN(void) | |
1790 | -{ | |
1791 | - ST0 = ST(PARAM1); | |
1792 | -} | |
1793 | - | |
1794 | -void OPPROTO op_fmov_STN_ST0(void) | |
1795 | -{ | |
1796 | - ST(PARAM1) = ST0; | |
1797 | -} | |
1798 | - | |
1799 | -void OPPROTO op_fxchg_ST0_STN(void) | |
1404 | +void OPPROTO op_fcomi_dummy(void) | |
1800 | 1405 | { |
1801 | - CPU86_LDouble tmp; | |
1802 | - tmp = ST(PARAM1); | |
1803 | - ST(PARAM1) = ST0; | |
1804 | - ST0 = tmp; | |
1805 | -} | |
1806 | - | |
1807 | -/* FPU operations */ | |
1808 | - | |
1809 | -const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; | |
1810 | - | |
1811 | -void OPPROTO op_fcom_ST0_FT0(void) | |
1812 | -{ | |
1813 | - int ret; | |
1814 | - | |
1815 | - ret = floatx_compare(ST0, FT0, &env->fp_status); | |
1816 | - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; | |
1817 | - FORCE_RET(); | |
1818 | -} | |
1819 | - | |
1820 | -void OPPROTO op_fucom_ST0_FT0(void) | |
1821 | -{ | |
1822 | - int ret; | |
1823 | - | |
1824 | - ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); | |
1825 | - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; | |
1826 | - FORCE_RET(); | |
1827 | -} | |
1828 | - | |
1829 | -const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; | |
1830 | - | |
1831 | -void OPPROTO op_fcomi_ST0_FT0(void) | |
1832 | -{ | |
1833 | - int eflags; | |
1834 | - int ret; | |
1835 | - | |
1836 | - ret = floatx_compare(ST0, FT0, &env->fp_status); | |
1837 | - eflags = cc_table[CC_OP].compute_all(); | |
1838 | - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; | |
1839 | - CC_SRC = eflags; | |
1840 | - FORCE_RET(); | |
1841 | -} | |
1842 | - | |
1843 | -void OPPROTO op_fucomi_ST0_FT0(void) | |
1844 | -{ | |
1845 | - int eflags; | |
1846 | - int ret; | |
1847 | - | |
1848 | - ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); | |
1849 | - eflags = cc_table[CC_OP].compute_all(); | |
1850 | - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; | |
1851 | - CC_SRC = eflags; | |
1852 | - FORCE_RET(); | |
1853 | -} | |
1854 | - | |
1855 | -void OPPROTO op_fcmov_ST0_STN_T0(void) | |
1856 | -{ | |
1857 | - if (T0) { | |
1858 | - ST0 = ST(PARAM1); | |
1859 | - } | |
1860 | - FORCE_RET(); | |
1861 | -} | |
1862 | - | |
1863 | -void OPPROTO op_fadd_ST0_FT0(void) | |
1864 | -{ | |
1865 | - ST0 += FT0; | |
1866 | -} | |
1867 | - | |
1868 | -void OPPROTO op_fmul_ST0_FT0(void) | |
1869 | -{ | |
1870 | - ST0 *= FT0; | |
1871 | -} | |
1872 | - | |
1873 | -void OPPROTO op_fsub_ST0_FT0(void) | |
1874 | -{ | |
1875 | - ST0 -= FT0; | |
1876 | -} | |
1877 | - | |
1878 | -void OPPROTO op_fsubr_ST0_FT0(void) | |
1879 | -{ | |
1880 | - ST0 = FT0 - ST0; | |
1881 | -} | |
1882 | - | |
1883 | -void OPPROTO op_fdiv_ST0_FT0(void) | |
1884 | -{ | |
1885 | - ST0 = helper_fdiv(ST0, FT0); | |
1886 | -} | |
1887 | - | |
1888 | -void OPPROTO op_fdivr_ST0_FT0(void) | |
1889 | -{ | |
1890 | - ST0 = helper_fdiv(FT0, ST0); | |
1891 | -} | |
1892 | - | |
1893 | -/* fp operations between STN and ST0 */ | |
1894 | - | |
1895 | -void OPPROTO op_fadd_STN_ST0(void) | |
1896 | -{ | |
1897 | - ST(PARAM1) += ST0; | |
1898 | -} | |
1899 | - | |
1900 | -void OPPROTO op_fmul_STN_ST0(void) | |
1901 | -{ | |
1902 | - ST(PARAM1) *= ST0; | |
1903 | -} | |
1904 | - | |
1905 | -void OPPROTO op_fsub_STN_ST0(void) | |
1906 | -{ | |
1907 | - ST(PARAM1) -= ST0; | |
1908 | -} | |
1909 | - | |
1910 | -void OPPROTO op_fsubr_STN_ST0(void) | |
1911 | -{ | |
1912 | - CPU86_LDouble *p; | |
1913 | - p = &ST(PARAM1); | |
1914 | - *p = ST0 - *p; | |
1915 | -} | |
1916 | - | |
1917 | -void OPPROTO op_fdiv_STN_ST0(void) | |
1918 | -{ | |
1919 | - CPU86_LDouble *p; | |
1920 | - p = &ST(PARAM1); | |
1921 | - *p = helper_fdiv(*p, ST0); | |
1922 | -} | |
1923 | - | |
1924 | -void OPPROTO op_fdivr_STN_ST0(void) | |
1925 | -{ | |
1926 | - CPU86_LDouble *p; | |
1927 | - p = &ST(PARAM1); | |
1928 | - *p = helper_fdiv(ST0, *p); | |
1929 | -} | |
1930 | - | |
1931 | -/* misc FPU operations */ | |
1932 | -void OPPROTO op_fchs_ST0(void) | |
1933 | -{ | |
1934 | - ST0 = floatx_chs(ST0); | |
1935 | -} | |
1936 | - | |
1937 | -void OPPROTO op_fabs_ST0(void) | |
1938 | -{ | |
1939 | - ST0 = floatx_abs(ST0); | |
1940 | -} | |
1941 | - | |
1942 | -void OPPROTO op_fxam_ST0(void) | |
1943 | -{ | |
1944 | - helper_fxam_ST0(); | |
1945 | -} | |
1946 | - | |
1947 | -void OPPROTO op_fld1_ST0(void) | |
1948 | -{ | |
1949 | - ST0 = f15rk[1]; | |
1950 | -} | |
1951 | - | |
1952 | -void OPPROTO op_fldl2t_ST0(void) | |
1953 | -{ | |
1954 | - ST0 = f15rk[6]; | |
1955 | -} | |
1956 | - | |
1957 | -void OPPROTO op_fldl2e_ST0(void) | |
1958 | -{ | |
1959 | - ST0 = f15rk[5]; | |
1960 | -} | |
1961 | - | |
1962 | -void OPPROTO op_fldpi_ST0(void) | |
1963 | -{ | |
1964 | - ST0 = f15rk[2]; | |
1965 | -} | |
1966 | - | |
1967 | -void OPPROTO op_fldlg2_ST0(void) | |
1968 | -{ | |
1969 | - ST0 = f15rk[3]; | |
1970 | -} | |
1971 | - | |
1972 | -void OPPROTO op_fldln2_ST0(void) | |
1973 | -{ | |
1974 | - ST0 = f15rk[4]; | |
1975 | -} | |
1976 | - | |
1977 | -void OPPROTO op_fldz_ST0(void) | |
1978 | -{ | |
1979 | - ST0 = f15rk[0]; | |
1980 | -} | |
1981 | - | |
1982 | -void OPPROTO op_fldz_FT0(void) | |
1983 | -{ | |
1984 | - FT0 = f15rk[0]; | |
1985 | -} | |
1986 | - | |
1987 | -/* associated heplers to reduce generated code length and to simplify | |
1988 | - relocation (FP constants are usually stored in .rodata section) */ | |
1989 | - | |
1990 | -void OPPROTO op_f2xm1(void) | |
1991 | -{ | |
1992 | - helper_f2xm1(); | |
1993 | -} | |
1994 | - | |
1995 | -void OPPROTO op_fyl2x(void) | |
1996 | -{ | |
1997 | - helper_fyl2x(); | |
1998 | -} | |
1999 | - | |
2000 | -void OPPROTO op_fptan(void) | |
2001 | -{ | |
2002 | - helper_fptan(); | |
2003 | -} | |
2004 | - | |
2005 | -void OPPROTO op_fpatan(void) | |
2006 | -{ | |
2007 | - helper_fpatan(); | |
2008 | -} | |
2009 | - | |
2010 | -void OPPROTO op_fxtract(void) | |
2011 | -{ | |
2012 | - helper_fxtract(); | |
2013 | -} | |
2014 | - | |
2015 | -void OPPROTO op_fprem1(void) | |
2016 | -{ | |
2017 | - helper_fprem1(); | |
2018 | -} | |
2019 | - | |
2020 | - | |
2021 | -void OPPROTO op_fprem(void) | |
2022 | -{ | |
2023 | - helper_fprem(); | |
2024 | -} | |
2025 | - | |
2026 | -void OPPROTO op_fyl2xp1(void) | |
2027 | -{ | |
2028 | - helper_fyl2xp1(); | |
2029 | -} | |
2030 | - | |
2031 | -void OPPROTO op_fsqrt(void) | |
2032 | -{ | |
2033 | - helper_fsqrt(); | |
2034 | -} | |
2035 | - | |
2036 | -void OPPROTO op_fsincos(void) | |
2037 | -{ | |
2038 | - helper_fsincos(); | |
2039 | -} | |
2040 | - | |
2041 | -void OPPROTO op_frndint(void) | |
2042 | -{ | |
2043 | - helper_frndint(); | |
2044 | -} | |
2045 | - | |
2046 | -void OPPROTO op_fscale(void) | |
2047 | -{ | |
2048 | - helper_fscale(); | |
2049 | -} | |
2050 | - | |
2051 | -void OPPROTO op_fsin(void) | |
2052 | -{ | |
2053 | - helper_fsin(); | |
2054 | -} | |
2055 | - | |
2056 | -void OPPROTO op_fcos(void) | |
2057 | -{ | |
2058 | - helper_fcos(); | |
2059 | -} | |
2060 | - | |
2061 | -void OPPROTO op_fnstsw_A0(void) | |
2062 | -{ | |
2063 | - int fpus; | |
2064 | - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | |
2065 | - stw(A0, fpus); | |
2066 | - FORCE_RET(); | |
2067 | -} | |
2068 | - | |
2069 | -void OPPROTO op_fnstsw_EAX(void) | |
2070 | -{ | |
2071 | - int fpus; | |
2072 | - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | |
2073 | - EAX = (EAX & ~0xffff) | fpus; | |
2074 | -} | |
2075 | - | |
2076 | -void OPPROTO op_fnstcw_A0(void) | |
2077 | -{ | |
2078 | - stw(A0, env->fpuc); | |
2079 | - FORCE_RET(); | |
2080 | -} | |
2081 | - | |
2082 | -void OPPROTO op_fldcw_A0(void) | |
2083 | -{ | |
2084 | - env->fpuc = lduw(A0); | |
2085 | - update_fp_status(); | |
2086 | -} | |
2087 | - | |
2088 | -void OPPROTO op_fclex(void) | |
2089 | -{ | |
2090 | - env->fpus &= 0x7f00; | |
2091 | -} | |
2092 | - | |
2093 | -void OPPROTO op_fwait(void) | |
2094 | -{ | |
2095 | - if (env->fpus & FPUS_SE) | |
2096 | - fpu_raise_exception(); | |
2097 | - FORCE_RET(); | |
2098 | -} | |
2099 | - | |
2100 | -void OPPROTO op_fninit(void) | |
2101 | -{ | |
2102 | - env->fpus = 0; | |
2103 | - env->fpstt = 0; | |
2104 | - env->fpuc = 0x37f; | |
2105 | - env->fptags[0] = 1; | |
2106 | - env->fptags[1] = 1; | |
2107 | - env->fptags[2] = 1; | |
2108 | - env->fptags[3] = 1; | |
2109 | - env->fptags[4] = 1; | |
2110 | - env->fptags[5] = 1; | |
2111 | - env->fptags[6] = 1; | |
2112 | - env->fptags[7] = 1; | |
2113 | -} | |
2114 | - | |
2115 | -void OPPROTO op_fnstenv_A0(void) | |
2116 | -{ | |
2117 | - helper_fstenv(A0, PARAM1); | |
2118 | -} | |
2119 | - | |
2120 | -void OPPROTO op_fldenv_A0(void) | |
2121 | -{ | |
2122 | - helper_fldenv(A0, PARAM1); | |
2123 | -} | |
2124 | - | |
2125 | -void OPPROTO op_fnsave_A0(void) | |
2126 | -{ | |
2127 | - helper_fsave(A0, PARAM1); | |
2128 | -} | |
2129 | - | |
2130 | -void OPPROTO op_frstor_A0(void) | |
2131 | -{ | |
2132 | - helper_frstor(A0, PARAM1); | |
1406 | + T0 = 0; | |
2133 | 1407 | } |
2134 | 1408 | |
2135 | 1409 | /* threading support */ |
... | ... | @@ -2149,16 +1423,6 @@ void OPPROTO op_com_dummy(void) |
2149 | 1423 | T0 = 0; |
2150 | 1424 | } |
2151 | 1425 | |
2152 | -void OPPROTO op_fxsave_A0(void) | |
2153 | -{ | |
2154 | - helper_fxsave(A0, PARAM1); | |
2155 | -} | |
2156 | - | |
2157 | -void OPPROTO op_fxrstor_A0(void) | |
2158 | -{ | |
2159 | - helper_fxrstor(A0, PARAM1); | |
2160 | -} | |
2161 | - | |
2162 | 1426 | /* Secure Virtual Machine ops */ |
2163 | 1427 | |
2164 | 1428 | void OPPROTO op_vmrun(void) | ... | ... |
target-i386/translate.c
... | ... | @@ -1288,27 +1288,27 @@ static GenOpFunc *gen_setcc_sub[4][8] = { |
1288 | 1288 | #endif |
1289 | 1289 | }; |
1290 | 1290 | |
1291 | -static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = { | |
1292 | - gen_op_fadd_ST0_FT0, | |
1293 | - gen_op_fmul_ST0_FT0, | |
1294 | - gen_op_fcom_ST0_FT0, | |
1295 | - gen_op_fcom_ST0_FT0, | |
1296 | - gen_op_fsub_ST0_FT0, | |
1297 | - gen_op_fsubr_ST0_FT0, | |
1298 | - gen_op_fdiv_ST0_FT0, | |
1299 | - gen_op_fdivr_ST0_FT0, | |
1291 | +static void *helper_fp_arith_ST0_FT0[8] = { | |
1292 | + helper_fadd_ST0_FT0, | |
1293 | + helper_fmul_ST0_FT0, | |
1294 | + helper_fcom_ST0_FT0, | |
1295 | + helper_fcom_ST0_FT0, | |
1296 | + helper_fsub_ST0_FT0, | |
1297 | + helper_fsubr_ST0_FT0, | |
1298 | + helper_fdiv_ST0_FT0, | |
1299 | + helper_fdivr_ST0_FT0, | |
1300 | 1300 | }; |
1301 | 1301 | |
1302 | 1302 | /* NOTE the exception in "r" op ordering */ |
1303 | -static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = { | |
1304 | - gen_op_fadd_STN_ST0, | |
1305 | - gen_op_fmul_STN_ST0, | |
1303 | +static void *helper_fp_arith_STN_ST0[8] = { | |
1304 | + helper_fadd_STN_ST0, | |
1305 | + helper_fmul_STN_ST0, | |
1306 | 1306 | NULL, |
1307 | 1307 | NULL, |
1308 | - gen_op_fsubr_STN_ST0, | |
1309 | - gen_op_fsub_STN_ST0, | |
1310 | - gen_op_fdivr_STN_ST0, | |
1311 | - gen_op_fdiv_STN_ST0, | |
1308 | + helper_fsubr_STN_ST0, | |
1309 | + helper_fsub_STN_ST0, | |
1310 | + helper_fdivr_STN_ST0, | |
1311 | + helper_fdiv_STN_ST0, | |
1312 | 1312 | }; |
1313 | 1313 | |
1314 | 1314 | /* if d == OR_TMP0, it means memory operand (address in A0) */ |
... | ... | @@ -3014,7 +3014,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) |
3014 | 3014 | tcg_gen_addi_ptr(cpu_ptr0, cpu_env, |
3015 | 3015 | offsetof(CPUX86State,xmm_regs[rm])); |
3016 | 3016 | tcg_gen_helper_1_1(helper_movmskps, cpu_tmp2, cpu_ptr0); |
3017 | - tcg_gen_extu_i32_i64(cpu_T[0], cpu_tmp2); | |
3017 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
3018 | 3018 | gen_op_mov_reg_T0(OT_LONG, reg); |
3019 | 3019 | break; |
3020 | 3020 | case 0x150: /* movmskpd */ |
... | ... | @@ -3022,7 +3022,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) |
3022 | 3022 | tcg_gen_addi_ptr(cpu_ptr0, cpu_env, |
3023 | 3023 | offsetof(CPUX86State,xmm_regs[rm])); |
3024 | 3024 | tcg_gen_helper_1_1(helper_movmskpd, cpu_tmp2, cpu_ptr0); |
3025 | - tcg_gen_extu_i32_i64(cpu_T[0], cpu_tmp2); | |
3025 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
3026 | 3026 | gen_op_mov_reg_T0(OT_LONG, reg); |
3027 | 3027 | break; |
3028 | 3028 | case 0x02a: /* cvtpi2ps */ |
... | ... | @@ -3113,7 +3113,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) |
3113 | 3113 | tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset); |
3114 | 3114 | if (ot == OT_LONG) { |
3115 | 3115 | tcg_gen_helper_1_1(sse_op2, cpu_tmp2, cpu_ptr0); |
3116 | - tcg_gen_extu_i32_i64(cpu_T[0], cpu_tmp2); | |
3116 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
3117 | 3117 | } else { |
3118 | 3118 | tcg_gen_helper_1_1(sse_op2, cpu_T[0], cpu_ptr0); |
3119 | 3119 | } |
... | ... | @@ -3301,7 +3301,6 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) |
3301 | 3301 | } |
3302 | 3302 | } |
3303 | 3303 | |
3304 | - | |
3305 | 3304 | /* convert one instruction. s->is_jmp is set if the translation must |
3306 | 3305 | be stopped. Return the next pc value */ |
3307 | 3306 | static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
... | ... | @@ -4536,24 +4535,32 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4536 | 4535 | |
4537 | 4536 | switch(op >> 4) { |
4538 | 4537 | case 0: |
4539 | - gen_op_flds_FT0_A0(); | |
4538 | + gen_op_ld_T0_A0(OT_LONG); | |
4539 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4540 | + tcg_gen_helper_0_1(helper_flds_FT0, cpu_tmp2); | |
4540 | 4541 | break; |
4541 | 4542 | case 1: |
4542 | - gen_op_fildl_FT0_A0(); | |
4543 | + gen_op_ld_T0_A0(OT_LONG); | |
4544 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4545 | + tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2); | |
4543 | 4546 | break; |
4544 | 4547 | case 2: |
4545 | - gen_op_fldl_FT0_A0(); | |
4548 | + tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, | |
4549 | + (s->mem_index >> 2) - 1); | |
4550 | + tcg_gen_helper_0_1(helper_fldl_FT0, cpu_tmp1); | |
4546 | 4551 | break; |
4547 | 4552 | case 3: |
4548 | 4553 | default: |
4549 | - gen_op_fild_FT0_A0(); | |
4554 | + gen_op_ld_T0_A0(OT_WORD); | |
4555 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4556 | + tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2); | |
4550 | 4557 | break; |
4551 | 4558 | } |
4552 | 4559 | |
4553 | - gen_op_fp_arith_ST0_FT0[op1](); | |
4560 | + tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]); | |
4554 | 4561 | if (op1 == 3) { |
4555 | 4562 | /* fcomp needs pop */ |
4556 | - gen_op_fpop(); | |
4563 | + tcg_gen_helper_0_0(helper_fpop); | |
4557 | 4564 | } |
4558 | 4565 | } |
4559 | 4566 | break; |
... | ... | @@ -4567,96 +4574,158 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4567 | 4574 | case 0: |
4568 | 4575 | switch(op >> 4) { |
4569 | 4576 | case 0: |
4570 | - gen_op_flds_ST0_A0(); | |
4577 | + gen_op_ld_T0_A0(OT_LONG); | |
4578 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4579 | + tcg_gen_helper_0_1(helper_flds_ST0, cpu_tmp2); | |
4571 | 4580 | break; |
4572 | 4581 | case 1: |
4573 | - gen_op_fildl_ST0_A0(); | |
4582 | + gen_op_ld_T0_A0(OT_LONG); | |
4583 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4584 | + tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2); | |
4574 | 4585 | break; |
4575 | 4586 | case 2: |
4576 | - gen_op_fldl_ST0_A0(); | |
4587 | + tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, | |
4588 | + (s->mem_index >> 2) - 1); | |
4589 | + tcg_gen_helper_0_1(helper_fldl_ST0, cpu_tmp1); | |
4577 | 4590 | break; |
4578 | 4591 | case 3: |
4579 | 4592 | default: |
4580 | - gen_op_fild_ST0_A0(); | |
4593 | + gen_op_ld_T0_A0(OT_WORD); | |
4594 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4595 | + tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2); | |
4581 | 4596 | break; |
4582 | 4597 | } |
4583 | 4598 | break; |
4584 | 4599 | case 1: |
4600 | + /* XXX: the corresponding CPUID bit must be tested ! */ | |
4585 | 4601 | switch(op >> 4) { |
4586 | 4602 | case 1: |
4587 | - gen_op_fisttl_ST0_A0(); | |
4603 | + tcg_gen_helper_1_0(helper_fisttl_ST0, cpu_tmp2); | |
4604 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4605 | + gen_op_st_T0_A0(OT_LONG); | |
4588 | 4606 | break; |
4589 | 4607 | case 2: |
4590 | - gen_op_fisttll_ST0_A0(); | |
4608 | + tcg_gen_helper_1_0(helper_fisttll_ST0, cpu_tmp1); | |
4609 | + tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, | |
4610 | + (s->mem_index >> 2) - 1); | |
4591 | 4611 | break; |
4592 | 4612 | case 3: |
4593 | 4613 | default: |
4594 | - gen_op_fistt_ST0_A0(); | |
4614 | + tcg_gen_helper_1_0(helper_fistt_ST0, cpu_tmp2); | |
4615 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4616 | + gen_op_st_T0_A0(OT_WORD); | |
4617 | + break; | |
4595 | 4618 | } |
4596 | - gen_op_fpop(); | |
4619 | + tcg_gen_helper_0_0(helper_fpop); | |
4597 | 4620 | break; |
4598 | 4621 | default: |
4599 | 4622 | switch(op >> 4) { |
4600 | 4623 | case 0: |
4601 | - gen_op_fsts_ST0_A0(); | |
4624 | + tcg_gen_helper_1_0(helper_fsts_ST0, cpu_tmp2); | |
4625 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4626 | + gen_op_st_T0_A0(OT_LONG); | |
4602 | 4627 | break; |
4603 | 4628 | case 1: |
4604 | - gen_op_fistl_ST0_A0(); | |
4629 | + tcg_gen_helper_1_0(helper_fistl_ST0, cpu_tmp2); | |
4630 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4631 | + gen_op_st_T0_A0(OT_LONG); | |
4605 | 4632 | break; |
4606 | 4633 | case 2: |
4607 | - gen_op_fstl_ST0_A0(); | |
4634 | + tcg_gen_helper_1_0(helper_fstl_ST0, cpu_tmp1); | |
4635 | + tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, | |
4636 | + (s->mem_index >> 2) - 1); | |
4608 | 4637 | break; |
4609 | 4638 | case 3: |
4610 | 4639 | default: |
4611 | - gen_op_fist_ST0_A0(); | |
4640 | + tcg_gen_helper_1_0(helper_fist_ST0, cpu_tmp2); | |
4641 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4642 | + gen_op_st_T0_A0(OT_WORD); | |
4612 | 4643 | break; |
4613 | 4644 | } |
4614 | 4645 | if ((op & 7) == 3) |
4615 | - gen_op_fpop(); | |
4646 | + tcg_gen_helper_0_0(helper_fpop); | |
4616 | 4647 | break; |
4617 | 4648 | } |
4618 | 4649 | break; |
4619 | 4650 | case 0x0c: /* fldenv mem */ |
4620 | - gen_op_fldenv_A0(s->dflag); | |
4651 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4652 | + gen_op_set_cc_op(s->cc_op); | |
4653 | + gen_jmp_im(pc_start - s->cs_base); | |
4654 | + tcg_gen_helper_0_2(helper_fldenv, | |
4655 | + cpu_A0, tcg_const_i32(s->dflag)); | |
4621 | 4656 | break; |
4622 | 4657 | case 0x0d: /* fldcw mem */ |
4623 | - gen_op_fldcw_A0(); | |
4658 | + gen_op_ld_T0_A0(OT_WORD + s->mem_index); | |
4659 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
4660 | + tcg_gen_helper_0_1(helper_fldcw, cpu_tmp2); | |
4624 | 4661 | break; |
4625 | 4662 | case 0x0e: /* fnstenv mem */ |
4626 | - gen_op_fnstenv_A0(s->dflag); | |
4663 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4664 | + gen_op_set_cc_op(s->cc_op); | |
4665 | + gen_jmp_im(pc_start - s->cs_base); | |
4666 | + tcg_gen_helper_0_2(helper_fstenv, | |
4667 | + cpu_A0, tcg_const_i32(s->dflag)); | |
4627 | 4668 | break; |
4628 | 4669 | case 0x0f: /* fnstcw mem */ |
4629 | - gen_op_fnstcw_A0(); | |
4670 | + tcg_gen_helper_1_0(helper_fnstcw, cpu_tmp2); | |
4671 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4672 | + gen_op_st_T0_A0(OT_WORD + s->mem_index); | |
4630 | 4673 | break; |
4631 | 4674 | case 0x1d: /* fldt mem */ |
4632 | - gen_op_fldt_ST0_A0(); | |
4675 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4676 | + gen_op_set_cc_op(s->cc_op); | |
4677 | + gen_jmp_im(pc_start - s->cs_base); | |
4678 | + tcg_gen_helper_0_1(helper_fldt_ST0, cpu_A0); | |
4633 | 4679 | break; |
4634 | 4680 | case 0x1f: /* fstpt mem */ |
4635 | - gen_op_fstt_ST0_A0(); | |
4636 | - gen_op_fpop(); | |
4681 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4682 | + gen_op_set_cc_op(s->cc_op); | |
4683 | + gen_jmp_im(pc_start - s->cs_base); | |
4684 | + tcg_gen_helper_0_1(helper_fstt_ST0, cpu_A0); | |
4685 | + tcg_gen_helper_0_0(helper_fpop); | |
4637 | 4686 | break; |
4638 | 4687 | case 0x2c: /* frstor mem */ |
4639 | - gen_op_frstor_A0(s->dflag); | |
4688 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4689 | + gen_op_set_cc_op(s->cc_op); | |
4690 | + gen_jmp_im(pc_start - s->cs_base); | |
4691 | + tcg_gen_helper_0_2(helper_frstor, | |
4692 | + cpu_A0, tcg_const_i32(s->dflag)); | |
4640 | 4693 | break; |
4641 | 4694 | case 0x2e: /* fnsave mem */ |
4642 | - gen_op_fnsave_A0(s->dflag); | |
4695 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4696 | + gen_op_set_cc_op(s->cc_op); | |
4697 | + gen_jmp_im(pc_start - s->cs_base); | |
4698 | + tcg_gen_helper_0_2(helper_fsave, | |
4699 | + cpu_A0, tcg_const_i32(s->dflag)); | |
4643 | 4700 | break; |
4644 | 4701 | case 0x2f: /* fnstsw mem */ |
4645 | - gen_op_fnstsw_A0(); | |
4702 | + tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2); | |
4703 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4704 | + gen_op_st_T0_A0(OT_WORD + s->mem_index); | |
4646 | 4705 | break; |
4647 | 4706 | case 0x3c: /* fbld */ |
4648 | - gen_op_fbld_ST0_A0(); | |
4707 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4708 | + gen_op_set_cc_op(s->cc_op); | |
4709 | + gen_jmp_im(pc_start - s->cs_base); | |
4710 | + tcg_gen_helper_0_1(helper_fbld_ST0, cpu_A0); | |
4649 | 4711 | break; |
4650 | 4712 | case 0x3e: /* fbstp */ |
4651 | - gen_op_fbst_ST0_A0(); | |
4652 | - gen_op_fpop(); | |
4713 | + if (s->cc_op != CC_OP_DYNAMIC) | |
4714 | + gen_op_set_cc_op(s->cc_op); | |
4715 | + gen_jmp_im(pc_start - s->cs_base); | |
4716 | + tcg_gen_helper_0_1(helper_fbst_ST0, cpu_A0); | |
4717 | + tcg_gen_helper_0_0(helper_fpop); | |
4653 | 4718 | break; |
4654 | 4719 | case 0x3d: /* fildll */ |
4655 | - gen_op_fildll_ST0_A0(); | |
4720 | + tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, | |
4721 | + (s->mem_index >> 2) - 1); | |
4722 | + tcg_gen_helper_0_1(helper_fildll_ST0, cpu_tmp1); | |
4656 | 4723 | break; |
4657 | 4724 | case 0x3f: /* fistpll */ |
4658 | - gen_op_fistll_ST0_A0(); | |
4659 | - gen_op_fpop(); | |
4725 | + tcg_gen_helper_1_0(helper_fistll_ST0, cpu_tmp1); | |
4726 | + tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, | |
4727 | + (s->mem_index >> 2) - 1); | |
4728 | + tcg_gen_helper_0_0(helper_fpop); | |
4660 | 4729 | break; |
4661 | 4730 | default: |
4662 | 4731 | goto illegal_op; |
... | ... | @@ -4667,13 +4736,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4667 | 4736 | |
4668 | 4737 | switch(op) { |
4669 | 4738 | case 0x08: /* fld sti */ |
4670 | - gen_op_fpush(); | |
4671 | - gen_op_fmov_ST0_STN((opreg + 1) & 7); | |
4739 | + tcg_gen_helper_0_0(helper_fpush); | |
4740 | + tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32((opreg + 1) & 7)); | |
4672 | 4741 | break; |
4673 | 4742 | case 0x09: /* fxchg sti */ |
4674 | 4743 | case 0x29: /* fxchg4 sti, undocumented op */ |
4675 | 4744 | case 0x39: /* fxchg7 sti, undocumented op */ |
4676 | - gen_op_fxchg_ST0_STN(opreg); | |
4745 | + tcg_gen_helper_0_1(helper_fxchg_ST0_STN, tcg_const_i32(opreg)); | |
4677 | 4746 | break; |
4678 | 4747 | case 0x0a: /* grp d9/2 */ |
4679 | 4748 | switch(rm) { |
... | ... | @@ -4682,7 +4751,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4682 | 4751 | if (s->cc_op != CC_OP_DYNAMIC) |
4683 | 4752 | gen_op_set_cc_op(s->cc_op); |
4684 | 4753 | gen_jmp_im(pc_start - s->cs_base); |
4685 | - gen_op_fwait(); | |
4754 | + tcg_gen_helper_0_0(helper_fwait); | |
4686 | 4755 | break; |
4687 | 4756 | default: |
4688 | 4757 | goto illegal_op; |
... | ... | @@ -4691,17 +4760,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4691 | 4760 | case 0x0c: /* grp d9/4 */ |
4692 | 4761 | switch(rm) { |
4693 | 4762 | case 0: /* fchs */ |
4694 | - gen_op_fchs_ST0(); | |
4763 | + tcg_gen_helper_0_0(helper_fchs_ST0); | |
4695 | 4764 | break; |
4696 | 4765 | case 1: /* fabs */ |
4697 | - gen_op_fabs_ST0(); | |
4766 | + tcg_gen_helper_0_0(helper_fabs_ST0); | |
4698 | 4767 | break; |
4699 | 4768 | case 4: /* ftst */ |
4700 | - gen_op_fldz_FT0(); | |
4701 | - gen_op_fcom_ST0_FT0(); | |
4769 | + tcg_gen_helper_0_0(helper_fldz_FT0); | |
4770 | + tcg_gen_helper_0_0(helper_fcom_ST0_FT0); | |
4702 | 4771 | break; |
4703 | 4772 | case 5: /* fxam */ |
4704 | - gen_op_fxam_ST0(); | |
4773 | + tcg_gen_helper_0_0(helper_fxam_ST0); | |
4705 | 4774 | break; |
4706 | 4775 | default: |
4707 | 4776 | goto illegal_op; |
... | ... | @@ -4711,32 +4780,32 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4711 | 4780 | { |
4712 | 4781 | switch(rm) { |
4713 | 4782 | case 0: |
4714 | - gen_op_fpush(); | |
4715 | - gen_op_fld1_ST0(); | |
4783 | + tcg_gen_helper_0_0(helper_fpush); | |
4784 | + tcg_gen_helper_0_0(helper_fld1_ST0); | |
4716 | 4785 | break; |
4717 | 4786 | case 1: |
4718 | - gen_op_fpush(); | |
4719 | - gen_op_fldl2t_ST0(); | |
4787 | + tcg_gen_helper_0_0(helper_fpush); | |
4788 | + tcg_gen_helper_0_0(helper_fldl2t_ST0); | |
4720 | 4789 | break; |
4721 | 4790 | case 2: |
4722 | - gen_op_fpush(); | |
4723 | - gen_op_fldl2e_ST0(); | |
4791 | + tcg_gen_helper_0_0(helper_fpush); | |
4792 | + tcg_gen_helper_0_0(helper_fldl2e_ST0); | |
4724 | 4793 | break; |
4725 | 4794 | case 3: |
4726 | - gen_op_fpush(); | |
4727 | - gen_op_fldpi_ST0(); | |
4795 | + tcg_gen_helper_0_0(helper_fpush); | |
4796 | + tcg_gen_helper_0_0(helper_fldpi_ST0); | |
4728 | 4797 | break; |
4729 | 4798 | case 4: |
4730 | - gen_op_fpush(); | |
4731 | - gen_op_fldlg2_ST0(); | |
4799 | + tcg_gen_helper_0_0(helper_fpush); | |
4800 | + tcg_gen_helper_0_0(helper_fldlg2_ST0); | |
4732 | 4801 | break; |
4733 | 4802 | case 5: |
4734 | - gen_op_fpush(); | |
4735 | - gen_op_fldln2_ST0(); | |
4803 | + tcg_gen_helper_0_0(helper_fpush); | |
4804 | + tcg_gen_helper_0_0(helper_fldln2_ST0); | |
4736 | 4805 | break; |
4737 | 4806 | case 6: |
4738 | - gen_op_fpush(); | |
4739 | - gen_op_fldz_ST0(); | |
4807 | + tcg_gen_helper_0_0(helper_fpush); | |
4808 | + tcg_gen_helper_0_0(helper_fldz_ST0); | |
4740 | 4809 | break; |
4741 | 4810 | default: |
4742 | 4811 | goto illegal_op; |
... | ... | @@ -4746,58 +4815,58 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4746 | 4815 | case 0x0e: /* grp d9/6 */ |
4747 | 4816 | switch(rm) { |
4748 | 4817 | case 0: /* f2xm1 */ |
4749 | - gen_op_f2xm1(); | |
4818 | + tcg_gen_helper_0_0(helper_f2xm1); | |
4750 | 4819 | break; |
4751 | 4820 | case 1: /* fyl2x */ |
4752 | - gen_op_fyl2x(); | |
4821 | + tcg_gen_helper_0_0(helper_fyl2x); | |
4753 | 4822 | break; |
4754 | 4823 | case 2: /* fptan */ |
4755 | - gen_op_fptan(); | |
4824 | + tcg_gen_helper_0_0(helper_fptan); | |
4756 | 4825 | break; |
4757 | 4826 | case 3: /* fpatan */ |
4758 | - gen_op_fpatan(); | |
4827 | + tcg_gen_helper_0_0(helper_fpatan); | |
4759 | 4828 | break; |
4760 | 4829 | case 4: /* fxtract */ |
4761 | - gen_op_fxtract(); | |
4830 | + tcg_gen_helper_0_0(helper_fxtract); | |
4762 | 4831 | break; |
4763 | 4832 | case 5: /* fprem1 */ |
4764 | - gen_op_fprem1(); | |
4833 | + tcg_gen_helper_0_0(helper_fprem1); | |
4765 | 4834 | break; |
4766 | 4835 | case 6: /* fdecstp */ |
4767 | - gen_op_fdecstp(); | |
4836 | + tcg_gen_helper_0_0(helper_fdecstp); | |
4768 | 4837 | break; |
4769 | 4838 | default: |
4770 | 4839 | case 7: /* fincstp */ |
4771 | - gen_op_fincstp(); | |
4840 | + tcg_gen_helper_0_0(helper_fincstp); | |
4772 | 4841 | break; |
4773 | 4842 | } |
4774 | 4843 | break; |
4775 | 4844 | case 0x0f: /* grp d9/7 */ |
4776 | 4845 | switch(rm) { |
4777 | 4846 | case 0: /* fprem */ |
4778 | - gen_op_fprem(); | |
4847 | + tcg_gen_helper_0_0(helper_fprem); | |
4779 | 4848 | break; |
4780 | 4849 | case 1: /* fyl2xp1 */ |
4781 | - gen_op_fyl2xp1(); | |
4850 | + tcg_gen_helper_0_0(helper_fyl2xp1); | |
4782 | 4851 | break; |
4783 | 4852 | case 2: /* fsqrt */ |
4784 | - gen_op_fsqrt(); | |
4853 | + tcg_gen_helper_0_0(helper_fsqrt); | |
4785 | 4854 | break; |
4786 | 4855 | case 3: /* fsincos */ |
4787 | - gen_op_fsincos(); | |
4856 | + tcg_gen_helper_0_0(helper_fsincos); | |
4788 | 4857 | break; |
4789 | 4858 | case 5: /* fscale */ |
4790 | - gen_op_fscale(); | |
4859 | + tcg_gen_helper_0_0(helper_fscale); | |
4791 | 4860 | break; |
4792 | 4861 | case 4: /* frndint */ |
4793 | - gen_op_frndint(); | |
4862 | + tcg_gen_helper_0_0(helper_frndint); | |
4794 | 4863 | break; |
4795 | 4864 | case 6: /* fsin */ |
4796 | - gen_op_fsin(); | |
4865 | + tcg_gen_helper_0_0(helper_fsin); | |
4797 | 4866 | break; |
4798 | 4867 | default: |
4799 | 4868 | case 7: /* fcos */ |
4800 | - gen_op_fcos(); | |
4869 | + tcg_gen_helper_0_0(helper_fcos); | |
4801 | 4870 | break; |
4802 | 4871 | } |
4803 | 4872 | break; |
... | ... | @@ -4809,34 +4878,34 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4809 | 4878 | |
4810 | 4879 | op1 = op & 7; |
4811 | 4880 | if (op >= 0x20) { |
4812 | - gen_op_fp_arith_STN_ST0[op1](opreg); | |
4881 | + tcg_gen_helper_0_1(helper_fp_arith_STN_ST0[op1], tcg_const_i32(opreg)); | |
4813 | 4882 | if (op >= 0x30) |
4814 | - gen_op_fpop(); | |
4883 | + tcg_gen_helper_0_0(helper_fpop); | |
4815 | 4884 | } else { |
4816 | - gen_op_fmov_FT0_STN(opreg); | |
4817 | - gen_op_fp_arith_ST0_FT0[op1](); | |
4885 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4886 | + tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]); | |
4818 | 4887 | } |
4819 | 4888 | } |
4820 | 4889 | break; |
4821 | 4890 | case 0x02: /* fcom */ |
4822 | 4891 | case 0x22: /* fcom2, undocumented op */ |
4823 | - gen_op_fmov_FT0_STN(opreg); | |
4824 | - gen_op_fcom_ST0_FT0(); | |
4892 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4893 | + tcg_gen_helper_0_0(helper_fcom_ST0_FT0); | |
4825 | 4894 | break; |
4826 | 4895 | case 0x03: /* fcomp */ |
4827 | 4896 | case 0x23: /* fcomp3, undocumented op */ |
4828 | 4897 | case 0x32: /* fcomp5, undocumented op */ |
4829 | - gen_op_fmov_FT0_STN(opreg); | |
4830 | - gen_op_fcom_ST0_FT0(); | |
4831 | - gen_op_fpop(); | |
4898 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4899 | + tcg_gen_helper_0_0(helper_fcom_ST0_FT0); | |
4900 | + tcg_gen_helper_0_0(helper_fpop); | |
4832 | 4901 | break; |
4833 | 4902 | case 0x15: /* da/5 */ |
4834 | 4903 | switch(rm) { |
4835 | 4904 | case 1: /* fucompp */ |
4836 | - gen_op_fmov_FT0_STN(1); | |
4837 | - gen_op_fucom_ST0_FT0(); | |
4838 | - gen_op_fpop(); | |
4839 | - gen_op_fpop(); | |
4905 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1)); | |
4906 | + tcg_gen_helper_0_0(helper_fucom_ST0_FT0); | |
4907 | + tcg_gen_helper_0_0(helper_fpop); | |
4908 | + tcg_gen_helper_0_0(helper_fpop); | |
4840 | 4909 | break; |
4841 | 4910 | default: |
4842 | 4911 | goto illegal_op; |
... | ... | @@ -4849,10 +4918,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4849 | 4918 | case 1: /* fdisi (287 only, just do nop here) */ |
4850 | 4919 | break; |
4851 | 4920 | case 2: /* fclex */ |
4852 | - gen_op_fclex(); | |
4921 | + tcg_gen_helper_0_0(helper_fclex); | |
4853 | 4922 | break; |
4854 | 4923 | case 3: /* fninit */ |
4855 | - gen_op_fninit(); | |
4924 | + tcg_gen_helper_0_0(helper_fninit); | |
4856 | 4925 | break; |
4857 | 4926 | case 4: /* fsetpm (287 only, just do nop here) */ |
4858 | 4927 | break; |
... | ... | @@ -4863,59 +4932,63 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4863 | 4932 | case 0x1d: /* fucomi */ |
4864 | 4933 | if (s->cc_op != CC_OP_DYNAMIC) |
4865 | 4934 | gen_op_set_cc_op(s->cc_op); |
4866 | - gen_op_fmov_FT0_STN(opreg); | |
4867 | - gen_op_fucomi_ST0_FT0(); | |
4935 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4936 | + tcg_gen_helper_0_0(helper_fucomi_ST0_FT0); | |
4937 | + gen_op_fcomi_dummy(); | |
4868 | 4938 | s->cc_op = CC_OP_EFLAGS; |
4869 | 4939 | break; |
4870 | 4940 | case 0x1e: /* fcomi */ |
4871 | 4941 | if (s->cc_op != CC_OP_DYNAMIC) |
4872 | 4942 | gen_op_set_cc_op(s->cc_op); |
4873 | - gen_op_fmov_FT0_STN(opreg); | |
4874 | - gen_op_fcomi_ST0_FT0(); | |
4943 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4944 | + tcg_gen_helper_0_0(helper_fcomi_ST0_FT0); | |
4945 | + gen_op_fcomi_dummy(); | |
4875 | 4946 | s->cc_op = CC_OP_EFLAGS; |
4876 | 4947 | break; |
4877 | 4948 | case 0x28: /* ffree sti */ |
4878 | - gen_op_ffree_STN(opreg); | |
4949 | + tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg)); | |
4879 | 4950 | break; |
4880 | 4951 | case 0x2a: /* fst sti */ |
4881 | - gen_op_fmov_STN_ST0(opreg); | |
4952 | + tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg)); | |
4882 | 4953 | break; |
4883 | 4954 | case 0x2b: /* fstp sti */ |
4884 | 4955 | case 0x0b: /* fstp1 sti, undocumented op */ |
4885 | 4956 | case 0x3a: /* fstp8 sti, undocumented op */ |
4886 | 4957 | case 0x3b: /* fstp9 sti, undocumented op */ |
4887 | - gen_op_fmov_STN_ST0(opreg); | |
4888 | - gen_op_fpop(); | |
4958 | + tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg)); | |
4959 | + tcg_gen_helper_0_0(helper_fpop); | |
4889 | 4960 | break; |
4890 | 4961 | case 0x2c: /* fucom st(i) */ |
4891 | - gen_op_fmov_FT0_STN(opreg); | |
4892 | - gen_op_fucom_ST0_FT0(); | |
4962 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4963 | + tcg_gen_helper_0_0(helper_fucom_ST0_FT0); | |
4893 | 4964 | break; |
4894 | 4965 | case 0x2d: /* fucomp st(i) */ |
4895 | - gen_op_fmov_FT0_STN(opreg); | |
4896 | - gen_op_fucom_ST0_FT0(); | |
4897 | - gen_op_fpop(); | |
4966 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
4967 | + tcg_gen_helper_0_0(helper_fucom_ST0_FT0); | |
4968 | + tcg_gen_helper_0_0(helper_fpop); | |
4898 | 4969 | break; |
4899 | 4970 | case 0x33: /* de/3 */ |
4900 | 4971 | switch(rm) { |
4901 | 4972 | case 1: /* fcompp */ |
4902 | - gen_op_fmov_FT0_STN(1); | |
4903 | - gen_op_fcom_ST0_FT0(); | |
4904 | - gen_op_fpop(); | |
4905 | - gen_op_fpop(); | |
4973 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1)); | |
4974 | + tcg_gen_helper_0_0(helper_fcom_ST0_FT0); | |
4975 | + tcg_gen_helper_0_0(helper_fpop); | |
4976 | + tcg_gen_helper_0_0(helper_fpop); | |
4906 | 4977 | break; |
4907 | 4978 | default: |
4908 | 4979 | goto illegal_op; |
4909 | 4980 | } |
4910 | 4981 | break; |
4911 | 4982 | case 0x38: /* ffreep sti, undocumented op */ |
4912 | - gen_op_ffree_STN(opreg); | |
4913 | - gen_op_fpop(); | |
4983 | + tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg)); | |
4984 | + tcg_gen_helper_0_0(helper_fpop); | |
4914 | 4985 | break; |
4915 | 4986 | case 0x3c: /* df/4 */ |
4916 | 4987 | switch(rm) { |
4917 | 4988 | case 0: |
4918 | - gen_op_fnstsw_EAX(); | |
4989 | + tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2); | |
4990 | + tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2); | |
4991 | + gen_op_mov_reg_T0(OT_WORD, R_EAX); | |
4919 | 4992 | break; |
4920 | 4993 | default: |
4921 | 4994 | goto illegal_op; |
... | ... | @@ -4924,23 +4997,25 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4924 | 4997 | case 0x3d: /* fucomip */ |
4925 | 4998 | if (s->cc_op != CC_OP_DYNAMIC) |
4926 | 4999 | gen_op_set_cc_op(s->cc_op); |
4927 | - gen_op_fmov_FT0_STN(opreg); | |
4928 | - gen_op_fucomi_ST0_FT0(); | |
4929 | - gen_op_fpop(); | |
5000 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
5001 | + tcg_gen_helper_0_0(helper_fucomi_ST0_FT0); | |
5002 | + tcg_gen_helper_0_0(helper_fpop); | |
5003 | + gen_op_fcomi_dummy(); | |
4930 | 5004 | s->cc_op = CC_OP_EFLAGS; |
4931 | 5005 | break; |
4932 | 5006 | case 0x3e: /* fcomip */ |
4933 | 5007 | if (s->cc_op != CC_OP_DYNAMIC) |
4934 | 5008 | gen_op_set_cc_op(s->cc_op); |
4935 | - gen_op_fmov_FT0_STN(opreg); | |
4936 | - gen_op_fcomi_ST0_FT0(); | |
4937 | - gen_op_fpop(); | |
5009 | + tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg)); | |
5010 | + tcg_gen_helper_0_0(helper_fcomi_ST0_FT0); | |
5011 | + tcg_gen_helper_0_0(helper_fpop); | |
5012 | + gen_op_fcomi_dummy(); | |
4938 | 5013 | s->cc_op = CC_OP_EFLAGS; |
4939 | 5014 | break; |
4940 | 5015 | case 0x10 ... 0x13: /* fcmovxx */ |
4941 | 5016 | case 0x18 ... 0x1b: |
4942 | 5017 | { |
4943 | - int op1; | |
5018 | + int op1, l1; | |
4944 | 5019 | const static uint8_t fcmov_cc[8] = { |
4945 | 5020 | (JCC_B << 1), |
4946 | 5021 | (JCC_Z << 1), |
... | ... | @@ -4949,7 +5024,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4949 | 5024 | }; |
4950 | 5025 | op1 = fcmov_cc[op & 3] | ((op >> 3) & 1); |
4951 | 5026 | gen_setcc(s, op1); |
4952 | - gen_op_fcmov_ST0_STN_T0(opreg); | |
5027 | + l1 = gen_new_label(); | |
5028 | + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1); | |
5029 | + tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32(opreg)); | |
5030 | + gen_set_label(l1); | |
4953 | 5031 | } |
4954 | 5032 | break; |
4955 | 5033 | default: |
... | ... | @@ -5550,7 +5628,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
5550 | 5628 | if (s->cc_op != CC_OP_DYNAMIC) |
5551 | 5629 | gen_op_set_cc_op(s->cc_op); |
5552 | 5630 | gen_jmp_im(pc_start - s->cs_base); |
5553 | - gen_op_fwait(); | |
5631 | + tcg_gen_helper_0_0(helper_fwait); | |
5554 | 5632 | } |
5555 | 5633 | break; |
5556 | 5634 | case 0xcc: /* int3 */ |
... | ... | @@ -6301,7 +6379,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
6301 | 6379 | break; |
6302 | 6380 | } |
6303 | 6381 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
6304 | - gen_op_fxsave_A0((s->dflag == 2)); | |
6382 | + if (s->cc_op != CC_OP_DYNAMIC) | |
6383 | + gen_op_set_cc_op(s->cc_op); | |
6384 | + gen_jmp_im(pc_start - s->cs_base); | |
6385 | + tcg_gen_helper_0_2(helper_fxsave, | |
6386 | + cpu_A0, tcg_const_i32((s->dflag == 2))); | |
6305 | 6387 | break; |
6306 | 6388 | case 1: /* fxrstor */ |
6307 | 6389 | if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || |
... | ... | @@ -6312,7 +6394,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
6312 | 6394 | break; |
6313 | 6395 | } |
6314 | 6396 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
6315 | - gen_op_fxrstor_A0((s->dflag == 2)); | |
6397 | + if (s->cc_op != CC_OP_DYNAMIC) | |
6398 | + gen_op_set_cc_op(s->cc_op); | |
6399 | + gen_jmp_im(pc_start - s->cs_base); | |
6400 | + tcg_gen_helper_0_2(helper_fxrstor, | |
6401 | + cpu_A0, tcg_const_i32((s->dflag == 2))); | |
6316 | 6402 | break; |
6317 | 6403 | case 2: /* ldmxcsr */ |
6318 | 6404 | case 3: /* stmxcsr */ |
... | ... | @@ -6615,8 +6701,8 @@ static uint16_t opc_write_flags[NB_OPS] = { |
6615 | 6701 | [INDEX_op_lsl] = CC_Z, |
6616 | 6702 | [INDEX_op_verr] = CC_Z, |
6617 | 6703 | [INDEX_op_verw] = CC_Z, |
6618 | - [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C, | |
6619 | - [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C, | |
6704 | + [INDEX_op_fcomi_dummy] = CC_Z | CC_P | CC_C, | |
6705 | + [INDEX_op_fcomi_dummy] = CC_Z | CC_P | CC_C, | |
6620 | 6706 | |
6621 | 6707 | #define DEF_WRITEF(SUFFIX)\ |
6622 | 6708 | [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\ | ... | ... |