#include "MySystem.h"
#include "SDCCmacro.h"
#include "SDCCutil.h"
+#include "SDCCargs.h"
#if NATIVE_WIN32
#include <process.h>
int currRegBank = 0;
struct optimize optimize;
struct options options;
-char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
+char *VersionString = SDCC_VERSION_STR;
int preProcOnly = 0;
int noAssemble = 0;
char *linkOptions[128];
#define OPTION_SHORT_IS_8BITS "--short-is-8bits"
#define OPTION_TINI_LIBID "--tini-libid"
-/** Table of all options supported by all ports.
- This table provides:
- * A reference for all options.
- * An easy way to maintain help for the options.
- * Automatic support for setting flags on simple options.
-*/
-typedef struct {
- /** The short option character e.g. 'h' for -h. 0 for none. */
- char shortOpt;
- /** Long option e.g. "--help". Includes the -- prefix. NULL for
- none. */
- const char *longOpt;
- /** Pointer to an int that will be incremented every time the
- option is encountered. May be NULL.
- */
- int *pparameter;
- /** Help text to go with this option. May be NULL. */
- const char *help;
-} OPTION;
-
static const OPTION
optionsTable[] = {
{ 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
+ { 'p', NULL, NULL, "Select port specific processor e.g. -mpic14 -p16f84" },
{ 'd', NULL, NULL, NULL },
{ 'D', NULL, NULL, "Define macro as in -Dmacro" },
{ 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
{ 0, "--cyclomatic", &options.cyclomatic, NULL },
{ 0, "--nooverlay", &options.noOverlay, NULL },
{ 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
+ { 0, "--xram-movc", &options.xram_movc, "Use movc instead of movx to read xram (xdata)" },
{ 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
{ 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
{ 0, "--peep-asm", &options.asmpeep, NULL },
{ 0, "--all-callee-saves", &options.all_callee_saves, "callee will always save registers used" },
{ 0, "--use-accelerator", &options.useAccelerator,"generate code for DS390 Arithmetic Accelerator"},
{ 0, "--stack-probe", &options.stack_probe,"insert call to function __stack_probe at each function prologue"},
- { 0, "--tini-libid", NULL,"<nnnn> LibraryID used in -mTININative"}
+ { 0, "--tini-libid", NULL,"<nnnn> LibraryID used in -mTININative"},
+ { 0, "--protect-sp-update", &options.protect_sp_update,"DS390 - will disable interrupts during ESP:SP updates"},
+ { 0, "--parms-in-bank1", &options.parms_in_bank1,"MCS51/DS390 - use Bank1 for parameter passing"},
+ /* End of options */
+ { 0, NULL }
};
/** Table of all unsupported options and help text to display when one
{ 'g', NULL, "use --generic instead" },
{ 'X', NULL, "use --xstack-loc instead" },
{ 'x', NULL, "use --xstack instead" },
- { 'p', NULL, "use --stack-loc instead" },
- { 'P', NULL, "use --stack-loc instead" },
{ 'i', NULL, "use --idata-loc instead" },
{ 'r', NULL, "use --xdata-loc instead" },
{ 's', NULL, "use --code-loc instead" },
NULL
};
-static const char *_preCmd = "{cpp} -Wall -lang-c++ -DSDCC=1 {cppextraopts} {fullsrcfilename} {cppoutfilename}";
+static const char *_preCmd = "{cpp} -nostdinc -Wall -lang-c++ -DSDCC=1 {cppextraopts} {fullsrcfilename} {cppoutfilename}";
PORT *port;
#if !OPT_DISABLE_PIC
&pic_port,
#endif
-#if !OPT_DISABLE_I186
- &i186_port,
-#endif
-#if !OPT_DISABLE_TLCS900H
- &tlcs900h_port,
-#endif
#if !OPT_DISABLE_TININative
&tininative_port,
#endif
#define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
-/**
- remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
- */
+#if !OPT_DISABLE_PIC
extern void picglue ();
+#endif
/** Sets the port to the one given by the command line option.
@param The name minus the option (eg 'mcs51')
exit (1);
}
+/* Override the default processor with the one specified
+ * on the command line */
+static void
+_setProcessor (char *_processor)
+{
+ port->processor = _processor;
+ fprintf(stderr,"Processor: %s\n",_processor);
+}
+
static void
_validatePorts (void)
{
{
if (_ports[i]->magic != PORT_MAGIC)
{
+ /* Uncomment this line to debug which port is causing the problem
+ * (the target name is close to the beginning of the port struct
+ * and probably can be accessed just fine). */
+ fprintf(stderr,"%s :",_ports[i]->target);
wassertl (0, "Port definition structure is incomplete");
}
}
}
+/* search through the command line options for the port */
static void
_findPort (int argc, char **argv)
{
port = _ports[0];
}
+/* search through the command line options for the processor */
+static void
+_findProcessor (int argc, char **argv)
+{
+ while (argc--)
+ {
+ if (!strncmp (*argv, "-p", 2))
+ {
+ _setProcessor (*argv + 2);
+ return;
+ }
+ argv++;
+ }
+
+ /* no error if processor was not specified. */
+}
+
/*-----------------------------------------------------------------*/
/* printVersionInfo - prints the version info */
/*-----------------------------------------------------------------*/
);
}
+static void
+printOptions(const OPTION *optionsTable)
+{
+ int i;
+ for (i = 0; optionsTable[i].shortOpt != 0 || optionsTable[i].longOpt != NULL; i++)
+ {
+ fprintf(stdout, " %c%c %-20s %s\n",
+ optionsTable[i].shortOpt !=0 ? '-' : ' ',
+ optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
+ optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
+ optionsTable[i].help != NULL ? optionsTable[i].help : ""
+ );
+ }
+}
+
/*-----------------------------------------------------------------*/
/* printUsage - prints command line syntax */
/*-----------------------------------------------------------------*/
"Options :-\n"
);
- for (i = 0; i < LENGTH(optionsTable); i++) {
- fprintf(stdout, " %c%c %-20s %s\n",
- optionsTable[i].shortOpt !=0 ? '-' : ' ',
- optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
- optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
- optionsTable[i].help != NULL ? optionsTable[i].help : ""
- );
- }
+ printOptions(optionsTable);
+
+ for (i = 0; i < NUM_PORTS; i++)
+ {
+ if (_ports[i]->poptions != NULL)
+ {
+ fprintf (stdout, "\nSpecial options for the %s port:\n", _ports[i]->target);
+ printOptions (_ports[i]->poptions);
+ }
+ }
+
exit (0);
}
}
}
+static bool
+scanOptionsTable(const OPTION *optionsTable, char shortOpt, const char *longOpt, char **argv, int *pi)
+{
+ int i;
+ for (i = 0; optionsTable[i].shortOpt != 0 || optionsTable[i].longOpt != NULL; i++)
+ {
+ if (optionsTable[i].shortOpt == shortOpt ||
+ (longOpt && optionsTable[i].longOpt &&
+ strcmp(optionsTable[i].longOpt, longOpt) == 0))
+ {
+
+ // If it is a flag then we can handle it here
+ if (optionsTable[i].pparameter != NULL)
+ {
+ if (optionsTable[i].shortOpt == shortOpt)
+ {
+ verifyShortOption(argv[*pi]);
+ }
+
+ (*optionsTable[i].pparameter)++;
+ return 1;
+ }
+ else {
+ // Not a flag. Handled manually later.
+ return 0;
+ }
+ }
+ }
+ // Didn't find in the table
+ return 0;
+}
+
static bool
tryHandleSimpleOpt(char **argv, int *pi)
{
{
const char *longOpt = "";
char shortOpt = -1;
- int i;
if (argv[*pi][1] == '-')
{
shortOpt = argv[*pi][1];
}
- for (i = 0; i < LENGTH(optionsTable); i++)
- {
- if (optionsTable[i].shortOpt == shortOpt ||
- (longOpt && optionsTable[i].longOpt &&
- strcmp(optionsTable[i].longOpt, longOpt) == 0))
- {
-
- // If it is a flag then we can handle it here
- if (optionsTable[i].pparameter != NULL)
- {
- if (optionsTable[i].shortOpt == shortOpt)
- {
- verifyShortOption(argv[*pi]);
- }
-
- (*optionsTable[i].pparameter)++;
- return 1;
- }
- else {
- // Not a flag. Handled manually later.
- return 0;
- }
- }
- }
- // Didn't find in the table
- return 0;
+ if (scanOptionsTable(optionsTable, shortOpt, longOpt, argv, pi))
+ {
+ return 1;
+ }
+ else if (port && port->poptions &&
+ scanOptionsTable(port->poptions, shortOpt, longOpt, argv, pi))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
}
else
{
break;
case 'm':
- /* Used to select the port */
- _setPort (argv[i] + 2);
+ /* Used to select the port. But this has already been done. */
+ break;
+
+ case 'p':
+ /* Used to select the processor in port. But this has
+ * already been done. */
break;
case 'c':
WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
/* indirect data */
- WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+ if (IDATA_NAME) {
+ WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+ }
/* bit segment start */
WRITE_SEG_LOC (BIT_NAME, 0);
/* standard library path */
if (!options.nostdlib)
{
-/****
- if (TARGET_IS_DS390)
+ switch (options.model)
{
+ case MODEL_SMALL:
+ c = "small";
+ break;
+ case MODEL_LARGE:
+ c = "large";
+ break;
+ case MODEL_FLAT24:
+ /* c = "flat24"; */
c = "ds390";
- }
- else
-*****/
- {
- switch (options.model)
- {
- case MODEL_SMALL:
- c = "small";
- break;
- case MODEL_LARGE:
- c = "large";
- break;
- case MODEL_FLAT24:
- /* c = "flat24"; */
- c = "ds390";
- break;
- default:
- werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
- c = "unknown";
- break;
- }
+ break;
+ case MODEL_PAGE0:
+ c = "xa51";
+ break;
+ default:
+ werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
+ c = "unknown";
+ break;
}
mfprintf (lnkfile, getRuntimeVariables(), "-k {libdir}{sep}%s\n", c);
/* standard library files */
- /* if (strcmp (port->target, "ds390") == 0) */
+#if !OPT_DISABLE_DS390
if (options.model == MODEL_FLAT24)
{
fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
}
+#endif
+
+#if !OPT_DISABLE_XA51
+#ifdef STD_XA51_LIB
+ if (options.model == MODEL_PAGE0)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
+ }
+#endif
+#endif
fprintf (lnkfile, "-l %s\n", STD_LIB);
fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
case MODEL_FLAT24:
addToList (preArgv, "-DSDCC_MODEL_FLAT24");
break;
+ case MODEL_PAGE0:
+ addToList (preArgv, "-DSDCC_MODEL_PAGE0");
+ break;
default:
werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
break;
/* Have to set cppoutfilename to something, even if just pre-processing. */
setMainValue ("cppoutfilename", preOutName ? preOutName : "");
-
+
if (options.verbose)
printf ("sdcc: Calling preprocessor...\n");
exit (1);
}
+ /* install atexit handler */
+ atexit(rm_tmpfiles);
+
+ /* Before parsing the command line options, do a
+ * search for the port and processor and initialize
+ * them if they're found. (We can't gurantee that these
+ * will be the first options specified).
+ */
+
_findPort (argc, argv);
+
#ifdef JAMIN_DS390
if (strcmp(port->target, "mcs51") == 0) {
printf("DS390 jammed in A\n");
ds390_jammed = 1;
}
#endif
+
+ _findProcessor (argc, argv);
+
/* Initalise the port. */
if (port->init)
port->init ();
if (srcFileName)
{
- preProcess (envp);
initMem ();
port->finaliseOptions ();
+ preProcess (envp);
initSymt ();
initiCode ();
yyparse ();
- if (!fatalError)
- {
- if (TARGET_IS_PIC) {
- /* TSD PIC port hack - if the PIC port option is enabled
- and SDCC is used to generate PIC code, then we will
- generate .asm files in gpasm's format instead of SDCC's
- assembler's format
- */
+ if (fatalError) {
+ // @FIX: Dario Vecchio 03-05-2001
+ if (preOutName) {
+ if (yyin && yyin != stdin)
+ fclose (yyin);
+ unlink (preOutName);
+ Safe_free (preOutName);
+ }
+ // EndFix
+ return 1;
+ }
+
+ if (TARGET_IS_PIC) {
+ /* TSD PIC port hack - if the PIC port option is enabled
+ and SDCC is used to generate PIC code, then we will
+ generate .asm files in gpasm's format instead of SDCC's
+ assembler's format
+ */
#if !OPT_DISABLE_PIC
- picglue ();
+ picglue ();
#endif
- } else {
- glue ();
- }
-
- if (fatalError)
- {
- // @FIX: Dario Vecchio 03-05-2001
- if (preOutName)
- {
- if (yyin && yyin != stdin)
- fclose (yyin);
- unlink (preOutName);
- Safe_free (preOutName);
- }
- // EndFix
- return 1;
- }
- if (!options.c1mode && !noAssemble)
- {
- if (options.verbose)
- printf ("sdcc: Calling assembler...\n");
- assemble (envp);
- }
- }
- else
- {
- // @FIX: Dario Vecchio 03-05-2001
- if (preOutName)
- {
- if (yyin && yyin != stdin)
- fclose (yyin);
- unlink (preOutName);
- Safe_free (preOutName);
- }
- // EndFix
- #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
- rm_tmpfiles();
- #endif
- return 1;
- }
+ }
+ else {
+ glue ();
+ }
+ if (!options.c1mode && !noAssemble)
+ {
+ if (options.verbose)
+ printf ("sdcc: Calling assembler...\n");
+ assemble (envp);
+ }
}
closeDumpFiles();
if (cdbFile)
fclose (cdbFile);
+ if (yyin && yyin != stdin)
+ fclose (yyin);
+
if (preOutName && !options.c1mode)
{
unlink (preOutName);
linkEdit (envp);
}
- if (yyin && yyin != stdin)
- fclose (yyin);
-
return 0;
-
}