Patchwork [v2,1/3] target-ppc: simplify NaN propagation for vector functions

login
register
mail settings
Submitter Aurelien Jarno
Date April 20, 2011, 11:32 a.m.
Message ID <1303299154-14373-1-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/92202/
State New
Headers show

Comments

Aurelien Jarno - April 20, 2011, 11:32 a.m.
Commit e024e881bb1a8b5085026589360d26ed97acdd64 provided a pickNaN()
function for PowerPC, implementing the correct NaN propagation rules.
Therefore there is no need to test the operands manually, we can rely
on the softfloat code to do that.

Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-ppc/op_helper.c |   26 +++++++-------------------
 1 files changed, 7 insertions(+), 19 deletions(-)

Note: Unfortunately the current propagation rules implemented in 
softfloat only concerns 2 operands operations, so we have to keep
HANDLE_NAN3 for now.
Peter Maydell - April 20, 2011, 12:04 p.m.
On 20 April 2011 12:32, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Commit e024e881bb1a8b5085026589360d26ed97acdd64 provided a pickNaN()
> function for PowerPC, implementing the correct NaN propagation rules.
> Therefore there is no need to test the operands manually, we can rely
> on the softfloat code to do that.
>
> Cc: Alexander Graf <agraf@suse.de>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-ppc/op_helper.c |   26 +++++++-------------------
>  1 files changed, 7 insertions(+), 19 deletions(-)
>
> Note: Unfortunately the current propagation rules implemented in
> softfloat only concerns 2 operands operations, so we have to keep
> HANDLE_NAN3 for now.

These first two patches remove all of the uses of HANDLE_NAN1 and
HANDLE_NAN2, so we can just delete those macro definitions, right?

You could clean up DO_HANDLE_NAN a little:

#define DO_HANDLE_NAN(result, x)               \
    if (float32_is_any_nan(x)) {               \
        result = float32_maybe_silence_nan(x); \
    } else

On a slight tangent:

I need to add ARM support for fused multiply-accumulate (vfma,vfms),
so perhaps in the long run it would be better to make them softfloat
primitives? (they are after all in the new IEEE spec, so they're in
softfloat's domain in some sense.) That would move the 'propagate one
of 3 NaNs' logic into softfloat.

(I suspect that implementing fused-mac by doing intermediate results
mas float64 will set the Inexact bit for some cases where the hardware
will not, but I haven't thought too deeply about it yet.)

-- PMM
Nathan Froyd - April 20, 2011, 12:55 p.m.
On Wed, Apr 20, 2011 at 01:04:48PM +0100, Peter Maydell wrote:
> I need to add ARM support for fused multiply-accumulate (vfma,vfms),
> so perhaps in the long run it would be better to make them softfloat
> primitives? (they are after all in the new IEEE spec, so they're in
> softfloat's domain in some sense.) That would move the 'propagate one
> of 3 NaNs' logic into softfloat.

+1 to implementing fma in softfloat.

-Nathan

Patch

diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index d5db484..f2c80a3 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -2087,9 +2087,7 @@  VARITH(uwm, u32)
     {                                                                   \
         int i;                                                          \
         for (i = 0; i < ARRAY_SIZE(r->f); i++) {                        \
-            HANDLE_NAN2(r->f[i], a->f[i], b->f[i]) {                    \
-                r->f[i] = func(a->f[i], b->f[i], &env->vec_status);     \
-            }                                                           \
+            r->f[i] = func(a->f[i], b->f[i], &env->vec_status);         \
         }                                                               \
     }
 VARITHFP(addfp, float32_add)
@@ -2650,9 +2648,7 @@  void helper_vrefp (ppc_avr_t *r, ppc_avr_t *b)
 {
     int i;
     for (i = 0; i < ARRAY_SIZE(r->f); i++) {
-        HANDLE_NAN1(r->f[i], b->f[i]) {
-            r->f[i] = float32_div(float32_one, b->f[i], &env->vec_status);
-        }
+        r->f[i] = float32_div(float32_one, b->f[i], &env->vec_status);
     }
 }
 
@@ -2663,9 +2659,7 @@  void helper_vrefp (ppc_avr_t *r, ppc_avr_t *b)
         float_status s = env->vec_status;                               \
         set_float_rounding_mode(rounding, &s);                          \
         for (i = 0; i < ARRAY_SIZE(r->f); i++) {                        \
-            HANDLE_NAN1(r->f[i], b->f[i]) {                             \
-                r->f[i] = float32_round_to_int (b->f[i], &s);           \
-            }                                                           \
+            r->f[i] = float32_round_to_int (b->f[i], &s);               \
         }                                                               \
     }
 VRFI(n, float_round_nearest_even)
@@ -2693,10 +2687,8 @@  void helper_vrsqrtefp (ppc_avr_t *r, ppc_avr_t *b)
 {
     int i;
     for (i = 0; i < ARRAY_SIZE(r->f); i++) {
-        HANDLE_NAN1(r->f[i], b->f[i]) {
-            float32 t = float32_sqrt(b->f[i], &env->vec_status);
-            r->f[i] = float32_div(float32_one, t, &env->vec_status);
-        }
+        float32 t = float32_sqrt(b->f[i], &env->vec_status);
+        r->f[i] = float32_div(float32_one, t, &env->vec_status);
     }
 }
 
@@ -2710,9 +2702,7 @@  void helper_vexptefp (ppc_avr_t *r, ppc_avr_t *b)
 {
     int i;
     for (i = 0; i < ARRAY_SIZE(r->f); i++) {
-        HANDLE_NAN1(r->f[i], b->f[i]) {
-            r->f[i] = float32_exp2(b->f[i], &env->vec_status);
-        }
+        r->f[i] = float32_exp2(b->f[i], &env->vec_status);
     }
 }
 
@@ -2720,9 +2710,7 @@  void helper_vlogefp (ppc_avr_t *r, ppc_avr_t *b)
 {
     int i;
     for (i = 0; i < ARRAY_SIZE(r->f); i++) {
-        HANDLE_NAN1(r->f[i], b->f[i]) {
-            r->f[i] = float32_log2(b->f[i], &env->vec_status);
-        }
+        r->f[i] = float32_log2(b->f[i], &env->vec_status);
     }
 }