Break DS80C390 support into seperate port (ds390); first pass at spilling temporaries...
[fw/sdcc] / src / SDCCmain.c
index 1324cb449444319994f77ca7d724161c787d7984..3becb08b915e34005430c518b5f8cc8ec6f91b7f 100644 (file)
@@ -25,7 +25,7 @@
 #include "common.h"
 #include <ctype.h>
 
-#ifdef __BORLANDC__
+#if NATIVE_WIN32
 #include <process.h>
 #else
 #include "spawn.h"
@@ -74,7 +74,10 @@ bool verboseExec = FALSE;
 //extern int wait (int *);
 char    *preOutName;
 
+/* Far functions, far data */
 #define OPTION_LARGE_MODEL "-model-large"
+/* Far functions, near data */
+#define OPTION_MEDIUM_MODEL "-model-medium"
 #define OPTION_SMALL_MODEL "-model-small"
 #define OPTION_FLAT24_MODEL "-model-flat24"
 #define OPTION_STACK_AUTO  "-stack-auto"
@@ -128,16 +131,41 @@ static const char *_preCmd[] = {
     "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
 };
 
+#if !OPT_DISABLE_MCS51
 extern PORT mcs51_port;
-extern PORT z80_port;
+#endif
+#if !OPT_DISABLE_GBZ80
 extern PORT gbz80_port;
+#endif
+#if !OPT_DISABLE_Z80
+extern PORT z80_port;
+#endif
+#if !OPT_DISABLE_AVR
+extern PORT avr_port;
+#endif
+#if !OPT_DISABLE_DS390
+extern PORT ds390_port;
+#endif
+
 
 PORT *port;
 
 static PORT *_ports[] = {
-    &mcs51_port,
+#if !OPT_DISABLE_MCS51
+   &mcs51_port,
+#endif
+#if !OPT_DISABLE_GBZ80
+    &gbz80_port,
+#endif
+#if !OPT_DISABLE_Z80
     &z80_port,
-    &gbz80_port
+#endif
+#if !OPT_DISABLE_AVR
+    &avr_port,
+#endif
+#if !OPT_DISABLE_DS390
+    &ds390_port,
+#endif
 };
 
 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
@@ -156,10 +184,11 @@ static int _setPort(const char *name)
        }
     }
     /* Error - didnt find */
-    return 1;
+    werror(E_UNKNOWN_TARGET,name);
+    exit(1);
 }
 
-static void _buildCmdLine(char *into, char **args, const char **cmds, 
+void buildCmdLine(char *into, char **args, const char **cmds, 
                          const char *p1, const char *p2, 
                          const char *p3, const char **list)
 {
@@ -176,6 +205,8 @@ static void _buildCmdLine(char *into, char **args, const char **cmds,
        /* See if it has a '$' anywhere - if not, just copy */
        if ((p = strchr(from, '$'))) {
            strncpy(into, from, p - from);
+           /* NULL terminate it */
+           into[p-from] = '\0';
            from = p+2;
            p++;
            switch (*p) {
@@ -227,8 +258,11 @@ void       printVersionInfo ()
             "SDCC : ");
     for (i=0; i<NUM_PORTS; i++)
        fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
-
-    fprintf(stderr, " %s `"
+    fprintf(stderr, " %s"
+#ifdef SDCC_SUB_VERSION_STR
+           "/" SDCC_SUB_VERSION_STR
+#endif
+           " ` "
 #ifdef __CYGWIN32__
                " (CYGWIN32)\n"
 #else
@@ -238,6 +272,7 @@ void        printVersionInfo ()
                " (UNIX) \n"
 # endif
 #endif
+
            , VersionString
            );
 }
@@ -269,7 +304,7 @@ void        printUsage ()
                 "PreProcessor Options :-\n"
                 "\t-Dmacro             -       Define Macro\n"          
                 "\t-Ipath              -       Include \"*.h\" path\n"
-                "Note: this is a complete list of options see docs for details\n",
+                "Note: this is NOT a complete list of options see docs for details\n",
                 _ports[0]->target
                 );             
        exit (0);
@@ -319,6 +354,7 @@ static void setDefaultOptions()
     options.idata_loc = 0x80;
     options.genericPtr = 1;   /* default on */
     options.nopeep    = 0;
+    options.model = port->general.default_model;
 
     /* now for the optimizations */
     /* turn on the everything */
@@ -393,8 +429,9 @@ static void processFile (char *s)
     /* if the extention is type .rel or .r or .REL or .R 
        addtional object file will be passed to the linker */
     if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
-       strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
-       
+       strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
+       strcmp(fext, port->linker.rel_ext) == 0)
+       {
        relFiles[nrelFiles++] = s;
        return ;
     }
@@ -436,6 +473,14 @@ static void _addToList(const char **list, const char *str)
     *(++list) = NULL;
 }
 
+static void _setModel(int model, const char *sz)
+{
+    if (port->general.supported_models & model)
+       options.model = model;
+    else
+       werror(W_UNSUPPORTED_MODEL, sz, port->target);
+}
+
 /*-----------------------------------------------------------------*/
 /* parseCmdLine - parses the command line and sets the options     */
 /*-----------------------------------------------------------------*/
@@ -463,17 +508,22 @@ int   parseCmdLine ( int argc, char **argv )
            }
 
            if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
