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 Fix logic for FI, FR, and FPRF fields o...



details:   https://anonhg.NetBSD.org/src/rev/5e7a2f3b5523
branches:  trunk
changeset: 369855:5e7a2f3b5523
user:      rin <rin%NetBSD.org@localhost>
date:      Sun Sep 04 13:14:57 2022 +0000

description:
Fix logic for FI, FR, and FPRF fields of FPSCR.

They are not sticky bits and updated by arithmetic and round
insns at the same time.

Comparison insns update only FPCC sub-field of FPRF.

For other insns, these field are left untouched.

Also, for single-precision insns, exception bits should be set by
the first fpu_implode(), which rounds the value to float.

diffstat:

 sys/arch/powerpc/fpu/fpu_compare.c |    6 +-
 sys/arch/powerpc/fpu/fpu_emu.c     |   19 +--
 sys/arch/powerpc/fpu/fpu_emu.h     |    6 +-
 sys/arch/powerpc/fpu/fpu_implode.c |  156 +++++++++++++++++-------------------
 4 files changed, 87 insertions(+), 100 deletions(-)

diffs (truncated from 528 to 300 lines):

diff -r 8e217b7385f2 -r 5e7a2f3b5523 sys/arch/powerpc/fpu/fpu_compare.c
--- a/sys/arch/powerpc/fpu/fpu_compare.c        Sun Sep 04 11:20:33 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_compare.c        Sun Sep 04 13:14:57 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_compare.c,v 1.5 2020/06/27 03:07:57 rin Exp $ */
+/*     $NetBSD: fpu_compare.c,v 1.6 2022/09/04 13:14:57 rin Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_compare.c,v 1.5 2020/06/27 03:07:57 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_compare.c,v 1.6 2022/09/04 13:14:57 rin Exp $");
 
 #include <sys/types.h>
 
@@ -79,6 +79,8 @@
        struct fpn *a, *b, *r;
        int cc;
 
+       fe->fe_fpscr &= ~FPSCR_FPCC;
+
        a = &fe->fe_f1;
        b = &fe->fe_f2;
        r = &fe->fe_f3;
diff -r 8e217b7385f2 -r 5e7a2f3b5523 sys/arch/powerpc/fpu/fpu_emu.c
--- a/sys/arch/powerpc/fpu/fpu_emu.c    Sun Sep 04 11:20:33 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.c    Sun Sep 04 13:14:57 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_emu.c,v 1.49 2022/09/03 04:54:47 rin Exp $ */
+/*     $NetBSD: fpu_emu.c,v 1.50 2022/09/04 13:14:57 rin Exp $ */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.49 2022/09/03 04:54:47 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.50 2022/09/04 13:14:57 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -297,7 +297,7 @@
        int ra, rb, rc, rt, type, mask, fsr, cx, bf, setcr, cond;
        u_int bits;
        struct fpreg *fs;
-       int i, mtfsb1 = 0;
+       int i;
 
        /* Setup work. */
        fp = NULL;
@@ -499,7 +499,7 @@
                                fpu_implode(fe, fp, FTYPE_SNG, &FR(rt));
                                fpu_explode(fe, fp = &fe->fe_f1, FTYPE_SNG,
                                    FR(rt));
-                               type = FTYPE_DBL | FTYPE_FPRF;
+                               type = FTYPE_DBL | FTYPE_FPSCR;
                                break;
                        case    OPC63_FCTIW:
                        case    OPC63_FCTIWZ:
@@ -526,7 +526,6 @@
                        case    OPC63_MTFSB1:
                                FPU_EMU_EVCNT_INCR(mtfsb1);
                                DPRINTF(FPE_INSN, ("fpu_execute: MTFSB1\n"));
-                               mtfsb1 = 1;
                                fe->fe_cx = (1 << (31 - rt)) &
                                    ~(FPSCR_FEX | FPSCR_VX);
                                break;
@@ -627,7 +626,7 @@
                                DPRINTF(FPE_INSN, ("fpu_execute: FCFID\n"));
                                type = FTYPE_LNG;
                                fpu_explode(fe, fp = &fe->fe_f1, type, FR(rb));
-                               type = FTYPE_DBL | FTYPE_FPRF;
+                               type = FTYPE_DBL | FTYPE_FPSCR;
                                break;
                        default:
                                return (NOTFPU);
