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

Reply via email to