aboutsummaryrefslogtreecommitdiff
path: root/target-i386/helper.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-03-13 17:01:47 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-03-13 17:01:47 +0000
commit7a0e1f41ceeb658791a1456ffc7f8f9edca7da19 (patch)
treeeab50fb37085ad2dc6e8aa283f334defd538fa8c /target-i386/helper.c
parent4ecc31906d7535c4ad88fcc63968bef412dd67ba (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.c78
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)