* device/lib/z80/printf.c: Changed emitter to volatile to work
[fw/sdcc] / src / SDCCmain.c
index 705e408f2a8a711981d76f5899485a408311e226..c1510d14e16761f8a13c1e3e22a45e8e29046aa4 100644 (file)
@@ -30,6 +30,7 @@
 #include "MySystem.h"
 #include "SDCCmacro.h"
 #include "SDCCutil.h"
+#include "SDCCargs.h"
 
 #if NATIVE_WIN32
 #include <process.h>
@@ -57,7 +58,7 @@ const char *preArgv[128];     /* pre-processor arguments  */
 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];
@@ -113,30 +114,12 @@ char DefaultExePath[128];
 #define OPTION_LESS_PEDANTIC   "--lesspedantic"
 #define OPTION_NO_GCSE         "--nogcse"
 #define OPTION_SHORT_IS_8BITS  "--short-is-8bits"
-
-/** 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;
+#define OPTION_TINI_LIBID      "--tini-libid"
 
 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" },
@@ -146,7 +129,7 @@ optionsTable[] = {
     { 'M',  NULL,                   NULL, "Preprocessor option" },
     { 'V',  NULL,                   &verboseExec, "Execute verbosely.  Show sub commands as they are run" },
     { 'S',  NULL,                   &noAssemble, "Compile only; do not assemble or link" },
-    { 'W',  NULL,                   NULL, "Pass through options to the assembler (a) or linker (l)" },
+    { 'W',  NULL,                   NULL, "Pass through options to the pre-processor (p), assembler (a) or linker (l)" },
     { 'L',  NULL,                   NULL, "Add the next field to the library search path" },
     { 'l',  NULL,                   NULL, "Include the given library in the link" },
     { 0,    OPTION_LARGE_MODEL,     NULL, "external data space is used" },
@@ -171,7 +154,7 @@ optionsTable[] = {
     { 0,    "--dumpliverange",      &options.dump_range, NULL },
     { 0,    "--dumpregpack",        &options.dump_pack, NULL },
     { 0,    "--dumpregassign",      &options.dump_rassgn, NULL },
-    { 0,    "--dumptree",           &options.dump_tree, NULL },
+    { 0,    "--dumptree",           &options.dump_tree, "dump front-end AST before generating iCode" },
     { 0,    OPTION_DUMP_ALL,        NULL, "Dump the internal structure at all stages" },
     { 0,    OPTION_XRAM_LOC,        NULL, "<nnnn> External Ram start location" },
     { 0,    OPTION_IRAM_SIZE,       NULL, "<nnnn> Internal Ram size" },
@@ -189,6 +172,7 @@ optionsTable[] = {
     { 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 },
@@ -205,7 +189,15 @@ optionsTable[] = {
     { 0,    OPTION_LESS_PEDANTIC,   NULL, "Disable some of the more pedantic warnings" },
     { 0,    OPTION_SHORT_IS_8BITS,   NULL, "Make short 8bits (for old times sake)" },
     { 0,    "--profile",            &options.profile, "On supported ports, generate extra profiling information" },
-    { 0,    "--fommit-frame-pointer", &options.ommitFramePtr, "Leave out the frame pointer." }
+    { 0,    "--fommit-frame-pointer", &options.ommitFramePtr, "Leave out the frame pointer." },
+    { 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,    "--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
@@ -227,8 +219,6 @@ unsupportedOptTable[] = {
     { '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" },
@@ -245,7 +235,7 @@ static const char *_baseValues[] = {
   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;
 
@@ -269,20 +259,19 @@ static PORT *_ports[] =
 #if !OPT_DISABLE_PIC
   &pic_port,
 #endif
-#if !OPT_DISABLE_I186
-  &i186_port,
+#if !OPT_DISABLE_TININative
+  &tininative_port,
 #endif
-#if !OPT_DISABLE_TLCS900H
-  &tlcs900h_port,
+#if !OPT_DISABLE_XA51
+  &xa51_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')
@@ -313,11 +302,16 @@ _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)
 {
@@ -372,6 +366,21 @@ printVersionInfo ()
     );
 }
 
+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         */
 /*-----------------------------------------------------------------*/
@@ -385,14 +394,17 @@ printUsage ()
              "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);
 }
 
@@ -509,8 +521,15 @@ processFile (char *s)
       /* copy the file name into the buffer */
       strcpy (buffer, s);
 
-      /* get rid of the "." */
-      strtok (buffer, ".");
+      /* get rid of the "."-extension */
+
+      /* is there a dot at all? */
+      if (strchr (buffer, '.') &&
+          /* is the dot in the filename, not in the path? */
+          (strrchr (buffer, '/' ) < strrchr (buffer, '.') ||
+           strrchr (buffer, '\\') < strrchr (buffer, '.')))
+        *strrchr (buffer, '.') = '\0';
+
       srcFileName = Safe_alloc ( strlen (buffer) + 1);
       strcpy (srcFileName, buffer);
 
