/* */
/* */
/* */
-/* (C) 2000-2001 Ullrich von Bassewitz */
+/* (C) 2000-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "abend.h"
#include "chartype.h"
#include "cmdline.h"
+#include "debugflag.h"
#include "fname.h"
#include "print.h"
+#include "segdefs.h"
#include "target.h"
#include "tgttrans.h"
#include "version.h"
fprintf (stderr,
"Usage: %s [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\tHelp (this text)\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"
" -T\t\t\tInclude source as comment\n"
" -V\t\t\tPrint the compiler version number\n"
" -W\t\t\tSuppress warnings\n"
+ " -d\t\t\tDebug mode\n"
+ " -g\t\t\tAdd debug info to object file\n"
+ " -h\t\t\tHelp (this text)\n"
+ " -j\t\t\tDefault characters are signed\n"
+ " -o name\t\tName the output file\n"
+ " -r\t\t\tEnable register variables\n"
+ " -t sys\t\tSet the target system\n"
+ " -v\t\t\tIncrease verbosity\n"
"\n"
"Long options:\n"
+ " --add-source\t\tInclude source as comment\n"
" --ansi\t\tStrict ANSI mode\n"
" --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"
+ " --codesize x\t\tAccept larger code by factor x\n"
" --cpu type\t\tSet cpu type\n"
+ " --create-dep\t\tCreate a make dependency file\n"
" --data-name seg\tSet the name of the DATA segment\n"
" --debug\t\tDebug mode\n"
" --debug-info\t\tAdd debug info to object file\n"
+ " --debug-opt name\tDebug optimization steps\n"
" --disable-opt name\tDisable an optimization step\n"
" --enable-opt name\tEnable an optimization step\n"
" --help\t\tHelp (this text)\n"
" --include-dir dir\tSet an include directory search path\n"
+ " --list-opt-steps\tList all optimizer steps and exit\n"
+ " --register-space b\tSet space available for register variables\n"
+ " --register-vars\tEnable register variables\n"
" --rodata-name seg\tSet the name of the RODATA segment\n"
" --signed-chars\tDefault characters are signed\n"
" --static-locals\tMake local variables static\n"
static void cbmsys (const char* sys)
/* Define a CBM system */
{
- AddNumericMacro ("__CBM__", 1);
- AddNumericMacro (sys, 1);
+ DefineNumericMacro ("__CBM__", 1);
+ DefineNumericMacro (sys, 1);
}
case TGT_NONE:
break;
+ case TGT_MODULE:
+ AbEnd ("Cannot use `module' as a target for the compiler");
+ break;
+
case TGT_ATARI:
- AddNumericMacro ("__ATARI__", 1);
+ DefineNumericMacro ("__ATARI__", 1);
+ break;
+
+ case TGT_C16:
+ cbmsys ("__C16__");
break;
case TGT_C64:
cbmsys ("__C64__");
break;
+ case TGT_VIC20:
+ cbmsys ("__VIC20__");
+ break;
+
case TGT_C128:
cbmsys ("__C128__");
break;
cbmsys ("__PLUS4__");
break;
+ case TGT_CBM510:
+ cbmsys ("__CBM510__");
+ break;
+
case TGT_CBM610:
cbmsys ("__CBM610__");
break;
break;
case TGT_BBC:
- AddNumericMacro ("__BBC__", 1);
+ DefineNumericMacro ("__BBC__", 1);
break;
case TGT_APPLE2:
- AddNumericMacro ("__APPLE2__", 1);
+ DefineNumericMacro ("__APPLE2__", 1);
break;
case TGT_GEOS:
/* Do not handle as a CBM system */
- AddNumericMacro ("__GEOS__", 1);
+ DefineNumericMacro ("__GEOS__", 1);
break;
+ case TGT_LUNIX:
+ DefineNumericMacro ("__LUNIX__", 1);
+ break;
+
+ case TGT_ATMOS:
+ DefineNumericMacro ("__ATMOS__", 1);
+ break;
+
default:
AbEnd ("Unknown target system type");
}
InvDef (Def);
}
/* No value given. Define the macro with the value 1 */
- AddNumericMacro (Def, 1);
+ DefineNumericMacro (Def, 1);
} else {
/* We have a value, P points to the '=' character. Since the argument
* is const, create a copy and replace the '=' in the copy by a zero
*Q++ = '\0';
/* Define this as a macro */
- AddTextMacro (S, Q);
+ DefineTextMacro (S, Q);
/* Release the allocated memory */
xfree (S);
-static void OptAddSource (const char* Opt, const char* Arg)
+static void OptAddSource (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Add source lines as comments in generated assembler file */
{
AddSource = 1;
-static void OptAnsi (const char* Opt, const char* Arg)
+static void OptAnsi (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Compile in strict ANSI mode */
{
ANSI = 1;
-static void OptBssName (const char* Opt, const char* Arg)
+static void OptBssName (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --bss-name option */
{
/* Check for a valid name */
-static void OptCheckStack (const char* Opt, const char* Arg)
+static void OptCheckStack (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Handle the --check-stack option */
{
CheckStack = 1;
-static void OptCodeName (const char* Opt, const char* Arg)
+static void OptCodeName (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --code-name option */
{
/* Check for a valid name */
-static void OptCreateDep (const char* Opt, const char* Arg)
+static void OptCreateDep (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Handle the --create-dep option */
{
CreateDep = 1;
} else if (strcmp (Arg, "65C02") == 0) {
CPU = CPU_65C02;
} else {
- AbEnd ("Invalid CPU: `%s'", Arg);
+ AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
}
}
-static void OptDataName (const char* Opt, const char* Arg)
-/* Handle the --code-name option */
+static void OptDataName (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --data-name option */
{
/* Check for a valid name */
CheckSegName (Arg);
-static void OptDebug (const char* Opt, const char* Arg)
+static void OptDebug (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Compiler debug mode */
{
- Debug = 1;
+ ++Debug;
}
-static void OptDebugInfo (const char* Opt, const char* Arg)
+static void OptDebugInfo (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Add debug info to the object file */
{
DebugInfo = 1;
-static void OptDisableOpt (const char* Opt, const char* Arg)
+static void OptDebugOpt (const char* Opt attribute ((unused)), const char* Arg)
+/* Debug optimization steps */
+{
+ char Buf [128];
+ char* Line;
+
+ /* Open the file */
+ FILE* F = fopen (Arg, "r");
+ if (F == 0) {
+ AbEnd ("Cannot open `%s': %s", Arg, strerror (errno));
+ }
+
+ /* Read line by line, ignore empty lines and switch optimization
+ * steps on/off.
+ */
+ while (fgets (Buf, sizeof (Buf), F) != 0) {
+
+ /* Remove trailing control chars. This will also remove the
+ * trailing newline.
+ */
+ unsigned Len = strlen (Buf);
+ while (Len > 0 && IsControl (Buf[Len-1])) {
+ --Len;
+ }
+ Buf[Len] = '\0';
+
+ /* Get a pointer to the buffer and remove leading white space */
+ Line = Buf;
+ while (IsBlank (*Line)) {
+ ++Line;
+ }
+
+ /* Check the first character and enable/disable the step or
+ * ignore the line
+ */
+ switch (*Line) {
+
+ case '\0':
+ case '#':
+ case ';':
+ /* Empty or comment line */
+ continue;
+
+ case '-':
+ DisableOpt (Line+1);
+ break;
+
+ case '+':
+ ++Line;
+ /* FALLTHROUGH */
+
+ default:
+ EnableOpt (Line);
+ break;
+
+ }
+
+ }
+
+ /* Close the file, no error check here since we were just reading and
+ * this is only a debug function.
+ */
+ (void) fclose (F);
+}
+
+
+
+static void OptDisableOpt (const char* Opt attribute ((unused)), const char* Arg)
/* Disable an optimization step */
{
DisableOpt (Arg);
-static void OptEnableOpt (const char* Opt, const char* Arg)
+static void OptEnableOpt (const char* Opt attribute ((unused)), const char* Arg)
/* Enable an optimization step */
{
EnableOpt (Arg);
-static void OptHelp (const char* Opt, const char* Arg)
+static void OptHelp (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Print usage information and exit */
{
Usage ();
-static void OptIncludeDir (const char* Opt, const char* Arg)
+static void OptIncludeDir (const char* Opt attribute ((unused)), const char* Arg)
/* Add an include search path */
{
AddIncludePath (Arg, INC_SYS | INC_USER);
-static void OptRodataName (const char* Opt, const char* Arg)
+static void OptListOptSteps (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* List all optimizer steps */
+{
+ /* List the optimizer steps */
+ ListOptSteps (stdout);
+
+ /* Terminate */
+ exit (EXIT_SUCCESS);
+}
+
+
+
+static void OptRegisterSpace (const char* Opt, const char* Arg)
+/* Handle the --register-space option */
+{
+ /* Numeric argument expected */
+ if (sscanf (Arg, "%u", &RegisterSpace) != 1 || RegisterSpace > 256) {
+ AbEnd ("Argument for option %s is invalid", Opt);
+ }
+}
+
+
+
+static void OptRegisterVars (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* Handle the --register-vars option */
+{
+ EnableRegVars = 1;
+}
+
+
+
+static void OptRodataName (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --rodata-name option */
{
/* Check for a valid name */
-static void OptSignedChars (const char* Opt, const char* Arg)
+static void OptSignedChars (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Make default characters signed */
{
SignedChars = 1;
-static void OptStaticLocals (const char* Opt, const char* Arg)
+static void OptStaticLocals (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Place local variables in static storage */
{
StaticLocals = 1;
-static void OptTarget (const char* Opt, const char* Arg)
+static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
/* Set the target system */
{
SetSys (Arg);
-static void OptVerbose (const char* Opt, const char* Arg)
+static void OptVerbose (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Increase verbosity */
{
++Verbosity;
-static void OptVersion (const char* Opt, const char* Arg)
+static void OptVersion (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Print the assembler version */
{
fprintf (stderr,
{ "--check-stack", 0, OptCheckStack },
{ "--code-name", 1, OptCodeName },
{ "--codesize", 1, OptCodeSize },
- { "--create-dep", 0, OptCreateDep },
{ "--cpu", 1, OptCPU },
+ { "--create-dep", 0, OptCreateDep },
{ "--data-name", 1, OptDataName },
{ "--debug", 0, OptDebug },
{ "--debug-info", 0, OptDebugInfo },
+ { "--debug-opt", 1, OptDebugOpt },
{ "--disable-opt", 1, OptDisableOpt },
{ "--enable-opt", 1, OptEnableOpt, },
{ "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir },
+ { "--list-opt-steps", 0, OptListOptSteps },
+ { "--register-space", 1, OptRegisterSpace },
+ { "--register-vars", 0, OptRegisterVars },
{ "--rodata-name", 1, OptRodataName },
{ "--signed-chars", 0, OptSignedChars },
{ "--static-locals", 0, OptStaticLocals },
- { "--target", 1, OptTarget },
+ { "--target", 1, OptTarget },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
};
- int I;
+ unsigned I;
/* Initialize the output file name */
const char* OutputFile = 0;
/* Parse the command line */
I = 1;
- while (I < (int)ArgCount) {
+ while (I < ArgCount) {
const char* P;
OutputFile = GetArg (&I, 2);
break;
+ case 'r':
+ OptRegisterVars (Arg, 0);
+ break;
+
case 't':
OptTarget (Arg, GetArg (&I, 2));
break;
OptStaticLocals (Arg, 0);
break;
default:
- UnknownOption (Arg);
- break;
+ UnknownOption (Arg);
+ break;
}
}
break;
break;
case 'i':
FavourSize = 0;
- CodeSizeFactor = 200;
+ CodeSizeFactor = 200;
break;
case 'r':
- EnableRegVars = 1;
+ EnableRegVars = 1;
break;
case 's':
InlineStdFuncs = 1;
- break;
+ break;
}
}
break;
AbEnd ("No input files");
}
- /* Open the input file */
- OpenMainFile (InputFile);
-
/* Create the output file name if it was not explicitly given */
if (OutputFile == 0) {
OutputFile = MakeFilename (InputFile, ".s");
}
-
-
-
/* Go! */
- Compile ();
+ Compile (InputFile);
/* Create the output file if we didn't had any errors */
if (ErrorCount == 0 || Debug) {