On 2016/12/28 18:27, Matt Thomas wrote:

On Dec 27, 2016, at 11:59 PM, Rin Okuyama <rokuy...@rk.phys.keio.ac.jp> wrote:

Thank you for your kind explanation. I'm starting to understand.
I will read again the reference manual from this point of view.
So, could I commit the patch?

Go commit it.


Thanks, I committed it!

By the way, I'd also like to fix port-powerpc/51368:

  http://gnats.netbsd.org/51368

FPU emulation for ppc gives wrong results for single precision
arithmetic. As described in the PR, I found the fix from FreeBSD:

====
  https://svnweb.freebsd.org/base?view=revision&revision=258250

  Make single precision floating point arithmetic actually work -- I think
  it never did -- and fix an obvious missing line. Floating point emulation
  on Book-E still needs some work but this gets it basically functional on
  soft-FPU systems (hard FPU for Book-E is not yet implemented).

  MFC after:    1 week
====

With this fix, single precision calculations get sane on ibm4xx and
booke as far as I checked.

Thanks,
Rin
====
--- src/sys/arch/powerpc/fpu/fpu_emu.c.orig     2016-07-27 10:04:00.737524067 
+0900
+++ src/sys/arch/powerpc/fpu/fpu_emu.c  2016-07-27 10:03:44.803486129 +0900
@@ -626,9 +626,11 @@
                        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 @@
                                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);
--- src/sys/arch/powerpc/fpu/fpu_explode.c.orig 2016-07-27 10:00:01.060507066 
+0900
+++ src/sys/arch/powerpc/fpu/fpu_explode.c      2016-07-27 10:00:12.431852649 
+0900
@@ -235,6 +235,7 @@
                s = fpu_dtof(fp, s, space[1]);
                break;
+ default:
                panic("fpu_explode");
                panic("fpu_explode: invalid type %d", type);
        }

Reply via email to