- /* Give a warning in some special cases */
- if ((flags & CF_UNSIGNED) && val == 0) {
- Warning ("Condition is never true");
- }
-
- /* Look at the type */
- switch (flags & CF_TYPE) {
-
- 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) == 0 && val == 0) {
- /* If we have a signed compare against zero, we only need to
- * test the high byte.
- */
- AddCodeLine ("txa");
- AddCodeLine ("jsr boollt");
- return;
- }
- /* Direct code only for unsigned data types */
- if (flags & CF_UNSIGNED) {
- unsigned L = GetLocalLabel();
- AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
- AddCodeLine ("bne %s", LocalLabelName (L));
- AddCodeLine ("cmp #$%02X", (unsigned char)val);
- g_defcodelabel (L);
- AddCodeLine ("jsr boolult");
- return;
- }
- break;
-
- 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");
- AddCodeLine ("jsr boollt");
- return;
- }
- break;
-
- 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.
- */
- g_push (flags & ~CF_CONST, 0);
-
+ /* Because the handling of the overflow flag is too complex for
+ * inlining, we can handle only unsigned compares, and signed
+ * compares against zero here.
+ */
+ if (flags & CF_UNSIGNED) {
+
+ /* Give a warning in some special cases */
+ if (val == 0) {
+ Warning ("Condition is never true");
+ AddCodeLine ("jsr return0");
+ return;
+ }
+
+ /* Look at the type */
+ switch (flags & CF_TYPE) {
+
+ case CF_CHAR:
+ if (flags & CF_FORCECHAR) {
+ AddCodeLine ("cmp #$%02X", (unsigned char)val);
+ AddCodeLine ("jsr boolult");
+ return;
+ }
+ /* FALLTHROUGH */
+
+ case CF_INT:
+ /* If the low byte is zero, we must only test the high byte */
+ AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8));
+ if ((val & 0xFF) != 0) {
+ unsigned L = GetLocalLabel();
+ AddCodeLine ("bne %s", LocalLabelName (L));
+ AddCodeLine ("cmp #$%02X", (unsigned char)val);
+ g_defcodelabel (L);
+ }
+ AddCodeLine ("jsr boolult");
+ return;
+
+ case CF_LONG:
+ /* 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);
+ }
+
+ } else if (val == 0) {
+
+ /* A signed compare against zero must only look at the sign bit */
+ switch (flags & CF_TYPE) {
+
+ case CF_CHAR:
+ if (flags & CF_FORCECHAR) {
+ AddCodeLine ("asl a"); /* Bit 7 -> carry */
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
+ return;
+ }
+ /* FALLTHROUGH */
+
+ case CF_INT:
+ /* Just check the high byte */
+ AddCodeLine ("cpx #$80"); /* Bit 7 -> carry */
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
+ return;
+
+ case CF_LONG:
+ /* Just check the high byte */
+ AddCodeLine ("lda sreg+1");
+ AddCodeLine ("asl a"); /* Bit 7 -> carry */
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
+ return;
+
+ default:
+ typeerror (flags);
+ }
+
+ } else {
+
+ /* Signed compare against a constant != zero */
+ switch (flags & CF_TYPE) {
+
+ case CF_CHAR:
+ if (flags & CF_FORCECHAR) {
+ Label = GetLocalLabel ();
+ AddCodeLine ("sec");
+ AddCodeLine ("sbc #$%02X", (unsigned char)val);
+ AddCodeLine ("bvc %s", LocalLabelName (Label));
+ AddCodeLine ("eor #$80");
+ g_defcodelabel (Label);
+ AddCodeLine ("asl a"); /* Bit 7 -> carry */
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
+ return;
+ }
+ /* FALLTHROUGH */
+
+ case CF_INT:
+ /* Do a subtraction */
+ Label = GetLocalLabel ();
+ AddCodeLine ("cmp #$%02X", (unsigned char)val);
+ AddCodeLine ("txa");
+ AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
+ AddCodeLine ("bvc %s", LocalLabelName (Label));
+ AddCodeLine ("eor #$80");
+ g_defcodelabel (Label);
+ AddCodeLine ("asl a"); /* Bit 7 -> carry */
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
+ return;
+
+ case CF_LONG:
+ /* This one is too costly */
+ break;
+
+ 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. Note: The standard stuff will
+ * always work with ints.
+ */
+ flags &= ~CF_FORCECHAR;
+ g_push (flags & ~CF_CONST, 0);