linux-user/hppa: Send proper si_code on SIGFPE exception

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>
This commit is contained in:
Helge Deller 2025-05-17 13:20:17 +02:00
parent 923976dfe3
commit b4b49cf39d

View 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);