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)
165 /* PENDING: special case here - should remove */
166 if (!strcmp (map->sname, CODE_NAME))
167 tfprintf (map->oFile, "\t!areacode\n", map->sname);
168 else if (!strcmp (map->sname, DATA_NAME))
169 tfprintf (map->oFile, "\t!areadata\n", map->sname);
170 else if (!strcmp (map->sname, HOME_NAME))
171 tfprintf (map->oFile, "\t!areahome\n", map->sname);
173 tfprintf (map->oFile, "\t!area\n", map->sname);
176 for (sym = setFirstItem (map->syms); sym;
177 sym = setNextItem (map->syms))
181 /* if extern then add it into the extern list */
182 if (IS_EXTERN (sym->etype))
184 addSetHead (&externs, sym);
188 /* if allocation required check is needed
189 then check if the symbol really requires
190 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 /* for bitvar locals and parameters */
198 if (!arFlag && !sym->allocreq && sym->level
199 && !SPEC_ABSA (sym->etype)) {
203 /* if global variable & not static or extern
204 and addPublics allowed then add it to the public set */
205 if ((sym->level == 0 ||
206 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
208 !IS_STATIC (sym->etype) &&
209 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
211 addSetHead (&publics, sym);
214 /* if extern then do nothing or is a function
216 if (IS_FUNC (sym->type))
219 /* print extra debug info if required */
221 cdbSymbol (sym, cdbFile, FALSE, FALSE);
222 if (!sym->level) /* global */
223 if (IS_STATIC (sym->etype))
224 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
226 fprintf (map->oFile, "G$"); /* scope is global */
228 /* symbol is local */
229 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
230 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
233 /* if it has an initial value then do it only if
234 it is a global variable */
235 if (sym->ival && sym->level == 0) {
236 if (SPEC_OCLS(sym->etype)==xidata) {
237 // create a new "XINIT (CODE)" symbol, that will be emitted later
238 newSym=copySymbol (sym);
239 SPEC_OCLS(newSym->etype)=xinit;
240 sprintf (newSym->name, "__xinit_%s", sym->name);
241 sprintf (newSym->rname,"__xinit_%s", sym->rname);
242 SPEC_CONST(newSym->etype)=1;
243 SPEC_STAT(newSym->etype)=1;
244 resolveIvalSym(newSym->ival);
246 // add it to the "XINIT (CODE)" segment
247 addSet(&xinit->syms, newSym);
250 if (IS_AGGREGATE (sym->type)) {
251 ival = initAggregates (sym, sym->ival, NULL);
253 if (getNelements(sym->type, sym->ival)>1) {
254 werror (W_EXCESS_INITIALIZERS, "scalar",
255 sym->name, sym->lineDef);
257 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
258 decorateType (resolveSymbols (list2expr (sym->ival))));
260 codeOutFile = statsg->oFile;
263 // set ival's lineno to where the symbol was defined
264 setAstLineno (ival, lineno=sym->lineDef);
265 // check if this is not a constant expression
266 if (!constExprTree(ival)) {
267 werror (E_CONST_EXPECTED, "found expression");
268 // but try to do it anyway
271 eBBlockFromiCode (iCodeFromAst (ival));
278 /* if is has an absolute address then generate
279 an equate for this no need to allocate space */
280 if (SPEC_ABSA (sym->etype))
284 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
286 if (TARGET_IS_XA51) {
289 } else if (map==bit || map==sfrbit) {
293 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
295 SPEC_ADDR (sym->etype));
298 int size = getSize (sym->type);
300 werror(E_UNKNOWN_SIZE,sym->name);
304 fprintf (map->oFile, "==.\n");
306 if (IS_STATIC (sym->etype))
307 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
309 tfprintf (map->oFile, "!labeldef\n", sym->rname);
310 tfprintf (map->oFile, "\t!ds\n",
311 (unsigned int) size & 0xffff);
316 /*-----------------------------------------------------------------*/
317 /* initPointer - pointer initialization code massaging */
318 /*-----------------------------------------------------------------*/
320 initPointer (initList * ilist)
323 ast *expr = list2expr (ilist);
328 /* try it the oldway first */
329 if ((val = constExprValue (expr, FALSE)))
332 /* no then we have to do these cludgy checks */
333 /* pointers can be initialized with address of
334 a variable or address of an array element */
335 if (IS_AST_OP (expr) && expr->opval.op == '&') {
336 /* address of symbol */
337 if (IS_AST_SYM_VALUE (expr->left)) {
338 val = copyValue (AST_VALUE (expr->left));
339 val->type = newLink ();
340 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
341 DCL_TYPE (val->type) = CPOINTER;
342 DCL_PTR_CONST (val->type) = port->mem.code_ro;
344 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
345 DCL_TYPE (val->type) = FPOINTER;
346 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
347 DCL_TYPE (val->type) = PPOINTER;
348 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
349 DCL_TYPE (val->type) = IPOINTER;
350 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
351 DCL_TYPE (val->type) = EEPPOINTER;
353 DCL_TYPE (val->type) = POINTER;
354 val->type->next = expr->left->ftype;
355 val->etype = getSpec (val->type);
359 /* if address of indexed array */
360 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
361 return valForArray (expr->left);
363 /* if address of structure element then
365 if (IS_AST_OP (expr->left) &&
366 expr->left->opval.op == '.') {
367 return valForStructElem (expr->left->left,
372 (&some_struct)->element */
373 if (IS_AST_OP (expr->left) &&
374 expr->left->opval.op == PTR_OP &&
375 IS_ADDRESS_OF_OP (expr->left->left)) {
376 return valForStructElem (expr->left->left->left,
380 /* case 3. (((char *) &a) +/- constant) */
381 if (IS_AST_OP (expr) &&
382 (expr->opval.op == '+' || expr->opval.op == '-') &&
383 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
384 IS_AST_OP (expr->left->right) &&
385 expr->left->right->opval.op == '&' &&
386 IS_AST_LIT_VALUE (expr->right)) {
388 return valForCastAggr (expr->left->right->left,
389 expr->left->left->opval.lnk,
390 expr->right, expr->opval.op);
394 /* case 4. (char *)(array type) */
395 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
396 IS_ARRAY(expr->right->ftype)) {
398 val = copyValue (AST_VALUE (expr->right));
399 val->type = newLink ();
400 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
401 DCL_TYPE (val->type) = CPOINTER;
402 DCL_PTR_CONST (val->type) = port->mem.code_ro;
404 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
405 DCL_TYPE (val->type) = FPOINTER;
406 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
407 DCL_TYPE (val->type) = PPOINTER;
408 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
409 DCL_TYPE (val->type) = IPOINTER;
410 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
411 DCL_TYPE (val->type) = EEPPOINTER;
413 DCL_TYPE (val->type) = POINTER;
414 val->type->next = expr->right->ftype->next;
415 val->etype = getSpec (val->type);
419 werror (W_INIT_WRONG);
424 /*-----------------------------------------------------------------*/
425 /* printChar - formats and prints a characater string with DB */
426 /*-----------------------------------------------------------------*/
428 printChar (FILE * ofile, char *s, int plen)
431 int len = strlen (s);
436 while (len && pplen < plen)
439 while (i && *s && pplen < plen)
441 if (*s < ' ' || *s == '\"' || *s=='\\')
445 tfprintf (ofile, "\t!ascii\n", buf);
446 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
461 tfprintf (ofile, "\t!ascii\n", buf);
470 tfprintf (ofile, "\t!db !constbyte\n", 0);
473 /*-----------------------------------------------------------------*/
474 /* return the generic pointer high byte for a given pointer type. */
475 /*-----------------------------------------------------------------*/
477 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
485 /* hack - if we get a generic pointer, we just assume
486 * it's an FPOINTER (i.e. in XDATA space).
488 werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname);
498 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
506 /*-----------------------------------------------------------------*/
507 /* printPointerType - generates ival for pointer type */
508 /*-----------------------------------------------------------------*/
510 _printPointerType (FILE * oFile, const char *name)
512 /* if (TARGET_IS_DS390) */
513 if (options.model == MODEL_FLAT24)
515 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
519 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
523 /*-----------------------------------------------------------------*/
524 /* printPointerType - generates ival for pointer type */
525 /*-----------------------------------------------------------------*/
527 printPointerType (FILE * oFile, const char *name)
529 _printPointerType (oFile, name);
530 fprintf (oFile, "\n");
533 /*-----------------------------------------------------------------*/
534 /* printGPointerType - generates ival for generic pointer type */
535 /*-----------------------------------------------------------------*/
537 printGPointerType (FILE * oFile, const char *iname, const char *oname,
538 const unsigned int type)
540 _printPointerType (oFile, iname);
541 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
544 /*-----------------------------------------------------------------*/
545 /* printIvalType - generates ival for int/char */
546 /*-----------------------------------------------------------------*/
548 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
552 /* if initList is deep */
553 if (ilist->type == INIT_DEEP)
554 ilist = ilist->init.deep;
556 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
557 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
560 if (!(val = list2val (ilist))) {
561 // assuming a warning has been thrown
565 if (val->type != type) {
566 val = valCastLiteral(type, floatFromVal(val));
569 switch (getSize (type)) {
572 tfprintf (oFile, "\t!db !constbyte\n", 0);
574 tfprintf (oFile, "\t!dbs\n",
575 aopLiteral (val, 0));
579 if (port->use_dw_for_init)
580 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
582 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
586 tfprintf (oFile, "\t!dw !constword\n", 0);
587 tfprintf (oFile, "\t!dw !constword\n", 0);
590 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
591 aopLiteral (val, 0), aopLiteral (val, 1),
592 aopLiteral (val, 2), aopLiteral (val, 3));
598 /*-----------------------------------------------------------------*/
599 /* printIvalBitFields - generate initializer for bitfields */
600 /*-----------------------------------------------------------------*/
601 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
605 initList *lilist = *ilist ;
606 unsigned long ival = 0;
612 val = list2val(lilist);
614 if (SPEC_BLEN(lsym->etype) > 8) {
615 size += ((SPEC_BLEN (lsym->etype) / 8) +
616 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
619 size = ((SPEC_BLEN (lsym->etype) / 8) +
620 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
622 i = (unsigned long)floatFromVal(val);
623 i <<= SPEC_BSTR (lsym->etype);
625 if (! ( lsym->next &&
626 (IS_BITFIELD(lsym->next->type)) &&
627 (SPEC_BSTR(lsym->next->etype)))) break;
629 lilist = lilist->next;
633 tfprintf (oFile, "\t!db !constbyte\n",ival);
637 tfprintf (oFile, "\t!dw !constword\n",ival);
640 tfprintf (oFile, "\t!db !constword,!constword\n",
641 (ival >> 8) & 0xffff, (ival & 0xffff));
648 /*-----------------------------------------------------------------*/
649 /* printIvalStruct - generates initial value for structures */
650 /*-----------------------------------------------------------------*/
652 printIvalStruct (symbol * sym, sym_link * type,
653 initList * ilist, FILE * oFile)
658 sflds = SPEC_STRUCT (type)->fields;
659 if (ilist->type != INIT_DEEP) {
660 werror (E_INIT_STRUCT, sym->name);
664 iloop = ilist->init.deep;
666 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
667 if (IS_BITFIELD(sflds->type)) {
668 printIvalBitFields(&sflds,&iloop,oFile);
670 printIval (sym, sflds->type, iloop, oFile);
674 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
679 /*-----------------------------------------------------------------*/
680 /* printIvalChar - generates initital value for character array */
681 /*-----------------------------------------------------------------*/
683 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
691 val = list2val (ilist);
692 /* if the value is a character string */
693 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
695 if (!DCL_ELEM (type))
696 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
698 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
700 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
702 tfprintf (oFile, "\t!db !constbyte\n", 0);
710 printChar (oFile, s, strlen (s) + 1);
714 /*-----------------------------------------------------------------*/
715 /* printIvalArray - generates code for array initialization */
716 /*-----------------------------------------------------------------*/
718 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
722 int lcnt = 0, size = 0;
724 /* take care of the special case */
725 /* array of characters can be init */
727 if (IS_CHAR (type->next)) {
728 if (!IS_LITERAL(list2val(ilist)->etype)) {
729 werror (W_INIT_WRONG);
732 if (printIvalChar (type,
733 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
734 oFile, SPEC_CVAL (sym->etype).v_char))
737 /* not the special case */
738 if (ilist->type != INIT_DEEP)
740 werror (E_INIT_STRUCT, sym->name);
744 iloop = ilist->init.deep;
745 lcnt = DCL_ELEM (type);
750 printIval (sym, type->next, iloop, oFile);
751 iloop = (iloop ? iloop->next : NULL);
754 /* if not array limits given & we */
755 /* are out of initialisers then */
756 if (!DCL_ELEM (type) && !iloop)
759 /* no of elements given and we */
760 /* have generated for all of them */
762 /* if initializers left */
764 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
770 /* if we have not been given a size */
771 if (!DCL_ELEM (type))
772 DCL_ELEM (type) = size;
777 /*-----------------------------------------------------------------*/
778 /* printIvalFuncPtr - generate initial value for function pointers */
779 /*-----------------------------------------------------------------*/
781 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
786 val = list2val (ilist);
788 if (IS_LITERAL(val->etype)) {
789 if (compareType(type,val->etype)==0) {
790 werror (E_INCOMPAT_TYPES);
791 printFromToType (val->type, type);
793 printIvalCharPtr (NULL, type, val, oFile);
797 /* check the types */
798 if ((dLvl = compareType (val->type, type->next)) <= 0)
800 tfprintf (oFile, "\t!dw !constword\n", 0);
804 /* now generate the name */
807 if (port->use_dw_for_init)
809 tfprintf (oFile, "\t!dws\n", val->name);
813 printPointerType (oFile, val->name);
816 else if (port->use_dw_for_init)
818 tfprintf (oFile, "\t!dws\n", val->sym->rname);
822 printPointerType (oFile, val->sym->rname);
828 /*-----------------------------------------------------------------*/
829 /* printIvalCharPtr - generates initial values for character pointers */
830 /*-----------------------------------------------------------------*/
832 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
836 /* PENDING: this is _very_ mcs51 specific, including a magic
838 It's also endin specific.
840 size = getSize (type);
842 if (val->name && strlen (val->name))
844 if (size == 1) /* This appears to be Z80 specific?? */
847 "\t!dbs\n", val->name);
849 else if (size == FPTRSIZE)
851 if (port->use_dw_for_init)
853 tfprintf (oFile, "\t!dws\n", val->name);
857 printPointerType (oFile, val->name);
860 else if (size == GPTRSIZE)
863 if (IS_PTR (val->type)) {
864 type = DCL_TYPE (val->type);
866 type = PTR_TYPE (SPEC_OCLS (val->etype));
868 if (val->sym && val->sym->isstrlit) {
869 // this is a literal string
872 printGPointerType (oFile, val->name, sym->name, type);
876 fprintf (stderr, "*** internal error: unknown size in "
877 "printIvalCharPtr.\n");
882 // these are literals assigned to pointers
886 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
889 if (port->use_dw_for_init)
890 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
892 tfprintf (oFile, "\t.byte %s,%s\n",
893 aopLiteral (val, 0), aopLiteral (val, 1));
896 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
897 // non-zero mcs51 generic pointer
898 werror (E_LITERAL_GENERIC);
900 fprintf (oFile, "\t.byte %s,%s,%s\n",
903 aopLiteral (val, 2));
906 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
907 // non-zero ds390 generic pointer
908 werror (E_LITERAL_GENERIC);
910 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
914 aopLiteral (val, 3));
921 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
922 addSet (&statsg->syms, val->sym);
928 /*-----------------------------------------------------------------*/
929 /* printIvalPtr - generates initial value for pointers */
930 /*-----------------------------------------------------------------*/
932 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
938 if (ilist->type == INIT_DEEP)
939 ilist = ilist->init.deep;
941 /* function pointer */
942 if (IS_FUNC (type->next))
944 printIvalFuncPtr (type, ilist, oFile);
948 if (!(val = initPointer (ilist)))
951 /* if character pointer */
952 if (IS_CHAR (type->next))
953 if (printIvalCharPtr (sym, type, val, oFile))
957 if (compareType (type, val->type) == 0)
958 werror (W_INIT_WRONG);
960 /* if val is literal */
961 if (IS_LITERAL (val->etype))
963 switch (getSize (type))
966 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
969 if (port->use_dw_for_init)
970 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
972 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
975 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
976 aopLiteral (val, 0), aopLiteral (val, 1));
982 size = getSize (type);
984 if (size == 1) /* Z80 specific?? */
986 tfprintf (oFile, "\t!dbs\n", val->name);
988 else if (size == FPTRSIZE)
990 if (port->use_dw_for_init) {
991 tfprintf (oFile, "\t!dws\n", val->name);
993 printPointerType (oFile, val->name);
996 else if (size == GPTRSIZE)
998 printGPointerType (oFile, val->name, sym->name,
999 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1000 PTR_TYPE (SPEC_OCLS (val->etype))));
1005 /*-----------------------------------------------------------------*/
1006 /* printIval - generates code for initial value */
1007 /*-----------------------------------------------------------------*/
1009 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1014 /* if structure then */
1015 if (IS_STRUCT (type))
1017 printIvalStruct (sym, type, ilist, oFile);
1021 /* if this is a pointer */
1024 printIvalPtr (sym, type, ilist, oFile);
1028 /* if this is an array */
1029 if (IS_ARRAY (type))
1031 printIvalArray (sym, type, ilist, oFile);
1035 /* if type is SPECIFIER */
1038 printIvalType (sym, type, ilist, oFile);
1043 /*-----------------------------------------------------------------*/
1044 /* emitStaticSeg - emitcode for the static segment */
1045 /*-----------------------------------------------------------------*/
1047 emitStaticSeg (memmap * map, FILE * out)
1051 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1053 /* for all variables in this segment do */
1054 for (sym = setFirstItem (map->syms); sym;
1055 sym = setNextItem (map->syms))
1058 /* if it is "extern" then do nothing */
1059 if (IS_EXTERN (sym->etype))
1062 /* if it is not static add it to the public
1064 if (!IS_STATIC (sym->etype))
1066 addSetHead (&publics, sym);
1069 /* print extra debug info if required */
1070 if (options.debug) {
1071 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1074 if (IS_STATIC (sym->etype))
1075 fprintf (out, "F%s$", moduleName); /* scope is file */
1077 fprintf (out, "G$"); /* scope is global */
1080 /* symbol is local */
1081 fprintf (out, "L%s$",
1082 (sym->localof ? sym->localof->name : "-null-"));
1083 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1086 /* if it has an absolute address */
1087 if (SPEC_ABSA (sym->etype))
1090 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1092 fprintf (out, "%s\t=\t0x%04x\n",
1094 SPEC_ADDR (sym->etype));
1099 fprintf (out, " == .\n");
1101 /* if it has an initial value */
1104 fprintf (out, "%s:\n", sym->rname);
1106 resolveIvalSym (sym->ival);
1107 printIval (sym, sym->type, sym->ival, out);
1111 /* allocate space */
1112 int size = getSize (sym->type);
1115 werror(E_UNKNOWN_SIZE,sym->name);
1117 fprintf (out, "%s:\n", sym->rname);
1118 /* special case for character strings */
1119 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1120 SPEC_CVAL (sym->etype).v_char)
1122 SPEC_CVAL (sym->etype).v_char,
1123 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1125 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1131 /*-----------------------------------------------------------------*/
1132 /* emitMaps - emits the code for the data portion the code */
1133 /*-----------------------------------------------------------------*/
1138 /* no special considerations for the following
1139 data, idata & bit & xdata */
1140 emitRegularMap (data, TRUE, TRUE);
1141 emitRegularMap (idata, TRUE, TRUE);
1142 emitRegularMap (bit, TRUE, FALSE);
1143 emitRegularMap (xdata, TRUE, TRUE);
1144 if (port->genXINIT) {
1145 emitRegularMap (xidata, TRUE, TRUE);
1147 emitRegularMap (sfr, FALSE, FALSE);
1148 emitRegularMap (sfrbit, FALSE, FALSE);
1149 emitRegularMap (home, TRUE, FALSE);
1150 emitRegularMap (code, TRUE, FALSE);
1152 emitStaticSeg (statsg, code->oFile);
1153 if (port->genXINIT) {
1154 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1155 emitStaticSeg (xinit, code->oFile);
1160 /*-----------------------------------------------------------------*/
1161 /* flushStatics - flush all currently defined statics out to file */
1162 /* and delete. Temporary function */
1163 /*-----------------------------------------------------------------*/
1167 emitStaticSeg (statsg, codeOutFile);
1168 statsg->syms = NULL;
1171 /*-----------------------------------------------------------------*/
1172 /* createInterruptVect - creates the interrupt vector */
1173 /*-----------------------------------------------------------------*/
1175 createInterruptVect (FILE * vFile)
1178 mainf = newSymbol ("main", 0);
1181 /* only if the main function exists */
1182 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1184 if (!options.cc_only && !noAssemble)
1189 /* if the main is only a prototype ie. no body then do nothing */
1190 if (!IFFUNC_HASBODY(mainf->type))
1192 /* if ! compile only then main function should be present */
1193 if (!options.cc_only && !noAssemble)
1198 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1199 fprintf (vFile, "__interrupt_vect:\n");
1202 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1204 /* "generic" interrupt table header (if port doesn't specify one).
1205 * Look suspiciously like 8051 code to me...
1208 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1211 /* now for the other interrupts */
1212 for (; i < maxInterrupts; i++)
1215 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1217 fprintf (vFile, "\treti\n\t.ds\t7\n");
1224 ";--------------------------------------------------------\n"
1225 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1229 ";--------------------------------------------------------\n"};
1232 /*-----------------------------------------------------------------*/
1233 /* initialComments - puts in some initial comments */
1234 /*-----------------------------------------------------------------*/
1236 initialComments (FILE * afile)
1240 fprintf (afile, "%s", iComments1);
1241 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1242 fprintf (afile, "%s", iComments2);
1245 /*-----------------------------------------------------------------*/
1246 /* printPublics - generates .global for publics */
1247 /*-----------------------------------------------------------------*/
1249 printPublics (FILE * afile)
1253 fprintf (afile, "%s", iComments2);
1254 fprintf (afile, "; Public variables in this module\n");
1255 fprintf (afile, "%s", iComments2);
1257 for (sym = setFirstItem (publics); sym;
1258 sym = setNextItem (publics))
1259 tfprintf (afile, "\t!global\n", sym->rname);
1262 /*-----------------------------------------------------------------*/
1263 /* printExterns - generates .global for externs */
1264 /*-----------------------------------------------------------------*/
1266 printExterns (FILE * afile)
1270 fprintf (afile, "%s", iComments2);
1271 fprintf (afile, "; Externals used\n");
1272 fprintf (afile, "%s", iComments2);
1274 for (sym = setFirstItem (externs); sym;
1275 sym = setNextItem (externs))
1276 tfprintf (afile, "\t!extern\n", sym->rname);
1279 /*-----------------------------------------------------------------*/
1280 /* emitOverlay - will emit code for the overlay stuff */
1281 /*-----------------------------------------------------------------*/
1283 emitOverlay (FILE * afile)
1287 if (!elementsInSet (ovrSetSets))
1288 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1290 /* for each of the sets in the overlay segment do */
1291 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1292 ovrset = setNextItem (ovrSetSets))
1297 if (elementsInSet (ovrset))
1299 /* output the area informtion */
1300 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1303 for (sym = setFirstItem (ovrset); sym;
1304 sym = setNextItem (ovrset))
1306 /* if extern then it is in the publics table: do nothing */
1307 if (IS_EXTERN (sym->etype))
1310 /* if allocation required check is needed
1311 then check if the symbol really requires
1312 allocation only for local variables */
1313 if (!IS_AGGREGATE (sym->type) &&
1314 !(sym->_isparm && !IS_REGPARM (sym->etype))
1315 && !sym->allocreq && sym->level)
1318 /* if global variable & not static or extern
1319 and addPublics allowed then add it to the public set */
1320 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1321 && !IS_STATIC (sym->etype))
1323 addSetHead (&publics, sym);
1326 /* if extern then do nothing or is a function
1328 if (IS_FUNC (sym->type))
1331 /* print extra debug info if required */
1334 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1338 if (IS_STATIC (sym->etype))
1339 fprintf (afile, "F%s$", moduleName); /* scope is file */
1341 fprintf (afile, "G$"); /* scope is global */
1344 /* symbol is local */
1345 fprintf (afile, "L%s$",
1346 (sym->localof ? sym->localof->name : "-null-"));
1347 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1350 /* if is has an absolute address then generate
1351 an equate for this no need to allocate space */
1352 if (SPEC_ABSA (sym->etype))
1356 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1358 fprintf (afile, "%s\t=\t0x%04x\n",
1360 SPEC_ADDR (sym->etype));
1363 int size = getSize(sym->type);
1366 werror(E_UNKNOWN_SIZE,sym->name);
1369 fprintf (afile, "==.\n");
1371 /* allocate space */
1372 tfprintf (afile, "!labeldef\n", sym->rname);
1373 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1380 /*-----------------------------------------------------------------*/
1381 /* glue - the final glue that hold the whole thing together */
1382 /*-----------------------------------------------------------------*/
1388 FILE *ovrFile = tempfile ();
1390 addSetHead (&tmpfileSet, ovrFile);
1391 /* print the global struct definitions */
1393 cdbStructBlock (0, cdbFile);
1395 vFile = tempfile ();
1396 /* PENDING: this isnt the best place but it will do */
1397 if (port->general.glue_up_main)
1399 /* create the interrupt vector table */
1400 createInterruptVect (vFile);
1403 addSetHead (&tmpfileSet, vFile);
1405 /* emit code for the all the variables declared */
1407 /* do the overlay segments */
1408 emitOverlay (ovrFile);
1410 /* now put it all together into the assembler file */
1411 /* create the assembler file name */
1413 if (!options.c1mode)
1415 sprintf (scratchFileName, srcFileName);
1416 strcat (scratchFileName, port->assembler.file_ext);
1420 strcpy (scratchFileName, options.out_name);
1423 if (!(asmFile = fopen (scratchFileName, "w")))
1425 werror (E_FILE_OPEN_ERR, scratchFileName);
1429 /* initial comments */
1430 initialComments (asmFile);
1432 /* print module name */
1433 tfprintf (asmFile, "\t!module\n", moduleName);
1434 tfprintf (asmFile, "\t!fileprelude\n");
1436 /* Let the port generate any global directives, etc. */
1437 if (port->genAssemblerPreamble)
1439 port->genAssemblerPreamble (asmFile);
1442 /* print the global variables in this module */
1443 printPublics (asmFile);
1444 if (port->assembler.externGlobal)
1445 printExterns (asmFile);
1447 /* copy the sfr segment */
1448 fprintf (asmFile, "%s", iComments2);
1449 fprintf (asmFile, "; special function registers\n");
1450 fprintf (asmFile, "%s", iComments2);
1451 copyFile (asmFile, sfr->oFile);
1453 /* copy the sbit segment */
1454 fprintf (asmFile, "%s", iComments2);
1455 fprintf (asmFile, "; special function bits \n");
1456 fprintf (asmFile, "%s", iComments2);
1457 copyFile (asmFile, sfrbit->oFile);
1459 /* copy the data segment */
1460 fprintf (asmFile, "%s", iComments2);
1461 fprintf (asmFile, "; internal ram data\n");
1462 fprintf (asmFile, "%s", iComments2);
1463 copyFile (asmFile, data->oFile);
1466 /* create the overlay segments */
1468 fprintf (asmFile, "%s", iComments2);
1469 fprintf (asmFile, "; overlayable items in internal ram \n");
1470 fprintf (asmFile, "%s", iComments2);
1471 copyFile (asmFile, ovrFile);
1474 /* create the stack segment MOF */
1475 if (mainf && IFFUNC_HASBODY(mainf->type))
1477 fprintf (asmFile, "%s", iComments2);
1478 fprintf (asmFile, "; Stack segment in internal ram \n");
1479 fprintf (asmFile, "%s", iComments2);
1480 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1481 "__start__stack:\n\t.ds\t1\n\n");
1484 /* create the idata segment */
1486 fprintf (asmFile, "%s", iComments2);
1487 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1488 fprintf (asmFile, "%s", iComments2);
1489 copyFile (asmFile, idata->oFile);
1492 /* copy the bit segment */
1493 fprintf (asmFile, "%s", iComments2);
1494 fprintf (asmFile, "; bit data\n");
1495 fprintf (asmFile, "%s", iComments2);
1496 copyFile (asmFile, bit->oFile);
1498 /* if external stack then reserve space of it */
1499 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1501 fprintf (asmFile, "%s", iComments2);
1502 fprintf (asmFile, "; external stack \n");
1503 fprintf (asmFile, "%s", iComments2);
1504 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1505 fprintf (asmFile, "\t.ds 256\n");
1509 /* copy xtern ram data */
1510 fprintf (asmFile, "%s", iComments2);
1511 fprintf (asmFile, "; external ram data\n");
1512 fprintf (asmFile, "%s", iComments2);
1513 copyFile (asmFile, xdata->oFile);
1515 /* copy xternal initialized ram data */
1516 fprintf (asmFile, "%s", iComments2);
1517 fprintf (asmFile, "; external initialized ram data\n");
1518 fprintf (asmFile, "%s", iComments2);
1519 copyFile (asmFile, xidata->oFile);
1521 /* copy the interrupt vector table */
1522 if (mainf && IFFUNC_HASBODY(mainf->type))
1524 fprintf (asmFile, "%s", iComments2);
1525 fprintf (asmFile, "; interrupt vector \n");
1526 fprintf (asmFile, "%s", iComments2);
1527 copyFile (asmFile, vFile);
1530 /* copy global & static initialisations */
1531 fprintf (asmFile, "%s", iComments2);
1532 fprintf (asmFile, "; global & static initialisations\n");
1533 fprintf (asmFile, "%s", iComments2);
1535 /* Everywhere we generate a reference to the static_name area,
1536 * (which is currently only here), we immediately follow it with a
1537 * definition of the post_static_name area. This guarantees that
1538 * the post_static_name area will immediately follow the static_name
1541 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1542 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1543 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1545 if (mainf && IFFUNC_HASBODY(mainf->type))
1547 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1548 /* if external stack is specified then the
1549 higher order byte of the xdatalocation is
1550 going into P2 and the lower order going into
1552 if (options.useXstack)
1554 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1555 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1556 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1557 (unsigned int) options.xdata_loc & 0xff);
1560 /* initialise the stack pointer */
1561 /* if the user specified a value then use it */
1562 if (options.stack_loc)
1563 fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc & 0xff);
1565 /* no: we have to compute it */
1566 if (!options.stackOnData && maxRegBank <= 3)
1567 fprintf (asmFile, "\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1);
1569 fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */
1571 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1572 fprintf (asmFile, "\tmov\ta,dpl\n");
1573 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1574 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1575 fprintf (asmFile, "__sdcc_init_data:\n");
1577 // if the port can copy the XINIT segment to XISEG
1578 if (port->genXINIT) {
1579 port->genXINIT(asmFile);
1583 copyFile (asmFile, statsg->oFile);
1585 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1587 /* This code is generated in the post-static area.
1588 * This area is guaranteed to follow the static area
1589 * by the ugly shucking and jiving about 20 lines ago.
1591 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1592 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1598 "%s", iComments2, iComments2);
1599 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1600 copyFile (asmFile, home->oFile);
1602 /* copy over code */
1603 fprintf (asmFile, "%s", iComments2);
1604 fprintf (asmFile, "; code\n");
1605 fprintf (asmFile, "%s", iComments2);
1606 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1607 if (mainf && IFFUNC_HASBODY(mainf->type))
1610 /* entry point @ start of CSEG */
1611 fprintf (asmFile, "__sdcc_program_startup:\n");
1613 /* put in the call to main */
1614 fprintf (asmFile, "\tlcall\t_main\n");
1615 if (options.mainreturn)
1618 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1619 fprintf (asmFile, "\tret\n");
1625 fprintf (asmFile, ";\treturn from main will lock up\n");
1626 fprintf (asmFile, "\tsjmp .\n");
1629 copyFile (asmFile, code->oFile);
1631 if (port->genAssemblerEnd) {
1632 port->genAssemblerEnd(asmFile);
1635 applyToSet (tmpfileSet, closeTmpFiles);
1636 applyToSet (tmpfileNameSet, rmTmpFiles);
1639 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1643 applyToSet (tmpfileSet, closeTmpFiles);
1644 applyToSet (tmpfileNameSet, rmTmpFiles);
1648 /** Creates a temporary file name a'la tmpnam which avoids the bugs
1649 in cygwin wrt c:\tmp.
1650 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1655 #if !defined(_MSC_VER)
1656 const char *tmpdir = NULL;
1658 tmpdir = getenv ("TMP");
1659 else if (getenv ("TEMP"))
1660 tmpdir = getenv ("TEMP");
1661 else if (getenv ("TMPDIR"))
1662 tmpdir = getenv ("TMPDIR");
1665 char *name = tempnam (tmpdir, "sdcc");
1672 return tmpnam (NULL);
1675 /** Creates a temporary file a'la tmpfile which avoids the bugs
1676 in cygwin wrt c:\tmp.
1677 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1682 #if !defined(_MSC_VER)
1683 const char *tmpdir = NULL;
1685 tmpdir = getenv ("TMP");
1686 else if (getenv ("TEMP"))
1687 tmpdir = getenv ("TEMP");
1688 else if (getenv ("TMPDIR"))
1689 tmpdir = getenv ("TMPDIR");
1692 char *name = Safe_strdup( tempnam (tmpdir, "sdcc"));
1695 FILE *fp = fopen (name, "w+b");
1698 addSetHead (&tmpfileNameSet, name);