diff mbox series

[v25,14/20] i386: separate fpu_helper into user and sysemu parts

Message ID 20210226175143.22388-15-cfontana@suse.de
State New
Headers show
Series i386 cleanup PART 2 | expand

Commit Message

Claudio Fontana Feb. 26, 2021, 5:51 p.m. UTC
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
 target/i386/cpu.h                   |  3 ++
 target/i386/tcg/helper-tcg.h        |  7 +++
 target/i386/tcg/fpu_helper.c        | 77 +++--------------------------
 target/i386/tcg/sysemu/fpu_helper.c | 57 +++++++++++++++++++++
 target/i386/tcg/user/fpu_helper.c   | 42 ++++++++++++++++
 target/i386/tcg/sysemu/meson.build  |  1 +
 target/i386/tcg/user/meson.build    |  1 +
 7 files changed, 119 insertions(+), 69 deletions(-)
 create mode 100644 target/i386/tcg/sysemu/fpu_helper.c
 create mode 100644 target/i386/tcg/user/fpu_helper.c

Comments

Richard Henderson Feb. 26, 2021, 6:42 p.m. UTC | #1
On 2/26/21 9:51 AM, Claudio Fontana wrote:
> +/* fpu_helper.c */
> +
> +void do_fsave(CPUX86State *env, target_ulong ptr, int data32, uintptr_t ra);
> +void do_frstor(CPUX86State *env, target_ulong ptr, int data32, uintptr_t ra);
> +void do_fxsave(CPUX86State *env, target_ulong ptr, uintptr_t ra);
> +void do_fxrstor(CPUX86State *env, target_ulong ptr, uintptr_t ra);

Is this really worth it?  It means that we unnecessarily expose these functions
in system mode, where they are still not safe.

I had thought about doing something like

#ifdef CONFIG_USER_ONLY
#define SYSEMU_STATIC
#else
#define SYSEMU_STATIC static
#endif

SYSEMU_STATIC void
cpu_x86_fsave(...)
{
  ...
}

void helper_fsave(...)
{
    cpu_x86_fsave(..., GETPC());
}

but I thought the existing example of "do_" functions within that file to be
compelling.  I think small sections of this CONFIG within a file should be
fine, especially where it interacts with other functions like this.

I guess either way,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
Claudio Fontana March 1, 2021, 8:41 a.m. UTC | #2
On 2/26/21 7:42 PM, Richard Henderson wrote:
> On 2/26/21 9:51 AM, Claudio Fontana wrote:
>> +/* fpu_helper.c */
>> +
>> +void do_fsave(CPUX86State *env, target_ulong ptr, int data32, uintptr_t ra);
>> +void do_frstor(CPUX86State *env, target_ulong ptr, int data32, uintptr_t ra);
>> +void do_fxsave(CPUX86State *env, target_ulong ptr, uintptr_t ra);
>> +void do_fxrstor(CPUX86State *env, target_ulong ptr, uintptr_t ra);
> 
> Is this really worth it?

No, probably not. Will respin without these parts,
and leaving the small ifdefs in the global tcg/fpu_helper.c

Thanks,

Claudio


> It means that we unnecessarily expose these functions
> in system mode, where they are still not safe.
> 
> I had thought about doing something like
> 
> #ifdef CONFIG_USER_ONLY
> #define SYSEMU_STATIC
> #else
> #define SYSEMU_STATIC static
> #endif
> 
> SYSEMU_STATIC void
> cpu_x86_fsave(...)
> {
>   ...
> }
> 
> void helper_fsave(...)
> {
>     cpu_x86_fsave(..., GETPC());
> }
> 
> but I thought the existing example of "do_" functions within that file to be
> compelling.  I think small sections of this CONFIG within a file should be
> fine, especially where it interacts with other functions like this.
> 
> I guess either way,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> 
> 
> r~
>
diff mbox series

Patch

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c8a84a9033..3797789dc2 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1816,7 +1816,10 @@  int cpu_x86_support_mca_broadcast(CPUX86State *env);
 int cpu_get_pic_interrupt(CPUX86State *s);
 /* MSDOS compatibility mode FPU exception support */
 void x86_register_ferr_irq(qemu_irq irq);
+void fpu_check_raise_ferr_irq(CPUX86State *s);
 void cpu_set_ignne(void);
+void cpu_clear_ignne(void);
+
 /* mpx_helper.c */
 void cpu_sync_bndcs_hflags(CPUX86State *env);
 
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index b420b3356d..93fc4a7e7e 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -95,4 +95,11 @@  void do_smm_enter(X86CPU *cpu);
 /* bpt_helper.c */
 bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update);
 
