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 -------------------------------------------------------------------------*/
29 /* This is a bit messy. We cant include unistd.h as it defines
30 'link' which we also use.
32 int access(const char *path, int mode);
34 int unlink(const char *path);
36 extern void initSymt ();
37 extern void initMem ();
38 extern void initExpr ();
39 extern void initiCode ();
40 extern void initCSupport ();
41 extern void initPeepHole ();
42 extern void createObject ();
43 extern int yyparse ();
45 extern struct value *constVal(char *s);
46 extern double floatFromVal(struct value *);
47 extern int fatalError ;
48 FILE *srcFile ;/* source file */
49 FILE *cdbFile = NULL ;/* debugger information output file */
50 char *fullSrcFileName ;/* full name for the source file */
51 char *srcFileName ;/* source file name with the .c stripped */
52 char *moduleName ;/* module name is srcFilename stripped of any path */
53 const char *preArgv[128] ;/* pre-processor arguments */
55 struct optimize optimize ;
56 struct options options ;
57 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
58 short preProcOnly = 0;
60 char *linkOptions[128];
61 const char *asmOptions[128];
68 bool verboseExec = FALSE;
69 //extern int wait (int *);
72 #define OPTION_LARGE_MODEL "-model-large"
73 #define OPTION_SMALL_MODEL "-model-small"
74 #define OPTION_FLAT24_MODEL "-model-flat24"
75 #define OPTION_STACK_AUTO "-stack-auto"
76 #define OPTION_XSTACK "-xstack"
77 #define OPTION_GENERIC "-generic"
78 #define OPTION_NO_GCSE "-nogcse"
79 #define OPTION_NO_LOOP_INV "-noinvariant"
80 #define OPTION_NO_LOOP_IND "-noinduction"
81 #define OPTION_NO_JTBOUND "-nojtbound"
82 #define OPTION_NO_LOOPREV "-noloopreverse"
83 #define OPTION_XREGS "-regextend"
84 #define OPTION_COMP_ONLY "-compile-only"
85 #define OPTION_DUMP_RAW "-dumpraw"
86 #define OPTION_DUMP_GCSE "-dumpgcse"
87 #define OPTION_DUMP_LOOP "-dumploop"
88 #define OPTION_DUMP_KILL "-dumpdeadcode"
89 #define OPTION_DUMP_RANGE "-dumpliverange"
90 #define OPTION_DUMP_PACK "-dumpregpack"
91 #define OPTION_DUMP_RASSGN "-dumpregassign"
92 #define OPTION_DUMP_ALL "-dumpall"
93 #define OPTION_XRAM_LOC "-xram-loc"
94 #define OPTION_IRAM_SIZE "-iram-size"
95 #define OPTION_XSTACK_LOC "-xstack-loc"
96 #define OPTION_CODE_LOC "-code-loc"
97 #define OPTION_STACK_LOC "-stack-loc"
98 #define OPTION_DATA_LOC "-data-loc"
99 #define OPTION_IDATA_LOC "-idata-loc"
100 #define OPTION_PEEP_FILE "-peep-file"
101 #define OPTION_LIB_PATH "-lib-path"
102 #define OPTION_INTLONG_RENT "-int-long-reent"
103 #define OPTION_FLOAT_RENT "-float-reent"
104 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
105 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
106 #define OPTION_CYCLOMATIC "-cyclomatic"
107 #define OPTION_NOOVERLAY "-nooverlay"
108 #define OPTION_MAINRETURN "-main-return"
109 #define OPTION_NOPEEP "-no-peep"
110 #define OPTION_ASMPEEP "-peep-asm"
111 #define OPTION_DEBUG "-debug"
112 #define OPTION_VERSION "-version"
113 #define OPTION_STKAFTRDATA "-stack-after-data"
114 #define OPTION_PREPROC_ONLY "-preprocessonly"
115 #define OPTION_C1_MODE "-c1mode"
116 #define OPTION_HELP "-help"
117 #define OPTION_CALLEE_SAVES "-callee-saves"
118 #define OPTION_NOREGPARMS "-noregparms"
120 static const char *_preCmd[] = {
121 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
122 "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
125 extern PORT mcs51_port;
126 extern PORT z80_port;
127 extern PORT gbz80_port;
131 static PORT *_ports[] = {
137 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
139 /** Sets the port to the one given by the command line option.
140 @param The name minus the option (eg 'mcs51')
141 @return 0 on success.
143 static int _setPort(const char *name)
146 for (i=0; i<NUM_PORTS; i++) {
147 if (!strcmp(_ports[i]->target, name)) {
152 /* Error - didnt find */
156 static void _buildCmdLine(char *into, char **args, const char **cmds,
157 const char *p1, const char *p2,
158 const char *p3, const char **list)
160 const char *p, *from;
170 /* See if it has a '$' anywhere - if not, just copy */
171 if ((p = strchr(from, '$'))) {
172 strncpy(into, from, p - from);
189 const char **tmp = list;
193 into += strlen(into)+1;
206 if (strlen(into) == 0)
208 into += strlen(into)+1;
213 /*-----------------------------------------------------------------*/
214 /* printVersionInfo - prints the version info */
215 /*-----------------------------------------------------------------*/
216 void printVersionInfo ()
222 for (i=0; i<NUM_PORTS; i++)
223 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
225 fprintf(stderr, " %s `"
239 /*-----------------------------------------------------------------*/
240 /* printUsage - prints command line syntax */
241 /*-----------------------------------------------------------------*/
246 "Usage : [options] filename\n"
248 "\t-m<proc> - Target processor <proc>. Default %s\n"
249 "\t Try --version for supported values of <proc>\n"
250 "\t--model-large - Large Model\n"
251 "\t--model-small - Small Model (default)\n"
252 "\t--stack-auto - Stack automatic variables\n"
253 "\t--xstack - Use external stack\n"
254 "\t--xram-loc <nnnn> - External Ram start location\n"
255 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
256 "\t--code-loc <nnnn> - Code Segment Location\n"
257 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
258 "\t--data-loc <nnnn> - Direct data start location\n"
259 "\t--idata-loc <nnnn> - Indirect data start location\n"
260 "\t--iram-size <nnnn> - Internal Ram size\n"
261 "\t--nojtbound - Don't generate boundary check for jump tables\n"
262 "\t--generic - All unqualified ptrs converted to '_generic'\n"
263 "PreProcessor Options :-\n"
264 "\t-Dmacro - Define Macro\n"
265 "\t-Ipath - Include \"*.h\" path\n"
266 "Note: this is a complete list of options see docs for details\n",
272 /*-----------------------------------------------------------------*/
273 /* parseWithComma - separates string with comma */
274 /*-----------------------------------------------------------------*/
275 void parseWithComma (char **dest,char *src)
280 /* skip the initial white spaces */
281 while (isspace(*src)) src++;
295 /*-----------------------------------------------------------------*/
296 /* setDefaultOptions - sets the default options */
297 /*-----------------------------------------------------------------*/
298 static void setDefaultOptions()
302 for ( i = 0 ; i < 128 ; i++)
303 preArgv[i] = asmOptions [i] =
304 linkOptions[i] = relFiles[i] = libFiles[i] =
307 /* first the options part */
308 options.stack_loc = 0; /* stack pointer initialised to 0 */
309 options.xstack_loc= 0; /* xternal stack starts at 0 */
310 options.code_loc = 0; /* code starts at 0 */
311 options.data_loc = 0x0030; /* data starts at 0x0030 */
312 options.xdata_loc = 0;
313 options.idata_loc = 0x80;
314 options.genericPtr = 1; /* default on */
317 /* now for the optimizations */
318 /* turn on the everything */
319 optimize.global_cse = 1;
324 optimize.loopInvariant = 1;
325 optimize.loopInduction = 1;
327 port->setDefaultOptions();
330 /*-----------------------------------------------------------------*/
331 /* processFile - determines the type of file from the extension */
332 /*-----------------------------------------------------------------*/
333 static void processFile (char *s)
337 /* get the file extension */
338 fext = s + strlen(s);
339 while ((fext != s) && *fext != '.') fext--;
341 /* now if no '.' then we don't know what the file type is
342 so give a warning and return */
344 werror(W_UNKNOWN_FEXT,s);
348 /* otherwise depending on the file type */
349 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
350 /* source file name : not if we already have a
353 werror(W_TOO_MANY_SRC,s);
357 /* the only source file */
358 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
359 werror(E_FILE_OPEN_ERR,s);
363 /* copy the file name into the buffer */
366 /* get rid of the "." */
368 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
369 strcpy(srcFileName,buffer);
371 /* get rid of any path information
372 for the module name; do this by going
373 backwards till we get to either '/' or '\' or ':'
374 or start of buffer */
375 fext = buffer + strlen(buffer);
376 while (fext != buffer &&
377 *(fext -1) != '\\' &&
381 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
382 strcpy(moduleName,fext);
387 /* if the extention is type .rel or .r or .REL or .R
388 addtional object file will be passed to the linker */
389 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
390 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
392 relFiles[nrelFiles++] = s;
396 /* if .lib or .LIB */
397 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
398 libFiles[nlibFiles++] = s;
402 werror(W_UNKNOWN_FEXT,s);
406 static void _processC1Arg(char *s)
409 if (options.out_name) {
410 werror(W_TOO_MANY_SRC,s);
413 options.out_name = strdup(s);
420 static void _addToList(const char **list, const char *str)
422 /* This is the bad way to do things :) */
427 werror(E_OUT_OF_MEM,__FILE__, 0);
433 /*-----------------------------------------------------------------*/
434 /* parseCmdLine - parses the command line and sets the options */
435 /*-----------------------------------------------------------------*/
436 int parseCmdLine ( int argc, char **argv )
441 /* go thru all whole command line */
442 for ( i = 1; i < argc; i++ ) {
447 if (argv[i][0] == '-' && argv[i][1] == '-') {
449 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
454 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
455 options.regExtend = 1;
459 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
460 options.model = MODEL_LARGE;
464 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
465 options.model = MODEL_SMALL;
469 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
470 options.model = MODEL_FLAT24;
474 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
475 options.stackAuto = 1;
479 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
480 options.dump_raw = 1;
484 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
485 options.cyclomatic = 1;
489 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
490 options.dump_gcse = 1;
494 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
495 options.dump_loop = 1;
499 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
500 options.dump_kill = 1;
504 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
505 options.intlong_rent = 1;
509 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
510 options.float_rent = 1;
514 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
515 options.dump_range = 1;
519 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
520 options.dump_pack = 1;
524 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
525 options.dump_rassgn = 1;
529 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
534 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
539 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
540 options.noOverlay = 1;
544 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
545 options.stackOnData = 1;
549 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
554 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
560 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
561 options.dump_rassgn =
567 options.dump_raw = 1;
571 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
576 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
577 options.genericPtr = 1;
581 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
586 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
591 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
596 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
597 options.noregparms = 1;
601 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
602 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
604 &argv[i][1+strlen(OPTION_PEEP_FILE)];
606 options.peep_file = argv[++i];
610 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
611 if (argv[i][1+strlen(OPTION_LIB_PATH)])
612 libPaths[nlibPaths++] =
613 &argv[i][1+strlen(OPTION_PEEP_FILE)];
615 libPaths[nlibPaths++] = argv[++i];
619 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
621 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
623 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
626 (int) floatFromVal(constVal(argv[++i]));
630 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
631 options.useXstack = 1;
635 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
636 options.mainreturn = 1;
640 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
641 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
642 parseWithComma(options.calleeSaves
643 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
645 parseWithComma(options.calleeSaves,argv[++i]);
649 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
651 if (argv[i][1+strlen(OPTION_STACK_LOC)])
653 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
656 (int) floatFromVal(constVal(argv[++i]));
660 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
662 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
664 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
667 (unsigned int) floatFromVal(constVal(argv[++i]));
671 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
673 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
675 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
678 (int) floatFromVal(constVal(argv[++i]));
682 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
688 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
690 if (argv[i][1+strlen(OPTION_DATA_LOC)])
692 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
695 (int) floatFromVal(constVal(argv[++i]));
699 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
701 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
703 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
706 (int) floatFromVal(constVal(argv[++i]));
710 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
712 if (argv[i][1+strlen(OPTION_CODE_LOC)])
714 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
717 (int) floatFromVal(constVal(argv[++i]));
722 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
723 optimize.noJTabBoundary = 1;
727 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
728 optimize.global_cse = 0;
732 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
733 optimize.loopInvariant = 0;
737 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
738 optimize.loopInduction = 0;
742 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
743 optimize.noLoopReverse = 1;
747 if (!port->parseOption(&argc, argv, &i))
749 werror(W_UNKNOWN_OPTION,argv[i]);
757 /* these are undocumented options */
758 /* if preceded by '/' then turn off certain optmizations, used
759 for debugging only these are also the legacy options from
760 version 1.xx will be removed gradually.
761 It may be an absolute filename.
763 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
764 switch (argv[i][1]) {
767 optimize.ptrArithmetic=0;
771 switch (argv[i][2]) {
776 optimize.label4 = 0 ;
794 switch (argv[i][2]) {
796 optimize.loopInvariant = 0;
799 optimize.loopInduction = 0;
806 optimize.global_cse = 0;
813 /* if preceded by '-' then option */
814 if ( *argv[i] == '-' ) {
815 switch (argv[i][1]) {
826 /* Used to select the port */
827 if (_setPort(argv[i] + 2)) {
828 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
833 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
837 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
840 case 'X' : /* use external stack */
841 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
845 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
848 case 'p' : /* stack pointer intial value */
850 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
854 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
858 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
862 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
870 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
875 libPaths[nlibPaths++] = &argv[i][2];
877 libPaths[nlibPaths++] = argv[++i];
882 if (argv[i][2] == 'l') {
884 parseWithComma(linkOptions,&argv[i][3]);
886 parseWithComma(linkOptions,argv[++i]);
888 /* assembler options */
889 if (argv[i][2] == 'a') {
891 parseWithComma((char **)asmOptions,&argv[i][3]);
893 parseWithComma((char **)asmOptions,argv[++i]);
896 werror(W_UNKNOWN_OPTION,argv[i]);
905 #if FEATURE_VERBOSE_EXEC
913 /* preprocessor options */
922 char sOpt = argv[i][1] ;
925 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
932 if ( argv[i][1] == 'Y' )
934 if (argv[i][1] == 'M')
937 sprintf(buffer, "-%c%s", sOpt, rest);
938 _addToList(preArgv, buffer);
943 if (!port->parseOption(&argc, argv, &i))
944 werror(W_UNKNOWN_OPTION,argv[i]);
949 if (!port->parseOption(&argc, argv, &i)) {
950 /* no option must be a filename */
952 _processC1Arg(argv[i]);
954 processFile(argv[i]);
958 /* set up external stack location if not explicitly specified */
959 if ( !options.xstack_loc )
960 options.xstack_loc = options.xdata_loc ;
962 /* if debug option is set the open the cdbFile */
963 if (/* options.debug && */ srcFileName) {
964 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
965 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
966 werror(E_FILE_OPEN_ERR,cdbfnbuf);
968 /* add a module record */
969 fprintf(cdbFile,"M:%s\n",moduleName);
972 port->finaliseOptions();
976 /*-----------------------------------------------------------------*/
977 /* my_system - will call a program with arguments */
978 /*-----------------------------------------------------------------*/
979 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
980 int my_system (const char *cmd, char **cmd_argv)
983 char *dir, *got= NULL; int i= 0;
984 while (!got && try_dir[i]) {
985 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
986 strcpy(dir, try_dir[i]); strcat(dir, "/"); strcat(dir, cmd);
987 if (access(dir, X_OK) == 0)
992 #if FEATURE_VERBOSE_EXEC
994 char **pCmd = cmd_argv;
996 printf("%s ", *pCmd);
1003 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1005 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1007 perror("Cannot exec process ");
1014 /*-----------------------------------------------------------------*/
1015 /* linkEdit : - calls the linkage editor with options */
1016 /*-----------------------------------------------------------------*/
1017 static void linkEdit (char **envp)
1025 srcFileName = "temp";
1027 /* first we need to create the <filename>.lnk file */
1028 sprintf(buffer,"%s.lnk",srcFileName);
1029 if (!(lnkfile = fopen(buffer,"w"))) {
1030 werror(E_FILE_OPEN_ERR,buffer);
1034 /* now write the options */
1035 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1037 /* if iram size specified */
1038 if (options.iram_size)
1039 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1041 /*if (options.debug) */
1042 fprintf(lnkfile,"-z\n");
1044 #define WRITE_SEG_LOC(N, L) \
1045 segName = strdup(N); \
1046 c = strtok(segName, " \t"); \
1047 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1048 if (segName) { free(segName); }
1050 /* code segment start */
1051 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1053 /* data segment start */
1054 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1057 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1060 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1062 /* bit segment start */
1063 WRITE_SEG_LOC(BIT_NAME, 0);
1065 /* add the extra linker options */
1066 for (i=0; linkOptions[i] ; i++)
1067 fprintf(lnkfile,"%s\n",linkOptions[i]);
1069 /* standard library path */
1070 switch(options.model)
1082 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1086 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1088 /* other library paths if specified */
1089 for (i = 0 ; i < nlibPaths ; i++ )
1090 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1092 /* standard library files */
1093 fprintf (lnkfile,"-l %s\n",STD_LIB);
1094 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1095 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1096 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1098 /* additional libraries if any */
1099 for (i = 0 ; i < nlibFiles; i++)
1100 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1102 /* put in the object files */
1103 if (strcmp(srcFileName,"temp"))
1104 fprintf (lnkfile,"%s ",srcFileName);
1106 for (i = 0 ; i < nrelFiles ; i++ )
1107 fprintf (lnkfile,"%s\n",relFiles[i]);
1109 fprintf (lnkfile,"\n-e\n");
1112 _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1114 /* call the linker */
1115 if (my_system(argv[0], argv)) {
1116 perror("Cannot exec linker");
1120 if (strcmp(srcFileName,"temp") == 0) {
1121 /* rename "temp.cdb" to "firstRelFile.cdb" */
1122 char *f = strtok(strdup(relFiles[0]),".");
1123 f = strcat(f,".cdb");
1124 rename("temp.cdb",f);
1129 /*-----------------------------------------------------------------*/
1130 /* assemble - spawns the assembler with arguments */
1131 /*-----------------------------------------------------------------*/
1132 static void assemble (char **envp)
1134 char *argv[128]; /* assembler arguments */
1136 _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1138 if (my_system(argv[0], argv)) {
1139 perror("Cannot exec assember");
1146 /*-----------------------------------------------------------------*/
1147 /* preProcess - spawns the preprocessor with arguments */
1148 /*-----------------------------------------------------------------*/
1149 static int preProcess (char **envp)
1156 if (!options.c1mode) {
1157 /* if using external stack define the macro */
1158 if ( options.useXstack )
1159 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1161 /* set the macro for stack autos */
1162 if ( options.stackAuto )
1163 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1165 /* set the macro for large model */
1166 switch(options.model)
1169 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1172 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1175 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1178 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1183 /* add port (processor information to processor */
1184 sprintf(procDef,"-DSDCC_%s",port->target);
1185 _addToList(preArgv,procDef);
1188 preOutName = strdup(tmpnam(NULL));
1190 _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1191 preOutName, srcFileName, preArgv);
1193 if (my_system(argv[0], argv)) {
1194 unlink (preOutName);
1195 perror("Cannot exec Preprocessor");
1203 preOutName = fullSrcFileName;
1206 yyin = fopen(preOutName, "r");
1208 perror("Preproc file not found\n");
1215 static void _findPort(int argc, char **argv)
1219 if (!strncmp(*argv, "-m", 2)) {
1220 _setPort(*argv + 2);
1226 /* Use the first in the list */
1232 * initialises and calls the parser
1235 int main ( int argc, char **argv , char **envp)
1237 /* turn all optimizations off by default */
1238 memset(&optimize,0,sizeof(struct optimize));
1240 /*printVersionInfo ();*/
1242 _findPort(argc, argv);
1243 /* Initalise the port. */
1247 setDefaultOptions();
1248 parseCmdLine(argc,argv);
1250 /* if no input then printUsage & exit */
1251 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1271 if (!options.c1mode)
1280 if (!options.cc_only &&
1284 (srcFileName || nrelFiles))
1287 if (yyin && yyin != stdin)
1290 if (preOutName && !options.c1mode) {