diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 6b3fc32a9..3704aebf5 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -41,6 +41,7 @@ #include "asmcode.h" #include "asmlabel.h" #include "check.h" +#include "cpu.h" #include "error.h" #include "global.h" #include "io.h" @@ -157,6 +158,11 @@ void g_preamble (void) AddCodeLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"", VER_MAJOR, VER_MINOR, VER_PATCH); AddEmptyLine (); + /* If we're producing code for some other CPU, switch the command set */ + if (CPU == CPU_65C02) { + AddCodeLine (".pc02"); + } + /* Allow auto import for runtime library routines */ AddCodeLine (".autoimport\ton"); @@ -920,7 +926,7 @@ void g_getind (unsigned flags, unsigned offs) } - + void g_leasp (int offs) /* Fetch the address of the specified symbol into the primary register */ { @@ -3096,14 +3102,26 @@ void g_inc (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t#$%02X", val & 0xFF); + if (CPU == CPU_65C02 && val <= 2) { + while (val--) { + AddCodeLine ("\tina"); + } + } else { + AddCodeLine ("\tclc"); + AddCodeLine ("\tadc\t#$%02X", val & 0xFF); + } break; } /* FALLTHROUGH */ case CF_INT: - if (FavourSize) { + if (CPU == CPU_65C02 && val == 1) { + AddCodeLine ("\tina"); + AddCodeLine ("\tbne\t*+3"); + AddCodeLine ("\tinx"); + /* Tell the optimizer that the X register may be invalid */ + AddCodeHint ("x:!"); + } else if (FavourSize) { /* Use jsr calls */ if (val <= 8) { AddCodeLine ("\tjsr\tincax%u", val); @@ -3172,8 +3190,14 @@ void g_dec (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tsec"); - AddCodeLine ("\tsbc\t#$%02X", val & 0xFF); + if (CPU == CPU_65C02 && val <= 2) { + while (val--) { + AddCodeLine ("\tdea"); + } + } else { + AddCodeLine ("\tsec"); + AddCodeLine ("\tsbc\t#$%02X", val & 0xFF); + } break; } /* FALLTHROUGH */ diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 5225d9b68..31c88fd3a 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -44,7 +44,7 @@ #include "expr.h" #include "function.h" #include "global.h" -#include "include.h" +#include "incpath.h" #include "io.h" #include "litpool.h" #include "macrotab.h" diff --git a/src/cc65/cpu.c b/src/cc65/cpu.c new file mode 100644 index 000000000..98e92e3a4 --- /dev/null +++ b/src/cc65/cpu.c @@ -0,0 +1,50 @@ +/*****************************************************************************/ +/* */ +/* cpu.c */ +/* */ +/* CPU type definitions */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include "cpu.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Current CPU */ +CPUType CPU = CPU_6502; + + + diff --git a/src/cc65/cpu.h b/src/cc65/cpu.h new file mode 100644 index 000000000..003bce908 --- /dev/null +++ b/src/cc65/cpu.h @@ -0,0 +1,63 @@ +/*****************************************************************************/ +/* */ +/* cpu.h */ +/* */ +/* CPU type definitions */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CPU_H +#define CPU_H + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Supported CPUs */ +typedef enum CPUType { + CPU_6502, + CPU_65C02 +} CPUType; + +/* Current CPU */ +extern CPUType CPU; + + + +/* End of cpu.h */ + +#endif + + + diff --git a/src/cc65/include.h b/src/cc65/include.h deleted file mode 100644 index 9d0b074fb..000000000 --- a/src/cc65/include.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * include.h - Include file handling for cc65 - * - * Ullrich von Bassewitz, 18.08.1998 - */ - - - -#ifndef INCLUDE_H -#define INCLUDE_H - - - -/*****************************************************************************/ -/* data */ -/*****************************************************************************/ - - - -#define INC_SYS 0x0001 /* Add to system include path */ -#define INC_USER 0x0002 /* Add to user include path */ - - - -/*****************************************************************************/ -/* code */ -/*****************************************************************************/ - - - -void AddIncludePath (const char* NewPath, unsigned Where); -/* Add a new include path to the existing one */ - -char* FindInclude (const char* Name, unsigned Where); -/* Find an include file. Return a pointer to a malloced area that contains - * the complete path, if found, return 0 otherwise. - */ - - - -/* End of include.h */ -#endif - - - diff --git a/src/cc65/include.c b/src/cc65/incpath.c similarity index 56% rename from src/cc65/include.c rename to src/cc65/incpath.c index e68227fdf..0349c253d 100644 --- a/src/cc65/include.c +++ b/src/cc65/incpath.c @@ -1,8 +1,35 @@ -/* - * include.c - Include file handling for cc65 - * - * Ullrich von Bassewitz, 18.08.1998 - */ +/*****************************************************************************/ +/* */ +/* incpath.c */ +/* */ +/* Include path handling for cc65 */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ @@ -18,12 +45,12 @@ #endif #include "mem.h" -#include "include.h" +#include "incpath.h" /*****************************************************************************/ -/* data */ +/* Data */ /*****************************************************************************/ @@ -34,7 +61,7 @@ static char* UserIncludePath = 0; /*****************************************************************************/ -/* code */ +/* Code */ /*****************************************************************************/ @@ -161,4 +188,3 @@ char* FindInclude (const char* Name, unsigned Where) - diff --git a/src/cc65/incpath.h b/src/cc65/incpath.h new file mode 100644 index 000000000..6e83de21d --- /dev/null +++ b/src/cc65/incpath.h @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* */ +/* incpath.h */ +/* */ +/* Include path handling for cc65 */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef INCPATH_H +#define INCPATH_H + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +#define INC_SYS 0x0001 /* Add to system include path */ +#define INC_USER 0x0002 /* Add to user include path */ + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void AddIncludePath (const char* NewPath, unsigned Where); +/* Add a new include path to the existing one */ + +char* FindInclude (const char* Name, unsigned Where); +/* Find an include file. Return a pointer to a malloced area that contains + * the complete path, if found, return 0 otherwise. + */ + + + +/* End of incpath.h */ +#endif + + + diff --git a/src/cc65/io.c b/src/cc65/io.c index 517aa9520..c94d8b863 100644 --- a/src/cc65/io.c +++ b/src/cc65/io.c @@ -112,7 +112,7 @@ static void CloseInclude (void) -int readline (void) +int NextLine (void) /* Get a line from the current input. Returns -1 on end of file. */ { unsigned Len; diff --git a/src/cc65/io.h b/src/cc65/io.h index aa836700e..46671c0d1 100644 --- a/src/cc65/io.h +++ b/src/cc65/io.h @@ -73,7 +73,7 @@ int gch (void); * pointer (no end of line check is performed). */ -int readline (void); +int NextLine (void); /* Get a line from the current input. Returns -1 on end of file. */ diff --git a/src/cc65/main.c b/src/cc65/main.c index e86f65900..e23e2f33a 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -1,4 +1,37 @@ -/* CC65 main program */ +/*****************************************************************************/ +/* */ +/* main.c */ +/* */ +/* cc65 main program */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + #include #include @@ -6,13 +39,15 @@ #include #include +#include "../common/cmdline.h" #include "../common/version.h" #include "asmcode.h" #include "compile.h" +#include "cpu.h" #include "error.h" #include "global.h" -#include "include.h" +#include "incpath.h" #include "io.h" #include "macrotab.h" #include "mem.h" @@ -50,57 +85,46 @@ static const char* TargetNames [] = { -static void usage (int ExitCode) +static void Usage (void) { - fputs ("Usage: cc65 [options] file\n" - "\t-d\t\tDebug mode\n" - "\t-g\t\tAdd debug info to object files\n" - "\t-h\t\tPrint this help\n" - "\t-j\t\tDefault characters are signed\n" - "\t-o name\t\tName the output file\n" - "\t-tx\t\tSet target system x\n" - "\t-v\t\tVerbose mode\n" - "\t-A\t\tStrict ANSI mode\n" - "\t-Cl\t\tMake local variables static\n" - "\t-Dsym[=defn]\tDefine a symbol\n" - "\t-I path\t\tSet include directory\n" - "\t-O\t\tOptimize code\n" - "\t-Oi\t\tOptimize code, inline more code\n" - "\t-Or\t\tEnable register variables\n" - "\t-Os\t\tInline some known functions\n" - "\t-T\t\tInclude source as comment\n" - "\t-V\t\tPrint version number\n" - "\t-W\t\tSuppress warnings\n", - stderr); - exit (ExitCode); + fprintf (stderr, + "Usage: cc65 [options] file\n" + "Short options:\n" + " -d\t\t\tDebug mode\n" + " -g\t\t\tAdd debug info to object file\n" + " -h\t\t\tPrint this help\n" + " -j\t\t\tDefault characters are signed\n" + " -o name\t\tName the output file\n" + " -t sys\t\tSet the target system\n" + " -v\t\t\tIncrease verbosity\n" + " -A\t\t\tStrict ANSI mode\n" + " -Cl\t\t\tMake local variables static\n" + " -Dsym[=defn]\t\tDefine a symbol\n" + " -I path\t\tSet an include directory search path\n" + " -O\t\t\tOptimize code\n" + " -Oi\t\t\tOptimize code, inline more code\n" + " -Or\t\t\tEnable register variables\n" + " -Os\t\t\tInline some known functions\n" + " -T\t\t\tInclude source as comment\n" + " -V\t\t\tPrint the compiler version number\n" + " -W\t\t\tSuppress warnings\n" + "\n" + "Long options:\n" + " --ansi\t\tStrict ANSI mode\n" + " --cpu type\t\tSet cpu type\n" + " --debug-info\t\tAdd debug info to object file\n" + " --help\t\tHelp (this text)\n" + " --include-dir dir\tSet an include directory search path\n" + " --signed-chars\tDefault characters are signed\n" + " --target sys\t\tSet the target system\n" + " --verbose\t\tIncrease verbosity\n" + " --version\t\tPrint the compiler version number\n"); } -static char* GetArg (int* ArgNum, char* argv [], unsigned Len) -/* Get an option argument */ -{ - char* Arg = argv [*ArgNum]; - if (Arg [Len] != '\0') { - /* Argument appended */ - return Arg + Len; - } else { - /* Separate argument */ - Arg = argv [*ArgNum + 1]; - if (Arg == 0) { - /* End of arguments */ - fprintf (stderr, "Option requires an argument: %s\n", argv [*ArgNum]); - exit (EXIT_FAILURE); - } - ++(*ArgNum); - return Arg; - } -} - - - -/* Define a CBM system */ static void cbmsys (const char* sys) +/* Define a CBM system */ { AddNumericMacro ("__CBM__", 1); AddNumericMacro (sys, 1); @@ -133,8 +157,8 @@ static int MapSys (const char* Name) -/* Define a target system */ static void SetSys (const char* Sys) +/* Define a target system */ { switch (Target = MapSys (Sys)) { @@ -142,7 +166,7 @@ static void SetSys (const char* Sys) break; case TGT_ATARI: - AddNumericMacro ("__ATARI__", 1); + AddNumericMacro ("__ATARI__", 1); break; case TGT_C64: @@ -184,21 +208,12 @@ static void SetSys (const char* Sys) default: fputs ("Unknown system type\n", stderr); - usage (EXIT_FAILURE); + exit (EXIT_FAILURE); } } -static void InvSym (const char* Def) -/* Print an error about an invalid macro definition and die */ -{ - fprintf (stderr, "Invalid macro definition: `%s'\n", Def); - exit (EXIT_FAILURE); -} - - - static void DefineSym (const char* Def) /* Define a symbol on the command line */ { @@ -206,7 +221,7 @@ static void DefineSym (const char* Def) /* The symbol must start with a character or underline */ if (Def [0] != '_' && !isalpha (Def [0])) { - InvSym (Def); + InvDef (Def); } /* Check the symbol name */ @@ -217,7 +232,7 @@ static void DefineSym (const char* Def) /* Do we have a value given? */ if (*P != '=') { if (*P != '\0') { - InvSym (Def); + InvDef (Def); } /* No value given. Define the macro with the value 1 */ AddNumericMacro (Def, 1); @@ -236,29 +251,147 @@ static void DefineSym (const char* Def) /* Define this as a macro */ AddTextMacro (S, Q); - /* Release the allocated memory */ - xfree (S); + /* Release the allocated memory */ + xfree (S); } } -int main (int argc, char **argv) +static void OptAnsi (const char* Opt, const char* Arg) +/* Compile in strict ANSI mode */ { - int i; - char *argp; + ANSI = 1; +} + + + +static void OptCPU (const char* Opt, const char* Arg) +/* Handle the --cpu option */ +{ + if (Arg == 0) { + NeedArg (Opt); + } + if (strcmp (Arg, "6502") == 0) { + CPU = CPU_6502; + } else if (strcmp (Arg, "65C02") == 0) { + CPU = CPU_65C02; + } else { + fprintf (stderr, "Invalid CPU: `%s'\n", Arg); + exit (EXIT_FAILURE); + } +} + + + +static void OptDebugInfo (const char* Opt, const char* Arg) +/* Add debug info to the object file */ +{ + DebugInfo = 1; +} + + + +static void OptHelp (const char* Opt, const char* Arg) +/* Print usage information and exit */ +{ + Usage (); + exit (EXIT_SUCCESS); +} + + + +static void OptIncludeDir (const char* Opt, const char* Arg) +/* Add an include search path */ +{ + if (Arg == 0) { + NeedArg (Opt); + } + AddIncludePath (Arg, INC_SYS | INC_USER); +} + + + +static void OptSignedChars (const char* Opt, const char* Arg) +/* Make default characters signed */ +{ + SignedChars = 1; +} + + + +static void OptTarget (const char* Opt, const char* Arg) +/* Set the target system */ +{ + if (Arg == 0) { + NeedArg (Opt); + } + SetSys (Arg); +} + + + +static void OptVerbose (const char* Opt, const char* Arg) +/* Increase verbosity */ +{ + ++Verbose; +} + + + +static void OptVersion (const char* Opt, const char* Arg) +/* Print the assembler version */ +{ + fprintf (stderr, + "cc65 V%u.%u.%u\n", + VER_MAJOR, VER_MINOR, VER_PATCH); +} + + + +int main (int argc, char* argv[]) +{ + /* Program long options */ + static const LongOpt OptTab[] = { + { "--ansi", 0, OptAnsi }, + { "--cpu", 1, OptCPU }, + { "--debug-info", 0, OptDebugInfo }, + { "--help", 0, OptHelp }, + { "--include-dir", 1, OptIncludeDir }, + { "--signed-chars", 0, OptSignedChars }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, + }; + + int I; char out_name [256]; - char* p; /* Initialize the output file name */ out_name [0] = '\0'; fin = NULL; + /* Initialize the cmdline module */ + InitCmdLine (argc, argv); + /* Parse the command line */ - for (i = 1; i < argc; i++) { - if (*(argp = argv[i]) == '-') { - switch (argp[1]) { + I = 1; + while (I < argc) { + + const char* P; + + /* Get the argument */ + const char* Arg = argv [I]; + + /* Check for an option */ + if (Arg [0] == '-') { + + switch (Arg [1]) { + + case '-': + LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0])); + break; case 'd': /* debug mode */ Debug = 1; @@ -266,68 +399,68 @@ int main (int argc, char **argv) case 'h': case '?': - usage (EXIT_SUCCESS); + OptHelp (Arg, 0); break; case 'g': - DebugInfo = 1; + OptDebugInfo (Arg, 0); break; case 'j': - SignedChars = 1; + OptSignedChars (Arg, 0); break; - case 'o': - strcpy (out_name, GetArg (&i, argv, 2)); + case 'o': + strcpy (out_name, GetArg (&I, 2)); break; case 't': - SetSys (GetArg (&i, argv, 2)); + OptTarget (Arg, GetArg (&I, 2)); break; case 'v': - ++Verbose; + OptVerbose (Arg, 0); break; case 'A': - ANSI = 1; + OptAnsi (Arg, 0); break; case 'C': - p = argp + 2; - while (*p) { - switch (*p++) { - case 'l': - LocalsAreStatic = 1; - break; - } + P = Arg + 2; + while (*P) { + switch (*P++) { + case 'l': + LocalsAreStatic = 1; + break; + } } break; case 'D': - DefineSym (GetArg (&i, argv, 2)); + DefineSym (GetArg (&I, 2)); break; case 'I': - AddIncludePath (GetArg (&i, argv, 2), INC_SYS | INC_USER); + OptIncludeDir (Arg, GetArg (&I, 2)); break; case 'O': Optimize = 1; - p = argp + 2; - while (*p) { - switch (*p++) { - case 'f': - sscanf (p, "%lx", (long*) &OptDisable); - break; - case 'i': - FavourSize = 0; - break; - case 'r': - EnableRegVars = 1; + P = Arg + 2; + while (*P) { + switch (*P++) { + case 'f': + sscanf (P, "%lx", (long*) &OptDisable); + break; + case 'i': + FavourSize = 0; + break; + case 'r': + EnableRegVars = 1; break; case 's': - InlineStdFuncs = 1; + InlineStdFuncs = 1; break; } } @@ -338,8 +471,7 @@ int main (int argc, char **argv) break; case 'V': - fprintf (stderr, "cc65 V%u.%u.%u\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + OptVersion (Arg, 0); break; case 'W': @@ -347,21 +479,26 @@ int main (int argc, char **argv) break; default: - fprintf (stderr, "Invalid option %s\n", argp); - usage (EXIT_FAILURE); + UnknownOption (Arg); + break; } } else { if (fin) { fprintf (stderr, "additional file specs ignored\n"); } else { - fin = xstrdup (argp); + fin = xstrdup (Arg); inp = fopen (fin, "r"); if (inp == 0) { Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno)); } } } + + /* Next argument */ + ++I; } + + /* Did we have a file spec on the command line? */ if (!fin) { fprintf (stderr, "%s: No input files\n", argv [0]); exit (EXIT_FAILURE); @@ -370,8 +507,10 @@ int main (int argc, char **argv) /* Create the output file name. We should really have * some checks for string overflow, but I'll drop this because of the * additional code size it would need (as in other places). Sigh. + * #### To be removed */ if (out_name [0] == '\0') { + char* p; /* No output name given, create default */ strcpy (out_name, fin); if ((p = strrchr (out_name, '.'))) { @@ -414,3 +553,4 @@ int main (int argc, char **argv) } + diff --git a/src/cc65/make/gcc.mak b/src/cc65/make/gcc.mak index d30ffd444..1b1519c17 100644 --- a/src/cc65/make/gcc.mak +++ b/src/cc65/make/gcc.mak @@ -16,6 +16,7 @@ OBJS = anonname.o \ check.o \ codegen.o \ compile.o \ + cpu.o \ ctrans.o \ datatype.o \ declare.o \ @@ -26,7 +27,7 @@ OBJS = anonname.o \ global.o \ goto.o \ ident.o \ - include.o \ + incpath.o \ io.o \ litpool.o \ locals.o \ diff --git a/src/cc65/make/watcom.mak b/src/cc65/make/watcom.mak index a0d6625ea..9e758ebe9 100644 --- a/src/cc65/make/watcom.mak +++ b/src/cc65/make/watcom.mak @@ -70,6 +70,7 @@ OBJS = anonname.obj \ check.obj \ codegen.obj \ compile.obj \ + cpu.obj \ ctrans.obj \ datatype.obj \ declare.obj \ @@ -80,7 +81,7 @@ OBJS = anonname.obj \ global.obj \ goto.obj \ ident.obj \ - include.obj \ + incpath.obj \ io.obj \ litpool.obj \ locals.obj \ @@ -126,6 +127,7 @@ FILE asmline.obj FILE check.obj FILE codegen.obj FILE compile.obj +FILE cpu.obj FILE ctrans.obj FILE datatype.obj FILE declare.obj @@ -136,7 +138,7 @@ FILE function.obj FILE global.obj FILE goto.obj FILE ident.obj -FILE include.obj +FILE incpath.obj FILE io.obj FILE litpool.obj FILE locals.obj diff --git a/src/cc65/optimize.c b/src/cc65/optimize.c index ac8480cef..8302ebdc2 100644 --- a/src/cc65/optimize.c +++ b/src/cc65/optimize.c @@ -40,6 +40,7 @@ #include "asmlabel.h" #include "asmline.h" #include "check.h" +#include "cpu.h" #include "error.h" #include "global.h" #include "io.h" @@ -123,10 +124,14 @@ static const struct { { "\tcmp\t", 0, REG_A, REG_NONE }, { "\tcpx\t", 0, REG_X, REG_NONE }, { "\tcpy\t", 0, REG_Y, REG_NONE }, + { "\tdea", 1, REG_A, REG_NONE }, + { "\tdec\ta", 1, REG_A, REG_NONE }, { "\tdec\t", 0, REG_NONE, REG_NONE }, { "\tdex", 1, REG_X, REG_NONE }, { "\tdey", 1, REG_Y, REG_NONE }, { "\teor\t", 0, REG_A, REG_NONE }, + { "\tina", 1, REG_A, REG_NONE }, + { "\tinc\ta", 1, REG_A, REG_NONE }, { "\tinc\t", 0, REG_NONE, REG_NONE }, { "\tinx", 1, REG_X, REG_NONE }, { "\tiny", 1, REG_Y, REG_NONE }, @@ -164,6 +169,7 @@ static const struct { { "\tsta\t", 0, REG_A, REG_NONE }, { "\tstx\t", 0, REG_X, REG_NONE }, { "\tsty\t", 0, REG_Y, REG_NONE }, + { "\tstz\t", 0, REG_NONE, REG_NONE }, { "\ttax", 1, REG_A, REG_X }, { "\ttay", 1, REG_A, REG_Y }, { "\ttsx", 1, REG_NONE, REG_X }, @@ -559,7 +565,7 @@ static int IsCondJump (Line* L) -static int IsXIndAddrMode (Line* L) +static int IsXAddrMode (Line* L) /* Return true if the given line does use the X register */ { unsigned Len = strlen (L->Line); @@ -569,15 +575,15 @@ static int IsXIndAddrMode (Line* L) -static int NoXIndAddrMode (Line* L) +static int NoXAddrMode (Line* L) /* Return true if the given line does use the X register */ { - return !IsXIndAddrMode (L); + return !IsXAddrMode (L); } -static int IsYIndAddrMode (Line* L) +static int IsYAddrMode (Line* L) /* Return true if the given line does use the Y register */ { unsigned Len = strlen (L->Line); @@ -779,7 +785,13 @@ static unsigned EstimateDataSize (Line* L, unsigned Chunk) static unsigned EstimateSize (Line* L) /* Estimate the size of an instruction */ { - static const char* Transfers [] = { + static const char* OneByteCmds [] = { + "\tdea", + "\tdex", + "\tdey", + "\tina", + "\tinx", + "\tiny" "\ttax", "\ttay", "\ttsx", @@ -819,7 +831,7 @@ static unsigned EstimateSize (Line* L) if (LineMatchX (L, LongBranches) >= 0) { return 5; } - if (LineMatchX (L, Transfers) >= 0) { + if (LineMatchX (L, OneByteCmds) >= 0) { return 1; } return 3; @@ -1141,9 +1153,9 @@ static unsigned RVUInt2 (Line* L, /* Evaluate the use flags, check for addressing modes */ R = CmdDesc[I].Use; - if (IsXIndAddrMode (L)) { + if (IsXAddrMode (L)) { R |= REG_X; - } else if (IsYIndAddrMode (L)) { + } else if (IsYAddrMode (L)) { R |= REG_Y; } if (R) { @@ -1323,7 +1335,7 @@ static void OptCompares1 (void) (Cond = TosCmpFunc (L2[4])) >= 0) { /* Replace it */ - if (IsXIndAddrMode (L2[0])) { + if (IsXAddrMode (L2[0])) { /* The load is X indirect, so we may not remove the load * of the X register. */ @@ -1377,7 +1389,7 @@ static void OptCompares1 (void) Offs = GetHexNum (L2[2]->Line+7) - 2; /* Replace it */ - if (IsXIndAddrMode (L2[0])) { + if (IsXAddrMode (L2[0])) { /* The load is X indirect, so we may not remove the load * of the X register. */ @@ -1637,7 +1649,7 @@ static void OptLoads (void) LineFullMatch (L2 [1], "\tjsr\tpushax")) { /* Be sure, X is not used in the load */ - if (NoXIndAddrMode (L2 [0])) { + if (NoXAddrMode (L2 [0])) { /* Replace the subroutine call */ L2 [1] = ReplaceLine (L2 [1], "\tjsr\tpusha0"); @@ -1667,7 +1679,7 @@ static void OptLoads (void) LineMatch (L2 [1], "\tcmp\t#$")) { /* Be sure, X is not used in the load */ - if (NoXIndAddrMode (L2 [0])) { + if (NoXAddrMode (L2 [0])) { /* Remove the unnecessary load */ FreeLine (L); @@ -1693,7 +1705,7 @@ static void OptLoads (void) LineFullMatch (L2 [1], "\tjsr\tbnega")) { /* Be sure, X is not used in the load */ - if (NoXIndAddrMode (L2 [0])) { + if (NoXAddrMode (L2 [0])) { /* Remove the unnecessary load */ FreeLine (L); @@ -3630,12 +3642,16 @@ static Line* OptOneBlock (Line* L) if (A != -1) { A = (A << 1) & 0xFF; } + } else if (CPU == CPU_65C02 && LineFullMatch (L, "\tdea")) { + DEC (A, 1); } else if (LineFullMatch (L, "\tdex")) { DEC (X, 1); } else if (LineFullMatch (L, "\tdey")) { DEC (Y, 1); } else if (LineMatch (L, "\teor")) { A = -1; + } else if (CPU == CPU_65C02 && LineFullMatch (L, "\tina")) { + INC (A, 1); } else if (LineFullMatch (L, "\tinx")) { INC (X, 1); } else if (LineFullMatch (L, "\tiny")) { @@ -3949,7 +3965,7 @@ static Line* OptOneBlock (Line* L) /* The value loaded is not used later, remove it */ Delete = 1; } else if (LineMatch (L, "\tlda\t(")) { - if (IsXIndAddrMode (L)) { + if (IsXAddrMode (L)) { /* lda (zp,x) - if Y and X are both zero, replace by * load indirect y and save one cycle in some cases. */ @@ -3982,6 +3998,13 @@ static Line* OptOneBlock (Line* L) } else if (NewVal == Y) { /* Requested value is already in Y */ L = ReplaceLine (L, "\ttya"); + } else if (CPU == CPU_65C02 && A != -1) { + /* Try ina/dea operators of 65C02 */ + if (NewVal == ((A - 1) & 0xFF)) { + L = ReplaceLine (L, "\tdea"); + } else if (NewVal == ((A + 1) & 0xFF)) { + L = ReplaceLine (L, "\tina"); + } } /* Anyway, the new value is now in A */ A = NewVal; @@ -4066,6 +4089,22 @@ static Line* OptOneBlock (Line* L) A = X = Y = -1; } else if (LineMatch (L, "\tsbc\t")) { A = -1; + } else if (CPU == CPU_65C02 && LineMatch (L, "\tst")) { + /* Try to replace by stz if possible */ + if (A == 0 && LineMatch (L, "\tsta\t")) { + /* Not indirect and not Y allowed */ + if (L->Line[5] != '(' && !IsYAddrMode (L)) { + L->Line[3] = 'z'; + } + } else if (X == 0 && LineMatch (L, "\tstx\t")) { + /* absolute,y not allowed */ + if (!IsYAddrMode (L)) { + L->Line[3] = 'z'; + } + } else if (Y == 0 && LineMatch (L, "\tsty\t")) { + /* sty and stz share all addressing modes */ + L->Line[3] = 'z'; + } } else if (LineFullMatch (L, "\ttax")) { if (A != -1 && X == A) { /* Load has no effect */ diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index e30379371..89c92aa15 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -12,7 +12,7 @@ #include "expr.h" #include "global.h" #include "ident.h" -#include "include.h" +#include "incpath.h" #include "io.h" #include "macrotab.h" #include "mem.h" @@ -89,7 +89,7 @@ static void comment (void) gch (); while (*lptr != '*' || nch () != '/') { if (*lptr == '\0') { - if (readline () == 0) { + if (NextLine () == 0) { PPError (ERR_EOF_IN_COMMENT, StartingLine); return; } @@ -283,7 +283,7 @@ static int MacroCall (Macro* M) skipblank (); } else if (C == '\0') { /* End of line inside macro argument list - read next line */ - if (readline () == 0) { + if (NextLine () == 0) { return 0; } } else { @@ -864,7 +864,7 @@ void preprocess (void) } } - if (readline () == 0) { + if (NextLine () == 0) { if (i_ifdef >= 0) { PPError (ERR_CPP_ENDIF_EXPECTED); } diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 27b6a15d1..fd88f31f3 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -137,7 +137,7 @@ static int skipwhite (void) { while (1) { while (*lptr == 0) { - if (readline () == 0) { + if (NextLine () == 0) { return 0; } preprocess ();