@samitouri / QOSamiQemu / commits / 668d571bf0

linux-user/sh4: Initialize the FPSCR register on signal

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: qemu-stable@nongnu.org Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Reviewed-by: Yoshinori Sato <yoshinori.sato@nifty.com> Signed-off-by: Helge Deller <deller@gmx.de>

Mikulas Patocka committed Aug 4, 2026 at 10:59 UTC 668d571bf0c2ee4851be2187798f413025647fc3
1 file changed +4
linux-user/sh4/signal.c
+4
@@ -206,6 +206,8 @@ void setup_frame(int sig, struct target_sigaction *ka,
206 __put_user(set->sig[i + 1], &frame->extramask[i]);
207 }
208
209 + regs->fpscr = FPSCR_PR;
210 +
211 /* Set up to return from userspace. If provided, use a stub
212 already in userspace. */
213 if (ka->sa_flags & TARGET_SA_RESTORER) {
@@ -258,6 +260,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
260 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
261 }
262
263 + regs->fpscr = FPSCR_PR;
264 +
265 /* Set up to return from userspace. If provided, use a stub
266 already in userspace. */
267 if (ka->sa_flags & TARGET_SA_RESTORER) {