1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 #include "dbuf_string.h"
38 symbol *interrupts[INTNO_MAX+1];
40 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Variables that are declared as extern */
44 unsigned maxInterrupts = 0;
47 set *pipeSet = NULL; /* set of pipes */
48 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
49 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
51 /*-----------------------------------------------------------------*/
52 /* closePipes - closes all pipes created by the compiler */
53 /*-----------------------------------------------------------------*/
54 DEFSETFUNC (closePipes)
67 /*-----------------------------------------------------------------*/
68 /* closeTmpFiles - closes all tmp files created by the compiler */
69 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
70 /*-----------------------------------------------------------------*/
71 DEFSETFUNC (closeTmpFiles)
84 /*-----------------------------------------------------------------*/
85 /* rmTmpFiles - unlinks all tmp files created by the compiler */
86 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
87 /*-----------------------------------------------------------------*/
88 DEFSETFUNC (rmTmpFiles)
103 aopLiteralLong (value * val, int offset, int size)
112 // assuming we have been warned before
113 val = constCharVal (0);
116 /* if it is a float then it gets tricky */
117 /* otherwise it is fairly simple */
118 if (!IS_FLOAT (val->type)) {
119 unsigned long v = ulFromVal (val);
124 tsprintf (buffer, sizeof(buffer),
125 "!immedbyte", (unsigned int) v & 0xff);
128 tsprintf (buffer, sizeof(buffer),
129 "!immedword", (unsigned int) v & 0xffff);
132 /* Hmm. Too big for now. */
135 return Safe_strdup (buffer);
138 /* PENDING: For now size must be 1 */
141 /* it is type float */
142 fl.f = (float) floatFromVal (val);
143 #ifdef WORDS_BIGENDIAN
144 tsprintf (buffer, sizeof(buffer),
145 "!immedbyte", fl.c[3 - offset]);
147 tsprintf (buffer, sizeof(buffer),
148 "!immedbyte", fl.c[offset]);
150 return Safe_strdup (buffer);
153 /*-----------------------------------------------------------------*/
154 /* aopLiteral - string from a literal value */
155 /*-----------------------------------------------------------------*/
157 aopLiteral (value * val, int offset)
159 return aopLiteralLong (val, offset, 1);
162 /*-----------------------------------------------------------------*/
163 /* emitRegularMap - emit code for maps with no special cases */
164 /*-----------------------------------------------------------------*/
166 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
176 /* PENDING: special case here - should remove */
177 if (!strcmp (map->sname, CODE_NAME))
178 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
179 else if (!strcmp (map->sname, DATA_NAME))
180 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
181 else if (!strcmp (map->sname, HOME_NAME))
182 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
184 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
187 for (sym = setFirstItem (map->syms); sym;
188 sym = setNextItem (map->syms))
192 /* if extern then add it into the extern list */
193 if (IS_EXTERN (sym->etype))
195 addSetHead (&externs, sym);
199 /* if allocation required check is needed
200 then check if the symbol really requires
201 allocation only for local variables */
203 if (arFlag && !IS_AGGREGATE (sym->type) &&
204 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
205 !sym->allocreq && sym->level)
208 /* for bitvar locals and parameters */
209 if (!arFlag && !sym->allocreq && sym->level
210 && !SPEC_ABSA (sym->etype)) {
214 /* if global variable & not static or extern
215 and addPublics allowed then add it to the public set */
216 if ((sym->level == 0 ||
217 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
219 !IS_STATIC (sym->etype) &&
220 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
222 addSetHead (&publics, sym);
225 /* if extern then do nothing or is a function
227 if (IS_FUNC (sym->type) && !(sym->isitmp))
230 /* print extra debug info if required */
233 if (!sym->level) /* global */
235 if (IS_STATIC (sym->etype))
236 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
238 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
242 /* symbol is local */
243 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
245 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
248 /* if it has an initial value then do it only if
249 it is a global variable */
250 if (sym->ival && sym->level == 0) {
251 if ((SPEC_OCLS(sym->etype)==xidata) && !SPEC_ABSA (sym->etype)) {
252 /* create a new "XINIT (CODE)" symbol, that will be emitted later
254 newSym=copySymbol (sym);
255 SPEC_OCLS(newSym->etype)=xinit;
256 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
257 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
258 if (IS_SPEC (newSym->type))
259 SPEC_CONST (newSym->type) = 1;
261 DCL_PTR_CONST (newSym->type) = 1;
262 SPEC_STAT(newSym->etype)=1;
263 resolveIvalSym(newSym->ival, newSym->type);
265 // add it to the "XINIT (CODE)" segment
266 addSet(&xinit->syms, newSym);
268 if (!SPEC_ABSA (sym->etype))
270 struct dbuf_s tmpBuf;
272 dbuf_init(&tmpBuf, 4096);
273 // before allocation we must parse the sym->ival tree
274 // but without actually generating initialization code
276 resolveIvalSym (sym->ival, sym->type);
277 printIval (sym, sym->type, sym->ival, &tmpBuf);
279 dbuf_destroy(&tmpBuf);
282 if (IS_AGGREGATE (sym->type)) {
283 ival = initAggregates (sym, sym->ival, NULL);
285 if (getNelements(sym->type, sym->ival)>1) {
286 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
289 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
290 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
292 codeOutBuf = &statsg->oBuf;
295 // set ival's lineno to where the symbol was defined
296 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
297 // check if this is not a constant expression
298 if (!constExprTree(ival)) {
299 werror (E_CONST_EXPECTED, "found expression");
300 // but try to do it anyway
303 if (!astErrors(ival))
304 eBBlockFromiCode (iCodeFromAst (ival));
310 /* if it has an absolute address then generate
311 an equate for this no need to allocate space */
312 if (SPEC_ABSA (sym->etype) && !sym->ival)
316 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
318 if (TARGET_IS_XA51) {
321 } else if (map==bit || map==sfrbit) {
325 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n",
327 SPEC_ADDR (sym->etype));
331 int size = getSize (sym->type) + sym->flexArrayLength;
333 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
337 dbuf_printf (&map->oBuf, "==.\n");
339 if (SPEC_ABSA (sym->etype))
341 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
343 if (IS_STATIC (sym->etype) || sym->level)
344 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
346 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
347 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
353 /*-----------------------------------------------------------------*/
354 /* initPointer - pointer initialization code massaging */
355 /*-----------------------------------------------------------------*/
357 initPointer (initList * ilist, sym_link *toType)
363 return valCastLiteral(toType, 0.0);
366 expr = list2expr (ilist);
371 /* try it the old way first */
372 if ((val = constExprValue (expr, FALSE)))
375 /* ( ptr + constant ) */
376 if (IS_AST_OP (expr) &&
377 (expr->opval.op == '+' || expr->opval.op == '-') &&
378 IS_AST_SYM_VALUE (expr->left) &&
379 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
380 compareType(toType, expr->left->ftype) &&
381 IS_AST_LIT_VALUE (expr->right)) {
382 return valForCastAggr (expr->left, expr->left->ftype,
388 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
389 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
390 if (compareType(toType, expr->left->ftype)!=1) {
391 werror (W_INIT_WRONG);
392 printFromToType(expr->left->ftype, toType);
398 /* no then we have to do these cludgy checks */
399 /* pointers can be initialized with address of
400 a variable or address of an array element */
401 if (IS_AST_OP (expr) && expr->opval.op == '&') {
402 /* address of symbol */
403 if (IS_AST_SYM_VALUE (expr->left)) {
404 val = AST_VALUE (expr->left);
405 val->type = newLink (DECLARATOR);
406 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
407 DCL_TYPE (val->type) = CPOINTER;
408 DCL_PTR_CONST (val->type) = port->mem.code_ro;
410 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
411 DCL_TYPE (val->type) = FPOINTER;
412 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
413 DCL_TYPE (val->type) = PPOINTER;
414 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
415 DCL_TYPE (val->type) = IPOINTER;
416 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
417 DCL_TYPE (val->type) = EEPPOINTER;
419 DCL_TYPE (val->type) = POINTER;
420 val->type->next = expr->left->ftype;
421 val->etype = getSpec (val->type);
425 /* if address of indexed array */
426 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
427 return valForArray (expr->left);
429 /* if address of structure element then
431 if (IS_AST_OP (expr->left) &&
432 expr->left->opval.op == '.') {
433 return valForStructElem (expr->left->left,
438 (&some_struct)->element */
439 if (IS_AST_OP (expr->left) &&
440 expr->left->opval.op == PTR_OP &&
441 IS_ADDRESS_OF_OP (expr->left->left)) {
442 return valForStructElem (expr->left->left->left,
446 /* case 3. (((char *) &a) +/- constant) */
447 if (IS_AST_OP (expr) &&
448 (expr->opval.op == '+' || expr->opval.op == '-') &&
449 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
450 IS_AST_OP (expr->left->right) &&
451 expr->left->right->opval.op == '&' &&
452 IS_AST_LIT_VALUE (expr->right)) {
454 return valForCastAggr (expr->left->right->left,
455 expr->left->left->opval.lnk,
456 expr->right, expr->opval.op);
459 /* case 4. (char *)(array type) */
460 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
461 IS_ARRAY(expr->right->ftype)) {
463 val = copyValue (AST_VALUE (expr->right));
464 val->type = newLink (DECLARATOR);
465 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
466 DCL_TYPE (val->type) = CPOINTER;
467 DCL_PTR_CONST (val->type) = port->mem.code_ro;
469 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
470 DCL_TYPE (val->type) = FPOINTER;
471 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
472 DCL_TYPE (val->type) = PPOINTER;
473 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
474 DCL_TYPE (val->type) = IPOINTER;
475 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
476 DCL_TYPE (val->type) = EEPPOINTER;
478 DCL_TYPE (val->type) = POINTER;
479 val->type->next = expr->right->ftype->next;
480 val->etype = getSpec (val->type);
485 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
487 werror (E_INCOMPAT_PTYPES);
492 /*-----------------------------------------------------------------*/
493 /* printChar - formats and prints a characater string with DB */
494 /*-----------------------------------------------------------------*/
496 printChar (struct dbuf_s * oBuf, char *s, int plen)
504 while (len && pplen < plen)
507 while (i && pplen < plen)
509 if (*s < ' ' || *s == '\"' || *s=='\\')
513 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
514 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
529 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
540 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
545 /*-----------------------------------------------------------------*/
546 /* return the generic pointer high byte for a given pointer type. */
547 /*-----------------------------------------------------------------*/
549 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
557 werror (E_CANNOT_USE_GENERIC_POINTER,
558 iname ? iname : "<null>",
559 oname ? oname : "<null>");
566 return GPTYPE_XSTACK;
568 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
576 /*-----------------------------------------------------------------*/
577 /* printPointerType - generates ival for pointer type */
578 /*-----------------------------------------------------------------*/
580 _printPointerType (struct dbuf_s * oBuf, const char *name)
582 if (options.model == MODEL_FLAT24)
584 if (port->little_endian)
585 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
587 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
591 if (port->little_endian)
592 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
594 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
598 /*-----------------------------------------------------------------*/
599 /* printPointerType - generates ival for pointer type */
600 /*-----------------------------------------------------------------*/
602 printPointerType (struct dbuf_s * oBuf, const char *name)
604 _printPointerType (oBuf, name);
605 dbuf_printf (oBuf, "\n");
608 /*-----------------------------------------------------------------*/
609 /* printGPointerType - generates ival for generic pointer type */
610 /*-----------------------------------------------------------------*/
612 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
613 const unsigned int type)
615 _printPointerType (oBuf, iname);
616 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
619 /*-----------------------------------------------------------------*/
620 /* printIvalType - generates ival for int/char */
621 /*-----------------------------------------------------------------*/
623 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
627 /* if initList is deep */
628 if (ilist && (ilist->type == INIT_DEEP))
629 ilist = ilist->init.deep;
631 if (!(val = list2val (ilist))) {
632 // assuming a warning has been thrown
633 val = constCharVal (0);
636 if (val->type != type) {
637 val = valCastLiteral(type, floatFromVal(val));
640 switch (getSize (type)) {
643 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
645 dbuf_tprintf (oBuf, "\t!dbs\n",
646 aopLiteral (val, 0));
650 if (port->use_dw_for_init)
651 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
652 else if (port->little_endian)
653 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
655 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
659 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
660 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
662 else if (port->little_endian) {
663 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
664 aopLiteral (val, 0), aopLiteral (val, 1),
665 aopLiteral (val, 2), aopLiteral (val, 3));
668 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
669 aopLiteral (val, 3), aopLiteral (val, 2),
670 aopLiteral (val, 1), aopLiteral (val, 0));
676 /*-----------------------------------------------------------------*/
677 /* printIvalBitFields - generate initializer for bitfields */
678 /*-----------------------------------------------------------------*/
679 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
683 initList *lilist = *ilist ;
684 unsigned long ival = 0;
690 val = list2val(lilist);
692 if (SPEC_BLEN(lsym->etype) > 8) {
693 size += ((SPEC_BLEN (lsym->etype) / 8) +
694 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
697 size = ((SPEC_BLEN (lsym->etype) / 8) +
698 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
701 i <<= SPEC_BSTR (lsym->etype);
703 if (! ( lsym->next &&
704 (IS_BITFIELD(lsym->next->type)) &&
705 (SPEC_BSTR(lsym->next->etype)))) break;
707 lilist = lilist->next;
711 dbuf_tprintf (oBuf, "\t!db !constbyte\n",ival);
715 dbuf_tprintf (oBuf, "\t!dw !constword\n",ival);
717 case 4: /* EEP: why is this db and not dw? */
718 dbuf_tprintf (oBuf, "\t!db !constword,!constword\n",
719 (ival >> 8) & 0xffff, (ival & 0xffff));
726 /*-----------------------------------------------------------------*/
727 /* printIvalStruct - generates initial value for structures */
728 /*-----------------------------------------------------------------*/
730 printIvalStruct (symbol * sym, sym_link * type,
731 initList * ilist, struct dbuf_s * oBuf)
734 initList *iloop = NULL;
736 sflds = SPEC_STRUCT (type)->fields;
739 if (ilist->type != INIT_DEEP) {
740 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
744 iloop = ilist->init.deep;
747 if (SPEC_STRUCT (type)->type == UNION) {
748 printIval (sym, sflds->type, iloop, oBuf);
749 iloop = iloop ? iloop->next : NULL;
751 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
752 if (IS_BITFIELD(sflds->type)) {
753 printIvalBitFields(&sflds, &iloop, oBuf);
755 printIval (sym, sflds->type, iloop, oBuf);
760 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
765 /*-----------------------------------------------------------------*/
766 /* printIvalChar - generates initital value for character array */
767 /*-----------------------------------------------------------------*/
769 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
772 unsigned int size = DCL_ELEM (type);
776 val = list2val (ilist);
777 /* if the value is a character string */
778 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
782 /* we have not been given a size, but now we know it */
783 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
784 /* but first check, if it's a flexible array */
785 if (sym && IS_STRUCT (sym->type))
786 sym->flexArrayLength = size;
788 DCL_ELEM (type) = size;
791 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
799 printChar (oBuf, s, strlen (s) + 1);
803 /*-----------------------------------------------------------------*/
804 /* printIvalArray - generates code for array initialization */
805 /*-----------------------------------------------------------------*/
807 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
808 struct dbuf_s * oBuf)
812 unsigned int size = 0;
815 /* take care of the special case */
816 /* array of characters can be init */
818 if (IS_CHAR (type->next)) {
819 val = list2val(ilist);
821 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
824 if (!IS_LITERAL(val->etype)) {
825 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
828 if (printIvalChar (sym, type,
829 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
830 oBuf, SPEC_CVAL (sym->etype).v_char))
833 /* not the special case */
834 if (ilist->type != INIT_DEEP) {
835 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
839 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
840 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
841 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
844 printIval (sym, type->next, iloop, oBuf);
848 if (DCL_ELEM(type)) {
849 // pad with zeros if needed
850 if (size<DCL_ELEM(type)) {
851 size = (DCL_ELEM(type) - size) * getSize(type->next);
853 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
857 /* we have not been given a size, but now we know it */
858 /* but first check, if it's a flexible array */
859 if (IS_STRUCT (sym->type))
860 sym->flexArrayLength = size * getSize (type->next);
862 DCL_ELEM (type) = size;
868 /*-----------------------------------------------------------------*/
869 /* printIvalFuncPtr - generate initial value for function pointers */
870 /*-----------------------------------------------------------------*/
872 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
878 val = list2val (ilist);
880 val = valCastLiteral(type, 0.0);
883 // an error has been thrown already
884 val = constCharVal (0);
887 if (IS_LITERAL(val->etype)) {
888 if (compareType(type, val->etype) == 0) {
889 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
890 printFromToType (val->type, type);
892 printIvalCharPtr (NULL, type, val, oBuf);
896 /* check the types */
897 if ((dLvl = compareType (val->type, type->next)) <= 0)
899 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
903 /* now generate the name */
906 if (port->use_dw_for_init)
908 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
912 printPointerType (oBuf, val->name);
915 else if (port->use_dw_for_init)
917 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
921 printPointerType (oBuf, val->sym->rname);
927 /*-----------------------------------------------------------------*/
928 /* printIvalCharPtr - generates initial values for character pointers */
929 /*-----------------------------------------------------------------*/
931 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
935 /* PENDING: this is _very_ mcs51 specific, including a magic
937 It's also endian specific.
939 size = getSize (type);
941 if (val->name && strlen (val->name))
943 if (size == 1) /* This appears to be Z80 specific?? */
946 "\t!dbs\n", val->name);
948 else if (size == FPTRSIZE)
950 if (port->use_dw_for_init)
952 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
956 printPointerType (oBuf, val->name);
959 else if (size == GPTRSIZE)
962 if (IS_PTR (val->type)) {
963 type = DCL_TYPE (val->type);
965 type = PTR_TYPE (SPEC_OCLS (val->etype));
967 if (val->sym && val->sym->isstrlit) {
968 // this is a literal string
971 printGPointerType (oBuf, val->name, sym->name, type);
975 fprintf (stderr, "*** internal error: unknown size in "
976 "printIvalCharPtr.\n");
981 // these are literals assigned to pointers
985 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
988 if (port->use_dw_for_init)
989 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
990 else if (port->little_endian)
991 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
992 aopLiteral (val, 0), aopLiteral (val, 1));
994 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
995 aopLiteral (val, 1), aopLiteral (val, 0));
998 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
999 // non-zero mcs51 generic pointer
1000 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1002 if (port->little_endian) {
1003 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1004 aopLiteral (val, 0),
1005 aopLiteral (val, 1),
1006 aopLiteral (val, 2));
1008 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1009 aopLiteral (val, 2),
1010 aopLiteral (val, 1),
1011 aopLiteral (val, 0));
1015 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1016 // non-zero ds390 generic pointer
1017 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1019 if (port->little_endian) {
1020 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1021 aopLiteral (val, 0),
1022 aopLiteral (val, 1),
1023 aopLiteral (val, 2),
1024 aopLiteral (val, 3));
1026 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1027 aopLiteral (val, 3),
1028 aopLiteral (val, 2),
1029 aopLiteral (val, 1),
1030 aopLiteral (val, 0));
1038 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1039 addSet (&statsg->syms, val->sym);
1045 /*-----------------------------------------------------------------*/
1046 /* printIvalPtr - generates initial value for pointers */
1047 /*-----------------------------------------------------------------*/
1049 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1055 if (ilist && (ilist->type == INIT_DEEP))
1056 ilist = ilist->init.deep;
1058 /* function pointer */
1059 if (IS_FUNC (type->next))
1061 printIvalFuncPtr (type, ilist, oBuf);
1065 if (!(val = initPointer (ilist, type)))
1068 /* if character pointer */
1069 if (IS_CHAR (type->next))
1070 if (printIvalCharPtr (sym, type, val, oBuf))
1073 /* check the type */
1074 if (compareType (type, val->type) == 0) {
1075 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1076 printFromToType (val->type, type);
1079 /* if val is literal */
1080 if (IS_LITERAL (val->etype))
1082 switch (getSize (type))
1085 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1088 if (port->use_dw_for_init)
1089 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1090 else if (port->little_endian)
1091 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1093 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1095 case 3: // how about '390??
1096 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1097 if (port->little_endian)
1099 dbuf_printf (oBuf, "\t.byte %s,%s",
1100 aopLiteral (val, 0), aopLiteral (val, 1));
1104 dbuf_printf (oBuf, "\t.byte %s,%s",
1105 aopLiteral (val, 1), aopLiteral (val, 0));
1107 if (IS_GENPTR (val->type))
1108 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1109 else if (IS_PTR (val->type))
1110 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1112 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1118 size = getSize (type);
1120 if (size == 1) /* Z80 specific?? */
1122 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1124 else if (size == FPTRSIZE)
1126 if (port->use_dw_for_init) {
1127 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1129 printPointerType (oBuf, val->name);
1132 else if (size == GPTRSIZE)
1134 printGPointerType (oBuf, val->name, sym->name,
1135 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1136 PTR_TYPE (SPEC_OCLS (val->etype))));
1141 /*-----------------------------------------------------------------*/
1142 /* printIval - generates code for initial value */
1143 /*-----------------------------------------------------------------*/
1145 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1149 /* if structure then */
1150 if (IS_STRUCT (type))
1152 printIvalStruct (sym, type, ilist, oBuf);
1156 /* if this is an array */
1157 if (IS_ARRAY (type))
1159 printIvalArray (sym, type, ilist, oBuf);
1165 // not an aggregate, ilist must be a node
1166 if (ilist->type!=INIT_NODE) {
1167 // or a 1-element list
1168 if (ilist->init.deep->next) {
1169 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1172 ilist=ilist->init.deep;
1176 // and the type must match
1177 itype=ilist->init.node->ftype;
1179 if (compareType(type, itype)==0) {
1180 // special case for literal strings
1181 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1182 // which are really code pointers
1183 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1186 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1187 printFromToType(itype, type);
1192 /* if this is a pointer */
1195 printIvalPtr (sym, type, ilist, oBuf);
1199 /* if type is SPECIFIER */
1202 printIvalType (sym, type, ilist, oBuf);
1207 /*-----------------------------------------------------------------*/
1208 /* emitStaticSeg - emitcode for the static segment */
1209 /*-----------------------------------------------------------------*/
1211 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1215 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1217 /* for all variables in this segment do */
1218 for (sym = setFirstItem (map->syms); sym;
1219 sym = setNextItem (map->syms))
1222 /* if it is "extern" then do nothing */
1223 if (IS_EXTERN (sym->etype))
1226 /* if it is not static add it to the public table */
1227 if (!IS_STATIC (sym->etype))
1229 addSetHead (&publics, sym);
1232 /* print extra debug info if required */
1233 if (options.debug) {
1237 if (IS_STATIC (sym->etype))
1238 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1240 dbuf_printf (oBuf, "G$"); /* scope is global */
1243 /* symbol is local */
1244 dbuf_printf (oBuf, "L%s$",
1245 (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);
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(), __DATE__, 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));
1535 int size = getSize(sym->type);
1538 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1541 dbuf_printf (aBuf, "==.\n");
1543 /* allocate space */
1544 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1545 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1552 /*-----------------------------------------------------------------*/
1553 /* glue - the final glue that hold the whole thing together */
1554 /*-----------------------------------------------------------------*/
1559 struct dbuf_s ovrBuf;
1563 dbuf_init (&vBuf, 4096);
1564 dbuf_init (&ovrBuf, 4096);
1566 mcs51_like = (port->general.glue_up_main &&
1567 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1569 /* print the global struct definitions */
1573 /* PENDING: this isn't the best place but it will do */
1574 if (port->general.glue_up_main)
1576 /* create the interrupt vector table */
1577 createInterruptVect (&vBuf);
1580 /* emit code for the all the variables declared */
1582 /* do the overlay segments */
1583 emitOverlay (&ovrBuf);
1585 outputDebugSymbols ();
1587 /* now put it all together into the assembler file */
1588 /* create the assembler file name */
1590 /* -o option overrides default name? */
1591 if ((noAssemble || options.c1mode) && fullDstFileName)
1593 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1597 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1598 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1601 if (!(asmFile = fopen (scratchFileName, "w")))
1603 werror (E_FILE_OPEN_ERR, scratchFileName);
1604 exit (EXIT_FAILURE);
1607 /* initial comments */
1608 initialComments (asmFile);
1610 /* print module name */
1611 tfprintf (asmFile, "\t!module\n", moduleName);
1614 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1616 switch(options.model)
1618 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1619 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1620 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1621 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1622 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1623 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1626 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1627 if(options.useXstack) fprintf (asmFile, " --xstack");
1628 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1629 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1630 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1631 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1632 fprintf (asmFile, "\n");
1634 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1636 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1639 tfprintf (asmFile, "\t!fileprelude\n");
1641 /* Let the port generate any global directives, etc. */
1642 if (port->genAssemblerPreamble)
1644 port->genAssemblerPreamble (asmFile);
1647 /* print the global variables in this module */
1648 printPublics (asmFile);
1649 if (port->assembler.externGlobal)
1650 printExterns (asmFile);
1653 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1655 /* copy the sfr segment */
1656 fprintf (asmFile, "%s", iComments2);
1657 fprintf (asmFile, "; special function registers\n");
1658 fprintf (asmFile, "%s", iComments2);
1659 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1664 /* copy the sbit segment */
1665 fprintf (asmFile, "%s", iComments2);
1666 fprintf (asmFile, "; special function bits\n");
1667 fprintf (asmFile, "%s", iComments2);
1668 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1670 /*JCF: Create the areas for the register banks*/
1671 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1673 fprintf (asmFile, "%s", iComments2);
1674 fprintf (asmFile, "; overlayable register banks\n");
1675 fprintf (asmFile, "%s", iComments2);
1677 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1678 if (RegBankUsed[1] || options.parms_in_bank1)
1679 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1681 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1683 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1687 fprintf (asmFile, "%s", iComments2);
1688 fprintf (asmFile, "; overlayable bit register bank\n");
1689 fprintf (asmFile, "%s", iComments2);
1690 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1691 fprintf (asmFile, "bits:\n\t.ds 1\n");
1692 fprintf (asmFile, "\tb0 = bits[0]\n");
1693 fprintf (asmFile, "\tb1 = bits[1]\n");
1694 fprintf (asmFile, "\tb2 = bits[2]\n");
1695 fprintf (asmFile, "\tb3 = bits[3]\n");
1696 fprintf (asmFile, "\tb4 = bits[4]\n");
1697 fprintf (asmFile, "\tb5 = bits[5]\n");
1698 fprintf (asmFile, "\tb6 = bits[6]\n");
1699 fprintf (asmFile, "\tb7 = bits[7]\n");
1703 /* copy the data segment */
1704 fprintf (asmFile, "%s", iComments2);
1705 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1706 fprintf (asmFile, "%s", iComments2);
1707 dbuf_write_and_destroy (&data->oBuf, asmFile);
1710 /* create the overlay segments */
1713 fprintf (asmFile, "%s", iComments2);
1714 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1715 fprintf (asmFile, "%s", iComments2);
1716 dbuf_write_and_destroy (&ovrBuf, asmFile);
1719 /* create the stack segment MOF */
1720 if (mainf && IFFUNC_HASBODY (mainf->type))
1722 fprintf (asmFile, "%s", iComments2);
1723 fprintf (asmFile, "; Stack segment in internal ram \n");
1724 fprintf (asmFile, "%s", iComments2);
1725 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1726 "__start__stack:\n\t.ds\t1\n\n");
1729 /* create the idata segment */
1730 if ((idata) && (mcs51_like))
1732 fprintf (asmFile, "%s", iComments2);
1733 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1734 fprintf (asmFile, "%s", iComments2);
1735 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1738 /* create the absolute idata/data segment */
1739 if ((i_abs) && (mcs51_like))
1741 fprintf (asmFile, "%s", iComments2);
1742 fprintf (asmFile, "; absolute internal ram data\n");
1743 fprintf (asmFile, "%s", iComments2);
1744 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1745 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1748 /* copy the bit segment */
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile, "; bit data\n");
1753 fprintf (asmFile, "%s", iComments2);
1754 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1757 /* copy paged external ram data */
1760 fprintf (asmFile, "%s", iComments2);
1761 fprintf (asmFile, "; paged external ram data\n");
1762 fprintf (asmFile, "%s", iComments2);
1763 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1766 /* if external stack then reserve space for it */
1767 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1769 fprintf (asmFile, "%s", iComments2);
1770 fprintf (asmFile, "; external stack \n");
1771 fprintf (asmFile, "%s", iComments2);
1772 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1773 "__start__xstack:\n\t.ds\t1\n\n");
1776 /* copy external ram data */
1779 fprintf (asmFile, "%s", iComments2);
1780 fprintf (asmFile, "; external ram data\n");
1781 fprintf (asmFile, "%s", iComments2);
1782 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1785 /* create the absolute xdata segment */
1786 if (mcs51_like || TARGET_IS_HC08)
1788 fprintf (asmFile, "%s", iComments2);
1789 fprintf (asmFile, "; absolute external ram data\n");
1790 fprintf (asmFile, "%s", iComments2);
1791 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1794 /* copy external initialized ram data */
1795 fprintf (asmFile, "%s", iComments2);
1796 fprintf (asmFile, "; external initialized ram data\n");
1797 fprintf (asmFile, "%s", iComments2);
1798 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1800 /* If the port wants to generate any extra areas, let it do so. */
1801 if (port->extraAreas.genExtraAreaDeclaration)
1803 port->extraAreas.genExtraAreaDeclaration(asmFile,
1804 mainf && IFFUNC_HASBODY(mainf->type));
1807 /* copy the interrupt vector table */
1808 if (mainf && IFFUNC_HASBODY (mainf->type))
1810 fprintf (asmFile, "%s", iComments2);
1811 fprintf (asmFile, "; interrupt vector \n");
1812 fprintf (asmFile, "%s", iComments2);
1813 dbuf_write_and_destroy (&vBuf, asmFile);
1816 /* copy global & static initialisations */
1817 fprintf (asmFile, "%s", iComments2);
1818 fprintf (asmFile, "; global & static initialisations\n");
1819 fprintf (asmFile, "%s", iComments2);
1821 /* Everywhere we generate a reference to the static_name area,
1822 * (which is currently only here), we immediately follow it with a
1823 * definition of the post_static_name area. This guarantees that
1824 * the post_static_name area will immediately follow the static_name
1827 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1828 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1829 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1830 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1832 if (mainf && IFFUNC_HASBODY (mainf->type))
1834 if (port->genInitStartup)
1836 port->genInitStartup (asmFile);
1840 assert (mcs51_like);
1841 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1842 /* if external stack is specified then the
1843 higher order byte of the xdatalocation is
1844 going into P2 and the lower order going into
1846 if (options.useXstack)
1848 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1849 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1850 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1851 (unsigned int) options.xdata_loc & 0xff);
1854 // This should probably be a port option, but I'm being lazy.
1855 // on the 400, the firmware boot loader gives us a valid stack
1856 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1857 if (!TARGET_IS_DS400)
1859 /* initialise the stack pointer. JCF: aslink takes care of the location */
1860 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1863 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1864 fprintf (asmFile, "\tmov\ta,dpl\n");
1865 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1866 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1867 fprintf (asmFile, "__sdcc_init_data:\n");
1869 // if the port can copy the XINIT segment to XISEG
1872 port->genXINIT (asmFile);
1876 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1878 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1880 /* This code is generated in the post-static area.
1881 * This area is guaranteed to follow the static area
1882 * by the ugly shucking and jiving about 20 lines ago.
1884 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1885 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1891 "%s", iComments2, iComments2);
1892 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1893 dbuf_write_and_destroy (&home->oBuf, asmFile);
1895 if (mainf && IFFUNC_HASBODY (mainf->type))
1897 /* entry point @ start of HOME */
1898 fprintf (asmFile, "__sdcc_program_startup:\n");
1900 /* put in jump or call to main */
1901 if (options.mainreturn)
1903 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1904 fprintf (asmFile, ";\treturn from main will return to caller\n");
1908 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1909 fprintf (asmFile, ";\treturn from main will lock up\n");
1910 fprintf (asmFile, "\tsjmp .\n");
1913 /* copy over code */
1914 fprintf (asmFile, "%s", iComments2);
1915 fprintf (asmFile, "; code\n");
1916 fprintf (asmFile, "%s", iComments2);
1917 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1918 dbuf_write_and_destroy (&code->oBuf, asmFile);
1920 if (port->genAssemblerEnd)
1922 port->genAssemblerEnd (asmFile);