1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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 -------------------------------------------------------------------------*/
30 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
31 #if 0 /* This should no longer be necessary. */
32 // This is a bit messy because we define link ourself
41 // No unistd.h in Borland C++
44 symbol *interrupts[256];
46 void printIval (symbol *, sym_link *, initList *, FILE *);
47 set *publics = NULL; /* public variables */
48 set *externs = NULL; /* Varibles that are declared as extern */
50 /* TODO: this should be configurable (DS803C90 uses more than 6) */
51 unsigned maxInterrupts = 6;
54 extern char *VersionString;
55 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
56 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
58 /*-----------------------------------------------------------------*/
59 /* closeTmpFiles - closes all tmp files created by the compiler */
60 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
61 /*-----------------------------------------------------------------*/
62 DEFSETFUNC (closeTmpFiles)
72 /*-----------------------------------------------------------------*/
73 /* rmTmpFiles - closes all tmp files created by the compiler */
74 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
75 /*-----------------------------------------------------------------*/
76 DEFSETFUNC (rmTmpFiles)
88 /*-----------------------------------------------------------------*/
89 /* copyFile - copies source file to destination file */
90 /*-----------------------------------------------------------------*/
92 copyFile (FILE * dest, FILE * src)
98 if ((ch = fgetc (src)) != EOF)
103 aopLiteralLong (value * val, int offset, int size)
112 /* if it is a float then it gets tricky */
113 /* otherwise it is fairly simple */
114 if (!IS_FLOAT (val->type)) {
115 unsigned long v = (unsigned long) floatFromVal (val);
120 tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
123 tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
126 /* Hmm. Too big for now. */
129 rs = Safe_calloc (1, strlen (buffer) + 1);
130 return strcpy (rs, buffer);
133 /* PENDING: For now size must be 1 */
136 /* it is type float */
137 fl.f = (float) floatFromVal (val);
139 tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
141 tsprintf (buffer, "!immedbyte", fl.c[offset]);
143 rs = Safe_calloc (1, strlen (buffer) + 1);
144 return strcpy (rs, buffer);
147 /*-----------------------------------------------------------------*/
148 /* aopLiteral - string from a literal value */
149 /*-----------------------------------------------------------------*/
151 aopLiteral (value * val, int offset)
153 return aopLiteralLong (val, offset, 1);
156 /*-----------------------------------------------------------------*/
157 /* emitRegularMap - emit code for maps with no special cases */
158 /*-----------------------------------------------------------------*/
160 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
166 /* PENDING: special case here - should remove */
167 if (!strcmp (map->sname, CODE_NAME))
168 tfprintf (map->oFile, "\t!areacode\n", map->sname);
169 else if (!strcmp (map->sname, DATA_NAME))
170 tfprintf (map->oFile, "\t!areadata\n", map->sname);
171 else if (!strcmp (map->sname, HOME_NAME))
172 tfprintf (map->oFile, "\t!areahome\n", map->sname);
174 tfprintf (map->oFile, "\t!area\n", map->sname);
177 /* print the area name */
178 for (sym = setFirstItem (map->syms); sym;
179 sym = setNextItem (map->syms))
182 /* if extern then add it into the extern list */
183 if (IS_EXTERN (sym->etype))
185 addSetHead (&externs, sym);
189 /* if allocation required check is needed
190 then check if the symbol really requires
191 allocation only for local variables */
192 if (arFlag && !IS_AGGREGATE (sym->type) &&
193 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
194 !sym->allocreq && sym->level)
197 /* if global variable & not static or extern
198 and addPublics allowed then add it to the public set */
199 if ((sym->level == 0 ||
200 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
202 !IS_STATIC (sym->etype) &&
203 (sym->used || sym->fbody))
205 addSetHead (&publics, sym);
208 /* if extern then do nothing or is a function
210 if (IS_FUNC (sym->type))
213 /* print extra debug info if required */
214 if ((options.debug || sym->level == 0) && !options.nodebug)
217 cdbSymbol (sym, cdbFile, FALSE, FALSE);
219 if (!sym->level) /* global */
220 if (IS_STATIC (sym->etype))
221 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
223 fprintf (map->oFile, "G$"); /* scope is global */
225 /* symbol is local */
226 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
227 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
230 /* if is has an absolute address then generate
231 an equate for this no need to allocate space */
232 if (SPEC_ABSA (sym->etype))
234 if ((options.debug || sym->level == 0) && !options.nodebug)
235 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
237 fprintf (map->oFile, "%s\t=\t0x%04x\n",
239 SPEC_ADDR (sym->etype));
244 if ((options.debug || sym->level == 0) && !options.nodebug)
245 fprintf (map->oFile, "==.\n");
246 if (IS_STATIC (sym->etype))
247 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
249 tfprintf (map->oFile, "!labeldef\n", sym->rname);
250 tfprintf (map->oFile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
253 /* if it has an initial value then do it only if
254 it is a global variable */
255 if (sym->ival && sym->level == 0)
259 if (IS_AGGREGATE (sym->type))
260 ival = initAggregates (sym, sym->ival, NULL);
262 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
263 decorateType (resolveSymbols (list2expr (sym->ival))));
264 codeOutFile = statsg->oFile;
266 eBBlockFromiCode (iCodeFromAst (ival));
273 /*-----------------------------------------------------------------*/
274 /* initPointer - pointer initialization code massaging */
275 /*-----------------------------------------------------------------*/
277 initPointer (initList * ilist)
280 ast *expr = list2expr (ilist);
285 /* try it the oldway first */
286 if ((val = constExprValue (expr, FALSE)))
289 /* no then we have to do these cludgy checks */
290 /* pointers can be initialized with address of
291 a variable or address of an array element */
292 if (IS_AST_OP (expr) && expr->opval.op == '&') {
293 /* address of symbol */
294 if (IS_AST_SYM_VALUE (expr->left)) {
295 val = copyValue (AST_VALUE (expr->left));
296 val->type = newLink ();
297 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
298 DCL_TYPE (val->type) = CPOINTER;
299 DCL_PTR_CONST (val->type) = port->mem.code_ro;
301 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
302 DCL_TYPE (val->type) = FPOINTER;
303 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
304 DCL_TYPE (val->type) = PPOINTER;
305 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
306 DCL_TYPE (val->type) = IPOINTER;
307 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
308 DCL_TYPE (val->type) = EEPPOINTER;
310 DCL_TYPE (val->type) = POINTER;
311 val->type->next = expr->left->ftype;
312 val->etype = getSpec (val->type);
316 /* if address of indexed array */
317 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
318 return valForArray (expr->left);
320 /* if address of structure element then
322 if (IS_AST_OP (expr->left) &&
323 expr->left->opval.op == '.') {
324 return valForStructElem (expr->left->left,
329 (&some_struct)->element */
330 if (IS_AST_OP (expr->left) &&
331 expr->left->opval.op == PTR_OP &&
332 IS_ADDRESS_OF_OP (expr->left->left))
333 return valForStructElem (expr->left->left->left,
337 /* case 3. (((char *) &a) +/- constant) */
338 if (IS_AST_OP (expr) &&
339 (expr->opval.op == '+' || expr->opval.op == '-') &&
340 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
341 IS_AST_OP (expr->left->right) &&
342 expr->left->right->opval.op == '&' &&
343 IS_AST_LIT_VALUE (expr->right)) {
345 return valForCastAggr (expr->left->right->left,
346 expr->left->left->opval.lnk,
347 expr->right, expr->opval.op);
351 /* case 4. (char *)(array type) */
352 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
353 IS_ARRAY(expr->right->ftype)) {
355 val = copyValue (AST_VALUE (expr->right));
356 val->type = newLink ();
357 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
358 DCL_TYPE (val->type) = CPOINTER;
359 DCL_PTR_CONST (val->type) = port->mem.code_ro;
361 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
362 DCL_TYPE (val->type) = FPOINTER;
363 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
364 DCL_TYPE (val->type) = PPOINTER;
365 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
366 DCL_TYPE (val->type) = IPOINTER;
367 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
368 DCL_TYPE (val->type) = EEPPOINTER;
370 DCL_TYPE (val->type) = POINTER;
371 val->type->next = expr->right->ftype->next;
372 val->etype = getSpec (val->type);
376 werror (E_INIT_WRONG);
381 /*-----------------------------------------------------------------*/
382 /* printChar - formats and prints a characater string with DB */
383 /*-----------------------------------------------------------------*/
385 printChar (FILE * ofile, char *s, int plen)
388 int len = strlen (s);
393 while (len && pplen < plen)
396 while (i && *s && pplen < plen)
398 if (*s < ' ' || *s == '\"' || *s=='\\')
402 tfprintf (ofile, "\t!ascii\n", buf);
403 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
418 tfprintf (ofile, "\t!ascii\n", buf);
427 tfprintf (ofile, "\t!db !constbyte\n", 0);
430 /*-----------------------------------------------------------------*/
431 /* return the generic pointer high byte for a given pointer type. */
432 /*-----------------------------------------------------------------*/
434 pointerTypeToGPByte (const int p_type)
442 /* hack - if we get a generic pointer, we just assume
443 * it's an FPOINTER (i.e. in XDATA space).
452 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
460 /*-----------------------------------------------------------------*/
461 /* printPointerType - generates ival for pointer type */
462 /*-----------------------------------------------------------------*/
464 _printPointerType (FILE * oFile, const char *name)
468 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
472 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
476 /*-----------------------------------------------------------------*/
477 /* printPointerType - generates ival for pointer type */
478 /*-----------------------------------------------------------------*/
480 printPointerType (FILE * oFile, const char *name)
482 _printPointerType (oFile, name);
483 fprintf (oFile, "\n");
486 /*-----------------------------------------------------------------*/
487 /* printGPointerType - generates ival for generic pointer type */
488 /*-----------------------------------------------------------------*/
490 printGPointerType (FILE * oFile, const char *name,
491 const unsigned int type)
493 _printPointerType (oFile, name);
494 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type));
497 /*-----------------------------------------------------------------*/
498 /* printIvalType - generates ival for int/char */
499 /*-----------------------------------------------------------------*/
501 printIvalType (sym_link * type, initList * ilist, FILE * oFile)
505 /* if initList is deep */
506 if (ilist->type == INIT_DEEP)
507 ilist = ilist->init.deep;
509 val = list2val (ilist);
510 switch (getSize (type)) {
513 tfprintf (oFile, "\t!db !constbyte\n", 0);
515 tfprintf (oFile, "\t!dbs\n",
516 aopLiteral (val, 0));
520 if (port->use_dw_for_init)
521 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
523 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
527 tfprintf (oFile, "\t!dw !constword\n", 0);
528 tfprintf (oFile, "\t!dw !constword\n", 0);
531 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
532 aopLiteral (val, 0), aopLiteral (val, 1),
533 aopLiteral (val, 2), aopLiteral (val, 3));
539 /*-----------------------------------------------------------------*/
540 /* printIvalBitFields - generate initializer for bitfields */
541 /*-----------------------------------------------------------------*/
542 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
546 initList *lilist = *ilist ;
547 unsigned long ival = 0;
553 val = list2val(lilist);
555 if (SPEC_BLEN(lsym->etype) > 8) {
556 size += ((SPEC_BLEN (lsym->etype) / 8) +
557 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
560 size = ((SPEC_BLEN (lsym->etype) / 8) +
561 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
563 i = (unsigned long)floatFromVal(val);
564 i <<= SPEC_BSTR (lsym->etype);
566 if (! ( lsym->next &&
567 (IS_BITFIELD(lsym->next->type)) &&
568 (SPEC_BSTR(lsym->next->etype)))) break;
570 lilist = lilist->next;
574 tfprintf (oFile, "\t!db !constbyte\n",ival);
578 tfprintf (oFile, "\t!dw !constword\n",ival);
581 tfprintf (oFile, "\t!db !constword,!constword\n",
582 (ival >> 8) & 0xffff, (ival & 0xffff));
589 /*-----------------------------------------------------------------*/
590 /* printIvalStruct - generates initial value for structures */
591 /*-----------------------------------------------------------------*/
593 printIvalStruct (symbol * sym, sym_link * type,
594 initList * ilist, FILE * oFile)
599 sflds = SPEC_STRUCT (type)->fields;
600 if (ilist->type != INIT_DEEP) {
601 werror (E_INIT_STRUCT, sym->name);
605 iloop = ilist->init.deep;
607 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
608 if (IS_BITFIELD(sflds->type)) {
609 printIvalBitFields(&sflds,&iloop,oFile);
611 printIval (sflds, sflds->type, iloop, oFile);
617 /*-----------------------------------------------------------------*/
618 /* printIvalChar - generates initital value for character array */
619 /*-----------------------------------------------------------------*/
621 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
629 val = list2val (ilist);
630 /* if the value is a character string */
631 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
633 if (!DCL_ELEM (type))
634 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
636 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
638 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
640 tfprintf (oFile, "\t!db !constbyte\n", 0);
648 printChar (oFile, s, strlen (s) + 1);
652 /*-----------------------------------------------------------------*/
653 /* printIvalArray - generates code for array initialization */
654 /*-----------------------------------------------------------------*/
656 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
660 int lcnt = 0, size = 0;
662 /* take care of the special case */
663 /* array of characters can be init */
665 if (IS_CHAR (type->next))
666 if (printIvalChar (type,
667 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
668 oFile, SPEC_CVAL (sym->etype).v_char))
671 /* not the special case */
672 if (ilist->type != INIT_DEEP)
674 werror (E_INIT_STRUCT, sym->name);
678 iloop = ilist->init.deep;
679 lcnt = DCL_ELEM (type);
684 printIval (sym, type->next, iloop, oFile);
685 iloop = (iloop ? iloop->next : NULL);
688 /* if not array limits given & we */
689 /* are out of initialisers then */
690 if (!DCL_ELEM (type) && !iloop)
693 /* no of elements given and we */
694 /* have generated for all of them */
696 /* if initializers left */
698 werror (W_EXESS_ARRAY_INITIALIZERS, sym->name, sym->lineDef);
704 /* if we have not been given a size */
705 if (!DCL_ELEM (type))
706 DCL_ELEM (type) = size;
711 /*-----------------------------------------------------------------*/
712 /* printIvalFuncPtr - generate initial value for function pointers */
713 /*-----------------------------------------------------------------*/
715 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
720 val = list2val (ilist);
721 /* check the types */
722 if ((dLvl = checkType (val->type, type->next)) <= 0)
724 tfprintf (oFile, "\t!dw !constword\n", 0);
728 /* now generate the name */
731 if (port->use_dw_for_init)
733 tfprintf (oFile, "\t!dws\n", val->name);
737 printPointerType (oFile, val->name);
740 else if (port->use_dw_for_init)
742 tfprintf (oFile, "\t!dws\n", val->sym->rname);
746 printPointerType (oFile, val->sym->rname);
752 /*-----------------------------------------------------------------*/
753 /* printIvalCharPtr - generates initial values for character pointers */
754 /*-----------------------------------------------------------------*/
756 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
760 /* PENDING: this is _very_ mcs51 specific, including a magic
762 It's also endin specific.
764 size = getSize (type);
766 if (val->name && strlen (val->name))
768 if (size == 1) /* This appears to be Z80 specific?? */
771 "\t!dbs\n", val->name);
773 else if (size == FPTRSIZE)
775 if (port->use_dw_for_init)
777 tfprintf (oFile, "\t!dws\n", val->name);
781 printPointerType (oFile, val->name);
784 else if (size == GPTRSIZE)
786 /* PENDING: 0x02 or 0x%02x, CDATA? */
787 printGPointerType (oFile, val->name,
788 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
789 PTR_TYPE (SPEC_OCLS (val->etype))));
793 fprintf (stderr, "*** internal error: unknown size in "
794 "printIvalCharPtr.\n");
799 /* What is this case? Are these pointers? */
803 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
806 if (port->use_dw_for_init)
807 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
809 tfprintf (oFile, "\t.byte %s,%s\n",
810 aopLiteral (val, 0), aopLiteral (val, 1));
813 /* PENDING: 0x02 or 0x%02x, CDATA? */
814 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
815 aopLiteral (val, 0), aopLiteral (val, 1));
822 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
823 addSet (&statsg->syms, val->sym);
829 /*-----------------------------------------------------------------*/
830 /* printIvalPtr - generates initial value for pointers */
831 /*-----------------------------------------------------------------*/
833 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
839 if (ilist->type == INIT_DEEP)
840 ilist = ilist->init.deep;
842 /* function pointer */
843 if (IS_FUNC (type->next))
845 printIvalFuncPtr (type, ilist, oFile);
849 if (!(val = initPointer (ilist)))
852 /* if character pointer */
853 if (IS_CHAR (type->next))
854 if (printIvalCharPtr (sym, type, val, oFile))
858 if (checkType (type, val->type) == 0)
859 werror (E_INIT_WRONG);
861 /* if val is literal */
862 if (IS_LITERAL (val->etype))
864 switch (getSize (type))
867 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
870 if (port->use_dw_for_init)
871 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
873 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
876 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
877 aopLiteral (val, 0), aopLiteral (val, 1));
883 size = getSize (type);
885 if (size == 1) /* Z80 specific?? */
887 tfprintf (oFile, "\t!dbs\n", val->name);
889 else if (size == FPTRSIZE)
891 if (port->use_dw_for_init) {
892 tfprintf (oFile, "\t!dws\n", val->name);
894 printPointerType (oFile, val->name);
897 else if (size == GPTRSIZE)
899 printGPointerType (oFile, val->name,
900 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
901 PTR_TYPE (SPEC_OCLS (val->etype))));
906 /*-----------------------------------------------------------------*/
907 /* printIval - generates code for initial value */
908 /*-----------------------------------------------------------------*/
910 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
915 /* if structure then */
916 if (IS_STRUCT (type))
918 printIvalStruct (sym, type, ilist, oFile);
922 /* if this is a pointer */
925 printIvalPtr (sym, type, ilist, oFile);
929 /* if this is an array */
932 printIvalArray (sym, type, ilist, oFile);
936 /* if type is SPECIFIER */
939 printIvalType (type, ilist, oFile);
944 /*-----------------------------------------------------------------*/
945 /* emitStaticSeg - emitcode for the static segment */
946 /*-----------------------------------------------------------------*/
948 emitStaticSeg (memmap * map, FILE * out)
952 /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
956 /* for all variables in this segment do */
957 for (sym = setFirstItem (map->syms); sym;
958 sym = setNextItem (map->syms))
961 /* if it is "extern" then do nothing */
962 if (IS_EXTERN (sym->etype))
965 /* if it is not static add it to the public
967 if (!IS_STATIC (sym->etype))
968 addSetHead (&publics, sym);
970 /* print extra debug info if required */
971 if ((options.debug || sym->level == 0) && !options.nodebug)
974 cdbSymbol (sym, cdbFile, FALSE, FALSE);
978 if (IS_STATIC (sym->etype))
979 fprintf (out, "F%s$", moduleName); /* scope is file */
981 fprintf (out, "G$"); /* scope is global */
984 /* symbol is local */
985 fprintf (out, "L%s$",
986 (sym->localof ? sym->localof->name : "-null-"));
987 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
990 /* if it has an absolute address */
991 if (SPEC_ABSA (sym->etype))
993 if ((options.debug || sym->level == 0) && !options.nodebug)
994 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
996 fprintf (out, "%s\t=\t0x%04x\n",
998 SPEC_ADDR (sym->etype));
1002 if ((options.debug || sym->level == 0) && !options.nodebug)
1003 fprintf (out, " == .\n");
1005 /* if it has an initial value */
1008 fprintf (out, "%s:\n", sym->rname);
1010 resolveIvalSym (sym->ival);
1011 printIval (sym, sym->type, sym->ival, out);
1016 /* allocate space */
1017 fprintf (out, "%s:\n", sym->rname);
1018 /* special case for character strings */
1019 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1020 SPEC_CVAL (sym->etype).v_char)
1022 SPEC_CVAL (sym->etype).v_char,
1023 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1025 tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1031 /*-----------------------------------------------------------------*/
1032 /* emitMaps - emits the code for the data portion the code */
1033 /*-----------------------------------------------------------------*/
1038 /* no special considerations for the following
1039 data, idata & bit & xdata */
1040 emitRegularMap (data, TRUE, TRUE);
1041 emitRegularMap (idata, TRUE, TRUE);
1042 emitRegularMap (bit, TRUE, FALSE);
1043 emitRegularMap (xdata, TRUE, TRUE);
1044 emitRegularMap (sfr, FALSE, FALSE);
1045 emitRegularMap (sfrbit, FALSE, FALSE);
1046 emitRegularMap (home, TRUE, FALSE);
1047 emitRegularMap (code, TRUE, FALSE);
1049 emitStaticSeg (statsg, code->oFile);
1053 /*-----------------------------------------------------------------*/
1054 /* flushStatics - flush all currently defined statics out to file */
1055 /* and delete. Temporary function */
1056 /*-----------------------------------------------------------------*/
1060 emitStaticSeg (statsg, codeOutFile);
1061 statsg->syms = NULL;
1064 /*-----------------------------------------------------------------*/
1065 /* createInterruptVect - creates the interrupt vector */
1066 /*-----------------------------------------------------------------*/
1068 createInterruptVect (FILE * vFile)
1071 mainf = newSymbol ("main", 0);
1074 /* only if the main function exists */
1075 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1077 if (!options.cc_only)
1082 /* if the main is only a prototype ie. no body then do nothing */
1085 /* if ! compile only then main function should be present */
1086 if (!options.cc_only)
1091 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1092 fprintf (vFile, "__interrupt_vect:\n");
1095 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1097 /* "generic" interrupt table header (if port doesn't specify one).
1099 * Look suspiciously like 8051 code to me...
1102 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1105 /* now for the other interrupts */
1106 for (; i < maxInterrupts; i++)
1109 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1111 fprintf (vFile, "\treti\n\t.ds\t7\n");
1118 ";--------------------------------------------------------\n"
1119 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1123 ";--------------------------------------------------------\n"};
1126 /*-----------------------------------------------------------------*/
1127 /* initialComments - puts in some initial comments */
1128 /*-----------------------------------------------------------------*/
1130 initialComments (FILE * afile)
1134 fprintf (afile, "%s", iComments1);
1135 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1136 fprintf (afile, "%s", iComments2);
1139 /*-----------------------------------------------------------------*/
1140 /* printPublics - generates .global for publics */
1141 /*-----------------------------------------------------------------*/
1143 printPublics (FILE * afile)
1147 fprintf (afile, "%s", iComments2);
1148 fprintf (afile, "; Public variables in this module\n");
1149 fprintf (afile, "%s", iComments2);
1151 for (sym = setFirstItem (publics); sym;
1152 sym = setNextItem (publics))
1153 tfprintf (afile, "\t!global\n", sym->rname);
1156 /*-----------------------------------------------------------------*/
1157 /* printExterns - generates .global for externs */
1158 /*-----------------------------------------------------------------*/
1160 printExterns (FILE * afile)
1164 fprintf (afile, "%s", iComments2);
1165 fprintf (afile, "; Externals used\n");
1166 fprintf (afile, "%s", iComments2);
1168 for (sym = setFirstItem (externs); sym;
1169 sym = setNextItem (externs))
1170 tfprintf (afile, "\t!global\n", sym->rname);
1173 /*-----------------------------------------------------------------*/
1174 /* emitOverlay - will emit code for the overlay stuff */
1175 /*-----------------------------------------------------------------*/
1177 emitOverlay (FILE * afile)
1181 if (!elementsInSet (ovrSetSets))
1182 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1184 /* for each of the sets in the overlay segment do */
1185 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1186 ovrset = setNextItem (ovrSetSets))
1191 if (elementsInSet (ovrset))
1193 /* this dummy area is used to fool the assembler
1194 otherwise the assembler will append each of these
1195 declarations into one chunk and will not overlay
1197 fprintf (afile, "\t.area _DUMMY\n");
1198 /* output the area informtion */
1199 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1202 for (sym = setFirstItem (ovrset); sym;
1203 sym = setNextItem (ovrset))
1206 /* if extern then add it to the publics tabledo nothing */
1207 if (IS_EXTERN (sym->etype))
1210 /* if allocation required check is needed
1211 then check if the symbol really requires
1212 allocation only for local variables */
1213 if (!IS_AGGREGATE (sym->type) &&
1214 !(sym->_isparm && !IS_REGPARM (sym->etype))
1215 && !sym->allocreq && sym->level)
1218 /* if global variable & not static or extern
1219 and addPublics allowed then add it to the public set */
1220 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1221 && !IS_STATIC (sym->etype))
1222 addSetHead (&publics, sym);
1224 /* if extern then do nothing or is a function
1226 if (IS_FUNC (sym->type))
1229 /* print extra debug info if required */
1230 if ((options.debug || sym->level == 0) && !options.nodebug)
1233 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1237 if (IS_STATIC (sym->etype))
1238 fprintf (afile, "F%s$", moduleName); /* scope is file */
1240 fprintf (afile, "G$"); /* scope is global */
1243 /* symbol is local */
1244 fprintf (afile, "L%s$",
1245 (sym->localof ? sym->localof->name : "-null-"));
1246 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1249 /* if is has an absolute address then generate
1250 an equate for this no need to allocate space */
1251 if (SPEC_ABSA (sym->etype))
1254 if ((options.debug || sym->level == 0) && !options.nodebug)
1255 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1257 fprintf (afile, "%s\t=\t0x%04x\n",
1259 SPEC_ADDR (sym->etype));
1263 if ((options.debug || sym->level == 0) && !options.nodebug)
1264 fprintf (afile, "==.\n");
1266 /* allocate space */
1267 tfprintf (afile, "!labeldef\n", sym->rname);
1268 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1275 /*-----------------------------------------------------------------*/
1276 /* glue - the final glue that hold the whole thing together */
1277 /*-----------------------------------------------------------------*/
1283 FILE *ovrFile = tempfile ();
1285 addSetHead (&tmpfileSet, ovrFile);
1286 /* print the global struct definitions */
1287 if (options.debug && !options.nodebug)
1288 cdbStructBlock (0, cdbFile);
1290 vFile = tempfile ();
1291 /* PENDING: this isnt the best place but it will do */
1292 if (port->general.glue_up_main)
1294 /* create the interrupt vector table */
1295 createInterruptVect (vFile);
1298 addSetHead (&tmpfileSet, vFile);
1300 /* emit code for the all the variables declared */
1302 /* do the overlay segments */
1303 emitOverlay (ovrFile);
1305 /* now put it all together into the assembler file */
1306 /* create the assembler file name */
1308 if (!options.c1mode)
1310 sprintf (scratchFileName, srcFileName);
1311 strcat (scratchFileName, port->assembler.file_ext);
1315 strcpy (scratchFileName, options.out_name);
1318 if (!(asmFile = fopen (scratchFileName, "w")))
1320 werror (E_FILE_OPEN_ERR, scratchFileName);
1324 /* initial comments */
1325 initialComments (asmFile);
1327 /* print module name */
1328 tfprintf (asmFile, "\t!module\n", moduleName);
1329 tfprintf (asmFile, "\t!fileprelude\n");
1331 /* Let the port generate any global directives, etc. */
1332 if (port->genAssemblerPreamble)
1334 port->genAssemblerPreamble (asmFile);
1337 /* print the global variables in this module */
1338 printPublics (asmFile);
1339 if (port->assembler.externGlobal)
1340 printExterns (asmFile);
1342 /* copy the sfr segment */
1343 fprintf (asmFile, "%s", iComments2);
1344 fprintf (asmFile, "; special function registers\n");
1345 fprintf (asmFile, "%s", iComments2);
1346 copyFile (asmFile, sfr->oFile);
1348 /* copy the sbit segment */
1349 fprintf (asmFile, "%s", iComments2);
1350 fprintf (asmFile, "; special function bits \n");
1351 fprintf (asmFile, "%s", iComments2);
1352 copyFile (asmFile, sfrbit->oFile);
1354 /* copy the data segment */
1355 fprintf (asmFile, "%s", iComments2);
1356 fprintf (asmFile, "; internal ram data\n");
1357 fprintf (asmFile, "%s", iComments2);
1358 copyFile (asmFile, data->oFile);
1361 /* create the overlay segments */
1362 fprintf (asmFile, "%s", iComments2);
1363 fprintf (asmFile, "; overlayable items in internal ram \n");
1364 fprintf (asmFile, "%s", iComments2);
1365 copyFile (asmFile, ovrFile);
1367 /* create the stack segment MOF */
1368 if (mainf && mainf->fbody)
1370 fprintf (asmFile, "%s", iComments2);
1371 fprintf (asmFile, "; Stack segment in internal ram \n");
1372 fprintf (asmFile, "%s", iComments2);
1373 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1374 "__start__stack:\n\t.ds\t1\n\n");
1377 /* create the idata segment */
1378 fprintf (asmFile, "%s", iComments2);
1379 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1380 fprintf (asmFile, "%s", iComments2);
1381 copyFile (asmFile, idata->oFile);
1383 /* copy the bit segment */
1384 fprintf (asmFile, "%s", iComments2);
1385 fprintf (asmFile, "; bit data\n");
1386 fprintf (asmFile, "%s", iComments2);
1387 copyFile (asmFile, bit->oFile);
1389 /* if external stack then reserve space of it */
1390 if (mainf && mainf->fbody && options.useXstack)
1392 fprintf (asmFile, "%s", iComments2);
1393 fprintf (asmFile, "; external stack \n");
1394 fprintf (asmFile, "%s", iComments2);
1395 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1396 fprintf (asmFile, "\t.ds 256\n");
1400 /* copy xtern ram data */
1401 fprintf (asmFile, "%s", iComments2);
1402 fprintf (asmFile, "; external ram data\n");
1403 fprintf (asmFile, "%s", iComments2);
1404 copyFile (asmFile, xdata->oFile);
1406 /* copy the interrupt vector table */
1407 if (mainf && mainf->fbody)
1409 fprintf (asmFile, "%s", iComments2);
1410 fprintf (asmFile, "; interrupt vector \n");
1411 fprintf (asmFile, "%s", iComments2);
1412 copyFile (asmFile, vFile);
1415 /* copy global & static initialisations */
1416 fprintf (asmFile, "%s", iComments2);
1417 fprintf (asmFile, "; global & static initialisations\n");
1418 fprintf (asmFile, "%s", iComments2);
1420 /* Everywhere we generate a reference to the static_name area,
1421 * (which is currently only here), we immediately follow it with a
1422 * definition of the post_static_name area. This guarantees that
1423 * the post_static_name area will immediately follow the static_name
1426 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1427 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1428 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1430 if (mainf && mainf->fbody)
1432 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1433 /* if external stack is specified then the
1434 higher order byte of the xdatalocation is
1435 going into P2 and the lower order going into
1437 if (options.useXstack)
1439 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1440 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1441 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1442 (unsigned int) options.xdata_loc & 0xff);
1445 /* initialise the stack pointer */
1446 /* if the user specified a value then use it */
1447 if (options.stack_loc)
1448 fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc);
1450 /* no: we have to compute it */
1451 if (!options.stackOnData && maxRegBank <= 3)
1452 fprintf (asmFile, "\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1);
1454 fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */
1456 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1457 fprintf (asmFile, "\tmov\ta,dpl\n");
1458 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1459 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1460 fprintf (asmFile, "__sdcc_init_data:\n");
1463 copyFile (asmFile, statsg->oFile);
1465 if (port->general.glue_up_main && mainf && mainf->fbody)
1467 /* This code is generated in the post-static area.
1468 * This area is guaranteed to follow the static area
1469 * by the ugly shucking and jiving about 20 lines ago.
1471 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1472 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1478 "%s", iComments2, iComments2);
1479 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1480 copyFile (asmFile, home->oFile);
1482 /* copy over code */
1483 fprintf (asmFile, "%s", iComments2);
1484 fprintf (asmFile, "; code\n");
1485 fprintf (asmFile, "%s", iComments2);
1486 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1487 if (mainf && mainf->fbody)
1490 /* entry point @ start of CSEG */
1491 fprintf (asmFile, "__sdcc_program_startup:\n");
1493 /* put in the call to main */
1494 fprintf (asmFile, "\tlcall\t_main\n");
1495 if (options.mainreturn)
1498 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1499 fprintf (asmFile, "\tret\n");
1505 fprintf (asmFile, ";\treturn from main will lock up\n");
1506 fprintf (asmFile, "\tsjmp .\n");
1509 copyFile (asmFile, code->oFile);
1512 applyToSet (tmpfileSet, closeTmpFiles);
1513 applyToSet (tmpfileNameSet, rmTmpFiles);
1516 /** Creates a temporary file a'la tmpfile which avoids the bugs
1517 in cygwin wrt c:\tmp.
1518 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1523 #if !defined(_MSC_VER)
1524 const char *tmpdir = NULL;
1526 tmpdir = getenv ("TMP");
1527 else if (getenv ("TEMP"))
1528 tmpdir = getenv ("TEMP");
1529 else if (getenv ("TMPDIR"))
1530 tmpdir = getenv ("TMPDIR");
1533 char *name = tempnam (tmpdir, "sdcc");
1536 FILE *fp = fopen (name, "w+b");
1539 addSetHead (&tmpfileNameSet, name);
1550 gc_strdup (const char *s)
1553 ret = Safe_calloc (1, strlen (s) + 1);