@@ -763,12 +762,12 @@
 
                        /* If the instruction was single precision, round */
                        if (!(instr.i_any.i_opcd & 0x4)) {
-                               fpu_implode(fe, fp, FTYPE_SNG | FTYPE_FPRF,
+                               fpu_implode(fe, fp, FTYPE_SNG | FTYPE_FPSCR,
                                    &FR(rt));
                                fpu_explode(fe, fp = &fe->fe_f1, FTYPE_SNG,
                                    FR(rt));
                        } else
-                               type |= FTYPE_FPRF;
+                               type |= FTYPE_FPSCR;
                }
        } else {
                return (NOTFPU);
@@ -785,10 +784,6 @@
        cx = fe->fe_cx;
        fsr = fe->fe_fpscr & ~(FPSCR_FEX|FPSCR_VX);
        if (cx != 0) {
-               if (mtfsb1 == 0 && (cx & FPSCR_FPRF) != 0) {
-                       /* Need to replace CC */
-                       fsr &= ~FPSCR_FPRF;
-               }
                fsr |= cx;
                DPRINTF(FPE_INSN, ("fpu_execute: cx %x, fsr %x\n", cx, fsr));
        }
diff -r 8e217b7385f2 -r 5e7a2f3b5523 sys/arch/powerpc/fpu/fpu_emu.h
--- a/sys/arch/powerpc/fpu/fpu_emu.h    Sun Sep 04 11:20:33 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.h    Sun Sep 04 13:14:57 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_emu.h,v 1.8 2022/09/02 12:40:49 rin Exp $ */
+/*     $NetBSD: fpu_emu.h,v 1.9 2022/09/04 13:14:57 rin Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -141,8 +141,8 @@
 #define        FTYPE_SNG       0x02    /* data = 32-bit float */
 #define        FTYPE_DBL       0x04    /* data = 64-bit double */
 #define        FTYPE_RD_RZ     0x08
-#define        FTYPE_FPRF      0x10
-#define        FTYPE_FLAG_MASK (FTYPE_RD_RZ | FTYPE_FPRF)
+#define        FTYPE_FPSCR     0x10
+#define        FTYPE_FLAG_MASK (FTYPE_RD_RZ | FTYPE_FPSCR)
 
 /*
  * Emulator state.
diff -r 8e217b7385f2 -r 5e7a2f3b5523 sys/arch/powerpc/fpu/fpu_implode.c
--- a/sys/arch/powerpc/fpu/fpu_implode.c        Sun Sep 04 11:20:33 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_implode.c        Sun Sep 04 13:14:57 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_implode.c,v 1.20 2022/09/04 09:23:07 rin Exp $ */
+/*     $NetBSD: fpu_implode.c,v 1.21 2022/09/04 13:14:57 rin Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_implode.c,v 1.20 2022/09/04 09:23:07 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_implode.c,v 1.21 2022/09/04 13:14:57 rin Exp $");
 
 #include <sys/types.h>
 #include <sys/systm.h>
@@ -60,14 +60,14 @@
 #include <powerpc/fpu/fpu_emu.h>
 #include <powerpc/fpu/fpu_extern.h>
 
-static int round(struct fpemu *, struct fpn *);
+static int round(struct fpemu *, struct fpn *, int *);
 static int toinf(struct fpemu *, int);
 static int round_int(struct fpn *, int *, int, int, int);
 
-static u_int fpu_ftoi(struct fpemu *, struct fpn *, int);
-static uint64_t fpu_ftox(struct fpemu *, struct fpn *, int);
-static u_int fpu_ftos(struct fpemu *, struct fpn *, bool);
-static uint64_t fpu_ftod(struct fpemu *, struct fpn *, bool);
+static u_int fpu_ftoi(struct fpemu *, struct fpn *, int *, int);
+static uint64_t fpu_ftox(struct fpemu *, struct fpn *, int *, int);
+static u_int fpu_ftos(struct fpemu *, struct fpn *, int *);
+static uint64_t fpu_ftod(struct fpemu *, struct fpn *, int *);
 
 /*
  * Round a number (algorithm from Motorola MC68882 manual, modified for
@@ -82,7 +82,7 @@
  * responsibility to fix this if necessary.
  */
 static int
-round(struct fpemu *fe, struct fpn *fp)
+round(struct fpemu *fe, struct fpn *fp, int *cx)
 {
        u_int m0, m1, m2, m3;
        int gr, s;
@@ -104,7 +104,7 @@
        if ((gr | s) == 0)      /* result is exact: no rounding needed */
                goto rounddown;
 
-       fe->fe_cx |= FPSCR_XX|FPSCR_FI; /* inexact */
+       *cx |= FPSCR_FI;        /* inexact */
 
        /* Go to rounddown to round down; break to round up. */
        switch ((fe->fe_fpscr) & FPSCR_RN) {
@@ -140,7 +140,7 @@
        }
 
        /* Bump low bit of mantissa, with carry. */
-       fe->fe_cx |= FPSCR_FR;
+       *cx |= FPSCR_FR;
 
        FPU_ADDS(m3, m3, 1);
        FPU_ADDCS(m2, m2, 0);
@@ -190,8 +190,6 @@
                inf = sign;
                break;
        }
-       if (inf)
-               fe->fe_cx |= FPSCR_OX;
        return (inf);
 }
 
