Is this (gasp) a chip bug?

Larry Jones scjones at thor.UUCP
Tue Jul 31 00:48:56 AEST 1990


In article <1990Jul23.223341.26431 at cbnewsc.att.com>, imdave at cbnewsc.att.com (david.e.bodenstab) writes:
< 	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
< The assembly instructions generated for both cpu's were:
< 	sub	x from y
< 	bge	skip		# branch greater than or equal
< 	push	args for printf...
< 	call	printf
< skip:

That's a code generation error, although not an obvious one.
Those instructions corresponds to  "if ((int)y - (int)x < 0)"
which is not, of course, what you wanted.  bge fails because
you have taken a large negative number and subtracted a large
positive number which results in a very large negative number
which overflows.  The correct instruction would be bns (branch
not sign) since you really just want to test the sign of the
final result.  I suspect that using a temporary variable to
hold the intermediate result rather than counting on the cast
the compiler will do the right thing.
----
Larry Jones                         UUCP: uunet!sdrc!thor!scjones
SDRC                                      scjones at thor.UUCP
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"This probably just goes to show something, but I sure don't know what."
-Calvin



More information about the Comp.unix.i386 mailing list