From: Ullrich von Bassewitz (uz_at_musoftware.de)
Date: 2000-01-06 22:47:44
Keith asked me about the integer compare bug. Since this may be interesting for more people here is an explanation. When comparing values, the compiler generated the following code: int a; if (a > 0x1FF) ... lda _a ldx _a+1 cpx #$01 bne *+4 cmp #$FF jsr boolgt The subroutine evaluates the N and Z flags assuming a signed compare greater than and loads a boolean value. The problem is, that the generated code is wrong for signed values: If the high byte of both values is equal, the low byte must be compared, but this must be an unsigned compare, not a signed one. That means, for the high byte, the Z and N flags have to be evaluated, but for the low byte the Z and C flags. As a consequence, the result of the compare was wrong for specific values. These values have the same high byte, and (lhs - rhs) >= $80 So the N flag was set and evaluated in the wrong way. Unfortunately, the same code was used in the runtime library, and the peephole optimizer had several routines looking for this and similar pieces of code, since in many cases the code may be simplified, or the call to the subroutine may be removed. If you look at the code, it seems to be silly, how one can overlook the problem. And I did not only overlook it, I changed the old, slow but working code against a faster non-working one. The current solution is to fix the subroutine in the runtime library, and use it for signed values instead of inlining the code. There are probably solutions that produce faster code, but I was afraid to break anything, so I took the easiest way out. Regards Uz -- Ullrich von Bassewitz uz_at_musoftware.de ---------------------------------------------------------------------- To unsubscribe from the list send mail to majordomo_at_musoftware.de with the string "unsubscribe cc65" in the body(!) of the mail.
This archive was generated by hypermail 2.1.3 : 2001-12-14 22:05:35 CET