static void typeerror (unsigned type)
/* Print an error message about an invalid operand type */
{
- Internal ("Invalid type in CF flags: %04X, type = %u", type, type & CF_TYPE);
+ /* Special handling for floats here: */
+ if ((type & CF_TYPE) == CF_FLOAT) {
+ Fatal ("Floating point type is currently unsupported");
+ } else {
+ Internal ("Invalid type in CF flags: %04X, type = %u", type, type & CF_TYPE);
+ }
}
AddCodeLine ("inx");
} else {
ldaconst (offs);
- AddCodeLine ("clc");
AddCodeLine ("ldx sp+1");
+ AddCodeLine ("clc");
AddCodeLine ("adc sp");
AddCodeLine ("bcc %s", LocalLabelName (L));
AddCodeLine ("inx");
AddCodeLine ("dec %s", lbuf);
AddCodeLine ("lda %s", lbuf);
} else {
- AddCodeLine ("sec");
AddCodeLine ("lda %s", lbuf);
+ AddCodeLine ("sec");
AddCodeLine ("sbc #$%02X", (int)(val & 0xFF));
AddCodeLine ("sta %s", lbuf);
}
/* FALLTHROUGH */
case CF_INT:
- AddCodeLine ("sec");
if (flags & CF_CONST) {
AddCodeLine ("lda %s", lbuf);
+ AddCodeLine ("sec");
AddCodeLine ("sbc #$%02X", (unsigned char)val);
AddCodeLine ("sta %s", lbuf);
if (val < 0x100) {
}
} else {
AddCodeLine ("eor #$FF");
+ AddCodeLine ("sec");
AddCodeLine ("adc %s", lbuf);
AddCodeLine ("sta %s", lbuf);
AddCodeLine ("txa");
if (flags & CF_FORCECHAR) {
ldyconst (offs);
AddCodeLine ("ldx #$00");
- AddCodeLine ("sec");
if (flags & CF_CONST) {
AddCodeLine ("lda (sp),y");
+ AddCodeLine ("sec");
AddCodeLine ("sbc #$%02X", (unsigned char)val);
} else {
AddCodeLine ("eor #$FF");
+ AddCodeLine ("sec");
AddCodeLine ("adc (sp),y");
}
AddCodeLine ("sta (sp),y");
}
return;
} else if (val == 8 && (flags & CF_UNSIGNED)) {
- AddCodeLine ("txa");
+ AddCodeLine ("txa");
AddCodeLine ("ldx sreg");
AddCodeLine ("ldy sreg+1");
AddCodeLine ("sty sreg");
if (val >= 0x300) {
AddCodeLine ("inx");
}
- } else {
+ } else if ((val & 0xFF) != 0) {
AddCodeLine ("clc");
- if ((val & 0xFF) != 0) {
- AddCodeLine ("adc #$%02X", (unsigned char) val);
- }
+ AddCodeLine ("adc #$%02X", (unsigned char) val);
AddCodeLine ("pha");
AddCodeLine ("txa");
AddCodeLine ("adc #$%02X", (unsigned char) (val >> 8));
AddCodeLine ("tax");
AddCodeLine ("pla");
+ } else {
+ AddCodeLine ("pha");
+ AddCodeLine ("txa");
+ AddCodeLine ("clc");
+ AddCodeLine ("adc #$%02X", (unsigned char) (val >> 8));
+ AddCodeLine ("tax");
+ AddCodeLine ("pla");
}
}
break;
AddCodeLine ("dex");
}
} else {
- AddCodeLine ("sec");
if ((val & 0xFF) != 0) {
+ AddCodeLine ("sec");
AddCodeLine ("sbc #$%02X", (unsigned char) val);
+ AddCodeLine ("pha");
+ AddCodeLine ("txa");
+ AddCodeLine ("sbc #$%02X", (unsigned char) (val >> 8));
+ AddCodeLine ("tax");
+ AddCodeLine ("pla");
+ } else {
+ AddCodeLine ("pha");
+ AddCodeLine ("txa");
+ AddCodeLine ("sec");
+ AddCodeLine ("sbc #$%02X", (unsigned char) (val >> 8));
+ AddCodeLine ("tax");
+ AddCodeLine ("pla");
}
- AddCodeLine ("pha");
- AddCodeLine ("txa");
- AddCodeLine ("sbc #$%02X", (unsigned char) (val >> 8));
- AddCodeLine ("tax");
- AddCodeLine ("pla");
}
}
break;
"tosltax", "tosultax", "toslteax", "tosulteax",
};
+ unsigned Label;
+
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
} else if (val == 0) {
- /* Look at the type */
+ /* A signed compare against zero must only look at the sign bit */
switch (flags & CF_TYPE) {
case CF_CHAR:
if (flags & CF_FORCECHAR) {
- AddCodeLine ("tax");
- AddCodeLine ("jsr boollt");
+ 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 ("txa");
- AddCodeLine ("jsr boollt");
+ 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 ("jsr boollt");
+ 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
"tosgeax", "tosugeax", "tosgeeax", "tosugeeax",
};
+ unsigned Label;
+
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
case CF_CHAR:
if (flags & CF_FORCECHAR) {
+ /* Do a subtraction. Condition is true if carry set */
AddCodeLine ("cmp #$%02X", (unsigned char)val);
- AddCodeLine ("jsr booluge");
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
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 booluge");
+ /* Do a subtraction. Condition is true if carry set */
+ AddCodeLine ("cmp #$%02X", (unsigned char)val);
+ AddCodeLine ("txa");
+ AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
return;
case CF_LONG:
- /* Do a subtraction */
+ /* Do a subtraction. Condition is true if carry set */
AddCodeLine ("cmp #$%02X", (unsigned char)val);
AddCodeLine ("txa");
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8));
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 16));
AddCodeLine ("lda sreg+1");
AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 24));
- AddCodeLine ("jsr booluge");
+ AddCodeLine ("lda #$00");
+ AddCodeLine ("ldx #$00");
+ AddCodeLine ("rol a");
return;
default:
} else if (val == 0) {
- /* Look at the type */
+ /* A signed compare against zero must only look at the sign bit */
switch (flags & CF_TYPE) {
case CF_CHAR:
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 ("bvs %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 ("bvs %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