Added -p command line option to allow selection of port dependent processor.
[fw/sdcc] / src / SDCCmain.c
index a0fff7cee509a26149f5eada32ea5c08273d3c9a..fa2883d36e1f5f130f4d7ec6e7d6c443e61f851b 100644 (file)
@@ -57,7 +57,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];
@@ -79,8 +79,8 @@ int ds390_jammed = 0;
 #endif
 
 // Globally accessible scratch buffer for file names.
-char scratchFileName[FILENAME_MAX];
-char buffer[FILENAME_MAX];
+char scratchFileName[PATH_MAX];
+char buffer[PATH_MAX];
 
 // In MSC VC6 default search path for exe's to path for this
 
@@ -113,6 +113,7 @@ char DefaultExePath[128];
 #define OPTION_LESS_PEDANTIC   "--lesspedantic"
 #define OPTION_NO_GCSE         "--nogcse"
 #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:
@@ -137,6 +138,7 @@ typedef struct {
 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 +148,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,6 +173,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, "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" },
@@ -188,6 +191,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 },
@@ -203,7 +207,14 @@ optionsTable[] = {
     { 0,    "--verbose",            &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
     { 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,    "--profile",            &options.profile, "On supported ports, generate extra profiling information" },
+    { 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"}
 };
 
 /** Table of all unsupported options and help text to display when one
@@ -225,8 +236,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" },
@@ -273,14 +282,19 @@ static PORT *_ports[] =
 #if !OPT_DISABLE_TLCS900H
   &tlcs900h_port,
 #endif
+#if !OPT_DISABLE_TININative
+  &tininative_port,
+#endif
+#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')
@@ -311,11 +325,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)
 {
@@ -507,9 +526,16 @@ processFile (char *s)
       /* copy the file name into the buffer */
       strcpy (buffer, s);
 
-      /* get rid of the "." */
-      strtok (buffer, ".");
-      srcFileName = Safe_calloc (1, strlen (buffer) + 1);
+      /* 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);
 
       /* get rid of any path information
@@ -522,7 +548,7 @@ processFile (char *s)
             *(fext - 1) != '/' &&
             *(fext - 1) != ':')
        fext--;
-      moduleName = Safe_calloc (1, strlen (fext) + 1);
+      moduleName = Safe_alloc ( strlen (fext) + 1);
       strcpy (moduleName, fext);
 
       return;
@@ -559,7 +585,7 @@ _processC1Arg (char *s)
          werror (W_TOO_MANY_SRC, s);
          return;
        }
-      options.out_name = strdup (s);
+      options.out_name = Safe_strdup (s);
     }
   else
     {
@@ -576,6 +602,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.
 */
@@ -890,6 +923,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))
            {
@@ -918,6 +957,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]);
 
@@ -933,23 +977,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')
-               {
-                    parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
-               }
-             else
+             else if (argv[i][2] == 'l')
                {
-                 /* 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':
@@ -1073,10 +1119,10 @@ linkEdit (char **envp)
     fprintf (lnkfile, "-z\n");
 
 #define WRITE_SEG_LOC(N, L) \
-    segName = strdup(N); \
+    segName = Safe_strdup(N); \
     c = strtok(segName, " \t"); \
     fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
-    if (segName) { free(segName); }
+    if (segName) { Safe_free(segName); }
 
   /* code segment start */
   WRITE_SEG_LOC (CODE_NAME, options.code_loc);
@@ -1088,7 +1134,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);
@@ -1104,40 +1152,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";
+         break;
+       case MODEL_PAGE0:
+         c = "xa51";
+         break;
+       default:
+         werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
+         c = "unknown";
+         break;
        }
-      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;
-           }
-       }
-      fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
+      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);
@@ -1163,7 +1215,9 @@ linkEdit (char **envp)
 
   if (port->linker.cmd)
     {
-      buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
+      char buffer2[PATH_MAX];
+      buildCmdLine (buffer2, port->linker.cmd, srcFileName, NULL, NULL, NULL);
+      buildCmdLine2 (buffer, buffer2);
     }
   else
     {
@@ -1178,7 +1232,7 @@ linkEdit (char **envp)
   if (strcmp (srcFileName, "temp") == 0)
     {
       /* rename "temp.cdb" to "firstRelFile.cdb" */
-      char *f = strtok (strdup (relFiles[0]), ".");
+      char *f = strtok (Safe_strdup (relFiles[0]), ".");
       f = strcat (f, ".cdb");
       rename ("temp.cdb", f);
       srcFileName = NULL;
@@ -1191,23 +1245,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);
     }
 }
 
