diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-03-13 17:01:47 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-03-13 17:01:47 +0000 |
commit | 7a0e1f41ceeb658791a1456ffc7f8f9edca7da19 (patch) | |
tree | eab50fb37085ad2dc6e8aa283f334defd538fa8c /target-i386/helper.c | |
parent | 4ecc31906d7535c4ad88fcc63968bef412dd67ba (diff) |
soft float support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1336 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/helper.c')
-rw-r--r-- | target-i386/helper.c | 78 |
1 files changed, 36 insertions, 42 deletions
diff --git a/target-i386/helper.c b/target-i386/helper.c index 53b85d3aaa..64cb51ab53 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -2541,13 +2541,11 @@ void helper_fbld_ST0_A0(void) void helper_fbst_ST0_A0(void) { - CPU86_LDouble tmp; int v; target_ulong mem_ref, mem_end; int64_t val; - tmp = rint(ST0); - val = (int64_t)tmp; + val = floatx_to_int64(ST0, &env->fp_status); mem_ref = A0; mem_end = mem_ref + 9; if (val < 0) { @@ -2740,29 +2738,7 @@ void helper_fsincos(void) void helper_frndint(void) { - CPU86_LDouble a; - - a = ST0; -#ifdef __arm__ - switch(env->fpuc & RC_MASK) { - default: - case RC_NEAR: - asm("rndd %0, %1" : "=f" (a) : "f"(a)); - break; - case RC_DOWN: - asm("rnddm %0, %1" : "=f" (a) : "f"(a)); - break; - case RC_UP: - asm("rnddp %0, %1" : "=f" (a) : "f"(a)); - break; - case RC_CHOP: - asm("rnddz %0, %1" : "=f" (a) : "f"(a)); - break; - } -#else - a = rint(a); -#endif - ST0 = a; + ST0 = floatx_round_to_int(ST0, &env->fp_status); } void helper_fscale(void) @@ -3263,25 +3239,43 @@ float approx_rcp(float a) return 1.0 / a; } -/* XXX: find a better solution */ -double helper_sqrt(double a) +void update_fp_status(void) { - return sqrt(a); -} + int rnd_type; -/* XXX: move that to another file */ -#if defined(__powerpc__) -/* better to call an helper on ppc */ -float int32_to_float32(int32_t a) -{ - return (float)a; -} - -double int32_to_float64(int32_t a) -{ - return (double)a; -} + /* set rounding mode */ + switch(env->fpuc & RC_MASK) { + default: + case RC_NEAR: + rnd_type = float_round_nearest_even; + break; + case RC_DOWN: + rnd_type = float_round_down; + break; + case RC_UP: + rnd_type = float_round_up; + break; + case RC_CHOP: + rnd_type = float_round_to_zero; + break; + } + set_float_rounding_mode(rnd_type, &env->fp_status); +#ifdef FLOATX80 + switch((env->fpuc >> 8) & 3) { + case 0: + rnd_type = 32; + break; + case 2: + rnd_type = 64; + break; + case 3: + default: + rnd_type = 80; + break; + } + set_floatx80_rounding_precision(rnd_type, &env->fp_status); #endif +} #if !defined(CONFIG_USER_ONLY) |