-               options.model = MODEL_LARGE;
+               _setModel(MODEL_LARGE, argv[i]);
+                continue;
+           }
+
+           if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
+               _setModel(MODEL_MEDIUM, argv[i]);
                 continue;
            }
            
            if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
-               options.model = MODEL_SMALL;
+               _setModel(MODEL_SMALL, argv[i]);
                 continue;
            }
            
            if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
-               options.model = MODEL_FLAT24;
+               _setModel(MODEL_FLAT24, argv[i]);
                 continue;
            }
            
@@ -980,7 +1030,6 @@ int   parseCmdLine ( int argc, char **argv )
            fprintf(cdbFile,"M:%s\n",moduleName);
        }
     }
-    port->finaliseOptions();
     return 0;
 }
 
@@ -991,9 +1040,6 @@ char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
 int my_system (const char *cmd, char **cmd_argv)
 {    
     char *dir, *got= NULL; int i= 0;
-    #ifdef __BORLANDC__
-    char *r;
-    #endif
 
     while (!got && try_dir[i])
     {
@@ -1002,21 +1048,24 @@ int my_system (const char *cmd, char **cmd_argv)
         strcat(dir, "/");
         strcat(dir, cmd);
 
-        #ifdef __BORLANDC__
+#if NATIVE_WIN32
         strcat(dir, ".exe");
 
         /* Mung slashes into backslashes to keep WIndoze happy. */
-       r = dir;
-
-        while (*r)
-        {
-            if (*r == '/')
-            {
-                *r = '\\';
-            }
-            r++;
-        }
-        #endif
+       {
+           char *r;
+           r = dir;
+           
+           while (*r)
+               {
+                   if (*r == '/')
+                       {
+                           *r = '\\';
+                       }
+                   r++;
+               }
+       }
+#endif
 
         if (access(dir, X_OK) == 0)
         {
@@ -1145,7 +1194,7 @@ static void linkEdit (char **envp)
     fprintf (lnkfile,"\n-e\n");
     fclose(lnkfile);
 
-    _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
+    buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
 
     /* call the linker */
     if (my_system(argv[0], argv)) {
@@ -1169,7 +1218,7 @@ static void assemble (char **envp)
 {
     char *argv[128];  /* assembler arguments */
 
-    _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
+    buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
 
     if (my_system(argv[0], argv)) {
        perror("Cannot exec assember");
@@ -1211,6 +1260,12 @@ static int preProcess (char **envp)
            case MODEL_SMALL:
                _addToList(preArgv, "-DSDCC_MODEL_SMALL");
                break;
+           case MODEL_COMPACT:
+               _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
+               break;
+           case MODEL_MEDIUM:
+               _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
+               break;
            case MODEL_FLAT24:
                _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
                break;
@@ -1227,7 +1282,7 @@ static int preProcess (char **envp)
        if (!preProcOnly)
            preOutName = strdup(tmpnam(NULL));
 
-       _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName, 
+       buildCmdLine(buffer, argv, _preCmd, fullSrcFileName, 
                      preOutName, srcFileName, preArgv);
 
        if (my_system(argv[0], argv)) {
@@ -1283,17 +1338,19 @@ int main ( int argc, char **argv , char **envp)
     /* Initalise the port. */
     if (port->init)
        port->init();
-    
-    initMem();
+
     setDefaultOptions();
     parseCmdLine(argc,argv);
 
+    initMem();
+
+    port->finaliseOptions();
+
     /* if no input then printUsage & exit */
     if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
        printUsage();
        exit(0);
     }
-
        
     if (srcFileName)
        preProcess(envp) ;
@@ -1310,7 +1367,9 @@ int main ( int argc, char **argv , char **envp)
            glue();
            if (!options.c1mode)
                assemble(envp);
-       }
+       } else {
+           return 1;
+        }
        
     }
     
@@ -1321,8 +1380,12 @@ int main ( int argc, char **argv , char **envp)
        !fatalError      &&
        !noAssemble      &&
        !options.c1mode  &&
-       (srcFileName || nrelFiles))
-       linkEdit (envp);
+       (srcFileName || nrelFiles)) {
+       if (port->linker.do_link)
+           port->linker.do_link();
+       else
+           linkEdit (envp);
+    }
 
     if (yyin && yyin != stdin)
        fclose(yyin);
@@ -1331,6 +1394,7 @@ int main ( int argc, char **argv , char **envp)
         unlink(preOutName);
         free(preOutName);
     }
+
     return 0;
     
 }