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. We cant include unistd.h as it defines
35 'link' which we also use.
37 int access(const char *path, int mode);
39 int unlink(const char *path);
41 extern void initSymt ();
42 extern void initMem ();
43 extern void initExpr ();
44 extern void initiCode ();
45 extern void initCSupport ();
46 extern void initPeepHole ();
47 extern void createObject ();
48 extern int yyparse ();
50 extern struct value *constVal(char *s);
51 extern double floatFromVal(struct value *);
52 extern int fatalError ;
53 FILE *srcFile ;/* source file */
54 FILE *cdbFile = NULL ;/* debugger information output file */
55 char *fullSrcFileName ;/* full name for the source file */
56 char *srcFileName ;/* source file name with the .c stripped */
57 char *moduleName ;/* module name is srcFilename stripped of any path */
58 const char *preArgv[128] ;/* pre-processor arguments */
60 struct optimize optimize ;
61 struct options options ;
62 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
63 short preProcOnly = 0;
65 char *linkOptions[128];
66 const char *asmOptions[128];
73 bool verboseExec = FALSE;
74 //extern int wait (int *);
77 #define OPTION_LARGE_MODEL "-model-large"
78 #define OPTION_SMALL_MODEL "-model-small"
79 #define OPTION_FLAT24_MODEL "-model-flat24"
80 #define OPTION_STACK_AUTO "-stack-auto"
81 #define OPTION_XSTACK "-xstack"
82 #define OPTION_GENERIC "-generic"
83 #define OPTION_NO_GCSE "-nogcse"
84 #define OPTION_NO_LOOP_INV "-noinvariant"
85 #define OPTION_NO_LOOP_IND "-noinduction"
86 #define OPTION_NO_JTBOUND "-nojtbound"
87 #define OPTION_NO_LOOPREV "-noloopreverse"
88 #define OPTION_XREGS "-regextend"
89 #define OPTION_COMP_ONLY "-compile-only"
90 #define OPTION_DUMP_RAW "-dumpraw"
91 #define OPTION_DUMP_GCSE "-dumpgcse"
92 #define OPTION_DUMP_LOOP "-dumploop"
93 #define OPTION_DUMP_KILL "-dumpdeadcode"
94 #define OPTION_DUMP_RANGE "-dumpliverange"
95 #define OPTION_DUMP_PACK "-dumpregpack"
96 #define OPTION_DUMP_RASSGN "-dumpregassign"
97 #define OPTION_DUMP_ALL "-dumpall"
98 #define OPTION_XRAM_LOC "-xram-loc"
99 #define OPTION_IRAM_SIZE "-iram-size"
100 #define OPTION_XSTACK_LOC "-xstack-loc"
101 #define OPTION_CODE_LOC "-code-loc"
102 #define OPTION_STACK_LOC "-stack-loc"
103 #define OPTION_DATA_LOC "-data-loc"
104 #define OPTION_IDATA_LOC "-idata-loc"
105 #define OPTION_PEEP_FILE "-peep-file"
106 #define OPTION_LIB_PATH "-lib-path"
107 #define OPTION_INTLONG_RENT "-int-long-reent"
108 #define OPTION_FLOAT_RENT "-float-reent"
109 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
110 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
111 #define OPTION_CYCLOMATIC "-cyclomatic"
112 #define OPTION_NOOVERLAY "-nooverlay"
113 #define OPTION_MAINRETURN "-main-return"
114 #define OPTION_NOPEEP "-no-peep"
115 #define OPTION_ASMPEEP "-peep-asm"
116 #define OPTION_DEBUG "-debug"
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"
125 static const char *_preCmd[] = {
126 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
127 "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
130 extern PORT mcs51_port;
131 extern PORT z80_port;
132 extern PORT gbz80_port;
136 static PORT *_ports[] = {
142 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
144 /** Sets the port to the one given by the command line option.
145 @param The name minus the option (eg 'mcs51')
146 @return 0 on success.
148 static int _setPort(const char *name)
151 for (i=0; i<NUM_PORTS; i++) {
152 if (!strcmp(_ports[i]->target, name)) {
157 /* Error - didnt find */
161 static void _buildCmdLine(char *into, char **args, const char **cmds,
162 const char *p1, const char *p2,
163 const char *p3, const char **list)
165 const char *p, *from;
175 /* See if it has a '$' anywhere - if not, just copy */
176 if ((p = strchr(from, '$'))) {
177 strncpy(into, from, p - from);
194 const char **tmp = list;
198 into += strlen(into)+1;
211 if (strlen(into) == 0)
213 into += strlen(into)+1;
218 /*-----------------------------------------------------------------*/
219 /* printVersionInfo - prints the version info */
220 /*-----------------------------------------------------------------*/
221 void printVersionInfo ()
227 for (i=0; i<NUM_PORTS; i++)
228 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
230 fprintf(stderr, " %s `"
244 /*-----------------------------------------------------------------*/
245 /* printUsage - prints command line syntax */
246 /*-----------------------------------------------------------------*/
251 "Usage : [options] filename\n"
253 "\t-m<proc> - Target processor <proc>. Default %s\n"
254 "\t Try --version for supported values of <proc>\n"
255 "\t--model-large - Large Model\n"
256 "\t--model-small - Small Model (default)\n"
257 "\t--stack-auto - Stack automatic variables\n"
258 "\t--xstack - Use external stack\n"
259 "\t--xram-loc <nnnn> - External Ram start location\n"
260 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
261 "\t--code-loc <nnnn> - Code Segment Location\n"
262 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
263 "\t--data-loc <nnnn> - Direct data start location\n"
264 "\t--idata-loc <nnnn> - Indirect data start location\n"
265 "\t--iram-size <nnnn> - Internal Ram size\n"
266 "\t--nojtbound - Don't generate boundary check for jump tables\n"
267 "\t--generic - All unqualified ptrs converted to '_generic'\n"
268 "PreProcessor Options :-\n"
269 "\t-Dmacro - Define Macro\n"
270 "\t-Ipath - Include \"*.h\" path\n"
271 "Note: this is a complete list of options see docs for details\n",
277 /*-----------------------------------------------------------------*/
278 /* parseWithComma - separates string with comma */
279 /*-----------------------------------------------------------------*/
280 void parseWithComma (char **dest,char *src)
285 /* skip the initial white spaces */
286 while (isspace(*src)) src++;
300 /*-----------------------------------------------------------------*/
301 /* setDefaultOptions - sets the default options */
302 /*-----------------------------------------------------------------*/
303 static void setDefaultOptions()
307 for ( i = 0 ; i < 128 ; i++)
308 preArgv[i] = asmOptions [i] =
309 linkOptions[i] = relFiles[i] = libFiles[i] =
312 /* first the options part */
313 options.stack_loc = 0; /* stack pointer initialised to 0 */
314 options.xstack_loc= 0; /* xternal stack starts at 0 */
315 options.code_loc = 0; /* code starts at 0 */
316 options.data_loc = 0x0030; /* data starts at 0x0030 */
317 options.xdata_loc = 0;
318 options.idata_loc = 0x80;
319 options.genericPtr = 1; /* default on */
322 /* now for the optimizations */
323 /* turn on the everything */
324 optimize.global_cse = 1;
329 optimize.loopInvariant = 1;
330 optimize.loopInduction = 1;
332 port->setDefaultOptions();
335 /*-----------------------------------------------------------------*/
336 /* processFile - determines the type of file from the extension */
337 /*-----------------------------------------------------------------*/
338 static void processFile (char *s)
342 /* get the file extension */
343 fext = s + strlen(s);
344 while ((fext != s) && *fext != '.') fext--;
346 /* now if no '.' then we don't know what the file type is
347 so give a warning and return */
349 werror(W_UNKNOWN_FEXT,s);
353 /* otherwise depending on the file type */
354 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
355 /* source file name : not if we already have a
358 werror(W_TOO_MANY_SRC,s);
362 /* the only source file */
363 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
364 werror(E_FILE_OPEN_ERR,s);
368 /* copy the file name into the buffer */
371 /* get rid of the "." */
373 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
374 strcpy(srcFileName,buffer);
376 /* get rid of any path information
377 for the module name; do this by going
378 backwards till we get to either '/' or '\' or ':'
379 or start of buffer */
380 fext = buffer + strlen(buffer);
381 while (fext != buffer &&
382 *(fext -1) != '\\' &&
386 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
387 strcpy(moduleName,fext);
392 /* if the extention is type .rel or .r or .REL or .R
393 addtional object file will be passed to the linker */
394 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
395 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
397 relFiles[nrelFiles++] = s;
401 /* if .lib or .LIB */
402 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
403 libFiles[nlibFiles++] = s;
407 werror(W_UNKNOWN_FEXT,s);
411 static void _processC1Arg(char *s)
414 if (options.out_name) {
415 werror(W_TOO_MANY_SRC,s);
418 options.out_name = strdup(s);
425 static void _addToList(const char **list, const char *str)
427 /* This is the bad way to do things :) */
432 werror(E_OUT_OF_MEM,__FILE__, 0);
438 /*-----------------------------------------------------------------*/
439 /* parseCmdLine - parses the command line and sets the options */
440 /*-----------------------------------------------------------------*/
441 int parseCmdLine ( int argc, char **argv )
446 /* go thru all whole command line */
447 for ( i = 1; i < argc; i++ ) {
452 if (argv[i][0] == '-' && argv[i][1] == '-') {
454 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
459 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
460 options.regExtend = 1;
464 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
465 options.model = MODEL_LARGE;
469 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
470 options.model = MODEL_SMALL;
474 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
475 options.model = MODEL_FLAT24;
479 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
480 options.stackAuto = 1;
484 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
485 options.dump_raw = 1;
489 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
490 options.cyclomatic = 1;
494 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
495 options.dump_gcse = 1;
499 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
500 options.dump_loop = 1;
504 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
505 options.dump_kill = 1;
509 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
510 options.intlong_rent = 1;
514 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
515 options.float_rent = 1;
519 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
520 options.dump_range = 1;
524 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
525 options.dump_pack = 1;
529 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
530 options.dump_rassgn = 1;
534 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
539 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
544 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
545 options.noOverlay = 1;
549 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
550 options.stackOnData = 1;
554 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
559 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
565 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
566 options.dump_rassgn =
572 options.dump_raw = 1;
576 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
581 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
582 options.genericPtr = 1;
586 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
591 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
596 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
601 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
602 options.noregparms = 1;
606 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
607 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
609 &argv[i][1+strlen(OPTION_PEEP_FILE)];
611 options.peep_file = argv[++i];
615 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
616 if (argv[i][1+strlen(OPTION_LIB_PATH)])
617 libPaths[nlibPaths++] =
618 &argv[i][1+strlen(OPTION_PEEP_FILE)];
620 libPaths[nlibPaths++] = argv[++i];
624 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
626 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
628 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
631 (int) floatFromVal(constVal(argv[++i]));
635 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
636 options.useXstack = 1;
640 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
641 options.mainreturn = 1;
645 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
646 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
647 parseWithComma(options.calleeSaves
648 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
650 parseWithComma(options.calleeSaves,argv[++i]);
654 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
656 if (argv[i][1+strlen(OPTION_STACK_LOC)])
658 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
661 (int) floatFromVal(constVal(argv[++i]));
665 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
667 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
669 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
672 (unsigned int) floatFromVal(constVal(argv[++i]));
676 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
678 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
680 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
683 (int) floatFromVal(constVal(argv[++i]));
687 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
693 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
695 if (argv[i][1+strlen(OPTION_DATA_LOC)])
697 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
700 (int) floatFromVal(constVal(argv[++i]));
704 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
706 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
708 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
711 (int) floatFromVal(constVal(argv[++i]));
715 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
717 if (argv[i][1+strlen(OPTION_CODE_LOC)])
719 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
722 (int) floatFromVal(constVal(argv[++i]));
727 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
728 optimize.noJTabBoundary = 1;
732 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
733 optimize.global_cse = 0;
737 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
738 optimize.loopInvariant = 0;
742 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
743 optimize.loopInduction = 0;
747 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
748 optimize.noLoopReverse = 1;
752 if (!port->parseOption(&argc, argv, &i))
754 werror(W_UNKNOWN_OPTION,argv[i]);
762 /* these are undocumented options */
763 /* if preceded by '/' then turn off certain optmizations, used
764 for debugging only these are also the legacy options from
765 version 1.xx will be removed gradually.
766 It may be an absolute filename.
768 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
769 switch (argv[i][1]) {
772 optimize.ptrArithmetic=0;
776 switch (argv[i][2]) {
781 optimize.label4 = 0 ;
799 switch (argv[i][2]) {
801 optimize.loopInvariant = 0;
804 optimize.loopInduction = 0;
811 optimize.global_cse = 0;
818 /* if preceded by '-' then option */
819 if ( *argv[i] == '-' ) {
820 switch (argv[i][1]) {
831 /* Used to select the port */
832 if (_setPort(argv[i] + 2)) {
833 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
838 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
842 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
845 case 'X' : /* use external stack */
846 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
850 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
853 case 'p' : /* stack pointer intial value */
855 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
859 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
863 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
867 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
875 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
880 libPaths[nlibPaths++] = &argv[i][2];
882 libPaths[nlibPaths++] = argv[++i];
887 if (argv[i][2] == 'l') {
889 parseWithComma(linkOptions,&argv[i][3]);
891 parseWithComma(linkOptions,argv[++i]);
893 /* assembler options */
894 if (argv[i][2] == 'a') {
896 parseWithComma((char **)asmOptions,&argv[i][3]);
898 parseWithComma((char **)asmOptions,argv[++i]);
901 werror(W_UNKNOWN_OPTION,argv[i]);
910 #if FEATURE_VERBOSE_EXEC
918 /* preprocessor options */
927 char sOpt = argv[i][1] ;
930 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
937 if ( argv[i][1] == 'Y' )
939 if (argv[i][1] == 'M')
942 sprintf(buffer, "-%c%s", sOpt, rest);
943 _addToList(preArgv, buffer);
948 if (!port->parseOption(&argc, argv, &i))
949 werror(W_UNKNOWN_OPTION,argv[i]);
954 if (!port->parseOption(&argc, argv, &i)) {
955 /* no option must be a filename */
957 _processC1Arg(argv[i]);
959 processFile(argv[i]);
963 /* set up external stack location if not explicitly specified */
964 if ( !options.xstack_loc )
965 options.xstack_loc = options.xdata_loc ;
967 /* if debug option is set the open the cdbFile */
968 if (/* options.debug && */ srcFileName) {
969 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
970 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
971 werror(E_FILE_OPEN_ERR,cdbfnbuf);
973 /* add a module record */
974 fprintf(cdbFile,"M:%s\n",moduleName);
977 port->finaliseOptions();
981 /*-----------------------------------------------------------------*/
982 /* my_system - will call a program with arguments */
983 /*-----------------------------------------------------------------*/
984 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
985 int my_system (const char *cmd, char **cmd_argv)
987 char *dir, *got= NULL; int i= 0;
992 while (!got && try_dir[i])
994 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
995 strcpy(dir, try_dir[i]);
1000 strcat(dir, ".exe");
1002 /* Mung slashes into backslashes to keep WIndoze happy. */
1015 if (access(dir, X_OK) == 0)
1022 #if FEATURE_VERBOSE_EXEC
1024 char **pCmd = cmd_argv;
1026 printf("%s ", *pCmd);
1033 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1035 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1037 perror("Cannot exec process ");
1044 /*-----------------------------------------------------------------*/
1045 /* linkEdit : - calls the linkage editor with options */
1046 /*-----------------------------------------------------------------*/
1047 static void linkEdit (char **envp)
1055 srcFileName = "temp";
1057 /* first we need to create the <filename>.lnk file */
1058 sprintf(buffer,"%s.lnk",srcFileName);
1059 if (!(lnkfile = fopen(buffer,"w"))) {
1060 werror(E_FILE_OPEN_ERR,buffer);
1064 /* now write the options */
1065 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1067 /* if iram size specified */
1068 if (options.iram_size)
1069 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1071 /*if (options.debug) */
1072 fprintf(lnkfile,"-z\n");
1074 #define WRITE_SEG_LOC(N, L) \
1075 segName = strdup(N); \
1076 c = strtok(segName, " \t"); \
1077 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1078 if (segName) { free(segName); }
1080 /* code segment start */
1081 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1083 /* data segment start */
1084 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1087 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1090 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1092 /* bit segment start */
1093 WRITE_SEG_LOC(BIT_NAME, 0);
1095 /* add the extra linker options */
1096 for (i=0; linkOptions[i] ; i++)
1097 fprintf(lnkfile,"%s\n",linkOptions[i]);
1099 /* standard library path */
1100 switch(options.model)
1112 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1116 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1118 /* other library paths if specified */
1119 for (i = 0 ; i < nlibPaths ; i++ )
1120 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1122 /* standard library files */
1123 fprintf (lnkfile,"-l %s\n",STD_LIB);
1124 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1125 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1126 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1128 /* additional libraries if any */
1129 for (i = 0 ; i < nlibFiles; i++)
1130 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1132 /* put in the object files */
1133 if (strcmp(srcFileName,"temp"))
1134 fprintf (lnkfile,"%s ",srcFileName);
1136 for (i = 0 ; i < nrelFiles ; i++ )
1137 fprintf (lnkfile,"%s\n",relFiles[i]);
1139 fprintf (lnkfile,"\n-e\n");
1142 _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1144 /* call the linker */
1145 if (my_system(argv[0], argv)) {
1146 perror("Cannot exec linker");
1150 if (strcmp(srcFileName,"temp") == 0) {
1151 /* rename "temp.cdb" to "firstRelFile.cdb" */
1152 char *f = strtok(strdup(relFiles[0]),".");
1153 f = strcat(f,".cdb");
1154 rename("temp.cdb",f);
1159 /*-----------------------------------------------------------------*/
1160 /* assemble - spawns the assembler with arguments */
1161 /*-----------------------------------------------------------------*/
1162 static void assemble (char **envp)
1164 char *argv[128]; /* assembler arguments */
1166 _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1168 if (my_system(argv[0], argv)) {
1169 perror("Cannot exec assember");
1176 /*-----------------------------------------------------------------*/
1177 /* preProcess - spawns the preprocessor with arguments */
1178 /*-----------------------------------------------------------------*/
1179 static int preProcess (char **envp)
1186 if (!options.c1mode) {
1187 /* if using external stack define the macro */
1188 if ( options.useXstack )
1189 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1191 /* set the macro for stack autos */
1192 if ( options.stackAuto )
1193 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1195 /* set the macro for large model */
1196 switch(options.model)
1199 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1202 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1205 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1208 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1213 /* add port (processor information to processor */
1214 sprintf(procDef,"-DSDCC_%s",port->target);
1215 _addToList(preArgv,procDef);
1218 preOutName = strdup(tmpnam(NULL));
1220 _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1221 preOutName, srcFileName, preArgv);
1223 if (my_system(argv[0], argv)) {
1224 unlink (preOutName);
1225 perror("Cannot exec Preprocessor");
1233 preOutName = fullSrcFileName;
1236 yyin = fopen(preOutName, "r");
1238 perror("Preproc file not found\n");
1245 static void _findPort(int argc, char **argv)
1249 if (!strncmp(*argv, "-m", 2)) {
1250 _setPort(*argv + 2);
1256 /* Use the first in the list */
1262 * initialises and calls the parser
1265 int main ( int argc, char **argv , char **envp)
1267 /* turn all optimizations off by default */
1268 memset(&optimize,0,sizeof(struct optimize));
1270 /*printVersionInfo ();*/
1272 _findPort(argc, argv);
1273 /* Initalise the port. */
1277 setDefaultOptions();
1278 parseCmdLine(argc,argv);
1280 /* if no input then printUsage & exit */
1281 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1301 if (!options.c1mode)
1310 if (!options.cc_only &&
1314 (srcFileName || nrelFiles))
1317 if (yyin && yyin != stdin)
1320 if (preOutName && !options.c1mode) {