PR port-powerpc/51368: powerpc FPU emulation fails for single precision
floating point arithmetic For single precision instruction, calculate first in double precision, and then round it. With this fix, single precision arithmetic gets sane on ibm4xx and booke. Taken from FreeBSD commit r258250: https://svnweb.freebsd.org/base?view=revision&revision=258250 Ok matt and simonb.
This commit is contained in:
parent
0b5b7fff16
commit
011775c944
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu_emu.c,v 1.18 2016/12/15 11:32:03 rin Exp $ */
|
||||
/* $NetBSD: fpu_emu.c,v 1.19 2016/12/28 10:52:30 rin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Wasabi Systems, Inc.
|
||||
|
@ -76,7 +76,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.18 2016/12/15 11:32:03 rin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.19 2016/12/28 10:52:30 rin Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
|
@ -626,9 +626,11 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
|
|||
rb = instr.i_a.i_frb;
|
||||
rc = instr.i_a.i_frc;
|
||||
|
||||
type = FTYPE_SNG;
|
||||
if (instr.i_any.i_opcd & 0x4)
|
||||
type = FTYPE_DBL;
|
||||
/*
|
||||
* All arithmetic operations work on registers, which
|
||||
* are stored as doubles.
|
||||
*/
|
||||
type = FTYPE_DBL;
|
||||
switch ((unsigned int)instr.i_a.i_xo) {
|
||||
case OPC59_FDIVS:
|
||||
FPU_EMU_EVCNT_INCR(fdiv);
|
||||
|
@ -745,6 +747,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
|
|||
return (NOTFPU);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the instruction was single precision, round */
|
||||
if (!(instr.i_any.i_opcd & 0x4)) {
|
||||
fpu_implode(fe, fp, FTYPE_SNG,
|
||||
(u_int *)&fs->fpreg[rt]);
|
||||
fpu_explode(fe, fp = &fe->fe_f1, FTYPE_SNG, rt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return (NOTFPU);
|
||||
|
|
Loading…
Reference in New Issue