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)
34 symbol *interrupts[256];
36 void printIval (symbol *, sym_link *, initList *, FILE *);
37 set *publics = NULL; /* public variables */
38 set *externs = NULL; /* Varibles that are declared as extern */
40 /* TODO: this should be configurable (DS803C90 uses more than 6) */
41 unsigned maxInterrupts = 6;
44 extern char *VersionString;
45 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
46 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
48 /*-----------------------------------------------------------------*/
49 /* closeTmpFiles - closes all tmp files created by the compiler */
50 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
51 /*-----------------------------------------------------------------*/
52 DEFSETFUNC (closeTmpFiles)
62 /*-----------------------------------------------------------------*/
63 /* rmTmpFiles - closes all tmp files created by the compiler */
64 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
65 /*-----------------------------------------------------------------*/
66 DEFSETFUNC (rmTmpFiles)
78 /*-----------------------------------------------------------------*/
79 /* copyFile - copies source file to destination file */
80 /*-----------------------------------------------------------------*/
82 copyFile (FILE * dest, FILE * src)
88 if ((ch = fgetc (src)) != EOF)
93 aopLiteralLong (value * val, int offset, int size)
102 /* if it is a float then it gets tricky */
103 /* otherwise it is fairly simple */
104 if (!IS_FLOAT (val->type)) {
105 unsigned long v = (unsigned long) floatFromVal (val);
110 tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
113 tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
116 /* Hmm. Too big for now. */
119 rs = Safe_calloc (1, strlen (buffer) + 1);
120 return strcpy (rs, buffer);
123 /* PENDING: For now size must be 1 */
126 /* it is type float */
127 fl.f = (float) floatFromVal (val);
129 tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
131 tsprintf (buffer, "!immedbyte", fl.c[offset]);
133 rs = Safe_calloc (1, strlen (buffer) + 1);
134 return strcpy (rs, buffer);
137 /*-----------------------------------------------------------------*/
138 /* aopLiteral - string from a literal value */
139 /*-----------------------------------------------------------------*/
141 aopLiteral (value * val, int offset)
143 return aopLiteralLong (val, offset, 1);
146 /*-----------------------------------------------------------------*/
147 /* emitRegularMap - emit code for maps with no special cases */
148 /*-----------------------------------------------------------------*/
150 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
152 symbol *sym, *symIval;
158 /* PENDING: special case here - should remove */
159 if (!strcmp (map->sname, CODE_NAME))
160 tfprintf (map->oFile, "\t!areacode\n", map->sname);
161 else if (!strcmp (map->sname, DATA_NAME))
162 tfprintf (map->oFile, "\t!areadata\n", map->sname);
163 else if (!strcmp (map->sname, HOME_NAME))
164 tfprintf (map->oFile, "\t!areahome\n", map->sname);
166 tfprintf (map->oFile, "\t!area\n", map->sname);
169 /* print the area name */
170 for (sym = setFirstItem (map->syms); sym;
171 sym = setNextItem (map->syms))
174 /* if extern then add it into the extern list */
175 if (IS_EXTERN (sym->etype))
177 addSetHead (&externs, sym);
181 /* if allocation required check is needed
182 then check if the symbol really requires
183 allocation only for local variables */
184 if (arFlag && !IS_AGGREGATE (sym->type) &&
185 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
186 !sym->allocreq && sym->level)
189 /* if global variable & not static or extern
190 and addPublics allowed then add it to the public set */
191 if ((sym->level == 0 ||
192 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
194 !IS_STATIC (sym->etype) &&
195 (IS_FUNC(sym->type) ? (sym->used || sym->fbody) : 1))
197 addSetHead (&publics, sym);
200 /* if extern then do nothing or is a function
202 if (IS_FUNC (sym->type))
205 /* print extra debug info if required */
207 cdbSymbol (sym, cdbFile, FALSE, FALSE);
208 if (!sym->level) /* global */
209 if (IS_STATIC (sym->etype))
210 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
212 fprintf (map->oFile, "G$"); /* scope is global */
214 /* symbol is local */
215 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
216 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
219 /* if is has an absolute address then generate
220 an equate for this no need to allocate space */
221 if (SPEC_ABSA (sym->etype))
224 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
226 fprintf (map->oFile, "%s\t=\t0x%04x\n",
228 SPEC_ADDR (sym->etype));
234 fprintf (map->oFile, "==.\n");
236 if (IS_STATIC (sym->etype))
237 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
239 tfprintf (map->oFile, "!labeldef\n", sym->rname);
240 tfprintf (map->oFile, "\t!ds\n",
241 (unsigned int) getSize (sym->type) & 0xffff);
244 /* if it has an initial value then do it only if
245 it is a global variable */
246 if (sym->ival && sym->level == 0)
248 if (IS_AGGREGATE (sym->type)) {
249 ival = initAggregates (sym, sym->ival, NULL);
251 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
252 decorateType (resolveSymbols (list2expr (sym->ival))));
254 codeOutFile = statsg->oFile;
257 // set ival's lineno to where the symbol was defined
258 if (ival) ival->lineno=sym->lineDef;
260 eBBlockFromiCode (iCodeFromAst (ival));
263 /* if the ival was a symbol, delete it from its segment */
264 if (IS_AST_SYM_VALUE(sym->ival->init.node)) {
265 symIval=AST_SYMBOL(sym->ival->init.node);
266 segment = SPEC_OCLS (symIval->etype);
267 deleteSetItem (&segment->syms, symIval);
274 /*-----------------------------------------------------------------*/
275 /* initPointer - pointer initialization code massaging */
276 /*-----------------------------------------------------------------*/
278 initPointer (initList * ilist)
281 ast *expr = list2expr (ilist);
286 /* try it the oldway first */
287 if ((val = constExprValue (expr, FALSE)))
290 /* no then we have to do these cludgy checks */
291 /* pointers can be initialized with address of
292 a variable or address of an array element */
293 if (IS_AST_OP (expr) && expr->opval.op == '&') {
294 /* address of symbol */
295 if (IS_AST_SYM_VALUE (expr->left)) {
296 val = copyValue (AST_VALUE (expr->left));
297 val->type = newLink ();
298 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
299 DCL_TYPE (val->type) = CPOINTER;
300 DCL_PTR_CONST (val->type) = port->mem.code_ro;
302 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
303 DCL_TYPE (val->type) = FPOINTER;
304 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
305 DCL_TYPE (val->type) = PPOINTER;
306 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
307 DCL_TYPE (val->type) = IPOINTER;
308 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
309 DCL_TYPE (val->type) = EEPPOINTER;
311 DCL_TYPE (val->type) = POINTER;
312 val->type->next = expr->left->ftype;
313 val->etype = getSpec (val->type);
317 /* if address of indexed array */
318 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
319 return valForArray (expr->left);
321 /* if address of structure element then
323 if (IS_AST_OP (expr->left) &&
324 expr->left->opval.op == '.') {
325 return valForStructElem (expr->left->left,
330 (&some_struct)->element */
331 if (IS_AST_OP (expr->left) &&
332 expr->left->opval.op == PTR_OP &&
333 IS_ADDRESS_OF_OP (expr->left->left))
334 return valForStructElem (expr->left->left->left,
338 /* case 3. (((char *) &a) +/- constant) */
339 if (IS_AST_OP (expr) &&
340 (expr->opval.op == '+' || expr->opval.op == '-') &&
341 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
342 IS_AST_OP (expr->left->right) &&
343 expr->left->right->opval.op == '&' &&
344 IS_AST_LIT_VALUE (expr->right)) {
346 return valForCastAggr (expr->left->right->left,
347 expr->left->left->opval.lnk,
348 expr->right, expr->opval.op);
352 /* case 4. (char *)(array type) */
353 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
354 IS_ARRAY(expr->right->ftype)) {
356 val = copyValue (AST_VALUE (expr->right));
357 val->type = newLink ();
358 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
359 DCL_TYPE (val->type) = CPOINTER;
360 DCL_PTR_CONST (val->type) = port->mem.code_ro;
362 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
363 DCL_TYPE (val->type) = FPOINTER;
364 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
365 DCL_TYPE (val->type) = PPOINTER;
366 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
367 DCL_TYPE (val->type) = IPOINTER;
368 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
369 DCL_TYPE (val->type) = EEPPOINTER;
371 DCL_TYPE (val->type) = POINTER;
372 val->type->next = expr->right->ftype->next;
373 val->etype = getSpec (val->type);
377 werror (E_INIT_WRONG);
382 /*-----------------------------------------------------------------*/
383 /* printChar - formats and prints a characater string with DB */
384 /*-----------------------------------------------------------------*/
386 printChar (FILE * ofile, char *s, int plen)
389 int len = strlen (s);
394 while (len && pplen < plen)
397 while (i && *s && pplen < plen)
399 if (*s < ' ' || *s == '\"' || *s=='\\')
403 tfprintf (ofile, "\t!ascii\n", buf);
404 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
419 tfprintf (ofile, "\t!ascii\n", buf);
428 tfprintf (ofile, "\t!db !constbyte\n", 0);
431 /*-----------------------------------------------------------------*/
432 /* return the generic pointer high byte for a given pointer type. */
433 /*-----------------------------------------------------------------*/
435 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
443 /* hack - if we get a generic pointer, we just assume
444 * it's an FPOINTER (i.e. in XDATA space).
446 werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname);
456 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
464 /*-----------------------------------------------------------------*/
465 /* printPointerType - generates ival for pointer type */
466 /*-----------------------------------------------------------------*/
468 _printPointerType (FILE * oFile, const char *name)
470 /* if (TARGET_IS_DS390) */
471 if (options.model == MODEL_FLAT24)
473 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
477 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
481 /*-----------------------------------------------------------------*/
482 /* printPointerType - generates ival for pointer type */
483 /*-----------------------------------------------------------------*/
485 printPointerType (FILE * oFile, const char *name)
487 _printPointerType (oFile, name);
488 fprintf (oFile, "\n");
491 /*-----------------------------------------------------------------*/
492 /* printGPointerType - generates ival for generic pointer type */
493 /*-----------------------------------------------------------------*/
495 printGPointerType (FILE * oFile, const char *iname, const char *oname,
496 const unsigned int type)
498 _printPointerType (oFile, iname);
499 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
502 /*-----------------------------------------------------------------*/
503 /* printIvalType - generates ival for int/char */
504 /*-----------------------------------------------------------------*/
506 printIvalType (sym_link * type, initList * ilist, FILE * oFile)
510 /* if initList is deep */
511 if (ilist->type == INIT_DEEP)
512 ilist = ilist->init.deep;
514 val = list2val (ilist);
515 switch (getSize (type)) {
518 tfprintf (oFile, "\t!db !constbyte\n", 0);
520 tfprintf (oFile, "\t!dbs\n",
521 aopLiteral (val, 0));
525 if (port->use_dw_for_init)
526 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
528 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
532 tfprintf (oFile, "\t!dw !constword\n", 0);
533 tfprintf (oFile, "\t!dw !constword\n", 0);
536 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
537 aopLiteral (val, 0), aopLiteral (val, 1),
538 aopLiteral (val, 2), aopLiteral (val, 3));
544 /*-----------------------------------------------------------------*/
545 /* printIvalBitFields - generate initializer for bitfields */
546 /*-----------------------------------------------------------------*/
547 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
551 initList *lilist = *ilist ;
552 unsigned long ival = 0;
558 val = list2val(lilist);
560 if (SPEC_BLEN(lsym->etype) > 8) {
561 size += ((SPEC_BLEN (lsym->etype) / 8) +
562 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
565 size = ((SPEC_BLEN (lsym->etype) / 8) +
566 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
568 i = (unsigned long)floatFromVal(val);
569 i <<= SPEC_BSTR (lsym->etype);
571 if (! ( lsym->next &&
572 (IS_BITFIELD(lsym->next->type)) &&
573 (SPEC_BSTR(lsym->next->etype)))) break;
575 lilist = lilist->next;
579 tfprintf (oFile, "\t!db !constbyte\n",ival);
583 tfprintf (oFile, "\t!dw !constword\n",ival);
586 tfprintf (oFile, "\t!db !constword,!constword\n",
587 (ival >> 8) & 0xffff, (ival & 0xffff));
594 /*-----------------------------------------------------------------*/
595 /* printIvalStruct - generates initial value for structures */
596 /*-----------------------------------------------------------------*/
598 printIvalStruct (symbol * sym, sym_link * type,
599 initList * ilist, FILE * oFile)
604 sflds = SPEC_STRUCT (type)->fields;
605 if (ilist->type != INIT_DEEP) {
606 werror (E_INIT_STRUCT, sym->name);
610 iloop = ilist->init.deep;
612 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
613 if (IS_BITFIELD(sflds->type)) {
614 printIvalBitFields(&sflds,&iloop,oFile);
616 printIval (sflds, sflds->type, iloop, oFile);
622 /*-----------------------------------------------------------------*/
623 /* printIvalChar - generates initital value for character array */
624 /*-----------------------------------------------------------------*/
626 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
634 val = list2val (ilist);
635 /* if the value is a character string */
636 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
638 if (!DCL_ELEM (type))
639 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
641 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
643 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
645 tfprintf (oFile, "\t!db !constbyte\n", 0);
653 printChar (oFile, s, strlen (s) + 1);
657 /*-----------------------------------------------------------------*/
658 /* printIvalArray - generates code for array initialization */
659 /*-----------------------------------------------------------------*/
661 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
665 int lcnt = 0, size = 0;
667 /* take care of the special case */
668 /* array of characters can be init */
670 if (IS_CHAR (type->next))
671 if (printIvalChar (type,
672 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
673 oFile, SPEC_CVAL (sym->etype).v_char))
676 /* not the special case */
677 if (ilist->type != INIT_DEEP)
679 werror (E_INIT_STRUCT, sym->name);
683 iloop = ilist->init.deep;
684 lcnt = DCL_ELEM (type);
689 printIval (sym, type->next, iloop, oFile);
690 iloop = (iloop ? iloop->next : NULL);
693 /* if not array limits given & we */
694 /* are out of initialisers then */
695 if (!DCL_ELEM (type) && !iloop)
698 /* no of elements given and we */
699 /* have generated for all of them */
701 /* if initializers left */
703 werror (W_EXESS_ARRAY_INITIALIZERS, sym->name, sym->lineDef);
709 /* if we have not been given a size */
710 if (!DCL_ELEM (type))
711 DCL_ELEM (type) = size;
716 /*-----------------------------------------------------------------*/
717 /* printIvalFuncPtr - generate initial value for function pointers */
718 /*-----------------------------------------------------------------*/
720 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
725 val = list2val (ilist);
726 /* check the types */
727 if ((dLvl = compareType (val->type, type->next)) <= 0)
729 tfprintf (oFile, "\t!dw !constword\n", 0);
733 /* now generate the name */
736 if (port->use_dw_for_init)
738 tfprintf (oFile, "\t!dws\n", val->name);
742 printPointerType (oFile, val->name);
745 else if (port->use_dw_for_init)
747 tfprintf (oFile, "\t!dws\n", val->sym->rname);
751 printPointerType (oFile, val->sym->rname);
757 /*-----------------------------------------------------------------*/
758 /* printIvalCharPtr - generates initial values for character pointers */
759 /*-----------------------------------------------------------------*/
761 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
765 /* PENDING: this is _very_ mcs51 specific, including a magic
767 It's also endin specific.
769 size = getSize (type);
771 if (val->name && strlen (val->name))
773 if (size == 1) /* This appears to be Z80 specific?? */
776 "\t!dbs\n", val->name);
778 else if (size == FPTRSIZE)
780 if (port->use_dw_for_init)
782 tfprintf (oFile, "\t!dws\n", val->name);
786 printPointerType (oFile, val->name);
789 else if (size == GPTRSIZE)
792 if (IS_PTR (val->type)) {
793 type = DCL_TYPE (val->type);
795 type = PTR_TYPE (SPEC_OCLS (val->etype));
797 if (val->sym && val->sym->isstrlit) {
798 // this is a literal string
801 printGPointerType (oFile, val->name, sym->name, type);
805 fprintf (stderr, "*** internal error: unknown size in "
806 "printIvalCharPtr.\n");
811 /* What is this case? Are these pointers? */
815 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
818 if (port->use_dw_for_init)
819 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
821 tfprintf (oFile, "\t.byte %s,%s\n",
822 aopLiteral (val, 0), aopLiteral (val, 1));
825 /* PENDING: 0x02 or 0x%02x, CDATA? */
826 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
827 aopLiteral (val, 0), aopLiteral (val, 1));
834 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
835 addSet (&statsg->syms, val->sym);
841 /*-----------------------------------------------------------------*/
842 /* printIvalPtr - generates initial value for pointers */
843 /*-----------------------------------------------------------------*/
845 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
851 if (ilist->type == INIT_DEEP)
852 ilist = ilist->init.deep;
854 /* function pointer */
855 if (IS_FUNC (type->next))
857 printIvalFuncPtr (type, ilist, oFile);
861 if (!(val = initPointer (ilist)))
864 /* if character pointer */
865 if (IS_CHAR (type->next))
866 if (printIvalCharPtr (sym, type, val, oFile))
870 if (compareType (type, val->type) == 0)
871 werror (E_INIT_WRONG);
873 /* if val is literal */
874 if (IS_LITERAL (val->etype))
876 switch (getSize (type))
879 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
882 if (port->use_dw_for_init)
883 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
885 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
888 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
889 aopLiteral (val, 0), aopLiteral (val, 1));
895 size = getSize (type);
897 if (size == 1) /* Z80 specific?? */
899 tfprintf (oFile, "\t!dbs\n", val->name);
901 else if (size == FPTRSIZE)
903 if (port->use_dw_for_init) {
904 tfprintf (oFile, "\t!dws\n", val->name);
906 printPointerType (oFile, val->name);
909 else if (size == GPTRSIZE)
911 printGPointerType (oFile, val->name, sym->name,
912 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
913 PTR_TYPE (SPEC_OCLS (val->etype))));
918 /*-----------------------------------------------------------------*/
919 /* printIval - generates code for initial value */
920 /*-----------------------------------------------------------------*/
922 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
927 /* if structure then */
928 if (IS_STRUCT (type))
930 printIvalStruct (sym, type, ilist, oFile);
934 /* if this is a pointer */
937 printIvalPtr (sym, type, ilist, oFile);
941 /* if this is an array */
944 printIvalArray (sym, type, ilist, oFile);
948 /* if type is SPECIFIER */
951 printIvalType (type, ilist, oFile);
956 /*-----------------------------------------------------------------*/
957 /* emitStaticSeg - emitcode for the static segment */
958 /*-----------------------------------------------------------------*/
960 emitStaticSeg (memmap * map, FILE * out)
964 /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
968 /* for all variables in this segment do */
969 for (sym = setFirstItem (map->syms); sym;
970 sym = setNextItem (map->syms))
973 /* if it is "extern" then do nothing */
974 if (IS_EXTERN (sym->etype))
977 /* if it is not static add it to the public
979 if (!IS_STATIC (sym->etype))
980 addSetHead (&publics, sym);
982 /* print extra debug info if required */
984 cdbSymbol (sym, cdbFile, FALSE, FALSE);
987 if (IS_STATIC (sym->etype))
988 fprintf (out, "F%s$", moduleName); /* scope is file */
990 fprintf (out, "G$"); /* scope is global */
993 /* symbol is local */
994 fprintf (out, "L%s$",
995 (sym->localof ? sym->localof->name : "-null-"));
996 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
999 /* if it has an absolute address */
1000 if (SPEC_ABSA (sym->etype))
1003 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1005 fprintf (out, "%s\t=\t0x%04x\n",
1007 SPEC_ADDR (sym->etype));
1012 fprintf (out, " == .\n");
1014 /* if it has an initial value */
1017 fprintf (out, "%s:\n", sym->rname);
1019 resolveIvalSym (sym->ival);
1020 printIval (sym, sym->type, sym->ival, out);
1025 /* allocate space */
1026 fprintf (out, "%s:\n", sym->rname);
1027 /* special case for character strings */
1028 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1029 SPEC_CVAL (sym->etype).v_char)
1031 SPEC_CVAL (sym->etype).v_char,
1032 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1034 tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1040 /*-----------------------------------------------------------------*/
1041 /* emitMaps - emits the code for the data portion the code */
1042 /*-----------------------------------------------------------------*/
1047 /* no special considerations for the following
1048 data, idata & bit & xdata */
1049 emitRegularMap (data, TRUE, TRUE);
1050 emitRegularMap (idata, TRUE, TRUE);
1051 emitRegularMap (bit, TRUE, FALSE);
1052 emitRegularMap (xdata, TRUE, TRUE);
1053 emitRegularMap (sfr, FALSE, FALSE);
1054 emitRegularMap (sfrbit, FALSE, FALSE);
1055 emitRegularMap (home, TRUE, FALSE);
1056 emitRegularMap (code, TRUE, FALSE);
1058 emitStaticSeg (statsg, code->oFile);
1062 /*-----------------------------------------------------------------*/
1063 /* flushStatics - flush all currently defined statics out to file */
1064 /* and delete. Temporary function */
1065 /*-----------------------------------------------------------------*/
1069 emitStaticSeg (statsg, codeOutFile);
1070 statsg->syms = NULL;
1073 /*-----------------------------------------------------------------*/
1074 /* createInterruptVect - creates the interrupt vector */
1075 /*-----------------------------------------------------------------*/
1077 createInterruptVect (FILE * vFile)
1080 mainf = newSymbol ("main", 0);
1083 /* only if the main function exists */
1084 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1086 if (!options.cc_only && !noAssemble)
1091 /* if the main is only a prototype ie. no body then do nothing */
1094 /* if ! compile only then main function should be present */
1095 if (!options.cc_only && !noAssemble)
1100 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1101 fprintf (vFile, "__interrupt_vect:\n");
1104 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1106 /* "generic" interrupt table header (if port doesn't specify one).
1108 * Look suspiciously like 8051 code to me...
1111 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1114 /* now for the other interrupts */
1115 for (; i < maxInterrupts; i++)
1118 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1120 fprintf (vFile, "\treti\n\t.ds\t7\n");
1127 ";--------------------------------------------------------\n"
1128 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1132 ";--------------------------------------------------------\n"};
1135 /*-----------------------------------------------------------------*/
1136 /* initialComments - puts in some initial comments */
1137 /*-----------------------------------------------------------------*/
1139 initialComments (FILE * afile)
1143 fprintf (afile, "%s", iComments1);
1144 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1145 fprintf (afile, "%s", iComments2);
1148 /*-----------------------------------------------------------------*/
1149 /* printPublics - generates .global for publics */
1150 /*-----------------------------------------------------------------*/
1152 printPublics (FILE * afile)
1156 fprintf (afile, "%s", iComments2);
1157 fprintf (afile, "; Public variables in this module\n");
1158 fprintf (afile, "%s", iComments2);
1160 for (sym = setFirstItem (publics); sym;
1161 sym = setNextItem (publics))
1162 tfprintf (afile, "\t!global\n", sym->rname);
1165 /*-----------------------------------------------------------------*/
1166 /* printExterns - generates .global for externs */
1167 /*-----------------------------------------------------------------*/
1169 printExterns (FILE * afile)
1173 fprintf (afile, "%s", iComments2);
1174 fprintf (afile, "; Externals used\n");
1175 fprintf (afile, "%s", iComments2);
1177 for (sym = setFirstItem (externs); sym;
1178 sym = setNextItem (externs))
1179 tfprintf (afile, "\t!global\n", sym->rname);
1182 /*-----------------------------------------------------------------*/
1183 /* emitOverlay - will emit code for the overlay stuff */
1184 /*-----------------------------------------------------------------*/
1186 emitOverlay (FILE * afile)
1190 if (!elementsInSet (ovrSetSets))
1191 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1193 /* for each of the sets in the overlay segment do */
1194 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1195 ovrset = setNextItem (ovrSetSets))
1200 if (elementsInSet (ovrset))
1202 /* this dummy area is used to fool the assembler
1203 otherwise the assembler will append each of these
1204 declarations into one chunk and will not overlay
1206 fprintf (afile, "\t.area _DUMMY\n");
1207 /* output the area informtion */
1208 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1211 for (sym = setFirstItem (ovrset); sym;
1212 sym = setNextItem (ovrset))
1215 /* if extern then add it to the publics tabledo nothing */
1216 if (IS_EXTERN (sym->etype))
1219 /* if allocation required check is needed
1220 then check if the symbol really requires
1221 allocation only for local variables */
1222 if (!IS_AGGREGATE (sym->type) &&
1223 !(sym->_isparm && !IS_REGPARM (sym->etype))
1224 && !sym->allocreq && sym->level)
1227 /* if global variable & not static or extern
1228 and addPublics allowed then add it to the public set */
1229 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1230 && !IS_STATIC (sym->etype))
1231 addSetHead (&publics, sym);
1233 /* if extern then do nothing or is a function
1235 if (IS_FUNC (sym->type))
1238 /* print extra debug info if required */
1241 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1245 if (IS_STATIC (sym->etype))
1246 fprintf (afile, "F%s$", moduleName); /* scope is file */
1248 fprintf (afile, "G$"); /* scope is global */
1251 /* symbol is local */
1252 fprintf (afile, "L%s$",
1253 (sym->localof ? sym->localof->name : "-null-"));
1254 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1257 /* if is has an absolute address then generate
1258 an equate for this no need to allocate space */
1259 if (SPEC_ABSA (sym->etype))
1263 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1265 fprintf (afile, "%s\t=\t0x%04x\n",
1267 SPEC_ADDR (sym->etype));
1272 fprintf (afile, "==.\n");
1274 /* allocate space */
1275 tfprintf (afile, "!labeldef\n", sym->rname);
1276 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1283 /*-----------------------------------------------------------------*/
1284 /* glue - the final glue that hold the whole thing together */
1285 /*-----------------------------------------------------------------*/
1291 FILE *ovrFile = tempfile ();
1293 addSetHead (&tmpfileSet, ovrFile);
1294 /* print the global struct definitions */
1296 cdbStructBlock (0, cdbFile);
1298 vFile = tempfile ();
1299 /* PENDING: this isnt the best place but it will do */
1300 if (port->general.glue_up_main)
1302 /* create the interrupt vector table */
1303 createInterruptVect (vFile);
1306 addSetHead (&tmpfileSet, vFile);
1308 /* emit code for the all the variables declared */
1310 /* do the overlay segments */
1311 emitOverlay (ovrFile);
1313 /* now put it all together into the assembler file */
1314 /* create the assembler file name */
1316 if (!options.c1mode)
1318 sprintf (scratchFileName, srcFileName);
1319 strcat (scratchFileName, port->assembler.file_ext);
1323 strcpy (scratchFileName, options.out_name);
1326 if (!(asmFile = fopen (scratchFileName, "w")))
1328 werror (E_FILE_OPEN_ERR, scratchFileName);
1332 /* initial comments */
1333 initialComments (asmFile);
1335 /* print module name */
1336 tfprintf (asmFile, "\t!module\n", moduleName);
1337 tfprintf (asmFile, "\t!fileprelude\n");
1339 /* Let the port generate any global directives, etc. */
1340 if (port->genAssemblerPreamble)
1342 port->genAssemblerPreamble (asmFile);
1345 /* print the global variables in this module */
1346 printPublics (asmFile);
1347 if (port->assembler.externGlobal)
1348 printExterns (asmFile);
1350 /* copy the sfr segment */
1351 fprintf (asmFile, "%s", iComments2);
1352 fprintf (asmFile, "; special function registers\n");
1353 fprintf (asmFile, "%s", iComments2);
1354 copyFile (asmFile, sfr->oFile);
1356 /* copy the sbit segment */
1357 fprintf (asmFile, "%s", iComments2);
1358 fprintf (asmFile, "; special function bits \n");
1359 fprintf (asmFile, "%s", iComments2);
1360 copyFile (asmFile, sfrbit->oFile);
1362 /* copy the data segment */
1363 fprintf (asmFile, "%s", iComments2);
1364 fprintf (asmFile, "; internal ram data\n");
1365 fprintf (asmFile, "%s", iComments2);
1366 copyFile (asmFile, data->oFile);
1369 /* create the overlay segments */
1370 fprintf (asmFile, "%s", iComments2);
1371 fprintf (asmFile, "; overlayable items in internal ram \n");
1372 fprintf (asmFile, "%s", iComments2);
1373 copyFile (asmFile, ovrFile);
1375 /* create the stack segment MOF */
1376 if (mainf && mainf->fbody)
1378 fprintf (asmFile, "%s", iComments2);
1379 fprintf (asmFile, "; Stack segment in internal ram \n");
1380 fprintf (asmFile, "%s", iComments2);
1381 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1382 "__start__stack:\n\t.ds\t1\n\n");
1385 /* create the idata segment */
1386 fprintf (asmFile, "%s", iComments2);
1387 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1388 fprintf (asmFile, "%s", iComments2);
1389 copyFile (asmFile, idata->oFile);
1391 /* copy the bit segment */
1392 fprintf (asmFile, "%s", iComments2);
1393 fprintf (asmFile, "; bit data\n");
1394 fprintf (asmFile, "%s", iComments2);
1395 copyFile (asmFile, bit->oFile);
1397 /* if external stack then reserve space of it */
1398 if (mainf && mainf->fbody && options.useXstack)
1400 fprintf (asmFile, "%s", iComments2);
1401 fprintf (asmFile, "; external stack \n");
1402 fprintf (asmFile, "%s", iComments2);
1403 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1404 fprintf (asmFile, "\t.ds 256\n");
1408 /* copy xtern ram data */
1409 fprintf (asmFile, "%s", iComments2);
1410 fprintf (asmFile, "; external ram data\n");
1411 fprintf (asmFile, "%s", iComments2);
1412 copyFile (asmFile, xdata->oFile);
1414 /* copy the interrupt vector table */
1415 if (mainf && mainf->fbody)
1417 fprintf (asmFile, "%s", iComments2);
1418 fprintf (asmFile, "; interrupt vector \n");
1419 fprintf (asmFile, "%s", iComments2);
1420 copyFile (asmFile, vFile);
1423 /* copy global & static initialisations */
1424 fprintf (asmFile, "%s", iComments2);
1425 fprintf (asmFile, "; global & static initialisations\n");
1426 fprintf (asmFile, "%s", iComments2);
1428 /* Everywhere we generate a reference to the static_name area,
1429 * (which is currently only here), we immediately follow it with a
1430 * definition of the post_static_name area. This guarantees that
1431 * the post_static_name area will immediately follow the static_name
1434 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1435 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1436 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1438 if (mainf && mainf->fbody)
1440 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1441 /* if external stack is specified then the
1442 higher order byte of the xdatalocation is
1443 going into P2 and the lower order going into
1445 if (options.useXstack)
1447 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1448 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1449 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1450 (unsigned int) options.xdata_loc & 0xff);
1453 /* initialise the stack pointer */
1454 /* if the user specified a value then use it */
1455 if (options.stack_loc)
1456 fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc);
1458 /* no: we have to compute it */
1459 if (!options.stackOnData && maxRegBank <= 3)
1460 fprintf (asmFile, "\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1);
1462 fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */
1464 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1465 fprintf (asmFile, "\tmov\ta,dpl\n");
1466 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1467 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1468 fprintf (asmFile, "__sdcc_init_data:\n");
1471 copyFile (asmFile, statsg->oFile);
1473 if (port->general.glue_up_main && mainf && mainf->fbody)
1475 /* This code is generated in the post-static area.
1476 * This area is guaranteed to follow the static area
1477 * by the ugly shucking and jiving about 20 lines ago.
1479 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1480 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1486 "%s", iComments2, iComments2);
1487 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1488 copyFile (asmFile, home->oFile);
1490 /* copy over code */
1491 fprintf (asmFile, "%s", iComments2);
1492 fprintf (asmFile, "; code\n");
1493 fprintf (asmFile, "%s", iComments2);
1494 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1495 if (mainf && mainf->fbody)
1498 /* entry point @ start of CSEG */
1499 fprintf (asmFile, "__sdcc_program_startup:\n");
1501 /* put in the call to main */
1502 fprintf (asmFile, "\tlcall\t_main\n");
1503 if (options.mainreturn)
1506 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1507 fprintf (asmFile, "\tret\n");
1513 fprintf (asmFile, ";\treturn from main will lock up\n");
1514 fprintf (asmFile, "\tsjmp .\n");
1517 copyFile (asmFile, code->oFile);
1520 applyToSet (tmpfileSet, closeTmpFiles);
1521 applyToSet (tmpfileNameSet, rmTmpFiles);
1524 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1528 applyToSet (tmpfileSet, closeTmpFiles);
1529 applyToSet (tmpfileNameSet, rmTmpFiles);
1533 /** Creates a temporary file a'la tmpfile which avoids the bugs
1534 in cygwin wrt c:\tmp.
1535 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1540 #if !defined(_MSC_VER)
1541 const char *tmpdir = NULL;
1543 tmpdir = getenv ("TMP");
1544 else if (getenv ("TEMP"))
1545 tmpdir = getenv ("TEMP");
1546 else if (getenv ("TMPDIR"))
1547 tmpdir = getenv ("TMPDIR");
1550 char *name = tempnam (tmpdir, "sdcc");
1553 FILE *fp = fopen (name, "w+b");
1556 addSetHead (&tmpfileNameSet, name);
1567 gc_strdup (const char *s)
1570 ret = Safe_calloc (1, strlen (s) + 1);