[v2,8/9] target-i386: cleanup helper_fxam_ST0()

Submitted by Aurelien Jarno on May 23, 2011, 9:42 p.m.

Details

Message ID 1306186971-9528-9-git-send-email-aurelien@aurel32.net
State New
Headers show

Commit Message

Aurelien Jarno May 23, 2011, 9:42 p.m.
Rewrite helper_fxam_ST0() using only softfloat functions.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c |   30 ++++++++++++------------------
 1 files changed, 12 insertions(+), 18 deletions(-)

Comments

Peter Maydell May 23, 2011, 10:02 p.m.
On 23 May 2011 22:42, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Rewrite helper_fxam_ST0() using only softfloat functions.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

(Sorry I didn't get round to this one earlier; I think I did
the easy patches and stalled on the ones I'd have to pull out
the x86 manuals for :-))

>     /* XXX: test fptags too */

You could fix this XXX while you were here; it's just adding

    if (env->fptags[env->fpstt]) {
       env->fpus |= 0x4100; /* (C3,C2,C0) <-- 101 */
    } else ...

to the top of the ladder, right?

(Catching the "Unsupported" case would be slightly more tedious,
we'd need to identify all the floatx80 weirdo bitpatterns
as per the table in the architecture manual. Could use a
FIXME/XXX comment on that account, maybe.)

> -    expdif = EXPD(temp);
> -    if (expdif == MAXEXPD) {
> -        if (MANTD(temp) == 0x8000000000000000ULL)
> -            env->fpus |=  0x500 /*Infinity*/;
> -        else
> -            env->fpus |=  0x100 /*NaN*/;
> -    } else if (expdif == 0) {
> -        if (MANTD(temp) == 0)
> -            env->fpus |=  0x4000 /*Zero*/;
> -        else
> -            env->fpus |= 0x4400 /*Denormal*/;
> +    if (floatx80_is_infinity(ST0)) {
> +        env->fpus |=  0x500; /* (C3,C2,C0) <-- 011 */
> +    } else if (floatx80_is_any_nan(ST0)) {
> +        env->fpus |=  0x100; /* (C3,C2,C0) <-- 001 */
> +    } else if (floatx80_is_zero(ST0)) {
> +        env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
> +    } else if (floatx80_is_zero_or_denormal(ST0)) {
> +        env->fpus |= 0x4400; /* (C3,C2,C0) <-- 110 */
>     } else {
> -        env->fpus |= 0x400;
> +        env->fpus |=  0x400; /* (C3,C2,C0) <-- 010 */
>     }
>  }

This all looks right. The C0/C1/C2/C3 bits seem to get enough
use in this and other functions to merit FPUS_* constants,
although that should probably be a different patch.

There's also code in helper_fstenv() which is currently
doing manual identification of zero/NaN/inf/denorm.

-- PMM

Patch hide | download patch | download mbox

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index cec0c76..8ba2b5f 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4241,29 +4241,23 @@  void helper_fcos(void)
 
 void helper_fxam_ST0(void)
 {
-    CPU_LDoubleU temp;
-    int expdif;
-
-    temp.d = ST0;
-
     env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
-    if (SIGND(temp))
+
+    if (floatx80_is_neg(ST0)) {
         env->fpus |= 0x200; /* C1 <-- 1 */
+    }
 
     /* XXX: test fptags too */
-    expdif = EXPD(temp);
-    if (expdif == MAXEXPD) {
-        if (MANTD(temp) == 0x8000000000000000ULL)
-            env->fpus |=  0x500 /*Infinity*/;
-        else
-            env->fpus |=  0x100 /*NaN*/;
-    } else if (expdif == 0) {
-        if (MANTD(temp) == 0)
-            env->fpus |=  0x4000 /*Zero*/;
-        else
-            env->fpus |= 0x4400 /*Denormal*/;
+    if (floatx80_is_infinity(ST0)) {
+        env->fpus |=  0x500; /* (C3,C2,C0) <-- 011 */
+    } else if (floatx80_is_any_nan(ST0)) {
+        env->fpus |=  0x100; /* (C3,C2,C0) <-- 001 */
+    } else if (floatx80_is_zero(ST0)) {
+        env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
+    } else if (floatx80_is_zero_or_denormal(ST0)) {
+        env->fpus |= 0x4400; /* (C3,C2,C0) <-- 110 */
     } else {
-        env->fpus |= 0x400;
+        env->fpus |=  0x400; /* (C3,C2,C0) <-- 010 */
     }
 }