From 2fead582431c9017cae8fb3c0289c248de5c9923 Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 24 Mar 2001 23:33:38 +0000 Subject: [PATCH] Allow a more exact specification which growth factor is allowed when generating code and favouring speed over size. git-svn-id: svn://svn.cc65.org/cc65/trunk@668 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codegen.c | 92 +++++++++++++++++++++++----------------------- src/cc65/expr.c | 2 +- src/cc65/global.c | 1 + src/cc65/global.h | 2 + src/cc65/main.c | 42 ++++++++++++++------- src/cc65/stmt.c | 2 +- 6 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 97c5c1fce..7830b099e 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -677,7 +677,7 @@ void g_getimmed (unsigned flags, unsigned long val, unsigned offs) AddCodeLine ("\tsta\tsreg+1"); AddCodeLine ("\tsta\tsreg"); AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); - } else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) { + } else if ((val & 0xFFFF0000) == 0 && CodeSizeFactor > 140) { AddCodeLine ("\tlda\t#$00"); AddCodeLine ("\tsta\tsreg+1"); AddCodeLine ("\tsta\tsreg"); @@ -820,19 +820,19 @@ void g_getlocal (unsigned flags, int offs) AddCodeLine ("\tdey"); AddCodeLine ("\tora\t(sp),y"); } else { - if (FavourSize) { + if (CodeSizeFactor > 180) { + ldyconst (offs + 1); + AddCodeLine ("\tlda\t(sp),y"); + AddCodeLine ("\ttax"); + AddCodeLine ("\tdey"); + AddCodeLine ("\tlda\t(sp),y"); + } else { if (offs) { ldyconst (offs+1); AddCodeLine ("\tjsr\tldaxysp"); } else { AddCodeLine ("\tjsr\tldax0sp"); } - } else { - ldyconst (offs + 1); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\ttax"); - AddCodeLine ("\tdey"); - AddCodeLine ("\tlda\t(sp),y"); } } break; @@ -878,13 +878,13 @@ void g_getind (unsigned flags, unsigned offs) } } else { if (flags & CF_UNSIGNED) { - if (FavourSize) { - AddCodeLine ("\tjsr\tldaui"); - } else { + if (CodeSizeFactor > 250) { AddCodeLine ("\tsta\tptr1"); AddCodeLine ("\tstx\tptr1+1"); AddCodeLine ("\tldx\t#$00"); AddCodeLine ("\tlda\t(ptr1,x)"); + } else { + AddCodeLine ("\tjsr\tldaui"); } } else { AddCodeLine ("\tjsr\tldai"); @@ -941,14 +941,14 @@ void g_leasp (int offs) AddCodeLine ("\tlda\tsp"); AddCodeLine ("\tldx\tsp+1"); } else { - if (FavourSize) { + if (CodeSizeFactor < 300) { ldaconst (offs); /* Load A with offset value */ AddCodeLine ("\tjsr\tleaasp"); /* Load effective address */ } else { if (CPU == CPU_65C02 && offs == 1) { AddCodeLine ("\tlda\tsp"); AddCodeLine ("\tldx\tsp+1"); - AddCodeLine ("\tina"); + AddCodeLine ("\tina"); AddCodeLine ("\tbne\t*+3"); AddCodeLine ("\tinx"); AddCodeHint ("x:!"); /* Invalidate X */ @@ -1127,7 +1127,7 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("\tsta\t(sp),y"); } } else { - if ((Flags & CF_NOKEEP) == 0 || FavourSize) { + if ((Flags & CF_NOKEEP) == 0 || CodeSizeFactor < 160) { if (Offs) { ldyconst (Offs); AddCodeLine ("\tjsr\tstaxysp"); @@ -1315,12 +1315,12 @@ void g_reglong (unsigned flags) case CF_CHAR: case CF_INT: if (flags & CF_UNSIGNED) { - if (FavourSize) { - AddCodeLine ("\tjsr\taxulong"); - } else { + if (CodeSizeFactor >= 200) { ldyconst (0); AddCodeLine ("\tsty\tsreg"); AddCodeLine ("\tsty\tsreg+1"); + } else { + AddCodeLine ("\tjsr\taxulong"); } } else { AddCodeLine ("\tjsr\taxlong"); @@ -1451,19 +1451,19 @@ void g_scale (unsigned flags, long val) /* FALLTHROUGH */ case CF_INT: - if (FavourSize || p2 >= 3) { - if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshlax%d", p2); - } else { - AddCodeLine ("\tjsr\taslax%d", p2); - } - } else { + if (CodeSizeFactor >= (p2+1)*130U) { AddCodeLine ("\tstx\ttmp1"); while (p2--) { AddCodeLine ("\tasl\ta"); AddCodeLine ("\trol\ttmp1"); } AddCodeLine ("\tldx\ttmp1"); + } else { + if (flags & CF_UNSIGNED) { + AddCodeLine ("\tjsr\tshlax%d", p2); + } else { + AddCodeLine ("\tjsr\taslax%d", p2); + } } break; @@ -1513,20 +1513,18 @@ void g_scale (unsigned flags, long val) case CF_INT: if (flags & CF_UNSIGNED) { - if (FavourSize || p2 >= 3) { - AddCodeLine ("\tjsr\tlsrax%d", p2); - } else { + if (CodeSizeFactor >= (p2+1)*130U) { AddCodeLine ("\tstx\ttmp1"); while (p2--) { AddCodeLine ("\tlsr\ttmp1"); AddCodeLine ("\tror\ta"); } AddCodeLine ("\tldx\ttmp1"); + } else { + AddCodeLine ("\tjsr\tlsrax%d", p2); } } else { - if (FavourSize || p2 >= 3) { - AddCodeLine ("\tjsr\tasrax%d", p2); - } else { + if (CodeSizeFactor >= (p2+1)*150U) { AddCodeLine ("\tstx\ttmp1"); while (p2--) { AddCodeLine ("\tcpx\t#$80"); @@ -1534,6 +1532,8 @@ void g_scale (unsigned flags, long val) AddCodeLine ("\tror\ta"); } AddCodeLine ("\tldx\ttmp1"); + } else { + AddCodeLine ("\tjsr\tasrax%d", p2); } } break; @@ -1902,7 +1902,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) break; case CF_INT: - if (!FavourSize) { + if (CodeSizeFactor >= 200) { /* Lots of code, use only if size is not important */ AddCodeLine ("\tsta\tptr1"); AddCodeLine ("\tstx\tptr1+1"); @@ -2137,7 +2137,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) break; case CF_INT: - if (!FavourSize) { + if (CodeSizeFactor >= 200) { /* Lots of code, use only if size is not important */ AddCodeLine ("\tsta\tptr1"); AddCodeLine ("\tstx\tptr1+1"); @@ -2419,11 +2419,11 @@ void g_push (unsigned flags, unsigned long val) if ((flags & CF_TYPE) == CF_CHAR && (flags & CF_FORCECHAR)) { /* Handle as 8 bit value */ - if (FavourSize && val <= 2) { - AddCodeLine ("\tjsr\tpushc%d", (int) val); - } else { + if (CodeSizeFactor >= 165 || val > 2) { ldaconst (val); AddCodeLine ("\tjsr\tpusha"); + } else { + AddCodeLine ("\tjsr\tpushc%d", (int) val); } } else { @@ -3309,7 +3309,7 @@ void g_inc (unsigned flags, unsigned long val) AddCodeLine ("\tinx"); /* Tell the optimizer that the X register may be invalid */ AddCodeHint ("x:!"); - } else if (FavourSize) { + } else if (CodeSizeFactor < 200) { /* Use jsr calls */ if (val <= 8) { AddCodeLine ("\tjsr\tincax%lu", val); @@ -3324,24 +3324,24 @@ void g_inc (unsigned flags, unsigned long val) if (val < 0x300) { if ((val & 0xFF) != 0) { AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t#$%02X", (unsigned char) val); - AddCodeLine ("\tbcc\t*+3"); - AddCodeLine ("\tinx"); - /* Tell the optimizer that the X register may be invalid */ + AddCodeLine ("\tadc\t#$%02X", (unsigned char) val); + AddCodeLine ("\tbcc\t*+3"); + AddCodeLine ("\tinx"); + /* Tell the optimizer that the X register may be invalid */ AddCodeHint ("x:!"); } if (val >= 0x100) { - AddCodeLine ("\tinx"); + AddCodeLine ("\tinx"); } if (val >= 0x200) { - AddCodeLine ("\tinx"); + AddCodeLine ("\tinx"); } } else { AddCodeLine ("\tclc"); if ((val & 0xFF) != 0) { - AddCodeLine ("\tadc\t#$%02X", (unsigned char) val); - /* Tell the optimizer that the X register may be invalid */ - AddCodeHint ("x:!"); + AddCodeLine ("\tadc\t#$%02X", (unsigned char) val); + /* Tell the optimizer that the X register may be invalid */ + AddCodeHint ("x:!"); } AddCodeLine ("\tpha"); AddCodeLine ("\ttxa"); @@ -3943,7 +3943,7 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs) } else { /* Address not constant but in primary */ - if (FavourSize) { + if (CodeSizeFactor < 400) { /* This is too much code, so call strlen instead of inlining */ AddCodeLine ("\tjsr\t_strlen"); } else { diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0cd605efc..f517933f4 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -539,7 +539,7 @@ static unsigned FunctionParamList (FuncDesc* Func) * - we have more than one parameter to push (don't count the last param * for __fastcall__ functions). */ - if (Optimize && !FavourSize) { + if (CodeSizeFactor >= 200) { /* Calculate the number and size of the parameters */ FrameParams = Func->ParamCount; diff --git a/src/cc65/global.c b/src/cc65/global.c index 3aa3f22fa..280a05d89 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -48,6 +48,7 @@ unsigned char WriteableStrings = 0; /* Literal strings are r/w */ unsigned char NoWarn = 0; /* Suppress warnings */ unsigned char Optimize = 0; /* Optimize flag */ unsigned char FavourSize = 1; /* Favour size over speed */ +unsigned CodeSizeFactor = 100; /* Size factor for generated code */ unsigned char InlineStdFuncs = 0; /* Inline some known functions */ unsigned char EnableRegVars = 0; /* Enable register variables */ unsigned char AllowRegVarAddr = 0; /* Allow taking addresses of register vars */ diff --git a/src/cc65/global.h b/src/cc65/global.h index bd3a4865b..20a5e6a9d 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -49,6 +49,7 @@ extern unsigned char WriteableStrings; /* Literal strings are r/w */ extern unsigned char NoWarn; /* Suppress warnings */ extern unsigned char Optimize; /* Optimize flag */ extern unsigned char FavourSize; /* Favour size over speed */ +extern unsigned CodeSizeFactor; /* Size factor for generated code */ extern unsigned char InlineStdFuncs; /* Inline some known functions */ extern unsigned char EnableRegVars; /* Enable register variables */ extern unsigned char AllowRegVarAddr; /* Allow taking addresses of register vars */ @@ -62,6 +63,7 @@ extern unsigned char CreateDep; /* Create a dependency file */ extern unsigned char CheckStack; /* Generate stack overflow checks */ + /* End of global.h */ #endif diff --git a/src/cc65/main.c b/src/cc65/main.c index bfd31cf5c..1bd6b51f7 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -99,6 +99,7 @@ static void Usage (void) " --bss-name seg\tSet the name of the BSS segment\n" " --check-stack\t\tGenerate stack overflow checks\n" " --code-name seg\tSet the name of the CODE segment\n" + " --codesize x\tAccept larger code by factor x\n" " --cpu type\t\tSet cpu type\n" " --data-name seg\tSet the name of the DATA segment\n" " --debug\t\tDebug mode\n" @@ -314,6 +315,19 @@ static void OptCodeName (const char* Opt, const char* Arg) +static void OptCodeSize (const char* Opt, const char* Arg) +/* Handle the --codesize option */ +{ + /* Numeric argument expected */ + if (sscanf (Arg, "%u", &CodeSizeFactor) != 1 || + CodeSizeFactor < 100 || + CodeSizeFactor > 1000) { + AbEnd ("Argument for %s is invalid", Opt); + } +} + + + static void OptCreateDep (const char* Opt, const char* Arg) /* Handle the --create-dep option */ { @@ -439,24 +453,25 @@ int main (int argc, char* argv[]) { /* Program long options */ static const LongOpt OptTab[] = { - { "--add-source", 0, OptAddSource }, - { "--ansi", 0, OptAnsi }, - { "--bss-name", 1, OptBssName }, + { "--add-source", 0, OptAddSource }, + { "--ansi", 0, OptAnsi }, + { "--bss-name", 1, OptBssName }, { "--check-stack", 0, OptCheckStack }, - { "--code-name", 1, OptCodeName }, - { "--create-dep", 0, OptCreateDep }, - { "--cpu", 1, OptCPU }, - { "--data-name", 1, OptDataName }, - { "--debug", 0, OptDebug }, - { "--debug-info", 0, OptDebugInfo }, - { "--help", 0, OptHelp }, + { "--code-name", 1, OptCodeName }, + { "--codesize", 1, OptCodeSize }, + { "--create-dep", 0, OptCreateDep }, + { "--cpu", 1, OptCPU }, + { "--data-name", 1, OptDataName }, + { "--debug", 0, OptDebug }, + { "--debug-info", 0, OptDebugInfo }, + { "--help", 0, OptHelp }, { "--include-dir", 1, OptIncludeDir }, { "--rodata-name", 1, OptRodataName }, { "--signed-chars", 0, OptSignedChars }, { "--static-locals", 0, OptStaticLocals }, - { "--target", 1, OptTarget }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, }; int I; @@ -558,6 +573,7 @@ int main (int argc, char* argv[]) break; case 'i': FavourSize = 0; + CodeSizeFactor = 200; break; case 'r': EnableRegVars = 1; diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 5a1ec4a9c..833d49c70 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -568,7 +568,7 @@ static void doswitch (void) ConsumeLCurly (); /* Now decide which sort of switch we will create: */ - if (IsTypeChar (eval.e_tptr) || (FavourSize == 0 && IsClassInt (eval.e_tptr))) { + if (IsTypeChar (eval.e_tptr) || (CodeSizeFactor >= 200 && IsClassInt (eval.e_tptr))) { cascadeswitch (&eval); } else { tableswitch (&eval);