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_STACK_10BIT "-stack-10bit"
82 #define OPTION_XSTACK "-xstack"
83 #define OPTION_GENERIC "-generic"
84 #define OPTION_NO_GCSE "-nogcse"
85 #define OPTION_NO_LOOP_INV "-noinvariant"
86 #define OPTION_NO_LOOP_IND "-noinduction"
87 #define OPTION_NO_JTBOUND "-nojtbound"
88 #define OPTION_NO_LOOPREV "-noloopreverse"
89 #define OPTION_XREGS "-regextend"
90 #define OPTION_COMP_ONLY "-compile-only"
91 #define OPTION_DUMP_RAW "-dumpraw"
92 #define OPTION_DUMP_GCSE "-dumpgcse"
93 #define OPTION_DUMP_LOOP "-dumploop"
94 #define OPTION_DUMP_KILL "-dumpdeadcode"
95 #define OPTION_DUMP_RANGE "-dumpliverange"
96 #define OPTION_DUMP_PACK "-dumpregpack"
97 #define OPTION_DUMP_RASSGN "-dumpregassign"
98 #define OPTION_DUMP_ALL "-dumpall"
99 #define OPTION_XRAM_LOC "-xram-loc"
100 #define OPTION_IRAM_SIZE "-iram-size"
101 #define OPTION_XSTACK_LOC "-xstack-loc"
102 #define OPTION_CODE_LOC "-code-loc"
103 #define OPTION_STACK_LOC "-stack-loc"
104 #define OPTION_DATA_LOC "-data-loc"
105 #define OPTION_IDATA_LOC "-idata-loc"
106 #define OPTION_PEEP_FILE "-peep-file"
107 #define OPTION_LIB_PATH "-lib-path"
108 #define OPTION_INTLONG_RENT "-int-long-reent"
109 #define OPTION_FLOAT_RENT "-float-reent"
110 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
111 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
112 #define OPTION_CYCLOMATIC "-cyclomatic"
113 #define OPTION_NOOVERLAY "-nooverlay"
114 #define OPTION_MAINRETURN "-main-return"
115 #define OPTION_NOPEEP "-no-peep"
116 #define OPTION_ASMPEEP "-peep-asm"
117 #define OPTION_DEBUG "-debug"
118 #define OPTION_VERSION "-version"
119 #define OPTION_STKAFTRDATA "-stack-after-data"
120 #define OPTION_PREPROC_ONLY "-preprocessonly"
121 #define OPTION_C1_MODE "-c1mode"
122 #define OPTION_HELP "-help"
123 #define OPTION_CALLEE_SAVES "-callee-saves"
124 #define OPTION_NOREGPARMS "-noregparms"
126 static const char *_preCmd[] = {
127 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
128 "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
131 extern PORT mcs51_port;
132 extern PORT z80_port;
133 extern PORT gbz80_port;
134 extern PORT avr_port;
138 static PORT *_ports[] = {
145 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
147 /** Sets the port to the one given by the command line option.
148 @param The name minus the option (eg 'mcs51')
149 @return 0 on success.
151 static int _setPort(const char *name)
154 for (i=0; i<NUM_PORTS; i++) {
155 if (!strcmp(_ports[i]->target, name)) {
160 /* Error - didnt find */
161 werror(E_UNKNOWN_TARGET,name);
165 static void _buildCmdLine(char *into, char **args, const char **cmds,
166 const char *p1, const char *p2,
167 const char *p3, const char **list)
169 const char *p, *from;
179 /* See if it has a '$' anywhere - if not, just copy */
180 if ((p = strchr(from, '$'))) {
181 strncpy(into, from, p - from);
198 const char **tmp = list;
202 into += strlen(into)+1;
215 if (strlen(into) == 0)
217 into += strlen(into)+1;
222 /*-----------------------------------------------------------------*/
223 /* printVersionInfo - prints the version info */
224 /*-----------------------------------------------------------------*/
225 void printVersionInfo ()
231 for (i=0; i<NUM_PORTS; i++)
232 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
234 fprintf(stderr, " %s `"
248 /*-----------------------------------------------------------------*/
249 /* printUsage - prints command line syntax */
250 /*-----------------------------------------------------------------*/
255 "Usage : [options] filename\n"
257 "\t-m<proc> - Target processor <proc>. Default %s\n"
258 "\t Try --version for supported values of <proc>\n"
259 "\t--model-large - Large Model\n"
260 "\t--model-small - Small Model (default)\n"
261 "\t--stack-auto - Stack automatic variables\n"
262 "\t--xstack - Use external stack\n"
263 "\t--xram-loc <nnnn> - External Ram start location\n"
264 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
265 "\t--code-loc <nnnn> - Code Segment Location\n"
266 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
267 "\t--data-loc <nnnn> - Direct data start location\n"
268 "\t--idata-loc <nnnn> - Indirect data start location\n"
269 "\t--iram-size <nnnn> - Internal Ram size\n"
270 "\t--nojtbound - Don't generate boundary check for jump tables\n"
271 "\t--generic - All unqualified ptrs converted to '_generic'\n"
272 "PreProcessor Options :-\n"
273 "\t-Dmacro - Define Macro\n"
274 "\t-Ipath - Include \"*.h\" path\n"
275 "Note: this is a complete list of options see docs for details\n",
281 /*-----------------------------------------------------------------*/
282 /* parseWithComma - separates string with comma */
283 /*-----------------------------------------------------------------*/
284 void parseWithComma (char **dest,char *src)
289 /* skip the initial white spaces */
290 while (isspace(*src)) src++;
304 /*-----------------------------------------------------------------*/
305 /* setDefaultOptions - sets the default options */
306 /*-----------------------------------------------------------------*/
307 static void setDefaultOptions()
311 for ( i = 0 ; i < 128 ; i++)
312 preArgv[i] = asmOptions [i] =
313 linkOptions[i] = relFiles[i] = libFiles[i] =
316 /* first the options part */
317 options.stack_loc = 0; /* stack pointer initialised to 0 */
318 options.xstack_loc= 0; /* xternal stack starts at 0 */
319 options.code_loc = 0; /* code starts at 0 */
320 options.data_loc = 0x0030; /* data starts at 0x0030 */
321 options.xdata_loc = 0;
322 options.idata_loc = 0x80;
323 options.genericPtr = 1; /* default on */
326 /* now for the optimizations */
327 /* turn on the everything */
328 optimize.global_cse = 1;
333 optimize.loopInvariant = 1;
334 optimize.loopInduction = 1;
336 port->setDefaultOptions();
339 /*-----------------------------------------------------------------*/
340 /* processFile - determines the type of file from the extension */
341 /*-----------------------------------------------------------------*/
342 static void processFile (char *s)
346 /* get the file extension */
347 fext = s + strlen(s);
348 while ((fext != s) && *fext != '.') fext--;
350 /* now if no '.' then we don't know what the file type is
351 so give a warning and return */
353 werror(W_UNKNOWN_FEXT,s);
357 /* otherwise depending on the file type */
358 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
359 /* source file name : not if we already have a
362 werror(W_TOO_MANY_SRC,s);
366 /* the only source file */
367 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
368 werror(E_FILE_OPEN_ERR,s);
372 /* copy the file name into the buffer */
375 /* get rid of the "." */
377 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
378 strcpy(srcFileName,buffer);
380 /* get rid of any path information
381 for the module name; do this by going
382 backwards till we get to either '/' or '\' or ':'
383 or start of buffer */
384 fext = buffer + strlen(buffer);
385 while (fext != buffer &&
386 *(fext -1) != '\\' &&
390 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
391 strcpy(moduleName,fext);
396 /* if the extention is type .rel or .r or .REL or .R
397 addtional object file will be passed to the linker */
398 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
399 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
401 relFiles[nrelFiles++] = s;
405 /* if .lib or .LIB */
406 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
407 libFiles[nlibFiles++] = s;
411 werror(W_UNKNOWN_FEXT,s);
415 static void _processC1Arg(char *s)
418 if (options.out_name) {
419 werror(W_TOO_MANY_SRC,s);
422 options.out_name = strdup(s);
429 static void _addToList(const char **list, const char *str)
431 /* This is the bad way to do things :) */
436 werror(E_OUT_OF_MEM,__FILE__, 0);
442 /*-----------------------------------------------------------------*/
443 /* parseCmdLine - parses the command line and sets the options */
444 /*-----------------------------------------------------------------*/
445 int parseCmdLine ( int argc, char **argv )
450 /* go thru all whole command line */
451 for ( i = 1; i < argc; i++ ) {
456 if (argv[i][0] == '-' && argv[i][1] == '-') {
458 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
463 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
464 options.regExtend = 1;
468 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
469 options.model = MODEL_LARGE;
473 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
474 options.model = MODEL_SMALL;
478 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
479 options.model = MODEL_FLAT24;
483 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
484 options.stack10bit = 1;
488 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
489 options.stackAuto = 1;
493 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
494 options.dump_raw = 1;
498 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
499 options.cyclomatic = 1;
503 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
504 options.dump_gcse = 1;
508 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
509 options.dump_loop = 1;
513 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
514 options.dump_kill = 1;
518 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
519 options.intlong_rent = 1;
523 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
524 options.float_rent = 1;
528 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
529 options.dump_range = 1;
533 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
534 options.dump_pack = 1;
538 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
539 options.dump_rassgn = 1;
543 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
548 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
553 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
554 options.noOverlay = 1;
558 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
559 options.stackOnData = 1;
563 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
568 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
574 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
575 options.dump_rassgn =
581 options.dump_raw = 1;
585 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
590 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
591 options.genericPtr = 1;
595 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
600 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
605 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
610 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
611 options.noregparms = 1;
615 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
616 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
618 &argv[i][1+strlen(OPTION_PEEP_FILE)];
620 options.peep_file = argv[++i];
624 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
625 if (argv[i][1+strlen(OPTION_LIB_PATH)])
626 libPaths[nlibPaths++] =
627 &argv[i][1+strlen(OPTION_PEEP_FILE)];
629 libPaths[nlibPaths++] = argv[++i];
633 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
635 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
637 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
640 (int) floatFromVal(constVal(argv[++i]));
644 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
645 options.useXstack = 1;
649 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
650 options.mainreturn = 1;
654 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
655 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
656 parseWithComma(options.calleeSaves
657 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
659 parseWithComma(options.calleeSaves,argv[++i]);
663 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
665 if (argv[i][1+strlen(OPTION_STACK_LOC)])
667 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
670 (int) floatFromVal(constVal(argv[++i]));
674 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
676 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
678 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
681 (unsigned int) floatFromVal(constVal(argv[++i]));
685 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
687 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
689 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
692 (int) floatFromVal(constVal(argv[++i]));
696 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
702 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
704 if (argv[i][1+strlen(OPTION_DATA_LOC)])
706 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
709 (int) floatFromVal(constVal(argv[++i]));
713 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
715 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
717 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
720 (int) floatFromVal(constVal(argv[++i]));
724 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
726 if (argv[i][1+strlen(OPTION_CODE_LOC)])
728 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
731 (int) floatFromVal(constVal(argv[++i]));
736 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
737 optimize.noJTabBoundary = 1;
741 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
742 optimize.global_cse = 0;
746 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
747 optimize.loopInvariant = 0;
751 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
752 optimize.loopInduction = 0;
756 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
757 optimize.noLoopReverse = 1;
761 if (!port->parseOption(&argc, argv, &i))
763 werror(W_UNKNOWN_OPTION,argv[i]);
771 /* these are undocumented options */
772 /* if preceded by '/' then turn off certain optmizations, used
773 for debugging only these are also the legacy options from
774 version 1.xx will be removed gradually.
775 It may be an absolute filename.
777 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
778 switch (argv[i][1]) {
781 optimize.ptrArithmetic=0;
785 switch (argv[i][2]) {
790 optimize.label4 = 0 ;
808 switch (argv[i][2]) {
810 optimize.loopInvariant = 0;
813 optimize.loopInduction = 0;
820 optimize.global_cse = 0;
827 /* if preceded by '-' then option */
828 if ( *argv[i] == '-' ) {
829 switch (argv[i][1]) {
840 /* Used to select the port */
841 if (_setPort(argv[i] + 2)) {
842 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
847 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
851 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
854 case 'X' : /* use external stack */
855 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
859 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
862 case 'p' : /* stack pointer intial value */
864 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
868 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
872 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
876 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
884 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
889 libPaths[nlibPaths++] = &argv[i][2];
891 libPaths[nlibPaths++] = argv[++i];
896 if (argv[i][2] == 'l') {
898 parseWithComma(linkOptions,&argv[i][3]);
900 parseWithComma(linkOptions,argv[++i]);
902 /* assembler options */
903 if (argv[i][2] == 'a') {
905 parseWithComma((char **)asmOptions,&argv[i][3]);
907 parseWithComma((char **)asmOptions,argv[++i]);
910 werror(W_UNKNOWN_OPTION,argv[i]);
919 #if FEATURE_VERBOSE_EXEC
927 /* preprocessor options */
936 char sOpt = argv[i][1] ;
939 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
946 if ( argv[i][1] == 'Y' )
948 if (argv[i][1] == 'M')
951 sprintf(buffer, "-%c%s", sOpt, rest);
952 _addToList(preArgv, buffer);
957 if (!port->parseOption(&argc, argv, &i))
958 werror(W_UNKNOWN_OPTION,argv[i]);
963 if (!port->parseOption(&argc, argv, &i)) {
964 /* no option must be a filename */
966 _processC1Arg(argv[i]);
968 processFile(argv[i]);
972 /* set up external stack location if not explicitly specified */
973 if ( !options.xstack_loc )
974 options.xstack_loc = options.xdata_loc ;
976 /* if debug option is set the open the cdbFile */
977 if (/* options.debug && */ srcFileName) {
978 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
979 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
980 werror(E_FILE_OPEN_ERR,cdbfnbuf);
982 /* add a module record */
983 fprintf(cdbFile,"M:%s\n",moduleName);
989 /*-----------------------------------------------------------------*/
990 /* my_system - will call a program with arguments */
991 /*-----------------------------------------------------------------*/
992 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
993 int my_system (const char *cmd, char **cmd_argv)
995 char *dir, *got= NULL; int i= 0;
997 while (!got && try_dir[i])
999 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1000 strcpy(dir, try_dir[i]);
1005 strcat(dir, ".exe");
1007 /* Mung slashes into backslashes to keep WIndoze happy. */
1023 if (access(dir, X_OK) == 0)
1030 #if FEATURE_VERBOSE_EXEC
1032 char **pCmd = cmd_argv;
1034 printf("%s ", *pCmd);
1041 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1043 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1045 perror("Cannot exec process ");
1052 /*-----------------------------------------------------------------*/
1053 /* linkEdit : - calls the linkage editor with options */
1054 /*-----------------------------------------------------------------*/
1055 static void linkEdit (char **envp)
1063 srcFileName = "temp";
1065 /* first we need to create the <filename>.lnk file */
1066 sprintf(buffer,"%s.lnk",srcFileName);
1067 if (!(lnkfile = fopen(buffer,"w"))) {
1068 werror(E_FILE_OPEN_ERR,buffer);
1072 /* now write the options */
1073 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1075 /* if iram size specified */
1076 if (options.iram_size)
1077 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1079 /*if (options.debug) */
1080 fprintf(lnkfile,"-z\n");
1082 #define WRITE_SEG_LOC(N, L) \
1083 segName = strdup(N); \
1084 c = strtok(segName, " \t"); \
1085 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1086 if (segName) { free(segName); }
1088 /* code segment start */
1089 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1091 /* data segment start */
1092 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1095 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1098 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1100 /* bit segment start */
1101 WRITE_SEG_LOC(BIT_NAME, 0);
1103 /* add the extra linker options */
1104 for (i=0; linkOptions[i] ; i++)
1105 fprintf(lnkfile,"%s\n",linkOptions[i]);
1107 /* standard library path */
1108 switch(options.model)
1120 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1124 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1126 /* other library paths if specified */
1127 for (i = 0 ; i < nlibPaths ; i++ )
1128 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1130 /* standard library files */
1131 fprintf (lnkfile,"-l %s\n",STD_LIB);
1132 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1133 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1134 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1136 /* additional libraries if any */
1137 for (i = 0 ; i < nlibFiles; i++)
1138 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1140 /* put in the object files */
1141 if (strcmp(srcFileName,"temp"))
1142 fprintf (lnkfile,"%s ",srcFileName);
1144 for (i = 0 ; i < nrelFiles ; i++ )
1145 fprintf (lnkfile,"%s\n",relFiles[i]);
1147 fprintf (lnkfile,"\n-e\n");
1150 _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1152 /* call the linker */
1153 if (my_system(argv[0], argv)) {
1154 perror("Cannot exec linker");
1158 if (strcmp(srcFileName,"temp") == 0) {
1159 /* rename "temp.cdb" to "firstRelFile.cdb" */
1160 char *f = strtok(strdup(relFiles[0]),".");
1161 f = strcat(f,".cdb");
1162 rename("temp.cdb",f);
1167 /*-----------------------------------------------------------------*/
1168 /* assemble - spawns the assembler with arguments */
1169 /*-----------------------------------------------------------------*/
1170 static void assemble (char **envp)
1172 char *argv[128]; /* assembler arguments */
1174 _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1176 if (my_system(argv[0], argv)) {
1177 perror("Cannot exec assember");
1184 /*-----------------------------------------------------------------*/
1185 /* preProcess - spawns the preprocessor with arguments */
1186 /*-----------------------------------------------------------------*/
1187 static int preProcess (char **envp)
1194 if (!options.c1mode) {
1195 /* if using external stack define the macro */
1196 if ( options.useXstack )
1197 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1199 /* set the macro for stack autos */
1200 if ( options.stackAuto )
1201 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1203 /* set the macro for stack autos */
1204 if ( options.stack10bit )
1205 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1207 /* set the macro for large model */
1208 switch(options.model)
1211 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1214 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1217 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1220 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1225 /* add port (processor information to processor */
1226 sprintf(procDef,"-DSDCC_%s",port->target);
1227 _addToList(preArgv,procDef);
1230 preOutName = strdup(tmpnam(NULL));
1232 _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1233 preOutName, srcFileName, preArgv);
1235 if (my_system(argv[0], argv)) {
1236 unlink (preOutName);
1237 perror("Cannot exec Preprocessor");
1245 preOutName = fullSrcFileName;
1248 yyin = fopen(preOutName, "r");
1250 perror("Preproc file not found\n");
1257 static void _findPort(int argc, char **argv)
1261 if (!strncmp(*argv, "-m", 2)) {
1262 _setPort(*argv + 2);
1268 /* Use the first in the list */
1274 * initialises and calls the parser
1277 int main ( int argc, char **argv , char **envp)
1279 /* turn all optimizations off by default */
1280 memset(&optimize,0,sizeof(struct optimize));
1282 /*printVersionInfo ();*/
1284 _findPort(argc, argv);
1285 /* Initalise the port. */
1289 setDefaultOptions();
1290 parseCmdLine(argc,argv);
1294 port->finaliseOptions();
1296 /* if no input then printUsage & exit */
1297 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1316 if (!options.c1mode)
1327 if (!options.cc_only &&
1331 (srcFileName || nrelFiles))
1334 if (yyin && yyin != stdin)
1337 if (preOutName && !options.c1mode) {