X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCmain.c;h=be3101f9266bc5132a4ac2c28b480a2d0db2129b;hb=c89270b76b63181412bdb2631932e10cb44e56d8;hp=ff58b6090de9501d4f786e8ae460ef26b99e612c;hpb=4ef1ca6ec6bbafa57d2f30a3a8bdc7889eff7243;p=fw%2Fsdcc diff --git a/src/SDCCmain.c b/src/SDCCmain.c index ff58b609..be3101f9 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -24,7 +24,12 @@ #include "common.h" #include + +#if NATIVE_WIN32 +#include +#else #include "spawn.h" +#endif /* This is a bit messy. We cant include unistd.h as it defines 'link' which we also use. @@ -50,7 +55,7 @@ FILE *cdbFile = NULL ;/* debugger information output file */ char *fullSrcFileName ;/* full name for the source file */ char *srcFileName ;/* source file name with the .c stripped */ char *moduleName ;/* module name is srcFilename stripped of any path */ -char *preArgv[128] ;/* pre-processor arguments */ +const char *preArgv[128] ;/* pre-processor arguments */ int currRegBank = 0 ; struct optimize optimize ; struct options options ; @@ -58,7 +63,7 @@ char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/; short preProcOnly = 0; short noAssemble = 0; char *linkOptions[128]; -char *asmOptions[128]; +const char *asmOptions[128]; char *libFiles[128] ; int nlibFiles = 0; char *libPaths[128] ; @@ -69,9 +74,14 @@ 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" +#define OPTION_STACK_10BIT "-stack-10bit" #define OPTION_XSTACK "-xstack" #define OPTION_GENERIC "-generic" #define OPTION_NO_GCSE "-nogcse" @@ -108,35 +118,55 @@ char *preOutName; #define OPTION_NOPEEP "-no-peep" #define OPTION_ASMPEEP "-peep-asm" #define OPTION_DEBUG "-debug" +#define OPTION_NODEBUG "-nodebug" #define OPTION_VERSION "-version" #define OPTION_STKAFTRDATA "-stack-after-data" #define OPTION_PREPROC_ONLY "-preprocessonly" +#define OPTION_C1_MODE "-c1mode" #define OPTION_HELP "-help" #define OPTION_CALLEE_SAVES "-callee-saves" #define OPTION_NOREGPARMS "-noregparms" -static const char *linkCmd[] = { - "$1", "-nf", "$2", NULL -}; - -static const char *preCmd[] = { - "sdcpp", "-version", "-Wall", "-lang-c++", "-DSDCC=1", +static const char *_preCmd[] = { + "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1", "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL }; -static const char *asmCmd[] = { - "$1", "-plosgffc", "$2.asm", NULL -}; - - +#if !OPT_DISABLE_MCS51 extern PORT mcs51_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, - &z80_port +#if !OPT_DISABLE_MCS51 + &mcs51_port, +#endif +#if !OPT_DISABLE_GBZ80 + &gbz80_port, +#endif +#if !OPT_DISABLE_Z80 + &z80_port, +#endif +#if !OPT_DISABLE_AVR + &avr_port, +#endif +#if !OPT_DISABLE_DS390 + &ds390_port, +#endif }; #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0])) @@ -155,10 +185,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) { @@ -175,6 +206,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) { @@ -226,8 +259,11 @@ void printVersionInfo () "SDCC : "); for (i=0; itarget); - - fprintf(stderr, " %s `" + fprintf(stderr, " %s" +#ifdef SDCC_SUB_VERSION_STR + "/" SDCC_SUB_VERSION_STR +#endif + " ` " #ifdef __CYGWIN32__ " (CYGWIN32)\n" #else @@ -237,6 +273,7 @@ void printVersionInfo () " (UNIX) \n" # endif #endif + , VersionString ); } @@ -268,7 +305,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); @@ -305,8 +342,8 @@ static void setDefaultOptions() int i ; for ( i = 0 ; i < 128 ; i++) - preArgv[i] = linkOptions [i] = - asmOptions[i] = relFiles[i] = libFiles[i] = + preArgv[i] = asmOptions [i] = + linkOptions[i] = relFiles[i] = libFiles[i] = libPaths[i] = NULL ; /* first the options part */ @@ -318,6 +355,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 */ @@ -351,7 +389,7 @@ static void processFile (char *s) } /* otherwise depending on the file type */ - if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0) { + if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) { /* source file name : not if we already have a source file */ if (srcFileName) { @@ -392,8 +430,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 ; } @@ -408,7 +447,21 @@ static void processFile (char *s) } -static void _addToList(char **list, const char *str) +static void _processC1Arg(char *s) +{ + if (srcFileName) { + if (options.out_name) { + werror(W_TOO_MANY_SRC,s); + return; + } + options.out_name = strdup(s); + } + else { + processFile(s); + } +} + +static void _addToList(const char **list, const char *str) { /* This is the bad way to do things :) */ while (*list) @@ -421,6 +474,14 @@ static void _addToList(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 */ /*-----------------------------------------------------------------*/ @@ -448,14 +509,29 @@ int parseCmdLine ( int argc, char **argv ) } if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) { - options.model = 1; + _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 = 0; + _setModel(MODEL_SMALL, argv[i]); continue; } + + if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) { + _setModel(MODEL_FLAT24, argv[i]); + continue; + } + + if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) { + options.stack10bit = 1; + continue; + } if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) { options.stackAuto = 1; @@ -537,6 +613,11 @@ int parseCmdLine ( int argc, char **argv ) continue; } + if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) { + options.c1mode = 1; + continue; + } + if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) { options.dump_rassgn = @@ -574,6 +655,11 @@ int parseCmdLine ( int argc, char **argv ) continue; } + if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) { + options.nodebug = 1; + continue; + } + if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) { options.noregparms = 1; continue; @@ -725,15 +811,23 @@ int parseCmdLine ( int argc, char **argv ) continue; } - if (!port->parseOption(&argc, argv)) + if (!port->parseOption(&argc, argv, &i)) + { werror(W_UNKNOWN_OPTION,argv[i]); + } + else + { + continue; + } } /* these are undocumented options */ /* if preceded by '/' then turn off certain optmizations, used for debugging only these are also the legacy options from - version 1.xx will be removed gradually */ - if ( *argv[i] == '/') { + version 1.xx will be removed gradually. + It may be an absolute filename. + */ + if ( *argv[i] == '/' && strlen(argv[i]) < 3) { switch (argv[i][1]) { case 'p': @@ -861,9 +955,9 @@ int parseCmdLine ( int argc, char **argv ) /* assembler options */ if (argv[i][2] == 'a') { if (argv[i][3]) - parseWithComma(asmOptions,&argv[i][3]); + parseWithComma((char **)asmOptions,&argv[i][3]); else - parseWithComma(asmOptions,argv[++i]); + parseWithComma((char **)asmOptions,argv[++i]); } else { werror(W_UNKNOWN_OPTION,argv[i]); @@ -884,11 +978,20 @@ int parseCmdLine ( int argc, char **argv ) break; /* preprocessor options */ + case 'M': + { + preProcOnly=1; + _addToList(preArgv, "-M"); + break; + } + case 'C': + { + _addToList(preArgv, "-C"); + break; + } case 'd': case 'D': case 'I': - case 'M': - case 'C': case 'A': case 'U': { @@ -904,8 +1007,6 @@ int parseCmdLine ( int argc, char **argv ) if ( argv[i][1] == 'Y' ) argv[i][1] = 'I'; - if (argv[i][1] == 'M') - preProcOnly = 1; sprintf(buffer, "-%c%s", sOpt, rest); _addToList(preArgv, buffer); @@ -913,15 +1014,18 @@ int parseCmdLine ( int argc, char **argv ) break ; default: - if (!port->parseOption(&argc, argv)) + if (!port->parseOption(&argc, argv, &i)) werror(W_UNKNOWN_OPTION,argv[i]); } continue ; } - if (!port->parseOption(&argc, argv)) { + if (!port->parseOption(&argc, argv, &i)) { /* no option must be a filename */ - processFile(argv[i]); + if (options.c1mode) + _processC1Arg(argv[i]); + else + processFile(argv[i]); } } @@ -930,7 +1034,7 @@ int parseCmdLine ( int argc, char **argv ) options.xstack_loc = options.xdata_loc ; /* if debug option is set the open the cdbFile */ - if (/* options.debug && */ srcFileName) { + if (!options.nodebug && srcFileName) { sprintf(cdbfnbuf,"%s.cdb",srcFileName); if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL) werror(E_FILE_OPEN_ERR,cdbfnbuf); @@ -939,7 +1043,6 @@ int parseCmdLine ( int argc, char **argv ) fprintf(cdbFile,"M:%s\n",moduleName); } } - port->finaliseOptions(); return 0; } @@ -949,15 +1052,40 @@ int parseCmdLine ( int argc, char **argv ) char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL}; int my_system (const char *cmd, char **cmd_argv) { - char *dir, *got= NULL; int i= 0; - while (!got && try_dir[i]) { - dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10); - strcpy(dir, try_dir[i]); strcat(dir, "/"); strcat(dir, cmd); - if (access(dir, X_OK) == 0) - got= strdup(dir); - free(dir); - i++; + + while (!got && try_dir[i]) + { + dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10); + strcpy(dir, try_dir[i]); + strcat(dir, "/"); + strcat(dir, cmd); + +#if NATIVE_WIN32 + strcat(dir, ".exe"); + + /* Mung slashes into backslashes to keep WIndoze happy. */ + { + char *r; + r = dir; + + while (*r) + { + if (*r == '/') + { + *r = '\\'; + } + r++; + } + } +#endif + + if (access(dir, X_OK) == 0) + { + got= strdup(dir); + } + free(dir); + i++; } #if FEATURE_VERBOSE_EXEC if (verboseExec) { @@ -988,6 +1116,7 @@ static void linkEdit (char **envp) { FILE *lnkfile ; char *argv[128]; + char *segName, *c; int i; if (!srcFileName) @@ -1009,30 +1138,63 @@ static void linkEdit (char **envp) /*if (options.debug) */ fprintf(lnkfile,"-z\n"); + +#define WRITE_SEG_LOC(N, L) \ + segName = strdup(N); \ + c = strtok(segName, " \t"); \ + fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \ + if (segName) { free(segName); } + /* code segment start */ - fprintf (lnkfile,"-b CODE = 0x%04x\n",options.code_loc); - /* data segment start */ - fprintf (lnkfile,"-b DSEG = 0x%04x\n",options.data_loc); + WRITE_SEG_LOC(CODE_NAME, options.code_loc); + + /* data segment start */ + WRITE_SEG_LOC(DATA_NAME, options.data_loc); + /* xdata start */ - fprintf (lnkfile,"-b XSEG = 0x%04x\n",options.xdata_loc); + WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc); + /* indirect data */ - fprintf (lnkfile,"-b ISEG = 0x%04x\n",options.idata_loc); + WRITE_SEG_LOC(IDATA_NAME, options.idata_loc); + /* bit segment start */ - fprintf (lnkfile,"-b BSEG = 0x%04x\n",0); + WRITE_SEG_LOC(BIT_NAME, 0); /* add the extra linker options */ for (i=0; linkOptions[i] ; i++) fprintf(lnkfile,"%s\n",linkOptions[i]); /* standard library path */ - fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/, - ( (options.model==0) ? "small": "large")); + if (strcmp(port->target,"ds390")==0) { + c="ds390"; + } else { + switch(options.model) + { + case MODEL_SMALL: + c = "small"; + break; + case MODEL_LARGE: + c = "large"; + break; + case MODEL_FLAT24: + c = "flat24"; + break; + default: + werror(W_UNKNOWN_MODEL, __FILE__, __LINE__); + c = "unknown"; + break; + } + } + fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c); /* other library paths if specified */ for (i = 0 ; i < nlibPaths ; i++ ) fprintf (lnkfile,"-k %s\n",libPaths[i]); /* standard library files */ + if (strcmp(port->target, "ds390")==0) { + fprintf (lnkfile,"-l %s\n",STD_DS390_LIB); + } fprintf (lnkfile,"-l %s\n",STD_LIB); fprintf (lnkfile,"-l %s\n",STD_INT_LIB); fprintf (lnkfile,"-l %s\n",STD_LONG_LIB); @@ -1052,7 +1214,7 @@ static void linkEdit (char **envp) fprintf (lnkfile,"\n-e\n"); fclose(lnkfile); - _buildCmdLine(buffer, argv, linkCmd, port->linker.exec_name, srcFileName, NULL, NULL); + buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL); /* call the linker */ if (my_system(argv[0], argv)) { @@ -1076,7 +1238,7 @@ static void assemble (char **envp) { char *argv[128]; /* assembler arguments */ - _buildCmdLine(buffer, argv, asmCmd, port->assembler.exec_name, srcFileName, NULL, asmOptions); + buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions); if (my_system(argv[0], argv)) { perror("Cannot exec assember"); @@ -1092,39 +1254,71 @@ static void assemble (char **envp) static int preProcess (char **envp) { char *argv[128]; + char procDef[128]; preOutName = NULL; - /* if using external stack define the macro */ - if ( options.useXstack ) - _addToList(preArgv, "-DSDCC_USE_XSTACK"); - - /* set the macro for stack autos */ - if ( options.stackAuto ) - _addToList(preArgv, "-DSDCC_STACK_AUTO"); + if (!options.c1mode) { + /* if using external stack define the macro */ + if ( options.useXstack ) + _addToList(preArgv, "-DSDCC_USE_XSTACK"); + + /* set the macro for stack autos */ + if ( options.stackAuto ) + _addToList(preArgv, "-DSDCC_STACK_AUTO"); + + /* set the macro for stack autos */ + if ( options.stack10bit ) + _addToList(preArgv, "-DSDCC_STACK_TENBIT"); - /* set the macro for large model */ - if ( options.model ) - _addToList(preArgv, "-DSDCC_MODEL_LARGE"); - else - _addToList(preArgv, "-DSDCC_MODEL_SMALL"); + /* set the macro for large model */ + switch(options.model) + { + case MODEL_LARGE: + _addToList(preArgv, "-DSDCC_MODEL_LARGE"); + break; + 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; + default: + werror(W_UNKNOWN_MODEL, __FILE__, __LINE__); + break; + } + - if (!preProcOnly) - preOutName = strdup(tmpnam(NULL)); + /* add port (processor information to processor */ + sprintf(procDef,"-DSDCC_%s",port->target); + _addToList(preArgv,procDef); - _buildCmdLine(buffer, argv, preCmd, fullSrcFileName, - preOutName, srcFileName, preArgv); + if (!preProcOnly) + preOutName = strdup(tmpnam(NULL)); - if (my_system(argv[0], argv)) { - unlink (preOutName); - perror("Cannot exec Preprocessor"); - exit(1); - } + buildCmdLine(buffer, argv, _preCmd, fullSrcFileName, + preOutName, srcFileName, preArgv); - if (preProcOnly) - exit(0); + if (my_system(argv[0], argv)) { + unlink (preOutName); + perror("Cannot exec Preprocessor"); + exit(1); + } + + if (preProcOnly) + exit(0); + } + else { + preOutName = fullSrcFileName; + } - yyin = fopen(preOutName,"r"); + yyin = fopen(preOutName, "r"); if (yyin == NULL) { perror("Preproc file not found\n"); exit(1); @@ -1157,15 +1351,23 @@ int main ( int argc, char **argv , char **envp) { /* turn all optimizations off by default */ memset(&optimize,0,sizeof(struct optimize)); - + /*printVersionInfo ();*/ _findPort(argc, argv); + /* Initalise the port. */ + if (port->init) + port->init(); + setDefaultOptions(); parseCmdLine(argc,argv); + initMem(); + + port->finaliseOptions(); + /* if no input then printUsage & exit */ - if (!srcFileName && !nrelFiles) { + if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) { printUsage(); exit(0); } @@ -1176,7 +1378,6 @@ int main ( int argc, char **argv , char **envp) if (srcFileName) { initSymt(); - initMem(); initiCode(); initCSupport (); initPeepHole(); @@ -1184,8 +1385,11 @@ int main ( int argc, char **argv , char **envp) if (!fatalError) { glue(); - assemble(envp); - } + if (!options.c1mode) + assemble(envp); + } else { + return 1; + } } @@ -1195,16 +1399,22 @@ int main ( int argc, char **argv , char **envp) if (!options.cc_only && !fatalError && !noAssemble && - (srcFileName || nrelFiles)) - linkEdit (envp); + !options.c1mode && + (srcFileName || nrelFiles)) { + if (port->linker.do_link) + port->linker.do_link(); + else + linkEdit (envp); + } if (yyin && yyin != stdin) fclose(yyin); - if (preOutName) { - unlink(preOutName); - free(preOutName); + if (preOutName && !options.c1mode) { + unlink(preOutName); + free(preOutName); } + return 0; }