diff mbox series

[v2,14/15] s390x/tcg: Handle all rounding modes overwritten by BFP instructions

Message ID 20190213143322.31371-15-david@redhat.com
State New
Headers show
Series s390x/tcg: Implement floating-point extension facility | expand

Commit Message

David Hildenbrand Feb. 13, 2019, 2:33 p.m. UTC
PoP describes "Round to nearest with ties away from 0" as
  "The candidate nearest to the input value is selected. In case of a tie,
   the candidate selected is the one that is larger in magnitude."

While float_round_ties_away is according to the introducing commit
f9288a76f181 ("softfloat: Add support for ties-away rounding")
  "roundTiesToAway: the floating-point number nearest to the infinitely
   precise result shall be delivered; if the two nearest floating-point
   numbers bracketing an unrepresentable infinitely precise result are
   equally near, the one with larger magnitude shall be delivered."

So this could be it if we're lucky ;)

Handle "round to prepare for shorter precision" just as when setting it
via SET FLOATING POINT and friends.

As all instructions properly check for valid rounding modes in translate.c
we can add an assert. Fix one missing empty line.

Cc: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/fpu_helper.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index 5e4b76f4aa..f790ec0c8e 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -397,14 +397,26 @@  uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
 int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3)
 {
     int ret = env->fpu_status.float_rounding_mode;
+
     switch (m3) {
     case 0:
         /* current mode */
         break;
     case 1:
-        /* biased round no nearest */
+        /* round to nearest with ties away from 0 */
+        set_float_rounding_mode(float_round_ties_away, &env->fpu_status);
+        break;
+    case 3:
+        /*
+         * round to prepare for shorter precision
+         *
+         * FIXME: we actually want something like round_to_odd, but that
+         * does not support all data types yet.
+         */
+        set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
+        break;
     case 4:
-        /* round to nearest */
+        /* round to nearest with ties to even */
         set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
         break;
     case 5:
@@ -419,6 +431,8 @@  int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3)
         /* round to -inf */
         set_float_rounding_mode(float_round_down, &env->fpu_status);
         break;
+    default:
+        g_assert_not_reached();
     }
     return ret;
 }