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 /* we have not been given a size, but now we know it */
778 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
779 /* but first check, if it's a flexible array */
780 if (sym && IS_STRUCT (sym->type))
781 sym->flexArrayLength = size;
783 DCL_ELEM (type) = size;
786 if (check && DCL_ELEM (val->type) > size)
787 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
789 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
797 printChar (oBuf, s, strlen (s) + 1);
801 /*-----------------------------------------------------------------*/
802 /* printIvalArray - generates code for array initialization */
803 /*-----------------------------------------------------------------*/
805 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
806 struct dbuf_s * oBuf, bool check)
810 unsigned int size = 0;
813 /* take care of the special case */
814 /* array of characters can be init */
816 if (IS_CHAR (type->next)) {
817 val = list2val(ilist);
819 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
822 if (!IS_LITERAL(val->etype)) {
823 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
826 if (printIvalChar (sym, type,
827 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
828 oBuf, SPEC_CVAL (sym->etype).v_char, check))
831 /* not the special case */
832 if (ilist->type != INIT_DEEP) {
833 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
837 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
838 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
839 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
842 printIval (sym, type->next, iloop, oBuf, TRUE);
846 if (DCL_ELEM(type)) {
847 // pad with zeros if needed
848 if (size<DCL_ELEM(type)) {
849 size = (DCL_ELEM(type) - size) * getSize(type->next);
851 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
855 /* we have not been given a size, but now we know it */
856 /* but first check, if it's a flexible array */
857 if (IS_STRUCT (sym->type))
858 sym->flexArrayLength = size * getSize (type->next);
860 DCL_ELEM (type) = size;
866 /*-----------------------------------------------------------------*/
867 /* printIvalFuncPtr - generate initial value for function pointers */
868 /*-----------------------------------------------------------------*/
870 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
876 val = list2val (ilist);
878 val = valCastLiteral(type, 0.0);
881 // an error has been thrown already
882 val = constCharVal (0);
885 if (IS_LITERAL(val->etype)) {
886 if (compareType(type, val->etype) == 0) {
887 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
888 printFromToType (val->type, type);
890 printIvalCharPtr (NULL, type, val, oBuf);
894 /* check the types */
895 if ((dLvl = compareType (val->type, type->next)) <= 0)
897 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
901 /* now generate the name */
904 if (port->use_dw_for_init)
906 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
910 printPointerType (oBuf, val->name);
913 else if (port->use_dw_for_init)
915 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
919 printPointerType (oBuf, val->sym->rname);
925 /*-----------------------------------------------------------------*/
926 /* printIvalCharPtr - generates initial values for character pointers */
927 /*-----------------------------------------------------------------*/
929 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
933 /* PENDING: this is _very_ mcs51 specific, including a magic
935 It's also endian specific.
937 size = getSize (type);
939 if (val->name && strlen (val->name))
941 if (size == 1) /* This appears to be Z80 specific?? */
944 "\t!dbs\n", val->name);
946 else if (size == FPTRSIZE)
948 if (port->use_dw_for_init)
950 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
954 printPointerType (oBuf, val->name);
957 else if (size == GPTRSIZE)
960 if (IS_PTR (val->type)) {
961 type = DCL_TYPE (val->type);
963 type = PTR_TYPE (SPEC_OCLS (val->etype));
965 if (val->sym && val->sym->isstrlit) {
966 // this is a literal string
969 printGPointerType (oBuf, val->name, sym->name, type);
973 fprintf (stderr, "*** internal error: unknown size in "
974 "printIvalCharPtr.\n");
979 // these are literals assigned to pointers
983 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
986 if (port->use_dw_for_init)
987 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
988 else if (port->little_endian)
989 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
990 aopLiteral (val, 0), aopLiteral (val, 1));
992 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
993 aopLiteral (val, 1), aopLiteral (val, 0));
996 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
997 // non-zero mcs51 generic pointer
998 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1000 if (port->little_endian) {
1001 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1002 aopLiteral (val, 0),
1003 aopLiteral (val, 1),
1004 aopLiteral (val, 2));
1006 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1007 aopLiteral (val, 2),
1008 aopLiteral (val, 1),
1009 aopLiteral (val, 0));
1013 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1014 // non-zero ds390 generic pointer
1015 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1017 if (port->little_endian) {
1018 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1019 aopLiteral (val, 0),
1020 aopLiteral (val, 1),
1021 aopLiteral (val, 2),
1022 aopLiteral (val, 3));
1024 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1025 aopLiteral (val, 3),
1026 aopLiteral (val, 2),
1027 aopLiteral (val, 1),
1028 aopLiteral (val, 0));
1036 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1037 addSet (&statsg->syms, val->sym);
1043 /*-----------------------------------------------------------------*/
1044 /* printIvalPtr - generates initial value for pointers */
1045 /*-----------------------------------------------------------------*/
1047 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1053 if (ilist && (ilist->type == INIT_DEEP))
1054 ilist = ilist->init.deep;
1056 /* function pointer */
1057 if (IS_FUNC (type->next))
1059 printIvalFuncPtr (type, ilist, oBuf);
1063 if (!(val = initPointer (ilist, type)))
1066 /* if character pointer */
1067 if (IS_CHAR (type->next))
1068 if (printIvalCharPtr (sym, type, val, oBuf))
1071 /* check the type */
1072 if (compareType (type, val->type) == 0) {
1073 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1074 printFromToType (val->type, type);
1077 /* if val is literal */
1078 if (IS_LITERAL (val->etype))
1080 switch (getSize (type))
1083 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1086 if (port->use_dw_for_init)
1087 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1088 else if (port->little_endian)
1089 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1091 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1093 case 3: // how about '390??
1094 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1095 if (port->little_endian)
1097 dbuf_printf (oBuf, "\t.byte %s,%s",
1098 aopLiteral (val, 0), aopLiteral (val, 1));
1102 dbuf_printf (oBuf, "\t.byte %s,%s",
1103 aopLiteral (val, 1), aopLiteral (val, 0));
1105 if (IS_GENPTR (val->type))
1106 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1107 else if (IS_PTR (val->type))
1108 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1110 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1116 size = getSize (type);
1118 if (size == 1) /* Z80 specific?? */
1120 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1122 else if (size == FPTRSIZE)
1124 if (port->use_dw_for_init) {
1125 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1127 printPointerType (oBuf, val->name);
1130 else if (size == GPTRSIZE)
1132 printGPointerType (oBuf, val->name, sym->name,
1133 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1134 PTR_TYPE (SPEC_OCLS (val->etype))));
1139 /*-----------------------------------------------------------------*/
1140 /* printIval - generates code for initial value */
1141 /*-----------------------------------------------------------------*/
1143 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1147 /* if structure then */
1148 if (IS_STRUCT (type))
1150 printIvalStruct (sym, type, ilist, oBuf);
1154 /* if this is an array */
1155 if (IS_ARRAY (type))
1157 printIvalArray (sym, type, ilist, oBuf, check);
1163 // not an aggregate, ilist must be a node
1164 if (ilist->type!=INIT_NODE) {
1165 // or a 1-element list
1166 if (ilist->init.deep->next) {
1167 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1170 ilist=ilist->init.deep;
1174 // and the type must match
1175 itype=ilist->init.node->ftype;
1177 if (compareType(type, itype)==0) {
1178 // special case for literal strings
1179 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1180 // which are really code pointers
1181 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1184 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1185 printFromToType(itype, type);
1190 /* if this is a pointer */
1193 printIvalPtr (sym, type, ilist, oBuf);
1197 /* if type is SPECIFIER */
1200 printIvalType (sym, type, ilist, oBuf);
1205 /*-----------------------------------------------------------------*/
1206 /* emitStaticSeg - emitcode for the static segment */
1207 /*-----------------------------------------------------------------*/
1209 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1213 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1215 /* for all variables in this segment do */
1216 for (sym = setFirstItem (map->syms); sym;
1217 sym = setNextItem (map->syms))
1220 /* if it is "extern" then do nothing */
1221 if (IS_EXTERN (sym->etype))
1224 /* if it is not static add it to the public table */
1225 if (!IS_STATIC (sym->etype))
1227 addSetHead (&publics, sym);
1230 /* print extra debug info if required */
1235 if (IS_STATIC (sym->etype))
1236 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1238 dbuf_printf (oBuf, "G$"); /* scope is global */
1242 /* symbol is local */
1243 dbuf_printf (oBuf, "L%s$",
1244 (sym->localof ? sym->localof->name : "-null-"));
1246 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1249 /* if it has an absolute address and no initializer */
1250 if (SPEC_ABSA (sym->etype) && !sym->ival)
1253 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1255 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1257 SPEC_ADDR (sym->etype));
1262 dbuf_printf (oBuf, " == .\n");
1264 /* if it has an initial value */
1267 if (SPEC_ABSA (sym->etype))
1269 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1271 dbuf_printf (oBuf, "%s:\n", sym->rname);
1273 resolveIvalSym (sym->ival, sym->type);
1274 printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1276 /* if sym is a simple string and sym->ival is a string,
1277 WE don't need it anymore */
1278 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1279 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1280 list2val(sym->ival)->sym->isstrlit) {
1281 freeStringSymbol(list2val(sym->ival)->sym);
1285 /* allocate space */
1286 int size = getSize (sym->type);
1289 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1291 dbuf_printf (oBuf, "%s:\n", sym->rname);
1292 /* special case for character strings */
1293 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1294 SPEC_CVAL (sym->etype).v_char)
1296 SPEC_CVAL (sym->etype).v_char,
1299 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1305 /*-----------------------------------------------------------------*/
1306 /* emitMaps - emits the code for the data portion the code */
1307 /*-----------------------------------------------------------------*/
1311 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1312 /* ports but let's be conservative - EEP */
1315 /* no special considerations for the following
1316 data, idata & bit & xdata */
1317 emitRegularMap (data, TRUE, TRUE);
1318 emitRegularMap (idata, TRUE, TRUE);
1319 emitRegularMap (d_abs, TRUE, TRUE);
1320 emitRegularMap (i_abs, TRUE, TRUE);
1321 emitRegularMap (bit, TRUE, TRUE);
1322 emitRegularMap (pdata, TRUE, TRUE);
1323 emitRegularMap (xdata, TRUE, TRUE);
1324 emitRegularMap (x_abs, TRUE, TRUE);
1325 if (port->genXINIT) {
1326 emitRegularMap (xidata, TRUE, TRUE);
1328 emitRegularMap (sfr, publicsfr, FALSE);
1329 emitRegularMap (sfrbit, publicsfr, FALSE);
1330 emitRegularMap (home, TRUE, FALSE);
1331 emitRegularMap (code, TRUE, FALSE);
1333 if (options.const_seg) {
1334 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1336 emitStaticSeg (statsg, &code->oBuf);
1337 if (port->genXINIT) {
1338 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1339 emitStaticSeg (xinit, &code->oBuf);
1341 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1342 emitStaticSeg (c_abs, &code->oBuf);
1346 /*-----------------------------------------------------------------*/
1347 /* flushStatics - flush all currently defined statics out to file */
1348 /* and delete. Temporary function */
1349 /*-----------------------------------------------------------------*/
1353 emitStaticSeg (statsg, codeOutBuf);
1354 statsg->syms = NULL;
1357 /*-----------------------------------------------------------------*/
1358 /* createInterruptVect - creates the interrupt vector */
1359 /*-----------------------------------------------------------------*/
1361 createInterruptVect (struct dbuf_s *vBuf)
1363 mainf = newSymbol ("main", 0);
1366 /* only if the main function exists */
1367 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1369 if (!options.cc_only && !noAssemble && !options.c1mode)
1374 /* if the main is only a prototype ie. no body then do nothing */
1375 if (!IFFUNC_HASBODY(mainf->type))
1377 /* if ! compile only then main function should be present */
1378 if (!options.cc_only && !noAssemble)
1383 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1384 dbuf_printf (vBuf, "__interrupt_vect:\n");
1387 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1389 /* There's no such thing as a "generic" interrupt table header. */
1396 ";--------------------------------------------------------\n"
1397 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1401 ";--------------------------------------------------------\n"};
1404 /*-----------------------------------------------------------------*/
1405 /* initialComments - puts in some initial comments */
1406 /*-----------------------------------------------------------------*/
1408 initialComments (FILE * afile)
1412 fprintf (afile, "%s", iComments1);
1413 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1414 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1415 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1416 fprintf (afile, "%s", iComments2);
1419 /*-----------------------------------------------------------------*/
1420 /* printPublics - generates .global for publics */
1421 /*-----------------------------------------------------------------*/
1423 printPublics (FILE * afile)
1427 fprintf (afile, "%s", iComments2);
1428 fprintf (afile, "; Public variables in this module\n");
1429 fprintf (afile, "%s", iComments2);
1431 for (sym = setFirstItem (publics); sym;
1432 sym = setNextItem (publics))
1433 tfprintf (afile, "\t!global\n", sym->rname);
1436 /*-----------------------------------------------------------------*/
1437 /* printExterns - generates .global for externs */
1438 /*-----------------------------------------------------------------*/
1440 printExterns (FILE * afile)
1444 fprintf (afile, "%s", iComments2);
1445 fprintf (afile, "; Externals used\n");
1446 fprintf (afile, "%s", iComments2);
1448 for (sym = setFirstItem (externs); sym;
1449 sym = setNextItem (externs))
1450 tfprintf (afile, "\t!extern\n", sym->rname);
1453 /*-----------------------------------------------------------------*/
1454 /* emitOverlay - will emit code for the overlay stuff */
1455 /*-----------------------------------------------------------------*/
1457 emitOverlay (struct dbuf_s * aBuf)
1461 if (!elementsInSet (ovrSetSets))
1462 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1464 /* for each of the sets in the overlay segment do */
1465 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1466 ovrset = setNextItem (ovrSetSets))
1471 if (elementsInSet (ovrset))
1473 /* output the area informtion */
1474 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1477 for (sym = setFirstItem (ovrset); sym;
1478 sym = setNextItem (ovrset))
1480 /* if extern then it is in the publics table: do nothing */
1481 if (IS_EXTERN (sym->etype))
1484 /* if allocation required check is needed
1485 then check if the symbol really requires
1486 allocation only for local variables */
1487 if (!IS_AGGREGATE (sym->type) &&
1488 !(sym->_isparm && !IS_REGPARM (sym->etype))
1489 && !sym->allocreq && sym->level)
1492 /* if global variable & not static or extern
1493 and addPublics allowed then add it to the public set */
1494 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1495 && !IS_STATIC (sym->etype))
1497 addSetHead (&publics, sym);
1500 /* if extern then do nothing or is a function
1502 if (IS_FUNC (sym->type))
1505 /* print extra debug info if required */
1510 if (IS_STATIC (sym->etype))
1511 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1513 dbuf_printf (aBuf, "G$"); /* scope is global */
1516 /* symbol is local */
1517 dbuf_printf (aBuf, "L%s$",
1518 (sym->localof ? sym->localof->name : "-null-"));
1519 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1522 /* if is has an absolute address then generate
1523 an equate for this no need to allocate space */
1524 if (SPEC_ABSA (sym->etype))
1528 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1530 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1532 SPEC_ADDR (sym->etype));
1536 int size = getSize(sym->type);
1539 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1542 dbuf_printf (aBuf, "==.\n");
1544 /* allocate space */
1545 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1546 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1553 /*-----------------------------------------------------------------*/
1554 /* glue - the final glue that hold the whole thing together */
1555 /*-----------------------------------------------------------------*/
1560 struct dbuf_s ovrBuf;
1564 dbuf_init (&vBuf, 4096);
1565 dbuf_init (&ovrBuf, 4096);
1567 mcs51_like = (port->general.glue_up_main &&
1568 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1570 /* print the global struct definitions */
1574 /* PENDING: this isn't the best place but it will do */
1575 if (port->general.glue_up_main)
1577 /* create the interrupt vector table */
1578 createInterruptVect (&vBuf);
1581 /* emit code for the all the variables declared */
1583 /* do the overlay segments */
1584 emitOverlay (&ovrBuf);
1586 outputDebugSymbols ();
1588 /* now put it all together into the assembler file */
1589 /* create the assembler file name */
1591 /* -o option overrides default name? */
1592 if ((noAssemble || options.c1mode) && fullDstFileName)
1594 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1598 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1599 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1602 if (!(asmFile = fopen (scratchFileName, "w")))
1604 werror (E_FILE_OPEN_ERR, scratchFileName);
1605 exit (EXIT_FAILURE);
1608 /* initial comments */
1609 initialComments (asmFile);
1611 /* print module name */
1612 tfprintf (asmFile, "\t!module\n", moduleName);
1615 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1617 switch(options.model)
1619 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1620 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1621 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1622 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1623 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1624 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1627 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1628 if(options.useXstack) fprintf (asmFile, " --xstack");
1629 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1630 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1631 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1632 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1633 fprintf (asmFile, "\n");
1635 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1637 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1640 tfprintf (asmFile, "\t!fileprelude\n");
1642 /* Let the port generate any global directives, etc. */
1643 if (port->genAssemblerPreamble)
1645 port->genAssemblerPreamble (asmFile);
1648 /* print the global variables in this module */
1649 printPublics (asmFile);
1650 if (port->assembler.externGlobal)
1651 printExterns (asmFile);
1654 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1656 /* copy the sfr segment */
1657 fprintf (asmFile, "%s", iComments2);
1658 fprintf (asmFile, "; special function registers\n");
1659 fprintf (asmFile, "%s", iComments2);
1660 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1665 /* copy the sbit segment */
1666 fprintf (asmFile, "%s", iComments2);
1667 fprintf (asmFile, "; special function bits\n");
1668 fprintf (asmFile, "%s", iComments2);
1669 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1671 /*JCF: Create the areas for the register banks*/
1672 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1674 fprintf (asmFile, "%s", iComments2);
1675 fprintf (asmFile, "; overlayable register banks\n");
1676 fprintf (asmFile, "%s", iComments2);
1678 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1679 if (RegBankUsed[1] || options.parms_in_bank1)
1680 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1682 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1684 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1688 fprintf (asmFile, "%s", iComments2);
1689 fprintf (asmFile, "; overlayable bit register bank\n");
1690 fprintf (asmFile, "%s", iComments2);
1691 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1692 fprintf (asmFile, "bits:\n\t.ds 1\n");
1693 fprintf (asmFile, "\tb0 = bits[0]\n");
1694 fprintf (asmFile, "\tb1 = bits[1]\n");
1695 fprintf (asmFile, "\tb2 = bits[2]\n");
1696 fprintf (asmFile, "\tb3 = bits[3]\n");
1697 fprintf (asmFile, "\tb4 = bits[4]\n");
1698 fprintf (asmFile, "\tb5 = bits[5]\n");
1699 fprintf (asmFile, "\tb6 = bits[6]\n");
1700 fprintf (asmFile, "\tb7 = bits[7]\n");
1704 /* copy the data segment */
1705 fprintf (asmFile, "%s", iComments2);
1706 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1707 fprintf (asmFile, "%s", iComments2);
1708 dbuf_write_and_destroy (&data->oBuf, asmFile);
1711 /* create the overlay segments */
1714 fprintf (asmFile, "%s", iComments2);
1715 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1716 fprintf (asmFile, "%s", iComments2);
1717 dbuf_write_and_destroy (&ovrBuf, asmFile);
1720 /* create the stack segment MOF */
1721 if (mainf && IFFUNC_HASBODY (mainf->type))
1723 fprintf (asmFile, "%s", iComments2);
1724 fprintf (asmFile, "; Stack segment in internal ram \n");
1725 fprintf (asmFile, "%s", iComments2);
1726 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1727 "__start__stack:\n\t.ds\t1\n\n");
1730 /* create the idata segment */
1731 if ((idata) && (mcs51_like))
1733 fprintf (asmFile, "%s", iComments2);
1734 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1735 fprintf (asmFile, "%s", iComments2);
1736 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1739 /* create the absolute idata/data segment */
1740 if ((i_abs) && (mcs51_like))
1742 fprintf (asmFile, "%s", iComments2);
1743 fprintf (asmFile, "; absolute internal ram data\n");
1744 fprintf (asmFile, "%s", iComments2);
1745 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1746 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1749 /* copy the bit segment */
1752 fprintf (asmFile, "%s", iComments2);
1753 fprintf (asmFile, "; bit data\n");
1754 fprintf (asmFile, "%s", iComments2);
1755 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1758 /* copy paged external ram data */
1761 fprintf (asmFile, "%s", iComments2);
1762 fprintf (asmFile, "; paged external ram data\n");
1763 fprintf (asmFile, "%s", iComments2);
1764 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1767 /* if external stack then reserve space for it */
1768 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1770 fprintf (asmFile, "%s", iComments2);
1771 fprintf (asmFile, "; external stack \n");
1772 fprintf (asmFile, "%s", iComments2);
1773 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1774 "__start__xstack:\n\t.ds\t1\n\n");
1777 /* copy external ram data */
1780 fprintf (asmFile, "%s", iComments2);
1781 fprintf (asmFile, "; external ram data\n");
1782 fprintf (asmFile, "%s", iComments2);
1783 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1786 /* create the absolute xdata segment */
1787 if (mcs51_like || TARGET_IS_HC08)
1789 fprintf (asmFile, "%s", iComments2);
1790 fprintf (asmFile, "; absolute external ram data\n");
1791 fprintf (asmFile, "%s", iComments2);
1792 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1795 /* copy external initialized ram data */
1796 fprintf (asmFile, "%s", iComments2);
1797 fprintf (asmFile, "; external initialized ram data\n");
1798 fprintf (asmFile, "%s", iComments2);
1799 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1801 /* If the port wants to generate any extra areas, let it do so. */
1802 if (port->extraAreas.genExtraAreaDeclaration)
1804 port->extraAreas.genExtraAreaDeclaration(asmFile,
1805 mainf && IFFUNC_HASBODY(mainf->type));
1808 /* copy the interrupt vector table */
1809 if (mainf && IFFUNC_HASBODY (mainf->type))
1811 fprintf (asmFile, "%s", iComments2);
1812 fprintf (asmFile, "; interrupt vector \n");
1813 fprintf (asmFile, "%s", iComments2);
1814 dbuf_write_and_destroy (&vBuf, asmFile);
1817 /* copy global & static initialisations */
1818 fprintf (asmFile, "%s", iComments2);
1819 fprintf (asmFile, "; global & static initialisations\n");
1820 fprintf (asmFile, "%s", iComments2);
1822 /* Everywhere we generate a reference to the static_name area,
1823 * (which is currently only here), we immediately follow it with a
1824 * definition of the post_static_name area. This guarantees that
1825 * the post_static_name area will immediately follow the static_name
1828 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1829 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1830 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1831 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1833 if (mainf && IFFUNC_HASBODY (mainf->type))
1835 if (port->genInitStartup)
1837 port->genInitStartup (asmFile);
1841 assert (mcs51_like);
1842 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1843 /* if external stack is specified then the
1844 higher order byte of the xdatalocation is
1845 going into P2 and the lower order going into
1847 if (options.useXstack)
1849 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1850 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1851 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1852 (unsigned int) options.xdata_loc & 0xff);
1855 // This should probably be a port option, but I'm being lazy.
1856 // on the 400, the firmware boot loader gives us a valid stack
1857 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1858 if (!TARGET_IS_DS400)
1860 /* initialise the stack pointer. JCF: aslink takes care of the location */
1861 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1864 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1865 fprintf (asmFile, "\tmov\ta,dpl\n");
1866 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1867 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1868 fprintf (asmFile, "__sdcc_init_data:\n");
1870 // if the port can copy the XINIT segment to XISEG
1873 port->genXINIT (asmFile);
1877 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1879 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1881 /* This code is generated in the post-static area.
1882 * This area is guaranteed to follow the static area
1883 * by the ugly shucking and jiving about 20 lines ago.
1885 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1886 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1892 "%s", iComments2, iComments2);
1893 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1894 dbuf_write_and_destroy (&home->oBuf, asmFile);
1896 if (mainf && IFFUNC_HASBODY (mainf->type))
1898 /* entry point @ start of HOME */
1899 fprintf (asmFile, "__sdcc_program_startup:\n");
1901 /* put in jump or call to main */
1902 if (options.mainreturn)
1904 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1905 fprintf (asmFile, ";\treturn from main will return to caller\n");
1909 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1910 fprintf (asmFile, ";\treturn from main will lock up\n");
1911 fprintf (asmFile, "\tsjmp .\n");
1914 /* copy over code */
1915 fprintf (asmFile, "%s", iComments2);
1916 fprintf (asmFile, "; code\n");
1917 fprintf (asmFile, "%s", iComments2);
1918 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1919 dbuf_write_and_destroy (&code->oBuf, asmFile);
1921 if (port->genAssemblerEnd)
1923 port->genAssemblerEnd (asmFile);