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_PDATA)
374 DCL_TYPE (val->type) = PPOINTER;
375 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
376 DCL_TYPE (val->type) = FPOINTER;
377 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
378 DCL_TYPE (val->type) = PPOINTER;
379 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
380 DCL_TYPE (val->type) = IPOINTER;
381 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
382 DCL_TYPE (val->type) = EEPPOINTER;
384 DCL_TYPE (val->type) = POINTER;
385 val->type->next = expr->left->ftype;
386 val->etype = getSpec (val->type);
390 /* if address of indexed array */
391 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
392 return valForArray (expr->left);
394 /* if address of structure element then
396 if (IS_AST_OP (expr->left) &&
397 expr->left->opval.op == '.') {
398 return valForStructElem (expr->left->left,
403 (&some_struct)->element */
404 if (IS_AST_OP (expr->left) &&
405 expr->left->opval.op == PTR_OP &&
406 IS_ADDRESS_OF_OP (expr->left->left)) {
407 return valForStructElem (expr->left->left->left,
411 /* case 3. (((char *) &a) +/- constant) */
412 if (IS_AST_OP (expr) &&
413 (expr->opval.op == '+' || expr->opval.op == '-') &&
414 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
415 IS_AST_OP (expr->left->right) &&
416 expr->left->right->opval.op == '&' &&
417 IS_AST_LIT_VALUE (expr->right)) {
419 return valForCastAggr (expr->left->right->left,
420 expr->left->left->opval.lnk,
421 expr->right, expr->opval.op);
424 /* case 4. (char *)(array type) */
425 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
426 IS_ARRAY(expr->right->ftype)) {
428 val = copyValue (AST_VALUE (expr->right));
429 val->type = newLink (DECLARATOR);
430 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
431 DCL_TYPE (val->type) = CPOINTER;
432 DCL_PTR_CONST (val->type) = port->mem.code_ro;
434 else if (SPEC_SCLS (expr->right->etype) == S_PDATA)
435 DCL_TYPE (val->type) = PPOINTER;
436 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
437 DCL_TYPE (val->type) = FPOINTER;
438 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
439 DCL_TYPE (val->type) = PPOINTER;
440 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
441 DCL_TYPE (val->type) = IPOINTER;
442 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
443 DCL_TYPE (val->type) = EEPPOINTER;
445 DCL_TYPE (val->type) = POINTER;
446 val->type->next = expr->right->ftype->next;
447 val->etype = getSpec (val->type);
452 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
454 werror (E_INCOMPAT_PTYPES);
459 /*-----------------------------------------------------------------*/
460 /* printChar - formats and prints a characater string with DB */
461 /*-----------------------------------------------------------------*/
463 printChar (struct dbuf_s * oBuf, char *s, int plen)
471 while (len && pplen < plen)
474 while (i && pplen < plen)
476 if (*s < ' ' || *s == '\"' || *s=='\\')
480 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
481 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
496 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
507 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
512 /*-----------------------------------------------------------------*/
513 /* return the generic pointer high byte for a given pointer type. */
514 /*-----------------------------------------------------------------*/
516 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
524 werror (E_CANNOT_USE_GENERIC_POINTER,
525 iname ? iname : "<null>",
526 oname ? oname : "<null>");
533 return GPTYPE_XSTACK;
535 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
543 /*-----------------------------------------------------------------*/
544 /* printPointerType - generates ival for pointer type */
545 /*-----------------------------------------------------------------*/
547 _printPointerType (struct dbuf_s * oBuf, const char *name)
549 if (options.model == MODEL_FLAT24)
551 if (port->little_endian)
552 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
554 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
558 if (port->little_endian)
559 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
561 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
565 /*-----------------------------------------------------------------*/
566 /* printPointerType - generates ival for pointer type */
567 /*-----------------------------------------------------------------*/
569 printPointerType (struct dbuf_s * oBuf, const char *name)
571 _printPointerType (oBuf, name);
572 dbuf_printf (oBuf, "\n");
575 /*-----------------------------------------------------------------*/
576 /* printGPointerType - generates ival for generic pointer type */
577 /*-----------------------------------------------------------------*/
579 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
580 const unsigned int type)
582 _printPointerType (oBuf, iname);
583 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
586 /*-----------------------------------------------------------------*/
587 /* printIvalType - generates ival for int/char */
588 /*-----------------------------------------------------------------*/
590 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
594 /* if initList is deep */
595 if (ilist && (ilist->type == INIT_DEEP))
596 ilist = ilist->init.deep;
598 if (!(val = list2val (ilist))) {
599 // assuming a warning has been thrown
600 val = constCharVal (0);
603 /* check if the literal value is within bounds */
604 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
605 !options.lessPedantic)
607 werror (W_LIT_OVERFLOW);
610 if (val->type != type) {
611 val = valCastLiteral(type, floatFromVal(val));
614 switch (getSize (type)) {
617 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
619 dbuf_tprintf (oBuf, "\t!dbs\n",
620 aopLiteral (val, 0));
624 if (port->use_dw_for_init)
625 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
626 else if (port->little_endian)
627 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
629 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
633 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
634 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
636 else if (port->little_endian) {
637 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
638 aopLiteral (val, 0), aopLiteral (val, 1),
639 aopLiteral (val, 2), aopLiteral (val, 3));
642 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
643 aopLiteral (val, 3), aopLiteral (val, 2),
644 aopLiteral (val, 1), aopLiteral (val, 0));
650 /*-----------------------------------------------------------------*/
651 /* printIvalBitFields - generate initializer for bitfields */
652 /*-----------------------------------------------------------------*/
654 printIvalBitFields (symbol **sym, initList **ilist, struct dbuf_s * oBuf)
657 initList *lilist = *ilist;
658 unsigned long ival = 0;
664 if (0 == SPEC_BLEN (lsym->etype))
666 /* bit-field structure member with a width of 0 */
670 else if (!SPEC_BUNNAMED (lsym->etype))
672 /* not an unnamed bit-field structure member */
673 value *val = list2val (lilist);
674 int bit_length = SPEC_BLEN (lsym->etype);
679 size += (bit_length + 7) / 8;
682 size = (bit_length + 7) / 8;
684 /* check if the literal value is within bounds */
686 checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
687 !options.lessPedantic)
689 werror (W_LIT_OVERFLOW);
692 ival |= (ulFromVal (val) & ((1ul << bit_length) - 1ul)) << SPEC_BSTR (lsym->etype);
693 lilist = lilist ? lilist->next : NULL;
701 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
705 dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
709 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
710 (ival >> 16) & 0xffff, (ival & 0xffff));
717 /*-----------------------------------------------------------------*/
718 /* printIvalStruct - generates initial value for structures */
719 /*-----------------------------------------------------------------*/
721 printIvalStruct (symbol * sym, sym_link * type,
722 initList * ilist, struct dbuf_s * oBuf)
725 initList *iloop = NULL;
727 sflds = SPEC_STRUCT (type)->fields;
731 if (ilist->type != INIT_DEEP)
733 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
737 iloop = ilist->init.deep;
740 if (SPEC_STRUCT (type)->type == UNION)
742 printIval (sym, sflds->type, iloop, oBuf, 1);
743 iloop = iloop ? iloop->next : NULL;
749 if (IS_BITFIELD (sflds->type))
750 printIvalBitFields(&sflds, &iloop, oBuf);
753 printIval (sym, sflds->type, iloop, oBuf, 1);
755 iloop = iloop ? iloop->next : NULL;
761 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
764 /*-----------------------------------------------------------------*/
765 /* printIvalChar - generates initital value for character array */
766 /*-----------------------------------------------------------------*/
768 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
771 unsigned int size = DCL_ELEM (type);
775 val = list2val (ilist);
776 /* if the value is a character string */
777 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
781 /* we have not been given a size, but now we know it */
782 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
783 /* but first check, if it's a flexible array */
784 if (sym && IS_STRUCT (sym->type))
785 sym->flexArrayLength = size;
787 DCL_ELEM (type) = size;
790 if (check && DCL_ELEM (val->type) > size)
791 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
793 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
801 printChar (oBuf, s, strlen (s) + 1);
805 /*-----------------------------------------------------------------*/
806 /* printIvalArray - generates code for array initialization */
807 /*-----------------------------------------------------------------*/
809 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
810 struct dbuf_s * oBuf, bool check)
814 unsigned int size = 0;
817 /* take care of the special case */
818 /* array of characters can be init */
820 if (IS_CHAR (type->next)) {
821 val = list2val(ilist);
823 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
826 if (!IS_LITERAL(val->etype)) {
827 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
830 if (printIvalChar (sym, type,
831 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
832 oBuf, SPEC_CVAL (sym->etype).v_char, check))
835 /* not the special case */
836 if (ilist->type != INIT_DEEP) {
837 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
841 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
842 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
843 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
846 printIval (sym, type->next, iloop, oBuf, TRUE);
850 if (DCL_ELEM(type)) {
851 // pad with zeros if needed
852 if (size<DCL_ELEM(type)) {
853 size = (DCL_ELEM(type) - size) * getSize(type->next);
855 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
859 /* we have not been given a size, but now we know it */
860 /* but first check, if it's a flexible array */
861 if (IS_STRUCT (sym->type))
862 sym->flexArrayLength = size * getSize (type->next);
864 DCL_ELEM (type) = size;
870 /*-----------------------------------------------------------------*/
871 /* printIvalFuncPtr - generate initial value for function pointers */
872 /*-----------------------------------------------------------------*/
874 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
880 val = list2val (ilist);
882 val = valCastLiteral(type, 0.0);
885 // an error has been thrown already
886 val = constCharVal (0);
889 if (IS_LITERAL(val->etype)) {
890 if (compareType(type, val->etype) == 0) {
891 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
892 printFromToType (val->type, type);
894 printIvalCharPtr (NULL, type, val, oBuf);
898 /* check the types */
899 if ((dLvl = compareType (val->type, type->next)) <= 0)
901 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
905 /* now generate the name */
908 if (port->use_dw_for_init)
910 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
914 printPointerType (oBuf, val->name);
917 else if (port->use_dw_for_init)
919 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
923 printPointerType (oBuf, val->sym->rname);
929 /*-----------------------------------------------------------------*/
930 /* printIvalCharPtr - generates initial values for character pointers */
931 /*-----------------------------------------------------------------*/
933 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
937 /* PENDING: this is _very_ mcs51 specific, including a magic
939 It's also endian specific.
941 size = getSize (type);
943 if (val->name && strlen (val->name))
945 if (size == 1) /* This appears to be Z80 specific?? */
948 "\t!dbs\n", val->name);
950 else if (size == FPTRSIZE)
952 if (port->use_dw_for_init)
954 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
958 printPointerType (oBuf, val->name);
961 else if (size == GPTRSIZE)
964 if (IS_PTR (val->type)) {
965 type = DCL_TYPE (val->type);
967 type = PTR_TYPE (SPEC_OCLS (val->etype));
969 if (val->sym && val->sym->isstrlit) {
970 // this is a literal string
973 printGPointerType (oBuf, val->name, sym->name, type);
977 fprintf (stderr, "*** internal error: unknown size in "
978 "printIvalCharPtr.\n");
983 // these are literals assigned to pointers
987 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
990 if (port->use_dw_for_init)
991 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
992 else if (port->little_endian)
993 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
994 aopLiteral (val, 0), aopLiteral (val, 1));
996 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
997 aopLiteral (val, 1), aopLiteral (val, 0));
1000 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1001 // non-zero mcs51 generic pointer
1002 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1004 if (port->little_endian) {
1005 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1006 aopLiteral (val, 0),
1007 aopLiteral (val, 1),
1008 aopLiteral (val, 2));
1010 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1011 aopLiteral (val, 2),
1012 aopLiteral (val, 1),
1013 aopLiteral (val, 0));
1017 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1018 // non-zero ds390 generic pointer
1019 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1021 if (port->little_endian) {
1022 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1023 aopLiteral (val, 0),
1024 aopLiteral (val, 1),
1025 aopLiteral (val, 2),
1026 aopLiteral (val, 3));
1028 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1029 aopLiteral (val, 3),
1030 aopLiteral (val, 2),
1031 aopLiteral (val, 1),
1032 aopLiteral (val, 0));
1040 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1041 addSet (&statsg->syms, val->sym);
1047 /*-----------------------------------------------------------------*/
1048 /* printIvalPtr - generates initial value for pointers */
1049 /*-----------------------------------------------------------------*/
1051 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1057 if (ilist && (ilist->type == INIT_DEEP))
1058 ilist = ilist->init.deep;
1060 /* function pointer */
1061 if (IS_FUNC (type->next))
1063 printIvalFuncPtr (type, ilist, oBuf);
1067 if (!(val = initPointer (ilist, type)))
1070 /* if character pointer */
1071 if (IS_CHAR (type->next))
1072 if (printIvalCharPtr (sym, type, val, oBuf))
1075 /* check the type */
1076 if (compareType (type, val->type) == 0) {
1077 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1078 printFromToType (val->type, type);
1081 /* if val is literal */
1082 if (IS_LITERAL (val->etype))
1084 switch (getSize (type))
1087 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1090 if (port->use_dw_for_init)
1091 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1092 else if (port->little_endian)
1093 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1095 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1097 case 3: // how about '390??
1098 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1099 if (port->little_endian)
1101 dbuf_printf (oBuf, "\t.byte %s,%s",
1102 aopLiteral (val, 0), aopLiteral (val, 1));
1106 dbuf_printf (oBuf, "\t.byte %s,%s",
1107 aopLiteral (val, 1), aopLiteral (val, 0));
1109 if (IS_GENPTR (val->type))
1110 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1111 else if (IS_PTR (val->type))
1112 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1114 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1120 size = getSize (type);
1122 if (size == 1) /* Z80 specific?? */
1124 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1126 else if (size == FPTRSIZE)
1128 if (port->use_dw_for_init) {
1129 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1131 printPointerType (oBuf, val->name);
1134 else if (size == GPTRSIZE)
1136 printGPointerType (oBuf, val->name, sym->name,
1137 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1138 PTR_TYPE (SPEC_OCLS (val->etype))));
1143 /*-----------------------------------------------------------------*/
1144 /* printIval - generates code for initial value */
1145 /*-----------------------------------------------------------------*/
1147 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1151 /* if structure then */
1152 if (IS_STRUCT (type))
1154 printIvalStruct (sym, type, ilist, oBuf);
1158 /* if this is an array */
1159 if (IS_ARRAY (type))
1161 printIvalArray (sym, type, ilist, oBuf, check);
1167 // not an aggregate, ilist must be a node
1168 if (ilist->type!=INIT_NODE) {
1169 // or a 1-element list
1170 if (ilist->init.deep->next) {
1171 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1174 ilist=ilist->init.deep;
1178 // and the type must match
1179 itype=ilist->init.node->ftype;
1181 if (compareType(type, itype)==0) {
1182 // special case for literal strings
1183 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1184 // which are really code pointers
1185 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1188 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1189 printFromToType(itype, type);
1194 /* if this is a pointer */
1197 printIvalPtr (sym, type, ilist, oBuf);
1201 /* if type is SPECIFIER */
1204 printIvalType (sym, type, ilist, oBuf);
1209 /*-----------------------------------------------------------------*/
1210 /* emitStaticSeg - emitcode for the static segment */
1211 /*-----------------------------------------------------------------*/
1213 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1217 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1219 /* for all variables in this segment do */
1220 for (sym = setFirstItem (map->syms); sym;
1221 sym = setNextItem (map->syms))
1224 /* if it is "extern" then do nothing */
1225 if (IS_EXTERN (sym->etype))
1228 /* if it is not static add it to the public table */
1229 if (!IS_STATIC (sym->etype))
1231 addSetHead (&publics, sym);
1234 /* print extra debug info if required */
1239 if (IS_STATIC (sym->etype))
1240 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1242 dbuf_printf (oBuf, "G$"); /* scope is global */
1246 /* symbol is local */
1247 dbuf_printf (oBuf, "L%s$",
1248 (sym->localof ? sym->localof->name : "-null-"));
1250 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1253 /* if it has an absolute address and no initializer */
1254 if (SPEC_ABSA (sym->etype) && !sym->ival)
1257 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1259 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1261 SPEC_ADDR (sym->etype));
1266 dbuf_printf (oBuf, " == .\n");
1268 /* if it has an initial value */
1271 if (SPEC_ABSA (sym->etype))
1273 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1275 dbuf_printf (oBuf, "%s:\n", sym->rname);
1277 resolveIvalSym (sym->ival, sym->type);
1278 printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1280 /* if sym is a simple string and sym->ival is a string,
1281 WE don't need it anymore */
1282 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1283 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1284 list2val(sym->ival)->sym->isstrlit) {
1285 freeStringSymbol(list2val(sym->ival)->sym);
1289 /* allocate space */
1290 int size = getSize (sym->type);
1293 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1295 dbuf_printf (oBuf, "%s:\n", sym->rname);
1296 /* special case for character strings */
1297 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1298 SPEC_CVAL (sym->etype).v_char)
1300 SPEC_CVAL (sym->etype).v_char,
1303 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1309 /*-----------------------------------------------------------------*/
1310 /* emitMaps - emits the code for the data portion the code */
1311 /*-----------------------------------------------------------------*/
1315 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1316 /* ports but let's be conservative - EEP */
1319 /* no special considerations for the following
1320 data, idata & bit & xdata */
1321 emitRegularMap (data, TRUE, TRUE);
1322 emitRegularMap (idata, TRUE, TRUE);
1323 emitRegularMap (d_abs, TRUE, TRUE);
1324 emitRegularMap (i_abs, TRUE, TRUE);
1325 emitRegularMap (bit, TRUE, TRUE);
1326 emitRegularMap (pdata, TRUE, TRUE);
1327 emitRegularMap (xdata, TRUE, TRUE);
1328 emitRegularMap (x_abs, TRUE, TRUE);
1329 if (port->genXINIT) {
1330 emitRegularMap (xidata, TRUE, TRUE);
1332 emitRegularMap (sfr, publicsfr, FALSE);
1333 emitRegularMap (sfrbit, publicsfr, FALSE);
1334 emitRegularMap (home, TRUE, FALSE);
1335 emitRegularMap (code, TRUE, FALSE);
1337 if (options.const_seg) {
1338 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1340 emitStaticSeg (statsg, &code->oBuf);
1341 if (port->genXINIT) {
1342 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1343 emitStaticSeg (xinit, &code->oBuf);
1345 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1346 emitStaticSeg (c_abs, &code->oBuf);
1350 /*-----------------------------------------------------------------*/
1351 /* flushStatics - flush all currently defined statics out to file */
1352 /* and delete. Temporary function */
1353 /*-----------------------------------------------------------------*/
1357 emitStaticSeg (statsg, codeOutBuf);
1358 statsg->syms = NULL;
1361 /*-----------------------------------------------------------------*/
1362 /* createInterruptVect - creates the interrupt vector */
1363 /*-----------------------------------------------------------------*/
1365 createInterruptVect (struct dbuf_s *vBuf)
1367 mainf = newSymbol ("main", 0);
1370 /* only if the main function exists */
1371 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1373 if (!options.cc_only && !noAssemble && !options.c1mode)
1378 /* if the main is only a prototype ie. no body then do nothing */
1379 if (!IFFUNC_HASBODY(mainf->type))
1381 /* if ! compile only then main function should be present */
1382 if (!options.cc_only && !noAssemble)
1387 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1388 dbuf_printf (vBuf, "__interrupt_vect:\n");
1391 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1393 /* There's no such thing as a "generic" interrupt table header. */
1400 ";--------------------------------------------------------\n"
1401 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1405 ";--------------------------------------------------------\n"};
1408 /*-----------------------------------------------------------------*/
1409 /* initialComments - puts in some initial comments */
1410 /*-----------------------------------------------------------------*/
1412 initialComments (FILE * afile)
1416 fprintf (afile, "%s", iComments1);
1417 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1418 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1419 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1420 fprintf (afile, "%s", iComments2);
1423 /*-----------------------------------------------------------------*/
1424 /* printPublics - generates .global for publics */
1425 /*-----------------------------------------------------------------*/
1427 printPublics (FILE * afile)
1431 fprintf (afile, "%s", iComments2);
1432 fprintf (afile, "; Public variables in this module\n");
1433 fprintf (afile, "%s", iComments2);
1435 for (sym = setFirstItem (publics); sym;
1436 sym = setNextItem (publics))
1437 tfprintf (afile, "\t!global\n", sym->rname);
1440 /*-----------------------------------------------------------------*/
1441 /* printExterns - generates .global for externs */
1442 /*-----------------------------------------------------------------*/
1444 printExterns (FILE * afile)
1448 fprintf (afile, "%s", iComments2);
1449 fprintf (afile, "; Externals used\n");
1450 fprintf (afile, "%s", iComments2);
1452 for (sym = setFirstItem (externs); sym;
1453 sym = setNextItem (externs))
1454 tfprintf (afile, "\t!extern\n", sym->rname);
1457 /*-----------------------------------------------------------------*/
1458 /* emitOverlay - will emit code for the overlay stuff */
1459 /*-----------------------------------------------------------------*/
1461 emitOverlay (struct dbuf_s * aBuf)
1465 if (!elementsInSet (ovrSetSets))
1466 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1468 /* for each of the sets in the overlay segment do */
1469 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1470 ovrset = setNextItem (ovrSetSets))
1475 if (elementsInSet (ovrset))
1477 /* output the area informtion */
1478 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1481 for (sym = setFirstItem (ovrset); sym;
1482 sym = setNextItem (ovrset))
1484 /* if extern then it is in the publics table: do nothing */
1485 if (IS_EXTERN (sym->etype))
1488 /* if allocation required check is needed
1489 then check if the symbol really requires
1490 allocation only for local variables */
1491 if (!IS_AGGREGATE (sym->type) &&
1492 !(sym->_isparm && !IS_REGPARM (sym->etype))
1493 && !sym->allocreq && sym->level)
1496 /* if global variable & not static or extern
1497 and addPublics allowed then add it to the public set */
1498 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1499 && !IS_STATIC (sym->etype))
1501 addSetHead (&publics, sym);
1504 /* if extern then do nothing or is a function
1506 if (IS_FUNC (sym->type))
1509 /* print extra debug info if required */
1514 if (IS_STATIC (sym->etype))
1515 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1517 dbuf_printf (aBuf, "G$"); /* scope is global */
1520 /* symbol is local */
1521 dbuf_printf (aBuf, "L%s$",
1522 (sym->localof ? sym->localof->name : "-null-"));
1523 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1526 /* if is has an absolute address then generate
1527 an equate for this no need to allocate space */
1528 if (SPEC_ABSA (sym->etype))
1532 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1534 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1536 SPEC_ADDR (sym->etype));
1540 int size = getSize(sym->type);
1543 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1546 dbuf_printf (aBuf, "==.\n");
1548 /* allocate space */
1549 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1550 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1557 /*-----------------------------------------------------------------*/
1558 /* glue - the final glue that hold the whole thing together */
1559 /*-----------------------------------------------------------------*/
1564 struct dbuf_s ovrBuf;
1568 dbuf_init (&vBuf, 4096);
1569 dbuf_init (&ovrBuf, 4096);
1571 mcs51_like = (port->general.glue_up_main &&
1572 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1574 /* print the global struct definitions */
1578 /* PENDING: this isn't the best place but it will do */
1579 if (port->general.glue_up_main)
1581 /* create the interrupt vector table */
1582 createInterruptVect (&vBuf);
1585 /* emit code for the all the variables declared */
1587 /* do the overlay segments */
1588 emitOverlay (&ovrBuf);
1590 outputDebugSymbols ();
1592 /* now put it all together into the assembler file */
1593 /* create the assembler file name */
1595 /* -o option overrides default name? */
1596 if ((noAssemble || options.c1mode) && fullDstFileName)
1598 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1602 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1603 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1606 if (!(asmFile = fopen (scratchFileName, "w")))
1608 werror (E_FILE_OPEN_ERR, scratchFileName);
1609 exit (EXIT_FAILURE);
1612 /* initial comments */
1613 initialComments (asmFile);
1615 /* print module name */
1616 tfprintf (asmFile, "\t!module\n", moduleName);
1619 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1621 switch(options.model)
1623 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1624 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1625 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1626 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1627 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1628 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1631 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1632 if(options.useXstack) fprintf (asmFile, " --xstack");
1633 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1634 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1635 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1636 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1637 fprintf (asmFile, "\n");
1639 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1641 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1644 tfprintf (asmFile, "\t!fileprelude\n");
1646 /* Let the port generate any global directives, etc. */
1647 if (port->genAssemblerPreamble)
1649 port->genAssemblerPreamble (asmFile);
1652 /* print the global variables in this module */
1653 printPublics (asmFile);
1654 if (port->assembler.externGlobal)
1655 printExterns (asmFile);
1658 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1660 /* copy the sfr segment */
1661 fprintf (asmFile, "%s", iComments2);
1662 fprintf (asmFile, "; special function registers\n");
1663 fprintf (asmFile, "%s", iComments2);
1664 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1669 /* copy the sbit segment */
1670 fprintf (asmFile, "%s", iComments2);
1671 fprintf (asmFile, "; special function bits\n");
1672 fprintf (asmFile, "%s", iComments2);
1673 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1675 /*JCF: Create the areas for the register banks*/
1676 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1678 fprintf (asmFile, "%s", iComments2);
1679 fprintf (asmFile, "; overlayable register banks\n");
1680 fprintf (asmFile, "%s", iComments2);
1682 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1683 if (RegBankUsed[1] || options.parms_in_bank1)
1684 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1686 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1688 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1692 fprintf (asmFile, "%s", iComments2);
1693 fprintf (asmFile, "; overlayable bit register bank\n");
1694 fprintf (asmFile, "%s", iComments2);
1695 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1696 fprintf (asmFile, "bits:\n\t.ds 1\n");
1697 fprintf (asmFile, "\tb0 = bits[0]\n");
1698 fprintf (asmFile, "\tb1 = bits[1]\n");
1699 fprintf (asmFile, "\tb2 = bits[2]\n");
1700 fprintf (asmFile, "\tb3 = bits[3]\n");
1701 fprintf (asmFile, "\tb4 = bits[4]\n");
1702 fprintf (asmFile, "\tb5 = bits[5]\n");
1703 fprintf (asmFile, "\tb6 = bits[6]\n");
1704 fprintf (asmFile, "\tb7 = bits[7]\n");
1708 /* copy the data segment */
1709 fprintf (asmFile, "%s", iComments2);
1710 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1711 fprintf (asmFile, "%s", iComments2);
1712 dbuf_write_and_destroy (&data->oBuf, asmFile);
1715 /* create the overlay segments */
1718 fprintf (asmFile, "%s", iComments2);
1719 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1720 fprintf (asmFile, "%s", iComments2);
1721 dbuf_write_and_destroy (&ovrBuf, asmFile);
1724 /* create the stack segment MOF */
1725 if (mainf && IFFUNC_HASBODY (mainf->type))
1727 fprintf (asmFile, "%s", iComments2);
1728 fprintf (asmFile, "; Stack segment in internal ram \n");
1729 fprintf (asmFile, "%s", iComments2);
1730 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1731 "__start__stack:\n\t.ds\t1\n\n");
1734 /* create the idata segment */
1735 if ((idata) && (mcs51_like))
1737 fprintf (asmFile, "%s", iComments2);
1738 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1739 fprintf (asmFile, "%s", iComments2);
1740 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1743 /* create the absolute idata/data segment */
1744 if ((i_abs) && (mcs51_like))
1746 fprintf (asmFile, "%s", iComments2);
1747 fprintf (asmFile, "; absolute internal ram data\n");
1748 fprintf (asmFile, "%s", iComments2);
1749 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1750 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1753 /* copy the bit segment */
1756 fprintf (asmFile, "%s", iComments2);
1757 fprintf (asmFile, "; bit data\n");
1758 fprintf (asmFile, "%s", iComments2);
1759 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1762 /* copy paged external ram data */
1765 fprintf (asmFile, "%s", iComments2);
1766 fprintf (asmFile, "; paged external ram data\n");
1767 fprintf (asmFile, "%s", iComments2);
1768 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1771 /* if external stack then reserve space for it */
1772 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1774 fprintf (asmFile, "%s", iComments2);
1775 fprintf (asmFile, "; external stack \n");
1776 fprintf (asmFile, "%s", iComments2);
1777 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1778 "__start__xstack:\n\t.ds\t1\n\n");
1781 /* copy external ram data */
1784 fprintf (asmFile, "%s", iComments2);
1785 fprintf (asmFile, "; external ram data\n");
1786 fprintf (asmFile, "%s", iComments2);
1787 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1790 /* create the absolute xdata segment */
1791 if (mcs51_like || TARGET_IS_HC08)
1793 fprintf (asmFile, "%s", iComments2);
1794 fprintf (asmFile, "; absolute external ram data\n");
1795 fprintf (asmFile, "%s", iComments2);
1796 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1799 /* copy external initialized ram data */
1800 fprintf (asmFile, "%s", iComments2);
1801 fprintf (asmFile, "; external initialized ram data\n");
1802 fprintf (asmFile, "%s", iComments2);
1803 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1805 /* If the port wants to generate any extra areas, let it do so. */
1806 if (port->extraAreas.genExtraAreaDeclaration)
1808 port->extraAreas.genExtraAreaDeclaration(asmFile,
1809 mainf && IFFUNC_HASBODY(mainf->type));
1812 /* copy the interrupt vector table */
1813 if (mainf && IFFUNC_HASBODY (mainf->type))
1815 fprintf (asmFile, "%s", iComments2);
1816 fprintf (asmFile, "; interrupt vector \n");
1817 fprintf (asmFile, "%s", iComments2);
1818 dbuf_write_and_destroy (&vBuf, asmFile);
1821 /* copy global & static initialisations */
1822 fprintf (asmFile, "%s", iComments2);
1823 fprintf (asmFile, "; global & static initialisations\n");
1824 fprintf (asmFile, "%s", iComments2);
1826 /* Everywhere we generate a reference to the static_name area,
1827 * (which is currently only here), we immediately follow it with a
1828 * definition of the post_static_name area. This guarantees that
1829 * the post_static_name area will immediately follow the static_name
1832 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1833 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1834 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1835 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1837 if (mainf && IFFUNC_HASBODY (mainf->type))
1839 if (port->genInitStartup)
1841 port->genInitStartup (asmFile);
1845 assert (mcs51_like);
1846 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1847 /* if external stack is specified then the
1848 higher order byte of the xdatalocation is
1849 going into P2 and the lower order going into
1851 if (options.useXstack)
1853 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1854 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1855 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1856 (unsigned int) options.xdata_loc & 0xff);
1859 // This should probably be a port option, but I'm being lazy.
1860 // on the 400, the firmware boot loader gives us a valid stack
1861 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1862 if (!TARGET_IS_DS400)
1864 /* initialise the stack pointer. JCF: aslink takes care of the location */
1865 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1868 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1869 fprintf (asmFile, "\tmov\ta,dpl\n");
1870 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1871 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1872 fprintf (asmFile, "__sdcc_init_data:\n");
1874 // if the port can copy the XINIT segment to XISEG
1877 port->genXINIT (asmFile);
1881 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1883 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1885 /* This code is generated in the post-static area.
1886 * This area is guaranteed to follow the static area
1887 * by the ugly shucking and jiving about 20 lines ago.
1889 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1890 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1896 "%s", iComments2, iComments2);
1897 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1898 dbuf_write_and_destroy (&home->oBuf, asmFile);
1900 if (mainf && IFFUNC_HASBODY (mainf->type))
1902 /* entry point @ start of HOME */
1903 fprintf (asmFile, "__sdcc_program_startup:\n");
1905 /* put in jump or call to main */
1906 if (options.mainreturn)
1908 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1909 fprintf (asmFile, ";\treturn from main will return to caller\n");
1913 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1914 fprintf (asmFile, ";\treturn from main will lock up\n");
1915 fprintf (asmFile, "\tsjmp .\n");
1918 /* copy over code */
1919 fprintf (asmFile, "%s", iComments2);
1920 fprintf (asmFile, "; code\n");
1921 fprintf (asmFile, "%s", iComments2);
1922 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1923 dbuf_write_and_destroy (&code->oBuf, asmFile);
1925 if (port->genAssemblerEnd)
1927 port->genAssemblerEnd (asmFile);