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]
Other format: [Raw text]

[Patch] Fix bad code in constant pool that effects MIPS n32 ABI.


When testing libgcj with mips64/n32 I was getting FAILures on the
majority of the -findirect-dispatch tests.  This was caused by bad code
in the constant pool that only effects big-endian targets with
BITS_PER_WORD > 32 and POINTER_SIZE == 32.  As far as I know mips64/n32
is the only ABI that fits these criteria.

The root of the problem is that we have to calculate where to place a 32
bit value in a union of a pointer and a 32 bit int.  For big-endian
systems with 64 bit pointers the value must be shifted so that it can be
read out of the 32 bit int.  The calculation that was doing this
erroneously assumed that BITS_PER_WORD == POINTER_SIZE.  The fix is to
use POINTER_SIZE for the calculation.

Spot checked on mips64/{n32/n64} and fully regression tested on
x86_64-pc-linxu-gnu with both native and -m32 ABIs.

OK to commit?

2007-11-16  David Daney  <ddaney@avtrex.com>
        Andrew Haley  <aph@redhat.com>

    * constants.c (build_constants_constructor):  Use POINTER_SIZE
    insead of BITS_PER_WORD in big-endian work around.

Index: gcc/java/constants.c
===================================================================
--- gcc/java/constants.c	(revision 130154)
+++ gcc/java/constants.c	(working copy)
@@ -518,13 +518,13 @@ build_constants_constructor (void)
 	{
 	  unsigned HOST_WIDE_INT temp = outgoing_cpool->data[i].w;
 
-	  /* Make sure that on a 64-bit big-endian machine this
-	     32-bit jint appears in the first word.  
+	  /* Make sure that on a big-endian machine with 64-bit
+	     pointers this 32-bit jint appears in the first word.
 	     FIXME: This is a kludge.  The field we're initializing is
 	     not a scalar but a union, and that's how we should
 	     represent it in the compiler.  We should fix this.  */
-	  if (BYTES_BIG_ENDIAN && BITS_PER_WORD > 32)
-	    temp <<= BITS_PER_WORD - 32;
+	  if (BYTES_BIG_ENDIAN && POINTER_SIZE > 32)
+	    temp <<= POINTER_SIZE - 32;
 
 	  tags_list
 	    = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),

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