1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
34 symbol *interrupts[256];
36 void printIval (symbol *, sym_link *, initList *, FILE *);
37 set *publics = NULL; /* public variables */
38 set *externs = NULL; /* Varibles that are declared as extern */
40 /* TODO: this should be configurable (DS803C90 uses more than 6) */
41 unsigned maxInterrupts = 6;
44 extern char *VersionString;
45 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
46 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
48 /*-----------------------------------------------------------------*/
49 /* closeTmpFiles - closes all tmp files created by the compiler */
50 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
51 /*-----------------------------------------------------------------*/
52 DEFSETFUNC (closeTmpFiles)
62 /*-----------------------------------------------------------------*/
63 /* rmTmpFiles - closes all tmp files created by the compiler */
64 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
65 /*-----------------------------------------------------------------*/
66 DEFSETFUNC (rmTmpFiles)
78 /*-----------------------------------------------------------------*/
79 /* copyFile - copies source file to destination file */
80 /*-----------------------------------------------------------------*/
82 copyFile (FILE * dest, FILE * src)
88 if ((ch = fgetc (src)) != EOF)
93 aopLiteralLong (value * val, int offset, int size)
103 // assuming we have been warned before
107 /* if it is a float then it gets tricky */
108 /* otherwise it is fairly simple */
109 if (!IS_FLOAT (val->type)) {
110 unsigned long v = (unsigned long) floatFromVal (val);
115 tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
118 tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
121 /* Hmm. Too big for now. */
124 rs = Safe_calloc (1, strlen (buffer) + 1);
125 return strcpy (rs, buffer);
128 /* PENDING: For now size must be 1 */
131 /* it is type float */
132 fl.f = (float) floatFromVal (val);
134 tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
136 tsprintf (buffer, "!immedbyte", fl.c[offset]);
138 rs = Safe_calloc (1, strlen (buffer) + 1);
139 return strcpy (rs, buffer);
142 /*-----------------------------------------------------------------*/
143 /* aopLiteral - string from a literal value */
144 /*-----------------------------------------------------------------*/
146 aopLiteral (value * val, int offset)
148 return aopLiteralLong (val, offset, 1);
151 /*-----------------------------------------------------------------*/
152 /* emitRegularMap - emit code for maps with no special cases */
153 /*-----------------------------------------------------------------*/
155 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
157 symbol *sym, *symIval;
163 /* PENDING: special case here - should remove */
164 if (!strcmp (map->sname, CODE_NAME))
165 tfprintf (map->oFile, "\t!areacode\n", map->sname);
166 else if (!strcmp (map->sname, DATA_NAME))
167 tfprintf (map->oFile, "\t!areadata\n", map->sname);
168 else if (!strcmp (map->sname, HOME_NAME))
169 tfprintf (map->oFile, "\t!areahome\n", map->sname);
171 tfprintf (map->oFile, "\t!area\n", map->sname);
174 for (sym = setFirstItem (map->syms); sym;
175 sym = setNextItem (map->syms))
180 /* if extern then add it into the extern list */
181 if (IS_EXTERN (sym->etype))
183 addSetHead (&externs, sym);
187 /* if allocation required check is needed
188 then check if the symbol really requires
189 allocation only for local variables */
191 if (arFlag && !IS_AGGREGATE (sym->type) &&
192 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
193 !sym->allocreq && sym->level)
196 /* for bitvar locals and parameters */
197 if (!arFlag && !sym->allocreq && sym->level
198 && !SPEC_ABSA (sym->etype)) {
202 /* if global variable & not static or extern
203 and addPublics allowed then add it to the public set */
204 if ((sym->level == 0 ||
205 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
207 !IS_STATIC (sym->etype) &&
208 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
210 addSetHead (&publics, sym);
213 /* if extern then do nothing or is a function
215 if (IS_FUNC (sym->type))
218 /* print extra debug info if required */
220 cdbSymbol (sym, cdbFile, FALSE, FALSE);
221 if (!sym->level) /* global */
222 if (IS_STATIC (sym->etype))
223 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
225 fprintf (map->oFile, "G$"); /* scope is global */
227 /* symbol is local */
228 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
229 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
232 /* if it has an initial value then do it only if
233 it is a global variable */
234 if (sym->ival && sym->level == 0) {
235 if (SPEC_OCLS(sym->etype)==xidata) {
236 // create a new "XINIT (CODE)" symbol, that will be emitted later
237 newSym=copySymbol (sym);
238 SPEC_OCLS(newSym->etype)=xinit;
239 sprintf (newSym->name, "_xinit_%s", sym->name);
240 sprintf (newSym->rname,"_xinit_%s", sym->rname);
241 SPEC_CONST(newSym->etype)=1;
242 //SPEC_STAT(newSym->etype)=1;
243 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
245 // add it to the "XINIT (CODE)" segment
246 addSet(&xinit->syms, newSym);
248 //fprintf (stderr, "moved %s from xdata to xidata\n", sym->rname);
251 if (IS_AGGREGATE (sym->type)) {
252 ival = initAggregates (sym, sym->ival, NULL);
254 if (getNelements(sym->type, sym->ival)>1) {
255 werror (W_EXCESS_INITIALIZERS, "scalar",
256 sym->name, sym->lineDef);
258 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
259 decorateType (resolveSymbols (list2expr (sym->ival))));
261 codeOutFile = statsg->oFile;
264 // set ival's lineno to where the symbol was defined
265 if (ival) ival->lineno=sym->lineDef;
266 eBBlockFromiCode (iCodeFromAst (ival));
270 /* if the ival is a symbol assigned to an aggregate,
271 (bug #458099 -> #462479)
272 we don't need it anymore, so delete it from its segment */
273 if (sym->ival->type == INIT_NODE &&
274 IS_AST_SYM_VALUE(sym->ival->init.node) &&
275 IS_AGGREGATE (sym->type) ) {
276 symIval=AST_SYMBOL(sym->ival->init.node);
277 segment = SPEC_OCLS (symIval->etype);
278 deleteSetItem (&segment->syms, symIval);
284 /* if is has an absolute address then generate
285 an equate for this no need to allocate space */
286 if (SPEC_ABSA (sym->etype))
289 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
291 fprintf (map->oFile, "%s\t=\t0x%04x\n",
293 SPEC_ADDR (sym->etype));
297 // this has been moved to another segment
299 int size = getSize (sym->type);
301 werror(E_UNKNOWN_SIZE,sym->name);
305 fprintf (map->oFile, "==.\n");
307 if (IS_STATIC (sym->etype))
308 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
310 tfprintf (map->oFile, "!labeldef\n", sym->rname);
311 tfprintf (map->oFile, "\t!ds\n",
312 (unsigned int) size & 0xffff);
318 /*-----------------------------------------------------------------*/
319 /* initPointer - pointer initialization code massaging */
320 /*-----------------------------------------------------------------*/
322 initPointer (initList * ilist)
325 ast *expr = list2expr (ilist);
330 /* try it the oldway first */
331 if ((val = constExprValue (expr, FALSE)))
334 /* no then we have to do these cludgy checks */
335 /* pointers can be initialized with address of
336 a variable or address of an array element */
337 if (IS_AST_OP (expr) && expr->opval.op == '&') {
338 /* address of symbol */
339 if (IS_AST_SYM_VALUE (expr->left)) {
340 val = copyValue (AST_VALUE (expr->left));
341 val->type = newLink ();
342 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
343 DCL_TYPE (val->type) = CPOINTER;
344 DCL_PTR_CONST (val->type) = port->mem.code_ro;
346 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
347 DCL_TYPE (val->type) = FPOINTER;
348 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
349 DCL_TYPE (val->type) = PPOINTER;
350 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
351 DCL_TYPE (val->type) = IPOINTER;
352 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
353 DCL_TYPE (val->type) = EEPPOINTER;
355 DCL_TYPE (val->type) = POINTER;
356 val->type->next = expr->left->ftype;
357 val->etype = getSpec (val->type);
361 /* if address of indexed array */
362 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
363 return valForArray (expr->left);
365 /* if address of structure element then
367 if (IS_AST_OP (expr->left) &&
368 expr->left->opval.op == '.') {
369 return valForStructElem (expr->left->left,
374 (&some_struct)->element */
375 if (IS_AST_OP (expr->left) &&
376 expr->left->opval.op == PTR_OP &&
377 IS_ADDRESS_OF_OP (expr->left->left))
378 return valForStructElem (expr->left->left->left,
382 /* case 3. (((char *) &a) +/- constant) */
383 if (IS_AST_OP (expr) &&
384 (expr->opval.op == '+' || expr->opval.op == '-') &&
385 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
386 IS_AST_OP (expr->left->right) &&
387 expr->left->right->opval.op == '&' &&
388 IS_AST_LIT_VALUE (expr->right)) {
390 return valForCastAggr (expr->left->right->left,
391 expr->left->left->opval.lnk,
392 expr->right, expr->opval.op);
396 /* case 4. (char *)(array type) */
397 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
398 IS_ARRAY(expr->right->ftype)) {
400 val = copyValue (AST_VALUE (expr->right));
401 val->type = newLink ();
402 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
403 DCL_TYPE (val->type) = CPOINTER;
404 DCL_PTR_CONST (val->type) = port->mem.code_ro;
406 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
407 DCL_TYPE (val->type) = FPOINTER;
408 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
409 DCL_TYPE (val->type) = PPOINTER;
410 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
411 DCL_TYPE (val->type) = IPOINTER;
412 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
413 DCL_TYPE (val->type) = EEPPOINTER;
415 DCL_TYPE (val->type) = POINTER;
416 val->type->next = expr->right->ftype->next;
417 val->etype = getSpec (val->type);
421 werror (W_INIT_WRONG);
426 /*-----------------------------------------------------------------*/
427 /* printChar - formats and prints a characater string with DB */
428 /*-----------------------------------------------------------------*/
430 printChar (FILE * ofile, char *s, int plen)
433 int len = strlen (s);
438 while (len && pplen < plen)
441 while (i && *s && pplen < plen)
443 if (*s < ' ' || *s == '\"' || *s=='\\')
447 tfprintf (ofile, "\t!ascii\n", buf);
448 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
463 tfprintf (ofile, "\t!ascii\n", buf);
472 tfprintf (ofile, "\t!db !constbyte\n", 0);
475 /*-----------------------------------------------------------------*/
476 /* return the generic pointer high byte for a given pointer type. */
477 /*-----------------------------------------------------------------*/
479 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
487 /* hack - if we get a generic pointer, we just assume
488 * it's an FPOINTER (i.e. in XDATA space).
490 werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname);
500 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
508 /*-----------------------------------------------------------------*/
509 /* printPointerType - generates ival for pointer type */
510 /*-----------------------------------------------------------------*/
512 _printPointerType (FILE * oFile, const char *name)
514 /* if (TARGET_IS_DS390) */
515 if (options.model == MODEL_FLAT24)
517 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
521 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
525 /*-----------------------------------------------------------------*/
526 /* printPointerType - generates ival for pointer type */
527 /*-----------------------------------------------------------------*/
529 printPointerType (FILE * oFile, const char *name)
531 _printPointerType (oFile, name);
532 fprintf (oFile, "\n");
535 /*-----------------------------------------------------------------*/
536 /* printGPointerType - generates ival for generic pointer type */
537 /*-----------------------------------------------------------------*/
539 printGPointerType (FILE * oFile, const char *iname, const char *oname,
540 const unsigned int type)
542 _printPointerType (oFile, iname);
543 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
546 /*-----------------------------------------------------------------*/
547 /* printIvalType - generates ival for int/char */
548 /*-----------------------------------------------------------------*/
550 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
554 /* if initList is deep */
555 if (ilist->type == INIT_DEEP)
556 ilist = ilist->init.deep;
558 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
559 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
562 val = list2val (ilist);
563 if (val->type != type) {
564 val = valCastLiteral(type, floatFromVal(val));
567 switch (getSize (type)) {
570 tfprintf (oFile, "\t!db !constbyte\n", 0);
572 tfprintf (oFile, "\t!dbs\n",
573 aopLiteral (val, 0));
577 if (port->use_dw_for_init)
578 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
580 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
584 tfprintf (oFile, "\t!dw !constword\n", 0);
585 tfprintf (oFile, "\t!dw !constword\n", 0);
588 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
589 aopLiteral (val, 0), aopLiteral (val, 1),
590 aopLiteral (val, 2), aopLiteral (val, 3));
596 /*-----------------------------------------------------------------*/
597 /* printIvalBitFields - generate initializer for bitfields */
598 /*-----------------------------------------------------------------*/
599 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
603 initList *lilist = *ilist ;
604 unsigned long ival = 0;
610 val = list2val(lilist);
612 if (SPEC_BLEN(lsym->etype) > 8) {
613 size += ((SPEC_BLEN (lsym->etype) / 8) +
614 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
617 size = ((SPEC_BLEN (lsym->etype) / 8) +
618 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
620 i = (unsigned long)floatFromVal(val);
621 i <<= SPEC_BSTR (lsym->etype);
623 if (! ( lsym->next &&
624 (IS_BITFIELD(lsym->next->type)) &&
625 (SPEC_BSTR(lsym->next->etype)))) break;
627 lilist = lilist->next;
631 tfprintf (oFile, "\t!db !constbyte\n",ival);
635 tfprintf (oFile, "\t!dw !constword\n",ival);
638 tfprintf (oFile, "\t!db !constword,!constword\n",
639 (ival >> 8) & 0xffff, (ival & 0xffff));
646 /*-----------------------------------------------------------------*/
647 /* printIvalStruct - generates initial value for structures */
648 /*-----------------------------------------------------------------*/
650 printIvalStruct (symbol * sym, sym_link * type,
651 initList * ilist, FILE * oFile)
656 sflds = SPEC_STRUCT (type)->fields;
657 if (ilist->type != INIT_DEEP) {
658 werror (E_INIT_STRUCT, sym->name);
662 iloop = ilist->init.deep;
664 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
665 if (IS_BITFIELD(sflds->type)) {
666 printIvalBitFields(&sflds,&iloop,oFile);
668 printIval (sym, sflds->type, iloop, oFile);
672 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
677 /*-----------------------------------------------------------------*/
678 /* printIvalChar - generates initital value for character array */
679 /*-----------------------------------------------------------------*/
681 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
689 val = list2val (ilist);
690 /* if the value is a character string */
691 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
693 if (!DCL_ELEM (type))
694 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
696 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
698 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
700 tfprintf (oFile, "\t!db !constbyte\n", 0);
708 printChar (oFile, s, strlen (s) + 1);
712 /*-----------------------------------------------------------------*/
713 /* printIvalArray - generates code for array initialization */
714 /*-----------------------------------------------------------------*/
716 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
720 int lcnt = 0, size = 0;
722 /* take care of the special case */
723 /* array of characters can be init */
725 if (IS_CHAR (type->next))
726 if (printIvalChar (type,
727 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
728 oFile, SPEC_CVAL (sym->etype).v_char))
731 /* not the special case */
732 if (ilist->type != INIT_DEEP)
734 werror (E_INIT_STRUCT, sym->name);
738 iloop = ilist->init.deep;
739 lcnt = DCL_ELEM (type);
744 printIval (sym, type->next, iloop, oFile);
745 iloop = (iloop ? iloop->next : NULL);
748 /* if not array limits given & we */
749 /* are out of initialisers then */
750 if (!DCL_ELEM (type) && !iloop)
753 /* no of elements given and we */
754 /* have generated for all of them */
756 /* if initializers left */
758 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
764 /* if we have not been given a size */
765 if (!DCL_ELEM (type))
766 DCL_ELEM (type) = size;
771 /*-----------------------------------------------------------------*/
772 /* printIvalFuncPtr - generate initial value for function pointers */
773 /*-----------------------------------------------------------------*/
775 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
780 val = list2val (ilist);
781 /* check the types */
782 if ((dLvl = compareType (val->type, type->next)) <= 0)
784 tfprintf (oFile, "\t!dw !constword\n", 0);
788 /* now generate the name */
791 if (port->use_dw_for_init)
793 tfprintf (oFile, "\t!dws\n", val->name);
797 printPointerType (oFile, val->name);
800 else if (port->use_dw_for_init)
802 tfprintf (oFile, "\t!dws\n", val->sym->rname);
806 printPointerType (oFile, val->sym->rname);
812 /*-----------------------------------------------------------------*/
813 /* printIvalCharPtr - generates initial values for character pointers */
814 /*-----------------------------------------------------------------*/
816 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
820 /* PENDING: this is _very_ mcs51 specific, including a magic
822 It's also endin specific.
824 size = getSize (type);
826 if (val->name && strlen (val->name))
828 if (size == 1) /* This appears to be Z80 specific?? */
831 "\t!dbs\n", val->name);
833 else if (size == FPTRSIZE)
835 if (port->use_dw_for_init)
837 tfprintf (oFile, "\t!dws\n", val->name);
841 printPointerType (oFile, val->name);
844 else if (size == GPTRSIZE)
847 if (IS_PTR (val->type)) {
848 type = DCL_TYPE (val->type);
850 type = PTR_TYPE (SPEC_OCLS (val->etype));
852 if (val->sym && val->sym->isstrlit) {
853 // this is a literal string
856 printGPointerType (oFile, val->name, sym->name, type);
860 fprintf (stderr, "*** internal error: unknown size in "
861 "printIvalCharPtr.\n");
866 // these are literals assigned to pointers
870 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
873 if (port->use_dw_for_init)
874 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
876 tfprintf (oFile, "\t.byte %s,%s\n",
877 aopLiteral (val, 0), aopLiteral (val, 1));
880 // mcs51 generic pointer
881 if (floatFromVal(val)!=0) {
882 werror (E_LITERAL_GENERIC);
884 fprintf (oFile, "\t.byte %s,%s,%s\n",
887 aopLiteral (val, 2));
890 // ds390 generic pointer
891 if (floatFromVal(val)!=0) {
892 werror (E_LITERAL_GENERIC);
894 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
898 aopLiteral (val, 3));
905 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
906 addSet (&statsg->syms, val->sym);
912 /*-----------------------------------------------------------------*/
913 /* printIvalPtr - generates initial value for pointers */
914 /*-----------------------------------------------------------------*/
916 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
922 if (ilist->type == INIT_DEEP)
923 ilist = ilist->init.deep;
925 /* function pointer */
926 if (IS_FUNC (type->next))
928 printIvalFuncPtr (type, ilist, oFile);
932 if (!(val = initPointer (ilist)))
935 /* if character pointer */
936 if (IS_CHAR (type->next))
937 if (printIvalCharPtr (sym, type, val, oFile))
941 if (compareType (type, val->type) == 0)
942 werror (W_INIT_WRONG);
944 /* if val is literal */
945 if (IS_LITERAL (val->etype))
947 switch (getSize (type))
950 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
953 if (port->use_dw_for_init)
954 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
956 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
959 fprintf (oFile, "\t.byte %s,%s,#0x02\n",
960 aopLiteral (val, 0), aopLiteral (val, 1));
966 size = getSize (type);
968 if (size == 1) /* Z80 specific?? */
970 tfprintf (oFile, "\t!dbs\n", val->name);
972 else if (size == FPTRSIZE)
974 if (port->use_dw_for_init) {
975 tfprintf (oFile, "\t!dws\n", val->name);
977 printPointerType (oFile, val->name);
980 else if (size == GPTRSIZE)
982 printGPointerType (oFile, val->name, sym->name,
983 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
984 PTR_TYPE (SPEC_OCLS (val->etype))));
989 /*-----------------------------------------------------------------*/
990 /* printIval - generates code for initial value */
991 /*-----------------------------------------------------------------*/
993 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
998 /* if structure then */
999 if (IS_STRUCT (type))
1001 printIvalStruct (sym, type, ilist, oFile);
1005 /* if this is a pointer */
1008 printIvalPtr (sym, type, ilist, oFile);
1012 /* if this is an array */
1013 if (IS_ARRAY (type))
1015 printIvalArray (sym, type, ilist, oFile);
1019 /* if type is SPECIFIER */
1022 printIvalType (sym, type, ilist, oFile);
1027 /*-----------------------------------------------------------------*/
1028 /* emitStaticSeg - emitcode for the static segment */
1029 /*-----------------------------------------------------------------*/
1031 emitStaticSeg (memmap * map, FILE * out)
1035 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1037 /* for all variables in this segment do */
1038 for (sym = setFirstItem (map->syms); sym;
1039 sym = setNextItem (map->syms))
1042 /* if it is "extern" then do nothing */
1043 if (IS_EXTERN (sym->etype))
1046 /* if it is not static add it to the public
1048 if (!IS_STATIC (sym->etype))
1049 addSetHead (&publics, sym);
1051 /* print extra debug info if required */
1052 if (options.debug) {
1053 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1056 if (IS_STATIC (sym->etype))
1057 fprintf (out, "F%s$", moduleName); /* scope is file */
1059 fprintf (out, "G$"); /* scope is global */
1062 /* symbol is local */
1063 fprintf (out, "L%s$",
1064 (sym->localof ? sym->localof->name : "-null-"));
1065 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1068 /* if it has an absolute address */
1069 if (SPEC_ABSA (sym->etype))
1072 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1074 fprintf (out, "%s\t=\t0x%04x\n",
1076 SPEC_ADDR (sym->etype));
1081 fprintf (out, " == .\n");
1083 /* if it has an initial value */
1086 fprintf (out, "%s:\n", sym->rname);
1088 resolveIvalSym (sym->ival);
1089 printIval (sym, sym->type, sym->ival, out);
1093 /* allocate space */
1094 int size = getSize (sym->type);
1097 werror(E_UNKNOWN_SIZE,sym->name);
1099 fprintf (out, "%s:\n", sym->rname);
1100 /* special case for character strings */
1101 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1102 SPEC_CVAL (sym->etype).v_char)
1104 SPEC_CVAL (sym->etype).v_char,
1105 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1107 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1113 /*-----------------------------------------------------------------*/
1114 /* emitMaps - emits the code for the data portion the code */
1115 /*-----------------------------------------------------------------*/
1120 /* no special considerations for the following
1121 data, idata & bit & xdata */
1122 emitRegularMap (data, TRUE, TRUE);
1123 emitRegularMap (idata, TRUE, TRUE);
1124 emitRegularMap (bit, TRUE, FALSE);
1125 emitRegularMap (xdata, TRUE, TRUE);
1126 if (port->genXINIT) {
1127 emitRegularMap (xidata, TRUE, TRUE);
1129 emitRegularMap (sfr, FALSE, FALSE);
1130 emitRegularMap (sfrbit, FALSE, FALSE);
1131 emitRegularMap (home, TRUE, FALSE);
1132 emitRegularMap (code, TRUE, FALSE);
1134 emitStaticSeg (statsg, code->oFile);
1135 if (port->genXINIT) {
1136 fprintf (code->oFile, "\t.area\t%s\n", xinit->sname);
1137 emitStaticSeg (xinit, code->oFile);
1142 /*-----------------------------------------------------------------*/
1143 /* flushStatics - flush all currently defined statics out to file */
1144 /* and delete. Temporary function */
1145 /*-----------------------------------------------------------------*/
1149 emitStaticSeg (statsg, codeOutFile);
1150 statsg->syms = NULL;
1153 /*-----------------------------------------------------------------*/
1154 /* createInterruptVect - creates the interrupt vector */
1155 /*-----------------------------------------------------------------*/
1157 createInterruptVect (FILE * vFile)
1160 mainf = newSymbol ("main", 0);
1163 /* only if the main function exists */
1164 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1166 if (!options.cc_only && !noAssemble)
1171 /* if the main is only a prototype ie. no body then do nothing */
1172 if (!IFFUNC_HASBODY(mainf->type))
1174 /* if ! compile only then main function should be present */
1175 if (!options.cc_only && !noAssemble)
1180 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1181 fprintf (vFile, "__interrupt_vect:\n");
1184 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1186 /* "generic" interrupt table header (if port doesn't specify one).
1187 * Look suspiciously like 8051 code to me...
1190 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1193 /* now for the other interrupts */
1194 for (; i < maxInterrupts; i++)
1197 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1199 fprintf (vFile, "\treti\n\t.ds\t7\n");
1206 ";--------------------------------------------------------\n"
1207 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1211 ";--------------------------------------------------------\n"};
1214 /*-----------------------------------------------------------------*/
1215 /* initialComments - puts in some initial comments */
1216 /*-----------------------------------------------------------------*/
1218 initialComments (FILE * afile)
1222 fprintf (afile, "%s", iComments1);
1223 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1224 fprintf (afile, "%s", iComments2);
1227 /*-----------------------------------------------------------------*/
1228 /* printPublics - generates .global for publics */
1229 /*-----------------------------------------------------------------*/
1231 printPublics (FILE * afile)
1235 fprintf (afile, "%s", iComments2);
1236 fprintf (afile, "; Public variables in this module\n");
1237 fprintf (afile, "%s", iComments2);
1239 for (sym = setFirstItem (publics); sym;
1240 sym = setNextItem (publics))
1241 tfprintf (afile, "\t!global\n", sym->rname);
1244 /*-----------------------------------------------------------------*/
1245 /* printExterns - generates .global for externs */
1246 /*-----------------------------------------------------------------*/
1248 printExterns (FILE * afile)
1252 fprintf (afile, "%s", iComments2);
1253 fprintf (afile, "; Externals used\n");
1254 fprintf (afile, "%s", iComments2);
1256 for (sym = setFirstItem (externs); sym;
1257 sym = setNextItem (externs))
1258 tfprintf (afile, "\t!global\n", sym->rname);
1261 /*-----------------------------------------------------------------*/
1262 /* emitOverlay - will emit code for the overlay stuff */
1263 /*-----------------------------------------------------------------*/
1265 emitOverlay (FILE * afile)
1269 if (!elementsInSet (ovrSetSets))
1270 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1272 /* for each of the sets in the overlay segment do */
1273 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1274 ovrset = setNextItem (ovrSetSets))
1279 if (elementsInSet (ovrset))
1282 /* this dummy area is used to fool the assembler
1283 otherwise the assembler will append each of these
1284 declarations into one chunk and will not overlay
1286 fprintf (afile, "\t.area _DUMMY\n");
1288 /* not anymore since asmain.c:1.13 */
1290 /* output the area informtion */
1291 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1294 for (sym = setFirstItem (ovrset); sym;
1295 sym = setNextItem (ovrset))
1298 /* if extern then add it to the publics tabledo nothing */
1299 if (IS_EXTERN (sym->etype))
1302 /* if allocation required check is needed
1303 then check if the symbol really requires
1304 allocation only for local variables */
1305 if (!IS_AGGREGATE (sym->type) &&
1306 !(sym->_isparm && !IS_REGPARM (sym->etype))
1307 && !sym->allocreq && sym->level)
1310 /* if global variable & not static or extern
1311 and addPublics allowed then add it to the public set */
1312 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1313 && !IS_STATIC (sym->etype))
1314 addSetHead (&publics, sym);
1316 /* if extern then do nothing or is a function
1318 if (IS_FUNC (sym->type))
1321 /* print extra debug info if required */
1324 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1328 if (IS_STATIC (sym->etype))
1329 fprintf (afile, "F%s$", moduleName); /* scope is file */
1331 fprintf (afile, "G$"); /* scope is global */
1334 /* symbol is local */
1335 fprintf (afile, "L%s$",
1336 (sym->localof ? sym->localof->name : "-null-"));
1337 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1340 /* if is has an absolute address then generate
1341 an equate for this no need to allocate space */
1342 if (SPEC_ABSA (sym->etype))
1346 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1348 fprintf (afile, "%s\t=\t0x%04x\n",
1350 SPEC_ADDR (sym->etype));
1353 int size = getSize(sym->type);
1356 werror(E_UNKNOWN_SIZE,sym->name);
1359 fprintf (afile, "==.\n");
1361 /* allocate space */
1362 tfprintf (afile, "!labeldef\n", sym->rname);
1363 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1370 /*-----------------------------------------------------------------*/
1371 /* glue - the final glue that hold the whole thing together */
1372 /*-----------------------------------------------------------------*/
1378 FILE *ovrFile = tempfile ();
1380 addSetHead (&tmpfileSet, ovrFile);
1381 /* print the global struct definitions */
1383 cdbStructBlock (0, cdbFile);
1385 vFile = tempfile ();
1386 /* PENDING: this isnt the best place but it will do */
1387 if (port->general.glue_up_main)
1389 /* create the interrupt vector table */
1390 createInterruptVect (vFile);
1393 addSetHead (&tmpfileSet, vFile);
1395 /* emit code for the all the variables declared */
1397 /* do the overlay segments */
1398 emitOverlay (ovrFile);
1400 /* now put it all together into the assembler file */
1401 /* create the assembler file name */
1403 if (!options.c1mode)
1405 sprintf (scratchFileName, srcFileName);
1406 strcat (scratchFileName, port->assembler.file_ext);
1410 strcpy (scratchFileName, options.out_name);
1413 if (!(asmFile = fopen (scratchFileName, "w")))
1415 werror (E_FILE_OPEN_ERR, scratchFileName);
1419 /* initial comments */
1420 initialComments (asmFile);
1422 /* print module name */
1423 tfprintf (asmFile, "\t!module\n", moduleName);
1424 tfprintf (asmFile, "\t!fileprelude\n");
1426 /* Let the port generate any global directives, etc. */
1427 if (port->genAssemblerPreamble)
1429 port->genAssemblerPreamble (asmFile);
1432 /* print the global variables in this module */
1433 printPublics (asmFile);
1434 if (port->assembler.externGlobal)
1435 printExterns (asmFile);
1437 /* copy the sfr segment */
1438 fprintf (asmFile, "%s", iComments2);
1439 fprintf (asmFile, "; special function registers\n");
1440 fprintf (asmFile, "%s", iComments2);
1441 copyFile (asmFile, sfr->oFile);
1443 /* copy the sbit segment */
1444 fprintf (asmFile, "%s", iComments2);
1445 fprintf (asmFile, "; special function bits \n");
1446 fprintf (asmFile, "%s", iComments2);
1447 copyFile (asmFile, sfrbit->oFile);
1449 /* copy the data segment */
1450 fprintf (asmFile, "%s", iComments2);
1451 fprintf (asmFile, "; internal ram data\n");
1452 fprintf (asmFile, "%s", iComments2);
1453 copyFile (asmFile, data->oFile);
1456 /* create the overlay segments */
1457 fprintf (asmFile, "%s", iComments2);
1458 fprintf (asmFile, "; overlayable items in internal ram \n");
1459 fprintf (asmFile, "%s", iComments2);
1460 copyFile (asmFile, ovrFile);
1462 /* create the stack segment MOF */
1463 if (mainf && IFFUNC_HASBODY(mainf->type))
1465 fprintf (asmFile, "%s", iComments2);
1466 fprintf (asmFile, "; Stack segment in internal ram \n");
1467 fprintf (asmFile, "%s", iComments2);
1468 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1469 "__start__stack:\n\t.ds\t1\n\n");
1472 /* create the idata segment */
1473 fprintf (asmFile, "%s", iComments2);
1474 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1475 fprintf (asmFile, "%s", iComments2);
1476 copyFile (asmFile, idata->oFile);
1478 /* copy the bit segment */
1479 fprintf (asmFile, "%s", iComments2);
1480 fprintf (asmFile, "; bit data\n");
1481 fprintf (asmFile, "%s", iComments2);
1482 copyFile (asmFile, bit->oFile);
1484 /* if external stack then reserve space of it */
1485 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1487 fprintf (asmFile, "%s", iComments2);
1488 fprintf (asmFile, "; external stack \n");
1489 fprintf (asmFile, "%s", iComments2);
1490 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1491 fprintf (asmFile, "\t.ds 256\n");
1495 /* copy xtern ram data */
1496 fprintf (asmFile, "%s", iComments2);
1497 fprintf (asmFile, "; external ram data\n");
1498 fprintf (asmFile, "%s", iComments2);
1499 copyFile (asmFile, xdata->oFile);
1501 /* copy xternal initialized ram data */
1502 fprintf (asmFile, "%s", iComments2);
1503 fprintf (asmFile, "; external initialized ram data\n");
1504 fprintf (asmFile, "%s", iComments2);
1505 copyFile (asmFile, xidata->oFile);
1507 /* copy the interrupt vector table */
1508 if (mainf && IFFUNC_HASBODY(mainf->type))
1510 fprintf (asmFile, "%s", iComments2);
1511 fprintf (asmFile, "; interrupt vector \n");
1512 fprintf (asmFile, "%s", iComments2);
1513 copyFile (asmFile, vFile);
1516 /* copy global & static initialisations */
1517 fprintf (asmFile, "%s", iComments2);
1518 fprintf (asmFile, "; global & static initialisations\n");
1519 fprintf (asmFile, "%s", iComments2);
1521 /* Everywhere we generate a reference to the static_name area,
1522 * (which is currently only here), we immediately follow it with a
1523 * definition of the post_static_name area. This guarantees that
1524 * the post_static_name area will immediately follow the static_name
1527 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1528 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1529 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1531 if (mainf && IFFUNC_HASBODY(mainf->type))
1533 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1534 /* if external stack is specified then the
1535 higher order byte of the xdatalocation is
1536 going into P2 and the lower order going into
1538 if (options.useXstack)
1540 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1541 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1542 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1543 (unsigned int) options.xdata_loc & 0xff);
1546 /* initialise the stack pointer */
1547 /* if the user specified a value then use it */
1548 if (options.stack_loc)
1549 fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc & 0xff);
1551 /* no: we have to compute it */
1552 if (!options.stackOnData && maxRegBank <= 3)
1553 fprintf (asmFile, "\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1);
1555 fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */
1557 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1558 fprintf (asmFile, "\tmov\ta,dpl\n");
1559 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1560 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1561 fprintf (asmFile, "__sdcc_init_data:\n");
1563 // if the port can copy the XINIT segment to XISEG
1564 if (port->genXINIT) {
1565 port->genXINIT(asmFile);
1569 copyFile (asmFile, statsg->oFile);
1571 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1573 /* This code is generated in the post-static area.
1574 * This area is guaranteed to follow the static area
1575 * by the ugly shucking and jiving about 20 lines ago.
1577 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1578 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1584 "%s", iComments2, iComments2);
1585 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1586 copyFile (asmFile, home->oFile);
1588 /* copy over code */
1589 fprintf (asmFile, "%s", iComments2);
1590 fprintf (asmFile, "; code\n");
1591 fprintf (asmFile, "%s", iComments2);
1592 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1593 if (mainf && IFFUNC_HASBODY(mainf->type))
1596 /* entry point @ start of CSEG */
1597 fprintf (asmFile, "__sdcc_program_startup:\n");
1599 /* put in the call to main */
1600 fprintf (asmFile, "\tlcall\t_main\n");
1601 if (options.mainreturn)
1604 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1605 fprintf (asmFile, "\tret\n");
1611 fprintf (asmFile, ";\treturn from main will lock up\n");
1612 fprintf (asmFile, "\tsjmp .\n");
1615 copyFile (asmFile, code->oFile);
1618 applyToSet (tmpfileSet, closeTmpFiles);
1619 applyToSet (tmpfileNameSet, rmTmpFiles);
1622 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1626 applyToSet (tmpfileSet, closeTmpFiles);
1627 applyToSet (tmpfileNameSet, rmTmpFiles);
1631 /** Creates a temporary file name a'la tmpnam which avoids the bugs
1632 in cygwin wrt c:\tmp.
1633 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1638 #if !defined(_MSC_VER)
1639 const char *tmpdir = NULL;
1641 tmpdir = getenv ("TMP");
1642 else if (getenv ("TEMP"))
1643 tmpdir = getenv ("TEMP");
1644 else if (getenv ("TMPDIR"))
1645 tmpdir = getenv ("TMPDIR");
1648 char *name = tempnam (tmpdir, "sdcc");
1655 return tmpnam (NULL);
1658 /** Creates a temporary file a'la tmpfile which avoids the bugs
1659 in cygwin wrt c:\tmp.
1660 Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
1665 #if !defined(_MSC_VER)
1666 const char *tmpdir = NULL;
1668 tmpdir = getenv ("TMP");
1669 else if (getenv ("TEMP"))
1670 tmpdir = getenv ("TEMP");
1671 else if (getenv ("TMPDIR"))
1672 tmpdir = getenv ("TMPDIR");
1675 char *name = Safe_strdup( tempnam (tmpdir, "sdcc"));
1678 FILE *fp = fopen (name, "w+b");
1681 addSetHead (&tmpfileNameSet, name);