Andrew Haley wrote:
David Daney writes:
 > Richard,
> > Sometime between 1/7 and 1/16 on the trunk I started getting wrong code > on a bunch of java testcases under mipsel-linux. > > It looks related to (but not necessarily caused by) this patch: > > http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01346.html > > For example if we examine the assembler output of the PR9577.java > testcase, we see: > > .
 > .
 > .
 > $LBB2:
 >         lw      $2,40($fp)
 >         sw      $2,24($fp)
 >         lw      $2,24($fp)
 >         move    $4,$2
 >         .option pic0
 >         jal     _ZN4java4lang6ObjectC1Ev
 >         nop
> > .option pic2
 >         lw      $28,16($fp)
 > $LBE2:
 >         move    $sp,$fp
 >         lw      $31,36($sp)
 >         lw      $fp,32($sp)
 >         addiu   $sp,$sp,40
 >         j       $31
 >         nop
> > The call to _ZN4java4lang6ObjectC1Ev is being generated as non-pic, even > though that symbol is defined in libgcj.so. The assembler and linker > conspire to jump to address 0x00000000 for this call. > > It looks like the logic that decides if a symbol is external to the > compilation unit is faulty. > > Any ideas about where it might have gone wrong?

Does http://gcc.gnu.org/ml/gcc/2007-01/msg01184.html fix this?


Unfortunately no. The following output is generated with r121186 + Andrew.s patched class.c

There are several problems with the generated code for the failing class:

public class PR9577
{
  private native void sayHello (String[] s, Object o);

  public static void main (String[] args)
  {
    PR9577 x = new PR9577( );
    x.sayHello( null, null);
  }
}

Note that this class has an implicit public constructor that does nothing other than call the super class (java.lang.Object) constructor.

/home/build/gcc-build/gcc/gcj -v -B/home/build/gcc-build/mipsel-unknown-linux-gnu/libjava/ -B/home/build/gcc-build/gcc/ --encoding=UTF-8 -B/home/build/gcc-build/mipsel-unknown-linux-gnu/libjava/testsuite/../ /home/build/gcc/libjava/testsuite/libjava.cni/PR9577.jar -o j.s -S

Here is the entire generated code for the constructor:

        .globl  _ZN6PR9577C1Ev
        .ent    _ZN6PR9577C1Ev
        .type   _ZN6PR9577C1Ev, @function
_ZN6PR9577C1Ev:
$LFB2:
.frame $fp,40,$31 # vars= 8, regs= 2/0, args= 16, gp= 8
        .mask   0xc0000000,-4
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro

        addiu   $sp,$sp,-40
$LCFI0:
        sw      $31,36($sp)
$LCFI1:
        sw      $fp,32($sp)
$LCFI2:
        move    $fp,$sp
$LCFI3:
        .cprestore      16
        sw      $4,40($fp)
$LBB2:
        lw      $2,40($fp)
        sw      $2,24($fp)
        lw      $2,24($fp)
        move    $4,$2
        .option pic0
        jal     _ZN4java4lang6ObjectC1Ev
        nop

        .option pic2
        lw      $28,16($fp)
$LBE2:
        move    $sp,$fp
        lw      $31,36($sp)
        lw      $fp,32($sp)
        addiu   $sp,$sp,40
        j       $31
        nop

        .set    macro
        .set    reorder
$LFE2:
        .end    _ZN6PR9577C1Ev

Here are the problems I see:

1) The call to _ZN4java4lang6ObjectC1Ev is absolute instead of via the plt. That function is in a shared library not this compilation unit.

2) It is a public global method.  $gp should be initialized, but it is not.

If I compile it with -O3 -mshared I get:

        .globl  _ZN6PR9577C1Ev
        .ent    _ZN6PR9577C1Ev
        .type   _ZN6PR9577C1Ev, @function
_ZN6PR9577C1Ev:
$LFB2:
.frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8
        .mask   0x80000000,-8
        .fmask  0x00000000,0
        .set    noreorder
        .cpload $25
        .set    nomacro

        addiu   $sp,$sp,-32
$LCFI0:
        sw      $31,24($sp)
$LCFI1:
        .cprestore      16
        lw      $25,%call16(_ZN4java4lang6ObjectC1Ev)($28)
        jalr    $25
        nop

        lw      $28,16($sp)
        lw      $31,24($sp)
        j       $31
        addiu   $sp,$sp,32

        .set    macro
        .set    reorder
$LFE2:
        .end    _ZN6PR9577C1Ev

This time the call to _ZN4java4lang6ObjectC1Ev *is* done via the plt, but we are using .cpload instead of having gcc generate the individual instructions and interleaving them with the $sp adjustment as it normally does.

David Daney

Reply via email to