+/* fpu_helper.c */
+
+void do_fsave(CPUX86State *env, target_ulong ptr, int data32, uintptr_t ra);
+void do_frstor(CPUX86State *env, target_ulong ptr, int data32, uintptr_t ra);
+void do_fxsave(CPUX86State *env, target_ulong ptr, uintptr_t ra);
+void do_fxrstor(CPUX86State *env, target_ulong ptr, uintptr_t ra);
+
 #endif /* I386_HELPER_TCG_H */
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 20e4d2e715..48384ef506 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -21,17 +21,10 @@ 
 #include <math.h>
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "qemu/host-utils.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
 #include "fpu/softfloat.h"
 #include "fpu/softfloat-macros.h"
 #include "helper-tcg.h"
 
-#ifdef CONFIG_SOFTMMU
-#include "hw/irq.h"
-#endif
-
 /* float macros */
 #define FT0    (env->ft0)
 #define ST0    (env->fpregs[env->fpstt].d)
@@ -75,36 +68,6 @@ 
 #define floatx80_ln2_d make_floatx80(0x3ffe, 0xb17217f7d1cf79abLL)
 #define floatx80_pi_d make_floatx80(0x4000, 0xc90fdaa22168c234LL)
 
-#if !defined(CONFIG_USER_ONLY)
-static qemu_irq ferr_irq;
-
-void x86_register_ferr_irq(qemu_irq irq)
-{
-    ferr_irq = irq;
-}
-
-static void cpu_clear_ignne(void)
-{
-    CPUX86State *env = &X86_CPU(first_cpu)->env;
-    env->hflags2 &= ~HF2_IGNNE_MASK;
-}
-
-void cpu_set_ignne(void)
-{
-    CPUX86State *env = &X86_CPU(first_cpu)->env;
-    env->hflags2 |= HF2_IGNNE_MASK;
-    /*
-     * We get here in response to a write to port F0h.  The chipset should
-     * deassert FP_IRQ and FERR# instead should stay signaled until FPSW_SE is
-     * cleared, because FERR# and FP_IRQ are two separate pins on real
-     * hardware.  However, we don't model FERR# as a qemu_irq, so we just
-     * do directly what the chipset would do, i.e. deassert FP_IRQ.
-     */
-    qemu_irq_lower(ferr_irq);
-}
-#endif
-
-
 static inline void fpush(CPUX86State *env)
 {
     env->fpstt = (env->fpstt - 1) & 7;
@@ -202,8 +165,8 @@  static void fpu_raise_exception(CPUX86State *env, uintptr_t retaddr)
         raise_exception_ra(env, EXCP10_COPR, retaddr);
     }
 #if !defined(CONFIG_USER_ONLY)
-    else if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) {
-        qemu_irq_raise(ferr_irq);
+    else {
+        fpu_check_raise_ferr_irq(env);
     }
 #endif
 }
@@ -2457,8 +2420,8 @@  void helper_fldenv(CPUX86State *env, target_ulong ptr, int data32)
     do_fldenv(env, ptr, data32, GETPC());
 }
 
-static void do_fsave(CPUX86State *env, target_ulong ptr, int data32,
-                     uintptr_t retaddr)
+void do_fsave(CPUX86State *env, target_ulong ptr, int data32,
+              uintptr_t retaddr)
 {
     floatx80 tmp;
     int i;
@@ -2491,8 +2454,8 @@  void helper_fsave(CPUX86State *env, target_ulong ptr, int data32)
     do_fsave(env, ptr, data32, GETPC());
 }
 
-static void do_frstor(CPUX86State *env, target_ulong ptr, int data32,
-                      uintptr_t retaddr)
+void do_frstor(CPUX86State *env, target_ulong ptr, int data32,
+               uintptr_t retaddr)
 {
     floatx80 tmp;
     int i;
@@ -2512,18 +2475,6 @@  void helper_frstor(CPUX86State *env, target_ulong ptr, int data32)
     do_frstor(env, ptr, data32, GETPC());
 }
 
-#if defined(CONFIG_USER_ONLY)
-void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32)
-{
-    do_fsave(env, ptr, data32, 0);
-}
-
-void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32)
-{
-    do_frstor(env, ptr, data32, 0);
-}
-#endif
-
 #define XO(X)  offsetof(X86XSaveArea, X)
 
 static void do_xsave_fpu(CPUX86State *env, target_ulong ptr, uintptr_t ra)
