diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 7777ea8b0..a67cde071 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3367,14 +3367,47 @@ void g_dec (unsigned flags, unsigned long val) /* FALLTHROUGH */ case CF_INT: - if (val <= 8) { - AddCodeLine ("\tjsr\tdecax%d", (int) val); - } else if (val <= 255) { - ldyconst (val); - AddCodeLine ("\tjsr\tdecaxy"); + if (CodeSizeFactor < 200) { + /* Use subroutines */ + if (val <= 8) { + AddCodeLine ("\tjsr\tdecax%d", (int) val); + } else if (val <= 255) { + ldyconst (val); + AddCodeLine ("\tjsr\tdecaxy"); + } else { + g_sub (flags | CF_CONST, val); + } } else { - g_sub (flags | CF_CONST, val); - } + /* Inline the code */ + if (val < 0x300) { + if ((val & 0xFF) != 0) { + AddCodeLine ("\tsec"); + AddCodeLine ("\tsbc\t#$%02X", (unsigned char) val); + AddCodeLine ("\tbcs\t*+3"); + AddCodeLine ("\tdex"); + /* Tell the optimizer that the X register may be invalid */ + AddCodeHint ("x:!"); + } + if (val >= 0x100) { + AddCodeLine ("\tdex"); + } + if (val >= 0x200) { + AddCodeLine ("\tdex"); + } + } else { + AddCodeLine ("\tsec"); + if ((val & 0xFF) != 0) { + AddCodeLine ("\tsbc\t#$%02X", (unsigned char) val); + /* Tell the optimizer that the X register may be invalid */ + AddCodeHint ("x:!"); + } + AddCodeLine ("\tpha"); + AddCodeLine ("\ttxa"); + AddCodeLine ("\tsbc\t#$%02X", (unsigned char) (val >> 8)); + AddCodeLine ("\ttax"); + AddCodeLine ("\tpla"); + } + } break; case CF_LONG: diff --git a/src/cc65/optimize.c b/src/cc65/optimize.c index 3cbf28428..4676deaaa 100644 --- a/src/cc65/optimize.c +++ b/src/cc65/optimize.c @@ -1737,10 +1737,10 @@ static void OptLoads (void) * and replace it by: * * lda xx - * ldy #$01 + * ldy #$01 * sta (sp),y * dey - * lda yy + * lda yy * sta (sp),y * * provided that that the X register is not used later. This code @@ -1762,22 +1762,63 @@ static void OptLoads (void) /* Remove the remaining line */ FreeLine (L2[1]); - } + + /* Search for + * + * adc #xx + * bcc *+3 + * inx + * + * Remove the handling of the high byte if the X register + * is not used any more + */ + } else if (LineMatch (L, "\tadc\t#") && + GetNextCodeLines (L, L2, 3) && + LineFullMatch (L2[0], "\tbcc\t*+3") && + LineFullMatch (L2[1], "\tinx") && + L2[1]->Next && + IsHint (L2[1]->Next, "x:!") && + !RegXUsed (L2[1])) { + + /* Delete the lines */ + FreeLines (L2[0], L2[1]->Next); + + /* Search for + * + * sbc #xx + * bcs *+3 + * dex + * + * Remove the handling of the high byte if the X register + * is not used any more + */ + } else if (LineMatch (L, "\tsbc\t#") && + GetNextCodeLines (L, L2, 3) && + LineFullMatch (L2[0], "\tbcs\t*+3") && + LineFullMatch (L2[1], "\tdex") && + L2[1]->Next && + IsHint (L2[1]->Next, "x:!") && + !RegXUsed (L2[1])) { + + /* Delete the lines */ + FreeLines (L2[0], L2[1]->Next); + } + /* All other patterns start with this one: */ if (!LineFullMatch (L, "\tldx\t#$00")) { /* Next line */ goto NextLine; - } + } /* Search for: * - * ldx #$00 - * jsr pushax + * ldx #$00 + * jsr pushax * * and replace it by: * - * jsr pusha0 + * jsr pusha0 * */ if (GetNextCodeLines (L, L2, 1) && @@ -1792,13 +1833,13 @@ static void OptLoads (void) /* Search for: * - * ldx #$00 - * lda ... - * jsr pushax + * ldx #$00 + * lda ... + * jsr pushax * * and replace it by: * - * lda ... + * lda ... * jsr pusha0 * */ @@ -1812,7 +1853,7 @@ static void OptLoads (void) /* Replace the subroutine call */ L2 [1] = ReplaceLine (L2 [1], "\tjsr\tpusha0"); - /* Remove the unnecessary load */ + /* Remove the unnecessary load */ FreeLine (L); /* L must be valid */ @@ -1898,20 +1939,20 @@ static void OptRegLoads (void) /* Search for a load of X and check if the value is used later */ if (LineMatch (L, "\tldx\t") && - !RegXUsed (L) && - !IsCondJump (NextInstruction (L))) { + !RegXUsed (L) && + !IsCondJump (NextInstruction (L))) { - /* Remember to delete this line */ - Delete = 1; + /* Remember to delete this line */ + Delete = 1; } /* Search for a load of A and check if the value is used later */ else if (LineMatch (L, "\tlda\t") && - !RegAUsed (L) && - !IsCondJump (NextInstruction (L))) { + !RegAUsed (L) && + !IsCondJump (NextInstruction (L))) { - /* Remember to delete this line */ - Delete = 1; + /* Remember to delete this line */ + Delete = 1; } /* Search for a load of Y and check if the value is used later */ @@ -1919,8 +1960,8 @@ static void OptRegLoads (void) !RegYUsed (L) && !IsCondJump (NextInstruction (L))) { - /* Remember to delete this line */ - Delete = 1; + /* Remember to delete this line */ + Delete = 1; } /* Go to the next line, delete the current if requested */