Revision 19e6c4b8 target-i386/helper.c

b/target-i386/helper.c
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 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 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 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);

Also available in: Unified diff