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)
103 // assuming we have been warned before
107 /* if it is a float then it gets tricky */
108 /* otherwise it is fairly simple */
109 if (!IS_FLOAT (val->type)) {
110 unsigned long v = (unsigned long) floatFromVal (val);
115 tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
118 tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
121 /* Hmm. Too big for now. */
124 rs = Safe_calloc (1, strlen (buffer) + 1);
125 return strcpy (rs, buffer);
128 /* PENDING: For now size must be 1 */
131 /* it is type float */
132 fl.f = (float) floatFromVal (val);
134 tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
136 tsprintf (buffer, "!immedbyte", fl.c[offset]);
138 rs = Safe_calloc (1, strlen (buffer) + 1);
139 return strcpy (rs, buffer);
142 /*-----------------------------------------------------------------*/
143 /* aopLiteral - string from a literal value */
144 /*-----------------------------------------------------------------*/
146 aopLiteral (value * val, int offset)
148 return aopLiteralLong (val, offset, 1);
151 /*-----------------------------------------------------------------*/
152 /* emitRegularMap - emit code for maps with no special cases */
153 /*-----------------------------------------------------------------*/
155 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
157 symbol *sym, *symIval;
163 /* PENDING: special case here - should remove */
164 if (!strcmp (map->sname, CODE_NAME))
165 tfprintf (map->oFile, "\t!areacode\n", map->sname);
166 else if (!strcmp (map->sname, DATA_NAME))
167 tfprintf (map->oFile, "\t!areadata\n", map->sname);
168 else if (!strcmp (map->sname, HOME_NAME))
169 tfprintf (map->oFile, "\t!areahome\n", map->sname);
171 tfprintf (map->oFile, "\t!area\n", map->sname);
174 /* print the area name */
175 for (sym = setFirstItem (map->syms); sym;
176 sym = setNextItem (map->syms))
179 /* if extern then add it into the extern list */
180 if (IS_EXTERN (sym->etype))
182 addSetHead (&externs, sym);
186 /* if allocation required check is needed
187 then check if the symbol really requires
188 allocation only for local variables */
190 if (arFlag && !IS_AGGREGATE (sym->type) &&
191 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
192 !sym->allocreq && sym->level)
195 /* for bitvar locals and parameters */
196 if (!arFlag && !sym->allocreq && sym->level
197 && !SPEC_ABSA (sym->etype)) {
201 /* if global variable & not static or extern
202 and addPublics allowed then add it to the public set */
203 if ((sym->level == 0 ||
204 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
206 !IS_STATIC (sym->etype) &&
207 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
209 addSetHead (&publics, sym);
212 /* if extern then do nothing or is a function
214 if (IS_FUNC (sym->type))
217 /* print extra debug info if required */
219 cdbSymbol (sym, cdbFile, FALSE, FALSE);
220 if (!sym->level) /* global */
221 if (IS_STATIC (sym->etype))
222 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
224 fprintf (map->oFile, "G$"); /* scope is global */
226 /* symbol is local */
227 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
228 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
231 /* if is has an absolute address then generate
232 an equate for this no need to allocate space */
233 if (SPEC_ABSA (sym->etype))
236 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
238 fprintf (map->oFile, "%s\t=\t0x%04x\n",
240 SPEC_ADDR (sym->etype));
246 fprintf (map->oFile, "==.\n");
248 if (IS_STATIC (sym->etype))
249 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
251 tfprintf (map->oFile, "!labeldef\n", sym->rname);
252 tfprintf (map->oFile, "\t!ds\n",
253 (unsigned int) getSize (sym->type) & 0xffff);
256 /* if it has an initial value then do it only if
257 it is a global variable */
258 if (sym->ival && sym->level == 0)
260 if (IS_AGGREGATE (sym->type)) {
261 ival = initAggregates (sym, sym->ival, NULL);
263 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
264 decorateType (resolveSymbols (list2expr (sym->ival))));
266 codeOutFile = statsg->oFile;
269 // set ival's lineno to where the symbol was defined
270 if (ival) ival->lineno=sym->lineDef;
271 eBBlockFromiCode (iCodeFromAst (ival));
274 /* if the ival is a symbol assigned to an aggregate,
275 (bug #458099 -> #462479)
276 we don't need it anymore, so delete it from its segment */
277 if (sym->ival->type == INIT_NODE &&
278 IS_AST_SYM_VALUE(sym->ival->init.node) &&
279 IS_AGGREGATE (sym->type) ) {
280 symIval=AST_SYMBOL(sym->ival->init.node);
281 segment = SPEC_OCLS (symIval->etype);
282 deleteSetItem (&segment->syms, symIval);
290 /*-----------------------------------------------------------------*/
291 /* initPointer - pointer initialization code massaging */
292 /*-----------------------------------------------------------------*/
294 initPointer (initList * ilist)
297 ast *expr = list2expr (ilist);
302 /* try it the oldway first */
303 if ((val = constExprValue (expr, FALSE)))
306 /* no then we have to do these cludgy checks */
307 /* pointers can be initialized with address of
308 a variable or address of an array element */
309 if (IS_AST_OP (expr) && expr->opval.op == '&') {
310 /* address of symbol */
311 if (IS_AST_SYM_VALUE (expr->left)) {
312 val = copyValue (AST_VALUE (expr->left));
313 val->type = newLink ();
314 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
315 DCL_TYPE (val->type) = CPOINTER;
316 DCL_PTR_CONST (val->type) = port->mem.code_ro;
318 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
319 DCL_TYPE (val->type) = FPOINTER;
320 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
321 DCL_TYPE (val->type) = PPOINTER;
322 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
323 DCL_TYPE (val->type) = IPOINTER;
324 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
325 DCL_TYPE (val->type) = EEPPOINTER;
327 DCL_TYPE (val->type) = POINTER;
328 val->type->next = expr->left->ftype;
329 val->etype = getSpec (val->type);
333 /* if address of indexed array */
334 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
335 return valForArray (expr->left);
337 /* if address of structure element then
339 if (IS_AST_OP (expr->left) &&
340 expr->left->opval.op == '.') {
341 return valForStructElem (expr->left->left,
346 (&some_struct)->element */
347 if (IS_AST_OP (expr->left) &&
348 expr->left->opval.op == PTR_OP &&
349 IS_ADDRESS_OF_OP (expr->left->left))
350 return valForStructElem (expr->left->left->left,
354 /* case 3. (((char *) &a) +/- constant) */
355 if (IS_AST_OP (expr) &&
356 (expr->opval.op == '+' || expr->opval.op == '-') &&
357 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
358 IS_AST_OP (expr->left->right) &&
359 expr->left->right->opval.op == '&' &&
360 IS_AST_LIT_VALUE (expr->right)) {
362 return valForCastAggr (expr->left->right->left,
363 expr->left->left->opval.lnk,
364 expr->right, expr->opval.op);
368 /* case 4. (char *)(array type) */
369 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
370 IS_ARRAY(expr->right->ftype)) {
372 val = copyValue (AST_VALUE (expr->right));
373 val->type = newLink ();
374 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
375 DCL_TYPE (val->type) = CPOINTER;
376 DCL_PTR_CONST (val->type) = port->mem.code_ro;
378 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
379 DCL_TYPE (val->type) = FPOINTER;
380 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
381 DCL_TYPE (val->type) = PPOINTER;
382 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
383 DCL_TYPE (val->type) = IPOINTER;
384 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
385 DCL_TYPE (val->type) = EEPPOINTER;
387 DCL_TYPE (val->type) = POINTER;
388 val->type->next = expr->right->ftype->next;
389 val->etype = getSpec (val->type);
393 werror (W_INIT_WRONG);
398 /*-----------------------------------------------------------------*/
399 /* printChar - formats and prints a characater string with DB */
400 /*-----------------------------------------------------------------*/
402 printChar (FILE * ofile, char *s, int plen)
405 int len = strlen (s);
410 while (len && pplen < plen)
413 while (i && *s && pplen < plen)
415 if (*s < ' ' || *s == '\"' || *s=='\\')
419 tfprintf (ofile, "\t!ascii\n", buf);
420 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
435 tfprintf (ofile, "\t!ascii\n", buf);
444 tfprintf (ofile, "\t!db !constbyte\n", 0);
447 /*-----------------------------------------------------------------*/
448 /* return the generic pointer high byte for a given pointer type. */
449 /*-----------------------------------------------------------------*/
451 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
459 /* hack - if we get a generic pointer, we just assume
460 * it's an FPOINTER (i.e. in XDATA space).
462 werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname);
472 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
480 /*-----------------------------------------------------------------*/
481 /* printPointerType - generates ival for pointer type */
482 /*-----------------------------------------------------------------*/
484 _printPointerType (FILE * oFile, const char *name)
486 /* if (TARGET_IS_DS390) */
487 if (options.model == MODEL_FLAT24)
489 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
493 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
497 /*-----------------------------------------------------------------*/
498 /* printPointerType - generates ival for pointer type */
499 /*-----------------------------------------------------------------*/
501 printPointerType (FILE * oFile, const char *name)
503 _printPointerType (oFile, name);
504 fprintf (oFile, "\n");
507 /*-----------------------------------------------------------------*/
508 /* printGPointerType - generates ival for generic pointer type */
509 /*-----------------------------------------------------------------*/
511 printGPointerType (FILE * oFile, const char *iname, const char *oname,
512 const unsigned int type)
514 _printPointerType (oFile, iname);
515 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
518 /*-----------------------------------------------------------------*/
519 /* printIvalType - generates ival for int/char */
520 /*-----------------------------------------------------------------*/
522 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
526 /* if initList is deep */
527 if (ilist->type == INIT_DEEP)
528 ilist = ilist->init.deep;
530 if (sym && ilist->next) {
531 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
534 val = list2val (ilist);
535 switch (getSize (type)) {
538 tfprintf (oFile, "\t!db !constbyte\n", 0);
540 tfprintf (oFile, "\t!dbs\n",
541 aopLiteral (val, 0));
545 if (port->use_dw_for_init)
546 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
548 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
552 tfprintf (oFile, "\t!dw !constword\n", 0);
553 tfprintf (oFile, "\t!dw !constword\n", 0);
556 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
557 aopLiteral (val, 0), aopLiteral (val, 1),
558 aopLiteral (val, 2), aopLiteral (val, 3));
564 /*-----------------------------------------------------------------*/
565 /* printIvalBitFields - generate initializer for bitfields */
566 /*-----------------------------------------------------------------*/
567 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
571 initList *lilist = *ilist ;
572 unsigned long ival = 0;
578 val = list2val(lilist);
580 if (SPEC_BLEN(lsym->etype) > 8) {
581 size += ((SPEC_BLEN (lsym->etype) / 8) +
582 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
585 size = ((SPEC_BLEN (lsym->etype) / 8) +
586 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
588 i = (unsigned long)floatFromVal(val);
589 i <<= SPEC_BSTR (lsym->etype);
591 if (! ( lsym->next &&
592 (IS_BITFIELD(lsym->next->type)) &&
593 (SPEC_BSTR(lsym->next->etype)))) break;
595 lilist = lilist->next;
599 tfprintf (oFile, "\t!db !constbyte\n",ival);
603 tfprintf (oFile, "\t!dw !constword\n",ival);
606 tfprintf (oFile, "\t!db !constword,!constword\n",
607 (ival >> 8) & 0xffff, (ival & 0xffff));
614 /*-----------------------------------------------------------------*/
615 /* printIvalStruct - generates initial value for structures */
616 /*-----------------------------------------------------------------*/
618 printIvalStruct (symbol * sym, sym_link * type,
619 initList * ilist, FILE * oFile)
624 sflds = SPEC_STRUCT (type)->fields;
625 if (ilist->type != INIT_DEEP) {
626 werror (E_INIT_STRUCT, sym->name);
630 iloop = ilist->init.deep;
632 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
633 if (IS_BITFIELD(sflds->type)) {
634 printIvalBitFields(&sflds,&iloop,oFile);
636 printIval (NULL, sflds->type, iloop, oFile);
640 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
645 /*-----------------------------------------------------------------*/
646 /* printIvalChar - generates initital value for character array */
647 /*-----------------------------------------------------------------*/
649 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
657 val = list2val (ilist);
658 /* if the value is a character string */
659 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
661 if (!DCL_ELEM (type))
662 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
664 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
666 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
668 tfprintf (oFile, "\t!db !constbyte\n", 0);
676 printChar (oFile, s, strlen (s) + 1);
680 /*-----------------------------------------------------------------*/
681 /* printIvalArray - generates code for array initialization */
682 /*-----------------------------------------------------------------*/
684 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
688 int lcnt = 0, size = 0;
690 /* take care of the special case */
691 /* array of characters can be init */
693 if (IS_CHAR (type->next))
694 if (printIvalChar (type,
695 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
696 oFile, SPEC_CVAL (sym->etype).v_char))
699 /* not the special case */
700 if (ilist->type != INIT_DEEP)
702 werror (E_INIT_STRUCT, sym->name);
706 iloop = ilist->init.deep;
707 lcnt = DCL_ELEM (type);
712 printIval (NULL, type->next, iloop, oFile);
713 iloop = (iloop ? iloop->next : NULL);
716 /* if not array limits given & we */
717 /* are out of initialisers then */
718 if (!DCL_ELEM (type) && !iloop)
721 /* no of elements given and we */
722 /* have generated for all of them */
724 /* if initializers left */
726 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
732 /* if we have not been given a size */
733 if (!DCL_ELEM (type))
734 DCL_ELEM (type) = size;
739 /*-----------------------------------------------------------------*/
740 /* printIvalFuncPtr - generate initial value for function pointers */
741 /*-----------------------------------------------------------------*/
743 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
748 val = list2val (ilist);
749 /* check the types */
750 if ((dLvl = compareType (val->type, type->next)) <= 0)
752 tfprintf (oFile, "\t!dw !constword\n", 0);
756 /* now generate the name */
759 if (port->use_dw_for_init)
761 tfprintf (oFile, "\t!dws\n", val->name);
765 printPointerType (oFile, val->name);
768 else if (port->use_dw_for_init)
770 tfprintf (oFile, "\t!dws\n", val->sym->rname);
774 printPointerType (oFile, val->sym->rname);
780 /*-----------------------------------------------------------------*/
781 /* printIvalCharPtr - generates initial values for character pointers */
782 /*-----------------------------------------------------------------*/
784 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
788 /* PENDING: this is _very_ mcs51 specific, including a magic
790 It's also endin specific.
792 size = getSize (type);
794 if (val->name && strlen (val->name))
796 if (size == 1) /* This appears to be Z80 specific?? */
799 "\t!dbs\n", val->name);
801 else if (size == FPTRSIZE)
803 if (port->use_dw_for_init)
805 tfprintf (oFile, "\t!dws\n", val->name);
809 printPointerType (oFile, val->name);
812 else if (size == GPTRSIZE)
815 if (IS_PTR (val->type)) {
816 type = DCL_TYPE (val->type);
818 type = PTR_TYPE (SPEC_OCLS (val->etype));
820 if (val->sym && val->sym->isstrlit) {
821 // this is a literal string
824 printGPointerType (oFile, val->name, sym->name, type);
828 fprintf (stderr, "*** internal error: unknown size in "
829 "printIvalCharPtr.\n");
834 /* What is this case? Are these pointers? */
838 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
841 if (port->use_dw_for_init)
842 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
844 tfprintf (oFile, "\t.byte %s,%s\n",
845 aopLiteral (val, 0), aopLiteral (val, 1));
848 /* PENDING: 0x02 or 0x%02x, CDATA? */
849 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
850 aopLiteral (val, 0), aopLiteral (val, 1));
857 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
858 addSet (&statsg->syms, val->sym);
864 /*-----------------------------------------------------------------*/
865 /* printIvalPtr - generates initial value for pointers */
866 /*-----------------------------------------------------------------*/
868 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
874 if (ilist->type == INIT_DEEP)
875 ilist = ilist->init.deep;
877 /* function pointer */
878 if (IS_FUNC (type->next))
880 printIvalFuncPtr (type, ilist, oFile);
884 if (!(val = initPointer (ilist)))
887 /* if character pointer */
888 if (IS_CHAR (type->next))
889 if (printIvalCharPtr (sym, type, val, oFile))
893 if (compareType (type, val->type) == 0)
894 werror (W_INIT_WRONG);
896 /* if val is literal */
897 if (IS_LITERAL (val->etype))
899 switch (getSize (type))
902 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
905 if (port->use_dw_for_init)
906 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
908 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
911 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
912 aopLiteral (val, 0), aopLiteral (val, 1));
918 size = getSize (type);
920 if (size == 1) /* Z80 specific?? */
922 tfprintf (oFile, "\t!dbs\n", val->name);
924 else if (size == FPTRSIZE)
926 if (port->use_dw_for_init) {
927 tfprintf (oFile, "\t!dws\n", val->name);
929 printPointerType (oFile, val->name);
932 else if (size == GPTRSIZE)
934 printGPointerType (oFile, val->name, sym->name,
935 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
936 PTR_TYPE (SPEC_OCLS (val->etype))));
941 /*-----------------------------------------------------------------*/
942 /* printIval - generates code for initial value */
943 /*-----------------------------------------------------------------*/
945 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
950 /* if structure then */
951 if (IS_STRUCT (type))
953 printIvalStruct (sym, type, ilist, oFile);
957 /* if this is a pointer */
960 printIvalPtr (sym, type, ilist, oFile);
964 /* if this is an array */
967 printIvalArray (sym, type, ilist, oFile);
971 /* if type is SPECIFIER */
974 printIvalType (sym, type, ilist, oFile);
979 /*-----------------------------------------------------------------*/
980 /* emitStaticSeg - emitcode for the static segment */
981 /*-----------------------------------------------------------------*/
983 emitStaticSeg (memmap * map, FILE * out)
987 /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
991 /* for all variables in this segment do */
992 for (sym = setFirstItem (map->syms); sym;
993 sym = setNextItem (map->syms))
996 /* if it is "extern" then do nothing */
997 if (IS_EXTERN (sym->etype))
1000 /* if it is not static add it to the public
1002 if (!IS_STATIC (sym->etype))
1003 addSetHead (&publics, sym);
1005 /* print extra debug info if required */
1006 if (options.debug) {
1007 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1010 if (IS_STATIC (sym->etype))
1011 fprintf (out, "F%s$", moduleName); /* scope is file */
1013 fprintf (out, "G$"); /* scope is global */
1016 /* symbol is local */
1017 fprintf (out, "L%s$",
1018 (sym->localof ? sym->localof->name : "-null-"));
1019 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1022 /* if it has an absolute address */
1023 if (SPEC_ABSA (sym->etype))
1026 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1028 fprintf (out, "%s\t=\t0x%04x\n",
1030 SPEC_ADDR (sym->etype));
1035 fprintf (out, " == .\n");
1037 /* if it has an initial value */
1040 fprintf (out, "%s:\n", sym->rname);
1042 resolveIvalSym (sym->ival);
1043 printIval (sym, sym->type, sym->ival, out);
1048 /* allocate space */
1049 fprintf (out, "%s:\n", sym->rname);
1050 /* special case for character strings */
1051 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1052 SPEC_CVAL (sym->etype).v_char)
1054 SPEC_CVAL (sym->etype).v_char,
1055 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1057 tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1063 /*-----------------------------------------------------------------*/
1064 /* emitMaps - emits the code for the data portion the code */
1065 /*-----------------------------------------------------------------*/
1070 /* no special considerations for the following
1071 data, idata & bit & xdata */
1072 emitRegularMap (data, TRUE, TRUE);
1073 emitRegularMap (idata, TRUE, TRUE);
1074 emitRegularMap (bit, TRUE, FALSE);
1075 emitRegularMap (xdata, TRUE, TRUE);
1076 emitRegularMap (sfr, FALSE, FALSE);
1077 emitRegularMap (sfrbit, FALSE, FALSE);
1078 emitRegularMap (home, TRUE, FALSE);
1079 emitRegularMap (code, TRUE, FALSE);
1081 emitStaticSeg (statsg, code->oFile);
1085 /*-----------------------------------------------------------------*/
1086 /* flushStatics - flush all currently defined statics out to file */
1087 /* and delete. Temporary function */
1088 /*-----------------------------------------------------------------*/
1092 emitStaticSeg (statsg, codeOutFile);
1093 statsg->syms = NULL;
1096 /*-----------------------------------------------------------------*/
1097 /* createInterruptVect - creates the interrupt vector */
1098 /*-----------------------------------------------------------------*/
1100 createInterruptVect (FILE * vFile)
1103 mainf = newSymbol ("main", 0);
1106 /* only if the main function exists */
1107 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1109 if (!options.cc_only && !noAssemble)
1114 /* if the main is only a prototype ie. no body then do nothing */
1115 if (!IFFUNC_HASBODY(mainf->type))
1117 /* if ! compile only then main function should be present */
1118 if (!options.cc_only && !noAssemble)
1123 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1124 fprintf (vFile, "__interrupt_vect:\n");
1127 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1129 /* "generic" interrupt table header (if port doesn't specify one).
1131 * Look suspiciously like 8051 code to me...
1134 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1137 /* now for the other interrupts */
1138 for (; i < maxInterrupts; i++)
1141 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1143 fprintf (vFile, "\treti\n\t.ds\t7\n");
1150 ";--------------------------------------------------------\n"
1151 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1155 ";--------------------------------------------------------\n"};
1158 /*-----------------------------------------------------------------*/
1159 /* initialComments - puts in some initial comments */
1160 /*-----------------------------------------------------------------*/
1162 initialComments (FILE * afile)
1166 fprintf (afile, "%s", iComments1);
1167 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1168 fprintf (afile, "%s", iComments2);
1171 /*-----------------------------------------------------------------*/
1172 /* printPublics - generates .global for publics */
1173 /*-----------------------------------------------------------------*/
1175 printPublics (FILE * afile)
1179 fprintf (afile, "%s", iComments2);
1180 fprintf (afile, "; Public variables in this module\n");
1181 fprintf (afile, "%s", iComments2);
1183 for (sym = setFirstItem (publics); sym;
1184 sym = setNextItem (publics))
1185 tfprintf (afile, "\t!global\n", sym->rname);
1188 /*-----------------------------------------------------------------*/
1189 /* printExterns - generates .global for externs */
1190 /*-----------------------------------------------------------------*/
1192 printExterns (FILE * afile)
1196 fprintf (afile, "%s", iComments2);
1197 fprintf (afile, "; Externals used\n");
1198 fprintf (afile, "%s", iComments2);
1200 for (sym = setFirstItem (externs); sym;
1201 sym = setNextItem (externs))
1202 tfprintf (afile, "\t!global\n", sym->rname);
1205 /*-----------------------------------------------------------------*/
1206 /* emitOverlay - will emit code for the overlay stuff */
1207 /*-----------------------------------------------------------------*/
1209 emitOverlay (FILE * afile)
1213 if (!elementsInSet (ovrSetSets))
1214 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1216 /* for each of the sets in the overlay segment do */
1217 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1218 ovrset = setNextItem (ovrSetSets))
1223 if (elementsInSet (ovrset))
1225 /* this dummy area is used to fool the assembler
1226 otherwise the assembler will append each of these
1227 declarations into one chunk and will not overlay
1229 fprintf (afile, "\t.area _DUMMY\n");
1230 /* output the area informtion */
1231 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1234 for (sym = setFirstItem (ovrset); sym;
1235 sym = setNextItem (ovrset))
1238 /* if extern then add it to the publics tabledo nothing */
1239 if (IS_EXTERN (sym->etype))
1242 /* if allocation required check is needed
1243 then check if the symbol really requires
1244 allocation only for local variables */
1245 if (!IS_AGGREGATE (sym->type) &&
1246 !(sym->_isparm && !IS_REGPARM (sym->etype))
1247 && !sym->allocreq && sym->level)
1250 /* if global variable & not static or extern
1251 and addPublics allowed then add it to the public set */
1252 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1253 && !IS_STATIC (sym->etype))
1254 addSetHead (&publics, sym);
1256 /* if extern then do nothing or is a function
1258 if (IS_FUNC (sym->type))
1261 /* print extra debug info if required */
1264 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1268 if (IS_STATIC (sym->etype))
1269 fprintf (afile, "F%s$", moduleName); /* scope is file */
1271 fprintf (afile, "G$"); /* scope is global */
1274 /* symbol is local */
1275 fprintf (afile, "L%s$",
1276 (sym->localof ? sym->localof->name : "-null-"));
1277 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1280 /* if is has an absolute address then generate
1281 an equate for this no need to allocate space */
1282 if (SPEC_ABSA (sym->etype))
1286 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1288 fprintf (afile, "%s\t=\t0x%04x\n",
1290 SPEC_ADDR (sym->etype));
1295 fprintf (afile, "==.\n");
1297 /* allocate space */
1298 tfprintf (afile, "!labeldef\n", sym->rname);
1299 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1306 /*-----------------------------------------------------------------*/
1307 /* glue - the final glue that hold the whole thing together */
1308 /*-----------------------------------------------------------------*/
1314 FILE *ovrFile = tempfile ();
1316 addSetHead (&tmpfileSet, ovrFile);
1317 /* print the global struct definitions */
1319 cdbStructBlock (0, cdbFile);
1321 vFile = tempfile ();
1322 /* PENDING: this isnt the best place but it will do */
1323 if (port->general.glue_up_main)
1325 /* create the interrupt vector table */
1326 createInterruptVect (vFile);
1329 addSetHead (&tmpfileSet, vFile);
1331 /* emit code for the all the variables declared */
1333 /* do the overlay segments */
1334 emitOverlay (ovrFile);
1336 /* now put it all together into the assembler file */
1337 /* create the assembler file name */
1339 if (!options.c1mode)
1341 sprintf (scratchFileName, srcFileName);
1342 strcat (scratchFileName, port->assembler.file_ext);
1346 strcpy (scratchFileName, options.out_name);
1349 if (!(asmFile = fopen (scratchFileName, "w")))
1351 werror (E_FILE_OPEN_ERR, scratchFileName);
1355 /* initial comments */
1356 initialComments (asmFile);
1358 /* print module name */
1359 tfprintf (asmFile, "\t!module\n", moduleName);
1360 tfprintf (asmFile, "\t!fileprelude\n");
1362 /* Let the port generate any global directives, etc. */
1363 if (port->genAssemblerPreamble)
1365 port->genAssemblerPreamble (asmFile);
1368 /* print the global variables in this module */
1369 printPublics (asmFile);
1370 if (port->assembler.externGlobal)
1371 printExterns (asmFile);
1373 /* copy the sfr segment */
1374 fprintf (asmFile, "%s", iComments2);
1375 fprintf (asmFile, "; special function registers\n");
1376 fprintf (asmFile, "%s", iComments2);
1377 copyFile (asmFile, sfr->oFile);
1379 /* copy the sbit segment */
1380 fprintf (asmFile, "%s", iComments2);
1381 fprintf (asmFile, "; special function bits \n");
1382 fprintf (asmFile, "%s", iComments2);
1383 copyFile (asmFile, sfrbit->oFile);
1385 /* copy the data segment */
1386 fprintf (asmFile, "%s", iComments2);
1387 fprintf (asmFile, "; internal ram data\n");
1388 fprintf (asmFile, "%s", iComments2);
1389 copyFile (asmFile, data->oFile);
1392 /* create the overlay segments */
1393 fprintf (asmFile, "%s", iComments2);
1394 fprintf (asmFile, "; overlayable items in internal ram \n");
1395 fprintf (asmFile, "%s", iComments2);
1396 copyFile (asmFile, ovrFile);
1398 /* create the stack segment MOF */
1399 if (mainf && IFFUNC_HASBODY(mainf->type))
1401 fprintf (asmFile, "%s", iComments2);
1402 fprintf (asmFile, "; Stack segment in internal ram \n");
1403 fprintf (asmFile, "%s", iComments2);
1404 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1405 "__start__stack:\n\t.ds\t1\n\n");
1408 /* create the idata segment */
1409 fprintf (asmFile, "%s", iComments2);
1410 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1411 fprintf (asmFile, "%s", iComments2);
1412 copyFile (asmFile, idata->oFile);
1414 /* copy the bit segment */
1415 fprintf (asmFile, "%s", iComments2);
1416 fprintf (asmFile, "; bit data\n");
1417 fprintf (asmFile, "%s", iComments2);
1418 copyFile (asmFile, bit->oFile);
1420 /* if external stack then reserve space of it */
1421 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1423 fprintf (asmFile, "%s", iComments2);
1424 fprintf (asmFile, "; external stack \n");
1425 fprintf (asmFile, "%s", iComments2);
1426 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1427 fprintf (asmFile, "\t.ds 256\n");
1431 /* copy xtern ram data */
1432 fprintf (asmFile, "%s", iComments2);
1433 fprintf (asmFile, "; external ram data\n");
1434 fprintf (asmFile, "%s", iComments2);
1435 copyFile (asmFile, xdata->oFile);
1437 /* copy the interrupt vector table */
1438 if (mainf && IFFUNC_HASBODY(mainf->type))
1440 fprintf (asmFile, "%s", iComments2);
1441 fprintf (asmFile, "; interrupt vector \n");
1442 fprintf (asmFile, "%s", iComments2);
1443 copyFile (asmFile, vFile);
1446 /* copy global & static initialisations */
1447 fprintf (asmFile, "%s", iComments2);
1448 fprintf (asmFile, "; global & static initialisations\n");
1449 fprintf (asmFile, "%s", iComments2);
1451 /* Everywhere we generate a reference to the static_name area,
1452 * (which is currently only here), we immediately follow it with a
1453 * definition of the post_static_name area. This guarantees that
1454 * the post_static_name area will immediately follow the static_name
1457 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1458 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1459 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1461 if (mainf && IFFUNC_HASBODY(mainf->type))
1463 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1464 /* if external stack is specified then the
1465 higher order byte of the xdatalocation is
1466 going into P2 and the lower order going into
1468 if (options.useXstack)
1470 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1471 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1472 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1473 (unsigned int) options.xdata_loc & 0xff);
1476 /* initialise the stack pointer */
1477 /* if the user specified a value then use it */
1478 if (options.stack_loc)
1479 fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc);
1481 /* no: we have to compute it */
1482 if (!options.stackOnData && maxRegBank <= 3)
1483 fprintf (asmFile, "\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1);
1485 fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */
1487 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1488 fprintf (asmFile, "\tmov\ta,dpl\n");
1489 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1490 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1491 fprintf (asmFile, "__sdcc_init_data:\n");
1494 copyFile (asmFile, statsg->oFile);
1496 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1498 /* This code is generated in the post-static area.
1499 * This area is guaranteed to follow the static area
1500 * by the ugly shucking and jiving about 20 lines ago.
1502 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1503 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1509 "%s", iComments2, iComments2);
1510 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1511 copyFile (asmFile, home->oFile);
1513 /* copy over code */
1514 fprintf (asmFile, "%s", iComments2);
1515 fprintf (asmFile, "; code\n");
1516 fprintf (asmFile, "%s", iComments2);
1517 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1518 if (mainf && IFFUNC_HASBODY(mainf->type))
1521 /* entry point @ start of CSEG */
1522 fprintf (asmFile, "__sdcc_program_startup:\n");
1524 /* put in the call to main */
1525 fprintf (asmFile, "\tlcall\t_main\n");
1526 if (options.mainreturn)
1529 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1530 fprintf (asmFile, "\tret\n");
1536 fprintf (asmFile, ";\treturn from main will lock up\n");
1537 fprintf (asmFile, "\tsjmp .\n");
1540 copyFile (asmFile, code->oFile);
1543 applyToSet (tmpfileSet, closeTmpFiles);
1544 applyToSet (tmpfileNameSet, rmTmpFiles);
1547 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1551 applyToSet (tmpfileSet, closeTmpFiles);
1552 applyToSet (tmpfileNameSet, rmTmpFiles);
1556 /** Creates a temporary file name a'la tmpnam which avoids the bugs
1557 in cygwin wrt c:\tmp.
1558 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1563 #if !defined(_MSC_VER)
1564 const char *tmpdir = NULL;
1566 tmpdir = getenv ("TMP");
1567 else if (getenv ("TEMP"))
1568 tmpdir = getenv ("TEMP");
1569 else if (getenv ("TMPDIR"))
1570 tmpdir = getenv ("TMPDIR");
1573 char *name = tempnam (tmpdir, "sdcc");
1580 return tmpnam (NULL);
1583 /** Creates a temporary file a'la tmpfile which avoids the bugs
1584 in cygwin wrt c:\tmp.
1585 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1590 #if !defined(_MSC_VER)
1591 const char *tmpdir = NULL;
1593 tmpdir = getenv ("TMP");
1594 else if (getenv ("TEMP"))
1595 tmpdir = getenv ("TEMP");
1596 else if (getenv ("TMPDIR"))
1597 tmpdir = getenv ("TMPDIR");
1600 char *name = Safe_strdup( tempnam (tmpdir, "sdcc"));
1603 FILE *fp = fopen (name, "w+b");
1606 addSetHead (&tmpfileNameSet, name);