Revision c31da136 target-i386/op_helper.c
b/target-i386/op_helper.c | ||
---|---|---|
95 | 95 |
6, 7, 8, 0, 1, 2, 3, 4, |
96 | 96 |
}; |
97 | 97 |
|
98 |
#if defined(CONFIG_SOFTFLOAT) |
|
99 |
# define floatx_lg2 make_floatx80( 0x3ffd, 0x9a209a84fbcff799LL ) |
|
100 |
# define floatx_l2e make_floatx80( 0x3fff, 0xb8aa3b295c17f0bcLL ) |
|
101 |
# define floatx_l2t make_floatx80( 0x4000, 0xd49a784bcd1b8afeLL ) |
|
102 |
#else |
|
103 |
# define floatx_lg2 (0.30102999566398119523L) |
|
104 |
# define floatx_l2e (1.44269504088896340739L) |
|
105 |
# define floatx_l2t (3.32192809488736234781L) |
|
106 |
#endif |
|
107 |
|
|
108 |
static const CPU86_LDouble f15rk[7] = |
|
109 |
{ |
|
110 |
floatx_zero, |
|
111 |
floatx_one, |
|
112 |
floatx_pi, |
|
113 |
floatx_lg2, |
|
114 |
floatx_ln2, |
|
115 |
floatx_l2e, |
|
116 |
floatx_l2t, |
|
98 |
#define floatx80_lg2 make_floatx80( 0x3ffd, 0x9a209a84fbcff799LL ) |
|
99 |
#define floatx80_l2e make_floatx80( 0x3fff, 0xb8aa3b295c17f0bcLL ) |
|
100 |
#define floatx80_l2t make_floatx80( 0x4000, 0xd49a784bcd1b8afeLL ) |
|
101 |
|
|
102 |
static const floatx80 f15rk[7] = |
|
103 |
{ |
|
104 |
floatx80_zero, |
|
105 |
floatx80_one, |
|
106 |
floatx80_pi, |
|
107 |
floatx80_lg2, |
|
108 |
floatx80_ln2, |
|
109 |
floatx80_l2e, |
|
110 |
floatx80_l2t, |
|
117 | 111 |
}; |
118 | 112 |
|
119 | 113 |
/* broken thread support */ |
... | ... | |
3442 | 3436 |
|
3443 | 3437 |
/* x87 FPU helpers */ |
3444 | 3438 |
|
3445 |
static inline double CPU86_LDouble_to_double(CPU86_LDouble a)
|
|
3439 |
static inline double floatx80_to_double(floatx80 a)
|
|
3446 | 3440 |
{ |
3447 | 3441 |
union { |
3448 | 3442 |
float64 f64; |
3449 | 3443 |
double d; |
3450 | 3444 |
} u; |
3451 | 3445 |
|
3452 |
u.f64 = floatx_to_float64(a, &env->fp_status); |
|
3446 |
u.f64 = floatx80_to_float64(a, &env->fp_status);
|
|
3453 | 3447 |
return u.d; |
3454 | 3448 |
} |
3455 | 3449 |
|
3456 |
static inline CPU86_LDouble double_to_CPU86_LDouble(double a)
|
|
3450 |
static inline floatx80 double_to_floatx80(double a)
|
|
3457 | 3451 |
{ |
3458 | 3452 |
union { |
3459 | 3453 |
float64 f64; |
... | ... | |
3461 | 3455 |
} u; |
3462 | 3456 |
|
3463 | 3457 |
u.d = a; |
3464 |
return float64_to_floatx(u.f64, &env->fp_status); |
|
3458 |
return float64_to_floatx80(u.f64, &env->fp_status);
|
|
3465 | 3459 |
} |
3466 | 3460 |
|
3467 | 3461 |
static void fpu_set_exception(int mask) |
... | ... | |
3471 | 3465 |
env->fpus |= FPUS_SE | FPUS_B; |
3472 | 3466 |
} |
3473 | 3467 |
|
3474 |
static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
|
|
3468 |
static inline floatx80 helper_fdiv(floatx80 a, floatx80 b)
|
|
3475 | 3469 |
{ |
3476 |
if (floatx_is_zero(b)) { |
|
3470 |
if (floatx80_is_zero(b)) {
|
|
3477 | 3471 |
fpu_set_exception(FPUS_ZE); |
3478 | 3472 |
} |
3479 |
return floatx_div(a, b, &env->fp_status); |
|
3473 |
return floatx80_div(a, b, &env->fp_status);
|
|
3480 | 3474 |
} |
3481 | 3475 |
|
3482 | 3476 |
static void fpu_raise_exception(void) |
... | ... | |
3498 | 3492 |
uint32_t i; |
3499 | 3493 |
} u; |
3500 | 3494 |
u.i = val; |
3501 |
FT0 = float32_to_floatx(u.f, &env->fp_status); |
|
3495 |
FT0 = float32_to_floatx80(u.f, &env->fp_status);
|
|
3502 | 3496 |
} |
3503 | 3497 |
|
3504 | 3498 |
void helper_fldl_FT0(uint64_t val) |
... | ... | |
3508 | 3502 |
uint64_t i; |
3509 | 3503 |
} u; |
3510 | 3504 |
u.i = val; |
3511 |
FT0 = float64_to_floatx(u.f, &env->fp_status); |
|
3505 |
FT0 = float64_to_floatx80(u.f, &env->fp_status);
|
|
3512 | 3506 |
} |
3513 | 3507 |
|
3514 | 3508 |
void helper_fildl_FT0(int32_t val) |
3515 | 3509 |
{ |
3516 |
FT0 = int32_to_floatx(val, &env->fp_status); |
|
3510 |
FT0 = int32_to_floatx80(val, &env->fp_status);
|
|
3517 | 3511 |
} |
3518 | 3512 |
|
3519 | 3513 |
void helper_flds_ST0(uint32_t val) |
... | ... | |
3525 | 3519 |
} u; |
3526 | 3520 |
new_fpstt = (env->fpstt - 1) & 7; |
3527 | 3521 |
u.i = val; |
3528 |
env->fpregs[new_fpstt].d = float32_to_floatx(u.f, &env->fp_status); |
|
3522 |
env->fpregs[new_fpstt].d = float32_to_floatx80(u.f, &env->fp_status);
|
|
3529 | 3523 |
env->fpstt = new_fpstt; |
3530 | 3524 |
env->fptags[new_fpstt] = 0; /* validate stack entry */ |
3531 | 3525 |
} |
... | ... | |
3539 | 3533 |
} u; |
3540 | 3534 |
new_fpstt = (env->fpstt - 1) & 7; |
3541 | 3535 |
u.i = val; |
3542 |
env->fpregs[new_fpstt].d = float64_to_floatx(u.f, &env->fp_status); |
|
3536 |
env->fpregs[new_fpstt].d = float64_to_floatx80(u.f, &env->fp_status);
|
|
3543 | 3537 |
env->fpstt = new_fpstt; |
3544 | 3538 |
env->fptags[new_fpstt] = 0; /* validate stack entry */ |
3545 | 3539 |
} |
... | ... | |
3548 | 3542 |
{ |
3549 | 3543 |
int new_fpstt; |
3550 | 3544 |
new_fpstt = (env->fpstt - 1) & 7; |
3551 |
env->fpregs[new_fpstt].d = int32_to_floatx(val, &env->fp_status); |
|
3545 |
env->fpregs[new_fpstt].d = int32_to_floatx80(val, &env->fp_status);
|
|
3552 | 3546 |
env->fpstt = new_fpstt; |
3553 | 3547 |
env->fptags[new_fpstt] = 0; /* validate stack entry */ |
3554 | 3548 |
} |
... | ... | |
3557 | 3551 |
{ |
3558 | 3552 |
int new_fpstt; |
3559 | 3553 |
new_fpstt = (env->fpstt - 1) & 7; |
3560 |
env->fpregs[new_fpstt].d = int64_to_floatx(val, &env->fp_status); |
|
3554 |
env->fpregs[new_fpstt].d = int64_to_floatx80(val, &env->fp_status);
|
|
3561 | 3555 |
env->fpstt = new_fpstt; |
3562 | 3556 |
env->fptags[new_fpstt] = 0; /* validate stack entry */ |
3563 | 3557 |
} |
... | ... | |
3568 | 3562 |
float32 f; |
3569 | 3563 |
uint32_t i; |
3570 | 3564 |
} u; |
3571 |
u.f = floatx_to_float32(ST0, &env->fp_status); |
|
3565 |
u.f = floatx80_to_float32(ST0, &env->fp_status);
|
|
3572 | 3566 |
return u.i; |
3573 | 3567 |
} |
3574 | 3568 |
|
... | ... | |
3578 | 3572 |
float64 f; |
3579 | 3573 |
uint64_t i; |
3580 | 3574 |
} u; |
3581 |
u.f = floatx_to_float64(ST0, &env->fp_status); |
|
3575 |
u.f = floatx80_to_float64(ST0, &env->fp_status);
|
|
3582 | 3576 |
return u.i; |
3583 | 3577 |
} |
3584 | 3578 |
|
3585 | 3579 |
int32_t helper_fist_ST0(void) |
3586 | 3580 |
{ |
3587 | 3581 |
int32_t val; |
3588 |
val = floatx_to_int32(ST0, &env->fp_status); |
|
3582 |
val = floatx80_to_int32(ST0, &env->fp_status);
|
|
3589 | 3583 |
if (val != (int16_t)val) |
3590 | 3584 |
val = -32768; |
3591 | 3585 |
return val; |
... | ... | |
3594 | 3588 |
int32_t helper_fistl_ST0(void) |
3595 | 3589 |
{ |
3596 | 3590 |
int32_t val; |
3597 |
val = floatx_to_int32(ST0, &env->fp_status); |
|
3591 |
val = floatx80_to_int32(ST0, &env->fp_status);
|
|
3598 | 3592 |
return val; |
3599 | 3593 |
} |
3600 | 3594 |
|
3601 | 3595 |
int64_t helper_fistll_ST0(void) |
3602 | 3596 |
{ |
3603 | 3597 |
int64_t val; |
3604 |
val = floatx_to_int64(ST0, &env->fp_status); |
|
3598 |
val = floatx80_to_int64(ST0, &env->fp_status);
|
|
3605 | 3599 |
return val; |
3606 | 3600 |
} |
3607 | 3601 |
|
3608 | 3602 |
int32_t helper_fistt_ST0(void) |
3609 | 3603 |
{ |
3610 | 3604 |
int32_t val; |
3611 |
val = floatx_to_int32_round_to_zero(ST0, &env->fp_status); |
|
3605 |
val = floatx80_to_int32_round_to_zero(ST0, &env->fp_status);
|
|
3612 | 3606 |
if (val != (int16_t)val) |
3613 | 3607 |
val = -32768; |
3614 | 3608 |
return val; |
... | ... | |
3617 | 3611 |
int32_t helper_fisttl_ST0(void) |
3618 | 3612 |
{ |
3619 | 3613 |
int32_t val; |
3620 |
val = floatx_to_int32_round_to_zero(ST0, &env->fp_status); |
|
3614 |
val = floatx80_to_int32_round_to_zero(ST0, &env->fp_status);
|
|
3621 | 3615 |
return val; |
3622 | 3616 |
} |
3623 | 3617 |
|
3624 | 3618 |
int64_t helper_fisttll_ST0(void) |
3625 | 3619 |
{ |
3626 | 3620 |
int64_t val; |
3627 |
val = floatx_to_int64_round_to_zero(ST0, &env->fp_status); |
|
3621 |
val = floatx80_to_int64_round_to_zero(ST0, &env->fp_status);
|
|
3628 | 3622 |
return val; |
3629 | 3623 |
} |
3630 | 3624 |
|
... | ... | |
3693 | 3687 |
|
3694 | 3688 |
void helper_fxchg_ST0_STN(int st_index) |
3695 | 3689 |
{ |
3696 |
CPU86_LDouble tmp;
|
|
3690 |
floatx80 tmp;
|
|
3697 | 3691 |
tmp = ST(st_index); |
3698 | 3692 |
ST(st_index) = ST0; |
3699 | 3693 |
ST0 = tmp; |
... | ... | |
3707 | 3701 |
{ |
3708 | 3702 |
int ret; |
3709 | 3703 |
|
3710 |
ret = floatx_compare(ST0, FT0, &env->fp_status); |
|
3704 |
ret = floatx80_compare(ST0, FT0, &env->fp_status);
|
|
3711 | 3705 |
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; |
3712 | 3706 |
} |
3713 | 3707 |
|
... | ... | |
3715 | 3709 |
{ |
3716 | 3710 |
int ret; |
3717 | 3711 |
|
3718 |
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); |
|
3712 |
ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
|
|
3719 | 3713 |
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; |
3720 | 3714 |
} |
3721 | 3715 |
|
... | ... | |
3726 | 3720 |
int eflags; |
3727 | 3721 |
int ret; |
3728 | 3722 |
|
3729 |
ret = floatx_compare(ST0, FT0, &env->fp_status); |
|
3723 |
ret = floatx80_compare(ST0, FT0, &env->fp_status);
|
|
3730 | 3724 |
eflags = helper_cc_compute_all(CC_OP); |
3731 | 3725 |
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; |
3732 | 3726 |
CC_SRC = eflags; |
... | ... | |
3737 | 3731 |
int eflags; |
3738 | 3732 |
int ret; |
3739 | 3733 |
|
3740 |
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); |
|
3734 |
ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
|
|
3741 | 3735 |
eflags = helper_cc_compute_all(CC_OP); |
3742 | 3736 |
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; |
3743 | 3737 |
CC_SRC = eflags; |
... | ... | |
3745 | 3739 |
|
3746 | 3740 |
void helper_fadd_ST0_FT0(void) |
3747 | 3741 |
{ |
3748 |
ST0 = floatx_add(ST0, FT0, &env->fp_status); |
|
3742 |
ST0 = floatx80_add(ST0, FT0, &env->fp_status);
|
|
3749 | 3743 |
} |
3750 | 3744 |
|
3751 | 3745 |
void helper_fmul_ST0_FT0(void) |
3752 | 3746 |
{ |
3753 |
ST0 = floatx_mul(ST0, FT0, &env->fp_status); |
|
3747 |
ST0 = floatx80_mul(ST0, FT0, &env->fp_status);
|
|
3754 | 3748 |
} |
3755 | 3749 |
|
3756 | 3750 |
void helper_fsub_ST0_FT0(void) |
3757 | 3751 |
{ |
3758 |
ST0 = floatx_sub(ST0, FT0, &env->fp_status); |
|
3752 |
ST0 = floatx80_sub(ST0, FT0, &env->fp_status);
|
|
3759 | 3753 |
} |
3760 | 3754 |
|
3761 | 3755 |
void helper_fsubr_ST0_FT0(void) |
3762 | 3756 |
{ |
3763 |
ST0 = floatx_sub(FT0, ST0, &env->fp_status); |
|
3757 |
ST0 = floatx80_sub(FT0, ST0, &env->fp_status);
|
|
3764 | 3758 |
} |
3765 | 3759 |
|
3766 | 3760 |
void helper_fdiv_ST0_FT0(void) |
... | ... | |
3777 | 3771 |
|
3778 | 3772 |
void helper_fadd_STN_ST0(int st_index) |
3779 | 3773 |
{ |
3780 |
ST(st_index) = floatx_add(ST(st_index), ST0, &env->fp_status); |
|
3774 |
ST(st_index) = floatx80_add(ST(st_index), ST0, &env->fp_status);
|
|
3781 | 3775 |
} |
3782 | 3776 |
|
3783 | 3777 |
void helper_fmul_STN_ST0(int st_index) |
3784 | 3778 |
{ |
3785 |
ST(st_index) = floatx_mul(ST(st_index), ST0, &env->fp_status); |
|
3779 |
ST(st_index) = floatx80_mul(ST(st_index), ST0, &env->fp_status);
|
|
3786 | 3780 |
} |
3787 | 3781 |
|
3788 | 3782 |
void helper_fsub_STN_ST0(int st_index) |
3789 | 3783 |
{ |
3790 |
ST(st_index) = floatx_sub(ST(st_index), ST0, &env->fp_status); |
|
3784 |
ST(st_index) = floatx80_sub(ST(st_index), ST0, &env->fp_status);
|
|
3791 | 3785 |
} |
3792 | 3786 |
|
3793 | 3787 |
void helper_fsubr_STN_ST0(int st_index) |
3794 | 3788 |
{ |
3795 |
ST(st_index) = floatx_sub(ST0, ST(st_index), &env->fp_status); |
|
3789 |
ST(st_index) = floatx80_sub(ST0, ST(st_index), &env->fp_status);
|
|
3796 | 3790 |
} |
3797 | 3791 |
|
3798 | 3792 |
void helper_fdiv_STN_ST0(int st_index) |
3799 | 3793 |
{ |
3800 |
CPU86_LDouble *p;
|
|
3794 |
floatx80 *p;
|
|
3801 | 3795 |
p = &ST(st_index); |
3802 | 3796 |
*p = helper_fdiv(*p, ST0); |
3803 | 3797 |
} |
3804 | 3798 |
|
3805 | 3799 |
void helper_fdivr_STN_ST0(int st_index) |
3806 | 3800 |
{ |
3807 |
CPU86_LDouble *p;
|
|
3801 |
floatx80 *p;
|
|
3808 | 3802 |
p = &ST(st_index); |
3809 | 3803 |
*p = helper_fdiv(ST0, *p); |
3810 | 3804 |
} |
... | ... | |
3812 | 3806 |
/* misc FPU operations */ |
3813 | 3807 |
void helper_fchs_ST0(void) |
3814 | 3808 |
{ |
3815 |
ST0 = floatx_chs(ST0); |
|
3809 |
ST0 = floatx80_chs(ST0);
|
|
3816 | 3810 |
} |
3817 | 3811 |
|
3818 | 3812 |
void helper_fabs_ST0(void) |
3819 | 3813 |
{ |
3820 |
ST0 = floatx_abs(ST0); |
|
3814 |
ST0 = floatx80_abs(ST0);
|
|
3821 | 3815 |
} |
3822 | 3816 |
|
3823 | 3817 |
void helper_fld1_ST0(void) |
... | ... | |
3891 | 3885 |
break; |
3892 | 3886 |
} |
3893 | 3887 |
set_float_rounding_mode(rnd_type, &env->fp_status); |
3894 |
#ifdef FLOATX80 |
|
3895 | 3888 |
switch((env->fpuc >> 8) & 3) { |
3896 | 3889 |
case 0: |
3897 | 3890 |
rnd_type = 32; |
... | ... | |
3905 | 3898 |
break; |
3906 | 3899 |
} |
3907 | 3900 |
set_floatx80_rounding_precision(rnd_type, &env->fp_status); |
3908 |
#endif |
|
3909 | 3901 |
} |
3910 | 3902 |
|
3911 | 3903 |
void helper_fldcw(uint32_t val) |
... | ... | |
3944 | 3936 |
|
3945 | 3937 |
void helper_fbld_ST0(target_ulong ptr) |
3946 | 3938 |
{ |
3947 |
CPU86_LDouble tmp;
|
|
3939 |
floatx80 tmp;
|
|
3948 | 3940 |
uint64_t val; |
3949 | 3941 |
unsigned int v; |
3950 | 3942 |
int i; |
... | ... | |
3954 | 3946 |
v = ldub(ptr + i); |
3955 | 3947 |
val = (val * 100) + ((v >> 4) * 10) + (v & 0xf); |
3956 | 3948 |
} |
3957 |
tmp = int64_to_floatx(val, &env->fp_status); |
|
3949 |
tmp = int64_to_floatx80(val, &env->fp_status);
|
|
3958 | 3950 |
if (ldub(ptr + 9) & 0x80) { |
3959 |
floatx_chs(tmp); |
|
3951 |
floatx80_chs(tmp);
|
|
3960 | 3952 |
} |
3961 | 3953 |
fpush(); |
3962 | 3954 |
ST0 = tmp; |
... | ... | |
3968 | 3960 |
target_ulong mem_ref, mem_end; |
3969 | 3961 |
int64_t val; |
3970 | 3962 |
|
3971 |
val = floatx_to_int64(ST0, &env->fp_status); |
|
3963 |
val = floatx80_to_int64(ST0, &env->fp_status);
|
|
3972 | 3964 |
mem_ref = ptr; |
3973 | 3965 |
mem_end = mem_ref + 9; |
3974 | 3966 |
if (val < 0) { |
... | ... | |
3992 | 3984 |
|
3993 | 3985 |
void helper_f2xm1(void) |
3994 | 3986 |
{ |
3995 |
double val = CPU86_LDouble_to_double(ST0);
|
|
3987 |
double val = floatx80_to_double(ST0);
|
|
3996 | 3988 |
val = pow(2.0, val) - 1.0; |
3997 |
ST0 = double_to_CPU86_LDouble(val);
|
|
3989 |
ST0 = double_to_floatx80(val);
|
|
3998 | 3990 |
} |
3999 | 3991 |
|
4000 | 3992 |
void helper_fyl2x(void) |
4001 | 3993 |
{ |
4002 |
double fptemp = CPU86_LDouble_to_double(ST0);
|
|
3994 |
double fptemp = floatx80_to_double(ST0);
|
|
4003 | 3995 |
|
4004 | 3996 |
if (fptemp>0.0){ |
4005 | 3997 |
fptemp = log(fptemp)/log(2.0); /* log2(ST) */ |
4006 |
fptemp *= CPU86_LDouble_to_double(ST1);
|
|
4007 |
ST1 = double_to_CPU86_LDouble(fptemp);
|
|
3998 |
fptemp *= floatx80_to_double(ST1);
|
|
3999 |
ST1 = double_to_floatx80(fptemp);
|
|
4008 | 4000 |
fpop(); |
4009 | 4001 |
} else { |
4010 | 4002 |
env->fpus &= (~0x4700); |
... | ... | |
4014 | 4006 |
|
4015 | 4007 |
void helper_fptan(void) |
4016 | 4008 |
{ |
4017 |
double fptemp = CPU86_LDouble_to_double(ST0);
|
|
4009 |
double fptemp = floatx80_to_double(ST0);
|
|
4018 | 4010 |
|
4019 | 4011 |
if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { |
4020 | 4012 |
env->fpus |= 0x400; |
4021 | 4013 |
} else { |
4022 | 4014 |
fptemp = tan(fptemp); |
4023 |
ST0 = double_to_CPU86_LDouble(fptemp);
|
|
4015 |
ST0 = double_to_floatx80(fptemp);
|
|
4024 | 4016 |
fpush(); |
4025 |
ST0 = floatx_one; |
|
4017 |
ST0 = floatx80_one;
|
|
4026 | 4018 |
env->fpus &= (~0x400); /* C2 <-- 0 */ |
4027 | 4019 |
/* the above code is for |arg| < 2**52 only */ |
4028 | 4020 |
} |
... | ... | |
4032 | 4024 |
{ |
4033 | 4025 |
double fptemp, fpsrcop; |
4034 | 4026 |
|
4035 |
fpsrcop = CPU86_LDouble_to_double(ST1);
|
|
4036 |
fptemp = CPU86_LDouble_to_double(ST0);
|
|
4037 |
ST1 = double_to_CPU86_LDouble(atan2(fpsrcop, fptemp));
|
|
4027 |
fpsrcop = floatx80_to_double(ST1);
|
|
4028 |
fptemp = floatx80_to_double(ST0);
|
|
4029 |
ST1 = double_to_floatx80(atan2(fpsrcop, fptemp));
|
|
4038 | 4030 |
fpop(); |
4039 | 4031 |
} |
4040 | 4032 |
|
4041 | 4033 |
void helper_fxtract(void) |
4042 | 4034 |
{ |
4043 |
CPU86_LDoubleU temp;
|
|
4035 |
CPU_LDoubleU temp; |
|
4044 | 4036 |
|
4045 | 4037 |
temp.d = ST0; |
4046 | 4038 |
|
4047 |
if (floatx_is_zero(ST0)) { |
|
4039 |
if (floatx80_is_zero(ST0)) {
|
|
4048 | 4040 |
/* Easy way to generate -inf and raising division by 0 exception */ |
4049 |
ST0 = floatx_div(floatx_chs(floatx_one), floatx_zero, &env->fp_status);
|
|
4041 |
ST0 = floatx80_div(floatx80_chs(floatx80_one), floatx80_zero, &env->fp_status);
|
|
4050 | 4042 |
fpush(); |
4051 | 4043 |
ST0 = temp.d; |
4052 | 4044 |
} else { |
... | ... | |
4054 | 4046 |
|
4055 | 4047 |
expdif = EXPD(temp) - EXPBIAS; |
4056 | 4048 |
/*DP exponent bias*/ |
4057 |
ST0 = int32_to_floatx(expdif, &env->fp_status); |
|
4049 |
ST0 = int32_to_floatx80(expdif, &env->fp_status);
|
|
4058 | 4050 |
fpush(); |
4059 | 4051 |
BIASEXPONENT(temp); |
4060 | 4052 |
ST0 = temp.d; |
... | ... | |
4064 | 4056 |
void helper_fprem1(void) |
4065 | 4057 |
{ |
4066 | 4058 |
double st0, st1, dblq, fpsrcop, fptemp; |
4067 |
CPU86_LDoubleU fpsrcop1, fptemp1;
|
|
4059 |
CPU_LDoubleU fpsrcop1, fptemp1; |
|
4068 | 4060 |
int expdif; |
4069 | 4061 |
signed long long int q; |
4070 | 4062 |
|
4071 |
st0 = CPU86_LDouble_to_double(ST0);
|
|
4072 |
st1 = CPU86_LDouble_to_double(ST1);
|
|
4063 |
st0 = floatx80_to_double(ST0);
|
|
4064 |
st1 = floatx80_to_double(ST1);
|
|
4073 | 4065 |
|
4074 | 4066 |
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { |
4075 |
ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
|
|
4067 |
ST0 = double_to_floatx80(0.0 / 0.0); /* NaN */
|
|
4076 | 4068 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
4077 | 4069 |
return; |
4078 | 4070 |
} |
... | ... | |
4116 | 4108 |
-(floor(fabs(fpsrcop))) : floor(fpsrcop); |
4117 | 4109 |
st0 -= (st1 * fpsrcop * fptemp); |
4118 | 4110 |
} |
4119 |
ST0 = double_to_CPU86_LDouble(st0);
|
|
4111 |
ST0 = double_to_floatx80(st0);
|
|
4120 | 4112 |
} |
4121 | 4113 |
|
4122 | 4114 |
void helper_fprem(void) |
4123 | 4115 |
{ |
4124 | 4116 |
double st0, st1, dblq, fpsrcop, fptemp; |
4125 |
CPU86_LDoubleU fpsrcop1, fptemp1;
|
|
4117 |
CPU_LDoubleU fpsrcop1, fptemp1; |
|
4126 | 4118 |
int expdif; |
4127 | 4119 |
signed long long int q; |
4128 | 4120 |
|
4129 |
st0 = CPU86_LDouble_to_double(ST0);
|
|
4130 |
st1 = CPU86_LDouble_to_double(ST1);
|
|
4121 |
st0 = floatx80_to_double(ST0);
|
|
4122 |
st1 = floatx80_to_double(ST1);
|
|
4131 | 4123 |
|
4132 | 4124 |
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { |
4133 |
ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
|
|
4125 |
ST0 = double_to_floatx80(0.0 / 0.0); /* NaN */
|
|
4134 | 4126 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
4135 | 4127 |
return; |
4136 | 4128 |
} |
... | ... | |
4175 | 4167 |
-(floor(fabs(fpsrcop))) : floor(fpsrcop); |
4176 | 4168 |
st0 -= (st1 * fpsrcop * fptemp); |
4177 | 4169 |
} |
4178 |
ST0 = double_to_CPU86_LDouble(st0);
|
|
4170 |
ST0 = double_to_floatx80(st0);
|
|
4179 | 4171 |
} |
4180 | 4172 |
|
4181 | 4173 |
void helper_fyl2xp1(void) |
4182 | 4174 |
{ |
4183 |
double fptemp = CPU86_LDouble_to_double(ST0);
|
|
4175 |
double fptemp = floatx80_to_double(ST0);
|
|
4184 | 4176 |
|
4185 | 4177 |
if ((fptemp+1.0)>0.0) { |
4186 | 4178 |
fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */ |
4187 |
fptemp *= CPU86_LDouble_to_double(ST1);
|
|
4188 |
ST1 = double_to_CPU86_LDouble(fptemp);
|
|
4179 |
fptemp *= floatx80_to_double(ST1);
|
|
4180 |
ST1 = double_to_floatx80(fptemp);
|
|
4189 | 4181 |
fpop(); |
4190 | 4182 |
} else { |
4191 | 4183 |
env->fpus &= (~0x4700); |
... | ... | |
4195 | 4187 |
|
4196 | 4188 |
void helper_fsqrt(void) |
4197 | 4189 |
{ |
4198 |
if (floatx_is_neg(ST0)) { |
|
4190 |
if (floatx80_is_neg(ST0)) {
|
|
4199 | 4191 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
4200 | 4192 |
env->fpus |= 0x400; |
4201 | 4193 |
} |
4202 |
ST0 = floatx_sqrt(ST0, &env->fp_status); |
|
4194 |
ST0 = floatx80_sqrt(ST0, &env->fp_status);
|
|
4203 | 4195 |
} |
4204 | 4196 |
|
4205 | 4197 |
void helper_fsincos(void) |
4206 | 4198 |
{ |
4207 |
double fptemp = CPU86_LDouble_to_double(ST0);
|
|
4199 |
double fptemp = floatx80_to_double(ST0);
|
|
4208 | 4200 |
|
4209 | 4201 |
if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { |
4210 | 4202 |
env->fpus |= 0x400; |
4211 | 4203 |
} else { |
4212 |
ST0 = double_to_CPU86_LDouble(sin(fptemp));
|
|
4204 |
ST0 = double_to_floatx80(sin(fptemp));
|
|
4213 | 4205 |
fpush(); |
4214 |
ST0 = double_to_CPU86_LDouble(cos(fptemp));
|
|
4206 |
ST0 = double_to_floatx80(cos(fptemp));
|
|
4215 | 4207 |
env->fpus &= (~0x400); /* C2 <-- 0 */ |
4216 | 4208 |
/* the above code is for |arg| < 2**63 only */ |
4217 | 4209 |
} |
... | ... | |
4219 | 4211 |
|
4220 | 4212 |
void helper_frndint(void) |
4221 | 4213 |
{ |
4222 |
ST0 = floatx_round_to_int(ST0, &env->fp_status); |
|
4214 |
ST0 = floatx80_round_to_int(ST0, &env->fp_status);
|
|
4223 | 4215 |
} |
4224 | 4216 |
|
4225 | 4217 |
void helper_fscale(void) |
4226 | 4218 |
{ |
4227 |
if (floatx_is_any_nan(ST1)) { |
|
4219 |
if (floatx80_is_any_nan(ST1)) {
|
|
4228 | 4220 |
ST0 = ST1; |
4229 | 4221 |
} else { |
4230 |
int n = floatx_to_int32_round_to_zero(ST1, &env->fp_status); |
|
4231 |
ST0 = floatx_scalbn(ST0, n, &env->fp_status); |
|
4222 |
int n = floatx80_to_int32_round_to_zero(ST1, &env->fp_status);
|
|
4223 |
ST0 = floatx80_scalbn(ST0, n, &env->fp_status);
|
|
4232 | 4224 |
} |
4233 | 4225 |
} |
4234 | 4226 |
|
4235 | 4227 |
void helper_fsin(void) |
4236 | 4228 |
{ |
4237 |
double fptemp = CPU86_LDouble_to_double(ST0);
|
|
4229 |
double fptemp = floatx80_to_double(ST0);
|
|
4238 | 4230 |
|
4239 | 4231 |
if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { |
4240 | 4232 |
env->fpus |= 0x400; |
4241 | 4233 |
} else { |
4242 |
ST0 = double_to_CPU86_LDouble(sin(fptemp));
|
|
4234 |
ST0 = double_to_floatx80(sin(fptemp));
|
|
4243 | 4235 |
env->fpus &= (~0x400); /* C2 <-- 0 */ |
4244 | 4236 |
/* the above code is for |arg| < 2**53 only */ |
4245 | 4237 |
} |
... | ... | |
4247 | 4239 |
|
4248 | 4240 |
void helper_fcos(void) |
4249 | 4241 |
{ |
4250 |
double fptemp = CPU86_LDouble_to_double(ST0);
|
|
4242 |
double fptemp = floatx80_to_double(ST0);
|
|
4251 | 4243 |
|
4252 | 4244 |
if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { |
4253 | 4245 |
env->fpus |= 0x400; |
4254 | 4246 |
} else { |
4255 |
ST0 = double_to_CPU86_LDouble(cos(fptemp));
|
|
4247 |
ST0 = double_to_floatx80(cos(fptemp));
|
|
4256 | 4248 |
env->fpus &= (~0x400); /* C2 <-- 0 */ |
4257 | 4249 |
/* the above code is for |arg5 < 2**63 only */ |
4258 | 4250 |
} |
... | ... | |
4260 | 4252 |
|
4261 | 4253 |
void helper_fxam_ST0(void) |
4262 | 4254 |
{ |
4263 |
CPU86_LDoubleU temp;
|
|
4255 |
CPU_LDoubleU temp; |
|
4264 | 4256 |
int expdif; |
4265 | 4257 |
|
4266 | 4258 |
temp.d = ST0; |
... | ... | |
4272 | 4264 |
/* XXX: test fptags too */ |
4273 | 4265 |
expdif = EXPD(temp); |
4274 | 4266 |
if (expdif == MAXEXPD) { |
4275 |
#ifdef USE_X86LDOUBLE |
|
4276 | 4267 |
if (MANTD(temp) == 0x8000000000000000ULL) |
4277 |
#else |
|
4278 |
if (MANTD(temp) == 0) |
|
4279 |
#endif |
|
4280 | 4268 |
env->fpus |= 0x500 /*Infinity*/; |
4281 | 4269 |
else |
4282 | 4270 |
env->fpus |= 0x100 /*NaN*/; |
... | ... | |
4294 | 4282 |
{ |
4295 | 4283 |
int fpus, fptag, exp, i; |
4296 | 4284 |
uint64_t mant; |
4297 |
CPU86_LDoubleU tmp;
|
|
4285 |
CPU_LDoubleU tmp; |
|
4298 | 4286 |
|
4299 | 4287 |
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; |
4300 | 4288 |
fptag = 0; |
... | ... | |
4310 | 4298 |
/* zero */ |
4311 | 4299 |
fptag |= 1; |
4312 | 4300 |
} else if (exp == 0 || exp == MAXEXPD |
4313 |
#ifdef USE_X86LDOUBLE |
|
4314 | 4301 |
|| (mant & (1LL << 63)) == 0 |
4315 |
#endif |
|
4316 | 4302 |
) { |
4317 | 4303 |
/* NaNs, infinity, denormal */ |
4318 | 4304 |
fptag |= 2; |
... | ... | |
4364 | 4350 |
|
4365 | 4351 |
void helper_fsave(target_ulong ptr, int data32) |
4366 | 4352 |
{ |
4367 |
CPU86_LDouble tmp;
|
|
4353 |
floatx80 tmp;
|
|
4368 | 4354 |
int i; |
4369 | 4355 |
|
4370 | 4356 |
helper_fstenv(ptr, data32); |
... | ... | |
4392 | 4378 |
|
4393 | 4379 |
void helper_frstor(target_ulong ptr, int data32) |
4394 | 4380 |
{ |
4395 |
CPU86_LDouble tmp;
|
|
4381 |
floatx80 tmp;
|
|
4396 | 4382 |
int i; |
4397 | 4383 |
|
4398 | 4384 |
helper_fldenv(ptr, data32); |
... | ... | |
4408 | 4394 |
void helper_fxsave(target_ulong ptr, int data64) |
4409 | 4395 |
{ |
4410 | 4396 |
int fpus, fptag, i, nb_xmm_regs; |
4411 |
CPU86_LDouble tmp;
|
|
4397 |
floatx80 tmp;
|
|
4412 | 4398 |
target_ulong addr; |
4413 | 4399 |
|
4414 | 4400 |
/* The operand must be 16 byte aligned */ |
... | ... | |
4469 | 4455 |
void helper_fxrstor(target_ulong ptr, int data64) |
4470 | 4456 |
{ |
4471 | 4457 |
int i, fpus, fptag, nb_xmm_regs; |
4472 |
CPU86_LDouble tmp;
|
|
4458 |
floatx80 tmp;
|
|
4473 | 4459 |
target_ulong addr; |
4474 | 4460 |
|
4475 | 4461 |
/* The operand must be 16 byte aligned */ |
... | ... | |
4516 | 4502 |
} |
4517 | 4503 |
} |
4518 | 4504 |
|
4519 |
#ifndef USE_X86LDOUBLE |
|
4520 |
|
|
4521 |
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f) |
|
4505 |
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f) |
|
4522 | 4506 |
{ |
4523 |
CPU86_LDoubleU temp; |
|
4524 |
int e; |
|
4525 |
|
|
4526 |
temp.d = f; |
|
4527 |
/* mantissa */ |
|
4528 |
*pmant = (MANTD(temp) << 11) | (1LL << 63); |
|
4529 |
/* exponent + sign */ |
|
4530 |
e = EXPD(temp) - EXPBIAS + 16383; |
|
4531 |
e |= SIGND(temp) >> 16; |
|
4532 |
*pexp = e; |
|
4533 |
} |
|
4534 |
|
|
4535 |
CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper) |
|
4536 |
{ |
|
4537 |
CPU86_LDoubleU temp; |
|
4538 |
int e; |
|
4539 |
uint64_t ll; |
|
4540 |
|
|
4541 |
/* XXX: handle overflow ? */ |
|
4542 |
e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ |
|
4543 |
e |= (upper >> 4) & 0x800; /* sign */ |
|
4544 |
ll = (mant >> 11) & ((1LL << 52) - 1); |
|
4545 |
#ifdef __arm__ |
|
4546 |
temp.l.upper = (e << 20) | (ll >> 32); |
|
4547 |
temp.l.lower = ll; |
|
4548 |
#else |
|
4549 |
temp.ll = ll | ((uint64_t)e << 52); |
|
4550 |
#endif |
|
4551 |
return temp.d; |
|
4552 |
} |
|
4553 |
|
|
4554 |
#else |
|
4555 |
|
|
4556 |
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f) |
|
4557 |
{ |
|
4558 |
CPU86_LDoubleU temp; |
|
4507 |
CPU_LDoubleU temp; |
|
4559 | 4508 |
|
4560 | 4509 |
temp.d = f; |
4561 | 4510 |
*pmant = temp.l.lower; |
4562 | 4511 |
*pexp = temp.l.upper; |
4563 | 4512 |
} |
4564 | 4513 |
|
4565 |
CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
|
|
4514 |
floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper)
|
|
4566 | 4515 |
{ |
4567 |
CPU86_LDoubleU temp;
|
|
4516 |
CPU_LDoubleU temp; |
|
4568 | 4517 |
|
4569 | 4518 |
temp.l.upper = upper; |
4570 | 4519 |
temp.l.lower = mant; |
4571 | 4520 |
return temp.d; |
4572 | 4521 |
} |
4573 |
#endif |
|
4574 | 4522 |
|
4575 | 4523 |
#ifdef TARGET_X86_64 |
4576 | 4524 |
|
Also available in: Unified diff