mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'hppa-fpe-fixup-pull-request' of https://github.com/hdeller/qemu-hppa into staging
HPPA floating point exception handling fixes Fixes and improvements in the floating point exception handling in the hppa system and user emulation. # -----BEGIN PGP SIGNATURE----- # # iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCaC7b/QAKCRD3ErUQojoP # X8IPAQCZGjG3+iwJJuJkL6dSu7WKWgidX16zIxeRYQl+FXTpkAD9FBQ/nDP+EAFN # 5hQTeiixyj3xIsZHPeHwfzhWiBUwQAo= # =Q3zi # -----END PGP SIGNATURE----- # gpg: Signature made Thu 22 May 2025 04:10:37 EDT # gpg: using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F # gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown] # gpg: aka "Helge Deller <deller@kernel.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4544 8228 2CD9 10DB EF3D 25F8 3E5F 3D04 A7A2 4603 # Subkey fingerprint: BCE9 123E 1AD2 9F07 C049 BBDE F712 B510 A23A 0F5F * tag 'hppa-fpe-fixup-pull-request' of https://github.com/hdeller/qemu-hppa: target/hppa: Fix FPE exceptions linux-user/hppa: Send proper si_code on SIGFPE exception target/hppa: Copy instruction code into fr1 on FPU assist fault Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -94,7 +94,8 @@ static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
|
||||
{
|
||||
uint32_t soft_exp = get_float_exception_flags(&env->fp_status);
|
||||
uint32_t hard_exp = 0;
|
||||
uint32_t shadow = env->fr0_shadow;
|
||||
uint32_t shadow = env->fr0_shadow & 0x3ffffff;
|
||||
uint32_t fr1 = 0;
|
||||
|
||||
if (likely(soft_exp == 0)) {
|
||||
env->fr[0] = (uint64_t)shadow << 32;
|
||||
@@ -107,9 +108,22 @@ static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, R_FPSR_ENA_O_MASK);
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, R_FPSR_ENA_Z_MASK);
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, R_FPSR_ENA_V_MASK);
|
||||
shadow |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT);
|
||||
if (hard_exp & shadow) {
|
||||
shadow = FIELD_DP32(shadow, FPSR, T, 1);
|
||||
/* fill exception register #1, which is lower 32-bits of fr[0] */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (hard_exp & (R_FPSR_ENA_O_MASK | R_FPSR_ENA_U_MASK)) {
|
||||
/* over- and underflow both set overflow flag only */
|
||||
fr1 = FIELD_DP32(fr1, FPSR, C, 1);
|
||||
fr1 = FIELD_DP32(fr1, FPSR, FLG_O, 1);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fr1 |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT);
|
||||
}
|
||||
}
|
||||
env->fr0_shadow = shadow;
|
||||
env->fr[0] = (uint64_t)shadow << 32;
|
||||
env->fr[0] = (uint64_t)shadow << 32 | fr1;
|
||||
|
||||
if (hard_exp & shadow) {
|
||||
hppa_dynamic_excp(env, EXCP_ASSIST, ra);
|
||||
|
||||
@@ -177,6 +177,10 @@ void hppa_cpu_do_interrupt(CPUState *cs)
|
||||
}
|
||||
}
|
||||
env->cr[CR_IIR] = ldl_phys(cs->as, paddr);
|
||||
if (i == EXCP_ASSIST) {
|
||||
/* stuff insn code into bits of FP exception register #1 */
|
||||
env->fr[0] |= (env->cr[CR_IIR] & 0x03ffffff);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user