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 #if !OPT_DISABLE_MCS51
132 extern PORT mcs51_port;
134 #if !OPT_DISABLE_GBZ80
135 extern PORT gbz80_port;
138 extern PORT z80_port;
141 extern PORT avr_port;
146 static PORT *_ports[] = {
147 #if !OPT_DISABLE_MCS51
150 #if !OPT_DISABLE_GBZ80
161 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
163 /** Sets the port to the one given by the command line option.
164 @param The name minus the option (eg 'mcs51')
165 @return 0 on success.
167 static int _setPort(const char *name)
170 for (i=0; i<NUM_PORTS; i++) {
171 if (!strcmp(_ports[i]->target, name)) {
176 /* Error - didnt find */
177 werror(E_UNKNOWN_TARGET,name);
181 static void _buildCmdLine(char *into, char **args, const char **cmds,
182 const char *p1, const char *p2,
183 const char *p3, const char **list)
185 const char *p, *from;
195 /* See if it has a '$' anywhere - if not, just copy */
196 if ((p = strchr(from, '$'))) {
197 strncpy(into, from, p - from);
214 const char **tmp = list;
218 into += strlen(into)+1;
231 if (strlen(into) == 0)
233 into += strlen(into)+1;
238 /*-----------------------------------------------------------------*/
239 /* printVersionInfo - prints the version info */
240 /*-----------------------------------------------------------------*/
241 void printVersionInfo ()
247 for (i=0; i<NUM_PORTS; i++)
248 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
250 fprintf(stderr, " %s `"
264 /*-----------------------------------------------------------------*/
265 /* printUsage - prints command line syntax */
266 /*-----------------------------------------------------------------*/
271 "Usage : [options] filename\n"
273 "\t-m<proc> - Target processor <proc>. Default %s\n"
274 "\t Try --version for supported values of <proc>\n"
275 "\t--model-large - Large Model\n"
276 "\t--model-small - Small Model (default)\n"
277 "\t--stack-auto - Stack automatic variables\n"
278 "\t--xstack - Use external stack\n"
279 "\t--xram-loc <nnnn> - External Ram start location\n"
280 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
281 "\t--code-loc <nnnn> - Code Segment Location\n"
282 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
283 "\t--data-loc <nnnn> - Direct data start location\n"
284 "\t--idata-loc <nnnn> - Indirect data start location\n"
285 "\t--iram-size <nnnn> - Internal Ram size\n"
286 "\t--nojtbound - Don't generate boundary check for jump tables\n"
287 "\t--generic - All unqualified ptrs converted to '_generic'\n"
288 "PreProcessor Options :-\n"
289 "\t-Dmacro - Define Macro\n"
290 "\t-Ipath - Include \"*.h\" path\n"
291 "Note: this is a complete list of options see docs for details\n",
297 /*-----------------------------------------------------------------*/
298 /* parseWithComma - separates string with comma */
299 /*-----------------------------------------------------------------*/
300 void parseWithComma (char **dest,char *src)
305 /* skip the initial white spaces */
306 while (isspace(*src)) src++;
320 /*-----------------------------------------------------------------*/
321 /* setDefaultOptions - sets the default options */
322 /*-----------------------------------------------------------------*/
323 static void setDefaultOptions()
327 for ( i = 0 ; i < 128 ; i++)
328 preArgv[i] = asmOptions [i] =
329 linkOptions[i] = relFiles[i] = libFiles[i] =
332 /* first the options part */
333 options.stack_loc = 0; /* stack pointer initialised to 0 */
334 options.xstack_loc= 0; /* xternal stack starts at 0 */
335 options.code_loc = 0; /* code starts at 0 */
336 options.data_loc = 0x0030; /* data starts at 0x0030 */
337 options.xdata_loc = 0;
338 options.idata_loc = 0x80;
339 options.genericPtr = 1; /* default on */
342 /* now for the optimizations */
343 /* turn on the everything */
344 optimize.global_cse = 1;
349 optimize.loopInvariant = 1;
350 optimize.loopInduction = 1;
352 port->setDefaultOptions();
355 /*-----------------------------------------------------------------*/
356 /* processFile - determines the type of file from the extension */
357 /*-----------------------------------------------------------------*/
358 static void processFile (char *s)
362 /* get the file extension */
363 fext = s + strlen(s);
364 while ((fext != s) && *fext != '.') fext--;
366 /* now if no '.' then we don't know what the file type is
367 so give a warning and return */
369 werror(W_UNKNOWN_FEXT,s);
373 /* otherwise depending on the file type */
374 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
375 /* source file name : not if we already have a
378 werror(W_TOO_MANY_SRC,s);
382 /* the only source file */
383 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
384 werror(E_FILE_OPEN_ERR,s);
388 /* copy the file name into the buffer */
391 /* get rid of the "." */
393 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
394 strcpy(srcFileName,buffer);
396 /* get rid of any path information
397 for the module name; do this by going
398 backwards till we get to either '/' or '\' or ':'
399 or start of buffer */
400 fext = buffer + strlen(buffer);
401 while (fext != buffer &&
402 *(fext -1) != '\\' &&
406 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
407 strcpy(moduleName,fext);
412 /* if the extention is type .rel or .r or .REL or .R
413 addtional object file will be passed to the linker */
414 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
415 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
417 relFiles[nrelFiles++] = s;
421 /* if .lib or .LIB */
422 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
423 libFiles[nlibFiles++] = s;
427 werror(W_UNKNOWN_FEXT,s);
431 static void _processC1Arg(char *s)
434 if (options.out_name) {
435 werror(W_TOO_MANY_SRC,s);
438 options.out_name = strdup(s);
445 static void _addToList(const char **list, const char *str)
447 /* This is the bad way to do things :) */
452 werror(E_OUT_OF_MEM,__FILE__, 0);
458 /*-----------------------------------------------------------------*/
459 /* parseCmdLine - parses the command line and sets the options */
460 /*-----------------------------------------------------------------*/
461 int parseCmdLine ( int argc, char **argv )
466 /* go thru all whole command line */
467 for ( i = 1; i < argc; i++ ) {
472 if (argv[i][0] == '-' && argv[i][1] == '-') {
474 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
479 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
480 options.regExtend = 1;
484 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
485 options.model = MODEL_LARGE;
489 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
490 options.model = MODEL_SMALL;
494 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
495 options.model = MODEL_FLAT24;
499 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
500 options.stack10bit = 1;
504 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
505 options.stackAuto = 1;
509 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
510 options.dump_raw = 1;
514 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
515 options.cyclomatic = 1;
519 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
520 options.dump_gcse = 1;
524 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
525 options.dump_loop = 1;
529 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
530 options.dump_kill = 1;
534 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
535 options.intlong_rent = 1;
539 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
540 options.float_rent = 1;
544 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
545 options.dump_range = 1;
549 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
550 options.dump_pack = 1;
554 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
555 options.dump_rassgn = 1;
559 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
564 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
569 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
570 options.noOverlay = 1;
574 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
575 options.stackOnData = 1;
579 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
584 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
590 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
591 options.dump_rassgn =
597 options.dump_raw = 1;
601 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
606 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
607 options.genericPtr = 1;
611 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
616 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
621 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
626 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
627 options.noregparms = 1;
631 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
632 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
634 &argv[i][1+strlen(OPTION_PEEP_FILE)];
636 options.peep_file = argv[++i];
640 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
641 if (argv[i][1+strlen(OPTION_LIB_PATH)])
642 libPaths[nlibPaths++] =
643 &argv[i][1+strlen(OPTION_PEEP_FILE)];
645 libPaths[nlibPaths++] = argv[++i];
649 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
651 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
653 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
656 (int) floatFromVal(constVal(argv[++i]));
660 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
661 options.useXstack = 1;
665 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
666 options.mainreturn = 1;
670 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
671 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
672 parseWithComma(options.calleeSaves
673 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
675 parseWithComma(options.calleeSaves,argv[++i]);
679 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
681 if (argv[i][1+strlen(OPTION_STACK_LOC)])
683 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
686 (int) floatFromVal(constVal(argv[++i]));
690 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
692 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
694 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
697 (unsigned int) floatFromVal(constVal(argv[++i]));
701 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
703 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
705 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
708 (int) floatFromVal(constVal(argv[++i]));
712 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
718 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
720 if (argv[i][1+strlen(OPTION_DATA_LOC)])
722 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
725 (int) floatFromVal(constVal(argv[++i]));
729 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
731 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
733 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
736 (int) floatFromVal(constVal(argv[++i]));
740 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
742 if (argv[i][1+strlen(OPTION_CODE_LOC)])
744 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
747 (int) floatFromVal(constVal(argv[++i]));
752 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
753 optimize.noJTabBoundary = 1;
757 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
758 optimize.global_cse = 0;
762 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
763 optimize.loopInvariant = 0;
767 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
768 optimize.loopInduction = 0;
772 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
773 optimize.noLoopReverse = 1;
777 if (!port->parseOption(&argc, argv, &i))
779 werror(W_UNKNOWN_OPTION,argv[i]);
787 /* these are undocumented options */
788 /* if preceded by '/' then turn off certain optmizations, used
789 for debugging only these are also the legacy options from
790 version 1.xx will be removed gradually.
791 It may be an absolute filename.
793 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
794 switch (argv[i][1]) {
797 optimize.ptrArithmetic=0;
801 switch (argv[i][2]) {
806 optimize.label4 = 0 ;
824 switch (argv[i][2]) {
826 optimize.loopInvariant = 0;
829 optimize.loopInduction = 0;
836 optimize.global_cse = 0;
843 /* if preceded by '-' then option */
844 if ( *argv[i] == '-' ) {
845 switch (argv[i][1]) {
856 /* Used to select the port */
857 if (_setPort(argv[i] + 2)) {
858 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
863 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
867 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
870 case 'X' : /* use external stack */
871 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
875 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
878 case 'p' : /* stack pointer intial value */
880 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
884 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
888 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
892 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
900 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
905 libPaths[nlibPaths++] = &argv[i][2];
907 libPaths[nlibPaths++] = argv[++i];
912 if (argv[i][2] == 'l') {
914 parseWithComma(linkOptions,&argv[i][3]);
916 parseWithComma(linkOptions,argv[++i]);
918 /* assembler options */
919 if (argv[i][2] == 'a') {
921 parseWithComma((char **)asmOptions,&argv[i][3]);
923 parseWithComma((char **)asmOptions,argv[++i]);
926 werror(W_UNKNOWN_OPTION,argv[i]);
935 #if FEATURE_VERBOSE_EXEC
943 /* preprocessor options */
952 char sOpt = argv[i][1] ;
955 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
962 if ( argv[i][1] == 'Y' )
964 if (argv[i][1] == 'M')
967 sprintf(buffer, "-%c%s", sOpt, rest);
968 _addToList(preArgv, buffer);
973 if (!port->parseOption(&argc, argv, &i))
974 werror(W_UNKNOWN_OPTION,argv[i]);
979 if (!port->parseOption(&argc, argv, &i)) {
980 /* no option must be a filename */
982 _processC1Arg(argv[i]);
984 processFile(argv[i]);
988 /* set up external stack location if not explicitly specified */
989 if ( !options.xstack_loc )
990 options.xstack_loc = options.xdata_loc ;
992 /* if debug option is set the open the cdbFile */
993 if (/* options.debug && */ srcFileName) {
994 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
995 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
996 werror(E_FILE_OPEN_ERR,cdbfnbuf);
998 /* add a module record */
999 fprintf(cdbFile,"M:%s\n",moduleName);
1005 /*-----------------------------------------------------------------*/
1006 /* my_system - will call a program with arguments */
1007 /*-----------------------------------------------------------------*/
1008 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1009 int my_system (const char *cmd, char **cmd_argv)
1011 char *dir, *got= NULL; int i= 0;
1013 while (!got && try_dir[i])
1015 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1016 strcpy(dir, try_dir[i]);
1021 strcat(dir, ".exe");
1023 /* Mung slashes into backslashes to keep WIndoze happy. */
1039 if (access(dir, X_OK) == 0)
1046 #if FEATURE_VERBOSE_EXEC
1048 char **pCmd = cmd_argv;
1050 printf("%s ", *pCmd);
1057 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1059 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1061 perror("Cannot exec process ");
1068 /*-----------------------------------------------------------------*/
1069 /* linkEdit : - calls the linkage editor with options */
1070 /*-----------------------------------------------------------------*/
1071 static void linkEdit (char **envp)
1079 srcFileName = "temp";
1081 /* first we need to create the <filename>.lnk file */
1082 sprintf(buffer,"%s.lnk",srcFileName);
1083 if (!(lnkfile = fopen(buffer,"w"))) {
1084 werror(E_FILE_OPEN_ERR,buffer);
1088 /* now write the options */
1089 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1091 /* if iram size specified */
1092 if (options.iram_size)
1093 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1095 /*if (options.debug) */
1096 fprintf(lnkfile,"-z\n");
1098 #define WRITE_SEG_LOC(N, L) \
1099 segName = strdup(N); \
1100 c = strtok(segName, " \t"); \
1101 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1102 if (segName) { free(segName); }
1104 /* code segment start */
1105 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1107 /* data segment start */
1108 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1111 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1114 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1116 /* bit segment start */
1117 WRITE_SEG_LOC(BIT_NAME, 0);
1119 /* add the extra linker options */
1120 for (i=0; linkOptions[i] ; i++)
1121 fprintf(lnkfile,"%s\n",linkOptions[i]);
1123 /* standard library path */
1124 switch(options.model)
1136 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1140 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1142 /* other library paths if specified */
1143 for (i = 0 ; i < nlibPaths ; i++ )
1144 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1146 /* standard library files */
1147 fprintf (lnkfile,"-l %s\n",STD_LIB);
1148 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1149 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1150 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1152 /* additional libraries if any */
1153 for (i = 0 ; i < nlibFiles; i++)
1154 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1156 /* put in the object files */
1157 if (strcmp(srcFileName,"temp"))
1158 fprintf (lnkfile,"%s ",srcFileName);
1160 for (i = 0 ; i < nrelFiles ; i++ )
1161 fprintf (lnkfile,"%s\n",relFiles[i]);
1163 fprintf (lnkfile,"\n-e\n");
1166 _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1168 /* call the linker */
1169 if (my_system(argv[0], argv)) {
1170 perror("Cannot exec linker");
1174 if (strcmp(srcFileName,"temp") == 0) {
1175 /* rename "temp.cdb" to "firstRelFile.cdb" */
1176 char *f = strtok(strdup(relFiles[0]),".");
1177 f = strcat(f,".cdb");
1178 rename("temp.cdb",f);
1183 /*-----------------------------------------------------------------*/
1184 /* assemble - spawns the assembler with arguments */
1185 /*-----------------------------------------------------------------*/
1186 static void assemble (char **envp)
1188 char *argv[128]; /* assembler arguments */
1190 _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1192 if (my_system(argv[0], argv)) {
1193 perror("Cannot exec assember");
1200 /*-----------------------------------------------------------------*/
1201 /* preProcess - spawns the preprocessor with arguments */
1202 /*-----------------------------------------------------------------*/
1203 static int preProcess (char **envp)
1210 if (!options.c1mode) {
1211 /* if using external stack define the macro */
1212 if ( options.useXstack )
1213 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1215 /* set the macro for stack autos */
1216 if ( options.stackAuto )
1217 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1219 /* set the macro for stack autos */
1220 if ( options.stack10bit )
1221 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1223 /* set the macro for large model */
1224 switch(options.model)
1227 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1230 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1233 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1236 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1241 /* add port (processor information to processor */
1242 sprintf(procDef,"-DSDCC_%s",port->target);
1243 _addToList(preArgv,procDef);
1246 preOutName = strdup(tmpnam(NULL));
1248 _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1249 preOutName, srcFileName, preArgv);
1251 if (my_system(argv[0], argv)) {
1252 unlink (preOutName);
1253 perror("Cannot exec Preprocessor");
1261 preOutName = fullSrcFileName;
1264 yyin = fopen(preOutName, "r");
1266 perror("Preproc file not found\n");
1273 static void _findPort(int argc, char **argv)
1277 if (!strncmp(*argv, "-m", 2)) {
1278 _setPort(*argv + 2);
1284 /* Use the first in the list */
1290 * initialises and calls the parser
1293 int main ( int argc, char **argv , char **envp)
1295 /* turn all optimizations off by default */
1296 memset(&optimize,0,sizeof(struct optimize));
1298 /*printVersionInfo ();*/
1300 _findPort(argc, argv);
1301 /* Initalise the port. */
1305 setDefaultOptions();
1306 parseCmdLine(argc,argv);
1310 port->finaliseOptions();
1312 /* if no input then printUsage & exit */
1313 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1331 if (!options.c1mode)
1342 if (!options.cc_only &&
1346 (srcFileName || nrelFiles))
1349 if (yyin && yyin != stdin)
1352 if (preOutName && !options.c1mode) {