1 /*-------------------------------------------------------------------------
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
34 // This is a bit messy because we define link ourself
35 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
40 // No unistd.h in Borland C++
41 extern int access(const char *, int);
49 FILE *srcFile ;/* source file */
50 FILE *cdbFile = NULL ;/* debugger information output file */
51 char *fullSrcFileName ;/* full name for the source file */
52 char *srcFileName ;/* source file name with the .c stripped */
53 char *moduleName ;/* module name is srcFilename stripped of any path */
54 const char *preArgv[128] ;/* pre-processor arguments */
56 struct optimize optimize ;
57 struct options options ;
58 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
59 short preProcOnly = 0;
61 char *linkOptions[128];
62 const char *asmOptions[128];
69 bool verboseExec = FALSE;
72 /* Far functions, far data */
73 #define OPTION_LARGE_MODEL "-model-large"
74 /* Far functions, near data */
75 #define OPTION_MEDIUM_MODEL "-model-medium"
76 #define OPTION_SMALL_MODEL "-model-small"
77 #define OPTION_FLAT24_MODEL "-model-flat24"
78 #define OPTION_STACK_AUTO "-stack-auto"
79 #define OPTION_STACK_10BIT "-stack-10bit"
80 #define OPTION_XSTACK "-xstack"
81 #define OPTION_GENERIC "-generic"
82 #define OPTION_NO_GCSE "-nogcse"
83 #define OPTION_NO_LOOP_INV "-noinvariant"
84 #define OPTION_NO_LOOP_IND "-noinduction"
85 #define OPTION_NO_JTBOUND "-nojtbound"
86 #define OPTION_NO_LOOPREV "-noloopreverse"
87 #define OPTION_XREGS "-regextend"
88 #define OPTION_COMP_ONLY "-compile-only"
89 #define OPTION_DUMP_RAW "-dumpraw"
90 #define OPTION_DUMP_GCSE "-dumpgcse"
91 #define OPTION_DUMP_LOOP "-dumploop"
92 #define OPTION_DUMP_KILL "-dumpdeadcode"
93 #define OPTION_DUMP_RANGE "-dumpliverange"
94 #define OPTION_DUMP_PACK "-dumpregpack"
95 #define OPTION_DUMP_RASSGN "-dumpregassign"
96 #define OPTION_DUMP_ALL "-dumpall"
97 #define OPTION_XRAM_LOC "-xram-loc"
98 #define OPTION_IRAM_SIZE "-iram-size"
99 #define OPTION_XSTACK_LOC "-xstack-loc"
100 #define OPTION_CODE_LOC "-code-loc"
101 #define OPTION_STACK_LOC "-stack-loc"
102 #define OPTION_DATA_LOC "-data-loc"
103 #define OPTION_IDATA_LOC "-idata-loc"
104 #define OPTION_PEEP_FILE "-peep-file"
105 #define OPTION_LIB_PATH "-lib-path"
106 #define OPTION_INTLONG_RENT "-int-long-reent"
107 #define OPTION_FLOAT_RENT "-float-reent"
108 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
109 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
110 #define OPTION_CYCLOMATIC "-cyclomatic"
111 #define OPTION_NOOVERLAY "-nooverlay"
112 #define OPTION_MAINRETURN "-main-return"
113 #define OPTION_NOPEEP "-no-peep"
114 #define OPTION_ASMPEEP "-peep-asm"
115 #define OPTION_DEBUG "-debug"
116 #define OPTION_NODEBUG "-nodebug"
117 #define OPTION_VERSION "-version"
118 #define OPTION_STKAFTRDATA "-stack-after-data"
119 #define OPTION_PREPROC_ONLY "-preprocessonly"
120 #define OPTION_C1_MODE "-c1mode"
121 #define OPTION_HELP "-help"
122 #define OPTION_CALLEE_SAVES "-callee-saves"
123 #define OPTION_NOREGPARMS "-noregparms"
124 #define OPTION_NOSTDLIB "-nostdlib"
125 #define OPTION_NOSTDINC "-nostdinc"
126 #define OPTION_VERBOSE "-verbose"
127 #define OPTION_ANSIINT "-ansiint"
128 static const char *_preCmd[] = {
129 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
130 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
135 static PORT *_ports[] = {
136 #if !OPT_DISABLE_MCS51
139 #if !OPT_DISABLE_GBZ80
148 #if !OPT_DISABLE_DS390
154 #if !OPT_DISABLE_I186
157 #if !OPT_DISABLE_TLCS900H
162 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
165 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
167 extern void pic14glue();
169 /** Sets the port to the one given by the command line option.
170 @param The name minus the option (eg 'mcs51')
171 @return 0 on success.
173 static int _setPort(const char *name)
176 for (i=0; i<NUM_PORTS; i++) {
177 if (!strcmp(_ports[i]->target, name)) {
182 /* Error - didnt find */
183 werror(E_UNKNOWN_TARGET,name);
187 static void _validatePorts(void)
190 for (i=0; i<NUM_PORTS; i++) {
191 if (_ports[i]->magic != PORT_MAGIC) {
192 printf("Error: port %s is incomplete.\n", _ports[i]->target);
198 void buildCmdLine(char *into, char **args, const char **cmds,
199 const char *p1, const char *p2,
200 const char *p3, const char **list)
202 const char *p, *from;
212 /* See if it has a '$' anywhere - if not, just copy */
213 if ((p = strchr(from, '$'))) {
214 strncpy(into, from, p - from);
215 /* NULL terminate it */
233 const char **tmp = list;
237 into += strlen(into)+1;
250 if (strlen(into) == 0)
252 into += strlen(into)+1;
257 /*-----------------------------------------------------------------*/
258 /* printVersionInfo - prints the version info */
259 /*-----------------------------------------------------------------*/
260 void printVersionInfo ()
266 for (i=0; i<NUM_PORTS; i++)
267 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
268 fprintf(stderr, " %s"
269 #ifdef SDCC_SUB_VERSION_STR
270 "/" SDCC_SUB_VERSION_STR
287 /*-----------------------------------------------------------------*/
288 /* printUsage - prints command line syntax */
289 /*-----------------------------------------------------------------*/
294 "Usage : [options] filename\n"
296 "\t-m<proc> - Target processor <proc>. Default %s\n"
297 "\t Try --version for supported values of <proc>\n"
298 "\t--model-large - Large Model\n"
299 "\t--model-small - Small Model (default)\n"
300 "\t--stack-auto - Stack automatic variables\n"
301 "\t--xstack - Use external stack\n"
302 "\t--xram-loc <nnnn> - External Ram start location\n"
303 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
304 "\t--code-loc <nnnn> - Code Segment Location\n"
305 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
306 "\t--data-loc <nnnn> - Direct data start location\n"
307 "\t--idata-loc <nnnn> - Indirect data start location\n"
308 "\t--iram-size <nnnn> - Internal Ram size\n"
309 "\t--nojtbound - Don't generate boundary check for jump tables\n"
310 "\t--generic - All unqualified ptrs converted to '_generic'\n"
311 "PreProcessor Options :-\n"
312 "\t-Dmacro - Define Macro\n"
313 "\t-Ipath - Include \"*.h\" path\n"
314 "Note: this is NOT a complete list of options see docs for details\n",
320 /*-----------------------------------------------------------------*/
321 /* parseWithComma - separates string with comma */
322 /*-----------------------------------------------------------------*/
323 void parseWithComma (char **dest,char *src)
328 /* skip the initial white spaces */
329 while (isspace(*src)) src++;
343 /*-----------------------------------------------------------------*/
344 /* setDefaultOptions - sets the default options */
345 /*-----------------------------------------------------------------*/
346 static void setDefaultOptions()
350 for ( i = 0 ; i < 128 ; i++)
351 preArgv[i] = asmOptions [i] =
352 linkOptions[i] = relFiles[i] = libFiles[i] =
355 /* first the options part */
356 options.stack_loc = 0; /* stack pointer initialised to 0 */
357 options.xstack_loc= 0; /* xternal stack starts at 0 */
358 options.code_loc = 0; /* code starts at 0 */
359 options.data_loc = 0x0030; /* data starts at 0x0030 */
360 options.xdata_loc = 0;
361 options.idata_loc = 0x80;
362 options.genericPtr = 1; /* default on */
364 options.model = port->general.default_model;
369 /* now for the optimizations */
370 /* turn on the everything */
371 optimize.global_cse = 1;
376 optimize.loopInvariant = 1;
377 optimize.loopInduction = 1;
379 port->setDefaultOptions();
382 /*-----------------------------------------------------------------*/
383 /* processFile - determines the type of file from the extension */
384 /*-----------------------------------------------------------------*/
385 static void processFile (char *s)
389 /* get the file extension */
390 fext = s + strlen(s);
391 while ((fext != s) && *fext != '.') fext--;
393 /* now if no '.' then we don't know what the file type is
394 so give a warning and return */
396 werror(W_UNKNOWN_FEXT,s);
400 /* otherwise depending on the file type */
401 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
402 /* source file name : not if we already have a
405 werror(W_TOO_MANY_SRC,s);
409 /* the only source file */
410 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
411 werror(E_FILE_OPEN_ERR,s);
415 /* copy the file name into the buffer */
418 /* get rid of the "." */
420 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
421 strcpy(srcFileName,buffer);
423 /* get rid of any path information
424 for the module name; do this by going
425 backwards till we get to either '/' or '\' or ':'
426 or start of buffer */
427 fext = buffer + strlen(buffer);
428 while (fext != buffer &&
429 *(fext -1) != '\\' &&
433 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
434 strcpy(moduleName,fext);
439 /* if the extention is type .rel or .r or .REL or .R
440 addtional object file will be passed to the linker */
441 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
442 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
443 strcmp(fext, port->linker.rel_ext) == 0)
445 relFiles[nrelFiles++] = s;
449 /* if .lib or .LIB */
450 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
451 libFiles[nlibFiles++] = s;
455 werror(W_UNKNOWN_FEXT,s);
459 static void _processC1Arg(char *s)
462 if (options.out_name) {
463 werror(W_TOO_MANY_SRC,s);
466 options.out_name = strdup(s);
473 static void _addToList(const char **list, const char *str)
475 /* This is the bad way to do things :) */
480 werror(E_OUT_OF_MEM,__FILE__, 0);
486 static void _setModel(int model, const char *sz)
488 if (port->general.supported_models & model)
489 options.model = model;
491 werror(W_UNSUPPORTED_MODEL, sz, port->target);
494 /*-----------------------------------------------------------------*/
495 /* parseCmdLine - parses the command line and sets the options */
496 /*-----------------------------------------------------------------*/
497 int parseCmdLine ( int argc, char **argv )
502 /* go thru all whole command line */
503 for ( i = 1; i < argc; i++ ) {
508 if (argv[i][0] == '-' && argv[i][1] == '-') {
510 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
515 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
516 options.regExtend = 1;
520 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
521 _setModel(MODEL_LARGE, argv[i]);
525 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
526 _setModel(MODEL_MEDIUM, argv[i]);
530 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
531 _setModel(MODEL_SMALL, argv[i]);
535 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
536 _setModel(MODEL_FLAT24, argv[i]);
540 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
541 options.stack10bit = 1;
545 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
546 options.stackAuto = 1;
550 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
551 options.dump_raw = 1;
555 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
556 options.cyclomatic = 1;
560 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
561 options.dump_gcse = 1;
565 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
566 options.dump_loop = 1;
570 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
571 options.dump_kill = 1;
575 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
576 options.intlong_rent = 1;
580 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
581 options.float_rent = 1;
585 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
586 options.dump_range = 1;
590 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
591 options.dump_pack = 1;
595 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
596 options.dump_rassgn = 1;
600 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
605 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
610 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
611 options.noOverlay = 1;
615 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
616 options.stackOnData = 1;
620 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
625 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
631 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
632 options.dump_rassgn =
638 options.dump_raw = 1;
642 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
647 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
648 options.genericPtr = 1;
652 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
657 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
662 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
667 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
672 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
673 options.noregparms = 1;
677 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
678 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
680 &argv[i][1+strlen(OPTION_PEEP_FILE)];
682 options.peep_file = argv[++i];
686 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
687 if (argv[i][1+strlen(OPTION_LIB_PATH)])
688 libPaths[nlibPaths++] =
689 &argv[i][1+strlen(OPTION_PEEP_FILE)];
691 libPaths[nlibPaths++] = argv[++i];
695 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
697 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
699 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
702 (int) floatFromVal(constVal(argv[++i]));
706 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
707 options.useXstack = 1;
711 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
712 options.mainreturn = 1;
716 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
717 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
718 parseWithComma(options.calleeSaves
719 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
721 parseWithComma(options.calleeSaves,argv[++i]);
725 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
727 if (argv[i][1+strlen(OPTION_STACK_LOC)])
729 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
732 (int) floatFromVal(constVal(argv[++i]));
736 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
738 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
740 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
743 (unsigned int) floatFromVal(constVal(argv[++i]));
747 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
749 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
751 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
754 (int) floatFromVal(constVal(argv[++i]));
758 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
764 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
766 if (argv[i][1+strlen(OPTION_DATA_LOC)])
768 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
771 (int) floatFromVal(constVal(argv[++i]));
775 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
777 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
779 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
782 (int) floatFromVal(constVal(argv[++i]));
786 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
788 if (argv[i][1+strlen(OPTION_CODE_LOC)])
790 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
793 (int) floatFromVal(constVal(argv[++i]));
798 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
799 optimize.noJTabBoundary = 1;
803 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
804 optimize.global_cse = 0;
808 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
809 optimize.loopInvariant = 0;
813 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
814 optimize.loopInduction = 0;
818 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
819 optimize.noLoopReverse = 1;
823 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
828 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
833 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
838 if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
843 if (!port->parseOption(&argc, argv, &i))
845 werror(W_UNKNOWN_OPTION,argv[i]);
853 /* these are undocumented options */
854 /* if preceded by '/' then turn off certain optmizations, used
855 for debugging only these are also the legacy options from
856 version 1.xx will be removed gradually.
857 It may be an absolute filename.
859 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
860 switch (argv[i][1]) {
863 optimize.ptrArithmetic=0;
867 switch (argv[i][2]) {
872 optimize.label4 = 0 ;
890 switch (argv[i][2]) {
892 optimize.loopInvariant = 0;
895 optimize.loopInduction = 0;
902 optimize.global_cse = 0;
909 /* if preceded by '-' then option */
910 if ( *argv[i] == '-' ) {
911 switch (argv[i][1]) {
922 /* Used to select the port */
923 if (_setPort(argv[i] + 2)) {
924 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
929 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
933 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
936 case 'X' : /* use external stack */
937 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
941 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
944 case 'p' : /* stack pointer intial value */
946 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
950 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
954 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
958 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
966 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
971 libPaths[nlibPaths++] = &argv[i][2];
973 libPaths[nlibPaths++] = argv[++i];
978 if (argv[i][2] == 'l') {
980 parseWithComma(linkOptions,&argv[i][3]);
982 parseWithComma(linkOptions,argv[++i]);
984 /* assembler options */
985 if (argv[i][2] == 'a') {
987 parseWithComma((char **)asmOptions,&argv[i][3]);
989 parseWithComma((char **)asmOptions,argv[++i]);
992 werror(W_UNKNOWN_OPTION,argv[i]);
1009 /* preprocessor options */
1013 _addToList(preArgv, "-M");
1018 _addToList(preArgv, "-C");
1027 char sOpt = argv[i][1] ;
1030 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1035 rest = &argv[i][2] ;
1037 if ( argv[i][1] == 'Y' )
1040 sprintf(buffer, "-%c%s", sOpt, rest);
1041 _addToList(preArgv, buffer);
1046 if (!port->parseOption(&argc, argv, &i))
1047 werror(W_UNKNOWN_OPTION,argv[i]);
1052 if (!port->parseOption(&argc, argv, &i)) {
1053 /* no option must be a filename */
1055 _processC1Arg(argv[i]);
1057 processFile(argv[i]);
1061 /* set up external stack location if not explicitly specified */
1062 if ( !options.xstack_loc )
1063 options.xstack_loc = options.xdata_loc ;
1065 /* if debug option is set the open the cdbFile */
1066 if (!options.nodebug && srcFileName) {
1067 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1068 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1069 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1071 /* add a module record */
1072 fprintf(cdbFile,"M:%s\n",moduleName);
1078 /*-----------------------------------------------------------------*/
1079 /* my_system - will call a program with arguments */
1080 /*-----------------------------------------------------------------*/
1082 #if defined(_MSC_VER)
1084 char *try_dir[]= {NULL}; // TODO : Fill in some default search list
1088 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1092 int my_system (const char *cmd, char **cmd_argv)
1094 char *dir, *got= NULL; int i= 0;
1096 while (!got && try_dir[i])
1098 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1099 strcpy(dir, try_dir[i]);
1104 strcat(dir, ".exe");
1106 /* Mung slashes into backslashes to keep WIndoze happy. */
1122 if (access(dir, X_OK) == 0)
1131 char **pCmd = cmd_argv;
1134 printf("%s ", *pCmd);
1142 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1146 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1148 perror("Cannot exec process ");
1155 /*-----------------------------------------------------------------*/
1156 /* linkEdit : - calls the linkage editor with options */
1157 /*-----------------------------------------------------------------*/
1158 static void linkEdit (char **envp)
1166 srcFileName = "temp";
1168 /* first we need to create the <filename>.lnk file */
1169 sprintf(buffer,"%s.lnk",srcFileName);
1170 if (!(lnkfile = fopen(buffer,"w"))) {
1171 werror(E_FILE_OPEN_ERR,buffer);
1175 /* now write the options */
1176 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1178 /* if iram size specified */
1179 if (options.iram_size)
1180 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1182 /*if (options.debug) */
1183 fprintf(lnkfile,"-z\n");
1185 #define WRITE_SEG_LOC(N, L) \
1186 segName = strdup(N); \
1187 c = strtok(segName, " \t"); \
1188 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1189 if (segName) { free(segName); }
1191 /* code segment start */
1192 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1194 /* data segment start */
1195 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1198 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1201 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1203 /* bit segment start */
1204 WRITE_SEG_LOC(BIT_NAME, 0);
1206 /* add the extra linker options */
1207 for (i=0; linkOptions[i] ; i++)
1208 fprintf(lnkfile,"%s\n",linkOptions[i]);
1210 /* other library paths if specified */
1211 for (i = 0 ; i < nlibPaths ; i++ )
1212 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1214 /* standard library path */
1215 if (!options.nostdlib) {
1216 if (IS_DS390_PORT) {
1219 switch(options.model)
1231 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1236 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1238 /* standard library files */
1239 if (strcmp(port->target, "ds390")==0) {
1240 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1242 fprintf (lnkfile,"-l %s\n",STD_LIB);
1243 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1244 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1245 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1248 /* additional libraries if any */
1249 for (i = 0 ; i < nlibFiles; i++)
1250 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1252 /* put in the object files */
1253 if (strcmp(srcFileName,"temp"))
1254 fprintf (lnkfile,"%s ",srcFileName);
1256 for (i = 0 ; i < nrelFiles ; i++ )
1257 fprintf (lnkfile,"%s\n",relFiles[i]);
1259 fprintf (lnkfile,"\n-e\n");
1262 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1264 if (options.verbose)
1265 printf ("sdcc: Calling linker...\n");
1266 if (my_system(argv[0], argv)) {
1267 perror("Cannot exec linker");
1271 if (strcmp(srcFileName,"temp") == 0) {
1272 /* rename "temp.cdb" to "firstRelFile.cdb" */
1273 char *f = strtok(strdup(relFiles[0]),".");
1274 f = strcat(f,".cdb");
1275 rename("temp.cdb",f);
1280 /*-----------------------------------------------------------------*/
1281 /* assemble - spawns the assembler with arguments */
1282 /*-----------------------------------------------------------------*/
1283 static void assemble (char **envp)
1285 char *argv[128]; /* assembler arguments */
1287 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1289 if (my_system(argv[0], argv)) {
1290 perror("Cannot exec assember");
1297 /*-----------------------------------------------------------------*/
1298 /* preProcess - spawns the preprocessor with arguments */
1299 /*-----------------------------------------------------------------*/
1300 static int preProcess (char **envp)
1307 if (!options.c1mode) {
1308 /* if using external stack define the macro */
1309 if ( options.useXstack )
1310 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1312 /* set the macro for stack autos */
1313 if ( options.stackAuto )
1314 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1316 /* set the macro for stack autos */
1317 if ( options.stack10bit )
1318 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1320 /* set the macro for large model */
1321 switch(options.model)
1324 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1327 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1330 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1333 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1336 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1339 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1344 /* add port (processor information to processor */
1345 sprintf(procDef,"-DSDCC_%s",port->target);
1346 _addToList(preArgv,procDef);
1349 preOutName = strdup(tmpnam(NULL));
1351 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1352 preOutName, srcFileName, preArgv);
1354 if (options.verbose)
1355 printf ("sdcc: Calling preprocessor...\n");
1357 if (my_system(argv[0], argv)) {
1358 unlink (preOutName);
1359 perror("Cannot exec Preprocessor");
1367 preOutName = fullSrcFileName;
1370 yyin = fopen(preOutName, "r");
1372 perror("Preproc file not found\n");
1379 static void _findPort(int argc, char **argv)
1385 if (!strncmp(*argv, "-m", 2)) {
1386 _setPort(*argv + 2);
1392 /* Use the first in the list */
1398 * initialises and calls the parser
1401 int main ( int argc, char **argv , char **envp)
1403 /* turn all optimizations off by default */
1404 memset(&optimize,0,sizeof(struct optimize));
1406 /*printVersionInfo ();*/
1408 _findPort(argc, argv);
1409 /* Initalise the port. */
1413 setDefaultOptions();
1414 parseCmdLine(argc,argv);
1418 port->finaliseOptions();
1420 /* if no input then printUsage & exit */
1421 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1434 if (options.verbose)
1435 printf ("sdcc: Generating code...\n");
1441 /* TSD PIC port hack - if the PIC port option is enabled
1442 and SDCC is used to generate PIC code, then we will
1443 generate .asm files in gpasm's format instead of SDCC's
1446 #if !OPT_DISABLE_PIC
1456 if (!options.c1mode)
1458 if (options.verbose)
1459 printf ("sdcc: Calling assembler...\n");
1474 if (!options.cc_only &&
1478 (srcFileName || nrelFiles)) {
1479 if (port->linker.do_link)
1480 port->linker.do_link();
1485 if (yyin && yyin != stdin)
1488 if (preOutName && !options.c1mode) {