This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] gen_lowpart fixes for HOST_BITS_PER_WIDE_INT 64, dwarf2 fix for 64bit build hosts


Hi!

This patch tries to fix several bugs I encountered on both sparc and
sparc64, if HOST_BITS_PER_WIDE_INT is 64:
REAL_VALUE_TO_TARGET_*DOUBLE are documented to return array of 2/3/4 longs
where only the low 32bits are filled (hence the computation in dwarf2out.c
looks terribly wrong to me), while if HOST_BITS_PER_WIDE_INT == 64,
gen_lowpart_common assumed all four filled 4 longs, while they in fact
filled first 2 (SF,DF), 3 (XF) or 4 (TF).
Also, the low 32bits of immed_double_const arguments need to be casted to
unsigned long, because otherwise if sizeof(long) == 4 and HOST_WIDE_INT long long
they are incorrect.
Bootstrap on sparc64-redhat-linux is pending.

2000-10-04  Jakub Jelinek  <jakub@redhat.com>

	* emit-rtl.c (gen_lowpart_common) [REAL_ARITHMETICS]: Fix conversion
	from float to integral mode with HOST_BITS_PER_WIDE_INT 64.
	* dwarf2out.c (add_const_value_attribute): Divide by 4, not
	sizeof(long).

--- gcc/emit-rtl.c.jj	Fri Sep 15 16:46:31 2000
+++ gcc/emit-rtl.c	Wed Oct  4 18:03:18 2000
@@ -1055,10 +1055,12 @@ gen_lowpart_common (mode, x)
 	  break;
 #if LONG_DOUBLE_TYPE_SIZE == 96
 	case XFmode:
+	  REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, i + endian);
+	  i[3-3*endian] = 0;
 #else
 	case TFmode:
-#endif
 	  REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, i);
+#endif
 	  break;
 	default:
 	  abort();
@@ -1071,14 +1073,24 @@ gen_lowpart_common (mode, x)
 #else
       if (HOST_BITS_PER_WIDE_INT != 64)
 	abort();
+
       for (c = 0; c < 4; c++)
 	i[c] &= 0xffffffffL;
-      
-      return immed_double_const (i[endian*3] | 
-				 (((HOST_WIDE_INT) i[1+endian]) << 32),
-				 i[2-endian] |
-				 (((HOST_WIDE_INT) i[3-endian*3]) << 32),
-				 mode);
+
+      switch (GET_MODE (x))
+	{
+	case SFmode:
+	case DFmode:
+	  return immed_double_const (((unsigned long) i[endian]) |
+				     (((HOST_WIDE_INT) i[1-endian]) << 32),
+				     0, mode);
+	default:
+	  return immed_double_const (((unsigned long) i[endian*3]) | 
+				     (((HOST_WIDE_INT) i[1+endian]) << 32),
+				     ((unsigned long) i[2-endian]) |
+				     (((HOST_WIDE_INT) i[3-endian*3]) << 32),
+				     mode);
+	}
 #endif
     }
 #endif /* ifndef REAL_ARITHMETIC */
--- gcc/dwarf2out.c.jj	Fri Sep 15 16:46:31 2000
+++ gcc/dwarf2out.c	Wed Oct  4 17:51:48 2000
@@ -7116,7 +7116,7 @@ add_const_value_attribute (die, rtl)
 
 	if (GET_MODE_CLASS (mode) == MODE_FLOAT)
 	  {
-	    register unsigned length = GET_MODE_SIZE (mode) / sizeof (long);
+	    register unsigned length = GET_MODE_SIZE (mode) / 4;
 	    long array[4];
 	    REAL_VALUE_TYPE rv;
 

	Jakub

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]