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 *, bool check);
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 */
51 aopLiteralLong (value * val, int offset, int size)
60 // assuming we have been warned before
61 val = constCharVal (0);
64 /* if it is a float then it gets tricky */
65 /* otherwise it is fairly simple */
66 if (!IS_FLOAT (val->type)) {
67 unsigned long v = ulFromVal (val);
72 tsprintf (buffer, sizeof(buffer),
73 "!immedbyte", (unsigned int) v & 0xff);
76 tsprintf (buffer, sizeof(buffer),
77 "!immedword", (unsigned int) v & 0xffff);
80 /* Hmm. Too big for now. */
83 return Safe_strdup (buffer);
86 /* PENDING: For now size must be 1 */
89 /* it is type float */
90 fl.f = (float) floatFromVal (val);
91 #ifdef WORDS_BIGENDIAN
92 tsprintf (buffer, sizeof(buffer),
93 "!immedbyte", fl.c[3 - offset]);
95 tsprintf (buffer, sizeof(buffer),
96 "!immedbyte", fl.c[offset]);
98 return Safe_strdup (buffer);
101 /*-----------------------------------------------------------------*/
102 /* aopLiteral - string from a literal value */
103 /*-----------------------------------------------------------------*/
105 aopLiteral (value * val, int offset)
107 return aopLiteralLong (val, offset, 1);
110 /*-----------------------------------------------------------------*/
111 /* emitRegularMap - emit code for maps with no special cases */
112 /*-----------------------------------------------------------------*/
114 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
124 /* PENDING: special case here - should remove */
125 if (!strcmp (map->sname, CODE_NAME))
126 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
127 else if (!strcmp (map->sname, DATA_NAME))
128 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
129 else if (!strcmp (map->sname, HOME_NAME))
130 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
132 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
135 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
137 symbol *newSym = NULL;
139 /* if extern then add it into the extern list */
140 if (IS_EXTERN (sym->etype))
142 addSetHead (&externs, sym);
146 /* if allocation required check is needed
147 then check if the symbol really requires
148 allocation only for local variables */
150 if (arFlag && !IS_AGGREGATE (sym->type) &&
151 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
152 !sym->allocreq && sym->level)
155 /* for bitvar locals and parameters */
156 if (!arFlag && !sym->allocreq && sym->level
157 && !SPEC_ABSA (sym->etype))
162 /* if global variable & not static or extern
163 and addPublics allowed then add it to the public set */
164 if ((sym->level == 0 ||
165 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
167 !IS_STATIC (sym->etype) &&
168 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : 1))
170 addSetHead (&publics, sym);
173 /* if extern then do nothing or is a function
175 if (IS_FUNC (sym->type) && !(sym->isitmp))
178 /* print extra debug info if required */
181 if (!sym->level) /* global */
183 if (IS_STATIC (sym->etype))
184 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
186 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
190 /* symbol is local */
191 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
193 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
196 /* if it has an initial value then do it only if
197 it is a global variable */
198 if (sym->ival && sym->level == 0)
200 if ((SPEC_OCLS (sym->etype) == xidata) && !SPEC_ABSA (sym->etype))
202 /* create a new "XINIT (CODE)" symbol, that will be emitted later
204 newSym=copySymbol (sym);
205 SPEC_OCLS(newSym->etype)=xinit;
206 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
207 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
208 if (IS_SPEC (newSym->type))
209 SPEC_CONST (newSym->type) = 1;
211 DCL_PTR_CONST (newSym->type) = 1;
212 SPEC_STAT(newSym->etype)=1;
213 resolveIvalSym(newSym->ival, newSym->type);
215 // add it to the "XINIT (CODE)" segment
216 addSet(&xinit->syms, newSym);
218 if (!SPEC_ABSA (sym->etype))
220 struct dbuf_s tmpBuf;
222 dbuf_init(&tmpBuf, 4096);
223 // before allocation we must parse the sym->ival tree
224 // but without actually generating initialization code
226 resolveIvalSym (sym->ival, sym->type);
228 printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
231 dbuf_destroy(&tmpBuf);
236 if (IS_AGGREGATE (sym->type))
238 ival = initAggregates (sym, sym->ival, NULL);
242 if (getNelements (sym->type, sym->ival)>1)
244 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
246 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
247 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
249 codeOutBuf = &statsg->oBuf;
253 // set ival's lineno to where the symbol was defined
254 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
255 // check if this is not a constant expression
256 if (!constExprTree (ival))
258 werror (E_CONST_EXPECTED, "found expression");
259 // but try to do it anyway
262 if (!astErrors (ival))
263 eBBlockFromiCode (iCodeFromAst (ival));
269 /* if it has an absolute address then generate
270 an equate for this no need to allocate space */
271 if (SPEC_ABSA (sym->etype) && !sym->ival)
275 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
283 else if (map == bit || map == sfrbit)
288 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
292 int size = getSize (sym->type) + sym->flexArrayLength;
295 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
300 dbuf_printf (&map->oBuf, "==.\n");
302 if (SPEC_ABSA (sym->etype))
304 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
306 if (IS_STATIC (sym->etype) || sym->level)
307 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
309 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
310 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
316 /*-----------------------------------------------------------------*/
317 /* initPointer - pointer initialization code massaging */
318 /*-----------------------------------------------------------------*/
320 initPointer (initList * ilist, sym_link *toType)
326 return valCastLiteral(toType, 0.0);
329 expr = list2expr (ilist);
334 /* try it the old way first */
335 if ((val = constExprValue (expr, FALSE)))
338 /* ( ptr + constant ) */
339 if (IS_AST_OP (expr) &&
340 (expr->opval.op == '+' || expr->opval.op == '-') &&
341 IS_AST_SYM_VALUE (expr->left) &&
342 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
343 compareType(toType, expr->left->ftype) &&
344 IS_AST_LIT_VALUE (expr->right)) {
345 return valForCastAggr (expr->left, expr->left->ftype,
351 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
352 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
353 if (compareType(toType, expr->left->ftype)!=1) {
354 werror (W_INIT_WRONG);
355 printFromToType(expr->left->ftype, toType);
361 /* no then we have to do these cludgy checks */
362 /* pointers can be initialized with address of
363 a variable or address of an array element */
364 if (IS_AST_OP (expr) && expr->opval.op == '&') {
365 /* address of symbol */
366 if (IS_AST_SYM_VALUE (expr->left)) {
367 val = AST_VALUE (expr->left);
368 val->type = newLink (DECLARATOR);
369 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
370 DCL_TYPE (val->type) = CPOINTER;
371 DCL_PTR_CONST (val->type) = port->mem.code_ro;
373 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
374 DCL_TYPE (val->type) = FPOINTER;
375 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
376 DCL_TYPE (val->type) = PPOINTER;
377 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
378 DCL_TYPE (val->type) = IPOINTER;
379 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
380 DCL_TYPE (val->type) = EEPPOINTER;
382 DCL_TYPE (val->type) = POINTER;
383 val->type->next = expr->left->ftype;
384 val->etype = getSpec (val->type);
388 /* if address of indexed array */
389 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
390 return valForArray (expr->left);
392 /* if address of structure element then
394 if (IS_AST_OP (expr->left) &&
395 expr->left->opval.op == '.') {
396 return valForStructElem (expr->left->left,
401 (&some_struct)->element */
402 if (IS_AST_OP (expr->left) &&
403 expr->left->opval.op == PTR_OP &&
404 IS_ADDRESS_OF_OP (expr->left->left)) {
405 return valForStructElem (expr->left->left->left,
409 /* case 3. (((char *) &a) +/- constant) */
410 if (IS_AST_OP (expr) &&
411 (expr->opval.op == '+' || expr->opval.op == '-') &&
412 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
413 IS_AST_OP (expr->left->right) &&
414 expr->left->right->opval.op == '&' &&
415 IS_AST_LIT_VALUE (expr->right)) {
417 return valForCastAggr (expr->left->right->left,
418 expr->left->left->opval.lnk,
419 expr->right, expr->opval.op);
422 /* case 4. (char *)(array type) */
423 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
424 IS_ARRAY(expr->right->ftype)) {
426 val = copyValue (AST_VALUE (expr->right));
427 val->type = newLink (DECLARATOR);
428 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
429 DCL_TYPE (val->type) = CPOINTER;
430 DCL_PTR_CONST (val->type) = port->mem.code_ro;
432 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
433 DCL_TYPE (val->type) = FPOINTER;
434 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
435 DCL_TYPE (val->type) = PPOINTER;
436 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
437 DCL_TYPE (val->type) = IPOINTER;
438 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
439 DCL_TYPE (val->type) = EEPPOINTER;
441 DCL_TYPE (val->type) = POINTER;
442 val->type->next = expr->right->ftype->next;
443 val->etype = getSpec (val->type);
448 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
450 werror (E_INCOMPAT_PTYPES);
455 /*-----------------------------------------------------------------*/
456 /* printChar - formats and prints a characater string with DB */
457 /*-----------------------------------------------------------------*/
459 printChar (struct dbuf_s * oBuf, char *s, int plen)
467 while (len && pplen < plen)
470 while (i && pplen < plen)
472 if (*s < ' ' || *s == '\"' || *s=='\\')
476 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
477 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
492 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
503 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
508 /*-----------------------------------------------------------------*/
509 /* return the generic pointer high byte for a given pointer type. */
510 /*-----------------------------------------------------------------*/
512 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
520 werror (E_CANNOT_USE_GENERIC_POINTER,
521 iname ? iname : "<null>",
522 oname ? oname : "<null>");
529 return GPTYPE_XSTACK;
531 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
539 /*-----------------------------------------------------------------*/
540 /* printPointerType - generates ival for pointer type */
541 /*-----------------------------------------------------------------*/
543 _printPointerType (struct dbuf_s * oBuf, const char *name)
545 if (options.model == MODEL_FLAT24)
547 if (port->little_endian)
548 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
550 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
554 if (port->little_endian)
555 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
557 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
561 /*-----------------------------------------------------------------*/
562 /* printPointerType - generates ival for pointer type */
563 /*-----------------------------------------------------------------*/
565 printPointerType (struct dbuf_s * oBuf, const char *name)
567 _printPointerType (oBuf, name);
568 dbuf_printf (oBuf, "\n");
571 /*-----------------------------------------------------------------*/
572 /* printGPointerType - generates ival for generic pointer type */
573 /*-----------------------------------------------------------------*/
575 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
576 const unsigned int type)
578 _printPointerType (oBuf, iname);
579 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
582 /*-----------------------------------------------------------------*/
583 /* printIvalType - generates ival for int/char */
584 /*-----------------------------------------------------------------*/
586 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
590 /* if initList is deep */
591 if (ilist && (ilist->type == INIT_DEEP))
592 ilist = ilist->init.deep;
594 if (!(val = list2val (ilist))) {
595 // assuming a warning has been thrown
596 val = constCharVal (0);
599 /* check if the literal value is within bounds */
600 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
601 !options.lessPedantic)
603 werror (W_LIT_OVERFLOW);
606 if (val->type != type) {
607 val = valCastLiteral(type, floatFromVal(val));
610 switch (getSize (type)) {
613 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
615 dbuf_tprintf (oBuf, "\t!dbs\n",
616 aopLiteral (val, 0));
620 if (port->use_dw_for_init)
621 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
622 else if (port->little_endian)
623 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
625 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
629 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
630 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
632 else if (port->little_endian) {
633 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
634 aopLiteral (val, 0), aopLiteral (val, 1),
635 aopLiteral (val, 2), aopLiteral (val, 3));
638 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
639 aopLiteral (val, 3), aopLiteral (val, 2),
640 aopLiteral (val, 1), aopLiteral (val, 0));
646 /*-----------------------------------------------------------------*/
647 /* printIvalBitFields - generate initializer for bitfields */
648 /*-----------------------------------------------------------------*/
650 printIvalBitFields (symbol **sym, initList **ilist, struct dbuf_s * oBuf)
653 initList *lilist = *ilist;
654 unsigned long ival = 0;
660 if (0 == SPEC_BLEN (lsym->etype))
662 /* bit-field structure member with a width of 0 */
666 else if (!SPEC_BUNNAMED (lsym->etype))
668 /* not an unnamed bit-field structure member */
669 value *val = list2val (lilist);
670 int bit_length = SPEC_BLEN (lsym->etype);
675 size += (bit_length + 7) / 8;
678 size = (bit_length + 7) / 8;
680 /* check if the literal value is within bounds */
682 checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
683 !options.lessPedantic)
685 werror (W_LIT_OVERFLOW);
688 ival |= (ulFromVal (val) & ((1ul << bit_length) - 1ul)) << SPEC_BSTR (lsym->etype);
689 lilist = lilist ? lilist->next : NULL;
697 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
701 dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
705 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
706 (ival >> 16) & 0xffff, (ival & 0xffff));
713 /*-----------------------------------------------------------------*/
714 /* printIvalStruct - generates initial value for structures */
715 /*-----------------------------------------------------------------*/
717 printIvalStruct (symbol * sym, sym_link * type,
718 initList * ilist, struct dbuf_s * oBuf)
721 initList *iloop = NULL;
723 sflds = SPEC_STRUCT (type)->fields;
727 if (ilist->type != INIT_DEEP)
729 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
733 iloop = ilist->init.deep;
736 if (SPEC_STRUCT (type)->type == UNION)
738 printIval (sym, sflds->type, iloop, oBuf, 1);
739 iloop = iloop ? iloop->next : NULL;
745 if (IS_BITFIELD (sflds->type))
746 printIvalBitFields(&sflds, &iloop, oBuf);
749 printIval (sym, sflds->type, iloop, oBuf, 1);
751 iloop = iloop ? iloop->next : NULL;
757 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
760 /*-----------------------------------------------------------------*/
761 /* printIvalChar - generates initital value for character array */
762 /*-----------------------------------------------------------------*/
764 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
767 unsigned int size = DCL_ELEM (type);
771 val = list2val (ilist);
772 /* if the value is a character string */
773 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
777 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
778 "size should never be 0");
780 /* we have not been given a size, but now we know it */
781 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
782 /* but first check, if it's a flexible array */
783 if (sym && IS_STRUCT (sym->type))
784 sym->flexArrayLength = size;
786 DCL_ELEM (type) = size;
789 if (check && DCL_ELEM (val->type) > size)
790 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
792 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
800 printChar (oBuf, s, strlen (s) + 1);
804 /*-----------------------------------------------------------------*/
805 /* printIvalArray - generates code for array initialization */
806 /*-----------------------------------------------------------------*/
808 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
809 struct dbuf_s * oBuf, bool check)
813 unsigned int size = 0;
816 /* take care of the special case */
817 /* array of characters can be init */
819 if (IS_CHAR (type->next)) {
820 val = list2val(ilist);
822 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
825 if (!IS_LITERAL(val->etype)) {
826 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
829 if (printIvalChar (sym, type,
830 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
831 oBuf, SPEC_CVAL (sym->etype).v_char, check))
834 /* not the special case */
835 if (ilist->type != INIT_DEEP) {
836 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
840 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
841 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
842 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
845 printIval (sym, type->next, iloop, oBuf, TRUE);
849 if (DCL_ELEM(type)) {
850 // pad with zeros if needed
851 if (size<DCL_ELEM(type)) {
852 size = (DCL_ELEM(type) - size) * getSize(type->next);
854 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
858 /* we have not been given a size, but now we know it */
859 /* but first check, if it's a flexible array */
860 if (IS_STRUCT (sym->type))
861 sym->flexArrayLength = size * getSize (type->next);
863 DCL_ELEM (type) = size;
869 /*-----------------------------------------------------------------*/
870 /* printIvalFuncPtr - generate initial value for function pointers */
871 /*-----------------------------------------------------------------*/
873 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
879 val = list2val (ilist);
881 val = valCastLiteral(type, 0.0);
884 // an error has been thrown already
885 val = constCharVal (0);
888 if (IS_LITERAL(val->etype)) {
889 if (compareType(type, val->etype) == 0) {
890 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
891 printFromToType (val->type, type);
893 printIvalCharPtr (NULL, type, val, oBuf);
897 /* check the types */
898 if ((dLvl = compareType (val->type, type->next)) <= 0)
900 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
904 /* now generate the name */
907 if (port->use_dw_for_init)
909 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
913 printPointerType (oBuf, val->name);
916 else if (port->use_dw_for_init)
918 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
922 printPointerType (oBuf, val->sym->rname);
928 /*-----------------------------------------------------------------*/
929 /* printIvalCharPtr - generates initial values for character pointers */
930 /*-----------------------------------------------------------------*/
932 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
936 /* PENDING: this is _very_ mcs51 specific, including a magic
938 It's also endian specific.
940 size = getSize (type);
942 if (val->name && strlen (val->name))
944 if (size == 1) /* This appears to be Z80 specific?? */
947 "\t!dbs\n", val->name);
949 else if (size == FPTRSIZE)
951 if (port->use_dw_for_init)
953 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
957 printPointerType (oBuf, val->name);
960 else if (size == GPTRSIZE)
963 if (IS_PTR (val->type)) {
964 type = DCL_TYPE (val->type);
966 type = PTR_TYPE (SPEC_OCLS (val->etype));
968 if (val->sym && val->sym->isstrlit) {
969 // this is a literal string
972 printGPointerType (oBuf, val->name, sym->name, type);
976 fprintf (stderr, "*** internal error: unknown size in "
977 "printIvalCharPtr.\n");
982 // these are literals assigned to pointers
986 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
989 if (port->use_dw_for_init)
990 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
991 else if (port->little_endian)
992 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
993 aopLiteral (val, 0), aopLiteral (val, 1));
995 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
996 aopLiteral (val, 1), aopLiteral (val, 0));
999 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1000 // non-zero mcs51 generic pointer
1001 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1003 if (port->little_endian) {
1004 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1005 aopLiteral (val, 0),
1006 aopLiteral (val, 1),
1007 aopLiteral (val, 2));
1009 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1010 aopLiteral (val, 2),
1011 aopLiteral (val, 1),
1012 aopLiteral (val, 0));
1016 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1017 // non-zero ds390 generic pointer
1018 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1020 if (port->little_endian) {
1021 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1022 aopLiteral (val, 0),
1023 aopLiteral (val, 1),
1024 aopLiteral (val, 2),
1025 aopLiteral (val, 3));
1027 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1028 aopLiteral (val, 3),
1029 aopLiteral (val, 2),
1030 aopLiteral (val, 1),
1031 aopLiteral (val, 0));
1039 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1040 addSet (&statsg->syms, val->sym);
1046 /*-----------------------------------------------------------------*/
1047 /* printIvalPtr - generates initial value for pointers */
1048 /*-----------------------------------------------------------------*/
1050 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1056 if (ilist && (ilist->type == INIT_DEEP))
1057 ilist = ilist->init.deep;
1059 /* function pointer */
1060 if (IS_FUNC (type->next))
1062 printIvalFuncPtr (type, ilist, oBuf);
1066 if (!(val = initPointer (ilist, type)))
1069 /* if character pointer */
1070 if (IS_CHAR (type->next))
1071 if (printIvalCharPtr (sym, type, val, oBuf))
1074 /* check the type */
1075 if (compareType (type, val->type) == 0) {
1076 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1077 printFromToType (val->type, type);
1080 /* if val is literal */
1081 if (IS_LITERAL (val->etype))
1083 switch (getSize (type))
1086 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1089 if (port->use_dw_for_init)
1090 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1091 else if (port->little_endian)
1092 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1094 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1096 case 3: // how about '390??
1097 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1098 if (port->little_endian)
1100 dbuf_printf (oBuf, "\t.byte %s,%s",
1101 aopLiteral (val, 0), aopLiteral (val, 1));
1105 dbuf_printf (oBuf, "\t.byte %s,%s",
1106 aopLiteral (val, 1), aopLiteral (val, 0));
1108 if (IS_GENPTR (val->type))
1109 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1110 else if (IS_PTR (val->type))
1111 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1113 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1119 size = getSize (type);
1121 if (size == 1) /* Z80 specific?? */
1123 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1125 else if (size == FPTRSIZE)
1127 if (port->use_dw_for_init) {
1128 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1130 printPointerType (oBuf, val->name);
1133 else if (size == GPTRSIZE)
1135 printGPointerType (oBuf, val->name, sym->name,
1136 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1137 PTR_TYPE (SPEC_OCLS (val->etype))));
1142 /*-----------------------------------------------------------------*/
1143 /* printIval - generates code for initial value */
1144 /*-----------------------------------------------------------------*/
1146 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1150 /* if structure then */
1151 if (IS_STRUCT (type))
1153 printIvalStruct (sym, type, ilist, oBuf);
1157 /* if this is an array */
1158 if (IS_ARRAY (type))
1160 printIvalArray (sym, type, ilist, oBuf, check);
1166 // not an aggregate, ilist must be a node
1167 if (ilist->type!=INIT_NODE) {
1168 // or a 1-element list
1169 if (ilist->init.deep->next) {
1170 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1173 ilist=ilist->init.deep;
1177 // and the type must match
1178 itype=ilist->init.node->ftype;
1180 if (compareType(type, itype)==0) {
1181 // special case for literal strings
1182 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1183 // which are really code pointers
1184 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1187 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1188 printFromToType(itype, type);
1193 /* if this is a pointer */
1196 printIvalPtr (sym, type, ilist, oBuf);
1200 /* if type is SPECIFIER */
1203 printIvalType (sym, type, ilist, oBuf);
1208 /*-----------------------------------------------------------------*/
1209 /* emitStaticSeg - emitcode for the static segment */
1210 /*-----------------------------------------------------------------*/
1212 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1216 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1218 /* for all variables in this segment do */
1219 for (sym = setFirstItem (map->syms); sym;
1220 sym = setNextItem (map->syms))
1223 /* if it is "extern" then do nothing */
1224 if (IS_EXTERN (sym->etype))
1227 /* if it is not static add it to the public table */
1228 if (!IS_STATIC (sym->etype))
1230 addSetHead (&publics, sym);
1233 /* print extra debug info if required */
1238 if (IS_STATIC (sym->etype))
1239 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1241 dbuf_printf (oBuf, "G$"); /* scope is global */
1245 /* symbol is local */
1246 dbuf_printf (oBuf, "L%s$",
1247 (sym->localof ? sym->localof->name : "-null-"));
1249 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1252 /* if it has an absolute address and no initializer */
1253 if (SPEC_ABSA (sym->etype) && !sym->ival)
1256 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1258 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1260 SPEC_ADDR (sym->etype));
1265 dbuf_printf (oBuf, " == .\n");
1267 /* if it has an initial value */
1270 if (SPEC_ABSA (sym->etype))
1272 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1274 dbuf_printf (oBuf, "%s:\n", sym->rname);
1276 resolveIvalSym (sym->ival, sym->type);
1277 printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1279 /* if sym is a simple string and sym->ival is a string,
1280 WE don't need it anymore */
1281 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1282 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1283 list2val(sym->ival)->sym->isstrlit) {
1284 freeStringSymbol(list2val(sym->ival)->sym);
1288 /* allocate space */
1289 int size = getSize (sym->type);
1292 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1294 dbuf_printf (oBuf, "%s:\n", sym->rname);
1295 /* special case for character strings */
1296 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1297 SPEC_CVAL (sym->etype).v_char)
1299 SPEC_CVAL (sym->etype).v_char,
1302 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1308 /*-----------------------------------------------------------------*/
1309 /* emitMaps - emits the code for the data portion the code */
1310 /*-----------------------------------------------------------------*/
1314 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1315 /* ports but let's be conservative - EEP */
1318 /* no special considerations for the following
1319 data, idata & bit & xdata */
1320 emitRegularMap (data, TRUE, TRUE);
1321 emitRegularMap (idata, TRUE, TRUE);
1322 emitRegularMap (d_abs, TRUE, TRUE);
1323 emitRegularMap (i_abs, TRUE, TRUE);
1324 emitRegularMap (bit, TRUE, TRUE);
1325 emitRegularMap (pdata, TRUE, TRUE);
1326 emitRegularMap (xdata, TRUE, TRUE);
1327 emitRegularMap (x_abs, TRUE, TRUE);
1328 if (port->genXINIT) {
1329 emitRegularMap (xidata, TRUE, TRUE);
1331 emitRegularMap (sfr, publicsfr, FALSE);
1332 emitRegularMap (sfrbit, publicsfr, FALSE);
1333 emitRegularMap (home, TRUE, FALSE);
1334 emitRegularMap (code, TRUE, FALSE);
1336 if (options.const_seg) {
1337 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1339 emitStaticSeg (statsg, &code->oBuf);
1340 if (port->genXINIT) {
1341 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1342 emitStaticSeg (xinit, &code->oBuf);
1344 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1345 emitStaticSeg (c_abs, &code->oBuf);
1349 /*-----------------------------------------------------------------*/
1350 /* flushStatics - flush all currently defined statics out to file */
1351 /* and delete. Temporary function */
1352 /*-----------------------------------------------------------------*/
1356 emitStaticSeg (statsg, codeOutBuf);
1357 statsg->syms = NULL;
1360 /*-----------------------------------------------------------------*/
1361 /* createInterruptVect - creates the interrupt vector */
1362 /*-----------------------------------------------------------------*/
1364 createInterruptVect (struct dbuf_s *vBuf)
1366 mainf = newSymbol ("main", 0);
1369 /* only if the main function exists */
1370 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1372 if (!options.cc_only && !noAssemble && !options.c1mode)
1377 /* if the main is only a prototype ie. no body then do nothing */
1378 if (!IFFUNC_HASBODY(mainf->type))
1380 /* if ! compile only then main function should be present */
1381 if (!options.cc_only && !noAssemble)
1386 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1387 dbuf_printf (vBuf, "__interrupt_vect:\n");
1390 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1392 /* There's no such thing as a "generic" interrupt table header. */
1399 ";--------------------------------------------------------\n"
1400 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1404 ";--------------------------------------------------------\n"};
1407 /*-----------------------------------------------------------------*/
1408 /* initialComments - puts in some initial comments */
1409 /*-----------------------------------------------------------------*/
1411 initialComments (FILE * afile)
1415 fprintf (afile, "%s", iComments1);
1416 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1417 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1418 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1419 fprintf (afile, "%s", iComments2);
1422 /*-----------------------------------------------------------------*/
1423 /* printPublics - generates .global for publics */
1424 /*-----------------------------------------------------------------*/
1426 printPublics (FILE * afile)
1430 fprintf (afile, "%s", iComments2);
1431 fprintf (afile, "; Public variables in this module\n");
1432 fprintf (afile, "%s", iComments2);
1434 for (sym = setFirstItem (publics); sym;
1435 sym = setNextItem (publics))
1436 tfprintf (afile, "\t!global\n", sym->rname);
1439 /*-----------------------------------------------------------------*/
1440 /* printExterns - generates .global for externs */
1441 /*-----------------------------------------------------------------*/
1443 printExterns (FILE * afile)
1447 fprintf (afile, "%s", iComments2);
1448 fprintf (afile, "; Externals used\n");
1449 fprintf (afile, "%s", iComments2);
1451 for (sym = setFirstItem (externs); sym;
1452 sym = setNextItem (externs))
1453 tfprintf (afile, "\t!extern\n", sym->rname);
1456 /*-----------------------------------------------------------------*/
1457 /* emitOverlay - will emit code for the overlay stuff */
1458 /*-----------------------------------------------------------------*/
1460 emitOverlay (struct dbuf_s * aBuf)
1464 if (!elementsInSet (ovrSetSets))
1465 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1467 /* for each of the sets in the overlay segment do */
1468 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1469 ovrset = setNextItem (ovrSetSets))
1474 if (elementsInSet (ovrset))
1476 /* output the area informtion */
1477 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1480 for (sym = setFirstItem (ovrset); sym;
1481 sym = setNextItem (ovrset))
1483 /* if extern then it is in the publics table: do nothing */
1484 if (IS_EXTERN (sym->etype))
1487 /* if allocation required check is needed
1488 then check if the symbol really requires
1489 allocation only for local variables */
1490 if (!IS_AGGREGATE (sym->type) &&
1491 !(sym->_isparm && !IS_REGPARM (sym->etype))
1492 && !sym->allocreq && sym->level)
1495 /* if global variable & not static or extern
1496 and addPublics allowed then add it to the public set */
1497 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1498 && !IS_STATIC (sym->etype))
1500 addSetHead (&publics, sym);
1503 /* if extern then do nothing or is a function
1505 if (IS_FUNC (sym->type))
1508 /* print extra debug info if required */
1513 if (IS_STATIC (sym->etype))
1514 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1516 dbuf_printf (aBuf, "G$"); /* scope is global */
1519 /* symbol is local */
1520 dbuf_printf (aBuf, "L%s$",
1521 (sym->localof ? sym->localof->name : "-null-"));
1522 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1525 /* if is has an absolute address then generate
1526 an equate for this no need to allocate space */
1527 if (SPEC_ABSA (sym->etype))
1531 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1533 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1535 SPEC_ADDR (sym->etype));
1539 int size = getSize(sym->type);
1542 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1545 dbuf_printf (aBuf, "==.\n");
1547 /* allocate space */
1548 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1549 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1556 /*-----------------------------------------------------------------*/
1557 /* glue - the final glue that hold the whole thing together */
1558 /*-----------------------------------------------------------------*/
1563 struct dbuf_s ovrBuf;
1567 dbuf_init (&vBuf, 4096);
1568 dbuf_init (&ovrBuf, 4096);
1570 mcs51_like = (port->general.glue_up_main &&
1571 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1573 /* print the global struct definitions */
1577 /* PENDING: this isn't the best place but it will do */
1578 if (port->general.glue_up_main)
1580 /* create the interrupt vector table */
1581 createInterruptVect (&vBuf);
1584 /* emit code for the all the variables declared */
1586 /* do the overlay segments */
1587 emitOverlay (&ovrBuf);
1589 outputDebugSymbols ();
1591 /* now put it all together into the assembler file */
1592 /* create the assembler file name */
1594 /* -o option overrides default name? */
1595 if ((noAssemble || options.c1mode) && fullDstFileName)
1597 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1601 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1602 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1605 if (!(asmFile = fopen (scratchFileName, "w")))
1607 werror (E_FILE_OPEN_ERR, scratchFileName);
1608 exit (EXIT_FAILURE);
1611 /* initial comments */
1612 initialComments (asmFile);
1614 /* print module name */
1615 tfprintf (asmFile, "\t!module\n", moduleName);
1618 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1620 switch(options.model)
1622 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1623 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1624 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1625 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1626 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1627 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1630 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1631 if(options.useXstack) fprintf (asmFile, " --xstack");
1632 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1633 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1634 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1635 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1636 fprintf (asmFile, "\n");
1638 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1640 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1643 tfprintf (asmFile, "\t!fileprelude\n");
1645 /* Let the port generate any global directives, etc. */
1646 if (port->genAssemblerPreamble)
1648 port->genAssemblerPreamble (asmFile);
1651 /* print the global variables in this module */
1652 printPublics (asmFile);
1653 if (port->assembler.externGlobal)
1654 printExterns (asmFile);
1657 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1659 /* copy the sfr segment */
1660 fprintf (asmFile, "%s", iComments2);
1661 fprintf (asmFile, "; special function registers\n");
1662 fprintf (asmFile, "%s", iComments2);
1663 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1668 /* copy the sbit segment */
1669 fprintf (asmFile, "%s", iComments2);
1670 fprintf (asmFile, "; special function bits\n");
1671 fprintf (asmFile, "%s", iComments2);
1672 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1674 /*JCF: Create the areas for the register banks*/
1675 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1677 fprintf (asmFile, "%s", iComments2);
1678 fprintf (asmFile, "; overlayable register banks\n");
1679 fprintf (asmFile, "%s", iComments2);
1681 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1682 if (RegBankUsed[1] || options.parms_in_bank1)
1683 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1685 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1687 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1691 fprintf (asmFile, "%s", iComments2);
1692 fprintf (asmFile, "; overlayable bit register bank\n");
1693 fprintf (asmFile, "%s", iComments2);
1694 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1695 fprintf (asmFile, "bits:\n\t.ds 1\n");
1696 fprintf (asmFile, "\tb0 = bits[0]\n");
1697 fprintf (asmFile, "\tb1 = bits[1]\n");
1698 fprintf (asmFile, "\tb2 = bits[2]\n");
1699 fprintf (asmFile, "\tb3 = bits[3]\n");
1700 fprintf (asmFile, "\tb4 = bits[4]\n");
1701 fprintf (asmFile, "\tb5 = bits[5]\n");
1702 fprintf (asmFile, "\tb6 = bits[6]\n");
1703 fprintf (asmFile, "\tb7 = bits[7]\n");
1707 /* copy the data segment */
1708 fprintf (asmFile, "%s", iComments2);
1709 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1710 fprintf (asmFile, "%s", iComments2);
1711 dbuf_write_and_destroy (&data->oBuf, asmFile);
1714 /* create the overlay segments */
1717 fprintf (asmFile, "%s", iComments2);
1718 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1719 fprintf (asmFile, "%s", iComments2);
1720 dbuf_write_and_destroy (&ovrBuf, asmFile);
1723 /* create the stack segment MOF */
1724 if (mainf && IFFUNC_HASBODY (mainf->type))
1726 fprintf (asmFile, "%s", iComments2);
1727 fprintf (asmFile, "; Stack segment in internal ram \n");
1728 fprintf (asmFile, "%s", iComments2);
1729 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1730 "__start__stack:\n\t.ds\t1\n\n");
1733 /* create the idata segment */
1734 if ((idata) && (mcs51_like))
1736 fprintf (asmFile, "%s", iComments2);
1737 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1738 fprintf (asmFile, "%s", iComments2);
1739 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1742 /* create the absolute idata/data segment */
1743 if ((i_abs) && (mcs51_like))
1745 fprintf (asmFile, "%s", iComments2);
1746 fprintf (asmFile, "; absolute internal ram data\n");
1747 fprintf (asmFile, "%s", iComments2);
1748 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1749 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1752 /* copy the bit segment */
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile, "; bit data\n");
1757 fprintf (asmFile, "%s", iComments2);
1758 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1761 /* copy paged external ram data */
1764 fprintf (asmFile, "%s", iComments2);
1765 fprintf (asmFile, "; paged external ram data\n");
1766 fprintf (asmFile, "%s", iComments2);
1767 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1770 /* if external stack then reserve space for it */
1771 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1773 fprintf (asmFile, "%s", iComments2);
1774 fprintf (asmFile, "; external stack \n");
1775 fprintf (asmFile, "%s", iComments2);
1776 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1777 "__start__xstack:\n\t.ds\t1\n\n");
1780 /* copy external ram data */
1783 fprintf (asmFile, "%s", iComments2);
1784 fprintf (asmFile, "; external ram data\n");
1785 fprintf (asmFile, "%s", iComments2);
1786 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1789 /* create the absolute xdata segment */
1790 if (mcs51_like || TARGET_IS_HC08)
1792 fprintf (asmFile, "%s", iComments2);
1793 fprintf (asmFile, "; absolute external ram data\n");
1794 fprintf (asmFile, "%s", iComments2);
1795 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1798 /* copy external initialized ram data */
1799 fprintf (asmFile, "%s", iComments2);
1800 fprintf (asmFile, "; external initialized ram data\n");
1801 fprintf (asmFile, "%s", iComments2);
1802 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1804 /* If the port wants to generate any extra areas, let it do so. */
1805 if (port->extraAreas.genExtraAreaDeclaration)
1807 port->extraAreas.genExtraAreaDeclaration(asmFile,
1808 mainf && IFFUNC_HASBODY(mainf->type));
1811 /* copy the interrupt vector table */
1812 if (mainf && IFFUNC_HASBODY (mainf->type))
1814 fprintf (asmFile, "%s", iComments2);
1815 fprintf (asmFile, "; interrupt vector \n");
1816 fprintf (asmFile, "%s", iComments2);
1817 dbuf_write_and_destroy (&vBuf, asmFile);
1820 /* copy global & static initialisations */
1821 fprintf (asmFile, "%s", iComments2);
1822 fprintf (asmFile, "; global & static initialisations\n");
1823 fprintf (asmFile, "%s", iComments2);
1825 /* Everywhere we generate a reference to the static_name area,
1826 * (which is currently only here), we immediately follow it with a
1827 * definition of the post_static_name area. This guarantees that
1828 * the post_static_name area will immediately follow the static_name
1831 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1832 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1833 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1834 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1836 if (mainf && IFFUNC_HASBODY (mainf->type))
1838 if (port->genInitStartup)
1840 port->genInitStartup (asmFile);
1844 assert (mcs51_like);
1845 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1846 /* if external stack is specified then the
1847 higher order byte of the xdatalocation is
1848 going into P2 and the lower order going into
1850 if (options.useXstack)
1852 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1853 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1854 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1855 (unsigned int) options.xdata_loc & 0xff);
1858 // This should probably be a port option, but I'm being lazy.
1859 // on the 400, the firmware boot loader gives us a valid stack
1860 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1861 if (!TARGET_IS_DS400)
1863 /* initialise the stack pointer. JCF: aslink takes care of the location */
1864 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1867 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1868 fprintf (asmFile, "\tmov\ta,dpl\n");
1869 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1870 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1871 fprintf (asmFile, "__sdcc_init_data:\n");
1873 // if the port can copy the XINIT segment to XISEG
1876 port->genXINIT (asmFile);
1880 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1882 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1884 /* This code is generated in the post-static area.
1885 * This area is guaranteed to follow the static area
1886 * by the ugly shucking and jiving about 20 lines ago.
1888 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1889 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1895 "%s", iComments2, iComments2);
1896 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1897 dbuf_write_and_destroy (&home->oBuf, asmFile);
1899 if (mainf && IFFUNC_HASBODY (mainf->type))
1901 /* entry point @ start of HOME */
1902 fprintf (asmFile, "__sdcc_program_startup:\n");
1904 /* put in jump or call to main */
1905 if (options.mainreturn)
1907 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1908 fprintf (asmFile, ";\treturn from main will return to caller\n");
1912 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1913 fprintf (asmFile, ";\treturn from main will lock up\n");
1914 fprintf (asmFile, "\tsjmp .\n");
1917 /* copy over code */
1918 fprintf (asmFile, "%s", iComments2);
1919 fprintf (asmFile, "; code\n");
1920 fprintf (asmFile, "%s", iComments2);
1921 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1922 dbuf_write_and_destroy (&code->oBuf, asmFile);
1924 if (port->genAssemblerEnd)
1926 port->genAssemblerEnd (asmFile);