case CF_CHAR:
if ((flags & CF_FORCECHAR) || (flags & CF_TEST)) {
- ldyconst (offs);
- AddCodeLine ("\tlda\t(sp),y");
+ if (CPU == CPU_65C02 && offs == 0) {
+ AddCodeLine ("\tlda\t(sp)");
+ } else {
+ ldyconst (offs);
+ AddCodeLine ("\tlda\t(sp),y");
+ }
} else {
if (offs == 0) {
AddCodeLine ("\tldx\t#$00");
switch (flags & CF_TYPE) {
case CF_CHAR:
- ldyconst (offs);
- AddCodeLine ("\tsta\t(sp),y");
+ if (CPU == CPU_65C02 && offs == 0) {
+ AddCodeLine ("\tsta\t(sp)");
+ } else {
+ ldyconst (offs);
+ AddCodeLine ("\tsta\t(sp),y");
+ }
break;
case CF_INT:
if (flags & CF_FORCECHAR) {
while (p2--) {
AddCodeLine ("\tasl\ta");
- }
- break;
- }
- /* FALLTHROUGH */
-
- case CF_INT:
- if (FavourSize || p2 >= 3) {
- if (flags & CF_UNSIGNED) {
- AddCodeLine ("\tjsr\tshlax%d", p2);
- } else {
- AddCodeLine ("\tjsr\taslax%d", p2);
- }
- } else {
- AddCodeLine ("\tstx\ttmp1");
- while (p2--) {
- AddCodeLine ("\tasl\ta");
- AddCodeLine ("\trol\ttmp1");
- }
- AddCodeLine ("\tldx\ttmp1");
- }
- break;
-
- case CF_LONG:
- if (flags & CF_UNSIGNED) {
- AddCodeLine ("\tjsr\tshleax%d", p2);
- } else {
- AddCodeLine ("\tjsr\tasleax%d", p2);
- }
- break;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case CF_INT:
+ if (FavourSize || p2 >= 3) {
+ if (flags & CF_UNSIGNED) {
+ AddCodeLine ("\tjsr\tshlax%d", p2);
+ } else {
+ AddCodeLine ("\tjsr\taslax%d", p2);
+ }
+ } else {
+ AddCodeLine ("\tstx\ttmp1");
+ while (p2--) {
+ AddCodeLine ("\tasl\ta");
+ AddCodeLine ("\trol\ttmp1");
+ }
+ AddCodeLine ("\tldx\ttmp1");
+ }
+ break;
+
+ case CF_LONG:
+ if (flags & CF_UNSIGNED) {
+ AddCodeLine ("\tjsr\tshleax%d", p2);
+ } else {
+ AddCodeLine ("\tjsr\tasleax%d", p2);
+ }
+ break;
default:
typeerror (flags);
} else {
AddCodeLine ("\tstx\ttmp1");
while (p2--) {
- AddCodeLine ("\tlsr\ttmp1");
+ AddCodeLine ("\tlsr\ttmp1");
AddCodeLine ("\tror\ta");
}
AddCodeLine ("\tldx\ttmp1");
/*****************************************************************************/
-/* Adds and subs of variables fix a fixed address */
+/* Adds and subs of variables fix a fixed address */
/*****************************************************************************/
if (flags & CF_CONST) {
if (val == 1) {
AddCodeLine ("\tinc\t%s", lbuf);
- AddCodeLine ("\tlda\t%s", lbuf);
- } else {
+ AddCodeLine ("\tlda\t%s", lbuf);
+ } else {
AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
- AddCodeLine ("\tclc");
- AddCodeLine ("\tadc\t%s", lbuf);
- AddCodeLine ("\tsta\t%s", lbuf);
- }
+ AddCodeLine ("\tclc");
+ AddCodeLine ("\tadc\t%s", lbuf);
+ AddCodeLine ("\tsta\t%s", lbuf);
+ }
} else {
- AddCodeLine ("\tclc");
- AddCodeLine ("\tadc\t%s", lbuf);
- AddCodeLine ("\tsta\t%s", lbuf);
- }
+ AddCodeLine ("\tclc");
+ AddCodeLine ("\tadc\t%s", lbuf);
+ AddCodeLine ("\tsta\t%s", lbuf);
+ }
if ((flags & CF_UNSIGNED) == 0) {
AddCodeLine ("\tbpl\t*+3");
AddCodeLine ("\tdex");
AddCodeLine ("\tsta\t%s", lbuf);
AddCodeLine ("\ttxa");
AddCodeLine ("\tadc\t%s+1", lbuf);
- AddCodeLine ("\tsta\t%s+1", lbuf);
- AddCodeLine ("\ttax");
- AddCodeLine ("\tlda\t%s", lbuf);
+ AddCodeLine ("\tsta\t%s+1", lbuf);
+ AddCodeLine ("\ttax");
+ AddCodeLine ("\tlda\t%s", lbuf);
}
break;
case CF_CHAR:
if (flags & CF_FORCECHAR) {
- if (offs == 0) {
- AddCodeLine ("\tldx\t#$00");
- if (flags & CF_CONST) {
- AddCodeLine ("\tclc");
+ if (offs == 0) {
+ AddCodeLine ("\tldx\t#$00");
+ if (flags & CF_CONST) {
+ AddCodeLine ("\tclc");
AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
- AddCodeLine ("\tadc\t(sp,x)");
- AddCodeLine ("\tsta\t(sp,x)");
- } else {
- AddCodeLine ("\tclc");
- AddCodeLine ("\tadc\t(sp,x)");
- AddCodeLine ("\tsta\t(sp,x)");
- }
- } else {
- ldyconst (offs);
- AddCodeLine ("\tldx\t#$00");
- if (flags & CF_CONST) {
- AddCodeLine ("\tclc");
+ AddCodeLine ("\tadc\t(sp,x)");
+ AddCodeLine ("\tsta\t(sp,x)");
+ } else {
+ AddCodeLine ("\tclc");
+ AddCodeLine ("\tadc\t(sp,x)");
+ AddCodeLine ("\tsta\t(sp,x)");
+ }
+ } else {
+ ldyconst (offs);
+ AddCodeLine ("\tldx\t#$00");
+ if (flags & CF_CONST) {
+ AddCodeLine ("\tclc");
AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
- AddCodeLine ("\tadc\t(sp),y");
- AddCodeLine ("\tsta\t(sp),y");
- } else {
+ AddCodeLine ("\tadc\t(sp),y");
+ AddCodeLine ("\tsta\t(sp),y");
+ } else {
AddCodeLine ("\tclc");
- AddCodeLine ("\tadc\t(sp),y");
- AddCodeLine ("\tsta\t(sp),y");
- }
- }
- if ((flags & CF_UNSIGNED) == 0) {
- AddCodeLine ("\tbpl\t*+3");
- AddCodeLine ("\tdex");
- AddCodeHint ("x:!"); /* Invalidate X */
- }
- break;
+ AddCodeLine ("\tadc\t(sp),y");
+ AddCodeLine ("\tsta\t(sp),y");
+ }
+ }
+ if ((flags & CF_UNSIGNED) == 0) {
+ AddCodeLine ("\tbpl\t*+3");
+ AddCodeLine ("\tdex");
+ AddCodeHint ("x:!"); /* Invalidate X */
+ }
+ break;
}
/* FALLTHROUGH */
g_getimmed (flags, val, 0);
}
if (offs == 0) {
- AddCodeLine ("\tjsr\taddeq0sp");
+ AddCodeLine ("\tjsr\taddeq0sp");
} else {
- ldyconst (offs);
- AddCodeLine ("\tjsr\taddeqysp");
+ ldyconst (offs);
+ AddCodeLine ("\tjsr\taddeqysp");
}
break;
AddCodeLine ("\tbpl\t*+3");
AddCodeLine ("\tdex");
AddCodeHint ("x:!"); /* Invalidate X */
- }
+ }
break;
}
/* FALLTHROUGH */
AddCodeLine ("\tsty\tptr1");
AddCodeLine ("\tldy\t#>(%s+1)", lbuf);
if (val == 1) {
- AddCodeLine ("\tjsr\tlsubeq1");
+ AddCodeLine ("\tjsr\tlsubeq1");
} else {
AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
AddCodeLine ("\tjsr\tlsubeqa");
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
} else {
AddCodeLine ("\tsta\ttmp1");
- AddCodeLine ("\tlda\t(sp),y");
+ AddCodeLine ("\tlda\t(sp),y");
AddCodeLine ("\tsbc\ttmp1");
}
AddCodeLine ("\tsta\t(sp),y");
AddCodeLine ("\tlda\t(ptr1),y");
AddCodeLine ("\tsbc\t#$%02X", (val >> 8) & 0xFF);
AddCodeLine ("\tsta\t(ptr1),y");
- AddCodeLine ("\ttax");
+ AddCodeLine ("\ttax");
AddCodeLine ("\tpla");
break;
}
break;
case CF_LONG:
- AddCodeLine ("\tjsr\tpusheax");
+ AddCodeLine ("\tjsr\tpusheax");
break;
default:
{
static char* ops [12] = {
0, "tosmula0", "tosmulax",
- 0, "tosumula0", "tosumulax",
+ 0, "tosumula0", "tosumulax",
0, 0, "tosmuleax",
0, 0, "tosumuleax",
};
AddCodeLine ("\tsta\ttmp1");
AddCodeLine ("\tasl\ta");
AddCodeLine ("\tasl\ta");
- AddCodeLine ("\tclc");
+ AddCodeLine ("\tclc");
AddCodeLine ("\tadc\ttmp1");
AddCodeLine ("\tasl\ta");
return;
return;
} else if ((val & 0xFF) == 0) {
AddCodeLine ("\tpha");
- AddCodeLine ("\ttxa");
+ AddCodeLine ("\ttxa");
AddCodeLine ("\teor\t#$%02X", (val >> 8) & 0xFF);
AddCodeLine ("\ttax");
AddCodeLine ("\tpla");
if (val <= 0xFF) {
ldxconst (0);
AddCodeLine ("\tstx\tsreg+1");
- AddCodeLine ("\tstx\tsreg");
+ AddCodeLine ("\tstx\tsreg");
if ((val & 0xFF) != 0xFF) {
AddCodeLine ("\tand\t#$%02X", val & 0xFF);
}
AddCodeLine ("\tlda\tsreg");
AddCodeLine ("\tsty\tsreg+1");
AddCodeLine ("\tsty\tsreg");
- return;
+ return;
}
break;
if (flags & CF_UNSIGNED) {
AddCodeLine ("\tjsr\tshlax%ld", val);
} else {
- AddCodeLine ("\tjsr\taslax%ld", val);
+ AddCodeLine ("\tjsr\taslax%ld", val);
}
return;
} else if (val == 8) {
while (val--) {
AddCodeLine ("\tina");
}
- } else {
+ } else {
AddCodeLine ("\tclc");
AddCodeLine ("\tadc\t#$%02X", val & 0xFF);
}
} else {
AddCodeLine ("\tclc");
if ((val & 0xFF) != 0) {
- AddCodeLine ("\tadc\t#$%02X", (unsigned char) val);
+ AddCodeLine ("\tadc\t#$%02X", (unsigned char) val);
/* Tell the optimizer that the X register may be invalid */
AddCodeHint ("x:!");
}
}
} else {
AddCodeLine ("\tsec");
- AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
+ AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
}
break;
}
}
return;
}
- /* FALLTHROUGH */
+ /* FALLTHROUGH */
case CF_INT:
if ((flags & CF_UNSIGNED) == 0 && val == 0) {
AddCodeLine ("\tjsr\tboolne");
}
} else {
- AddCodeLine ("\tjsr\tboolgt");
+ AddCodeLine ("\tjsr\tboolgt");
}
return;
}
AddCodeLine ("\tjsr\tbooluge");
return;
}
- break;
+ break;
case CF_LONG:
break;
switch (flags & CF_TYPE) {
case CF_CHAR:
- AddCodeLine ("\t.byte\t$%02lX", val & 0xFF);
+ AddCodeLine ("\t.byte\t$%02lX", val & 0xFF);
break;
case CF_INT:
AddCodeLine ("\t.res\t%u,$00", n);
}
-
+
/*****************************************************************************/
-/* Inlined known functions */
+/* Inlined known functions */
/*****************************************************************************/
AddCodeLine ("\tiny");
AddCodeLine ("\tlda\t%s,y", lbuf);
AddCodeLine ("\tbne\tL%04X", label);
+ AddCodeLine ("\ttax");
AddCodeLine ("\ttya");
- AddCodeLine ("\tldx\t#$00");
} else {
AddCodeLine ("\tiny");
AddCodeLine ("\tlda\t(ptr1),y");
AddCodeLine ("\tbne\tL%04X", label);
+ AddCodeLine ("\ttax");
AddCodeLine ("\ttya");
- AddCodeLine ("\tldx\t#$00");
}
}
}
do {
/* Handle jumps to local labels (continue there) */
- if (LineMatch (L, "\tjmp\tL")) {
+ if (LineMatch (L, "\tjmp\tL") || LineMatch (L, "\tbra\tL")) {
/* Get the target of the jump */
L = GetTargetLine (L->Line+5);
}
/* Bail out if we're done */
if (L == 0 || IsLabel (L)) {
- /* Something is wrong */
- return REG_ALL;
+ /* Something is wrong */
+ return REG_ALL;
}
/* Check if we had this line already. If so, bail out, if not,
* add it to the list of known lines.
*/
if (LCHasLine (LC, L) || !LCAddLine (LC, L)) {
- goto ExitPoint;
+ goto ExitPoint;
}
- } while (LineMatch (L, "\tjmp\tL"));
+ } while (LineMatch (L, "\tjmp\tL") || LineMatch (L, "\tbra\tL"));
/* Special handling for branches */
if (LineMatchX (L, ShortBranches) >= 0 ||
LineMatchX (L, LongBranches) >= 0) {
const char* Target = L->Line+5;
if (Target[0] == 'L') {
- /* Jump to local label. Check the register usage starting at
- * the branch target and at the code following the branch.
- * All registers that are unused in both execution flows are
- * returned as unused.
- */
- unsigned U1, U2;
+ /* Jump to local label. Check the register usage starting at
+ * the branch target and at the code following the branch.
+ * All registers that are unused in both execution flows are
+ * returned as unused.
+ */
+ unsigned U1, U2;
U2 = RVUInt1 (GetTargetLine (Target), LC, Used, Unused);
- U1 = RVUInt1 (L, LC, Used, Unused);
- return U1 | U2; /* Used in any of the branches */
+ U1 = RVUInt1 (L, LC, Used, Unused);
+ return U1 | U2; /* Used in any of the branches */
}
}
* If the end of the lookahead is reached, all registers that are uncertain
* are marked as used.
* The result of the search is returned.
- */
+ */
{
unsigned R;
/* Search for a load of Y and check if the value is used later */
else if (LineMatch (L, "\tldy\t") &&
- !RegYUsed (L) &&
+ !RegYUsed (L) &&
!IsCondJump (NextInstruction (L))) {
/* Remember to delete this line */
} else if (LineFullMatch (L, "\tjsr\tpushax")) {
/* We know about this function */
Y = 1;
+ } else if (LineFullMatch (L, "\tjsr\tpushaysp")) {
+ /* We know about this function */
+ A = -1;
+ Y = 0;
} else if (LineFullMatch (L, "\tjsr\tpushc0")) {
/* We know about this function */
A = 0;
}
L = NextCodeLine (L);
}
+
+ /* Special treatment for jumps on the 65C02 */
+ if (CPU == CPU_65C02) {
+
+ Line* L = FirstCode;
+ while (L) {
+ if (LineMatch (L, "\tjmp\tL")) {
+ Line* Target = GetTargetLine (L->Line+5);
+ unsigned Distance = GetJumpDistance (L, Target);
+ if (Distance < 123) { /* Safety */
+ L->Line [1] = 'b'; /* Make a short branch */
+ L->Line [2] = 'r';
+ L->Line [3] = 'a';
+ L->Size = 2; /* Set new size */
+ }
+ }
+ L = NextCodeLine (L);
+ }
+
+ }
}