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;
137 static PORT *_ports[] = {
143 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
145 /** Sets the port to the one given by the command line option.
146 @param The name minus the option (eg 'mcs51')
147 @return 0 on success.
149 static int _setPort(const char *name)
152 for (i=0; i<NUM_PORTS; i++) {
153 if (!strcmp(_ports[i]->target, name)) {
158 /* Error - didnt find */
162 static void _buildCmdLine(char *into, char **args, const char **cmds,
163 const char *p1, const char *p2,
164 const char *p3, const char **list)
166 const char *p, *from;
176 /* See if it has a '$' anywhere - if not, just copy */
177 if ((p = strchr(from, '$'))) {
178 strncpy(into, from, p - from);
195 const char **tmp = list;
199 into += strlen(into)+1;
212 if (strlen(into) == 0)
214 into += strlen(into)+1;
219 /*-----------------------------------------------------------------*/
220 /* printVersionInfo - prints the version info */
221 /*-----------------------------------------------------------------*/
222 void printVersionInfo ()
228 for (i=0; i<NUM_PORTS; i++)
229 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
231 fprintf(stderr, " %s `"
245 /*-----------------------------------------------------------------*/
246 /* printUsage - prints command line syntax */
247 /*-----------------------------------------------------------------*/
252 "Usage : [options] filename\n"
254 "\t-m<proc> - Target processor <proc>. Default %s\n"
255 "\t Try --version for supported values of <proc>\n"
256 "\t--model-large - Large Model\n"
257 "\t--model-small - Small Model (default)\n"
258 "\t--stack-auto - Stack automatic variables\n"
259 "\t--xstack - Use external stack\n"
260 "\t--xram-loc <nnnn> - External Ram start location\n"
261 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
262 "\t--code-loc <nnnn> - Code Segment Location\n"
263 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
264 "\t--data-loc <nnnn> - Direct data start location\n"
265 "\t--idata-loc <nnnn> - Indirect data start location\n"
266 "\t--iram-size <nnnn> - Internal Ram size\n"
267 "\t--nojtbound - Don't generate boundary check for jump tables\n"
268 "\t--generic - All unqualified ptrs converted to '_generic'\n"
269 "PreProcessor Options :-\n"
270 "\t-Dmacro - Define Macro\n"
271 "\t-Ipath - Include \"*.h\" path\n"
272 "Note: this is a complete list of options see docs for details\n",
278 /*-----------------------------------------------------------------*/
279 /* parseWithComma - separates string with comma */
280 /*-----------------------------------------------------------------*/
281 void parseWithComma (char **dest,char *src)
286 /* skip the initial white spaces */
287 while (isspace(*src)) src++;
301 /*-----------------------------------------------------------------*/
302 /* setDefaultOptions - sets the default options */
303 /*-----------------------------------------------------------------*/
304 static void setDefaultOptions()
308 for ( i = 0 ; i < 128 ; i++)
309 preArgv[i] = asmOptions [i] =
310 linkOptions[i] = relFiles[i] = libFiles[i] =
313 /* first the options part */
314 options.stack_loc = 0; /* stack pointer initialised to 0 */
315 options.xstack_loc= 0; /* xternal stack starts at 0 */
316 options.code_loc = 0; /* code starts at 0 */
317 options.data_loc = 0x0030; /* data starts at 0x0030 */
318 options.xdata_loc = 0;
319 options.idata_loc = 0x80;
320 options.genericPtr = 1; /* default on */
323 /* now for the optimizations */
324 /* turn on the everything */
325 optimize.global_cse = 1;
330 optimize.loopInvariant = 1;
331 optimize.loopInduction = 1;
333 port->setDefaultOptions();
336 /*-----------------------------------------------------------------*/
337 /* processFile - determines the type of file from the extension */
338 /*-----------------------------------------------------------------*/
339 static void processFile (char *s)
343 /* get the file extension */
344 fext = s + strlen(s);
345 while ((fext != s) && *fext != '.') fext--;
347 /* now if no '.' then we don't know what the file type is
348 so give a warning and return */
350 werror(W_UNKNOWN_FEXT,s);
354 /* otherwise depending on the file type */
355 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
356 /* source file name : not if we already have a
359 werror(W_TOO_MANY_SRC,s);
363 /* the only source file */
364 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
365 werror(E_FILE_OPEN_ERR,s);
369 /* copy the file name into the buffer */
372 /* get rid of the "." */
374 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
375 strcpy(srcFileName,buffer);
377 /* get rid of any path information
378 for the module name; do this by going
379 backwards till we get to either '/' or '\' or ':'
380 or start of buffer */
381 fext = buffer + strlen(buffer);
382 while (fext != buffer &&
383 *(fext -1) != '\\' &&
387 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
388 strcpy(moduleName,fext);
393 /* if the extention is type .rel or .r or .REL or .R
394 addtional object file will be passed to the linker */
395 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
396 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
398 relFiles[nrelFiles++] = s;
402 /* if .lib or .LIB */
403 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
404 libFiles[nlibFiles++] = s;
408 werror(W_UNKNOWN_FEXT,s);
412 static void _processC1Arg(char *s)
415 if (options.out_name) {
416 werror(W_TOO_MANY_SRC,s);
419 options.out_name = strdup(s);
426 static void _addToList(const char **list, const char *str)
428 /* This is the bad way to do things :) */
433 werror(E_OUT_OF_MEM,__FILE__, 0);
439 /*-----------------------------------------------------------------*/
440 /* parseCmdLine - parses the command line and sets the options */
441 /*-----------------------------------------------------------------*/
442 int parseCmdLine ( int argc, char **argv )
447 /* go thru all whole command line */
448 for ( i = 1; i < argc; i++ ) {
453 if (argv[i][0] == '-' && argv[i][1] == '-') {
455 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
460 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
461 options.regExtend = 1;
465 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
466 options.model = MODEL_LARGE;
470 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
471 options.model = MODEL_SMALL;
475 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
476 options.model = MODEL_FLAT24;
480 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
481 options.stack10bit = 1;
485 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
486 options.stackAuto = 1;
490 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
491 options.dump_raw = 1;
495 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
496 options.cyclomatic = 1;
500 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
501 options.dump_gcse = 1;
505 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
506 options.dump_loop = 1;
510 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
511 options.dump_kill = 1;
515 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
516 options.intlong_rent = 1;
520 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
521 options.float_rent = 1;
525 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
526 options.dump_range = 1;
530 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
531 options.dump_pack = 1;
535 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
536 options.dump_rassgn = 1;
540 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
545 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
550 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
551 options.noOverlay = 1;
555 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
556 options.stackOnData = 1;
560 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
565 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
571 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
572 options.dump_rassgn =
578 options.dump_raw = 1;
582 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
587 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
588 options.genericPtr = 1;
592 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
597 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
602 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
607 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
608 options.noregparms = 1;
612 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
613 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
615 &argv[i][1+strlen(OPTION_PEEP_FILE)];
617 options.peep_file = argv[++i];
621 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
622 if (argv[i][1+strlen(OPTION_LIB_PATH)])
623 libPaths[nlibPaths++] =
624 &argv[i][1+strlen(OPTION_PEEP_FILE)];
626 libPaths[nlibPaths++] = argv[++i];
630 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
632 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
634 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
637 (int) floatFromVal(constVal(argv[++i]));
641 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
642 options.useXstack = 1;
646 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
647 options.mainreturn = 1;
651 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
652 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
653 parseWithComma(options.calleeSaves
654 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
656 parseWithComma(options.calleeSaves,argv[++i]);
660 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
662 if (argv[i][1+strlen(OPTION_STACK_LOC)])
664 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
667 (int) floatFromVal(constVal(argv[++i]));
671 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
673 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
675 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
678 (unsigned int) floatFromVal(constVal(argv[++i]));
682 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
684 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
686 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
689 (int) floatFromVal(constVal(argv[++i]));
693 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
699 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
701 if (argv[i][1+strlen(OPTION_DATA_LOC)])
703 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
706 (int) floatFromVal(constVal(argv[++i]));
710 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
712 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
714 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
717 (int) floatFromVal(constVal(argv[++i]));
721 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
723 if (argv[i][1+strlen(OPTION_CODE_LOC)])
725 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
728 (int) floatFromVal(constVal(argv[++i]));
733 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
734 optimize.noJTabBoundary = 1;
738 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
739 optimize.global_cse = 0;
743 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
744 optimize.loopInvariant = 0;
748 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
749 optimize.loopInduction = 0;
753 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
754 optimize.noLoopReverse = 1;
758 if (!port->parseOption(&argc, argv, &i))
760 werror(W_UNKNOWN_OPTION,argv[i]);
768 /* these are undocumented options */
769 /* if preceded by '/' then turn off certain optmizations, used
770 for debugging only these are also the legacy options from
771 version 1.xx will be removed gradually.
772 It may be an absolute filename.
774 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
775 switch (argv[i][1]) {
778 optimize.ptrArithmetic=0;
782 switch (argv[i][2]) {
787 optimize.label4 = 0 ;
805 switch (argv[i][2]) {
807 optimize.loopInvariant = 0;
810 optimize.loopInduction = 0;
817 optimize.global_cse = 0;
824 /* if preceded by '-' then option */
825 if ( *argv[i] == '-' ) {
826 switch (argv[i][1]) {
837 /* Used to select the port */
838 if (_setPort(argv[i] + 2)) {
839 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
844 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
848 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
851 case 'X' : /* use external stack */
852 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
856 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
859 case 'p' : /* stack pointer intial value */
861 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
865 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
869 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
873 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
881 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
886 libPaths[nlibPaths++] = &argv[i][2];
888 libPaths[nlibPaths++] = argv[++i];
893 if (argv[i][2] == 'l') {
895 parseWithComma(linkOptions,&argv[i][3]);
897 parseWithComma(linkOptions,argv[++i]);
899 /* assembler options */
900 if (argv[i][2] == 'a') {
902 parseWithComma((char **)asmOptions,&argv[i][3]);
904 parseWithComma((char **)asmOptions,argv[++i]);
907 werror(W_UNKNOWN_OPTION,argv[i]);
916 #if FEATURE_VERBOSE_EXEC
924 /* preprocessor options */
933 char sOpt = argv[i][1] ;
936 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
943 if ( argv[i][1] == 'Y' )
945 if (argv[i][1] == 'M')
948 sprintf(buffer, "-%c%s", sOpt, rest);
949 _addToList(preArgv, buffer);
954 if (!port->parseOption(&argc, argv, &i))
955 werror(W_UNKNOWN_OPTION,argv[i]);
960 if (!port->parseOption(&argc, argv, &i)) {
961 /* no option must be a filename */
963 _processC1Arg(argv[i]);
965 processFile(argv[i]);
969 /* set up external stack location if not explicitly specified */
970 if ( !options.xstack_loc )
971 options.xstack_loc = options.xdata_loc ;
973 /* if debug option is set the open the cdbFile */
974 if (/* options.debug && */ srcFileName) {
975 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
976 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
977 werror(E_FILE_OPEN_ERR,cdbfnbuf);
979 /* add a module record */
980 fprintf(cdbFile,"M:%s\n",moduleName);
983 port->finaliseOptions();
987 /*-----------------------------------------------------------------*/
988 /* my_system - will call a program with arguments */
989 /*-----------------------------------------------------------------*/
990 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
991 int my_system (const char *cmd, char **cmd_argv)
993 char *dir, *got= NULL; int i= 0;
998 while (!got && try_dir[i])
1000 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1001 strcpy(dir, try_dir[i]);
1006 strcat(dir, ".exe");
1008 /* Mung slashes into backslashes to keep WIndoze happy. */
1021 if (access(dir, X_OK) == 0)
1028 #if FEATURE_VERBOSE_EXEC
1030 char **pCmd = cmd_argv;
1032 printf("%s ", *pCmd);
1039 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1041 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1043 perror("Cannot exec process ");
1050 /*-----------------------------------------------------------------*/
1051 /* linkEdit : - calls the linkage editor with options */
1052 /*-----------------------------------------------------------------*/
1053 static void linkEdit (char **envp)
1061 srcFileName = "temp";
1063 /* first we need to create the <filename>.lnk file */
1064 sprintf(buffer,"%s.lnk",srcFileName);
1065 if (!(lnkfile = fopen(buffer,"w"))) {
1066 werror(E_FILE_OPEN_ERR,buffer);
1070 /* now write the options */
1071 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1073 /* if iram size specified */
1074 if (options.iram_size)
1075 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1077 /*if (options.debug) */
1078 fprintf(lnkfile,"-z\n");
1080 #define WRITE_SEG_LOC(N, L) \
1081 segName = strdup(N); \
1082 c = strtok(segName, " \t"); \
1083 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1084 if (segName) { free(segName); }
1086 /* code segment start */
1087 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1089 /* data segment start */
1090 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1093 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1096 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1098 /* bit segment start */
1099 WRITE_SEG_LOC(BIT_NAME, 0);
1101 /* add the extra linker options */
1102 for (i=0; linkOptions[i] ; i++)
1103 fprintf(lnkfile,"%s\n",linkOptions[i]);
1105 /* standard library path */
1106 switch(options.model)
1118 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1122 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1124 /* other library paths if specified */
1125 for (i = 0 ; i < nlibPaths ; i++ )
1126 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1128 /* standard library files */
1129 fprintf (lnkfile,"-l %s\n",STD_LIB);
1130 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1131 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1132 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1134 /* additional libraries if any */
1135 for (i = 0 ; i < nlibFiles; i++)
1136 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1138 /* put in the object files */
1139 if (strcmp(srcFileName,"temp"))
1140 fprintf (lnkfile,"%s ",srcFileName);
1142 for (i = 0 ; i < nrelFiles ; i++ )
1143 fprintf (lnkfile,"%s\n",relFiles[i]);
1145 fprintf (lnkfile,"\n-e\n");
1148 _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1150 /* call the linker */
1151 if (my_system(argv[0], argv)) {
1152 perror("Cannot exec linker");
1156 if (strcmp(srcFileName,"temp") == 0) {
1157 /* rename "temp.cdb" to "firstRelFile.cdb" */
1158 char *f = strtok(strdup(relFiles[0]),".");
1159 f = strcat(f,".cdb");
1160 rename("temp.cdb",f);
1165 /*-----------------------------------------------------------------*/
1166 /* assemble - spawns the assembler with arguments */
1167 /*-----------------------------------------------------------------*/
1168 static void assemble (char **envp)
1170 char *argv[128]; /* assembler arguments */
1172 _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1174 if (my_system(argv[0], argv)) {
1175 perror("Cannot exec assember");
1182 /*-----------------------------------------------------------------*/
1183 /* preProcess - spawns the preprocessor with arguments */
1184 /*-----------------------------------------------------------------*/
1185 static int preProcess (char **envp)
1192 if (!options.c1mode) {
1193 /* if using external stack define the macro */
1194 if ( options.useXstack )
1195 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1197 /* set the macro for stack autos */
1198 if ( options.stackAuto )
1199 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1201 /* set the macro for stack autos */
1202 if ( options.stack10bit )
1203 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1205 /* set the macro for large model */
1206 switch(options.model)
1209 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1212 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1215 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1218 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1223 /* add port (processor information to processor */
1224 sprintf(procDef,"-DSDCC_%s",port->target);
1225 _addToList(preArgv,procDef);
1228 preOutName = strdup(tmpnam(NULL));
1230 _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1231 preOutName, srcFileName, preArgv);
1233 if (my_system(argv[0], argv)) {
1234 unlink (preOutName);
1235 perror("Cannot exec Preprocessor");
1243 preOutName = fullSrcFileName;
1246 yyin = fopen(preOutName, "r");
1248 perror("Preproc file not found\n");
1255 static void _findPort(int argc, char **argv)
1259 if (!strncmp(*argv, "-m", 2)) {
1260 _setPort(*argv + 2);
1266 /* Use the first in the list */
1272 * initialises and calls the parser
1275 int main ( int argc, char **argv , char **envp)
1277 /* turn all optimizations off by default */
1278 memset(&optimize,0,sizeof(struct optimize));
1280 /*printVersionInfo ();*/
1282 _findPort(argc, argv);
1283 /* Initalise the port. */
1288 setDefaultOptions();
1289 parseCmdLine(argc,argv);
1291 /* if no input then printUsage & exit */
1292 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1311 if (!options.c1mode)
1322 if (!options.cc_only &&
1326 (srcFileName || nrelFiles))
1329 if (yyin && yyin != stdin)
1332 if (preOutName && !options.c1mode) {