Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc/fpu Try to fix FPSCR bits in the end of emu...
details: https://anonhg.NetBSD.org/src/rev/addac978b8f9
branches: trunk
changeset: 935993:addac978b8f9
user: rin <rin%NetBSD.org@localhost>
date: Wed Jul 15 09:36:35 2020 +0000
description:
Try to fix FPSCR bits in the end of emulation:
- FPSCR[FEX] is not a sticky bit.
- Turn on FPSCR[FEX] if the emulated instruction causes invalid operation,
and invalid operation exception is not masked out.
- FPSCR[VX] is not a sticky bit, however it should be set when at least
one of FPSCR[VXfoo] bits (they are sticky!) is set.
- FPSCR[FX] is a sticky bit, and it should be set if FPSCR is modified by
instructions other than mtfsf{,i}.
diffstat:
sys/arch/powerpc/fpu/fpu_emu.c | 24 +++++++++++++++---------
1 files changed, 15 insertions(+), 9 deletions(-)
diffs (84 lines):
diff -r da21c63a1c0a -r addac978b8f9 sys/arch/powerpc/fpu/fpu_emu.c
--- a/sys/arch/powerpc/fpu/fpu_emu.c Wed Jul 15 09:22:26 2020 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.c Wed Jul 15 09:36:35 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_emu.c,v 1.31 2020/07/15 09:22:26 rin Exp $ */
+/* $NetBSD: fpu_emu.c,v 1.32 2020/07/15 09:36:35 rin Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.31 2020/07/15 09:22:26 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.32 2020/07/15 09:36:35 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -147,7 +147,9 @@
FPSCR_VXZDZ|FPSCR_VXIMZ|FPSCR_VXVC|FPSCR_VXSOFT|\
FPSCR_VXSQRT|FPSCR_VXCVI)
#define FPSR_EX (FPSCR_VE|FPSCR_OE|FPSCR_UE|FPSCR_ZE|FPSCR_XE)
-#define FPSR_EXOP (FPSR_EX_MSK&(~FPSR_EX))
+#define FPSR_INV (FPSCR_VXSNAN|FPSCR_VXISI|FPSCR_VXIDI| \
+ FPSCR_VXZDZ|FPSCR_VXIMZ|FPSCR_VXVC|FPSCR_VXSOFT|\
+ FPSCR_VXSQRT|FPSCR_VXCVI)
int fpe_debug = 0;
@@ -287,6 +289,7 @@
int ra, rb, rc, rt, type, mask, fsr, cx, bf, setcr;
unsigned int cond;
struct fpreg *fs;
+ int mtfsf = 0;
/* Setup work. */
fp = NULL;
@@ -550,6 +553,7 @@
sizeof(double));
break;
case OPC63_MTFSFI:
+ mtfsf = 1;
FPU_EMU_EVCNT_INCR(mtfsfi);
DPRINTF(FPE_INSN, ("fpu_execute: MTFSFI\n"));
rb >>= 1;
@@ -585,6 +589,7 @@
sizeof(fs->fpscr));
break;
case OPC63_MTFSF:
+ mtfsf = 1;
FPU_EMU_EVCNT_INCR(mtfsf);
DPRINTF(FPE_INSN, ("fpu_execute: MTFSF\n"));
if ((rt = instr.i_xfl.i_flm) == -1)
@@ -769,11 +774,10 @@
if (fp)
fpu_implode(fe, fp, type, (u_int *)&fs->fpreg[rt]);
cx = fe->fe_cx;
- fsr = fe->fe_fpscr;
+ fsr = fe->fe_fpscr & ~(FPSCR_FEX|FPSCR_VX);
if (cx != 0) {
- fsr &= ~FPSCR_FX;
- if ((cx^fsr)&FPSR_EX_MSK)
- fsr |= FPSCR_FX;
+ if (cx & FPSR_INV)
+ cx |= FPSCR_VX;
mask = fsr & FPSR_EX;
mask <<= (25-3);
if (cx & mask)
@@ -782,11 +786,13 @@
/* Need to replace CC */
fsr &= ~FPSCR_FPRF;
}
- if (cx & (FPSR_EXOP))
- fsr |= FPSCR_VX;
fsr |= cx;
DPRINTF(FPE_INSN, ("fpu_execute: cx %x, fsr %x\n", cx, fsr));
}
+ if (fsr & FPSR_INV)
+ fsr |= FPSCR_VX;
+ if (mtfsf == 0 && ((fsr ^ fe->fe_fpscr) & FPSR_EX_MSK))
+ fsr |= FPSCR_FX;
if (cond) {
cond = fsr & 0xf0000000;
Home |
Main Index |
Thread Index |
Old Index