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 extern ASM_PORT asxxxx_port;
148 extern ASM_PORT rgbds_port;
152 static ASM_PORT *_asm_ports[] = {
157 /** Sets the port to the one given by the command line option.
158 @param The name minus the option (eg 'mcs51')
159 @return 0 on success.
161 static int _setPort(const char *name)
164 for (i=0; i<NUM_PORTS; i++) {
165 if (!strcmp(_ports[i]->target, name)) {
170 /* Error - didnt find */
171 werror(E_UNKNOWN_TARGET,name);
175 static void _buildCmdLine(char *into, char **args, const char **cmds,
176 const char *p1, const char *p2,
177 const char *p3, const char **list)
179 const char *p, *from;
189 /* See if it has a '$' anywhere - if not, just copy */
190 if ((p = strchr(from, '$'))) {
191 strncpy(into, from, p - from);
208 const char **tmp = list;
212 into += strlen(into)+1;
225 if (strlen(into) == 0)
227 into += strlen(into)+1;
232 /*-----------------------------------------------------------------*/
233 /* printVersionInfo - prints the version info */
234 /*-----------------------------------------------------------------*/
235 void printVersionInfo ()
241 for (i=0; i<NUM_PORTS; i++)
242 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
244 fprintf(stderr, " %s `"
258 /*-----------------------------------------------------------------*/
259 /* printUsage - prints command line syntax */
260 /*-----------------------------------------------------------------*/
265 "Usage : [options] filename\n"
267 "\t-m<proc> - Target processor <proc>. Default %s\n"
268 "\t Try --version for supported values of <proc>\n"
269 "\t--model-large - Large Model\n"
270 "\t--model-small - Small Model (default)\n"
271 "\t--stack-auto - Stack automatic variables\n"
272 "\t--xstack - Use external stack\n"
273 "\t--xram-loc <nnnn> - External Ram start location\n"
274 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
275 "\t--code-loc <nnnn> - Code Segment Location\n"
276 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
277 "\t--data-loc <nnnn> - Direct data start location\n"
278 "\t--idata-loc <nnnn> - Indirect data start location\n"
279 "\t--iram-size <nnnn> - Internal Ram size\n"
280 "\t--nojtbound - Don't generate boundary check for jump tables\n"
281 "\t--generic - All unqualified ptrs converted to '_generic'\n"
282 "PreProcessor Options :-\n"
283 "\t-Dmacro - Define Macro\n"
284 "\t-Ipath - Include \"*.h\" path\n"
285 "Note: this is a complete list of options see docs for details\n",
291 /*-----------------------------------------------------------------*/
292 /* parseWithComma - separates string with comma */
293 /*-----------------------------------------------------------------*/
294 void parseWithComma (char **dest,char *src)
299 /* skip the initial white spaces */
300 while (isspace(*src)) src++;
314 /*-----------------------------------------------------------------*/
315 /* setDefaultOptions - sets the default options */
316 /*-----------------------------------------------------------------*/
317 static void setDefaultOptions()
321 for ( i = 0 ; i < 128 ; i++)
322 preArgv[i] = asmOptions [i] =
323 linkOptions[i] = relFiles[i] = libFiles[i] =
326 /* first the options part */
327 options.stack_loc = 0; /* stack pointer initialised to 0 */
328 options.xstack_loc= 0; /* xternal stack starts at 0 */
329 options.code_loc = 0; /* code starts at 0 */
330 options.data_loc = 0x0030; /* data starts at 0x0030 */
331 options.xdata_loc = 0;
332 options.idata_loc = 0x80;
333 options.genericPtr = 1; /* default on */
336 /* now for the optimizations */
337 /* turn on the everything */
338 optimize.global_cse = 1;
343 optimize.loopInvariant = 1;
344 optimize.loopInduction = 1;
346 port->setDefaultOptions();
349 /*-----------------------------------------------------------------*/
350 /* processFile - determines the type of file from the extension */
351 /*-----------------------------------------------------------------*/
352 static void processFile (char *s)
356 /* get the file extension */
357 fext = s + strlen(s);
358 while ((fext != s) && *fext != '.') fext--;
360 /* now if no '.' then we don't know what the file type is
361 so give a warning and return */
363 werror(W_UNKNOWN_FEXT,s);
367 /* otherwise depending on the file type */
368 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
369 /* source file name : not if we already have a
372 werror(W_TOO_MANY_SRC,s);
376 /* the only source file */
377 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
378 werror(E_FILE_OPEN_ERR,s);
382 /* copy the file name into the buffer */
385 /* get rid of the "." */
387 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
388 strcpy(srcFileName,buffer);
390 /* get rid of any path information
391 for the module name; do this by going
392 backwards till we get to either '/' or '\' or ':'
393 or start of buffer */
394 fext = buffer + strlen(buffer);
395 while (fext != buffer &&
396 *(fext -1) != '\\' &&
400 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
401 strcpy(moduleName,fext);
406 /* if the extention is type .rel or .r or .REL or .R
407 addtional object file will be passed to the linker */
408 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
409 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0) {
411 relFiles[nrelFiles++] = s;
415 /* if .lib or .LIB */
416 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
417 libFiles[nlibFiles++] = s;
421 werror(W_UNKNOWN_FEXT,s);
425 static void _processC1Arg(char *s)
428 if (options.out_name) {
429 werror(W_TOO_MANY_SRC,s);
432 options.out_name = strdup(s);
439 static void _addToList(const char **list, const char *str)
441 /* This is the bad way to do things :) */
446 werror(E_OUT_OF_MEM,__FILE__, 0);
452 /*-----------------------------------------------------------------*/
453 /* parseCmdLine - parses the command line and sets the options */
454 /*-----------------------------------------------------------------*/
455 int parseCmdLine ( int argc, char **argv )
460 /* go thru all whole command line */
461 for ( i = 1; i < argc; i++ ) {
466 if (argv[i][0] == '-' && argv[i][1] == '-') {
468 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
473 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
474 options.regExtend = 1;
478 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
479 options.model = MODEL_LARGE;
483 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
484 options.model = MODEL_SMALL;
488 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
489 options.model = MODEL_FLAT24;
493 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
494 options.stack10bit = 1;
498 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
499 options.stackAuto = 1;
503 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
504 options.dump_raw = 1;
508 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
509 options.cyclomatic = 1;
513 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
514 options.dump_gcse = 1;
518 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
519 options.dump_loop = 1;
523 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
524 options.dump_kill = 1;
528 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
529 options.intlong_rent = 1;
533 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
534 options.float_rent = 1;
538 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
539 options.dump_range = 1;
543 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
544 options.dump_pack = 1;
548 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
549 options.dump_rassgn = 1;
553 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
558 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
563 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
564 options.noOverlay = 1;
568 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
569 options.stackOnData = 1;
573 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
578 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
584 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
585 options.dump_rassgn =
591 options.dump_raw = 1;
595 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
600 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
601 options.genericPtr = 1;
605 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
610 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
615 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
620 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
621 options.noregparms = 1;
625 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
626 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
628 &argv[i][1+strlen(OPTION_PEEP_FILE)];
630 options.peep_file = argv[++i];
634 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
635 if (argv[i][1+strlen(OPTION_LIB_PATH)])
636 libPaths[nlibPaths++] =
637 &argv[i][1+strlen(OPTION_PEEP_FILE)];
639 libPaths[nlibPaths++] = argv[++i];
643 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
645 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
647 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
650 (int) floatFromVal(constVal(argv[++i]));
654 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
655 options.useXstack = 1;
659 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
660 options.mainreturn = 1;
664 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
665 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
666 parseWithComma(options.calleeSaves
667 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
669 parseWithComma(options.calleeSaves,argv[++i]);
673 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
675 if (argv[i][1+strlen(OPTION_STACK_LOC)])
677 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
680 (int) floatFromVal(constVal(argv[++i]));
684 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
686 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
688 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
691 (unsigned int) floatFromVal(constVal(argv[++i]));
695 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
697 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
699 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
702 (int) floatFromVal(constVal(argv[++i]));
706 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
712 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
714 if (argv[i][1+strlen(OPTION_DATA_LOC)])
716 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
719 (int) floatFromVal(constVal(argv[++i]));
723 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
725 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
727 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
730 (int) floatFromVal(constVal(argv[++i]));
734 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
736 if (argv[i][1+strlen(OPTION_CODE_LOC)])
738 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
741 (int) floatFromVal(constVal(argv[++i]));
746 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
747 optimize.noJTabBoundary = 1;
751 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
752 optimize.global_cse = 0;
756 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
757 optimize.loopInvariant = 0;
761 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
762 optimize.loopInduction = 0;
766 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
767 optimize.noLoopReverse = 1;
771 if (!port->parseOption(&argc, argv, &i))
773 werror(W_UNKNOWN_OPTION,argv[i]);
781 /* these are undocumented options */
782 /* if preceded by '/' then turn off certain optmizations, used
783 for debugging only these are also the legacy options from
784 version 1.xx will be removed gradually.
785 It may be an absolute filename.
787 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
788 switch (argv[i][1]) {
791 optimize.ptrArithmetic=0;
795 switch (argv[i][2]) {
800 optimize.label4 = 0 ;
818 switch (argv[i][2]) {
820 optimize.loopInvariant = 0;
823 optimize.loopInduction = 0;
830 optimize.global_cse = 0;
837 /* if preceded by '-' then option */
838 if ( *argv[i] == '-' ) {
839 switch (argv[i][1]) {
850 /* Used to select the port */
851 if (_setPort(argv[i] + 2)) {
852 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
857 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
861 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
864 case 'X' : /* use external stack */
865 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
869 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
872 case 'p' : /* stack pointer intial value */
874 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
878 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
882 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
886 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
894 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
899 libPaths[nlibPaths++] = &argv[i][2];
901 libPaths[nlibPaths++] = argv[++i];
906 if (argv[i][2] == 'l') {
908 parseWithComma(linkOptions,&argv[i][3]);
910 parseWithComma(linkOptions,argv[++i]);
912 /* assembler options */
913 if (argv[i][2] == 'a') {
915 parseWithComma((char **)asmOptions,&argv[i][3]);
917 parseWithComma((char **)asmOptions,argv[++i]);
920 werror(W_UNKNOWN_OPTION,argv[i]);
929 #if FEATURE_VERBOSE_EXEC
937 /* preprocessor options */
946 char sOpt = argv[i][1] ;
949 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
956 if ( argv[i][1] == 'Y' )
958 if (argv[i][1] == 'M')
961 sprintf(buffer, "-%c%s", sOpt, rest);
962 _addToList(preArgv, buffer);
967 if (!port->parseOption(&argc, argv, &i))
968 werror(W_UNKNOWN_OPTION,argv[i]);
973 if (!port->parseOption(&argc, argv, &i)) {
974 /* no option must be a filename */
976 _processC1Arg(argv[i]);
978 processFile(argv[i]);
982 /* set up external stack location if not explicitly specified */
983 if ( !options.xstack_loc )
984 options.xstack_loc = options.xdata_loc ;
986 /* if debug option is set the open the cdbFile */
987 if (/* options.debug && */ srcFileName) {
988 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
989 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
990 werror(E_FILE_OPEN_ERR,cdbfnbuf);
992 /* add a module record */
993 fprintf(cdbFile,"M:%s\n",moduleName);
996 port->finaliseOptions();
1000 /*-----------------------------------------------------------------*/
1001 /* my_system - will call a program with arguments */
1002 /*-----------------------------------------------------------------*/
1003 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1004 int my_system (const char *cmd, char **cmd_argv)
1006 char *dir, *got= NULL; int i= 0;
1008 while (!got && try_dir[i])
1010 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1011 strcpy(dir, try_dir[i]);
1016 strcat(dir, ".exe");
1018 /* Mung slashes into backslashes to keep WIndoze happy. */
1034 if (access(dir, X_OK) == 0)
1041 #if FEATURE_VERBOSE_EXEC
1043 char **pCmd = cmd_argv;
1045 printf("%s ", *pCmd);
1052 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1054 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1056 perror("Cannot exec process ");
1063 /*-----------------------------------------------------------------*/
1064 /* linkEdit : - calls the linkage editor with options */
1065 /*-----------------------------------------------------------------*/
1066 static void linkEdit (char **envp)
1074 srcFileName = "temp";
1076 /* first we need to create the <filename>.lnk file */
1077 sprintf(buffer,"%s.lnk",srcFileName);
1078 if (!(lnkfile = fopen(buffer,"w"))) {
1079 werror(E_FILE_OPEN_ERR,buffer);
1083 /* now write the options */
1084 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1086 /* if iram size specified */
1087 if (options.iram_size)
1088 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1090 /*if (options.debug) */
1091 fprintf(lnkfile,"-z\n");
1093 #define WRITE_SEG_LOC(N, L) \
1094 segName = strdup(N); \
1095 c = strtok(segName, " \t"); \
1096 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1097 if (segName) { free(segName); }
1099 /* code segment start */
1100 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1102 /* data segment start */
1103 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1106 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1109 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1111 /* bit segment start */
1112 WRITE_SEG_LOC(BIT_NAME, 0);
1114 /* add the extra linker options */
1115 for (i=0; linkOptions[i] ; i++)
1116 fprintf(lnkfile,"%s\n",linkOptions[i]);
1118 /* standard library path */
1119 switch(options.model)
1131 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1135 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1137 /* other library paths if specified */
1138 for (i = 0 ; i < nlibPaths ; i++ )
1139 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1141 /* standard library files */
1142 fprintf (lnkfile,"-l %s\n",STD_LIB);
1143 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1144 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1145 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1147 /* additional libraries if any */
1148 for (i = 0 ; i < nlibFiles; i++)
1149 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1151 /* put in the object files */
1152 if (strcmp(srcFileName,"temp"))
1153 fprintf (lnkfile,"%s ",srcFileName);
1155 for (i = 0 ; i < nrelFiles ; i++ )
1156 fprintf (lnkfile,"%s\n",relFiles[i]);
1158 fprintf (lnkfile,"\n-e\n");
1161 _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1163 /* call the linker */
1164 if (my_system(argv[0], argv)) {
1165 perror("Cannot exec linker");
1169 if (strcmp(srcFileName,"temp") == 0) {
1170 /* rename "temp.cdb" to "firstRelFile.cdb" */
1171 char *f = strtok(strdup(relFiles[0]),".");
1172 f = strcat(f,".cdb");
1173 rename("temp.cdb",f);
1178 /*-----------------------------------------------------------------*/
1179 /* assemble - spawns the assembler with arguments */
1180 /*-----------------------------------------------------------------*/
1181 static void assemble (char **envp)
1183 char *argv[128]; /* assembler arguments */
1185 _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1187 if (my_system(argv[0], argv)) {
1188 perror("Cannot exec assember");
1195 /*-----------------------------------------------------------------*/
1196 /* preProcess - spawns the preprocessor with arguments */
1197 /*-----------------------------------------------------------------*/
1198 static int preProcess (char **envp)
1205 if (!options.c1mode) {
1206 /* if using external stack define the macro */
1207 if ( options.useXstack )
1208 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1210 /* set the macro for stack autos */
1211 if ( options.stackAuto )
1212 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1214 /* set the macro for stack autos */
1215 if ( options.stack10bit )
1216 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1218 /* set the macro for large model */
1219 switch(options.model)
1222 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1225 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1228 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1231 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1236 /* add port (processor information to processor */
1237 sprintf(procDef,"-DSDCC_%s",port->target);
1238 _addToList(preArgv,procDef);
1241 preOutName = strdup(tmpnam(NULL));
1243 _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1244 preOutName, srcFileName, preArgv);
1246 if (my_system(argv[0], argv)) {
1247 unlink (preOutName);
1248 perror("Cannot exec Preprocessor");
1256 preOutName = fullSrcFileName;
1259 yyin = fopen(preOutName, "r");
1261 perror("Preproc file not found\n");
1268 static void _findPort(int argc, char **argv)
1270 asm_port = _asm_ports[0];
1273 if (!strncmp(*argv, "-m", 2)) {
1274 _setPort(*argv + 2);
1280 /* Use the first in the list */
1286 * initialises and calls the parser
1289 int main ( int argc, char **argv , char **envp)
1291 /* turn all optimizations off by default */
1292 memset(&optimize,0,sizeof(struct optimize));
1294 /*printVersionInfo ();*/
1296 _findPort(argc, argv);
1297 /* Initalise the port. */
1302 setDefaultOptions();
1303 parseCmdLine(argc,argv);
1305 /* if no input then printUsage & exit */
1306 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1325 if (!options.c1mode)
1336 if (!options.cc_only &&
1340 (srcFileName || nrelFiles))
1343 if (yyin && yyin != stdin)
1346 if (preOutName && !options.c1mode) {