]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
linux-user/hppa: Send proper si_code on SIGFPE exception
authorHelge Deller <deller@gmx.de>
Sat, 17 May 2025 11:20:17 +0000 (13:20 +0200)
committerMichael Tokarev <mjt@tls.msk.ru>
Sun, 25 May 2025 08:19:57 +0000 (11:19 +0300)
Improve the linux-user emulation to send the correct si_code depending
on overflow (TARGET_FPE_FLTOVF), underflow (TARGET_FPE_FLTUND), ...
Note that the hardware stores the relevant flags in FP exception
register #1, which is actually the lower 32-bits of the 64-bit fr[0]
register in qemu.

Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit b4b49cf39dba5f993ad925f204cb820aacfc8e45)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
linux-user/hppa/cpu_loop.c

index 890e758cd1c7d8ae120c4fb70f5b986b086498fa..9abaad5ef81d0d94e0161adeadd1b2d919906264 100644 (file)
@@ -112,7 +112,7 @@ static abi_ulong hppa_lws(CPUHPPAState *env)
 void cpu_loop(CPUHPPAState *env)
 {
     CPUState *cs = env_cpu(env);
-    abi_ulong ret;
+    abi_ulong ret, si_code = 0;
     int trapnr;
 
     while (1) {
@@ -169,7 +169,15 @@ void cpu_loop(CPUHPPAState *env)
             force_sig_fault(TARGET_SIGFPE, TARGET_FPE_CONDTRAP, env->iaoq_f);
             break;
         case EXCP_ASSIST:
-            force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
+            #define set_si_code(mask, val) \
+                if (env->fr[0] & mask) { si_code = val; }
+            set_si_code(R_FPSR_FLG_I_MASK, TARGET_FPE_FLTRES);
+            set_si_code(R_FPSR_FLG_U_MASK, TARGET_FPE_FLTUND);
+            set_si_code(R_FPSR_FLG_O_MASK, TARGET_FPE_FLTOVF);
+            set_si_code(R_FPSR_FLG_Z_MASK, TARGET_FPE_FLTDIV);
+            set_si_code(R_FPSR_FLG_V_MASK, TARGET_FPE_FLTINV);
+            #undef set_si_code
+            force_sig_fault(TARGET_SIGFPE, si_code, env->iaoq_f);
             break;
         case EXCP_BREAK:
             force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f);