@@ -206,7 +204,7 @@
        if ((g | rs) == 0)
                return 0;       /* exact */
 
-       *cx |= FPSCR_XX | FPSCR_FI;
+       *cx |= FPSCR_FI;
 
        switch (rn) {
        case FSR_RD_RN:
@@ -233,16 +231,15 @@
  * fpn -> int (int value returned as return value).
  */
 static u_int
-fpu_ftoi(struct fpemu *fe, struct fpn *fp, int rn)
+fpu_ftoi(struct fpemu *fe, struct fpn *fp, int *cx, int rn)
 {
        u_int i;
-       int sign, exp, cx;
+       int sign, exp, tmp_cx;
 
        sign = fp->fp_sign;
-       cx = 0;
        switch (fp->fp_class) {
        case FPC_SNAN:
-               fe->fe_cx |= FPSCR_VXSNAN;
+               *cx |= FPSCR_VXSNAN;
                /* FALLTHROUGH */
        case FPC_QNAN:
                sign = 1;
@@ -267,17 +264,18 @@
                /* NB: the following includes exp < 0 cases */
                (void)fpu_shr(fp, FP_NMANT - 32 - 1 - exp);
                i = fp->fp_mant[2];
-               i += round_int(fp, &cx, rn, sign, i & 1);
+               tmp_cx = 0;
+               i += round_int(fp, &tmp_cx, rn, sign, i & 1);
                if (i >= ((u_int)0x80000000 + sign))
                        break;
-               fe->fe_cx |= cx;
+               *cx |= tmp_cx;
                return (sign ? -i : i);
 
        case FPC_INF:
                break;
        }
        /* overflow: replace any inexact exception with invalid */
-       fe->fe_cx |= FPSCR_VXCVI;
+       *cx |= FPSCR_VXCVI;
        return (0x7fffffff + sign);
 }
 
@@ -285,16 +283,15 @@
  * fpn -> extended int (high bits of int value returned as return value).
  */
 static uint64_t
-fpu_ftox(struct fpemu *fe, struct fpn *fp, int rn)
+fpu_ftox(struct fpemu *fe, struct fpn *fp, int *cx, int rn)
 {
        uint64_t i;
-       int sign, exp, cx;
+       int sign, exp, tmp_cx;
 
        sign = fp->fp_sign;
-       cx = 0;
        switch (fp->fp_class) {
        case FPC_SNAN:
-               fe->fe_cx |= FPSCR_VXSNAN;
+               *cx |= FPSCR_VXSNAN;
                /* FALLTHROUGH */
        case FPC_QNAN:
                sign = 1;
@@ -319,17 +316,18 @@
                /* NB: the following includes exp < 0 cases */
                (void)fpu_shr(fp, FP_NMANT - 32 - 1 - exp);
                i = ((uint64_t)fp->fp_mant[1] << 32) | fp->fp_mant[2];
-               i += round_int(fp, &cx, rn, sign, i & 1);
+               tmp_cx = 0;
+               i += round_int(fp, &tmp_cx, rn, sign, i & 1);
                if (i >= ((uint64_t)0x8000000000000000LL + sign))
                        break;
-               fe->fe_cx |= cx;
+               *cx |= tmp_cx;
                return (sign ? -i : i);
 
        case FPC_INF:
                break;
        }
        /* overflow: replace any inexact exception with invalid */
-       fe->fe_cx |= FPSCR_VXCVI;
+       *cx |= FPSCR_VXCVI;
        return (0x7fffffffffffffffLL + sign);
 }
 
@@ -340,7 +338,7 @@
  * We assume <= 29 bits in a single-precision fraction (1.f part).
  */
 static u_int
-fpu_ftos(struct fpemu *fe, struct fpn *fp, bool fprf)
+fpu_ftos(struct fpemu *fe, struct fpn *fp, int *cx)
 {



Home | Main Index | Thread Index | Old Index