tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Gcc fix to make sh3 cross-buildable on 64bit build hosts (toolchain/34549)



There's a bug in gcc (still present on the trunk as far as I can tell
from visual inspection of svn trunk/logs) that prevents cross-building
native sh3 compiler on a 64-bit build machine.  I think the problem
affects all build64->host32->target64 setups (superh gcc supports
64-bit sh5, hence target64), but to actually trigger it a machine
description must use large enough constants, which sh3 unfortunately
does.

For details see 

  http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=34549
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32497

Basically the problem is that gen*.c programs (compiled on the build
host and thus pulling auto-build.h) incorrectly use build host wide
int defines to emit constants in C code (insn-*.c) that will be
compiled for the host, where wide int defines can be different.  So
when we cross build on say amd64 where wide int in "long", gen*.c emit
"L" suffix on constants that can be large enough not to fit into
32-bit long of the host. E.g. there's no difference for 1L and 1LL
(hence most other ports survive this mismatch), but e.g. 4294967295L
is too wide for 32-bit long (host wide int is long long).

One organizational fallout from this bug is that, since our releng
autobuild cluster is amd64-only at the moment, sh3 ports haven't been
autobuilt for a long time.

Suggested fix defers suffix choice until insn-*.c are compiled (for
host and thus they see correct auto-host.h defines for wide ints) and
is tiny and unintrusive.  But as it potentially affects all ports, I'd
like to get an ok from toolchain folks before committing it to the
netbsd tree.

SY, Uwe
-- 
uwe%stderr.spb.ru@localhost                       |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen
Index: genemit.c
===================================================================
RCS file: /cvsroot/src/gnu/dist/gcc4/gcc/genemit.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 genemit.c
--- genemit.c   20 Apr 2006 08:34:39 -0000      1.1.1.1
+++ genemit.c   17 Apr 2008 01:59:09 -0000
@@ -251,9 +251,9 @@
        printf ("const_true_rtx");
       else
        {
-         printf ("GEN_INT (");
-         printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
-         printf (")");
+         printf ("GEN_INT (HOST_WIDE_INT_CONSTANT (");
+         printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
+         printf ("))");
        }
       return;
 
Index: genrecog.c
===================================================================
RCS file: /cvsroot/src/gnu/dist/gcc4/gcc/genrecog.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 genrecog.c
--- genrecog.c  20 Apr 2006 08:26:33 -0000      1.1.1.1
+++ genrecog.c  17 Apr 2008 01:59:09 -0000
@@ -1864,11 +1864,13 @@
 static void
 print_host_wide_int (HOST_WIDE_INT val)
 {
+  /* XXX: the "min" below is computed for build, not host!!! */
   HOST_WIDE_INT min = (unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1);
   if (val == min)
-    printf ("(" HOST_WIDE_INT_PRINT_DEC_C "-1)", val + 1);
+    printf ("(HOST_WIDE_INT_CONSTANT (" HOST_WIDE_INT_PRINT_DEC ")-1)",
+           val + 1);
   else
-    printf (HOST_WIDE_INT_PRINT_DEC_C, val);
+    printf ("HOST_WIDE_INT_CONSTANT (" HOST_WIDE_INT_PRINT_DEC")", val);
 }
 
 /* Emit a switch statement, if possible, for an initial sequence of
Index: hwint.h
===================================================================
RCS file: /cvsroot/src/gnu/dist/gcc4/gcc/hwint.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 hwint.h
--- hwint.h     20 Apr 2006 09:07:39 -0000      1.1.1.1
+++ hwint.h     17 Apr 2008 01:59:09 -0000
@@ -72,6 +72,7 @@
 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
 # define HOST_WIDE_INT_PRINT "l"
 # define HOST_WIDE_INT_PRINT_C "L"
+# define HOST_WIDE_INT_CONSTANT(x) x ## L
   /* 'long' might be 32 or 64 bits, and the number of leading zeroes
      must be tweaked accordingly.  */
 # if HOST_BITS_PER_WIDE_INT == 64
@@ -82,6 +83,7 @@
 #else
 # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
 # define HOST_WIDE_INT_PRINT_C "LL"
+# define HOST_WIDE_INT_CONSTANT(x) x ## LL
   /* We can assume that 'long long' is at least 64 bits.  */
 # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
     "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"


Home | Main Index | Thread Index | Old Index