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 -------------------------------------------------------------------------*/
38 // This is a bit messy because we define link ourself
39 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
44 // No unistd.h in Borland C++
46 extern int access (const char *, int);
53 extern int yyparse ();
55 FILE *srcFile; /* source file */
56 FILE *cdbFile = NULL; /* debugger information output file */
57 char *fullSrcFileName; /* full name for the source file */
58 char *srcFileName; /* source file name with the .c stripped */
59 char *moduleName; /* module name is srcFilename stripped of any path */
60 const char *preArgv[128]; /* pre-processor arguments */
62 struct optimize optimize;
63 struct options options;
64 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
65 short preProcOnly = 0;
67 char *linkOptions[128];
68 const char *asmOptions[128];
75 bool verboseExec = FALSE;
78 // In MSC VC6 default search path for exe's to path for this
80 char DefaultExePath[128];
82 /* Far functions, far data */
83 #define OPTION_LARGE_MODEL "-model-large"
84 /* Far functions, near data */
85 #define OPTION_MEDIUM_MODEL "-model-medium"
86 #define OPTION_SMALL_MODEL "-model-small"
87 #define OPTION_FLAT24_MODEL "-model-flat24"
88 #define OPTION_STACK_AUTO "-stack-auto"
89 #define OPTION_STACK_8BIT "-stack-8bit"
90 #define OPTION_STACK_10BIT "-stack-10bit"
91 #define OPTION_XSTACK "-xstack"
92 #define OPTION_GENERIC "-generic"
93 #define OPTION_NO_GCSE "-nogcse"
94 #define OPTION_NO_LOOP_INV "-noinvariant"
95 #define OPTION_NO_LOOP_IND "-noinduction"
96 #define OPTION_NO_JTBOUND "-nojtbound"
97 #define OPTION_NO_LOOPREV "-noloopreverse"
98 #define OPTION_XREGS "-regextend"
99 #define OPTION_COMP_ONLY "-compile-only"
100 #define OPTION_DUMP_RAW "-dumpraw"
101 #define OPTION_DUMP_GCSE "-dumpgcse"
102 #define OPTION_DUMP_LOOP "-dumploop"
103 #define OPTION_DUMP_KILL "-dumpdeadcode"
104 #define OPTION_DUMP_RANGE "-dumpliverange"
105 #define OPTION_DUMP_PACK "-dumpregpack"
106 #define OPTION_DUMP_RASSGN "-dumpregassign"
107 #define OPTION_DUMP_ALL "-dumpall"
108 #define OPTION_XRAM_LOC "-xram-loc"
109 #define OPTION_IRAM_SIZE "-iram-size"
110 #define OPTION_XSTACK_LOC "-xstack-loc"
111 #define OPTION_CODE_LOC "-code-loc"
112 #define OPTION_STACK_LOC "-stack-loc"
113 #define OPTION_DATA_LOC "-data-loc"
114 #define OPTION_IDATA_LOC "-idata-loc"
115 #define OPTION_PEEP_FILE "-peep-file"
116 #define OPTION_LIB_PATH "-lib-path"
117 #define OPTION_INTLONG_RENT "-int-long-reent"
118 #define OPTION_FLOAT_RENT "-float-reent"
119 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
120 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
121 #define OPTION_CYCLOMATIC "-cyclomatic"
122 #define OPTION_NOOVERLAY "-nooverlay"
123 #define OPTION_MAINRETURN "-main-return"
124 #define OPTION_NOPEEP "-no-peep"
125 #define OPTION_ASMPEEP "-peep-asm"
126 #define OPTION_DEBUG "-debug"
127 #define OPTION_NODEBUG "-nodebug"
128 #define OPTION_VERSION "-version"
129 #define OPTION_STKAFTRDATA "-stack-after-data"
130 #define OPTION_PREPROC_ONLY "-preprocessonly"
131 #define OPTION_C1_MODE "-c1mode"
132 #define OPTION_HELP "-help"
133 #define OPTION_CALLEE_SAVES "-callee-saves"
134 #define OPTION_NOSTDLIB "-nostdlib"
135 #define OPTION_NOSTDINC "-nostdinc"
136 #define OPTION_VERBOSE "-verbose"
137 #define OPTION_LESS_PEDANTIC "-lesspedantic"
139 static const char *_preCmd[] =
141 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
142 "$l", "$1", "$2", NULL
147 static PORT *_ports[] =
149 #if !OPT_DISABLE_MCS51
152 #if !OPT_DISABLE_GBZ80
161 #if !OPT_DISABLE_DS390
167 #if !OPT_DISABLE_I186
170 #if !OPT_DISABLE_TLCS900H
175 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
178 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
180 extern void picglue ();
182 /** Sets the port to the one given by the command line option.
183 @param The name minus the option (eg 'mcs51')
184 @return 0 on success.
187 _setPort (const char *name)
190 for (i = 0; i < NUM_PORTS; i++)
192 if (!strcmp (_ports[i]->target, name))
198 /* Error - didnt find */
199 werror (E_UNKNOWN_TARGET, name);
204 _validatePorts (void)
207 for (i = 0; i < NUM_PORTS; i++)
209 if (_ports[i]->magic != PORT_MAGIC)
211 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
216 /*-----------------------------------------------------------------*/
217 /* printVersionInfo - prints the version info */
218 /*-----------------------------------------------------------------*/
226 for (i = 0; i < NUM_PORTS; i++)
227 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
229 fprintf (stderr, " %s"
230 #ifdef SDCC_SUB_VERSION_STR
231 "/" SDCC_SUB_VERSION_STR
239 #if defined(_MSC_VER)
251 /*-----------------------------------------------------------------*/
252 /* printUsage - prints command line syntax */
253 /*-----------------------------------------------------------------*/
259 "Usage : [options] filename\n"
261 "\t-m<proc> - Target processor <proc>. Default %s\n"
262 "\t Try --version for supported values of <proc>\n"
263 "\t--model-large - Large Model\n"
264 "\t--model-small - Small Model (default)\n"
265 "\t--stack-auto - Stack automatic variables\n"
266 "\t--xstack - Use external stack\n"
267 "\t--xram-loc <nnnn> - External Ram start location\n"
268 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
269 "\t--code-loc <nnnn> - Code Segment Location\n"
270 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
271 "\t--data-loc <nnnn> - Direct data start location\n"
272 "\t--idata-loc <nnnn> - Indirect data start location\n"
273 "\t--iram-size <nnnn> - Internal Ram size\n"
274 "\t--nojtbound - Don't generate boundary check for jump tables\n"
275 "\t--generic - All unqualified ptrs converted to '_generic'\n"
276 "PreProcessor Options :-\n"
277 "\t-Dmacro - Define Macro\n"
278 "\t-Ipath - Include \"*.h\" path\n"
279 "Note: this is NOT a complete list of options see docs for details\n",
285 /*-----------------------------------------------------------------*/
286 /* parseWithComma - separates string with comma */
287 /*-----------------------------------------------------------------*/
289 parseWithComma (char **dest, char *src)
293 strtok (src, "\n \t");
294 /* skip the initial white spaces */
295 while (isspace (*src))
312 /*-----------------------------------------------------------------*/
313 /* setDefaultOptions - sets the default options */
314 /*-----------------------------------------------------------------*/
320 for (i = 0; i < 128; i++)
321 preArgv[i] = asmOptions[i] =
322 linkOptions[i] = relFiles[i] = libFiles[i] =
325 /* first the options part */
326 options.stack_loc = 0; /* stack pointer initialised to 0 */
327 options.xstack_loc = 0; /* xternal stack starts at 0 */
328 options.code_loc = 0; /* code starts at 0 */
329 options.data_loc = 0x0030; /* data starts at 0x0030 */
330 options.xdata_loc = 0;
331 options.idata_loc = 0x80;
332 options.genericPtr = 1; /* default on */
334 options.model = port->general.default_model;
335 options.nostdlib = 0;
336 options.nostdinc = 0;
339 options.stack10bit=0;
341 /* now for the optimizations */
342 /* turn on the everything */
343 optimize.global_cse = 1;
348 optimize.loopInvariant = 1;
349 optimize.loopInduction = 1;
351 /* now for the ports */
352 port->setDefaultOptions ();
355 /*-----------------------------------------------------------------*/
356 /* processFile - determines the type of file from the extension */
357 /*-----------------------------------------------------------------*/
359 processFile (char *s)
363 /* get the file extension */
364 fext = s + strlen (s);
365 while ((fext != s) && *fext != '.')
368 /* now if no '.' then we don't know what the file type is
369 so give a warning and return */
372 werror (W_UNKNOWN_FEXT, s);
376 /* otherwise depending on the file type */
377 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
379 /* source file name : not if we already have a
383 werror (W_TOO_MANY_SRC, s);
387 /* the only source file */
388 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
390 werror (E_FILE_OPEN_ERR, s);
394 /* copy the file name into the buffer */
397 /* get rid of the "." */
398 strtok (buffer, ".");
399 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
400 strcpy (srcFileName, buffer);
402 /* get rid of any path information
403 for the module name; do this by going
404 backwards till we get to either '/' or '\' or ':'
405 or start of buffer */
406 fext = buffer + strlen (buffer);
407 while (fext != buffer &&
408 *(fext - 1) != '\\' &&
409 *(fext - 1) != '/' &&
412 moduleName = Safe_calloc (1, strlen (fext) + 1);
413 strcpy (moduleName, fext);
418 /* if the extention is type .rel or .r or .REL or .R
419 addtional object file will be passed to the linker */
420 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
421 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
422 strcmp (fext, port->linker.rel_ext) == 0)
424 relFiles[nrelFiles++] = s;
428 /* if .lib or .LIB */
429 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
431 libFiles[nlibFiles++] = s;
435 werror (W_UNKNOWN_FEXT, s);
440 _processC1Arg (char *s)
444 if (options.out_name)
446 werror (W_TOO_MANY_SRC, s);
449 options.out_name = strdup (s);
458 _addToList (const char **list, const char *str)
460 /* This is the bad way to do things :) */
463 *list = strdup (str);
466 werror (E_OUT_OF_MEM, __FILE__, 0);
473 _setModel (int model, const char *sz)
475 if (port->general.supported_models & model)
476 options.model = model;
478 werror (W_UNSUPPORTED_MODEL, sz, port->target);
481 /*-----------------------------------------------------------------*/
482 /* parseCmdLine - parses the command line and sets the options */
483 /*-----------------------------------------------------------------*/
485 parseCmdLine (int argc, char **argv)
490 /* go thru all whole command line */
491 for (i = 1; i < argc; i++)
497 if (argv[i][0] == '-' && argv[i][1] == '-')
500 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
506 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
508 options.regExtend = 1;
512 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
514 _setModel (MODEL_LARGE, argv[i]);
518 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
520 _setModel (MODEL_MEDIUM, argv[i]);
524 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
526 _setModel (MODEL_SMALL, argv[i]);
530 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
532 _setModel (MODEL_FLAT24, argv[i]);
536 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
538 options.stack10bit = 1;
542 if (strcmp (&argv[i][1], OPTION_STACK_8BIT) == 0)
544 options.stack10bit = 0;
548 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
550 options.stackAuto = 1;
554 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
556 options.dump_raw = 1;
560 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
562 options.cyclomatic = 1;
566 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
568 options.dump_gcse = 1;
572 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
574 options.dump_loop = 1;
578 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
580 options.dump_kill = 1;
584 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
586 options.intlong_rent = 1;
590 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
592 options.float_rent = 1;
596 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
598 options.dump_range = 1;
602 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
604 options.dump_pack = 1;
608 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
610 options.dump_rassgn = 1;
614 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
620 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
626 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
628 options.noOverlay = 1;
632 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
634 options.stackOnData = 1;
638 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
644 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
651 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
653 options.dump_rassgn =
659 options.dump_raw = 1;
663 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
669 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
671 options.genericPtr = 1;
675 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
681 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
687 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
693 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
699 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
701 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
703 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
705 options.peep_file = argv[++i];
709 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
711 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
712 libPaths[nlibPaths++] =
713 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
715 libPaths[nlibPaths++] = argv[++i];
719 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
722 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
724 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
727 (int) floatFromVal (constVal (argv[++i]));
731 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
733 options.useXstack = 1;
737 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
739 options.mainreturn = 1;
743 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
745 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
746 parseWithComma (options.calleeSaves
747 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
749 parseWithComma (options.calleeSaves, argv[++i]);
753 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
756 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
758 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
761 (int) floatFromVal (constVal (argv[++i]));
765 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
768 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
770 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
773 (unsigned int) floatFromVal (constVal (argv[++i]));
777 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
780 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
782 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
785 (int) floatFromVal (constVal (argv[++i]));
789 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
796 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
799 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
801 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
804 (int) floatFromVal (constVal (argv[++i]));
808 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
811 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
813 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
816 (int) floatFromVal (constVal (argv[++i]));
820 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
823 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
825 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
828 (int) floatFromVal (constVal (argv[++i]));
833 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
835 optimize.noJTabBoundary = 1;
839 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
841 optimize.global_cse = 0;
845 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
847 optimize.loopInvariant = 0;
851 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
853 optimize.loopInduction = 0;
857 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
859 optimize.noLoopReverse = 1;
863 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
865 options.nostdlib = 1;
869 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
871 options.nostdinc = 1;
875 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
881 if (strcmp (argv[i] +1, OPTION_LESS_PEDANTIC) == 0)
883 setErrorLogLevel(ERROR_LEVEL_WARNINGS);
887 if (!port->parseOption (&argc, argv, &i))
889 werror (W_UNKNOWN_OPTION, argv[i]);
898 /* if preceded by '-' then option */
913 /* Used to select the port */
914 _setPort (argv[i] + 2);
918 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
922 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
925 case 'X': /* use external stack */
926 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
930 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
933 case 'p': /* stack pointer intial value */
935 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
939 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
943 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
947 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
955 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
960 libPaths[nlibPaths++] = &argv[i][2];
962 libPaths[nlibPaths++] = argv[++i];
967 if (argv[i][2] == 'l')
970 parseWithComma (linkOptions, &argv[i][3]);
972 parseWithComma (linkOptions, argv[++i]);
976 /* assembler options */
977 if (argv[i][2] == 'a')
980 parseWithComma ((char **) asmOptions, &argv[i][3]);
982 parseWithComma ((char **) asmOptions, argv[++i]);
987 werror (W_UNKNOWN_OPTION, argv[i]);
1000 printVersionInfo ();
1004 /* preprocessor options */
1008 _addToList (preArgv, "-M");
1013 _addToList (preArgv, "-C");
1022 char sOpt = argv[i][1];
1025 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1033 if (argv[i][1] == 'Y')
1036 sprintf (buffer, "-%c%s", sOpt, rest);
1037 _addToList (preArgv, buffer);
1042 if (!port->parseOption (&argc, argv, &i))
1043 werror (W_UNKNOWN_OPTION, argv[i]);
1048 if (!port->parseOption (&argc, argv, &i))
1050 /* no option must be a filename */
1052 _processC1Arg (argv[i]);
1054 processFile (argv[i]);
1058 /* set up external stack location if not explicitly specified */
1059 if (!options.xstack_loc)
1060 options.xstack_loc = options.xdata_loc;
1062 /* if debug option is set the open the cdbFile */
1063 if (!options.nodebug && srcFileName)
1065 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1066 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1067 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1070 /* add a module record */
1071 fprintf (cdbFile, "M:%s\n", moduleName);
1077 /*-----------------------------------------------------------------*/
1078 /* linkEdit : - calls the linkage editor with options */
1079 /*-----------------------------------------------------------------*/
1081 linkEdit (char **envp)
1088 srcFileName = "temp";
1090 /* first we need to create the <filename>.lnk file */
1091 sprintf (buffer, "%s.lnk", srcFileName);
1092 if (!(lnkfile = fopen (buffer, "w")))
1094 werror (E_FILE_OPEN_ERR, buffer);
1098 /* now write the options */
1099 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1101 /* if iram size specified */
1102 if (options.iram_size)
1103 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1105 /*if (options.debug) */
1106 fprintf (lnkfile, "-z\n");
1108 #define WRITE_SEG_LOC(N, L) \
1109 segName = strdup(N); \
1110 c = strtok(segName, " \t"); \
1111 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1112 if (segName) { free(segName); }
1114 /* code segment start */
1115 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1117 /* data segment start */
1118 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1121 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1124 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1126 /* bit segment start */
1127 WRITE_SEG_LOC (BIT_NAME, 0);
1129 /* add the extra linker options */
1130 for (i = 0; linkOptions[i]; i++)
1131 fprintf (lnkfile, "%s\n", linkOptions[i]);
1133 /* other library paths if specified */
1134 for (i = 0; i < nlibPaths; i++)
1135 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1137 /* standard library path */
1138 if (!options.nostdlib)
1140 if (TARGET_IS_DS390)
1146 switch (options.model)
1158 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1163 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1165 /* standard library files */
1166 if (strcmp (port->target, "ds390") == 0)
1168 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1170 fprintf (lnkfile, "-l %s\n", STD_LIB);
1171 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1172 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1173 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1176 /* additional libraries if any */
1177 for (i = 0; i < nlibFiles; i++)
1178 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1180 /* put in the object files */
1181 if (strcmp (srcFileName, "temp"))
1182 fprintf (lnkfile, "%s ", srcFileName);
1184 for (i = 0; i < nrelFiles; i++)
1185 fprintf (lnkfile, "%s\n", relFiles[i]);
1187 fprintf (lnkfile, "\n-e\n");
1190 if (options.verbose)
1191 printf ("sdcc: Calling linker...\n");
1193 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1194 if (my_system (buffer))
1199 if (strcmp (srcFileName, "temp") == 0)
1201 /* rename "temp.cdb" to "firstRelFile.cdb" */
1202 char *f = strtok (strdup (relFiles[0]), ".");
1203 f = strcat (f, ".cdb");
1204 rename ("temp.cdb", f);
1209 /*-----------------------------------------------------------------*/
1210 /* assemble - spawns the assembler with arguments */
1211 /*-----------------------------------------------------------------*/
1213 assemble (char **envp)
1215 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1216 if (my_system (buffer))
1218 /* either system() or the assembler itself has reported an error
1219 perror ("Cannot exec assembler");
1227 /*-----------------------------------------------------------------*/
1228 /* preProcess - spawns the preprocessor with arguments */
1229 /*-----------------------------------------------------------------*/
1231 preProcess (char **envp)
1237 if (!options.c1mode)
1239 /* if using external stack define the macro */
1240 if (options.useXstack)
1241 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1243 /* set the macro for stack autos */
1244 if (options.stackAuto)
1245 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1247 /* set the macro for stack autos */
1248 if (options.stack10bit)
1249 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1251 /* set the macro for large model */
1252 switch (options.model)
1255 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1258 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1261 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1264 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1267 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1270 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1274 /* standard include path */
1275 if (!options.nostdinc) {
1276 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1279 /* add port (processor information to processor */
1280 sprintf (procDef, "-DSDCC_%s", port->target);
1281 _addToList (preArgv, procDef);
1282 sprintf (procDef, "-D__%s", port->target);
1283 _addToList (preArgv, procDef);
1286 preOutName = strdup (tmpnam (NULL));
1288 if (options.verbose)
1289 printf ("sdcc: Calling preprocessor...\n");
1291 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1292 preOutName, srcFileName, preArgv);
1293 if (my_system (buffer))
1295 // @FIX: Dario Vecchio 03-05-2001
1298 unlink (preOutName);
1310 preOutName = fullSrcFileName;
1313 yyin = fopen (preOutName, "r");
1316 perror ("Preproc file not found\n");
1324 _findPort (int argc, char **argv)
1331 if (!strncmp (*argv, "-m", 2))
1333 _setPort (*argv + 2);
1339 /* Use the first in the list */
1345 * initialises and calls the parser
1349 main (int argc, char **argv, char **envp)
1351 /* turn all optimizations off by default */
1352 memset (&optimize, 0, sizeof (struct optimize));
1354 /*printVersionInfo (); */
1357 fprintf (stderr, "Build error: no ports are enabled.\n");
1361 _findPort (argc, argv);
1362 /* Initalise the port. */
1366 // Create a default exe search path from the path to the sdcc command
1370 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1372 strcpy (DefaultExePath, argv[0]);
1373 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1374 ExePathList[0] = DefaultExePath;
1378 setDefaultOptions ();
1379 parseCmdLine (argc, argv);
1383 port->finaliseOptions ();
1385 /* if no input then printUsage & exit */
1386 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1401 if (options.verbose)
1402 printf ("sdcc: Generating code...\n");
1408 if (TARGET_IS_PIC) {
1409 /* TSD PIC port hack - if the PIC port option is enabled
1410 and SDCC is used to generate PIC code, then we will
1411 generate .asm files in gpasm's format instead of SDCC's
1414 #if !OPT_DISABLE_PIC
1423 // @FIX: Dario Vecchio 03-05-2001
1426 if (yyin && yyin != stdin)
1428 unlink (preOutName);
1434 if (!options.c1mode)
1436 if (options.verbose)
1437 printf ("sdcc: Calling assembler...\n");
1443 // @FIX: Dario Vecchio 03-05-2001
1446 if (yyin && yyin != stdin)
1448 unlink (preOutName);
1460 if (!options.cc_only &&
1464 (srcFileName || nrelFiles))
1466 if (port->linker.do_link)
1467 port->linker.do_link ();
1472 if (yyin && yyin != stdin)
1475 if (preOutName && !options.c1mode)
1477 unlink (preOutName);