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 - unlinks all tmp files created by the compiler */
64 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
65 /*-----------------------------------------------------------------*/
66 DEFSETFUNC (rmTmpFiles)
78 /*-----------------------------------------------------------------*/
79 /* rm_tmpfiles - close and remove temporary files and delete sets */
80 /*-----------------------------------------------------------------*/
84 /* close temporary files */
85 applyToSet (tmpfileSet, closeTmpFiles);
86 /* remove temporary files */
87 applyToSet (tmpfileNameSet, rmTmpFiles);
88 /* delete temorary file sets */
89 deleteSet (&tmpfileSet);
90 deleteSet (&tmpfileNameSet);
93 /*-----------------------------------------------------------------*/
94 /* copyFile - copies source file to destination file */
95 /*-----------------------------------------------------------------*/
97 copyFile (FILE * dest, FILE * src)
103 if ((ch = fgetc (src)) != EOF)
108 aopLiteralLong (value * val, int offset, int size)
118 // assuming we have been warned before
122 /* if it is a float then it gets tricky */
123 /* otherwise it is fairly simple */
124 if (!IS_FLOAT (val->type)) {
125 unsigned long v = (unsigned long) floatFromVal (val);
130 tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
133 tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
136 /* Hmm. Too big for now. */
139 rs = Safe_calloc (1, strlen (buffer) + 1);
140 return strcpy (rs, buffer);
143 /* PENDING: For now size must be 1 */
146 /* it is type float */
147 fl.f = (float) floatFromVal (val);
149 tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
151 tsprintf (buffer, "!immedbyte", fl.c[offset]);
153 rs = Safe_calloc (1, strlen (buffer) + 1);
154 return strcpy (rs, buffer);
157 /*-----------------------------------------------------------------*/
158 /* aopLiteral - string from a literal value */
159 /*-----------------------------------------------------------------*/
161 aopLiteral (value * val, int offset)
163 return aopLiteralLong (val, offset, 1);
166 /*-----------------------------------------------------------------*/
167 /* emitRegularMap - emit code for maps with no special cases */
168 /*-----------------------------------------------------------------*/
170 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
180 /* PENDING: special case here - should remove */
181 if (!strcmp (map->sname, CODE_NAME))
182 tfprintf (map->oFile, "\t!areacode\n", map->sname);
183 else if (!strcmp (map->sname, DATA_NAME))
184 tfprintf (map->oFile, "\t!areadata\n", map->sname);
185 else if (!strcmp (map->sname, HOME_NAME))
186 tfprintf (map->oFile, "\t!areahome\n", map->sname);
188 tfprintf (map->oFile, "\t!area\n", map->sname);
191 for (sym = setFirstItem (map->syms); sym;
192 sym = setNextItem (map->syms))
196 /* if extern then add it into the extern list */
197 if (IS_EXTERN (sym->etype))
199 addSetHead (&externs, sym);
203 /* if allocation required check is needed
204 then check if the symbol really requires
205 allocation only for local variables */
207 if (arFlag && !IS_AGGREGATE (sym->type) &&
208 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
209 !sym->allocreq && sym->level)
212 /* for bitvar locals and parameters */
213 if (!arFlag && !sym->allocreq && sym->level
214 && !SPEC_ABSA (sym->etype)) {
218 /* if global variable & not static or extern
219 and addPublics allowed then add it to the public set */
220 if ((sym->level == 0 ||
221 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
223 !IS_STATIC (sym->etype) &&
224 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
226 addSetHead (&publics, sym);
229 /* if extern then do nothing or is a function
231 if (IS_FUNC (sym->type))
234 /* print extra debug info if required */
236 cdbSymbol (sym, cdbFile, FALSE, FALSE);
237 if (!sym->level) /* global */
238 if (IS_STATIC (sym->etype))
239 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
241 fprintf (map->oFile, "G$"); /* scope is global */
243 /* symbol is local */
244 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
245 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
248 /* if it has an initial value then do it only if
249 it is a global variable */
250 if (sym->ival && sym->level == 0) {
251 if (SPEC_OCLS(sym->etype)==xidata) {
252 // create a new "XINIT (CODE)" symbol, that will be emitted later
253 newSym=copySymbol (sym);
254 SPEC_OCLS(newSym->etype)=xinit;
255 sprintf (newSym->name, "__xinit_%s", sym->name);
256 sprintf (newSym->rname,"__xinit_%s", sym->rname);
257 SPEC_CONST(newSym->etype)=1;
258 SPEC_STAT(newSym->etype)=1;
260 // add it to the "XINIT (CODE)" segment
261 addSet(&xinit->syms, newSym);
264 if (IS_AGGREGATE (sym->type)) {
265 ival = initAggregates (sym, sym->ival, NULL);
267 if (getNelements(sym->type, sym->ival)>1) {
268 werror (W_EXCESS_INITIALIZERS, "scalar",
269 sym->name, sym->lineDef);
271 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
272 decorateType (resolveSymbols (list2expr (sym->ival))));
274 codeOutFile = statsg->oFile;
277 // set ival's lineno to where the symbol was defined
278 setAstLineno (ival, lineno=sym->lineDef);
279 // check if this is not a constant expression
280 if (!constExprTree(ival)) {
281 werror (E_CONST_EXPECTED, "found expression");
282 // but try to do it anyway
285 eBBlockFromiCode (iCodeFromAst (ival));
292 /* if is has an absolute address then generate
293 an equate for this no need to allocate space */
294 if (SPEC_ABSA (sym->etype))
298 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
300 if (TARGET_IS_XA51) {
303 } else if (map==bit || map==sfrbit) {
307 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
309 SPEC_ADDR (sym->etype));
312 int size = getSize (sym->type);
314 werror(E_UNKNOWN_SIZE,sym->name);
318 fprintf (map->oFile, "==.\n");
320 if (IS_STATIC (sym->etype))
321 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
323 tfprintf (map->oFile, "!labeldef\n", sym->rname);
324 tfprintf (map->oFile, "\t!ds\n",
325 (unsigned int) size & 0xffff);
330 /*-----------------------------------------------------------------*/
331 /* initPointer - pointer initialization code massaging */
332 /*-----------------------------------------------------------------*/
334 initPointer (initList * ilist, sym_link *toType)
337 ast *expr = list2expr (ilist);
342 /* try it the oldway first */
343 if ((val = constExprValue (expr, FALSE)))
346 /* ( ptr + constant ) */
347 if (IS_AST_OP (expr) &&
348 (expr->opval.op == '+' || expr->opval.op == '-') &&
349 IS_AST_SYM_VALUE (expr->left) &&
350 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
351 compareType(toType, expr->left->ftype) &&
352 IS_AST_LIT_VALUE (expr->right)) {
353 return valForCastAggr (expr->left, expr->left->ftype,
359 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
360 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
361 if (compareType(toType, expr->left->ftype)!=1) {
362 werror (W_INIT_WRONG);
363 printFromToType(expr->left->ftype, toType);
369 /* no then we have to do these cludgy checks */
370 /* pointers can be initialized with address of
371 a variable or address of an array element */
372 if (IS_AST_OP (expr) && expr->opval.op == '&') {
373 /* address of symbol */
374 if (IS_AST_SYM_VALUE (expr->left)) {
375 val = copyValue (AST_VALUE (expr->left));
376 val->type = newLink ();
377 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
378 DCL_TYPE (val->type) = CPOINTER;
379 DCL_PTR_CONST (val->type) = port->mem.code_ro;
381 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
382 DCL_TYPE (val->type) = FPOINTER;
383 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
384 DCL_TYPE (val->type) = PPOINTER;
385 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
386 DCL_TYPE (val->type) = IPOINTER;
387 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
388 DCL_TYPE (val->type) = EEPPOINTER;
390 DCL_TYPE (val->type) = POINTER;
391 val->type->next = expr->left->ftype;
392 val->etype = getSpec (val->type);
396 /* if address of indexed array */
397 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
398 return valForArray (expr->left);
400 /* if address of structure element then
402 if (IS_AST_OP (expr->left) &&
403 expr->left->opval.op == '.') {
404 return valForStructElem (expr->left->left,
409 (&some_struct)->element */
410 if (IS_AST_OP (expr->left) &&
411 expr->left->opval.op == PTR_OP &&
412 IS_ADDRESS_OF_OP (expr->left->left)) {
413 return valForStructElem (expr->left->left->left,
417 /* case 3. (((char *) &a) +/- constant) */
418 if (IS_AST_OP (expr) &&
419 (expr->opval.op == '+' || expr->opval.op == '-') &&
420 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
421 IS_AST_OP (expr->left->right) &&
422 expr->left->right->opval.op == '&' &&
423 IS_AST_LIT_VALUE (expr->right)) {
425 return valForCastAggr (expr->left->right->left,
426 expr->left->left->opval.lnk,
427 expr->right, expr->opval.op);
430 /* case 4. (char *)(array type) */
431 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
432 IS_ARRAY(expr->right->ftype)) {
434 val = copyValue (AST_VALUE (expr->right));
435 val->type = newLink ();
436 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
437 DCL_TYPE (val->type) = CPOINTER;
438 DCL_PTR_CONST (val->type) = port->mem.code_ro;
440 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
441 DCL_TYPE (val->type) = FPOINTER;
442 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
443 DCL_TYPE (val->type) = PPOINTER;
444 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
445 DCL_TYPE (val->type) = IPOINTER;
446 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
447 DCL_TYPE (val->type) = EEPPOINTER;
449 DCL_TYPE (val->type) = POINTER;
450 val->type->next = expr->right->ftype->next;
451 val->etype = getSpec (val->type);
455 werror (E_INCOMPAT_PTYPES);
460 /*-----------------------------------------------------------------*/
461 /* printChar - formats and prints a characater string with DB */
462 /*-----------------------------------------------------------------*/
464 printChar (FILE * ofile, char *s, int plen)
467 int len = strlen (s);
472 while (len && pplen < plen)
475 while (i && *s && pplen < plen)
477 if (*s < ' ' || *s == '\"' || *s=='\\')
481 tfprintf (ofile, "\t!ascii\n", buf);
482 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
497 tfprintf (ofile, "\t!ascii\n", buf);
506 tfprintf (ofile, "\t!db !constbyte\n", 0);
509 /*-----------------------------------------------------------------*/
510 /* return the generic pointer high byte for a given pointer type. */
511 /*-----------------------------------------------------------------*/
513 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
521 werror (E_CANNOT_USE_GENERIC_POINTER,
522 iname ? iname : "<null>",
523 oname ? oname : "<null>");
530 return GPTYPE_XSTACK;
532 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
540 /*-----------------------------------------------------------------*/
541 /* printPointerType - generates ival for pointer type */
542 /*-----------------------------------------------------------------*/
544 _printPointerType (FILE * oFile, const char *name)
546 /* if (TARGET_IS_DS390) */
547 if (options.model == MODEL_FLAT24)
549 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
553 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
557 /*-----------------------------------------------------------------*/
558 /* printPointerType - generates ival for pointer type */
559 /*-----------------------------------------------------------------*/
561 printPointerType (FILE * oFile, const char *name)
563 _printPointerType (oFile, name);
564 fprintf (oFile, "\n");
567 /*-----------------------------------------------------------------*/
568 /* printGPointerType - generates ival for generic pointer type */
569 /*-----------------------------------------------------------------*/
571 printGPointerType (FILE * oFile, const char *iname, const char *oname,
572 const unsigned int type)
574 _printPointerType (oFile, iname);
575 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
578 /*-----------------------------------------------------------------*/
579 /* printIvalType - generates ival for int/char */
580 /*-----------------------------------------------------------------*/
582 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
586 /* if initList is deep */
587 if (ilist->type == INIT_DEEP)
588 ilist = ilist->init.deep;
590 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
591 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
594 if (!(val = list2val (ilist))) {
595 // assuming a warning has been thrown
599 if (val->type != type) {
600 val = valCastLiteral(type, floatFromVal(val));
603 switch (getSize (type)) {
606 tfprintf (oFile, "\t!db !constbyte\n", 0);
608 tfprintf (oFile, "\t!dbs\n",
609 aopLiteral (val, 0));
613 if (port->use_dw_for_init)
614 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
616 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
620 tfprintf (oFile, "\t!dw !constword\n", 0);
621 tfprintf (oFile, "\t!dw !constword\n", 0);
624 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
625 aopLiteral (val, 0), aopLiteral (val, 1),
626 aopLiteral (val, 2), aopLiteral (val, 3));
632 /*-----------------------------------------------------------------*/
633 /* printIvalBitFields - generate initializer for bitfields */
634 /*-----------------------------------------------------------------*/
635 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
639 initList *lilist = *ilist ;
640 unsigned long ival = 0;
646 val = list2val(lilist);
648 if (SPEC_BLEN(lsym->etype) > 8) {
649 size += ((SPEC_BLEN (lsym->etype) / 8) +
650 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
653 size = ((SPEC_BLEN (lsym->etype) / 8) +
654 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
656 i = (unsigned long)floatFromVal(val);
657 i <<= SPEC_BSTR (lsym->etype);
659 if (! ( lsym->next &&
660 (IS_BITFIELD(lsym->next->type)) &&
661 (SPEC_BSTR(lsym->next->etype)))) break;
663 lilist = lilist->next;
667 tfprintf (oFile, "\t!db !constbyte\n",ival);
671 tfprintf (oFile, "\t!dw !constword\n",ival);
674 tfprintf (oFile, "\t!db !constword,!constword\n",
675 (ival >> 8) & 0xffff, (ival & 0xffff));
682 /*-----------------------------------------------------------------*/
683 /* printIvalStruct - generates initial value for structures */
684 /*-----------------------------------------------------------------*/
686 printIvalStruct (symbol * sym, sym_link * type,
687 initList * ilist, FILE * oFile)
692 sflds = SPEC_STRUCT (type)->fields;
693 if (ilist->type != INIT_DEEP) {
694 werror (E_INIT_STRUCT, sym->name);
698 iloop = ilist->init.deep;
700 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
701 if (IS_BITFIELD(sflds->type)) {
702 printIvalBitFields(&sflds,&iloop,oFile);
704 printIval (sym, sflds->type, iloop, oFile);
708 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
713 /*-----------------------------------------------------------------*/
714 /* printIvalChar - generates initital value for character array */
715 /*-----------------------------------------------------------------*/
717 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
725 val = list2val (ilist);
726 /* if the value is a character string */
727 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
729 if (!DCL_ELEM (type))
730 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
732 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
734 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
736 tfprintf (oFile, "\t!db !constbyte\n", 0);
744 printChar (oFile, s, strlen (s) + 1);
748 /*-----------------------------------------------------------------*/
749 /* printIvalArray - generates code for array initialization */
750 /*-----------------------------------------------------------------*/
752 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
756 int lcnt = 0, size = 0;
759 /* take care of the special case */
760 /* array of characters can be init */
762 if (IS_CHAR (type->next)) {
763 if (!IS_LITERAL(list2val(ilist)->etype)) {
764 werror (E_CONST_EXPECTED);
767 if (printIvalChar (type,
768 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
769 oFile, SPEC_CVAL (sym->etype).v_char))
772 /* not the special case */
773 if (ilist->type != INIT_DEEP)
775 werror (E_INIT_STRUCT, sym->name);
779 iloop = ilist->init.deep;
780 lcnt = DCL_ELEM (type);
781 for (last_type = type->next; last_type && DCL_ELEM (last_type); last_type = last_type->next)
782 lcnt *= DCL_ELEM (last_type);
787 printIval (sym, type->next, iloop, oFile);
788 iloop = (iloop ? iloop->next : NULL);
791 /* if not array limits given & we */
792 /* are out of initialisers then */
793 if (!DCL_ELEM (type) && !iloop)
796 /* no of elements given and we */
797 /* have generated for all of them */
799 /* if initializers left */
801 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
807 /* if we have not been given a size */
808 if (!DCL_ELEM (type))
809 DCL_ELEM (type) = size;
814 /*-----------------------------------------------------------------*/
815 /* printIvalFuncPtr - generate initial value for function pointers */
816 /*-----------------------------------------------------------------*/
818 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
823 val = list2val (ilist);
826 // an error has been thrown allready
830 if (IS_LITERAL(val->etype)) {
831 if (compareType(type,val->etype)==0) {
832 werror (E_INCOMPAT_TYPES);
833 printFromToType (val->type, type);
835 printIvalCharPtr (NULL, type, val, oFile);
839 /* check the types */
840 if ((dLvl = compareType (val->type, type->next)) <= 0)
842 tfprintf (oFile, "\t!dw !constword\n", 0);
846 /* now generate the name */
849 if (port->use_dw_for_init)
851 tfprintf (oFile, "\t!dws\n", val->name);
855 printPointerType (oFile, val->name);
858 else if (port->use_dw_for_init)
860 tfprintf (oFile, "\t!dws\n", val->sym->rname);
864 printPointerType (oFile, val->sym->rname);
870 /*-----------------------------------------------------------------*/
871 /* printIvalCharPtr - generates initial values for character pointers */
872 /*-----------------------------------------------------------------*/
874 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
878 /* PENDING: this is _very_ mcs51 specific, including a magic
880 It's also endin specific.
882 size = getSize (type);
884 if (val->name && strlen (val->name))
886 if (size == 1) /* This appears to be Z80 specific?? */
889 "\t!dbs\n", val->name);
891 else if (size == FPTRSIZE)
893 if (port->use_dw_for_init)
895 tfprintf (oFile, "\t!dws\n", val->name);
899 printPointerType (oFile, val->name);
902 else if (size == GPTRSIZE)
905 if (IS_PTR (val->type)) {
906 type = DCL_TYPE (val->type);
908 type = PTR_TYPE (SPEC_OCLS (val->etype));
910 if (val->sym && val->sym->isstrlit) {
911 // this is a literal string
914 printGPointerType (oFile, val->name, sym->name, type);
918 fprintf (stderr, "*** internal error: unknown size in "
919 "printIvalCharPtr.\n");
924 // these are literals assigned to pointers
928 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
931 if (port->use_dw_for_init)
932 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
934 tfprintf (oFile, "\t.byte %s,%s\n",
935 aopLiteral (val, 0), aopLiteral (val, 1));
938 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
939 // non-zero mcs51 generic pointer
940 werror (E_LITERAL_GENERIC);
942 fprintf (oFile, "\t.byte %s,%s,%s\n",
945 aopLiteral (val, 2));
948 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
949 // non-zero ds390 generic pointer
950 werror (E_LITERAL_GENERIC);
952 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
956 aopLiteral (val, 3));
963 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
964 addSet (&statsg->syms, val->sym);
970 /*-----------------------------------------------------------------*/
971 /* printIvalPtr - generates initial value for pointers */
972 /*-----------------------------------------------------------------*/
974 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
980 if (ilist->type == INIT_DEEP)
981 ilist = ilist->init.deep;
983 /* function pointer */
984 if (IS_FUNC (type->next))
986 printIvalFuncPtr (type, ilist, oFile);
990 if (!(val = initPointer (ilist, type)))
993 /* if character pointer */
994 if (IS_CHAR (type->next))
995 if (printIvalCharPtr (sym, type, val, oFile))
999 if (compareType (type, val->type) == 0) {
1000 werror (W_INIT_WRONG);
1001 printFromToType (val->type, type);
1004 /* if val is literal */
1005 if (IS_LITERAL (val->etype))
1007 switch (getSize (type))
1010 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1013 if (port->use_dw_for_init)
1014 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1016 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1018 case 3: // how about '390??
1019 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1020 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1026 size = getSize (type);
1028 if (size == 1) /* Z80 specific?? */
1030 tfprintf (oFile, "\t!dbs\n", val->name);
1032 else if (size == FPTRSIZE)
1034 if (port->use_dw_for_init) {
1035 tfprintf (oFile, "\t!dws\n", val->name);
1037 printPointerType (oFile, val->name);
1040 else if (size == GPTRSIZE)
1042 printGPointerType (oFile, val->name, sym->name,
1043 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1044 PTR_TYPE (SPEC_OCLS (val->etype))));
1049 /*-----------------------------------------------------------------*/
1050 /* printIval - generates code for initial value */
1051 /*-----------------------------------------------------------------*/
1053 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1058 /* update line number for error msgs */
1059 lineno=sym->lineDef;
1061 /* if structure then */
1062 if (IS_STRUCT (type))
1064 printIvalStruct (sym, type, ilist, oFile);
1068 /* if this is a pointer */
1071 printIvalPtr (sym, type, ilist, oFile);
1075 /* if this is an array */
1076 if (IS_ARRAY (type))
1078 printIvalArray (sym, type, ilist, oFile);
1082 /* if type is SPECIFIER */
1085 printIvalType (sym, type, ilist, oFile);
1090 /*-----------------------------------------------------------------*/
1091 /* emitStaticSeg - emitcode for the static segment */
1092 /*-----------------------------------------------------------------*/
1094 emitStaticSeg (memmap * map, FILE * out)
1098 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1100 /* for all variables in this segment do */
1101 for (sym = setFirstItem (map->syms); sym;
1102 sym = setNextItem (map->syms))
1105 /* if it is "extern" then do nothing */
1106 if (IS_EXTERN (sym->etype))
1109 /* if it is not static add it to the public
1111 if (!IS_STATIC (sym->etype))
1113 addSetHead (&publics, sym);
1116 /* print extra debug info if required */
1117 if (options.debug) {
1118 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1121 if (IS_STATIC (sym->etype))
1122 fprintf (out, "F%s$", moduleName); /* scope is file */
1124 fprintf (out, "G$"); /* scope is global */
1127 /* symbol is local */
1128 fprintf (out, "L%s$",
1129 (sym->localof ? sym->localof->name : "-null-"));
1130 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1133 /* if it has an absolute address */
1134 if (SPEC_ABSA (sym->etype))
1137 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1139 fprintf (out, "%s\t=\t0x%04x\n",
1141 SPEC_ADDR (sym->etype));
1146 fprintf (out, " == .\n");
1148 /* if it has an initial value */
1151 fprintf (out, "%s:\n", sym->rname);
1153 resolveIvalSym (sym->ival);
1154 printIval (sym, sym->type, sym->ival, out);
1158 /* allocate space */
1159 int size = getSize (sym->type);
1162 werror(E_UNKNOWN_SIZE,sym->name);
1164 fprintf (out, "%s:\n", sym->rname);
1165 /* special case for character strings */
1166 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1167 SPEC_CVAL (sym->etype).v_char)
1169 SPEC_CVAL (sym->etype).v_char,
1170 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1172 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1178 /*-----------------------------------------------------------------*/
1179 /* emitMaps - emits the code for the data portion the code */
1180 /*-----------------------------------------------------------------*/
1185 /* no special considerations for the following
1186 data, idata & bit & xdata */
1187 emitRegularMap (data, TRUE, TRUE);
1188 emitRegularMap (idata, TRUE, TRUE);
1189 emitRegularMap (bit, TRUE, FALSE);
1190 emitRegularMap (xdata, TRUE, TRUE);
1191 if (port->genXINIT) {
1192 emitRegularMap (xidata, TRUE, TRUE);
1194 emitRegularMap (sfr, FALSE, FALSE);
1195 emitRegularMap (sfrbit, FALSE, FALSE);
1196 emitRegularMap (home, TRUE, FALSE);
1197 emitRegularMap (code, TRUE, FALSE);
1199 emitStaticSeg (statsg, code->oFile);
1200 if (port->genXINIT) {
1201 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1202 emitStaticSeg (xinit, code->oFile);
1207 /*-----------------------------------------------------------------*/
1208 /* flushStatics - flush all currently defined statics out to file */
1209 /* and delete. Temporary function */
1210 /*-----------------------------------------------------------------*/
1214 emitStaticSeg (statsg, codeOutFile);
1215 statsg->syms = NULL;
1218 /*-----------------------------------------------------------------*/
1219 /* createInterruptVect - creates the interrupt vector */
1220 /*-----------------------------------------------------------------*/
1222 createInterruptVect (FILE * vFile)
1225 mainf = newSymbol ("main", 0);
1228 /* only if the main function exists */
1229 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1231 if (!options.cc_only && !noAssemble && !options.c1mode)
1236 /* if the main is only a prototype ie. no body then do nothing */
1237 if (!IFFUNC_HASBODY(mainf->type))
1239 /* if ! compile only then main function should be present */
1240 if (!options.cc_only && !noAssemble)
1245 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1246 fprintf (vFile, "__interrupt_vect:\n");
1249 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1251 /* "generic" interrupt table header (if port doesn't specify one).
1252 * Look suspiciously like 8051 code to me...
1255 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1258 /* now for the other interrupts */
1259 for (; i < maxInterrupts; i++)
1262 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1264 fprintf (vFile, "\treti\n\t.ds\t7\n");
1271 ";--------------------------------------------------------\n"
1272 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1276 ";--------------------------------------------------------\n"};
1279 /*-----------------------------------------------------------------*/
1280 /* initialComments - puts in some initial comments */
1281 /*-----------------------------------------------------------------*/
1283 initialComments (FILE * afile)
1287 fprintf (afile, "%s", iComments1);
1288 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1289 fprintf (afile, "%s", iComments2);
1292 /*-----------------------------------------------------------------*/
1293 /* printPublics - generates .global for publics */
1294 /*-----------------------------------------------------------------*/
1296 printPublics (FILE * afile)
1300 fprintf (afile, "%s", iComments2);
1301 fprintf (afile, "; Public variables in this module\n");
1302 fprintf (afile, "%s", iComments2);
1304 for (sym = setFirstItem (publics); sym;
1305 sym = setNextItem (publics))
1306 tfprintf (afile, "\t!global\n", sym->rname);
1309 /*-----------------------------------------------------------------*/
1310 /* printExterns - generates .global for externs */
1311 /*-----------------------------------------------------------------*/
1313 printExterns (FILE * afile)
1317 fprintf (afile, "%s", iComments2);
1318 fprintf (afile, "; Externals used\n");
1319 fprintf (afile, "%s", iComments2);
1321 for (sym = setFirstItem (externs); sym;
1322 sym = setNextItem (externs))
1323 tfprintf (afile, "\t!extern\n", sym->rname);
1326 /*-----------------------------------------------------------------*/
1327 /* emitOverlay - will emit code for the overlay stuff */
1328 /*-----------------------------------------------------------------*/
1330 emitOverlay (FILE * afile)
1334 if (!elementsInSet (ovrSetSets))
1335 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1337 /* for each of the sets in the overlay segment do */
1338 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1339 ovrset = setNextItem (ovrSetSets))
1344 if (elementsInSet (ovrset))
1346 /* output the area informtion */
1347 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1350 for (sym = setFirstItem (ovrset); sym;
1351 sym = setNextItem (ovrset))
1353 /* if extern then it is in the publics table: do nothing */
1354 if (IS_EXTERN (sym->etype))
1357 /* if allocation required check is needed
1358 then check if the symbol really requires
1359 allocation only for local variables */
1360 if (!IS_AGGREGATE (sym->type) &&
1361 !(sym->_isparm && !IS_REGPARM (sym->etype))
1362 && !sym->allocreq && sym->level)
1365 /* if global variable & not static or extern
1366 and addPublics allowed then add it to the public set */
1367 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1368 && !IS_STATIC (sym->etype))
1370 addSetHead (&publics, sym);
1373 /* if extern then do nothing or is a function
1375 if (IS_FUNC (sym->type))
1378 /* print extra debug info if required */
1381 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1385 if (IS_STATIC (sym->etype))
1386 fprintf (afile, "F%s$", moduleName); /* scope is file */
1388 fprintf (afile, "G$"); /* scope is global */
1391 /* symbol is local */
1392 fprintf (afile, "L%s$",
1393 (sym->localof ? sym->localof->name : "-null-"));
1394 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1397 /* if is has an absolute address then generate
1398 an equate for this no need to allocate space */
1399 if (SPEC_ABSA (sym->etype))
1403 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1405 fprintf (afile, "%s\t=\t0x%04x\n",
1407 SPEC_ADDR (sym->etype));
1410 int size = getSize(sym->type);
1413 werror(E_UNKNOWN_SIZE,sym->name);
1416 fprintf (afile, "==.\n");
1418 /* allocate space */
1419 tfprintf (afile, "!labeldef\n", sym->rname);
1420 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1427 /*-----------------------------------------------------------------*/
1428 /* glue - the final glue that hold the whole thing together */
1429 /*-----------------------------------------------------------------*/
1435 FILE *ovrFile = tempfile ();
1437 addSetHead (&tmpfileSet, ovrFile);
1438 /* print the global struct definitions */
1440 cdbStructBlock (0, cdbFile);
1442 vFile = tempfile ();
1443 /* PENDING: this isnt the best place but it will do */
1444 if (port->general.glue_up_main)
1446 /* create the interrupt vector table */
1447 createInterruptVect (vFile);
1450 addSetHead (&tmpfileSet, vFile);
1452 /* emit code for the all the variables declared */
1454 /* do the overlay segments */
1455 emitOverlay (ovrFile);
1457 /* now put it all together into the assembler file */
1458 /* create the assembler file name */
1460 /* -o option overrides default name? */
1461 if ((noAssemble || options.c1mode) && fullDstFileName)
1463 strcpy (scratchFileName, fullDstFileName);
1467 strcpy (scratchFileName, dstFileName);
1468 strcat (scratchFileName, port->assembler.file_ext);
1471 if (!(asmFile = fopen (scratchFileName, "w")))
1473 werror (E_FILE_OPEN_ERR, scratchFileName);
1477 /* initial comments */
1478 initialComments (asmFile);
1480 /* print module name */
1481 tfprintf (asmFile, "\t!module\n", moduleName);
1482 tfprintf (asmFile, "\t!fileprelude\n");
1484 /* Let the port generate any global directives, etc. */
1485 if (port->genAssemblerPreamble)
1487 port->genAssemblerPreamble (asmFile);
1490 /* print the global variables in this module */
1491 printPublics (asmFile);
1492 if (port->assembler.externGlobal)
1493 printExterns (asmFile);
1495 /* copy the sfr segment */
1496 fprintf (asmFile, "%s", iComments2);
1497 fprintf (asmFile, "; special function registers\n");
1498 fprintf (asmFile, "%s", iComments2);
1499 copyFile (asmFile, sfr->oFile);
1501 /* copy the sbit segment */
1502 fprintf (asmFile, "%s", iComments2);
1503 fprintf (asmFile, "; special function bits \n");
1504 fprintf (asmFile, "%s", iComments2);
1505 copyFile (asmFile, sfrbit->oFile);
1507 /*JCF: Create the areas for the register banks*/
1508 if(port->general.glue_up_main &&
1509 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51))
1511 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1513 fprintf (asmFile, "%s", iComments2);
1514 fprintf (asmFile, "; overlayable register banks \n");
1515 fprintf (asmFile, "%s", iComments2);
1517 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1518 if(RegBankUsed[1]||options.parms_in_bank1)
1519 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1521 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1523 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1527 /* copy the data segment */
1528 fprintf (asmFile, "%s", iComments2);
1529 fprintf (asmFile, "; internal ram data\n");
1530 fprintf (asmFile, "%s", iComments2);
1531 copyFile (asmFile, data->oFile);
1534 /* create the overlay segments */
1536 fprintf (asmFile, "%s", iComments2);
1537 fprintf (asmFile, "; overlayable items in internal ram \n");
1538 fprintf (asmFile, "%s", iComments2);
1539 copyFile (asmFile, ovrFile);
1542 /* create the stack segment MOF */
1543 if (mainf && IFFUNC_HASBODY(mainf->type))
1545 fprintf (asmFile, "%s", iComments2);
1546 fprintf (asmFile, "; Stack segment in internal ram \n");
1547 fprintf (asmFile, "%s", iComments2);
1548 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1549 "__start__stack:\n\t.ds\t1\n\n");
1552 /* create the idata segment */
1554 fprintf (asmFile, "%s", iComments2);
1555 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1556 fprintf (asmFile, "%s", iComments2);
1557 copyFile (asmFile, idata->oFile);
1560 /* copy the bit segment */
1561 fprintf (asmFile, "%s", iComments2);
1562 fprintf (asmFile, "; bit data\n");
1563 fprintf (asmFile, "%s", iComments2);
1564 copyFile (asmFile, bit->oFile);
1566 /* if external stack then reserve space of it */
1567 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1569 fprintf (asmFile, "%s", iComments2);
1570 fprintf (asmFile, "; external stack \n");
1571 fprintf (asmFile, "%s", iComments2);
1572 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1573 fprintf (asmFile, "\t.ds 256\n");
1577 /* copy xtern ram data */
1578 fprintf (asmFile, "%s", iComments2);
1579 fprintf (asmFile, "; external ram data\n");
1580 fprintf (asmFile, "%s", iComments2);
1581 copyFile (asmFile, xdata->oFile);
1583 /* copy xternal initialized ram data */
1584 fprintf (asmFile, "%s", iComments2);
1585 fprintf (asmFile, "; external initialized ram data\n");
1586 fprintf (asmFile, "%s", iComments2);
1587 copyFile (asmFile, xidata->oFile);
1589 /* copy the interrupt vector table */
1590 if (mainf && IFFUNC_HASBODY(mainf->type))
1592 fprintf (asmFile, "%s", iComments2);
1593 fprintf (asmFile, "; interrupt vector \n");
1594 fprintf (asmFile, "%s", iComments2);
1595 copyFile (asmFile, vFile);
1598 /* copy global & static initialisations */
1599 fprintf (asmFile, "%s", iComments2);
1600 fprintf (asmFile, "; global & static initialisations\n");
1601 fprintf (asmFile, "%s", iComments2);
1603 /* Everywhere we generate a reference to the static_name area,
1604 * (which is currently only here), we immediately follow it with a
1605 * definition of the post_static_name area. This guarantees that
1606 * the post_static_name area will immediately follow the static_name
1609 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1610 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1611 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1613 if (mainf && IFFUNC_HASBODY(mainf->type))
1615 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1616 /* if external stack is specified then the
1617 higher order byte of the xdatalocation is
1618 going into P2 and the lower order going into
1620 if (options.useXstack)
1622 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1623 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1624 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1625 (unsigned int) options.xdata_loc & 0xff);
1628 /* initialise the stack pointer. JCF: aslink takes care of the location */
1629 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1631 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1632 fprintf (asmFile, "\tmov\ta,dpl\n");
1633 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1634 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1635 fprintf (asmFile, "__sdcc_init_data:\n");
1637 // if the port can copy the XINIT segment to XISEG
1638 if (port->genXINIT) {
1639 port->genXINIT(asmFile);
1643 copyFile (asmFile, statsg->oFile);
1645 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1647 /* This code is generated in the post-static area.
1648 * This area is guaranteed to follow the static area
1649 * by the ugly shucking and jiving about 20 lines ago.
1651 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1652 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1658 "%s", iComments2, iComments2);
1659 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1660 copyFile (asmFile, home->oFile);
1662 /* copy over code */
1663 fprintf (asmFile, "%s", iComments2);
1664 fprintf (asmFile, "; code\n");
1665 fprintf (asmFile, "%s", iComments2);
1666 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1667 if (mainf && IFFUNC_HASBODY(mainf->type))
1670 /* entry point @ start of CSEG */
1671 fprintf (asmFile, "__sdcc_program_startup:\n");
1673 /* put in the call to main */
1674 fprintf (asmFile, "\tlcall\t_main\n");
1675 if (options.mainreturn)
1678 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1679 fprintf (asmFile, "\tret\n");
1685 fprintf (asmFile, ";\treturn from main will lock up\n");
1686 fprintf (asmFile, "\tsjmp .\n");
1689 copyFile (asmFile, code->oFile);
1691 if (port->genAssemblerEnd) {
1692 port->genAssemblerEnd(asmFile);
1699 /** Creates a temporary file name a'la tmpnam which avoids the bugs
1700 in cygwin wrt c:\tmp.
1701 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1706 const char *tmpdir = NULL;
1708 tmpdir = getenv ("TMP");
1709 else if (getenv ("TEMP"))
1710 tmpdir = getenv ("TEMP");
1711 else if (getenv ("TMPDIR"))
1712 tmpdir = getenv ("TMPDIR");
1715 char *name = tempnam (tmpdir, "sdcc");
1721 return tmpnam (NULL);
1724 /** Creates a temporary file a'la tmpfile which avoids the bugs
1725 in cygwin wrt c:\tmp.
1726 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1731 const char *tmpdir = NULL;
1733 tmpdir = getenv ("TMP");
1734 else if (getenv ("TEMP"))
1735 tmpdir = getenv ("TEMP");
1736 else if (getenv ("TMPDIR"))
1737 tmpdir = getenv ("TMPDIR");
1740 char *name = Safe_strdup( tempnam (tmpdir, "sdcc"));
1743 FILE *fp = fopen (name, "w+b");
1746 addSetHead (&tmpfileNameSet, name);