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,\ | ... | ... |