This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
egcs-1.1.2, sparc long long bug
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: egcs-1.1.2, sparc long long bug
- From: Juergen Keil <jk at tools dot de>
- Date: Mon, 17 May 1999 15:23:25 +0200 (MET DST)
- Reply-To: Juergen Keil <jk at tools dot de>
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