@@ -578,6 +597,13 @@ _setModel (int model, const char *sz)
     werror (W_UNSUPPORTED_MODEL, sz, port->target);
 }
 
+static void
+_setProcessor (char *_processor)
+{
+  port->processor = _processor;
+  fprintf(stderr,"Processor: %s\n",_processor);
+}
+
 /** Gets the string argument to this option.  If the option is '--opt'
     then for input of '--optxyz' or '--opt xyz' returns xyz.
 */
@@ -661,6 +687,38 @@ tryHandleUnsupportedOpt(char **argv, int *pi)
     }
 }
 
+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)
 {
@@ -668,7 +726,6 @@ tryHandleSimpleOpt(char **argv, int *pi)
         {
             const char *longOpt = "";
             char shortOpt = -1;
-            int i;
 
             if (argv[*pi][1] == '-') 
                 {
@@ -680,32 +737,19 @@ tryHandleSimpleOpt(char **argv, int *pi)
                     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 
         {
@@ -892,6 +936,12 @@ parseCmdLine (int argc, char **argv)
               options.shortis8bits=1;
               continue;
             }
+
+         if (strcmp (argv[i], OPTION_TINI_LIBID) == 0)
+           {
+                options.tini_libid = getIntArg(OPTION_TINI_LIBID, argv, &i, argc);
+                continue;
+           }
           
          if (!port->parseOption (&argc, argv, &i))
            {
@@ -920,6 +970,11 @@ parseCmdLine (int argc, char **argv)
              _setPort (argv[i] + 2);
              break;
 
+           case 'p':
+             /* Used to select the processor in port */
+             _setProcessor (getStringArg("-p", argv, &i, argc));
+             break;
+
            case 'c':
               verifyShortOption(argv[i]);
 
@@ -935,23 +990,25 @@ parseCmdLine (int argc, char **argv)
                 break;
 
            case 'W':
+              /* pre-processer options */
+              if (argv[i][2] == 'p')
+                {
+                  parseWithComma ((char **)preArgv, getStringArg("-Wp", argv, &i, argc));
+                }
              /* linker options */
-             if (argv[i][2] == 'l')
+             else if (argv[i][2] == 'l')
                {
-                    parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
-               }
-             else
-               {
-                 /* assembler options */
-                 if (argv[i][2] == 'a')
-                   {
-                       parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
-                   }
-                 else
-                   {
-                     werror (W_UNKNOWN_OPTION, argv[i]);
-                   }
+                  parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
                }
+              /* assembler options */
+             else if (argv[i][2] == 'a')
+                {
+                  parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
+                }
+              else
+                {
+                  werror (W_UNKNOWN_OPTION, argv[i]);
+                }
              break;
 
            case 'v':
@@ -1090,7 +1147,9 @@ linkEdit (char **envp)
   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);
@@ -1106,40 +1165,44 @@ linkEdit (char **envp)
   /* 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);
@@ -1195,23 +1258,22 @@ linkEdit (char **envp)
 static void
 assemble (char **envp)
 {
-  if (port->assembler.cmd)
-    {
-      buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL,
-                    options.debug ? port->assembler.debug_opts : port->assembler.plain_opts,
-                    asmOptions);
-    }
-  else
-    {
-      buildCmdLine2 (buffer, port->assembler.mcmd);
+    if (port->assembler.do_assemble) {
+       port->assembler.do_assemble(asmOptions);
+       return ;
+    } else if (port->assembler.cmd) {
+       buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL,
+                     options.debug ? port->assembler.debug_opts : port->assembler.plain_opts,
+                     asmOptions);
+    } else {
+       buildCmdLine2 (buffer, port->assembler.mcmd);
     }
 
-  if (my_system (buffer))
-    {
-      /* either system() or the assembler itself has reported an error
-         perror ("Cannot exec assembler");
-       */
-      exit (1);
+    if (my_system (buffer)) {
+       /* either system() or the assembler itself has reported an error
+          perror ("Cannot exec assembler");
+       */
+       exit (1);
     }
 }
 
@@ -1259,6 +1321,9 @@ preProcess (char **envp)
        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;
@@ -1514,15 +1579,16 @@ main (int argc, char **argv, char **envp)
 
   if (srcFileName)
     {
-      preProcess (envp);
 
       initMem ();
 
       port->finaliseOptions ();
+      preProcess (envp);
 
       initSymt ();
       initiCode ();
       initCSupport ();
+      initBuiltIns();
       initPeepHole ();
 
       if (options.verbose)