1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-16 09:29:32 +00:00

65C02 additions, saved a few bytes in the code generator

git-svn-id: svn://svn.cc65.org/cc65/trunk@80 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-06-14 16:58:52 +00:00
parent 409d12534b
commit 500233166a
2 changed files with 147 additions and 115 deletions

View File

@ -790,8 +790,12 @@ void g_getlocal (unsigned flags, int offs)
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");
@ -1004,8 +1008,12 @@ void g_putlocal (unsigned flags, int offs)
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:
@ -1275,35 +1283,35 @@ void g_scale (unsigned flags, long val)
if (flags & CF_FORCECHAR) {
while (p2--) {
AddCodeLine ("\tasl\ta");
}
break;
}
/* FALLTHROUGH */
}
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_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;
case CF_LONG:
if (flags & CF_UNSIGNED) {
AddCodeLine ("\tjsr\tshleax%d", p2);
} else {
AddCodeLine ("\tjsr\tasleax%d", p2);
}
break;
default:
typeerror (flags);
@ -1348,7 +1356,7 @@ void g_scale (unsigned flags, long val)
} else {
AddCodeLine ("\tstx\ttmp1");
while (p2--) {
AddCodeLine ("\tlsr\ttmp1");
AddCodeLine ("\tlsr\ttmp1");
AddCodeLine ("\tror\ta");
}
AddCodeLine ("\tldx\ttmp1");
@ -1393,7 +1401,7 @@ void g_scale (unsigned flags, long val)
/*****************************************************************************/
/* Adds and subs of variables fix a fixed address */
/* Adds and subs of variables fix a fixed address */
/*****************************************************************************/
@ -1528,18 +1536,18 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs,
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");
@ -1584,9 +1592,9 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs,
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;
@ -1634,38 +1642,38 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val)
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 */
@ -1674,10 +1682,10 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val)
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;
@ -1801,7 +1809,7 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
AddCodeLine ("\tbpl\t*+3");
AddCodeLine ("\tdex");
AddCodeHint ("x:!"); /* Invalidate X */
}
}
break;
}
/* FALLTHROUGH */
@ -1846,7 +1854,7 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
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");
@ -1891,7 +1899,7 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val)
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");
@ -1981,7 +1989,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val)
AddCodeLine ("\tlda\t(ptr1),y");
AddCodeLine ("\tsbc\t#$%02X", (val >> 8) & 0xFF);
AddCodeLine ("\tsta\t(ptr1),y");
AddCodeLine ("\ttax");
AddCodeLine ("\ttax");
AddCodeLine ("\tpla");
break;
}
@ -2296,7 +2304,7 @@ void g_push (unsigned flags, unsigned long val)
break;
case CF_LONG:
AddCodeLine ("\tjsr\tpusheax");
AddCodeLine ("\tjsr\tpusheax");
break;
default:
@ -2521,7 +2529,7 @@ void g_mul (unsigned flags, unsigned long val)
{
static char* ops [12] = {
0, "tosmula0", "tosmulax",
0, "tosumula0", "tosumulax",
0, "tosumula0", "tosumulax",
0, 0, "tosmuleax",
0, 0, "tosumuleax",
};
@ -2566,7 +2574,7 @@ void g_mul (unsigned flags, unsigned long val)
AddCodeLine ("\tsta\ttmp1");
AddCodeLine ("\tasl\ta");
AddCodeLine ("\tasl\ta");
AddCodeLine ("\tclc");
AddCodeLine ("\tclc");
AddCodeLine ("\tadc\ttmp1");
AddCodeLine ("\tasl\ta");
return;
@ -2746,7 +2754,7 @@ void g_xor (unsigned flags, unsigned long val)
return;
} else if ((val & 0xFF) == 0) {
AddCodeLine ("\tpha");
AddCodeLine ("\ttxa");
AddCodeLine ("\ttxa");
AddCodeLine ("\teor\t#$%02X", (val >> 8) & 0xFF);
AddCodeLine ("\ttax");
AddCodeLine ("\tpla");
@ -2836,7 +2844,7 @@ void g_and (unsigned flags, unsigned long val)
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);
}
@ -2926,7 +2934,7 @@ void g_asr (unsigned flags, unsigned long val)
AddCodeLine ("\tlda\tsreg");
AddCodeLine ("\tsty\tsreg+1");
AddCodeLine ("\tsty\tsreg");
return;
return;
}
break;
@ -2971,7 +2979,7 @@ void g_asl (unsigned flags, unsigned long val)
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) {
@ -3106,7 +3114,7 @@ void g_inc (unsigned flags, unsigned long val)
while (val--) {
AddCodeLine ("\tina");
}
} else {
} else {
AddCodeLine ("\tclc");
AddCodeLine ("\tadc\t#$%02X", val & 0xFF);
}
@ -3151,7 +3159,7 @@ void g_inc (unsigned flags, unsigned long val)
} 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:!");
}
@ -3196,7 +3204,7 @@ void g_dec (unsigned flags, unsigned long val)
}
} else {
AddCodeLine ("\tsec");
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
}
break;
}
@ -3376,7 +3384,7 @@ void g_lt (unsigned flags, unsigned long val)
}
return;
}
/* FALLTHROUGH */
/* FALLTHROUGH */
case CF_INT:
if ((flags & CF_UNSIGNED) == 0 && val == 0) {
@ -3511,7 +3519,7 @@ void g_gt (unsigned flags, unsigned long val)
AddCodeLine ("\tjsr\tboolne");
}
} else {
AddCodeLine ("\tjsr\tboolgt");
AddCodeLine ("\tjsr\tboolgt");
}
return;
}
@ -3601,7 +3609,7 @@ void g_ge (unsigned flags, unsigned long val)
AddCodeLine ("\tjsr\tbooluge");
return;
}
break;
break;
case CF_LONG:
break;
@ -3646,7 +3654,7 @@ void g_defdata (unsigned flags, unsigned long val, unsigned offs)
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:
@ -3715,10 +3723,10 @@ void g_zerobytes (unsigned n)
AddCodeLine ("\t.res\t%u,$00", n);
}
/*****************************************************************************/
/* Inlined known functions */
/* Inlined known functions */
/*****************************************************************************/
@ -3741,8 +3749,8 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs)
AddCodeLine ("\tiny");
AddCodeLine ("\tlda\t%s,y", lbuf);
AddCodeLine ("\tbne\tL%04X", label);
AddCodeLine ("\ttax");
AddCodeLine ("\ttya");
AddCodeLine ("\tldx\t#$00");
} else {
@ -3759,8 +3767,8 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs)
AddCodeLine ("\tiny");
AddCodeLine ("\tlda\t(ptr1),y");
AddCodeLine ("\tbne\tL%04X", label);
AddCodeLine ("\ttax");
AddCodeLine ("\ttya");
AddCodeLine ("\tldx\t#$00");
}
}
}

View File

@ -1103,7 +1103,7 @@ static unsigned RVUInt2 (Line* L,
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);
}
@ -1113,33 +1113,33 @@ static unsigned RVUInt2 (Line* L,
/* 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 */
}
}
@ -1218,7 +1218,7 @@ static unsigned RegValUsed (Line* Start)
* 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;
@ -1758,7 +1758,7 @@ static void OptRegLoads (void)
/* 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 */
@ -3867,6 +3867,10 @@ static Line* OptOneBlock (Line* L)
} 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;
@ -4196,6 +4200,26 @@ static void OptJumps (void)
}
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);
}
}
}