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 #include "dbuf_string.h"
38 symbol *interrupts[INTNO_MAX+1];
40 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Variables that are declared as extern */
44 unsigned maxInterrupts = 0;
47 int noInit = 0; /* no initialization */
50 /*-----------------------------------------------------------------*/
51 /* closePipes - closes all pipes created by the compiler */
52 /*-----------------------------------------------------------------*/
53 DEFSETFUNC (closePipes)
66 /*-----------------------------------------------------------------*/
67 /* closeTmpFiles - closes all tmp files created by the compiler */
68 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
69 /*-----------------------------------------------------------------*/
70 DEFSETFUNC (closeTmpFiles)
83 /*-----------------------------------------------------------------*/
84 /* rmTmpFiles - unlinks all tmp files created by the compiler */
85 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
86 /*-----------------------------------------------------------------*/
87 DEFSETFUNC (rmTmpFiles)
102 aopLiteralLong (value * val, int offset, int size)
111 // assuming we have been warned before
112 val = constCharVal (0);
115 /* if it is a float then it gets tricky */
116 /* otherwise it is fairly simple */
117 if (!IS_FLOAT (val->type)) {
118 unsigned long v = ulFromVal (val);
123 tsprintf (buffer, sizeof(buffer),
124 "!immedbyte", (unsigned int) v & 0xff);
127 tsprintf (buffer, sizeof(buffer),
128 "!immedword", (unsigned int) v & 0xffff);
131 /* Hmm. Too big for now. */
134 return Safe_strdup (buffer);
137 /* PENDING: For now size must be 1 */
140 /* it is type float */
141 fl.f = (float) floatFromVal (val);
142 #ifdef WORDS_BIGENDIAN
143 tsprintf (buffer, sizeof(buffer),
144 "!immedbyte", fl.c[3 - offset]);
146 tsprintf (buffer, sizeof(buffer),
147 "!immedbyte", fl.c[offset]);
149 return Safe_strdup (buffer);
152 /*-----------------------------------------------------------------*/
153 /* aopLiteral - string from a literal value */
154 /*-----------------------------------------------------------------*/
156 aopLiteral (value * val, int offset)
158 return aopLiteralLong (val, offset, 1);
161 /*-----------------------------------------------------------------*/
162 /* emitRegularMap - emit code for maps with no special cases */
163 /*-----------------------------------------------------------------*/
165 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
175 /* PENDING: special case here - should remove */
176 if (!strcmp (map->sname, CODE_NAME))
177 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
178 else if (!strcmp (map->sname, DATA_NAME))
179 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
180 else if (!strcmp (map->sname, HOME_NAME))
181 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
183 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
186 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
188 symbol *newSym = NULL;
190 /* if extern then add it into the extern list */
191 if (IS_EXTERN (sym->etype))
193 addSetHead (&externs, sym);
197 /* if allocation required check is needed
198 then check if the symbol really requires
199 allocation only for local variables */
201 if (arFlag && !IS_AGGREGATE (sym->type) &&
202 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
203 !sym->allocreq && sym->level)
206 /* for bitvar locals and parameters */
207 if (!arFlag && !sym->allocreq && sym->level
208 && !SPEC_ABSA (sym->etype))
213 /* if global variable & not static or extern
214 and addPublics allowed then add it to the public set */
215 if ((sym->level == 0 ||
216 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
218 !IS_STATIC (sym->etype) &&
219 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : 1))
221 addSetHead (&publics, sym);
224 /* if extern then do nothing or is a function
226 if (IS_FUNC (sym->type) && !(sym->isitmp))
229 /* print extra debug info if required */
232 if (!sym->level) /* global */
234 if (IS_STATIC (sym->etype))
235 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
237 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
241 /* symbol is local */
242 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
244 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
247 /* if it has an initial value then do it only if
248 it is a global variable */
249 if (sym->ival && sym->level == 0)
251 if ((SPEC_OCLS (sym->etype) == xidata) && !SPEC_ABSA (sym->etype))
253 /* create a new "XINIT (CODE)" symbol, that will be emitted later
255 newSym=copySymbol (sym);
256 SPEC_OCLS(newSym->etype)=xinit;
257 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
258 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
259 if (IS_SPEC (newSym->type))
260 SPEC_CONST (newSym->type) = 1;
262 DCL_PTR_CONST (newSym->type) = 1;
263 SPEC_STAT(newSym->etype)=1;
264 resolveIvalSym(newSym->ival, newSym->type);
266 // add it to the "XINIT (CODE)" segment
267 addSet(&xinit->syms, newSym);
269 if (!SPEC_ABSA (sym->etype))
271 struct dbuf_s tmpBuf;
273 dbuf_init(&tmpBuf, 4096);
274 // before allocation we must parse the sym->ival tree
275 // but without actually generating initialization code
277 resolveIvalSym (sym->ival, sym->type);
279 printIval (sym, sym->type, sym->ival, &tmpBuf);
282 dbuf_destroy(&tmpBuf);
287 if (IS_AGGREGATE (sym->type))
289 ival = initAggregates (sym, sym->ival, NULL);
293 if (getNelements (sym->type, sym->ival)>1)
295 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
297 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
298 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
300 codeOutBuf = &statsg->oBuf;
304 // set ival's lineno to where the symbol was defined
305 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
306 // check if this is not a constant expression
307 if (!constExprTree (ival))
309 werror (E_CONST_EXPECTED, "found expression");
310 // but try to do it anyway
313 if (!astErrors (ival))
314 eBBlockFromiCode (iCodeFromAst (ival));
320 /* if it has an absolute address then generate
321 an equate for this no need to allocate space */
322 if (SPEC_ABSA (sym->etype) && !sym->ival)
326 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
334 else if (map == bit || map == sfrbit)
339 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
343 int size = getSize (sym->type) + sym->flexArrayLength;
346 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
351 dbuf_printf (&map->oBuf, "==.\n");
353 if (SPEC_ABSA (sym->etype))
355 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
357 if (IS_STATIC (sym->etype) || sym->level)
358 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
360 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
361 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
367 /*-----------------------------------------------------------------*/
368 /* initPointer - pointer initialization code massaging */
369 /*-----------------------------------------------------------------*/
371 initPointer (initList * ilist, sym_link *toType)
377 return valCastLiteral(toType, 0.0);
380 expr = list2expr (ilist);
385 /* try it the old way first */
386 if ((val = constExprValue (expr, FALSE)))
389 /* ( ptr + constant ) */
390 if (IS_AST_OP (expr) &&
391 (expr->opval.op == '+' || expr->opval.op == '-') &&
392 IS_AST_SYM_VALUE (expr->left) &&
393 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
394 compareType(toType, expr->left->ftype) &&
395 IS_AST_LIT_VALUE (expr->right)) {
396 return valForCastAggr (expr->left, expr->left->ftype,
402 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
403 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
404 if (compareType(toType, expr->left->ftype)!=1) {
405 werror (W_INIT_WRONG);
406 printFromToType(expr->left->ftype, toType);
412 /* no then we have to do these cludgy checks */
413 /* pointers can be initialized with address of
414 a variable or address of an array element */
415 if (IS_AST_OP (expr) && expr->opval.op == '&') {
416 /* address of symbol */
417 if (IS_AST_SYM_VALUE (expr->left)) {
418 val = AST_VALUE (expr->left);
419 val->type = newLink (DECLARATOR);
420 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
421 DCL_TYPE (val->type) = CPOINTER;
422 DCL_PTR_CONST (val->type) = port->mem.code_ro;
424 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
425 DCL_TYPE (val->type) = FPOINTER;
426 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
427 DCL_TYPE (val->type) = PPOINTER;
428 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
429 DCL_TYPE (val->type) = IPOINTER;
430 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
431 DCL_TYPE (val->type) = EEPPOINTER;
433 DCL_TYPE (val->type) = POINTER;
434 val->type->next = expr->left->ftype;
435 val->etype = getSpec (val->type);
439 /* if address of indexed array */
440 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
441 return valForArray (expr->left);
443 /* if address of structure element then
445 if (IS_AST_OP (expr->left) &&
446 expr->left->opval.op == '.') {
447 return valForStructElem (expr->left->left,
452 (&some_struct)->element */
453 if (IS_AST_OP (expr->left) &&
454 expr->left->opval.op == PTR_OP &&
455 IS_ADDRESS_OF_OP (expr->left->left)) {
456 return valForStructElem (expr->left->left->left,
460 /* case 3. (((char *) &a) +/- constant) */
461 if (IS_AST_OP (expr) &&
462 (expr->opval.op == '+' || expr->opval.op == '-') &&
463 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
464 IS_AST_OP (expr->left->right) &&
465 expr->left->right->opval.op == '&' &&
466 IS_AST_LIT_VALUE (expr->right)) {
468 return valForCastAggr (expr->left->right->left,
469 expr->left->left->opval.lnk,
470 expr->right, expr->opval.op);
473 /* case 4. (char *)(array type) */
474 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
475 IS_ARRAY(expr->right->ftype)) {
477 val = copyValue (AST_VALUE (expr->right));
478 val->type = newLink (DECLARATOR);
479 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
480 DCL_TYPE (val->type) = CPOINTER;
481 DCL_PTR_CONST (val->type) = port->mem.code_ro;
483 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
484 DCL_TYPE (val->type) = FPOINTER;
485 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
486 DCL_TYPE (val->type) = PPOINTER;
487 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
488 DCL_TYPE (val->type) = IPOINTER;
489 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
490 DCL_TYPE (val->type) = EEPPOINTER;
492 DCL_TYPE (val->type) = POINTER;
493 val->type->next = expr->right->ftype->next;
494 val->etype = getSpec (val->type);
499 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
501 werror (E_INCOMPAT_PTYPES);
506 /*-----------------------------------------------------------------*/
507 /* printChar - formats and prints a characater string with DB */
508 /*-----------------------------------------------------------------*/
510 printChar (struct dbuf_s * oBuf, char *s, int plen)
518 while (len && pplen < plen)
521 while (i && pplen < plen)
523 if (*s < ' ' || *s == '\"' || *s=='\\')
527 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
528 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
543 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
554 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
559 /*-----------------------------------------------------------------*/
560 /* return the generic pointer high byte for a given pointer type. */
561 /*-----------------------------------------------------------------*/
563 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
571 werror (E_CANNOT_USE_GENERIC_POINTER,
572 iname ? iname : "<null>",
573 oname ? oname : "<null>");
580 return GPTYPE_XSTACK;
582 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
590 /*-----------------------------------------------------------------*/
591 /* printPointerType - generates ival for pointer type */
592 /*-----------------------------------------------------------------*/
594 _printPointerType (struct dbuf_s * oBuf, const char *name)
596 if (options.model == MODEL_FLAT24)
598 if (port->little_endian)
599 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
601 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
605 if (port->little_endian)
606 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
608 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
612 /*-----------------------------------------------------------------*/
613 /* printPointerType - generates ival for pointer type */
614 /*-----------------------------------------------------------------*/
616 printPointerType (struct dbuf_s * oBuf, const char *name)
618 _printPointerType (oBuf, name);
619 dbuf_printf (oBuf, "\n");
622 /*-----------------------------------------------------------------*/
623 /* printGPointerType - generates ival for generic pointer type */
624 /*-----------------------------------------------------------------*/
626 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
627 const unsigned int type)
629 _printPointerType (oBuf, iname);
630 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
633 /*-----------------------------------------------------------------*/
634 /* printIvalType - generates ival for int/char */
635 /*-----------------------------------------------------------------*/
637 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
641 /* if initList is deep */
642 if (ilist && (ilist->type == INIT_DEEP))
643 ilist = ilist->init.deep;
645 if (!(val = list2val (ilist))) {
646 // assuming a warning has been thrown
647 val = constCharVal (0);
650 if (val->type != type) {
651 val = valCastLiteral(type, floatFromVal(val));
654 switch (getSize (type)) {
657 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
659 dbuf_tprintf (oBuf, "\t!dbs\n",
660 aopLiteral (val, 0));
664 if (port->use_dw_for_init)
665 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
666 else if (port->little_endian)
667 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
669 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
673 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
674 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
676 else if (port->little_endian) {
677 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
678 aopLiteral (val, 0), aopLiteral (val, 1),
679 aopLiteral (val, 2), aopLiteral (val, 3));
682 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
683 aopLiteral (val, 3), aopLiteral (val, 2),
684 aopLiteral (val, 1), aopLiteral (val, 0));
690 /*-----------------------------------------------------------------*/
691 /* printIvalBitFields - generate initializer for bitfields */
692 /*-----------------------------------------------------------------*/
693 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
697 initList *lilist = *ilist ;
698 unsigned long ival = 0;
704 val = list2val(lilist);
706 if (SPEC_BLEN(lsym->etype) > 8) {
707 size += ((SPEC_BLEN (lsym->etype) / 8) +
708 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
711 size = ((SPEC_BLEN (lsym->etype) / 8) +
712 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
715 i <<= SPEC_BSTR (lsym->etype);
717 if (! ( lsym->next &&
718 (IS_BITFIELD(lsym->next->type)) &&
719 (SPEC_BSTR(lsym->next->etype)))) break;
721 lilist = lilist ? lilist->next : NULL;
725 dbuf_tprintf (oBuf, "\t!db !constbyte\n",ival);
729 dbuf_tprintf (oBuf, "\t!dw !constword\n",ival);
732 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
733 (ival >> 16) & 0xffff, (ival & 0xffff));
740 /*-----------------------------------------------------------------*/
741 /* printIvalStruct - generates initial value for structures */
742 /*-----------------------------------------------------------------*/
744 printIvalStruct (symbol * sym, sym_link * type,
745 initList * ilist, struct dbuf_s * oBuf)
748 initList *iloop = NULL;
750 sflds = SPEC_STRUCT (type)->fields;
753 if (ilist->type != INIT_DEEP) {
754 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
758 iloop = ilist->init.deep;
761 if (SPEC_STRUCT (type)->type == UNION) {
762 printIval (sym, sflds->type, iloop, oBuf);
763 iloop = iloop ? iloop->next : NULL;
765 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
766 if (IS_BITFIELD(sflds->type)) {
767 printIvalBitFields(&sflds, &iloop, oBuf);
769 printIval (sym, sflds->type, iloop, oBuf);
774 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
779 /*-----------------------------------------------------------------*/
780 /* printIvalChar - generates initital value for character array */
781 /*-----------------------------------------------------------------*/
783 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
786 unsigned int size = DCL_ELEM (type);
790 val = list2val (ilist);
791 /* if the value is a character string */
792 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
796 /* we have not been given a size, but now we know it */
797 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
798 /* but first check, if it's a flexible array */
799 if (sym && IS_STRUCT (sym->type))
800 sym->flexArrayLength = size;
802 DCL_ELEM (type) = size;
805 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
813 printChar (oBuf, s, strlen (s) + 1);
817 /*-----------------------------------------------------------------*/
818 /* printIvalArray - generates code for array initialization */
819 /*-----------------------------------------------------------------*/
821 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
822 struct dbuf_s * oBuf)
826 unsigned int size = 0;
829 /* take care of the special case */
830 /* array of characters can be init */
832 if (IS_CHAR (type->next)) {
833 val = list2val(ilist);
835 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
838 if (!IS_LITERAL(val->etype)) {
839 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
842 if (printIvalChar (sym, type,
843 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
844 oBuf, SPEC_CVAL (sym->etype).v_char))
847 /* not the special case */
848 if (ilist->type != INIT_DEEP) {
849 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
853 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
854 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
855 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
858 printIval (sym, type->next, iloop, oBuf);
862 if (DCL_ELEM(type)) {
863 // pad with zeros if needed
864 if (size<DCL_ELEM(type)) {
865 size = (DCL_ELEM(type) - size) * getSize(type->next);
867 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
871 /* we have not been given a size, but now we know it */
872 /* but first check, if it's a flexible array */
873 if (IS_STRUCT (sym->type))
874 sym->flexArrayLength = size * getSize (type->next);
876 DCL_ELEM (type) = size;
882 /*-----------------------------------------------------------------*/
883 /* printIvalFuncPtr - generate initial value for function pointers */
884 /*-----------------------------------------------------------------*/
886 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
892 val = list2val (ilist);
894 val = valCastLiteral(type, 0.0);
897 // an error has been thrown already
898 val = constCharVal (0);
901 if (IS_LITERAL(val->etype)) {
902 if (compareType(type, val->etype) == 0) {
903 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
904 printFromToType (val->type, type);
906 printIvalCharPtr (NULL, type, val, oBuf);
910 /* check the types */
911 if ((dLvl = compareType (val->type, type->next)) <= 0)
913 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
917 /* now generate the name */
920 if (port->use_dw_for_init)
922 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
926 printPointerType (oBuf, val->name);
929 else if (port->use_dw_for_init)
931 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
935 printPointerType (oBuf, val->sym->rname);
941 /*-----------------------------------------------------------------*/
942 /* printIvalCharPtr - generates initial values for character pointers */
943 /*-----------------------------------------------------------------*/
945 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
949 /* PENDING: this is _very_ mcs51 specific, including a magic
951 It's also endian specific.
953 size = getSize (type);
955 if (val->name && strlen (val->name))
957 if (size == 1) /* This appears to be Z80 specific?? */
960 "\t!dbs\n", val->name);
962 else if (size == FPTRSIZE)
964 if (port->use_dw_for_init)
966 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
970 printPointerType (oBuf, val->name);
973 else if (size == GPTRSIZE)
976 if (IS_PTR (val->type)) {
977 type = DCL_TYPE (val->type);
979 type = PTR_TYPE (SPEC_OCLS (val->etype));
981 if (val->sym && val->sym->isstrlit) {
982 // this is a literal string
985 printGPointerType (oBuf, val->name, sym->name, type);
989 fprintf (stderr, "*** internal error: unknown size in "
990 "printIvalCharPtr.\n");
995 // these are literals assigned to pointers
999 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
1002 if (port->use_dw_for_init)
1003 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
1004 else if (port->little_endian)
1005 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1006 aopLiteral (val, 0), aopLiteral (val, 1));
1008 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1009 aopLiteral (val, 1), aopLiteral (val, 0));
1012 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1013 // non-zero mcs51 generic pointer
1014 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1016 if (port->little_endian) {
1017 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1018 aopLiteral (val, 0),
1019 aopLiteral (val, 1),
1020 aopLiteral (val, 2));
1022 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1023 aopLiteral (val, 2),
1024 aopLiteral (val, 1),
1025 aopLiteral (val, 0));
1029 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1030 // non-zero ds390 generic pointer
1031 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1033 if (port->little_endian) {
1034 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1035 aopLiteral (val, 0),
1036 aopLiteral (val, 1),
1037 aopLiteral (val, 2),
1038 aopLiteral (val, 3));
1040 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1041 aopLiteral (val, 3),
1042 aopLiteral (val, 2),
1043 aopLiteral (val, 1),
1044 aopLiteral (val, 0));
1052 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1053 addSet (&statsg->syms, val->sym);
1059 /*-----------------------------------------------------------------*/
1060 /* printIvalPtr - generates initial value for pointers */
1061 /*-----------------------------------------------------------------*/
1063 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1069 if (ilist && (ilist->type == INIT_DEEP))
1070 ilist = ilist->init.deep;
1072 /* function pointer */
1073 if (IS_FUNC (type->next))
1075 printIvalFuncPtr (type, ilist, oBuf);
1079 if (!(val = initPointer (ilist, type)))
1082 /* if character pointer */
1083 if (IS_CHAR (type->next))
1084 if (printIvalCharPtr (sym, type, val, oBuf))
1087 /* check the type */
1088 if (compareType (type, val->type) == 0) {
1089 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1090 printFromToType (val->type, type);
1093 /* if val is literal */
1094 if (IS_LITERAL (val->etype))
1096 switch (getSize (type))
1099 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1102 if (port->use_dw_for_init)
1103 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1104 else if (port->little_endian)
1105 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1107 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1109 case 3: // how about '390??
1110 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1111 if (port->little_endian)
1113 dbuf_printf (oBuf, "\t.byte %s,%s",
1114 aopLiteral (val, 0), aopLiteral (val, 1));
1118 dbuf_printf (oBuf, "\t.byte %s,%s",
1119 aopLiteral (val, 1), aopLiteral (val, 0));
1121 if (IS_GENPTR (val->type))
1122 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1123 else if (IS_PTR (val->type))
1124 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1126 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1132 size = getSize (type);
1134 if (size == 1) /* Z80 specific?? */
1136 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1138 else if (size == FPTRSIZE)
1140 if (port->use_dw_for_init) {
1141 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1143 printPointerType (oBuf, val->name);
1146 else if (size == GPTRSIZE)
1148 printGPointerType (oBuf, val->name, sym->name,
1149 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1150 PTR_TYPE (SPEC_OCLS (val->etype))));
1155 /*-----------------------------------------------------------------*/
1156 /* printIval - generates code for initial value */
1157 /*-----------------------------------------------------------------*/
1159 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1163 /* if structure then */
1164 if (IS_STRUCT (type))
1166 printIvalStruct (sym, type, ilist, oBuf);
1170 /* if this is an array */
1171 if (IS_ARRAY (type))
1173 printIvalArray (sym, type, ilist, oBuf);
1179 // not an aggregate, ilist must be a node
1180 if (ilist->type!=INIT_NODE) {
1181 // or a 1-element list
1182 if (ilist->init.deep->next) {
1183 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1186 ilist=ilist->init.deep;
1190 // and the type must match
1191 itype=ilist->init.node->ftype;
1193 if (compareType(type, itype)==0) {
1194 // special case for literal strings
1195 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1196 // which are really code pointers
1197 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1200 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1201 printFromToType(itype, type);
1206 /* if this is a pointer */
1209 printIvalPtr (sym, type, ilist, oBuf);
1213 /* if type is SPECIFIER */
1216 printIvalType (sym, type, ilist, oBuf);
1221 /*-----------------------------------------------------------------*/
1222 /* emitStaticSeg - emitcode for the static segment */
1223 /*-----------------------------------------------------------------*/
1225 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1229 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1231 /* for all variables in this segment do */
1232 for (sym = setFirstItem (map->syms); sym;
1233 sym = setNextItem (map->syms))
1236 /* if it is "extern" then do nothing */
1237 if (IS_EXTERN (sym->etype))
1240 /* if it is not static add it to the public table */
1241 if (!IS_STATIC (sym->etype))
1243 addSetHead (&publics, sym);
1246 /* print extra debug info if required */
1247 if (options.debug) {
1251 if (IS_STATIC (sym->etype))
1252 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1254 dbuf_printf (oBuf, "G$"); /* scope is global */
1257 /* symbol is local */
1258 dbuf_printf (oBuf, "L%s$",
1259 (sym->localof ? sym->localof->name : "-null-"));
1260 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1263 /* if it has an absolute address and no initializer */
1264 if (SPEC_ABSA (sym->etype) && !sym->ival)
1267 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1269 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1271 SPEC_ADDR (sym->etype));
1276 dbuf_printf (oBuf, " == .\n");
1278 /* if it has an initial value */
1281 if (SPEC_ABSA (sym->etype))
1283 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1285 dbuf_printf (oBuf, "%s:\n", sym->rname);
1287 resolveIvalSym (sym->ival, sym->type);
1288 printIval (sym, sym->type, sym->ival, oBuf);
1290 /* if sym is a simple string and sym->ival is a string,
1291 WE don't need it anymore */
1292 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1293 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1294 list2val(sym->ival)->sym->isstrlit) {
1295 freeStringSymbol(list2val(sym->ival)->sym);
1299 /* allocate space */
1300 int size = getSize (sym->type);
1303 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1305 dbuf_printf (oBuf, "%s:\n", sym->rname);
1306 /* special case for character strings */
1307 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1308 SPEC_CVAL (sym->etype).v_char)
1310 SPEC_CVAL (sym->etype).v_char,
1313 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1319 /*-----------------------------------------------------------------*/
1320 /* emitMaps - emits the code for the data portion the code */
1321 /*-----------------------------------------------------------------*/
1325 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1326 /* ports but let's be conservative - EEP */
1329 /* no special considerations for the following
1330 data, idata & bit & xdata */
1331 emitRegularMap (data, TRUE, TRUE);
1332 emitRegularMap (idata, TRUE, TRUE);
1333 emitRegularMap (d_abs, TRUE, TRUE);
1334 emitRegularMap (i_abs, TRUE, TRUE);
1335 emitRegularMap (bit, TRUE, TRUE);
1336 emitRegularMap (pdata, TRUE, TRUE);
1337 emitRegularMap (xdata, TRUE, TRUE);
1338 emitRegularMap (x_abs, TRUE, TRUE);
1339 if (port->genXINIT) {
1340 emitRegularMap (xidata, TRUE, TRUE);
1342 emitRegularMap (sfr, publicsfr, FALSE);
1343 emitRegularMap (sfrbit, publicsfr, FALSE);
1344 emitRegularMap (home, TRUE, FALSE);
1345 emitRegularMap (code, TRUE, FALSE);
1347 if (options.const_seg) {
1348 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1350 emitStaticSeg (statsg, &code->oBuf);
1351 if (port->genXINIT) {
1352 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1353 emitStaticSeg (xinit, &code->oBuf);
1355 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1356 emitStaticSeg (c_abs, &code->oBuf);
1360 /*-----------------------------------------------------------------*/
1361 /* flushStatics - flush all currently defined statics out to file */
1362 /* and delete. Temporary function */
1363 /*-----------------------------------------------------------------*/
1367 emitStaticSeg (statsg, codeOutBuf);
1368 statsg->syms = NULL;
1371 /*-----------------------------------------------------------------*/
1372 /* createInterruptVect - creates the interrupt vector */
1373 /*-----------------------------------------------------------------*/
1375 createInterruptVect (struct dbuf_s *vBuf)
1377 mainf = newSymbol ("main", 0);
1380 /* only if the main function exists */
1381 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1383 if (!options.cc_only && !noAssemble && !options.c1mode)
1388 /* if the main is only a prototype ie. no body then do nothing */
1389 if (!IFFUNC_HASBODY(mainf->type))
1391 /* if ! compile only then main function should be present */
1392 if (!options.cc_only && !noAssemble)
1397 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1398 dbuf_printf (vBuf, "__interrupt_vect:\n");
1401 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1403 /* There's no such thing as a "generic" interrupt table header. */
1410 ";--------------------------------------------------------\n"
1411 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1415 ";--------------------------------------------------------\n"};
1418 /*-----------------------------------------------------------------*/
1419 /* initialComments - puts in some initial comments */
1420 /*-----------------------------------------------------------------*/
1422 initialComments (FILE * afile)
1426 fprintf (afile, "%s", iComments1);
1427 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1428 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1429 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1430 fprintf (afile, "%s", iComments2);
1433 /*-----------------------------------------------------------------*/
1434 /* printPublics - generates .global for publics */
1435 /*-----------------------------------------------------------------*/
1437 printPublics (FILE * afile)
1441 fprintf (afile, "%s", iComments2);
1442 fprintf (afile, "; Public variables in this module\n");
1443 fprintf (afile, "%s", iComments2);
1445 for (sym = setFirstItem (publics); sym;
1446 sym = setNextItem (publics))
1447 tfprintf (afile, "\t!global\n", sym->rname);
1450 /*-----------------------------------------------------------------*/
1451 /* printExterns - generates .global for externs */
1452 /*-----------------------------------------------------------------*/
1454 printExterns (FILE * afile)
1458 fprintf (afile, "%s", iComments2);
1459 fprintf (afile, "; Externals used\n");
1460 fprintf (afile, "%s", iComments2);
1462 for (sym = setFirstItem (externs); sym;
1463 sym = setNextItem (externs))
1464 tfprintf (afile, "\t!extern\n", sym->rname);
1467 /*-----------------------------------------------------------------*/
1468 /* emitOverlay - will emit code for the overlay stuff */
1469 /*-----------------------------------------------------------------*/
1471 emitOverlay (struct dbuf_s * aBuf)
1475 if (!elementsInSet (ovrSetSets))
1476 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1478 /* for each of the sets in the overlay segment do */
1479 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1480 ovrset = setNextItem (ovrSetSets))
1485 if (elementsInSet (ovrset))
1487 /* output the area informtion */
1488 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1491 for (sym = setFirstItem (ovrset); sym;
1492 sym = setNextItem (ovrset))
1494 /* if extern then it is in the publics table: do nothing */
1495 if (IS_EXTERN (sym->etype))
1498 /* if allocation required check is needed
1499 then check if the symbol really requires
1500 allocation only for local variables */
1501 if (!IS_AGGREGATE (sym->type) &&
1502 !(sym->_isparm && !IS_REGPARM (sym->etype))
1503 && !sym->allocreq && sym->level)
1506 /* if global variable & not static or extern
1507 and addPublics allowed then add it to the public set */
1508 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1509 && !IS_STATIC (sym->etype))
1511 addSetHead (&publics, sym);
1514 /* if extern then do nothing or is a function
1516 if (IS_FUNC (sym->type))
1519 /* print extra debug info if required */
1524 if (IS_STATIC (sym->etype))
1525 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1527 dbuf_printf (aBuf, "G$"); /* scope is global */
1530 /* symbol is local */
1531 dbuf_printf (aBuf, "L%s$",
1532 (sym->localof ? sym->localof->name : "-null-"));
1533 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1536 /* if is has an absolute address then generate
1537 an equate for this no need to allocate space */
1538 if (SPEC_ABSA (sym->etype))
1542 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1544 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1546 SPEC_ADDR (sym->etype));
1550 int size = getSize(sym->type);
1553 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1556 dbuf_printf (aBuf, "==.\n");
1558 /* allocate space */
1559 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1560 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1567 /*-----------------------------------------------------------------*/
1568 /* glue - the final glue that hold the whole thing together */
1569 /*-----------------------------------------------------------------*/
1574 struct dbuf_s ovrBuf;
1578 dbuf_init (&vBuf, 4096);
1579 dbuf_init (&ovrBuf, 4096);
1581 mcs51_like = (port->general.glue_up_main &&
1582 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1584 /* print the global struct definitions */
1588 /* PENDING: this isn't the best place but it will do */
1589 if (port->general.glue_up_main)
1591 /* create the interrupt vector table */
1592 createInterruptVect (&vBuf);
1595 /* emit code for the all the variables declared */
1597 /* do the overlay segments */
1598 emitOverlay (&ovrBuf);
1600 outputDebugSymbols ();
1602 /* now put it all together into the assembler file */
1603 /* create the assembler file name */
1605 /* -o option overrides default name? */
1606 if ((noAssemble || options.c1mode) && fullDstFileName)
1608 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1612 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1613 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1616 if (!(asmFile = fopen (scratchFileName, "w")))
1618 werror (E_FILE_OPEN_ERR, scratchFileName);
1619 exit (EXIT_FAILURE);
1622 /* initial comments */
1623 initialComments (asmFile);
1625 /* print module name */
1626 tfprintf (asmFile, "\t!module\n", moduleName);
1629 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1631 switch(options.model)
1633 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1634 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1635 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1636 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1637 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1638 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1641 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1642 if(options.useXstack) fprintf (asmFile, " --xstack");
1643 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1644 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1645 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1646 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1647 fprintf (asmFile, "\n");
1649 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1651 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1654 tfprintf (asmFile, "\t!fileprelude\n");
1656 /* Let the port generate any global directives, etc. */
1657 if (port->genAssemblerPreamble)
1659 port->genAssemblerPreamble (asmFile);
1662 /* print the global variables in this module */
1663 printPublics (asmFile);
1664 if (port->assembler.externGlobal)
1665 printExterns (asmFile);
1668 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1670 /* copy the sfr segment */
1671 fprintf (asmFile, "%s", iComments2);
1672 fprintf (asmFile, "; special function registers\n");
1673 fprintf (asmFile, "%s", iComments2);
1674 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1679 /* copy the sbit segment */
1680 fprintf (asmFile, "%s", iComments2);
1681 fprintf (asmFile, "; special function bits\n");
1682 fprintf (asmFile, "%s", iComments2);
1683 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1685 /*JCF: Create the areas for the register banks*/
1686 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1688 fprintf (asmFile, "%s", iComments2);
1689 fprintf (asmFile, "; overlayable register banks\n");
1690 fprintf (asmFile, "%s", iComments2);
1692 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1693 if (RegBankUsed[1] || options.parms_in_bank1)
1694 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1696 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1698 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1702 fprintf (asmFile, "%s", iComments2);
1703 fprintf (asmFile, "; overlayable bit register bank\n");
1704 fprintf (asmFile, "%s", iComments2);
1705 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1706 fprintf (asmFile, "bits:\n\t.ds 1\n");
1707 fprintf (asmFile, "\tb0 = bits[0]\n");
1708 fprintf (asmFile, "\tb1 = bits[1]\n");
1709 fprintf (asmFile, "\tb2 = bits[2]\n");
1710 fprintf (asmFile, "\tb3 = bits[3]\n");
1711 fprintf (asmFile, "\tb4 = bits[4]\n");
1712 fprintf (asmFile, "\tb5 = bits[5]\n");
1713 fprintf (asmFile, "\tb6 = bits[6]\n");
1714 fprintf (asmFile, "\tb7 = bits[7]\n");
1718 /* copy the data segment */
1719 fprintf (asmFile, "%s", iComments2);
1720 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1721 fprintf (asmFile, "%s", iComments2);
1722 dbuf_write_and_destroy (&data->oBuf, asmFile);
1725 /* create the overlay segments */
1728 fprintf (asmFile, "%s", iComments2);
1729 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1730 fprintf (asmFile, "%s", iComments2);
1731 dbuf_write_and_destroy (&ovrBuf, asmFile);
1734 /* create the stack segment MOF */
1735 if (mainf && IFFUNC_HASBODY (mainf->type))
1737 fprintf (asmFile, "%s", iComments2);
1738 fprintf (asmFile, "; Stack segment in internal ram \n");
1739 fprintf (asmFile, "%s", iComments2);
1740 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1741 "__start__stack:\n\t.ds\t1\n\n");
1744 /* create the idata segment */
1745 if ((idata) && (mcs51_like))
1747 fprintf (asmFile, "%s", iComments2);
1748 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1749 fprintf (asmFile, "%s", iComments2);
1750 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1753 /* create the absolute idata/data segment */
1754 if ((i_abs) && (mcs51_like))
1756 fprintf (asmFile, "%s", iComments2);
1757 fprintf (asmFile, "; absolute internal ram data\n");
1758 fprintf (asmFile, "%s", iComments2);
1759 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1760 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1763 /* copy the bit segment */
1766 fprintf (asmFile, "%s", iComments2);
1767 fprintf (asmFile, "; bit data\n");
1768 fprintf (asmFile, "%s", iComments2);
1769 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1772 /* copy paged external ram data */
1775 fprintf (asmFile, "%s", iComments2);
1776 fprintf (asmFile, "; paged external ram data\n");
1777 fprintf (asmFile, "%s", iComments2);
1778 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1781 /* if external stack then reserve space for it */
1782 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1784 fprintf (asmFile, "%s", iComments2);
1785 fprintf (asmFile, "; external stack \n");
1786 fprintf (asmFile, "%s", iComments2);
1787 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1788 "__start__xstack:\n\t.ds\t1\n\n");
1791 /* copy external ram data */
1794 fprintf (asmFile, "%s", iComments2);
1795 fprintf (asmFile, "; external ram data\n");
1796 fprintf (asmFile, "%s", iComments2);
1797 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1800 /* create the absolute xdata segment */
1801 if (mcs51_like || TARGET_IS_HC08)
1803 fprintf (asmFile, "%s", iComments2);
1804 fprintf (asmFile, "; absolute external ram data\n");
1805 fprintf (asmFile, "%s", iComments2);
1806 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1809 /* copy external initialized ram data */
1810 fprintf (asmFile, "%s", iComments2);
1811 fprintf (asmFile, "; external initialized ram data\n");
1812 fprintf (asmFile, "%s", iComments2);
1813 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1815 /* If the port wants to generate any extra areas, let it do so. */
1816 if (port->extraAreas.genExtraAreaDeclaration)
1818 port->extraAreas.genExtraAreaDeclaration(asmFile,
1819 mainf && IFFUNC_HASBODY(mainf->type));
1822 /* copy the interrupt vector table */
1823 if (mainf && IFFUNC_HASBODY (mainf->type))
1825 fprintf (asmFile, "%s", iComments2);
1826 fprintf (asmFile, "; interrupt vector \n");
1827 fprintf (asmFile, "%s", iComments2);
1828 dbuf_write_and_destroy (&vBuf, asmFile);
1831 /* copy global & static initialisations */
1832 fprintf (asmFile, "%s", iComments2);
1833 fprintf (asmFile, "; global & static initialisations\n");
1834 fprintf (asmFile, "%s", iComments2);
1836 /* Everywhere we generate a reference to the static_name area,
1837 * (which is currently only here), we immediately follow it with a
1838 * definition of the post_static_name area. This guarantees that
1839 * the post_static_name area will immediately follow the static_name
1842 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1843 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1844 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1845 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1847 if (mainf && IFFUNC_HASBODY (mainf->type))
1849 if (port->genInitStartup)
1851 port->genInitStartup (asmFile);
1855 assert (mcs51_like);
1856 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1857 /* if external stack is specified then the
1858 higher order byte of the xdatalocation is
1859 going into P2 and the lower order going into
1861 if (options.useXstack)
1863 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1864 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1865 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1866 (unsigned int) options.xdata_loc & 0xff);
1869 // This should probably be a port option, but I'm being lazy.
1870 // on the 400, the firmware boot loader gives us a valid stack
1871 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1872 if (!TARGET_IS_DS400)
1874 /* initialise the stack pointer. JCF: aslink takes care of the location */
1875 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1878 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1879 fprintf (asmFile, "\tmov\ta,dpl\n");
1880 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1881 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1882 fprintf (asmFile, "__sdcc_init_data:\n");
1884 // if the port can copy the XINIT segment to XISEG
1887 port->genXINIT (asmFile);
1891 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1893 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1895 /* This code is generated in the post-static area.
1896 * This area is guaranteed to follow the static area
1897 * by the ugly shucking and jiving about 20 lines ago.
1899 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1900 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1906 "%s", iComments2, iComments2);
1907 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1908 dbuf_write_and_destroy (&home->oBuf, asmFile);
1910 if (mainf && IFFUNC_HASBODY (mainf->type))
1912 /* entry point @ start of HOME */
1913 fprintf (asmFile, "__sdcc_program_startup:\n");
1915 /* put in jump or call to main */
1916 if (options.mainreturn)
1918 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1919 fprintf (asmFile, ";\treturn from main will return to caller\n");
1923 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1924 fprintf (asmFile, ";\treturn from main will lock up\n");
1925 fprintf (asmFile, "\tsjmp .\n");
1928 /* copy over code */
1929 fprintf (asmFile, "%s", iComments2);
1930 fprintf (asmFile, "; code\n");
1931 fprintf (asmFile, "%s", iComments2);
1932 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1933 dbuf_write_and_destroy (&code->oBuf, asmFile);
1935 if (port->genAssemblerEnd)
1937 port->genAssemblerEnd (asmFile);