diff mbox series

[RFC,2/2] target/ppc: Enable hardfloat for PPC

Message ID 01eddb5c1639ab2dfb744b3515f9b907afcbb056.1581904461.git.balaton@eik.bme.hu
State New
Headers show
Series Enable hardfloat for PPC | expand

Commit Message

BALATON Zoltan Feb. 17, 2020, 1:19 a.m. UTC
While other targets take advantage of using host FPU to do floating
point computations, this was disabled for PPC target because always
clearing exception flags before every FP op made it slightly slower
than emulating everyting with softfloat. To emulate some FPSCR bits,
clearing of fp_status may be necessary (unless these could be handled
e.g. using FP exceptions on host but there's no API for that in QEMU
yet) but preserving at least the inexact flag makes hardfloat usable
and faster than softfloat. Since most clients don't actually care
about this flag, we can gain some speed trading some emulation
accuracy.

This patch implements a simple way to keep the inexact flag set for
hardfloat while still allowing to revert to softfloat for workloads
that need more accurate albeit slower emulation. (Set hardfloat
property of CPU, i.e. -cpu name,hardfloat=false for that.) There are
still more places where flags are reset so there is place for further
improvement. Also having a conditional to test for the hardfloat flag
every time makes the softfloat case slower than before this patch so
some other way (like setting a function pointer once and use that
instead if possible) may be needed to avoid this otherwise this patch
only makes sense if the default is also set to enable hardfloat.

Because of the above this patch at the moment is mainly for testing
different workloads to evaluate how viable would this be in practice.
Thus, RFC and not ready for merge yet.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 fpu/softfloat.c                 | 14 +++++++-------
 target/ppc/fpu_helper.c         |  7 ++++++-
 target/ppc/translate_init.inc.c |  2 +-
 3 files changed, 14 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 301ce3b537..6d3f4af72a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -216,15 +216,15 @@  GEN_INPUT_FLUSH3(float64_input_flush3, float64)
 #endif
 
 /*
- * Some targets clear the FP flags before most FP operations. This prevents
- * the use of hardfloat, since hardfloat relies on the inexact flag being
- * already set.
+ * Disable hardfloat for known problem cases.
+ * Additionally, some targets clear the FP flags before most FP operations.
+ * This prevents the use of hardfloat, since it relies on the inexact flag
+ * being already set and clearing it often may result in slower computations.
+ * Those targets could also be listed here.
  */
-#if defined(TARGET_PPC) || defined(__FAST_MATH__)
-# if defined(__FAST_MATH__)
-#  warning disabling hardfloat due to -ffast-math: hardfloat requires an exact \
+#if defined(__FAST_MATH__)
+# warning disabling hardfloat due to -ffast-math: hardfloat requires an exact \
     IEEE implementation
-# endif
 # define QEMU_NO_HARDFLOAT 1
 # define QEMU_SOFTFLOAT_ATTR QEMU_FLATTEN
 #else
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ae43b08eb5..33aa977970 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -659,7 +659,12 @@  void helper_float_check_status(CPUPPCState *env)
 
 void helper_reset_fpstatus(CPUPPCState *env)
 {
-    set_float_exception_flags(0, &env->fp_status);
+    if (env->hardfloat) {
+        /* hardfloat needs inexact flag already set, clear only others */
+        set_float_exception_flags(float_flag_inexact, &env->fp_status);
+    } else {
+        set_float_exception_flags(0, &env->fp_status);
+    }
 }
 
 static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc,
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index d6e1d66bc8..caac0c2d11 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10869,7 +10869,7 @@  static Property ppc_cpu_properties[] = {
                      false),
     DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
                      false),
-    DEFINE_PROP_BOOL("hardfloat", PowerPCCPU, hardfloat, false),
+    DEFINE_PROP_BOOL("hardfloat", PowerPCCPU, hardfloat, true),
     DEFINE_PROP_END_OF_LIST(),
 };