mirror of
https://github.com/cc65/cc65.git
synced 2025-02-13 12:30:40 +00:00
Fixed a bug in signed int compares
git-svn-id: svn://svn.cc65.org/cc65/trunk@2483 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
9a2b4dc849
commit
923ae328a5
@ -3492,8 +3492,13 @@ void g_lt (unsigned flags, unsigned long val)
|
||||
*/
|
||||
if (flags & CF_CONST) {
|
||||
|
||||
/* Because the handling of the overflow flag is too complex for
|
||||
* inlining, we can handle only unsigned compares here.
|
||||
*/
|
||||
if (flags & CF_UNSIGNED) {
|
||||
|
||||
/* Give a warning in some special cases */
|
||||
if ((flags & CF_UNSIGNED) && val == 0) {
|
||||
if (val == 0) {
|
||||
Warning ("Condition is never true");
|
||||
AddCodeLine ("jsr return0");
|
||||
return;
|
||||
@ -3505,18 +3510,12 @@ void g_lt (unsigned flags, unsigned long val)
|
||||
case CF_CHAR:
|
||||
if (flags & CF_FORCECHAR) {
|
||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("jsr boolult");
|
||||
} else {
|
||||
AddCodeLine ("jsr boollt");
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case CF_INT:
|
||||
if (flags & CF_UNSIGNED) {
|
||||
/* Unsigned compare */
|
||||
/* If the low byte is zero, we must only test the high byte */
|
||||
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
||||
if ((val & 0xFF) != 0) {
|
||||
@ -3526,28 +3525,9 @@ void g_lt (unsigned flags, unsigned long val)
|
||||
g_defcodelabel (L);
|
||||
}
|
||||
AddCodeLine ("jsr boolult");
|
||||
} else {
|
||||
/* Signed compare */
|
||||
if ((val & 0xFF) == 0) {
|
||||
/* Low byte is zero, just look at the high byte */
|
||||
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
||||
} else {
|
||||
/* Subtract the two values */
|
||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||
AddCodeLine ("txa");
|
||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
|
||||
}
|
||||
AddCodeLine ("jsr boollt");
|
||||
}
|
||||
return;
|
||||
|
||||
case CF_LONG:
|
||||
if ((flags & CF_UNSIGNED) == 0 && val == 0) {
|
||||
/* If we have a signed compare against zero, we only need to
|
||||
* test the high byte.
|
||||
*/
|
||||
AddCodeLine ("lda sreg+1");
|
||||
} else {
|
||||
/* Do a subtraction */
|
||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||
AddCodeLine ("txa");
|
||||
@ -3556,21 +3536,15 @@ void g_lt (unsigned flags, unsigned long val)
|
||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 16));
|
||||
AddCodeLine ("lda sreg+1");
|
||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 24));
|
||||
}
|
||||
/* Emit the proper makebool routine */
|
||||
if (flags & CF_UNSIGNED) {
|
||||
/* Unsigned compare */
|
||||
AddCodeLine ("jsr boolult");
|
||||
} else {
|
||||
/* Signed compare */
|
||||
AddCodeLine ("jsr boollt");
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
typeerror (flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
||||
* into the normal, non-optimized stuff.
|
||||
*/
|
||||
@ -3850,8 +3824,13 @@ void g_ge (unsigned flags, unsigned long val)
|
||||
*/
|
||||
if (flags & CF_CONST) {
|
||||
|
||||
/* Because the handling of the overflow flag is too complex for
|
||||
* inlining, we can handle only unsigned compares here.
|
||||
*/
|
||||
if (flags & CF_UNSIGNED) {
|
||||
|
||||
/* Give a warning in some special cases */
|
||||
if ((flags & CF_UNSIGNED) && val == 0) {
|
||||
if (val == 0) {
|
||||
Warning ("Condition is always true");
|
||||
AddCodeLine ("jsr return1");
|
||||
return;
|
||||
@ -3863,18 +3842,12 @@ void g_ge (unsigned flags, unsigned long val)
|
||||
case CF_CHAR:
|
||||
if (flags & CF_FORCECHAR) {
|
||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("jsr booluge");
|
||||
} else {
|
||||
AddCodeLine ("jsr boolge");
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case CF_INT:
|
||||
if (flags & CF_UNSIGNED) {
|
||||
/* Unsigned compare */
|
||||
/* If the low byte is zero, we must only test the high byte */
|
||||
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
||||
if ((val & 0xFF) != 0) {
|
||||
@ -3884,28 +3857,9 @@ void g_ge (unsigned flags, unsigned long val)
|
||||
g_defcodelabel (L);
|
||||
}
|
||||
AddCodeLine ("jsr booluge");
|
||||
} else {
|
||||
/* Signed compare */
|
||||
if ((val & 0xFF) == 0) {
|
||||
/* Low byte is zero, just look at the high byte */
|
||||
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
||||
} else {
|
||||
/* Subtract the two values */
|
||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||
AddCodeLine ("txa");
|
||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
|
||||
}
|
||||
AddCodeLine ("jsr boolge");
|
||||
}
|
||||
return;
|
||||
|
||||
case CF_LONG:
|
||||
if ((flags & CF_UNSIGNED) == 0 && val == 0) {
|
||||
/* If we have a signed compare against zero, we only need to
|
||||
* test the high byte.
|
||||
*/
|
||||
AddCodeLine ("lda sreg+1");
|
||||
} else {
|
||||
/* Do a subtraction */
|
||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||
AddCodeLine ("txa");
|
||||
@ -3914,21 +3868,15 @@ void g_ge (unsigned flags, unsigned long val)
|
||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 16));
|
||||
AddCodeLine ("lda sreg+1");
|
||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 24));
|
||||
}
|
||||
/* Emit the proper makebool routine */
|
||||
if (flags & CF_UNSIGNED) {
|
||||
/* Unsigned compare */
|
||||
AddCodeLine ("jsr booluge");
|
||||
} else {
|
||||
/* Signed compare */
|
||||
AddCodeLine ("jsr boolge");
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
typeerror (flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
||||
* into the normal, non-optimized stuff.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user