MIPS Wrong-code regression.
David Daney
ddaney@avtrex.com
Wed Jan 31 18:36:00 GMT 2007
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
More information about the Java
mailing list