[PATCH] linux-user/sh4: Initialize the FPSCR register on signal
Mikulas Patocka <[email protected]> Tue, 4 Aug 2026 10:59:18 +0200 (CEST)
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
On the SH4 architecture, the instructions that perform single precision and double precision floating point operations are encoded in the same way. The bit PR in the FPSCR register determines if the CPU performs single or double operation. According to the ABI, the PR bit must be set at function entry and function exit. GCC generates code that flips this bit as needed during function execution. If we get a signal, we must set the PR bit, so that the signal handler finds the bit in the expected state. Qemu lacked this logic, so that if the signal interrupts single-precision floating point calculation, the PR bit would be incorrectly clear at signal handler entry. If the signal handler performed some floating-point calculation, it would get incorrect result. This patch fixes the bug, by initializing the FPSCR register at signal entry. Note that we initialize the whole register, because the Linux kernel initializes the whole register too. Cc: [email protected] Signed-off-by: Mikulas Patocka <[email protected]> --- linux-user/sh4/signal.c | 4 ++++ 1 file changed, 4 insertions(+) Index: qemu/linux-user/sh4/signal.c =================================================================== --- qemu.orig/linux-user/sh4/signal.c 2026-08-02 18:03:09.000000000 +0200 +++ qemu/linux-user/sh4/signal.c 2026-08-04 09:40:21.000000000 +0200 @@ -206,6 +206,8 @@ void setup_frame(int sig, struct target_ __put_user(set->sig[i + 1], &frame->extramask[i]); } + regs->fpscr = FPSCR_PR; + /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa_flags & TARGET_SA_RESTORER) { @@ -258,6 +260,8 @@ void setup_rt_frame(int sig, struct targ __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); } + regs->fpscr = FPSCR_PR; + /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa_flags & TARGET_SA_RESTORER) {