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;
259 resolveIvalSym(newSym->ival);
261 // add it to the "XINIT (CODE)" segment
262 addSet(&xinit->syms, newSym);
265 if (IS_AGGREGATE (sym->type)) {
266 ival = initAggregates (sym, sym->ival, NULL);
268 if (getNelements(sym->type, sym->ival)>1) {
269 werror (W_EXCESS_INITIALIZERS, "scalar",
270 sym->name, sym->lineDef);
272 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
273 decorateType (resolveSymbols (list2expr (sym->ival))));
275 codeOutFile = statsg->oFile;
278 // set ival's lineno to where the symbol was defined
279 setAstLineno (ival, lineno=sym->lineDef);
280 // check if this is not a constant expression
281 if (!constExprTree(ival)) {
282 werror (E_CONST_EXPECTED, "found expression");
283 // but try to do it anyway
286 eBBlockFromiCode (iCodeFromAst (ival));
293 /* if is has an absolute address then generate
294 an equate for this no need to allocate space */
295 if (SPEC_ABSA (sym->etype))
299 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
301 if (TARGET_IS_XA51) {
304 } else if (map==bit || map==sfrbit) {
308 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
310 SPEC_ADDR (sym->etype));
313 int size = getSize (sym->type);
315 werror(E_UNKNOWN_SIZE,sym->name);
319 fprintf (map->oFile, "==.\n");
321 if (IS_STATIC (sym->etype))
322 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
324 tfprintf (map->oFile, "!labeldef\n", sym->rname);
325 tfprintf (map->oFile, "\t!ds\n",
326 (unsigned int) size & 0xffff);
331 /*-----------------------------------------------------------------*/
332 /* initPointer - pointer initialization code massaging */
333 /*-----------------------------------------------------------------*/
335 initPointer (initList * ilist, sym_link *toType)
338 ast *expr = list2expr (ilist);
343 /* try it the oldway first */
344 if ((val = constExprValue (expr, FALSE)))
347 /* ( ptr + constant ) */
348 if (IS_AST_OP (expr) &&
349 (expr->opval.op == '+' || expr->opval.op == '-') &&
350 IS_AST_SYM_VALUE (expr->left) &&
351 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
352 compareType(toType, expr->left->ftype) &&
353 IS_AST_LIT_VALUE (expr->right)) {
354 return valForCastAggr (expr->left, expr->left->ftype,
360 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
361 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
362 if (compareType(toType, expr->left->ftype)!=1) {
363 werror (W_INIT_WRONG);
364 printFromToType(expr->left->ftype, toType);
370 /* no then we have to do these cludgy checks */
371 /* pointers can be initialized with address of
372 a variable or address of an array element */
373 if (IS_AST_OP (expr) && expr->opval.op == '&') {
374 /* address of symbol */
375 if (IS_AST_SYM_VALUE (expr->left)) {
376 val = copyValue (AST_VALUE (expr->left));
377 val->type = newLink ();
378 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
379 DCL_TYPE (val->type) = CPOINTER;
380 DCL_PTR_CONST (val->type) = port->mem.code_ro;
382 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
383 DCL_TYPE (val->type) = FPOINTER;
384 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
385 DCL_TYPE (val->type) = PPOINTER;
386 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
387 DCL_TYPE (val->type) = IPOINTER;
388 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
389 DCL_TYPE (val->type) = EEPPOINTER;
391 DCL_TYPE (val->type) = POINTER;
392 val->type->next = expr->left->ftype;
393 val->etype = getSpec (val->type);
397 /* if address of indexed array */
398 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
399 return valForArray (expr->left);
401 /* if address of structure element then
403 if (IS_AST_OP (expr->left) &&
404 expr->left->opval.op == '.') {
405 return valForStructElem (expr->left->left,
410 (&some_struct)->element */
411 if (IS_AST_OP (expr->left) &&
412 expr->left->opval.op == PTR_OP &&
413 IS_ADDRESS_OF_OP (expr->left->left)) {
414 return valForStructElem (expr->left->left->left,
418 /* case 3. (((char *) &a) +/- constant) */
419 if (IS_AST_OP (expr) &&
420 (expr->opval.op == '+' || expr->opval.op == '-') &&
421 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
422 IS_AST_OP (expr->left->right) &&
423 expr->left->right->opval.op == '&' &&
424 IS_AST_LIT_VALUE (expr->right)) {
426 return valForCastAggr (expr->left->right->left,
427 expr->left->left->opval.lnk,
428 expr->right, expr->opval.op);
431 /* case 4. (char *)(array type) */
432 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
433 IS_ARRAY(expr->right->ftype)) {
435 val = copyValue (AST_VALUE (expr->right));
436 val->type = newLink ();
437 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
438 DCL_TYPE (val->type) = CPOINTER;
439 DCL_PTR_CONST (val->type) = port->mem.code_ro;
441 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
442 DCL_TYPE (val->type) = FPOINTER;
443 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
444 DCL_TYPE (val->type) = PPOINTER;
445 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
446 DCL_TYPE (val->type) = IPOINTER;
447 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
448 DCL_TYPE (val->type) = EEPPOINTER;
450 DCL_TYPE (val->type) = POINTER;
451 val->type->next = expr->right->ftype->next;
452 val->etype = getSpec (val->type);
456 werror (E_INCOMPAT_PTYPES);
461 /*-----------------------------------------------------------------*/
462 /* printChar - formats and prints a characater string with DB */
463 /*-----------------------------------------------------------------*/
465 printChar (FILE * ofile, char *s, int plen)
468 int len = strlen (s);
473 while (len && pplen < plen)
476 while (i && *s && pplen < plen)
478 if (*s < ' ' || *s == '\"' || *s=='\\')
482 tfprintf (ofile, "\t!ascii\n", buf);
483 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
498 tfprintf (ofile, "\t!ascii\n", buf);
507 tfprintf (ofile, "\t!db !constbyte\n", 0);
510 /*-----------------------------------------------------------------*/
511 /* return the generic pointer high byte for a given pointer type. */
512 /*-----------------------------------------------------------------*/
514 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
522 werror (E_CANNOT_USE_GENERIC_POINTER,
523 iname ? iname : "<null>",
524 oname ? oname : "<null>");
531 return GPTYPE_XSTACK;
533 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
541 /*-----------------------------------------------------------------*/
542 /* printPointerType - generates ival for pointer type */
543 /*-----------------------------------------------------------------*/
545 _printPointerType (FILE * oFile, const char *name)
547 /* if (TARGET_IS_DS390) */
548 if (options.model == MODEL_FLAT24)
550 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
554 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
558 /*-----------------------------------------------------------------*/
559 /* printPointerType - generates ival for pointer type */
560 /*-----------------------------------------------------------------*/
562 printPointerType (FILE * oFile, const char *name)
564 _printPointerType (oFile, name);
565 fprintf (oFile, "\n");
568 /*-----------------------------------------------------------------*/
569 /* printGPointerType - generates ival for generic pointer type */
570 /*-----------------------------------------------------------------*/
572 printGPointerType (FILE * oFile, const char *iname, const char *oname,
573 const unsigned int type)
575 _printPointerType (oFile, iname);
576 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
579 /*-----------------------------------------------------------------*/
580 /* printIvalType - generates ival for int/char */
581 /*-----------------------------------------------------------------*/
583 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
587 /* if initList is deep */
588 if (ilist->type == INIT_DEEP)
589 ilist = ilist->init.deep;
591 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
592 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
595 if (!(val = list2val (ilist))) {
596 // assuming a warning has been thrown
600 if (val->type != type) {
601 val = valCastLiteral(type, floatFromVal(val));
604 switch (getSize (type)) {
607 tfprintf (oFile, "\t!db !constbyte\n", 0);
609 tfprintf (oFile, "\t!dbs\n",
610 aopLiteral (val, 0));
614 if (port->use_dw_for_init)
615 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
617 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
621 tfprintf (oFile, "\t!dw !constword\n", 0);
622 tfprintf (oFile, "\t!dw !constword\n", 0);
625 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
626 aopLiteral (val, 0), aopLiteral (val, 1),
627 aopLiteral (val, 2), aopLiteral (val, 3));
633 /*-----------------------------------------------------------------*/
634 /* printIvalBitFields - generate initializer for bitfields */
635 /*-----------------------------------------------------------------*/
636 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
640 initList *lilist = *ilist ;
641 unsigned long ival = 0;
647 val = list2val(lilist);
649 if (SPEC_BLEN(lsym->etype) > 8) {
650 size += ((SPEC_BLEN (lsym->etype) / 8) +
651 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
654 size = ((SPEC_BLEN (lsym->etype) / 8) +
655 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
657 i = (unsigned long)floatFromVal(val);
658 i <<= SPEC_BSTR (lsym->etype);
660 if (! ( lsym->next &&
661 (IS_BITFIELD(lsym->next->type)) &&
662 (SPEC_BSTR(lsym->next->etype)))) break;
664 lilist = lilist->next;
668 tfprintf (oFile, "\t!db !constbyte\n",ival);
672 tfprintf (oFile, "\t!dw !constword\n",ival);
675 tfprintf (oFile, "\t!db !constword,!constword\n",
676 (ival >> 8) & 0xffff, (ival & 0xffff));
683 /*-----------------------------------------------------------------*/
684 /* printIvalStruct - generates initial value for structures */
685 /*-----------------------------------------------------------------*/
687 printIvalStruct (symbol * sym, sym_link * type,
688 initList * ilist, FILE * oFile)
693 sflds = SPEC_STRUCT (type)->fields;
694 if (ilist->type != INIT_DEEP) {
695 werror (E_INIT_STRUCT, sym->name);
699 iloop = ilist->init.deep;
701 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
702 if (IS_BITFIELD(sflds->type)) {
703 printIvalBitFields(&sflds,&iloop,oFile);
705 printIval (sym, sflds->type, iloop, oFile);
709 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
714 /*-----------------------------------------------------------------*/
715 /* printIvalChar - generates initital value for character array */
716 /*-----------------------------------------------------------------*/
718 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
726 val = list2val (ilist);
727 /* if the value is a character string */
728 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
730 if (!DCL_ELEM (type))
731 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
733 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
735 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
737 tfprintf (oFile, "\t!db !constbyte\n", 0);
745 printChar (oFile, s, strlen (s) + 1);
749 /*-----------------------------------------------------------------*/
750 /* printIvalArray - generates code for array initialization */
751 /*-----------------------------------------------------------------*/
753 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
757 int lcnt = 0, size = 0;
760 /* take care of the special case */
761 /* array of characters can be init */
763 if (IS_CHAR (type->next)) {
764 if (!IS_LITERAL(list2val(ilist)->etype)) {
765 werror (E_CONST_EXPECTED);
768 if (printIvalChar (type,
769 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
770 oFile, SPEC_CVAL (sym->etype).v_char))
773 /* not the special case */
774 if (ilist->type != INIT_DEEP)
776 werror (E_INIT_STRUCT, sym->name);
780 iloop = ilist->init.deep;
781 lcnt = DCL_ELEM (type);
782 for (last_type = type->next; last_type && DCL_ELEM (last_type); last_type = last_type->next)
783 lcnt *= DCL_ELEM (last_type);
788 printIval (sym, type->next, iloop, oFile);
789 iloop = (iloop ? iloop->next : NULL);
792 /* if not array limits given & we */
793 /* are out of initialisers then */
794 if (!DCL_ELEM (type) && !iloop)
797 /* no of elements given and we */
798 /* have generated for all of them */
800 /* if initializers left */
802 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
808 /* if we have not been given a size */
809 if (!DCL_ELEM (type))
810 DCL_ELEM (type) = size;
815 /*-----------------------------------------------------------------*/
816 /* printIvalFuncPtr - generate initial value for function pointers */
817 /*-----------------------------------------------------------------*/
819 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
824 val = list2val (ilist);
827 // an error has been thrown allready
831 if (IS_LITERAL(val->etype)) {
832 if (compareType(type,val->etype)==0) {
833 werror (E_INCOMPAT_TYPES);
834 printFromToType (val->type, type);
836 printIvalCharPtr (NULL, type, val, oFile);
840 /* check the types */
841 if ((dLvl = compareType (val->type, type->next)) <= 0)
843 tfprintf (oFile, "\t!dw !constword\n", 0);
847 /* now generate the name */
850 if (port->use_dw_for_init)
852 tfprintf (oFile, "\t!dws\n", val->name);
856 printPointerType (oFile, val->name);
859 else if (port->use_dw_for_init)
861 tfprintf (oFile, "\t!dws\n", val->sym->rname);
865 printPointerType (oFile, val->sym->rname);
871 /*-----------------------------------------------------------------*/
872 /* printIvalCharPtr - generates initial values for character pointers */
873 /*-----------------------------------------------------------------*/
875 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
879 /* PENDING: this is _very_ mcs51 specific, including a magic
881 It's also endin specific.
883 size = getSize (type);
885 if (val->name && strlen (val->name))
887 if (size == 1) /* This appears to be Z80 specific?? */
890 "\t!dbs\n", val->name);
892 else if (size == FPTRSIZE)
894 if (port->use_dw_for_init)
896 tfprintf (oFile, "\t!dws\n", val->name);
900 printPointerType (oFile, val->name);
903 else if (size == GPTRSIZE)
906 if (IS_PTR (val->type)) {
907 type = DCL_TYPE (val->type);
909 type = PTR_TYPE (SPEC_OCLS (val->etype));
911 if (val->sym && val->sym->isstrlit) {
912 // this is a literal string
915 printGPointerType (oFile, val->name, sym->name, type);
919 fprintf (stderr, "*** internal error: unknown size in "
920 "printIvalCharPtr.\n");
925 // these are literals assigned to pointers
929 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
932 if (port->use_dw_for_init)
933 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
935 tfprintf (oFile, "\t.byte %s,%s\n",
936 aopLiteral (val, 0), aopLiteral (val, 1));
939 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
940 // non-zero mcs51 generic pointer
941 werror (E_LITERAL_GENERIC);
943 fprintf (oFile, "\t.byte %s,%s,%s\n",
946 aopLiteral (val, 2));
949 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
950 // non-zero ds390 generic pointer
951 werror (E_LITERAL_GENERIC);
953 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
957 aopLiteral (val, 3));
964 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
965 addSet (&statsg->syms, val->sym);
971 /*-----------------------------------------------------------------*/
972 /* printIvalPtr - generates initial value for pointers */
973 /*-----------------------------------------------------------------*/
975 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
981 if (ilist->type == INIT_DEEP)
982 ilist = ilist->init.deep;
984 /* function pointer */
985 if (IS_FUNC (type->next))
987 printIvalFuncPtr (type, ilist, oFile);
991 if (!(val = initPointer (ilist, type)))
994 /* if character pointer */
995 if (IS_CHAR (type->next))
996 if (printIvalCharPtr (sym, type, val, oFile))
1000 if (compareType (type, val->type) == 0) {
1001 werror (W_INIT_WRONG);
1002 printFromToType (val->type, type);
1005 /* if val is literal */
1006 if (IS_LITERAL (val->etype))
1008 switch (getSize (type))
1011 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1014 if (port->use_dw_for_init)
1015 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1017 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1019 case 3: // how about '390??
1020 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1021 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1027 size = getSize (type);
1029 if (size == 1) /* Z80 specific?? */
1031 tfprintf (oFile, "\t!dbs\n", val->name);
1033 else if (size == FPTRSIZE)
1035 if (port->use_dw_for_init) {
1036 tfprintf (oFile, "\t!dws\n", val->name);
1038 printPointerType (oFile, val->name);
1041 else if (size == GPTRSIZE)
1043 printGPointerType (oFile, val->name, sym->name,
1044 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1045 PTR_TYPE (SPEC_OCLS (val->etype))));
1050 /*-----------------------------------------------------------------*/
1051 /* printIval - generates code for initial value */
1052 /*-----------------------------------------------------------------*/
1054 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1059 /* update line number for error msgs */
1060 lineno=sym->lineDef;
1062 /* if structure then */
1063 if (IS_STRUCT (type))
1065 printIvalStruct (sym, type, ilist, oFile);
1069 /* if this is a pointer */
1072 printIvalPtr (sym, type, ilist, oFile);
1076 /* if this is an array */
1077 if (IS_ARRAY (type))
1079 printIvalArray (sym, type, ilist, oFile);
1083 /* if type is SPECIFIER */
1086 printIvalType (sym, type, ilist, oFile);
1091 /*-----------------------------------------------------------------*/
1092 /* emitStaticSeg - emitcode for the static segment */
1093 /*-----------------------------------------------------------------*/
1095 emitStaticSeg (memmap * map, FILE * out)
1099 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1101 /* for all variables in this segment do */
1102 for (sym = setFirstItem (map->syms); sym;
1103 sym = setNextItem (map->syms))
1106 /* if it is "extern" then do nothing */
1107 if (IS_EXTERN (sym->etype))
1110 /* if it is not static add it to the public
1112 if (!IS_STATIC (sym->etype))
1114 addSetHead (&publics, sym);
1117 /* print extra debug info if required */
1118 if (options.debug) {
1119 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1122 if (IS_STATIC (sym->etype))
1123 fprintf (out, "F%s$", moduleName); /* scope is file */
1125 fprintf (out, "G$"); /* scope is global */
1128 /* symbol is local */
1129 fprintf (out, "L%s$",
1130 (sym->localof ? sym->localof->name : "-null-"));
1131 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1134 /* if it has an absolute address */
1135 if (SPEC_ABSA (sym->etype))
1138 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1140 fprintf (out, "%s\t=\t0x%04x\n",
1142 SPEC_ADDR (sym->etype));
1147 fprintf (out, " == .\n");
1149 /* if it has an initial value */
1152 fprintf (out, "%s:\n", sym->rname);
1154 resolveIvalSym (sym->ival);
1155 printIval (sym, sym->type, sym->ival, out);
1157 // now we don't need sym->ival anymore
1158 deleteSetItem(&map->syms, list2val(sym->ival)->sym);
1161 /* allocate space */
1162 int size = getSize (sym->type);
1165 werror(E_UNKNOWN_SIZE,sym->name);
1167 fprintf (out, "%s:\n", sym->rname);
1168 /* special case for character strings */
1169 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1170 SPEC_CVAL (sym->etype).v_char)
1172 SPEC_CVAL (sym->etype).v_char,
1173 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1175 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1181 /*-----------------------------------------------------------------*/
1182 /* emitMaps - emits the code for the data portion the code */
1183 /*-----------------------------------------------------------------*/
1188 /* no special considerations for the following
1189 data, idata & bit & xdata */
1190 emitRegularMap (data, TRUE, TRUE);
1191 emitRegularMap (idata, TRUE, TRUE);
1192 emitRegularMap (bit, TRUE, FALSE);
1193 emitRegularMap (xdata, TRUE, TRUE);
1194 if (port->genXINIT) {
1195 emitRegularMap (xidata, TRUE, TRUE);
1197 emitRegularMap (sfr, FALSE, FALSE);
1198 emitRegularMap (sfrbit, FALSE, FALSE);
1199 emitRegularMap (home, TRUE, FALSE);
1200 emitRegularMap (code, TRUE, FALSE);
1202 emitStaticSeg (statsg, code->oFile);
1203 if (port->genXINIT) {
1204 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1205 emitStaticSeg (xinit, code->oFile);
1210 /*-----------------------------------------------------------------*/
1211 /* flushStatics - flush all currently defined statics out to file */
1212 /* and delete. Temporary function */
1213 /*-----------------------------------------------------------------*/
1217 emitStaticSeg (statsg, codeOutFile);
1218 statsg->syms = NULL;
1221 /*-----------------------------------------------------------------*/
1222 /* createInterruptVect - creates the interrupt vector */
1223 /*-----------------------------------------------------------------*/
1225 createInterruptVect (FILE * vFile)
1228 mainf = newSymbol ("main", 0);
1231 /* only if the main function exists */
1232 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1234 if (!options.cc_only && !noAssemble && !options.c1mode)
1239 /* if the main is only a prototype ie. no body then do nothing */
1240 if (!IFFUNC_HASBODY(mainf->type))
1242 /* if ! compile only then main function should be present */
1243 if (!options.cc_only && !noAssemble)
1248 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1249 fprintf (vFile, "__interrupt_vect:\n");
1252 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1254 /* "generic" interrupt table header (if port doesn't specify one).
1255 * Look suspiciously like 8051 code to me...
1258 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1261 /* now for the other interrupts */
1262 for (; i < maxInterrupts; i++)
1265 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1267 fprintf (vFile, "\treti\n\t.ds\t7\n");
1274 ";--------------------------------------------------------\n"
1275 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1279 ";--------------------------------------------------------\n"};
1282 /*-----------------------------------------------------------------*/
1283 /* initialComments - puts in some initial comments */
1284 /*-----------------------------------------------------------------*/
1286 initialComments (FILE * afile)
1290 fprintf (afile, "%s", iComments1);
1291 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1292 fprintf (afile, "%s", iComments2);
1295 /*-----------------------------------------------------------------*/
1296 /* printPublics - generates .global for publics */
1297 /*-----------------------------------------------------------------*/
1299 printPublics (FILE * afile)
1303 fprintf (afile, "%s", iComments2);
1304 fprintf (afile, "; Public variables in this module\n");
1305 fprintf (afile, "%s", iComments2);
1307 for (sym = setFirstItem (publics); sym;
1308 sym = setNextItem (publics))
1309 tfprintf (afile, "\t!global\n", sym->rname);
1312 /*-----------------------------------------------------------------*/
1313 /* printExterns - generates .global for externs */
1314 /*-----------------------------------------------------------------*/
1316 printExterns (FILE * afile)
1320 fprintf (afile, "%s", iComments2);
1321 fprintf (afile, "; Externals used\n");
1322 fprintf (afile, "%s", iComments2);
1324 for (sym = setFirstItem (externs); sym;
1325 sym = setNextItem (externs))
1326 tfprintf (afile, "\t!extern\n", sym->rname);
1329 /*-----------------------------------------------------------------*/
1330 /* emitOverlay - will emit code for the overlay stuff */
1331 /*-----------------------------------------------------------------*/
1333 emitOverlay (FILE * afile)
1337 if (!elementsInSet (ovrSetSets))
1338 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1340 /* for each of the sets in the overlay segment do */
1341 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1342 ovrset = setNextItem (ovrSetSets))
1347 if (elementsInSet (ovrset))
1349 /* output the area informtion */
1350 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1353 for (sym = setFirstItem (ovrset); sym;
1354 sym = setNextItem (ovrset))
1356 /* if extern then it is in the publics table: do nothing */
1357 if (IS_EXTERN (sym->etype))
1360 /* if allocation required check is needed
1361 then check if the symbol really requires
1362 allocation only for local variables */
1363 if (!IS_AGGREGATE (sym->type) &&
1364 !(sym->_isparm && !IS_REGPARM (sym->etype))
1365 && !sym->allocreq && sym->level)
1368 /* if global variable & not static or extern
1369 and addPublics allowed then add it to the public set */
1370 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1371 && !IS_STATIC (sym->etype))
1373 addSetHead (&publics, sym);
1376 /* if extern then do nothing or is a function
1378 if (IS_FUNC (sym->type))
1381 /* print extra debug info if required */
1384 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1388 if (IS_STATIC (sym->etype))
1389 fprintf (afile, "F%s$", moduleName); /* scope is file */
1391 fprintf (afile, "G$"); /* scope is global */
1394 /* symbol is local */
1395 fprintf (afile, "L%s$",
1396 (sym->localof ? sym->localof->name : "-null-"));
1397 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1400 /* if is has an absolute address then generate
1401 an equate for this no need to allocate space */
1402 if (SPEC_ABSA (sym->etype))
1406 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1408 fprintf (afile, "%s\t=\t0x%04x\n",
1410 SPEC_ADDR (sym->etype));
1413 int size = getSize(sym->type);
1416 werror(E_UNKNOWN_SIZE,sym->name);
1419 fprintf (afile, "==.\n");
1421 /* allocate space */
1422 tfprintf (afile, "!labeldef\n", sym->rname);
1423 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1430 /*-----------------------------------------------------------------*/
1431 /* glue - the final glue that hold the whole thing together */
1432 /*-----------------------------------------------------------------*/
1438 FILE *ovrFile = tempfile ();
1440 addSetHead (&tmpfileSet, ovrFile);
1441 /* print the global struct definitions */
1443 cdbStructBlock (0, cdbFile);
1445 vFile = tempfile ();
1446 /* PENDING: this isnt the best place but it will do */
1447 if (port->general.glue_up_main)
1449 /* create the interrupt vector table */
1450 createInterruptVect (vFile);
1453 addSetHead (&tmpfileSet, vFile);
1455 /* emit code for the all the variables declared */
1457 /* do the overlay segments */
1458 emitOverlay (ovrFile);
1460 /* now put it all together into the assembler file */
1461 /* create the assembler file name */
1463 /* -o option overrides default name? */
1464 if ((noAssemble || options.c1mode) && fullDstFileName)
1466 strcpy (scratchFileName, fullDstFileName);
1470 strcpy (scratchFileName, dstFileName);
1471 strcat (scratchFileName, port->assembler.file_ext);
1474 if (!(asmFile = fopen (scratchFileName, "w")))
1476 werror (E_FILE_OPEN_ERR, scratchFileName);
1480 /* initial comments */
1481 initialComments (asmFile);
1483 /* print module name */
1484 tfprintf (asmFile, "\t!module\n", moduleName);
1485 tfprintf (asmFile, "\t!fileprelude\n");
1487 /* Let the port generate any global directives, etc. */
1488 if (port->genAssemblerPreamble)
1490 port->genAssemblerPreamble (asmFile);
1493 /* print the global variables in this module */
1494 printPublics (asmFile);
1495 if (port->assembler.externGlobal)
1496 printExterns (asmFile);
1498 /* copy the sfr segment */
1499 fprintf (asmFile, "%s", iComments2);
1500 fprintf (asmFile, "; special function registers\n");
1501 fprintf (asmFile, "%s", iComments2);
1502 copyFile (asmFile, sfr->oFile);
1504 /* copy the sbit segment */
1505 fprintf (asmFile, "%s", iComments2);
1506 fprintf (asmFile, "; special function bits \n");
1507 fprintf (asmFile, "%s", iComments2);
1508 copyFile (asmFile, sfrbit->oFile);
1510 /*JCF: Create the areas for the register banks*/
1511 if(port->general.glue_up_main &&
1512 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51))
1514 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1516 fprintf (asmFile, "%s", iComments2);
1517 fprintf (asmFile, "; overlayable register banks \n");
1518 fprintf (asmFile, "%s", iComments2);
1520 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1521 if(RegBankUsed[1]||options.parms_in_bank1)
1522 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1524 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1526 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1530 /* copy the data segment */
1531 fprintf (asmFile, "%s", iComments2);
1532 fprintf (asmFile, "; internal ram data\n");
1533 fprintf (asmFile, "%s", iComments2);
1534 copyFile (asmFile, data->oFile);
1537 /* create the overlay segments */
1539 fprintf (asmFile, "%s", iComments2);
1540 fprintf (asmFile, "; overlayable items in internal ram \n");
1541 fprintf (asmFile, "%s", iComments2);
1542 copyFile (asmFile, ovrFile);
1545 /* create the stack segment MOF */
1546 if (mainf && IFFUNC_HASBODY(mainf->type))
1548 fprintf (asmFile, "%s", iComments2);
1549 fprintf (asmFile, "; Stack segment in internal ram \n");
1550 fprintf (asmFile, "%s", iComments2);
1551 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1552 "__start__stack:\n\t.ds\t1\n\n");
1555 /* create the idata segment */
1557 fprintf (asmFile, "%s", iComments2);
1558 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1559 fprintf (asmFile, "%s", iComments2);
1560 copyFile (asmFile, idata->oFile);
1563 /* copy the bit segment */
1564 fprintf (asmFile, "%s", iComments2);
1565 fprintf (asmFile, "; bit data\n");
1566 fprintf (asmFile, "%s", iComments2);
1567 copyFile (asmFile, bit->oFile);
1569 /* if external stack then reserve space of it */
1570 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1572 fprintf (asmFile, "%s", iComments2);
1573 fprintf (asmFile, "; external stack \n");
1574 fprintf (asmFile, "%s", iComments2);
1575 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1576 fprintf (asmFile, "\t.ds 256\n");
1580 /* copy xtern ram data */
1581 fprintf (asmFile, "%s", iComments2);
1582 fprintf (asmFile, "; external ram data\n");
1583 fprintf (asmFile, "%s", iComments2);
1584 copyFile (asmFile, xdata->oFile);
1586 /* copy xternal initialized ram data */
1587 fprintf (asmFile, "%s", iComments2);
1588 fprintf (asmFile, "; external initialized ram data\n");
1589 fprintf (asmFile, "%s", iComments2);
1590 copyFile (asmFile, xidata->oFile);
1592 /* copy the interrupt vector table */
1593 if (mainf && IFFUNC_HASBODY(mainf->type))
1595 fprintf (asmFile, "%s", iComments2);
1596 fprintf (asmFile, "; interrupt vector \n");
1597 fprintf (asmFile, "%s", iComments2);
1598 copyFile (asmFile, vFile);
1601 /* copy global & static initialisations */
1602 fprintf (asmFile, "%s", iComments2);
1603 fprintf (asmFile, "; global & static initialisations\n");
1604 fprintf (asmFile, "%s", iComments2);
1606 /* Everywhere we generate a reference to the static_name area,
1607 * (which is currently only here), we immediately follow it with a
1608 * definition of the post_static_name area. This guarantees that
1609 * the post_static_name area will immediately follow the static_name
1612 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1613 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1614 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1616 if (mainf && IFFUNC_HASBODY(mainf->type))
1618 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1619 /* if external stack is specified then the
1620 higher order byte of the xdatalocation is
1621 going into P2 and the lower order going into
1623 if (options.useXstack)
1625 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1626 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1627 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1628 (unsigned int) options.xdata_loc & 0xff);
1631 /* initialise the stack pointer. JCF: aslink takes care of the location */
1632 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1634 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1635 fprintf (asmFile, "\tmov\ta,dpl\n");
1636 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1637 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1638 fprintf (asmFile, "__sdcc_init_data:\n");
1640 // if the port can copy the XINIT segment to XISEG
1641 if (port->genXINIT) {
1642 port->genXINIT(asmFile);
1646 copyFile (asmFile, statsg->oFile);
1648 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1650 /* This code is generated in the post-static area.
1651 * This area is guaranteed to follow the static area
1652 * by the ugly shucking and jiving about 20 lines ago.
1654 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1655 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1661 "%s", iComments2, iComments2);
1662 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1663 copyFile (asmFile, home->oFile);
1665 /* copy over code */
1666 fprintf (asmFile, "%s", iComments2);
1667 fprintf (asmFile, "; code\n");
1668 fprintf (asmFile, "%s", iComments2);
1669 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1670 if (mainf && IFFUNC_HASBODY(mainf->type))
1673 /* entry point @ start of CSEG */
1674 fprintf (asmFile, "__sdcc_program_startup:\n");
1676 /* put in the call to main */
1677 fprintf (asmFile, "\tlcall\t_main\n");
1678 if (options.mainreturn)
1681 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1682 fprintf (asmFile, "\tret\n");
1688 fprintf (asmFile, ";\treturn from main will lock up\n");
1689 fprintf (asmFile, "\tsjmp .\n");
1692 copyFile (asmFile, code->oFile);
1694 if (port->genAssemblerEnd) {
1695 port->genAssemblerEnd(asmFile);
1702 /** Creates a temporary file name a'la tmpnam which avoids the bugs
1703 in cygwin wrt c:\tmp.
1704 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1709 const char *tmpdir = NULL;
1711 tmpdir = getenv ("TMP");
1712 else if (getenv ("TEMP"))
1713 tmpdir = getenv ("TEMP");
1714 else if (getenv ("TMPDIR"))
1715 tmpdir = getenv ("TMPDIR");
1718 char *name = tempnam (tmpdir, "sdcc");
1724 return tmpnam (NULL);
1727 /** Creates a temporary file a'la tmpfile which avoids the bugs
1728 in cygwin wrt c:\tmp.
1729 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1734 const char *tmpdir = NULL;
1736 tmpdir = getenv ("TMP");
1737 else if (getenv ("TEMP"))
1738 tmpdir = getenv ("TEMP");
1739 else if (getenv ("TMPDIR"))
1740 tmpdir = getenv ("TMPDIR");
1743 char *name = Safe_strdup( tempnam (tmpdir, "sdcc"));
1746 FILE *fp = fopen (name, "w+b");
1749 addSetHead (&tmpfileNameSet, name);