All of lore.kernel.org
 help / color / mirror / Atom feed
From: Helge Deller <deller@kernel.org>
To: Stefan Hajnoczi <stefanha@gmail.com>, qemu-devel@nongnu.org
Cc: Helge Deller <deller@gmx.de>,
	Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
	Laurent Vivier <laurent@vivier.eu>,
	Max Filippov <jcmvbkbc@gmail.com>,
	Matt Turner <mattst88@gmail.com>,
	Richard Henderson <richard.henderson@linaro.org>
Subject: [PULL 3/4] target/xtensa: add cpu_set_fcr/fsr helpers to sync fp_status
Date: Fri, 12 Jun 2026 17:50:42 +0200	[thread overview]
Message-ID: <20260612155043.3552-4-deller@kernel.org> (raw)
In-Reply-To: <20260612155043.3552-1-deller@kernel.org>

From: Matt Turner <mattst88@gmail.com>

Factor FCR→fp_status and FSR→fp_status synchronisation out of the
wur_fpu{2k,}_fcr/wur_fpu_fsr helpers into cpu_set_fcr(), cpu_set_fsr(),
and cpu_get_fsr(). Signal delivery code needs to restore the FP rounding
mode and exception flags without duplicating the flag-mapping tables.

cpu_set_fcr() applies the union mask 0xfffff07f (superset of the
wur_fpu_fcr mask 0x0000007f and the wur_fpu2k_fcr mask 0xfffff07f) so
that FCR bits valid only on fpu2k configs are preserved while MBZ bits
7-11 are always cleared.

Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
---
 target/xtensa/cpu.h        |  4 +++
 target/xtensa/fpu_helper.c | 71 +++++++++++++++++++++-----------------
 2 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 75cfeee6e3..442e98bd1b 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -642,6 +642,10 @@ static inline void xtensa_select_static_vectors(CPUXtensaState *env,
 }
 void xtensa_runstall(CPUXtensaState *env, bool runstall);
 
+uint32_t cpu_get_fsr(CPUXtensaState *env);
+void cpu_set_fcr(CPUXtensaState *env, uint32_t v);
+void cpu_set_fsr(CPUXtensaState *env, uint32_t v);
+
 #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
 #define XTENSA_OPTION_ALL (~(uint64_t)0)
 
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
index 5358060c50..2e51cabe3f 100644
--- a/target/xtensa/fpu_helper.c
+++ b/target/xtensa/fpu_helper.c
@@ -64,46 +64,39 @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
                              &env->fp_status);
 }
 
-void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
+uint32_t cpu_get_fsr(CPUXtensaState *env)
 {
-    static const int rounding_mode[] = {
-        float_round_nearest_even,
-        float_round_to_zero,
-        float_round_up,
-        float_round_down,
-    };
+    uint32_t flags = 0;
+    int fef = get_float_exception_flags(&env->fp_status);
+    unsigned i;
 
-    env->uregs[FCR] = v & 0xfffff07f;
-    set_float_rounding_mode(rounding_mode[v & 3], &env->fp_status);
+    for (i = 0; i < ARRAY_SIZE(xtensa_fp_flag_map); ++i) {
+        if (fef & xtensa_fp_flag_map[i].softfloat_fp_flag) {
+            flags |= xtensa_fp_flag_map[i].xtensa_fp_flag;
+        }
+    }
+    return flags << XTENSA_FSR_FLAGS_SHIFT;
 }
 
-void HELPER(wur_fpu_fcr)(CPUXtensaState *env, uint32_t v)
+void cpu_set_fcr(CPUXtensaState *env, uint32_t v)
 {
-    static const int rounding_mode[] = {
+    static const FloatRoundMode rounding_mode[] = {
         float_round_nearest_even,
         float_round_to_zero,
         float_round_up,
         float_round_down,
     };
 
-    if (v & 0xfffff000) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "MBZ field of FCR is written non-zero: %08x\n", v);
-    }
-    env->uregs[FCR] = v & 0x0000007f;
+    env->uregs[FCR] = v & 0xfffff07f;
     set_float_rounding_mode(rounding_mode[v & 3], &env->fp_status);
 }
 
-void HELPER(wur_fpu_fsr)(CPUXtensaState *env, uint32_t v)
+void cpu_set_fsr(CPUXtensaState *env, uint32_t v)
 {
     uint32_t flags = v >> XTENSA_FSR_FLAGS_SHIFT;
     int fef = 0;
     unsigned i;
 
-    if (v & 0xfffff000) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "MBZ field of FSR is written non-zero: %08x\n", v);
-    }
     env->uregs[FSR] = v & 0x00000f80;
     for (i = 0; i < ARRAY_SIZE(xtensa_fp_flag_map); ++i) {
         if (flags & xtensa_fp_flag_map[i].xtensa_fp_flag) {
@@ -113,19 +106,35 @@ void HELPER(wur_fpu_fsr)(CPUXtensaState *env, uint32_t v)
     set_float_exception_flags(fef, &env->fp_status);
 }
 
-uint32_t HELPER(rur_fpu_fsr)(CPUXtensaState *env)
+void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
 {
-    uint32_t flags = 0;
-    int fef = get_float_exception_flags(&env->fp_status);
-    unsigned i;
+    cpu_set_fcr(env, v);
+}
 
-    for (i = 0; i < ARRAY_SIZE(xtensa_fp_flag_map); ++i) {
-        if (fef & xtensa_fp_flag_map[i].softfloat_fp_flag) {
-            flags |= xtensa_fp_flag_map[i].xtensa_fp_flag;
-        }
+void HELPER(wur_fpu_fcr)(CPUXtensaState *env, uint32_t v)
+{
+    if (v & 0xfffff000) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "MBZ field of FCR is written non-zero: %08x\n", v);
     }
-    env->uregs[FSR] = flags << XTENSA_FSR_FLAGS_SHIFT;
-    return flags << XTENSA_FSR_FLAGS_SHIFT;
+    cpu_set_fcr(env, v & 0x0000007f);
+}
+
+void HELPER(wur_fpu_fsr)(CPUXtensaState *env, uint32_t v)
+{
+    if (v & 0xfffff000) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "MBZ field of FSR is written non-zero: %08x\n", v);
+    }
+    cpu_set_fsr(env, v);
+}
+
+uint32_t HELPER(rur_fpu_fsr)(CPUXtensaState *env)
+{
+    uint32_t fsr = cpu_get_fsr(env);
+
+    env->uregs[FSR] = fsr;
+    return fsr;
 }
 
 float64 HELPER(abs_d)(float64 v)
-- 
2.54.0



  parent reply	other threads:[~2026-06-12 15:52 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-12 15:50 [PULL 0/4] Linux user patches Helge Deller
2026-06-12 15:50 ` [PULL 1/4] linux-user: add preadv2/preadv2 Helge Deller
2026-06-12 15:50 ` [PULL 2/4] linux-user: Implement /proc/cpuinfo for ppc cpus Helge Deller
2026-06-12 15:50 ` Helge Deller [this message]
2026-06-12 15:50 ` [PULL 4/4] linux-user/xtensa: save/restore FP registers across signal delivery Helge Deller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260612155043.3552-4-deller@kernel.org \
    --to=deller@kernel.org \
    --cc=deller@gmx.de \
    --cc=jcmvbkbc@gmail.com \
    --cc=laurent@vivier.eu \
    --cc=mattst88@gmail.com \
    --cc=pierrick.bouvier@oss.qualcomm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=stefanha@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.