mirror of
https://github.com/cc65/cc65.git
synced 2024-07-09 01:28:58 +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
@ -676,26 +676,26 @@ void g_getimmed (unsigned Flags, unsigned long Val, long Offs)
|
|||||||
AddCodeLine ("stx sreg+1");
|
AddCodeLine ("stx sreg+1");
|
||||||
Done |= 0x08;
|
Done |= 0x08;
|
||||||
}
|
}
|
||||||
if ((Done & 0x04) == 0 && B1 != B3) {
|
if ((Done & 0x04) == 0 && B1 != B3) {
|
||||||
AddCodeLine ("lda #$%02X", B3);
|
AddCodeLine ("lda #$%02X", B3);
|
||||||
AddCodeLine ("sta sreg");
|
AddCodeLine ("sta sreg");
|
||||||
Done |= 0x04;
|
Done |= 0x04;
|
||||||
}
|
}
|
||||||
if ((Done & 0x08) == 0 && B1 != B4) {
|
if ((Done & 0x08) == 0 && B1 != B4) {
|
||||||
AddCodeLine ("lda #$%02X", B4);
|
AddCodeLine ("lda #$%02X", B4);
|
||||||
AddCodeLine ("sta sreg+1");
|
AddCodeLine ("sta sreg+1");
|
||||||
Done |= 0x08;
|
Done |= 0x08;
|
||||||
}
|
}
|
||||||
AddCodeLine ("lda #$%02X", B1);
|
AddCodeLine ("lda #$%02X", B1);
|
||||||
Done |= 0x01;
|
Done |= 0x01;
|
||||||
if ((Done & 0x04) == 0) {
|
if ((Done & 0x04) == 0) {
|
||||||
CHECK (B1 == B3);
|
CHECK (B1 == B3);
|
||||||
AddCodeLine ("sta sreg");
|
AddCodeLine ("sta sreg");
|
||||||
}
|
}
|
||||||
if ((Done & 0x08) == 0) {
|
if ((Done & 0x08) == 0) {
|
||||||
CHECK (B1 == B4);
|
CHECK (B1 == B4);
|
||||||
AddCodeLine ("sta sreg+1");
|
AddCodeLine ("sta sreg+1");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -706,12 +706,12 @@ void g_getimmed (unsigned Flags, unsigned long Val, long Offs)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Some sort of label */
|
/* Some sort of label */
|
||||||
const char* Label = GetLabelName (Flags, Val, Offs);
|
const char* Label = GetLabelName (Flags, Val, Offs);
|
||||||
|
|
||||||
/* Load the address into the primary */
|
/* Load the address into the primary */
|
||||||
AddCodeLine ("lda #<(%s)", Label);
|
AddCodeLine ("lda #<(%s)", Label);
|
||||||
AddCodeLine ("ldx #>(%s)", Label);
|
AddCodeLine ("ldx #>(%s)", Label);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3492,84 +3492,58 @@ void g_lt (unsigned flags, unsigned long val)
|
|||||||
*/
|
*/
|
||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
|
|
||||||
/* Give a warning in some special cases */
|
/* Because the handling of the overflow flag is too complex for
|
||||||
if ((flags & CF_UNSIGNED) && val == 0) {
|
* inlining, we can handle only unsigned compares here.
|
||||||
Warning ("Condition is never true");
|
*/
|
||||||
AddCodeLine ("jsr return0");
|
if (flags & CF_UNSIGNED) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look at the type */
|
/* Give a warning in some special cases */
|
||||||
switch (flags & CF_TYPE) {
|
if (val == 0) {
|
||||||
|
Warning ("Condition is never true");
|
||||||
|
AddCodeLine ("jsr return0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case CF_CHAR:
|
/* Look at the type */
|
||||||
if (flags & CF_FORCECHAR) {
|
switch (flags & CF_TYPE) {
|
||||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
|
||||||
if (flags & CF_UNSIGNED) {
|
|
||||||
AddCodeLine ("jsr boolult");
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr boollt");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
case CF_INT:
|
case CF_CHAR:
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_FORCECHAR) {
|
||||||
/* Unsigned compare */
|
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||||
/* If the low byte is zero, we must only test the high byte */
|
AddCodeLine ("jsr boolult");
|
||||||
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
return;
|
||||||
if ((val & 0xFF) != 0) {
|
}
|
||||||
unsigned L = GetLocalLabel();
|
/* FALLTHROUGH */
|
||||||
AddCodeLine ("bne %s", LocalLabelName (L));
|
|
||||||
AddCodeLine ("cmp #$%02X", (unsigned char)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:
|
case CF_INT:
|
||||||
if ((flags & CF_UNSIGNED) == 0 && val == 0) {
|
/* If the low byte is zero, we must only test the high byte */
|
||||||
/* If we have a signed compare against zero, we only need to
|
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
||||||
* test the high byte.
|
if ((val & 0xFF) != 0) {
|
||||||
*/
|
unsigned L = GetLocalLabel();
|
||||||
AddCodeLine ("lda sreg+1");
|
AddCodeLine ("bne %s", LocalLabelName (L));
|
||||||
} else {
|
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||||
/* Do a subtraction */
|
g_defcodelabel (L);
|
||||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
}
|
||||||
AddCodeLine ("txa");
|
AddCodeLine ("jsr boolult");
|
||||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
|
return;
|
||||||
AddCodeLine ("lda sreg");
|
|
||||||
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:
|
case CF_LONG:
|
||||||
typeerror (flags);
|
/* Do a subtraction */
|
||||||
}
|
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||||
|
AddCodeLine ("txa");
|
||||||
|
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
|
||||||
|
AddCodeLine ("lda sreg");
|
||||||
|
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 16));
|
||||||
|
AddCodeLine ("lda sreg+1");
|
||||||
|
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 24));
|
||||||
|
AddCodeLine ("jsr boolult");
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
typeerror (flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
||||||
* into the normal, non-optimized stuff.
|
* into the normal, non-optimized stuff.
|
||||||
@ -3591,7 +3565,7 @@ void g_le (unsigned flags, unsigned long val)
|
|||||||
"tosle00", "toslea0", "tosleax",
|
"tosle00", "toslea0", "tosleax",
|
||||||
"tosule00", "tosulea0", "tosuleax",
|
"tosule00", "tosulea0", "tosuleax",
|
||||||
0, 0, "tosleeax",
|
0, 0, "tosleeax",
|
||||||
0, 0, "tosuleeax",
|
0, 0, "tosuleeax",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -3606,92 +3580,92 @@ void g_le (unsigned flags, unsigned long val)
|
|||||||
case CF_CHAR:
|
case CF_CHAR:
|
||||||
if (flags & CF_FORCECHAR) {
|
if (flags & CF_FORCECHAR) {
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
/* Unsigned compare */
|
/* Unsigned compare */
|
||||||
if (val < 0xFF) {
|
if (val < 0xFF) {
|
||||||
/* Use < instead of <= because the former gives
|
/* Use < instead of <= because the former gives
|
||||||
* better code on the 6502 than the latter.
|
* better code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_lt (flags, val+1);
|
g_lt (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Always true */
|
/* Always true */
|
||||||
Warning ("Condition is always true");
|
Warning ("Condition is always true");
|
||||||
AddCodeLine ("jsr return1");
|
AddCodeLine ("jsr return1");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Signed compare */
|
/* Signed compare */
|
||||||
if ((long) val < 0x7F) {
|
if ((long) val < 0x7F) {
|
||||||
/* Use < instead of <= because the former gives
|
/* Use < instead of <= because the former gives
|
||||||
* better code on the 6502 than the latter.
|
* better code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_lt (flags, val+1);
|
g_lt (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Always true */
|
/* Always true */
|
||||||
Warning ("Condition is always true");
|
Warning ("Condition is always true");
|
||||||
AddCodeLine ("jsr return1");
|
AddCodeLine ("jsr return1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case CF_INT:
|
case CF_INT:
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
/* Unsigned compare */
|
/* Unsigned compare */
|
||||||
if (val < 0xFFFF) {
|
if (val < 0xFFFF) {
|
||||||
/* Use < instead of <= because the former gives
|
/* Use < instead of <= because the former gives
|
||||||
* better code on the 6502 than the latter.
|
* better code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_lt (flags, val+1);
|
g_lt (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Always true */
|
/* Always true */
|
||||||
Warning ("Condition is always true");
|
Warning ("Condition is always true");
|
||||||
AddCodeLine ("jsr return1");
|
AddCodeLine ("jsr return1");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Signed compare */
|
/* Signed compare */
|
||||||
if ((long) val < 0x7FFF) {
|
if ((long) val < 0x7FFF) {
|
||||||
g_lt (flags, val+1);
|
g_lt (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Always true */
|
/* Always true */
|
||||||
Warning ("Condition is always true");
|
Warning ("Condition is always true");
|
||||||
AddCodeLine ("jsr return1");
|
AddCodeLine ("jsr return1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CF_LONG:
|
case CF_LONG:
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
/* Unsigned compare */
|
/* Unsigned compare */
|
||||||
if (val < 0xFFFFFFFF) {
|
if (val < 0xFFFFFFFF) {
|
||||||
/* Use < instead of <= because the former gives
|
/* Use < instead of <= because the former gives
|
||||||
* better code on the 6502 than the latter.
|
* better code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_lt (flags, val+1);
|
g_lt (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Always true */
|
/* Always true */
|
||||||
Warning ("Condition is always true");
|
Warning ("Condition is always true");
|
||||||
AddCodeLine ("jsr return1");
|
AddCodeLine ("jsr return1");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Signed compare */
|
/* Signed compare */
|
||||||
if ((long) val < 0x7FFFFFFF) {
|
if ((long) val < 0x7FFFFFFF) {
|
||||||
g_lt (flags, val+1);
|
g_lt (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Always true */
|
/* Always true */
|
||||||
Warning ("Condition is always true");
|
Warning ("Condition is always true");
|
||||||
AddCodeLine ("jsr return1");
|
AddCodeLine ("jsr return1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
typeerror (flags);
|
typeerror (flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
||||||
* into the normal, non-optimized stuff.
|
* into the normal, non-optimized stuff.
|
||||||
*/
|
*/
|
||||||
g_push (flags & ~CF_CONST, 0);
|
g_push (flags & ~CF_CONST, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3707,8 +3681,8 @@ void g_gt (unsigned flags, unsigned long val)
|
|||||||
static char* ops [12] = {
|
static char* ops [12] = {
|
||||||
"tosgt00", "tosgta0", "tosgtax",
|
"tosgt00", "tosgta0", "tosgtax",
|
||||||
"tosugt00", "tosugta0", "tosugtax",
|
"tosugt00", "tosugta0", "tosugtax",
|
||||||
0, 0, "tosgteax",
|
0, 0, "tosgteax",
|
||||||
0, 0, "tosugteax",
|
0, 0, "tosugteax",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -3724,32 +3698,32 @@ void g_gt (unsigned flags, unsigned long val)
|
|||||||
if (flags & CF_FORCECHAR) {
|
if (flags & CF_FORCECHAR) {
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
/* If we have a compare > 0, we will replace it by
|
/* If we have a compare > 0, we will replace it by
|
||||||
* != 0 here, since both are identical but the
|
* != 0 here, since both are identical but the
|
||||||
* latter is easier to optimize.
|
* latter is easier to optimize.
|
||||||
*/
|
*/
|
||||||
g_ne (flags, val);
|
g_ne (flags, val);
|
||||||
} else if (val < 0xFF) {
|
} else if (val < 0xFF) {
|
||||||
/* Use >= instead of > because the former gives
|
/* Use >= instead of > because the former gives
|
||||||
* better code on the 6502 than the latter.
|
* better code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_ge (flags, val+1);
|
g_ge (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Never true */
|
/* Never true */
|
||||||
Warning ("Condition is never true");
|
Warning ("Condition is never true");
|
||||||
AddCodeLine ("jsr return0");
|
AddCodeLine ("jsr return0");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((long) val < 0x7F) {
|
if ((long) val < 0x7F) {
|
||||||
/* Use >= instead of > because the former gives
|
/* Use >= instead of > because the former gives
|
||||||
* better code on the 6502 than the latter.
|
* better code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_ge (flags, val+1);
|
g_ge (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Never true */
|
/* Never true */
|
||||||
Warning ("Condition is never true");
|
Warning ("Condition is never true");
|
||||||
AddCodeLine ("jsr return0");
|
AddCodeLine ("jsr return0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3757,74 +3731,74 @@ void g_gt (unsigned flags, unsigned long val)
|
|||||||
|
|
||||||
case CF_INT:
|
case CF_INT:
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
/* Unsigned compare */
|
/* Unsigned compare */
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
/* If we have a compare > 0, we will replace it by
|
/* If we have a compare > 0, we will replace it by
|
||||||
* != 0 here, since both are identical but the latter
|
* != 0 here, since both are identical but the latter
|
||||||
* is easier to optimize.
|
* is easier to optimize.
|
||||||
*/
|
*/
|
||||||
g_ne (flags, val);
|
g_ne (flags, val);
|
||||||
} else if (val < 0xFFFF) {
|
} else if (val < 0xFFFF) {
|
||||||
/* Use >= instead of > because the former gives better
|
/* Use >= instead of > because the former gives better
|
||||||
* code on the 6502 than the latter.
|
* code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_ge (flags, val+1);
|
g_ge (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Never true */
|
/* Never true */
|
||||||
Warning ("Condition is never true");
|
Warning ("Condition is never true");
|
||||||
AddCodeLine ("jsr return0");
|
AddCodeLine ("jsr return0");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Signed compare */
|
/* Signed compare */
|
||||||
if ((long) val < 0x7FFF) {
|
if ((long) val < 0x7FFF) {
|
||||||
g_ge (flags, val+1);
|
g_ge (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Never true */
|
/* Never true */
|
||||||
Warning ("Condition is never true");
|
Warning ("Condition is never true");
|
||||||
AddCodeLine ("jsr return0");
|
AddCodeLine ("jsr return0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CF_LONG:
|
case CF_LONG:
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
/* Unsigned compare */
|
/* Unsigned compare */
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
/* If we have a compare > 0, we will replace it by
|
/* If we have a compare > 0, we will replace it by
|
||||||
* != 0 here, since both are identical but the latter
|
* != 0 here, since both are identical but the latter
|
||||||
* is easier to optimize.
|
* is easier to optimize.
|
||||||
*/
|
*/
|
||||||
g_ne (flags, val);
|
g_ne (flags, val);
|
||||||
} else if (val < 0xFFFFFFFF) {
|
} else if (val < 0xFFFFFFFF) {
|
||||||
/* Use >= instead of > because the former gives better
|
/* Use >= instead of > because the former gives better
|
||||||
* code on the 6502 than the latter.
|
* code on the 6502 than the latter.
|
||||||
*/
|
*/
|
||||||
g_ge (flags, val+1);
|
g_ge (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Never true */
|
/* Never true */
|
||||||
Warning ("Condition is never true");
|
Warning ("Condition is never true");
|
||||||
AddCodeLine ("jsr return0");
|
AddCodeLine ("jsr return0");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Signed compare */
|
/* Signed compare */
|
||||||
if ((long) val < 0x7FFFFFFF) {
|
if ((long) val < 0x7FFFFFFF) {
|
||||||
g_ge (flags, val+1);
|
g_ge (flags, val+1);
|
||||||
} else {
|
} else {
|
||||||
/* Never true */
|
/* Never true */
|
||||||
Warning ("Condition is never true");
|
Warning ("Condition is never true");
|
||||||
AddCodeLine ("jsr return0");
|
AddCodeLine ("jsr return0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
typeerror (flags);
|
typeerror (flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
||||||
* into the normal, non-optimized stuff.
|
* into the normal, non-optimized stuff.
|
||||||
*/
|
*/
|
||||||
g_push (flags & ~CF_CONST, 0);
|
g_push (flags & ~CF_CONST, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3850,84 +3824,58 @@ void g_ge (unsigned flags, unsigned long val)
|
|||||||
*/
|
*/
|
||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
|
|
||||||
/* Give a warning in some special cases */
|
/* Because the handling of the overflow flag is too complex for
|
||||||
if ((flags & CF_UNSIGNED) && val == 0) {
|
* inlining, we can handle only unsigned compares here.
|
||||||
Warning ("Condition is always true");
|
*/
|
||||||
AddCodeLine ("jsr return1");
|
if (flags & CF_UNSIGNED) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look at the type */
|
/* Give a warning in some special cases */
|
||||||
switch (flags & CF_TYPE) {
|
if (val == 0) {
|
||||||
|
Warning ("Condition is always true");
|
||||||
|
AddCodeLine ("jsr return1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case CF_CHAR:
|
/* Look at the type */
|
||||||
if (flags & CF_FORCECHAR) {
|
switch (flags & CF_TYPE) {
|
||||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
|
||||||
if (flags & CF_UNSIGNED) {
|
|
||||||
AddCodeLine ("jsr booluge");
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr boolge");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
case CF_INT:
|
case CF_CHAR:
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_FORCECHAR) {
|
||||||
/* Unsigned compare */
|
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||||
/* If the low byte is zero, we must only test the high byte */
|
AddCodeLine ("jsr booluge");
|
||||||
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
return;
|
||||||
if ((val & 0xFF) != 0) {
|
}
|
||||||
unsigned L = GetLocalLabel();
|
/* FALLTHROUGH */
|
||||||
AddCodeLine ("bne %s", LocalLabelName (L));
|
|
||||||
AddCodeLine ("cmp #$%02X", (unsigned char)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:
|
case CF_INT:
|
||||||
if ((flags & CF_UNSIGNED) == 0 && val == 0) {
|
/* If the low byte is zero, we must only test the high byte */
|
||||||
/* If we have a signed compare against zero, we only need to
|
AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
|
||||||
* test the high byte.
|
if ((val & 0xFF) != 0) {
|
||||||
*/
|
unsigned L = GetLocalLabel();
|
||||||
AddCodeLine ("lda sreg+1");
|
AddCodeLine ("bne %s", LocalLabelName (L));
|
||||||
} else {
|
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||||
/* Do a subtraction */
|
g_defcodelabel (L);
|
||||||
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
}
|
||||||
AddCodeLine ("txa");
|
AddCodeLine ("jsr booluge");
|
||||||
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
|
return;
|
||||||
AddCodeLine ("lda sreg");
|
|
||||||
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:
|
case CF_LONG:
|
||||||
typeerror (flags);
|
/* Do a subtraction */
|
||||||
}
|
AddCodeLine ("cmp #$%02X", (unsigned char)val);
|
||||||
|
AddCodeLine ("txa");
|
||||||
|
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
|
||||||
|
AddCodeLine ("lda sreg");
|
||||||
|
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 16));
|
||||||
|
AddCodeLine ("lda sreg+1");
|
||||||
|
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 24));
|
||||||
|
AddCodeLine ("jsr booluge");
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
typeerror (flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
/* If we go here, we didn't emit code. Push the lhs on stack and fall
|
||||||
* into the normal, non-optimized stuff.
|
* into the normal, non-optimized stuff.
|
||||||
|
Loading…
Reference in New Issue
Block a user