Is this (gasp) a chip bug?
Jon Ryshpan
jon at hitachi.uucp
Tue Jul 31 06:47:08 AEST 1990
In article <1990Jul23.223341.26431 at cbnewsc.att.com> imdave at cbnewsc.att.com (david.e.bodenstab) writes:
>Here is a little program derived from a problem we tracked down in a
>driver:
>
> main()
> {
> unsigned y = 0x7ffff0ff;
> unsigned x = 0x7ffff000;
>
> while (1) {
> if ( ((int)(y - x)) < 0 )
> printf("WRONG x=%x y=%x (y - x)=%x\n",x,y,y-x);
> x++;
> y++;
> }
> }
>
>This program `fails' on both a 386 and another cpu in-house -- the
>range of values for the `failure' are:
>
> 0x80000000 <= y <= 0x800000fe
> 0x7fffff01 <= x <= 0x7fffffff
>
It's a compiler bug. On the 68020 (Sun 3) I get the following code from
the standard Sun compiler:
L14:
movl a6@(-0x4),d0
subl a6@(-0x8),d0
tstl d0
jge L16
...
jbsr _printf
lea sp@(0x10),sp
L16:
This is correct. Note the key instruction "tstl d0", which is the
result of the cast from unsigned to int.
Under Interactive 386/ix, using the Interactive port of the ATT C
compiler (or whatever is the standard C compiler for 386/ix ver 2.02) I
get this code:
.L16:
movl -4(%ebp),%eax
subl -8(%ebp),%eax
jge .L17
...
call printf
addl $16,%esp
.L17:
This code is wrong since there is no cast from unsigned to int. It's
not possible to fix this by using an unsigned rather than a signed
branch, since this would just substitute one range of values which
produce an incorrect branch for another.
Jonathan Ryshpan <...!uunet!hitachi!jon>
M/S 420 (415) 244-7369
Hitachi America Ltd.
2000 Sierra Pt. Pkwy.
Brisbane CA 94005-1819
More information about the Comp.unix.i386
mailing list