This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

egcs-1.1.2, sparc long long bug


Hi,

I would like to report an egcs-1.1.x code generator bug.

The problem occurs both with gcc version egcs-2.91.60 19981201
(egcs-1.1.1 release) and also with gcc version egcs-2.91.66 19990314
(egcs-1.1.2 release) - running on sparc solaris 2.6 and solaris 7

The bug does not occur with gcc version egcs-2.90.29 980515
(egcs-1.0.3 release).


Appended below is small programme that demonstrates the problem.  The
bug happens with the second invocation of function 'bcd' in
'format_vskip'.  Since main calls 'format_vskip' with a parameter
scale==100, the second invocation of 'bcd' should pass 'state->offs+3'
as param #2.  With egcs-1.1.x, the incorrect value 'state->offs+2' is
passed.



	% gcc -v
	Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.7/egcs-2.91.60/specs
	gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)
	% gcc -O -o bug bug.c
	% bug
	offset=80000000
	offset=80000002		<-- 80000003 is expected here

An older release of egcs prints the expteced result:

	% gcc -v
	Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.29/specs
	gcc version egcs-2.90.29 980515 (egcs-1.0.3 release)
	% gcc -O -o bug bug.c
	% bug
	offset=80000000
	offset=80000003
	
-----------------------------------------------
typedef long long ioff_t;
typedef long dimen_t;


struct format_state {
    ioff_t      offs;
    struct io  *io;
    dimen_t     vskip;
    int         sign;
};


int bcd(struct io *io, ioff_t offset, int size) {
    printf("offset=%llx\n", offset);
}


static int format_vskip(struct format_state *state, int scale) {
  int new_vskip;

  new_vskip   = bcd(state->io, state->offs,   scale > 10 ? 3 : 2);
  state->sign = bcd(state->io, state->offs + (scale > 10 ? 3 : 2), 1);
  state->offs += scale > 10 ? 4 : 3;
  return 1;
} /* format_vskip */


main()
{
    static struct format_state state;

    state.offs = 0x80000000LL;
    format_vskip(&state, 100);
}
------------------------------------------------

Here's the generated assemply code from gcc -O -S bug.c:

        .align 4
        .type    format_vskip,#function
        .proc   04
format_vskip:
        !#PROLOGUE# 0
        save %sp,-112,%sp
        !#PROLOGUE# 1
        cmp %i1,10		<-- 1. sets CC for (scale > 10)
        ble .LL3
        mov 2,%o3
        mov 3,%o3
.LL3:
        ld [%i0],%o1
        ld [%i0+4],%o2
        call bcd,0
        ld [%i0+8],%o0
        ldd [%i0],%o4
        addcc %o5,2,%o3		<-- 2. long long addition destroys CC from 1. above
        addx %o4,0,%o2
        ble .LL10		<-- 3. attempts reuse of CC from 1. (but destroyed by 2.)		
        ld [%i0+8],%o0
        addcc %o5,3,%o3
        addx %o4,0,%o2
.LL10:
        mov %o2,%o1
        mov %o3,%o2
        call bcd,0
        mov 1,%o3
        st %o0,[%i0+16]
        cmp %i1,10
        ble .LL7
        ldd [%i0],%o0
        addcc %o1,4,%o1
        b .LL9
        addx %o0,0,%o0
.LL7:
        addcc %o1,3,%o1
        addx %o0,0,%o0
.LL9:
        std %o0,[%i0]
        ret
        restore %g0,1,%o0

-- 
Juergen Keil          		jk@tools.de
Tools GmbH			+49 (228) 9858011


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]