@@ -2605,7 +2556,7 @@  static void do_xsave_pkru(CPUX86State *env, target_ulong ptr, uintptr_t ra)
     cpu_stq_data_ra(env, ptr, env->pkru, ra);
 }
 
-static void do_fxsave(CPUX86State *env, target_ulong ptr, uintptr_t ra)
+void do_fxsave(CPUX86State *env, target_ulong ptr, uintptr_t ra)
 {
     /* The operand must be 16 byte aligned */
     if (ptr & 0xf) {
@@ -2772,7 +2723,7 @@  static void do_xrstor_pkru(CPUX86State *env, target_ulong ptr, uintptr_t ra)
     env->pkru = cpu_ldq_data_ra(env, ptr, ra);
 }
 
-static void do_fxrstor(CPUX86State *env, target_ulong ptr, uintptr_t ra)
+void do_fxrstor(CPUX86State *env, target_ulong ptr, uintptr_t ra)
 {
     /* The operand must be 16 byte aligned */
     if (ptr & 0xf) {
@@ -2797,18 +2748,6 @@  void helper_fxrstor(CPUX86State *env, target_ulong ptr)
     do_fxrstor(env, ptr, GETPC());
 }
 
-#if defined(CONFIG_USER_ONLY)
-void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr)
-{
-    do_fxsave(env, ptr, 0);
-}
-
-void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr)
-{
-    do_fxrstor(env, ptr, 0);
-}
-#endif
-
 void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm)
 {
     uintptr_t ra = GETPC();
diff --git a/target/i386/tcg/sysemu/fpu_helper.c b/target/i386/tcg/sysemu/fpu_helper.c
new file mode 100644
index 0000000000..1c3610da3b
--- /dev/null
+++ b/target/i386/tcg/sysemu/fpu_helper.c
@@ -0,0 +1,57 @@ 
+/*
+ *  x86 FPU, MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI helpers (sysemu code)
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/irq.h"
+
+static qemu_irq ferr_irq;
+
+void x86_register_ferr_irq(qemu_irq irq)
+{
+    ferr_irq = irq;
+}
+
+void fpu_check_raise_ferr_irq(CPUX86State *env)
+{
+    if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) {
+        qemu_irq_raise(ferr_irq);
+        return;
+    }
+}
+
+void cpu_clear_ignne(void)
+{
+    CPUX86State *env = &X86_CPU(first_cpu)->env;
+    env->hflags2 &= ~HF2_IGNNE_MASK;
+}
+
+void cpu_set_ignne(void)
+{
+    CPUX86State *env = &X86_CPU(first_cpu)->env;
+    env->hflags2 |= HF2_IGNNE_MASK;
+    /*
+     * We get here in response to a write to port F0h.  The chipset should
+     * deassert FP_IRQ and FERR# instead should stay signaled until FPSW_SE is
+     * cleared, because FERR# and FP_IRQ are two separate pins on real
+     * hardware.  However, we don't model FERR# as a qemu_irq, so we just
+     * do directly what the chipset would do, i.e. deassert FP_IRQ.
+     */
+    qemu_irq_lower(ferr_irq);
+}
diff --git a/target/i386/tcg/user/fpu_helper.c b/target/i386/tcg/user/fpu_helper.c
new file mode 100644
index 0000000000..302849d044
--- /dev/null
+++ b/target/i386/tcg/user/fpu_helper.c
@@ -0,0 +1,42 @@ 
+/*
+ *  x86 FPU, MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI helpers (user-mode)
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "tcg/helper-tcg.h"
+
+void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32)
+{
+    do_fsave(env, ptr, data32, 0);
+}
+
+void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32)
+{
+    do_frstor(env, ptr, data32, 0);
+}
+
+void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr)
+{
+    do_fxsave(env, ptr, 0);
+}
+
+void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr)
+{
+    do_fxrstor(env, ptr, 0);
+}
diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/meson.build
index b2aaab6eef..f84519a213 100644
--- a/target/i386/tcg/sysemu/meson.build
+++ b/target/i386/tcg/sysemu/meson.build
@@ -4,4 +4,5 @@  i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'], if_true: files(
   'excp_helper.c',
   'bpt_helper.c',
   'misc_helper.c',
+  'fpu_helper.c',
 ))
diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.build
index 2ab8bd903c..7d919d3bc8 100644
--- a/target/i386/tcg/user/meson.build
+++ b/target/i386/tcg/user/meson.build
@@ -1,4 +1,5 @@ 
 i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files(
   'excp_helper.c',
   'misc_stubs.c',
+  'fpu_helper.c',
 ))