re PR target/56890 (invalid fdtox instruction in 64-bit mode with -O2)
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 15 Apr 2013 08:28:41 +0000 (08:28 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 15 Apr 2013 08:28:41 +0000 (08:28 +0000)
PR target/56890
* config/sparc/sparc.c (enum sparc_mode_class): Add H_MODE value.
(S_MODES): Set H_MODE bit.
(SF_MODES): Set only S_MODE and SF_MODE bits.
(DF_MODES): Set SF_MODES and only D_MODE and DF_MODE bits.
(sparc_init_modes) <MODE_INT>: Set H_MODE bit for sub-word modes.
<MODE_VECTOR_INT>: Do not set SF_MODE for sub-word modes.
<MODE_FLOAT>: Likewise.

From-SVN: r197958

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr56890-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr56890-2.c [new file with mode: 0644]

index 26f460878f17b9040ad02c5f389ae96532425fd2..06d603dfb0eb720ee501deb4e9aaa339fcd45dc0 100644 (file)
@@ -1,3 +1,14 @@
+2013-04-15  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/56890
+       * config/sparc/sparc.c (enum sparc_mode_class): Add H_MODE value.
+       (S_MODES): Set H_MODE bit.
+       (SF_MODES): Set only S_MODE and SF_MODE bits.
+       (DF_MODES): Set SF_MODES and only D_MODE and DF_MODE bits.
+       (sparc_init_modes) <MODE_INT>: Set H_MODE bit for sub-word modes.
+       <MODE_VECTOR_INT>: Do not set SF_MODE for sub-word modes.
+       <MODE_FLOAT>: Likewise.
+
 2013-04-15  Joey Ye  <joey.ye@arm.com>
 
        * config/arm/arm.c (thumb_far_jump_used_p): Fix typo in comments.
index 56b95fe9cffc602b8a651fdcaec7c00396e62ee4..1dc4e3600a8f437137a7b3a722eab3a37ffe5740 100644 (file)
@@ -4467,13 +4467,14 @@ mem_min_alignment (rtx mem, int desired)
    mapped into one sparc_mode_class mode.  */
 
 enum sparc_mode_class {
-  S_MODE, D_MODE, T_MODE, O_MODE,
+  H_MODE, S_MODE, D_MODE, T_MODE, O_MODE,
   SF_MODE, DF_MODE, TF_MODE, OF_MODE,
   CC_MODE, CCFP_MODE
 };
 
 /* Modes for single-word and smaller quantities.  */
-#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
+#define S_MODES \
+  ((1 << (int) H_MODE) | (1 << (int) S_MODE) | (1 << (int) SF_MODE))
 
 /* Modes for double-word and smaller quantities.  */
 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
@@ -4484,13 +4485,11 @@ enum sparc_mode_class {
 /* Modes for 8-word and smaller quantities.  */
 #define O_MODES (T_MODES | (1 << (int) O_MODE) | (1 << (int) OF_MODE))
 
-/* Modes for single-float quantities.  We must allow any single word or
-   smaller quantity.  This is because the fix/float conversion instructions
-   take integer inputs/outputs from the float registers.  */
-#define SF_MODES (S_MODES)
+/* Modes for single-float quantities.  */
+#define SF_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
 
 /* Modes for double-float and smaller quantities.  */
-#define DF_MODES (D_MODES)
+#define DF_MODES (SF_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
 
 /* Modes for quad-float and smaller quantities.  */
 #define TF_MODES (DF_MODES | (1 << (int) TF_MODE))
@@ -4586,7 +4585,9 @@ sparc_init_modes (void)
        case MODE_INT:
        case MODE_PARTIAL_INT:
        case MODE_COMPLEX_INT:
-         if (GET_MODE_SIZE (i) <= 4)
+         if (GET_MODE_SIZE (i) < 4)
+           sparc_mode_class[i] = 1 << (int) H_MODE;
+         else if (GET_MODE_SIZE (i) == 4)
            sparc_mode_class[i] = 1 << (int) S_MODE;
          else if (GET_MODE_SIZE (i) == 8)
            sparc_mode_class[i] = 1 << (int) D_MODE;
@@ -4598,14 +4599,16 @@ sparc_init_modes (void)
            sparc_mode_class[i] = 0;
          break;
        case MODE_VECTOR_INT:
-         if (GET_MODE_SIZE (i) <= 4)
-           sparc_mode_class[i] = 1 << (int)SF_MODE;
+         if (GET_MODE_SIZE (i) == 4)
+           sparc_mode_class[i] = 1 << (int) SF_MODE;
          else if (GET_MODE_SIZE (i) == 8)
-           sparc_mode_class[i] = 1 << (int)DF_MODE;
+           sparc_mode_class[i] = 1 << (int) DF_MODE;
+         else
+           sparc_mode_class[i] = 0;
          break;
        case MODE_FLOAT:
        case MODE_COMPLEX_FLOAT:
-         if (GET_MODE_SIZE (i) <= 4)
+         if (GET_MODE_SIZE (i) == 4)
            sparc_mode_class[i] = 1 << (int) SF_MODE;
          else if (GET_MODE_SIZE (i) == 8)
            sparc_mode_class[i] = 1 << (int) DF_MODE;
index c8d46d5bd630a1ce6c4f95208b3191550724e432..98a2decdd05bdee6bffac5170fe0e0ad238e5d14 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-15  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.dg/pr56890-1.c: New test.
+       * gcc.dg/pr56890-2.c: Likewise.
+
 2013-04-15  Joey Ye  <joey.ye@arm.com>
 
        * gcc.target/arm/thumb1-far-jump-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr56890-1.c b/gcc/testsuite/gcc.dg/pr56890-1.c
new file mode 100644 (file)
index 0000000..93b2134
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/56890 */
+/* Reported by Rainer Jung <rainer.jung@kippdata.de> */
+
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+
+unsigned int buggy(unsigned int min, unsigned int max)
+{
+    if (max < 16384) {
+        unsigned short num16 = 0;
+        num16 = min + (long) ((double) (max - min + 1.0) * (num16 / (65535 + 1.0)));
+        return num16;
+    }
+    return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr56890-2.c b/gcc/testsuite/gcc.dg/pr56890-2.c
new file mode 100644 (file)
index 0000000..474327e
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR target/56890 */
+/* Reported by Rainer Jung <rainer.jung@kippdata.de> */
+
+/* { dg-do assemble } */
+/* { dg-options "-O" } */
+
+unsigned int buggy(unsigned int min, unsigned int max)
+{
+    unsigned int number;
+    if (max < 16384) {
+        unsigned short num16;
+        num16 = min + (long) ((double) (max - min + 1.0) * (num16 / (65535 + 1.0)));
+        return num16;
+    }
+    else {
+        (number) = min + (long) ((double) (max - min + 1.0) * (number / (4294967295U + 1.0)));
+    }
+    return number;
+}