Short synopsys:
---------------
You can not build a gcc for MCORE target on a 64-bit system. The bug is
identical for 4.0.2 and 4.1.0 versions of the gcc. The bug lies in the
actual MCORE crosscompiler; if it runs on a 64 bit system it handles
long long constants incorrectly. Minimal code to reproduce the bug
is given.
Long outputs from commands have been broken into short lines.
System (uname -a):
------------------
Linux linux 2.6.13-15-smp #1 SMP Tue Sep 13 14:56:15
UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
Compiler (gcc -v):
------------------
Target: x86_64-suse-linux
Configured with: ../configure --enable-threads=posix --prefix=/usr
--with-local-prefix=/usr/local --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
--enable-languages=c,c++,objc,f95,java,ada --disable-checking
--with-gxx-include-dir=/usr/include/c++/4.0.2 --enable-java-awt=gtk
--disable-libjava-multilib --with-slibdir=/lib64 --with-system-zlib
--enable-shared --enable-__cxa_atexit --without-system-libunwind
--host=x86_64-suse-linux
Thread model: posix
gcc version 4.0.2 20050901 (prerelease) (SUSE Linux)
The bug:
--------
Fresh download of gcc-4.1.0. Then:
~/GNU/gcc-mcore> ../gcc-4.1.0/configure --target=mcore-elf --with-gnu-as
--with-gnu-ld --enable-languages=c
Configure succeeds, typing make successfully builds xgcc.
It starts to build the libraries, and it fails:
/home/zoltan/GNU/gcc-mcore/./gcc/xgcc -B/home/zoltan/GNU/gcc-mcore/./gcc/
-B/usr/local/mcore-elf/bin/ -B/usr/local/mcore-elf/lib/
-isystem /usr/local/mcore-elf/include
-isystem /usr/local/mcore-elf/sys-include -O2 -O2 -g -O2
-DIN_GCC -DCROSS_COMPILE -DDONT_HAVE_STDIO -DDONT_HAVE_SETJMP
-Dinhibit_libc -W -Wall -Wwrite-strings -Wstrict-prototypes
-Wmissing-prototypes -Wold-style-definition -isystem ./include
-O3 -DNO_FLOATLIB_FIXUNSDFSI -g -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED
-Dinhibit_libc -I. -I. -I../../gcc-4.1.0/gcc -I../../gcc-4.1.0/gcc/.
-I../../gcc-4.1.0/gcc/../include -I../../gcc-4.1.0/gcc/../libcpp/include
-DL_floatdisf -c ../../gcc-4.1.0/gcc/libgcc2.c -o libgcc/./_floatdisf.o
/tmp/ccdhETch.s: Assembler messages:
/tmp/ccdhETch.s:38: Error: operand must be absolute in range 1..32, not 53
make[3]: *** [libgcc/./_floatdisf.o] Error 1
make[3]: Leaving directory `/home/zoltan/GNU/gcc-mcore/gcc'
make[2]: *** [stmp-multilib] Error 2
make[2]: Leaving directory `/home/zoltan/GNU/gcc-mcore/gcc'
make[1]: *** [all-gcc] Error 2
make[1]: Leaving directory `/home/zoltan/GNU/gcc-mcore'
make: *** [all] Error 2
Examining the assembler output that fails:
.file "libgcc2.c"
.section .debug_abbrev
.Ldebug_abbrev0:
.section .debug_info
.Ldebug_info0:
.section .debug_line
.Ldebug_line0:
.text
.Ltext0:
.import __floatsidf
.import __muldf3
.import __adddf3
.import __truncdfsf2
.section .rodata.cst8
.align 3
.LC0:
.long 0
.long 1106247680
.text
.align 1
.export __floatdisf
.type __floatdisf, @function
__floatdisf:
.LFB2:
.LM1:
.LVL0:
subi sp,32
stw r15,(sp)
stw r13,(sp,4)
stw r12,(sp,8)
stw r11,(sp,12)
stw r10,(sp,16)
stw r9,(sp,20)
stw r8,(sp,24)
mov r12,r2
mov r13,r3
.LM2:
bmaski r4,53 <- THIS IS THE ERRONEOUS INSN
movi r5,0
cmplt r4,r4
addc r4,r2
addc r5,r3
bmaski r7,22 // 4194303 0x3fffff
and so on
The C code in the library (libgcc2.c), which actually gets compiled,
looks like this:
if (DF_SIZE < DI_SIZE
&& DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
{
if (! (- ((DWtype) 1 << DF_SIZE) < u
&& u < ((DWtype) 1 << DF_SIZE)))
{
if ((UDWtype) u & (REP_BIT - 1))
{
u &= ~ (REP_BIT - 1);
u |= REP_BIT;
}
}
}
After running through the preprocessor ( with xgcc -E ) the actual C code looks
like this:
#pragma GCC visibility pop
# 44 "../../gcc-4.1.0/gcc/libgcc2.c" 2
# 1352 "../../gcc-4.1.0/gcc/libgcc2.c"
SFtype
__floatdisf (DItype u)
{
# 1378 "../../gcc-4.1.0/gcc/libgcc2.c"
if (53 < ((4 * 8) * 2)
&& 53 > (((4 * 8) * 2) - 53 + 24))
{
if (! (- ((DItype) 1 << 53) < u /* THIS GENERATES THE ERROR */
&& u < ((DItype) 1 << 53)))
{
if ((UDItype) u & (((UDItype) 1 << (((4 * 8) * 2) - 53)) - 1))
{
u &= ~ (((UDItype) 1 << (((4 * 8) * 2) - 53)) - 1);
u |= ((UDItype) 1 << (((4 * 8) * 2) - 53));
}
}
Further examination reveals a bug in xgcc itself, the following very short
code fragment generates the erroneous assembly insn:
long long XgccBug( long long a )
{
return( a & 0x1ffffffffLL );
}
results in the following (erroneous) assembly code:
.file "x.c"
.text
.align 1
.export XgccBug
.type XgccBug, @function
XgccBug:
bmaski r6,33
movi r7,0
and r2,r6
and r3,r7
jmp r15
.size XgccBug, .-XgccBug
Since the compiler can be built successfully on a 32-bit system, the error
probably is that gcc/config/mcore.c somewhere assumes that the target and
the host integers are the same size. I don't understand gcc's internals
enough to work out the exact location/reason/fix of the bug.
Zoltan
--
Summary: On a 64 bit system the generated crosscompiler generates
invalid assembly
Product: gcc
Version: 4.1.0
Status: UNCONFIRMED
Severity: blocker
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: zoltan at bendor dot com dot au
GCC host triplet: x86_64-suse-linux
GCC target triplet: mcore-elf-unknown
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26894