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 fcti{w,d}{,z}.
details: https://anonhg.NetBSD.org/src/rev/b9c1e25d3dde
branches: trunk
changeset: 369753:b9c1e25d3dde
user: rin <rin%NetBSD.org@localhost>
date: Tue Aug 30 11:09:34 2022 +0000
description:
Fix fcti{w,d}{,z}.
- Treat 64-bit integer correctly for fctid{,z}.
- Respect round mode specified by FPSCR[RN].
XXX
- Set FPSCR[FR] and [FI] appropriately.
- Also set FPSCR[FPRF]?
- fctid{,z} traps on powerpc32 (confirmed on 603e and G4).
diffstat:
sys/arch/powerpc/fpu/fpu_emu.c | 8 ++-
sys/arch/powerpc/fpu/fpu_emu.h | 12 +++--
sys/arch/powerpc/fpu/fpu_extern.h | 6 +-
sys/arch/powerpc/fpu/fpu_implode.c | 77 +++++++++++++++++++++++++++++--------
4 files changed, 76 insertions(+), 27 deletions(-)
diffs (231 lines):
diff -r e2f46e5013c7 -r b9c1e25d3dde sys/arch/powerpc/fpu/fpu_emu.c
--- a/sys/arch/powerpc/fpu/fpu_emu.c Tue Aug 30 11:05:59 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.c Tue Aug 30 11:09:34 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_emu.c,v 1.42 2022/08/30 10:59:43 rin Exp $ */
+/* $NetBSD: fpu_emu.c,v 1.43 2022/08/30 11:09:34 rin Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.42 2022/08/30 10:59:43 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.43 2022/08/30 11:09:34 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -504,6 +504,8 @@
DPRINTF(FPE_INSN, ("fpu_execute: FCTIW\n"));
fpu_explode(fe, fp = &fe->fe_f1, type, rb);
type = FTYPE_INT;
+ if (instr.i_x.i_xo == OPC63_FCTIWZ)
+ type |= FTYPE_RD_RZ;
break;
case OPC63_FCMPO:
FPU_EMU_EVCNT_INCR(fcmpo);
@@ -614,6 +616,8 @@
DPRINTF(FPE_INSN, ("fpu_execute: FCTID\n"));
fpu_explode(fe, fp = &fe->fe_f1, type, rb);
type = FTYPE_LNG;
+ if (instr.i_x.i_xo == OPC63_FCTIDZ)
+ type |= FTYPE_RD_RZ;
break;
case OPC63_FCFID:
FPU_EMU_EVCNT_INCR(fcfid);
diff -r e2f46e5013c7 -r b9c1e25d3dde sys/arch/powerpc/fpu/fpu_emu.h
--- a/sys/arch/powerpc/fpu/fpu_emu.h Tue Aug 30 11:05:59 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.h Tue Aug 30 11:09:34 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_emu.h,v 1.5 2022/08/30 11:05:59 rin Exp $ */
+/* $NetBSD: fpu_emu.h,v 1.6 2022/08/30 11:09:34 rin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -136,10 +136,12 @@
/*
* FPU data types.
*/
-#define FTYPE_LNG -1 /* data = 64-bit signed long integer */
-#define FTYPE_INT 0 /* data = 32-bit signed integer */
-#define FTYPE_SNG 1 /* data = 32-bit float */
-#define FTYPE_DBL 2 /* data = 64-bit double */
+#define FTYPE_INT 0x0 /* data = 32-bit signed integer */
+#define FTYPE_LNG 0x1 /* data = 64-bit signed long integer */
+#define FTYPE_SNG 0x2 /* data = 32-bit float */
+#define FTYPE_DBL 0x4 /* data = 64-bit double */
+#define FTYPE_RD_RZ 0x8
+#define FTYPE_RD_MASK (FTYPE_RD_RZ)
/*
* Emulator state.
diff -r e2f46e5013c7 -r b9c1e25d3dde sys/arch/powerpc/fpu/fpu_extern.h
--- a/sys/arch/powerpc/fpu/fpu_extern.h Tue Aug 30 11:05:59 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_extern.h Tue Aug 30 11:09:34 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_extern.h,v 1.6 2022/08/28 22:22:41 rin Exp $ */
+/* $NetBSD: fpu_extern.h,v 1.7 2022/08/30 11:09:34 rin Exp $ */
/*-
* Copyright (c) 1995 The NetBSD Foundation, Inc.
@@ -63,8 +63,8 @@
void fpu_explode(struct fpemu *, struct fpn *, int, int);
/* fpu_implode.c */
-u_int fpu_ftoi(struct fpemu *, struct fpn *);
-u_int fpu_ftox(struct fpemu *, struct fpn *, u_int *);
+u_int fpu_ftoi(struct fpemu *, struct fpn *, int);
+uint64_t fpu_ftox(struct fpemu *, struct fpn *, int);
u_int fpu_ftos(struct fpemu *, struct fpn *);
u_int fpu_ftod(struct fpemu *, struct fpn *, u_int *);
void fpu_implode(struct fpemu *, struct fpn *, int, u_int *);
diff -r e2f46e5013c7 -r b9c1e25d3dde sys/arch/powerpc/fpu/fpu_implode.c
--- a/sys/arch/powerpc/fpu/fpu_implode.c Tue Aug 30 11:05:59 2022 +0000
+++ b/sys/arch/powerpc/fpu/fpu_implode.c Tue Aug 30 11:09:34 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_implode.c,v 1.9 2022/08/30 11:00:49 rin Exp $ */
+/* $NetBSD: fpu_implode.c,v 1.10 2022/08/30 11:09:34 rin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_implode.c,v 1.9 2022/08/30 11:00:49 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_implode.c,v 1.10 2022/08/30 11:09:34 rin Exp $");
#include <sys/types.h>
#include <sys/systm.h>
@@ -191,15 +191,12 @@
/*
* fpn -> int (int value returned as return value).
- *
- * N.B.: this conversion always rounds towards zero (this is a peculiarity
- * of the SPARC instruction set).
*/
u_int
-fpu_ftoi(struct fpemu *fe, struct fpn *fp)
+fpu_ftoi(struct fpemu *fe, struct fpn *fp, int rn)
{
u_int i;
- int sign, exp;
+ int sign, exp, g, rs;
sign = fp->fp_sign;
switch (fp->fp_class) {
@@ -221,9 +218,29 @@
if ((exp = fp->fp_exp) >= 32)
break;
/* NB: the following includes exp < 0 cases */
- if (fpu_shr(fp, FP_NMANT - 1 - exp) != 0)
+ if (fpu_shr(fp, FP_NMANT - 32 - 1 - exp) != 0)
fe->fe_cx |= FPSCR_UX;
- i = fp->fp_mant[3];
+ i = fp->fp_mant[2];
+
+ g = fp->fp_mant[3] & 0x80000000;
+ rs = (fp->fp_mant[3] & 0x7fffffff) | fp->fp_sticky;
+ switch (rn) {
+ case FSR_RD_RN:
+ if (g && (rs | (i & 1)))
+ i++;
+ break;
+ case FSR_RD_RZ:
+ break;
+ case FSR_RD_RP:
+ if (!sign && (g | rs))
+ i++;
+ break;
+ case FSR_RD_RM:
+ if (sign && (g | rs))
+ i++;
+ break;
+ }
+
if (i >= ((u_int)0x80000000 + sign))
break;
return (sign ? -i : i);
@@ -242,17 +259,16 @@
* N.B.: this conversion always rounds towards zero (this is a peculiarity
* of the SPARC instruction set).
*/
-u_int
-fpu_ftox(struct fpemu *fe, struct fpn *fp, u_int *res)
+uint64_t
+fpu_ftox(struct fpemu *fe, struct fpn *fp, int rn)
{
uint64_t i;
- int sign, exp;
+ int sign, exp, g, rs;
sign = fp->fp_sign;
switch (fp->fp_class) {
case FPC_ZERO:
- res[1] = 0;
return (0);
case FPC_NUM:
@@ -269,9 +285,29 @@
if ((exp = fp->fp_exp) >= 64)
break;
/* NB: the following includes exp < 0 cases */
- if (fpu_shr(fp, FP_NMANT - 1 - exp) != 0)
+ if (fpu_shr(fp, FP_NMANT - 32 - 1 - exp) != 0)
fe->fe_cx |= FPSCR_UX;
- i = ((uint64_t)fp->fp_mant[2]<<32)|fp->fp_mant[3];
+ i = ((uint64_t)fp->fp_mant[1] << 32) | fp->fp_mant[2];
+
+ g = fp->fp_mant[3] & 0x80000000;
+ rs = (fp->fp_mant[3] & 0x7fffffff) | fp->fp_sticky;
+ switch (rn) {
+ case FSR_RD_RN:
+ if (g && (rs | (i & 1)))
+ i++;
+ break;
+ case FSR_RD_RZ:
+ break;
+ case FSR_RD_RP:
+ if (!sign && (g | rs))
+ i++;
+ break;
+ case FSR_RD_RM:
+ if (sign && (g | rs))
+ i++;
+ break;
+ }
+
if (i >= ((uint64_t)0x8000000000000000LL + sign))
break;
return (sign ? -i : i);
@@ -427,18 +463,25 @@
void
fpu_implode(struct fpemu *fe, struct fpn *fp, int type, u_int *space)
{
+ int rn;
+
+ if (type & FTYPE_RD_RZ)
+ rn = FSR_RD_RZ;
+ else
+ rn = fe->fe_fpscr & FPSCR_RN;
+ type &= ~FTYPE_RD_MASK;
switch (type) {
case FTYPE_LNG:
- space[0] = fpu_ftox(fe, fp, space);
+ *(uint64_t *)space = fpu_ftox(fe, fp, rn);
DPRINTF(FPE_REG, ("fpu_implode: long %x %x\n",
space[0], space[1]));
break;
case FTYPE_INT:
space[0] = 0;
- space[1] = fpu_ftoi(fe, fp);
+ space[1] = fpu_ftoi(fe, fp, rn);
DPRINTF(FPE_REG, ("fpu_implode: int %x\n",
space[1]));
break;
Home |
Main Index |
Thread Index |
Old Index