Correct fabs and fneg insns in simulator
authorOleg Endo <oleg.endo@t-online.de>
Fri, 28 Nov 2014 15:39:39 +0000 (19:39 +0400)
committerJoel Brobecker <brobecker@adacore.com>
Fri, 28 Nov 2014 15:44:03 +0000 (19:44 +0400)
It seems that the implementation of the SH fabs and fneg insns in the
simulator is not correct.  They use the FP_UNARY macro which checks the
FPSCR.PR setting and raises an exception if PR = 1 (double precision)
and the register number is not even (i.e. a valid DF reg number).
For normal unary FP insns this is fine.  However, fneg and fabs perform
the same (integer) operations regardless of the FPSCR.PR setting.

This issue initially popped up here
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63260

I've checked some of the failing tests mentioned in GCC PR 63260 above
with the patch applied and the failures go away.

sim/sh/ChangeLog (tiny patch):

* gencode.c (fabs, fneg): Implement as integer operation
instead of using the FP_UNARY macro.

sim/sh/ChangeLog
sim/sh/gencode.c

index 08db573570e929d965586f9f6184f3d01db13753..7d6cf915c6611a12b81b2206d3fe90f78d42aed1 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-14  Oleg Endo <olegendo@gcc.gnu.org>  (tiny patch)
+
+       * gencode.c (fabs, fneg): Implement as integer operation
+       instead of using the FP_UNARY macro.
+
 2014-08-19  Alan Modra  <amodra@gmail.com>
 
        * configure: Regenerate.
index 738b718e23ab86e3a7bda2e665b15d5cf270d177..bc6560460d4190c10538d1b97e77409b3233f96e 100644 (file)
@@ -429,8 +429,14 @@ op tab[] =
 
   /* sh2e */
   { "", "", "fabs <FREG_N>", "1111nnnn01011101",
-    "FP_UNARY (n, fabs);",
-    "/* FIXME: FR (n) &= 0x7fffffff; */",
+    "  union",
+    "  {",
+    "    unsigned int i;",
+    "    float f;",
+    "  } u;",
+    "  u.f = FR (n);",
+    "  u.i &= 0x7fffffff;",
+    "  SET_FR (n, u.f);",
   },
 
   /* sh2e */
@@ -662,7 +668,14 @@ op tab[] =
 
   /* sh2e */
   { "", "", "fneg <FREG_N>", "1111nnnn01001101",
-    "FP_UNARY (n, -);",
+    "  union",
+    "  {",
+    "    unsigned int i;",
+    "    float f;",
+    "  } u;",
+    "  u.f = FR (n);",
+    "  u.i ^= 0x80000000;",
+    "  SET_FR (n, u.f);",
   },
 
   /* sh4a */
This page took 0.028708 seconds and 4 git commands to generate.