@@ -1233,6 +1286,10 @@ preProcess (char **envp)
       if (options.stack10bit)
        addToList (preArgv, "-DSDCC_STACK_TENBIT");
 
+      /* set the macro for no overlay  */
+      if (options.noOverlay)
+        addToList (preArgv, "-DSDCC_NOOVERLAY");
+
       /* set the macro for large model  */
       switch (options.model)
        {
@@ -1251,6 +1308,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;
@@ -1268,7 +1328,7 @@ preProcess (char **envp)
       setMainValue ("cppextraopts", join(preArgv));
       
       if (!preProcOnly)
-          preOutName = strdup (tempfilename ());
+          preOutName = Safe_strdup (tempfilename ());
 
       /* Have to set cppoutfilename to something, even if just pre-processing. */
       setMainValue ("cppoutfilename", preOutName ? preOutName : "");
@@ -1284,7 +1344,7 @@ preProcess (char **envp)
           if (preOutName)
             {
               unlink (preOutName);
-              free (preOutName);
+              Safe_free (preOutName);
             }
           // EndFix
          exit (1);
@@ -1380,7 +1440,7 @@ _discoverPaths (const char *argv0)
       strcpy (scratchFileName, argv0);
       *strrchr (scratchFileName, DIR_SEPARATOR_CHAR) = '\0';
       setMainValue ("bindir", scratchFileName);
-      ExePathList[0] = gc_strdup (scratchFileName);
+      ExePathList[0] = Safe_strdup (scratchFileName);
     }
   else if (getenv (SDCCDIR_NAME) != NULL)
     {
@@ -1388,7 +1448,7 @@ _discoverPaths (const char *argv0)
       strcpy (scratchFileName, getenv (SDCCDIR_NAME));
       strcat (scratchFileName, buffer);
       setMainValue ("bindir", scratchFileName);
-      ExePathList[0] = gc_strdup (scratchFileName);
+      ExePathList[0] = Safe_strdup (scratchFileName);
     }
   else
     {
@@ -1444,10 +1504,11 @@ initValues (void)
 {
   populateMainValues (_baseValues);
   setMainValue ("port", port->target);
-  setMainValue ("fullsrcfilename", fullSrcFileName);
-  setMainValue ("srcfilename", srcFileName);
   setMainValue ("objext", port->linker.rel_ext);
   setMainValue ("asmext", port->assembler.file_ext);
+
+  setMainValue ("fullsrcfilename", fullSrcFileName ? fullSrcFileName : "fullsrcfilename");
+  setMainValue ("srcfilename", srcFileName ? srcFileName : "srcfilename");
 }
 
 /*
@@ -1500,20 +1561,21 @@ main (int argc, char **argv, char **envp)
       exit (0);
     }
 
+  initValues ();
+  _discoverPaths (argv[0]);
+
   if (srcFileName)
     {
-      initValues ();
-      _discoverPaths (argv[0]);
-
-      preProcess (envp);
 
       initMem ();
 
       port->finaliseOptions ();
+      preProcess (envp);
 
       initSymt ();
       initiCode ();
       initCSupport ();
+      initBuiltIns();
       initPeepHole ();
 
       if (options.verbose)
@@ -1544,7 +1606,7 @@ main (int argc, char **argv, char **envp)
                   if (yyin && yyin != stdin)
                     fclose (yyin);
                   unlink (preOutName);
-                  free (preOutName);
+                  Safe_free (preOutName);
                 }
               // EndFix
              return 1;
@@ -1564,7 +1626,7 @@ main (int argc, char **argv, char **envp)
               if (yyin && yyin != stdin)
                 fclose (yyin);
               unlink (preOutName);
-              free (preOutName);
+              Safe_free (preOutName);
             }
           // EndFix
           #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
@@ -1583,7 +1645,7 @@ main (int argc, char **argv, char **envp)
   if (preOutName && !options.c1mode)
     {
       unlink (preOutName);
-      free (preOutName);
+      Safe_free (preOutName);
     }
 
   if (!options.cc_only &&