1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 #include "dbuf_string.h"
38 symbol *interrupts[INTNO_MAX+1];
40 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Variables that are declared as extern */
44 unsigned maxInterrupts = 0;
47 int noInit = 0; /* no initialization */
50 /*-----------------------------------------------------------------*/
51 /* closePipes - closes all pipes created by the compiler */
52 /*-----------------------------------------------------------------*/
53 DEFSETFUNC (closePipes)
66 /*-----------------------------------------------------------------*/
67 /* closeTmpFiles - closes all tmp files created by the compiler */
68 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
69 /*-----------------------------------------------------------------*/
70 DEFSETFUNC (closeTmpFiles)
83 /*-----------------------------------------------------------------*/
84 /* rmTmpFiles - unlinks all tmp files created by the compiler */
85 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
86 /*-----------------------------------------------------------------*/
87 DEFSETFUNC (rmTmpFiles)
102 aopLiteralLong (value * val, int offset, int size)
111 // assuming we have been warned before
112 val = constCharVal (0);
115 /* if it is a float then it gets tricky */
116 /* otherwise it is fairly simple */
117 if (!IS_FLOAT (val->type)) {
118 unsigned long v = ulFromVal (val);
123 tsprintf (buffer, sizeof(buffer),
124 "!immedbyte", (unsigned int) v & 0xff);
127 tsprintf (buffer, sizeof(buffer),
128 "!immedword", (unsigned int) v & 0xffff);
131 /* Hmm. Too big for now. */
134 return Safe_strdup (buffer);
137 /* PENDING: For now size must be 1 */
140 /* it is type float */
141 fl.f = (float) floatFromVal (val);
142 #ifdef WORDS_BIGENDIAN
143 tsprintf (buffer, sizeof(buffer),
144 "!immedbyte", fl.c[3 - offset]);
146 tsprintf (buffer, sizeof(buffer),
147 "!immedbyte", fl.c[offset]);
149 return Safe_strdup (buffer);
152 /*-----------------------------------------------------------------*/
153 /* aopLiteral - string from a literal value */
154 /*-----------------------------------------------------------------*/
156 aopLiteral (value * val, int offset)
158 return aopLiteralLong (val, offset, 1);
161 /*-----------------------------------------------------------------*/
162 /* emitRegularMap - emit code for maps with no special cases */
163 /*-----------------------------------------------------------------*/
165 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
175 /* PENDING: special case here - should remove */
176 if (!strcmp (map->sname, CODE_NAME))
177 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
178 else if (!strcmp (map->sname, DATA_NAME))
179 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
180 else if (!strcmp (map->sname, HOME_NAME))
181 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
183 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
186 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
188 symbol *newSym = NULL;
190 /* if extern then add it into the extern list */
191 if (IS_EXTERN (sym->etype))
193 addSetHead (&externs, sym);
197 /* if allocation required check is needed
198 then check if the symbol really requires
199 allocation only for local variables */
201 if (arFlag && !IS_AGGREGATE (sym->type) &&
202 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
203 !sym->allocreq && sym->level)
206 /* for bitvar locals and parameters */
207 if (!arFlag && !sym->allocreq && sym->level
208 && !SPEC_ABSA (sym->etype))
213 /* if global variable & not static or extern
214 and addPublics allowed then add it to the public set */
215 if ((sym->level == 0 ||
216 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
218 !IS_STATIC (sym->etype) &&
219 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : 1))
221 addSetHead (&publics, sym);
224 /* if extern then do nothing or is a function
226 if (IS_FUNC (sym->type) && !(sym->isitmp))
229 /* print extra debug info if required */
232 if (!sym->level) /* global */
234 if (IS_STATIC (sym->etype))
235 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
237 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
241 /* symbol is local */
242 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
244 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
247 /* if it has an initial value then do it only if
248 it is a global variable */
249 if (sym->ival && sym->level == 0)
251 if ((SPEC_OCLS (sym->etype) == xidata) && !SPEC_ABSA (sym->etype))
253 /* create a new "XINIT (CODE)" symbol, that will be emitted later
255 newSym=copySymbol (sym);
256 SPEC_OCLS(newSym->etype)=xinit;
257 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
258 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
259 if (IS_SPEC (newSym->type))
260 SPEC_CONST (newSym->type) = 1;
262 DCL_PTR_CONST (newSym->type) = 1;
263 SPEC_STAT(newSym->etype)=1;
264 resolveIvalSym(newSym->ival, newSym->type);
266 // add it to the "XINIT (CODE)" segment
267 addSet(&xinit->syms, newSym);
269 if (!SPEC_ABSA (sym->etype))
271 struct dbuf_s tmpBuf;
273 dbuf_init(&tmpBuf, 4096);
274 // before allocation we must parse the sym->ival tree
275 // but without actually generating initialization code
277 resolveIvalSym (sym->ival, sym->type);
279 printIval (sym, sym->type, sym->ival, &tmpBuf);
282 dbuf_destroy(&tmpBuf);
287 if (IS_AGGREGATE (sym->type))
289 ival = initAggregates (sym, sym->ival, NULL);
293 if (getNelements (sym->type, sym->ival)>1)
295 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
297 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
298 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
300 codeOutBuf = &statsg->oBuf;
304 // set ival's lineno to where the symbol was defined
305 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
306 // check if this is not a constant expression
307 if (!constExprTree (ival))
309 werror (E_CONST_EXPECTED, "found expression");
310 // but try to do it anyway
313 if (!astErrors (ival))
314 eBBlockFromiCode (iCodeFromAst (ival));
320 /* if it has an absolute address then generate
321 an equate for this no need to allocate space */
322 if (SPEC_ABSA (sym->etype) && !sym->ival)
326 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
334 else if (map == bit || map == sfrbit)
339 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
343 int size = getSize (sym->type) + sym->flexArrayLength;
346 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
351 dbuf_printf (&map->oBuf, "==.\n");
353 if (SPEC_ABSA (sym->etype))
355 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
357 if (IS_STATIC (sym->etype) || sym->level)
358 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
360 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
361 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
367 /*-----------------------------------------------------------------*/
368 /* initPointer - pointer initialization code massaging */
369 /*-----------------------------------------------------------------*/
371 initPointer (initList * ilist, sym_link *toType)
377 return valCastLiteral(toType, 0.0);
380 expr = list2expr (ilist);
385 /* try it the old way first */
386 if ((val = constExprValue (expr, FALSE)))
389 /* ( ptr + constant ) */
390 if (IS_AST_OP (expr) &&
391 (expr->opval.op == '+' || expr->opval.op == '-') &&
392 IS_AST_SYM_VALUE (expr->left) &&
393 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
394 compareType(toType, expr->left->ftype) &&
395 IS_AST_LIT_VALUE (expr->right)) {
396 return valForCastAggr (expr->left, expr->left->ftype,
402 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
403 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
404 if (compareType(toType, expr->left->ftype)!=1) {
405 werror (W_INIT_WRONG);
406 printFromToType(expr->left->ftype, toType);
412 /* no then we have to do these cludgy checks */
413 /* pointers can be initialized with address of
414 a variable or address of an array element */
415 if (IS_AST_OP (expr) && expr->opval.op == '&') {
416 /* address of symbol */
417 if (IS_AST_SYM_VALUE (expr->left)) {
418 val = AST_VALUE (expr->left);
419 val->type = newLink (DECLARATOR);
420 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
421 DCL_TYPE (val->type) = CPOINTER;
422 DCL_PTR_CONST (val->type) = port->mem.code_ro;
424 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
425 DCL_TYPE (val->type) = FPOINTER;
426 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
427 DCL_TYPE (val->type) = PPOINTER;
428 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
429 DCL_TYPE (val->type) = IPOINTER;
430 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
431 DCL_TYPE (val->type) = EEPPOINTER;
433 DCL_TYPE (val->type) = POINTER;
434 val->type->next = expr->left->ftype;
435 val->etype = getSpec (val->type);
439 /* if address of indexed array */
440 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
441 return valForArray (expr->left);
443 /* if address of structure element then
445 if (IS_AST_OP (expr->left) &&
446 expr->left->opval.op == '.') {
447 return valForStructElem (expr->left->left,
452 (&some_struct)->element */
453 if (IS_AST_OP (expr->left) &&
454 expr->left->opval.op == PTR_OP &&
455 IS_ADDRESS_OF_OP (expr->left->left)) {
456 return valForStructElem (expr->left->left->left,
460 /* case 3. (((char *) &a) +/- constant) */
461 if (IS_AST_OP (expr) &&
462 (expr->opval.op == '+' || expr->opval.op == '-') &&
463 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
464 IS_AST_OP (expr->left->right) &&
465 expr->left->right->opval.op == '&' &&
466 IS_AST_LIT_VALUE (expr->right)) {
468 return valForCastAggr (expr->left->right->left,
469 expr->left->left->opval.lnk,
470 expr->right, expr->opval.op);
473 /* case 4. (char *)(array type) */
474 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
475 IS_ARRAY(expr->right->ftype)) {
477 val = copyValue (AST_VALUE (expr->right));
478 val->type = newLink (DECLARATOR);
479 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
480 DCL_TYPE (val->type) = CPOINTER;
481 DCL_PTR_CONST (val->type) = port->mem.code_ro;
483 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
484 DCL_TYPE (val->type) = FPOINTER;
485 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
486 DCL_TYPE (val->type) = PPOINTER;
487 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
488 DCL_TYPE (val->type) = IPOINTER;
489 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
490 DCL_TYPE (val->type) = EEPPOINTER;
492 DCL_TYPE (val->type) = POINTER;
493 val->type->next = expr->right->ftype->next;
494 val->etype = getSpec (val->type);
499 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
501 werror (E_INCOMPAT_PTYPES);
506 /*-----------------------------------------------------------------*/
507 /* printChar - formats and prints a characater string with DB */
508 /*-----------------------------------------------------------------*/
510 printChar (struct dbuf_s * oBuf, char *s, int plen)
518 while (len && pplen < plen)
521 while (i && pplen < plen)
523 if (*s < ' ' || *s == '\"' || *s=='\\')
527 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
528 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
543 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
554 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
559 /*-----------------------------------------------------------------*/
560 /* return the generic pointer high byte for a given pointer type. */
561 /*-----------------------------------------------------------------*/
563 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
571 werror (E_CANNOT_USE_GENERIC_POINTER,
572 iname ? iname : "<null>",
573 oname ? oname : "<null>");
580 return GPTYPE_XSTACK;
582 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
590 /*-----------------------------------------------------------------*/
591 /* printPointerType - generates ival for pointer type */
592 /*-----------------------------------------------------------------*/
594 _printPointerType (struct dbuf_s * oBuf, const char *name)
596 if (options.model == MODEL_FLAT24)
598 if (port->little_endian)
599 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
601 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
605 if (port->little_endian)
606 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
608 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
612 /*-----------------------------------------------------------------*/
613 /* printPointerType - generates ival for pointer type */
614 /*-----------------------------------------------------------------*/
616 printPointerType (struct dbuf_s * oBuf, const char *name)
618 _printPointerType (oBuf, name);
619 dbuf_printf (oBuf, "\n");
622 /*-----------------------------------------------------------------*/
623 /* printGPointerType - generates ival for generic pointer type */
624 /*-----------------------------------------------------------------*/
626 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
627 const unsigned int type)
629 _printPointerType (oBuf, iname);
630 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
633 /*-----------------------------------------------------------------*/
634 /* printIvalType - generates ival for int/char */
635 /*-----------------------------------------------------------------*/
637 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
641 /* if initList is deep */
642 if (ilist && (ilist->type == INIT_DEEP))
643 ilist = ilist->init.deep;
645 if (!(val = list2val (ilist))) {
646 // assuming a warning has been thrown
647 val = constCharVal (0);
650 /* check if the literal value is within bounds */
651 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
652 !options.lessPedantic)
654 werror (W_LIT_OVERFLOW);
657 if (val->type != type) {
658 val = valCastLiteral(type, floatFromVal(val));
661 switch (getSize (type)) {
664 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
666 dbuf_tprintf (oBuf, "\t!dbs\n",
667 aopLiteral (val, 0));
671 if (port->use_dw_for_init)
672 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
673 else if (port->little_endian)
674 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
676 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
680 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
681 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
683 else if (port->little_endian) {
684 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
685 aopLiteral (val, 0), aopLiteral (val, 1),
686 aopLiteral (val, 2), aopLiteral (val, 3));
689 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
690 aopLiteral (val, 3), aopLiteral (val, 2),
691 aopLiteral (val, 1), aopLiteral (val, 0));
697 /*-----------------------------------------------------------------*/
698 /* printIvalBitFields - generate initializer for bitfields */
699 /*-----------------------------------------------------------------*/
700 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
704 initList *lilist = *ilist ;
705 unsigned long ival = 0;
710 val = list2val(lilist);
712 if (SPEC_BLEN(lsym->etype) > 8) {
713 size += ((SPEC_BLEN (lsym->etype) / 8) +
714 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
717 size = ((SPEC_BLEN (lsym->etype) / 8) +
718 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
721 /* check if the literal value is within bounds */
722 if (checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
723 !options.lessPedantic)
725 werror (W_LIT_OVERFLOW);
728 i &= (1 << SPEC_BLEN (lsym->etype)) - 1;
729 i <<= SPEC_BSTR (lsym->etype);
731 if (! ( lsym->next &&
732 (IS_BITFIELD(lsym->next->type)) &&
733 (SPEC_BSTR(lsym->next->etype)))) break;
735 lilist = lilist ? lilist->next : NULL;
739 dbuf_tprintf (oBuf, "\t!db !constbyte\n",ival);
743 dbuf_tprintf (oBuf, "\t!dw !constword\n",ival);
746 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
747 (ival >> 16) & 0xffff, (ival & 0xffff));
754 /*-----------------------------------------------------------------*/
755 /* printIvalStruct - generates initial value for structures */
756 /*-----------------------------------------------------------------*/
758 printIvalStruct (symbol * sym, sym_link * type,
759 initList * ilist, struct dbuf_s * oBuf)
762 initList *iloop = NULL;
764 sflds = SPEC_STRUCT (type)->fields;
767 if (ilist->type != INIT_DEEP) {
768 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
772 iloop = ilist->init.deep;
775 if (SPEC_STRUCT (type)->type == UNION) {
776 printIval (sym, sflds->type, iloop, oBuf);
777 iloop = iloop ? iloop->next : NULL;
779 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
780 if (IS_BITFIELD(sflds->type)) {
781 printIvalBitFields(&sflds, &iloop, oBuf);
783 printIval (sym, sflds->type, iloop, oBuf);
788 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
793 /*-----------------------------------------------------------------*/
794 /* printIvalChar - generates initital value for character array */
795 /*-----------------------------------------------------------------*/
797 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
800 unsigned int size = DCL_ELEM (type);
804 val = list2val (ilist);
805 /* if the value is a character string */
806 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
810 /* we have not been given a size, but now we know it */
811 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
812 /* but first check, if it's a flexible array */
813 if (sym && IS_STRUCT (sym->type))
814 sym->flexArrayLength = size;
816 DCL_ELEM (type) = size;
819 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
827 printChar (oBuf, s, strlen (s) + 1);
831 /*-----------------------------------------------------------------*/
832 /* printIvalArray - generates code for array initialization */
833 /*-----------------------------------------------------------------*/
835 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
836 struct dbuf_s * oBuf)
840 unsigned int size = 0;
843 /* take care of the special case */
844 /* array of characters can be init */
846 if (IS_CHAR (type->next)) {
847 val = list2val(ilist);
849 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
852 if (!IS_LITERAL(val->etype)) {
853 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
856 if (printIvalChar (sym, type,
857 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
858 oBuf, SPEC_CVAL (sym->etype).v_char))
861 /* not the special case */
862 if (ilist->type != INIT_DEEP) {
863 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
867 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
868 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
869 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
872 printIval (sym, type->next, iloop, oBuf);
876 if (DCL_ELEM(type)) {
877 // pad with zeros if needed
878 if (size<DCL_ELEM(type)) {
879 size = (DCL_ELEM(type) - size) * getSize(type->next);
881 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
885 /* we have not been given a size, but now we know it */
886 /* but first check, if it's a flexible array */
887 if (IS_STRUCT (sym->type))
888 sym->flexArrayLength = size * getSize (type->next);
890 DCL_ELEM (type) = size;
896 /*-----------------------------------------------------------------*/
897 /* printIvalFuncPtr - generate initial value for function pointers */
898 /*-----------------------------------------------------------------*/
900 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
906 val = list2val (ilist);
908 val = valCastLiteral(type, 0.0);
911 // an error has been thrown already
912 val = constCharVal (0);
915 if (IS_LITERAL(val->etype)) {
916 if (compareType(type, val->etype) == 0) {
917 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
918 printFromToType (val->type, type);
920 printIvalCharPtr (NULL, type, val, oBuf);
924 /* check the types */
925 if ((dLvl = compareType (val->type, type->next)) <= 0)
927 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
931 /* now generate the name */
934 if (port->use_dw_for_init)
936 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
940 printPointerType (oBuf, val->name);
943 else if (port->use_dw_for_init)
945 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
949 printPointerType (oBuf, val->sym->rname);
955 /*-----------------------------------------------------------------*/
956 /* printIvalCharPtr - generates initial values for character pointers */
957 /*-----------------------------------------------------------------*/
959 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
963 /* PENDING: this is _very_ mcs51 specific, including a magic
965 It's also endian specific.
967 size = getSize (type);
969 if (val->name && strlen (val->name))
971 if (size == 1) /* This appears to be Z80 specific?? */
974 "\t!dbs\n", val->name);
976 else if (size == FPTRSIZE)
978 if (port->use_dw_for_init)
980 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
984 printPointerType (oBuf, val->name);
987 else if (size == GPTRSIZE)
990 if (IS_PTR (val->type)) {
991 type = DCL_TYPE (val->type);
993 type = PTR_TYPE (SPEC_OCLS (val->etype));
995 if (val->sym && val->sym->isstrlit) {
996 // this is a literal string
999 printGPointerType (oBuf, val->name, sym->name, type);
1003 fprintf (stderr, "*** internal error: unknown size in "
1004 "printIvalCharPtr.\n");
1009 // these are literals assigned to pointers
1013 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
1016 if (port->use_dw_for_init)
1017 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
1018 else if (port->little_endian)
1019 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1020 aopLiteral (val, 0), aopLiteral (val, 1));
1022 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1023 aopLiteral (val, 1), aopLiteral (val, 0));
1026 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1027 // non-zero mcs51 generic pointer
1028 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1030 if (port->little_endian) {
1031 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1032 aopLiteral (val, 0),
1033 aopLiteral (val, 1),
1034 aopLiteral (val, 2));
1036 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1037 aopLiteral (val, 2),
1038 aopLiteral (val, 1),
1039 aopLiteral (val, 0));
1043 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1044 // non-zero ds390 generic pointer
1045 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1047 if (port->little_endian) {
1048 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1049 aopLiteral (val, 0),
1050 aopLiteral (val, 1),
1051 aopLiteral (val, 2),
1052 aopLiteral (val, 3));
1054 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1055 aopLiteral (val, 3),
1056 aopLiteral (val, 2),
1057 aopLiteral (val, 1),
1058 aopLiteral (val, 0));
1066 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1067 addSet (&statsg->syms, val->sym);
1073 /*-----------------------------------------------------------------*/
1074 /* printIvalPtr - generates initial value for pointers */
1075 /*-----------------------------------------------------------------*/
1077 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1083 if (ilist && (ilist->type == INIT_DEEP))
1084 ilist = ilist->init.deep;
1086 /* function pointer */
1087 if (IS_FUNC (type->next))
1089 printIvalFuncPtr (type, ilist, oBuf);
1093 if (!(val = initPointer (ilist, type)))
1096 /* if character pointer */
1097 if (IS_CHAR (type->next))
1098 if (printIvalCharPtr (sym, type, val, oBuf))
1101 /* check the type */
1102 if (compareType (type, val->type) == 0) {
1103 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1104 printFromToType (val->type, type);
1107 /* if val is literal */
1108 if (IS_LITERAL (val->etype))
1110 switch (getSize (type))
1113 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1116 if (port->use_dw_for_init)
1117 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1118 else if (port->little_endian)
1119 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1121 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1123 case 3: // how about '390??
1124 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1125 if (port->little_endian)
1127 dbuf_printf (oBuf, "\t.byte %s,%s",
1128 aopLiteral (val, 0), aopLiteral (val, 1));
1132 dbuf_printf (oBuf, "\t.byte %s,%s",
1133 aopLiteral (val, 1), aopLiteral (val, 0));
1135 if (IS_GENPTR (val->type))
1136 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1137 else if (IS_PTR (val->type))
1138 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1140 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1146 size = getSize (type);
1148 if (size == 1) /* Z80 specific?? */
1150 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1152 else if (size == FPTRSIZE)
1154 if (port->use_dw_for_init) {
1155 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1157 printPointerType (oBuf, val->name);
1160 else if (size == GPTRSIZE)
1162 printGPointerType (oBuf, val->name, sym->name,
1163 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1164 PTR_TYPE (SPEC_OCLS (val->etype))));
1169 /*-----------------------------------------------------------------*/
1170 /* printIval - generates code for initial value */
1171 /*-----------------------------------------------------------------*/
1173 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1177 /* if structure then */
1178 if (IS_STRUCT (type))
1180 printIvalStruct (sym, type, ilist, oBuf);
1184 /* if this is an array */
1185 if (IS_ARRAY (type))
1187 printIvalArray (sym, type, ilist, oBuf);
1193 // not an aggregate, ilist must be a node
1194 if (ilist->type!=INIT_NODE) {
1195 // or a 1-element list
1196 if (ilist->init.deep->next) {
1197 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1200 ilist=ilist->init.deep;
1204 // and the type must match
1205 itype=ilist->init.node->ftype;
1207 if (compareType(type, itype)==0) {
1208 // special case for literal strings
1209 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1210 // which are really code pointers
1211 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1214 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1215 printFromToType(itype, type);
1220 /* if this is a pointer */
1223 printIvalPtr (sym, type, ilist, oBuf);
1227 /* if type is SPECIFIER */
1230 printIvalType (sym, type, ilist, oBuf);
1235 /*-----------------------------------------------------------------*/
1236 /* emitStaticSeg - emitcode for the static segment */
1237 /*-----------------------------------------------------------------*/
1239 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1243 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1245 /* for all variables in this segment do */
1246 for (sym = setFirstItem (map->syms); sym;
1247 sym = setNextItem (map->syms))
1250 /* if it is "extern" then do nothing */
1251 if (IS_EXTERN (sym->etype))
1254 /* if it is not static add it to the public table */
1255 if (!IS_STATIC (sym->etype))
1257 addSetHead (&publics, sym);
1260 /* print extra debug info if required */
1265 if (IS_STATIC (sym->etype))
1266 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1268 dbuf_printf (oBuf, "G$"); /* scope is global */
1272 /* symbol is local */
1273 dbuf_printf (oBuf, "L%s$",
1274 (sym->localof ? sym->localof->name : "-null-"));
1276 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1279 /* if it has an absolute address and no initializer */
1280 if (SPEC_ABSA (sym->etype) && !sym->ival)
1283 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1285 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1287 SPEC_ADDR (sym->etype));
1292 dbuf_printf (oBuf, " == .\n");
1294 /* if it has an initial value */
1297 if (SPEC_ABSA (sym->etype))
1299 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1301 dbuf_printf (oBuf, "%s:\n", sym->rname);
1303 resolveIvalSym (sym->ival, sym->type);
1304 printIval (sym, sym->type, sym->ival, oBuf);
1306 /* if sym is a simple string and sym->ival is a string,
1307 WE don't need it anymore */
1308 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1309 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1310 list2val(sym->ival)->sym->isstrlit) {
1311 freeStringSymbol(list2val(sym->ival)->sym);
1315 /* allocate space */
1316 int size = getSize (sym->type);
1319 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1321 dbuf_printf (oBuf, "%s:\n", sym->rname);
1322 /* special case for character strings */
1323 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1324 SPEC_CVAL (sym->etype).v_char)
1326 SPEC_CVAL (sym->etype).v_char,
1329 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1335 /*-----------------------------------------------------------------*/
1336 /* emitMaps - emits the code for the data portion the code */
1337 /*-----------------------------------------------------------------*/
1341 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1342 /* ports but let's be conservative - EEP */
1345 /* no special considerations for the following
1346 data, idata & bit & xdata */
1347 emitRegularMap (data, TRUE, TRUE);
1348 emitRegularMap (idata, TRUE, TRUE);
1349 emitRegularMap (d_abs, TRUE, TRUE);
1350 emitRegularMap (i_abs, TRUE, TRUE);
1351 emitRegularMap (bit, TRUE, TRUE);
1352 emitRegularMap (pdata, TRUE, TRUE);
1353 emitRegularMap (xdata, TRUE, TRUE);
1354 emitRegularMap (x_abs, TRUE, TRUE);
1355 if (port->genXINIT) {
1356 emitRegularMap (xidata, TRUE, TRUE);
1358 emitRegularMap (sfr, publicsfr, FALSE);
1359 emitRegularMap (sfrbit, publicsfr, FALSE);
1360 emitRegularMap (home, TRUE, FALSE);
1361 emitRegularMap (code, TRUE, FALSE);
1363 if (options.const_seg) {
1364 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1366 emitStaticSeg (statsg, &code->oBuf);
1367 if (port->genXINIT) {
1368 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1369 emitStaticSeg (xinit, &code->oBuf);
1371 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1372 emitStaticSeg (c_abs, &code->oBuf);
1376 /*-----------------------------------------------------------------*/
1377 /* flushStatics - flush all currently defined statics out to file */
1378 /* and delete. Temporary function */
1379 /*-----------------------------------------------------------------*/
1383 emitStaticSeg (statsg, codeOutBuf);
1384 statsg->syms = NULL;
1387 /*-----------------------------------------------------------------*/
1388 /* createInterruptVect - creates the interrupt vector */
1389 /*-----------------------------------------------------------------*/
1391 createInterruptVect (struct dbuf_s *vBuf)
1393 mainf = newSymbol ("main", 0);
1396 /* only if the main function exists */
1397 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1399 if (!options.cc_only && !noAssemble && !options.c1mode)
1404 /* if the main is only a prototype ie. no body then do nothing */
1405 if (!IFFUNC_HASBODY(mainf->type))
1407 /* if ! compile only then main function should be present */
1408 if (!options.cc_only && !noAssemble)
1413 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1414 dbuf_printf (vBuf, "__interrupt_vect:\n");
1417 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1419 /* There's no such thing as a "generic" interrupt table header. */
1426 ";--------------------------------------------------------\n"
1427 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1431 ";--------------------------------------------------------\n"};
1434 /*-----------------------------------------------------------------*/
1435 /* initialComments - puts in some initial comments */
1436 /*-----------------------------------------------------------------*/
1438 initialComments (FILE * afile)
1442 fprintf (afile, "%s", iComments1);
1443 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1444 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1445 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1446 fprintf (afile, "%s", iComments2);
1449 /*-----------------------------------------------------------------*/
1450 /* printPublics - generates .global for publics */
1451 /*-----------------------------------------------------------------*/
1453 printPublics (FILE * afile)
1457 fprintf (afile, "%s", iComments2);
1458 fprintf (afile, "; Public variables in this module\n");
1459 fprintf (afile, "%s", iComments2);
1461 for (sym = setFirstItem (publics); sym;
1462 sym = setNextItem (publics))
1463 tfprintf (afile, "\t!global\n", sym->rname);
1466 /*-----------------------------------------------------------------*/
1467 /* printExterns - generates .global for externs */
1468 /*-----------------------------------------------------------------*/
1470 printExterns (FILE * afile)
1474 fprintf (afile, "%s", iComments2);
1475 fprintf (afile, "; Externals used\n");
1476 fprintf (afile, "%s", iComments2);
1478 for (sym = setFirstItem (externs); sym;
1479 sym = setNextItem (externs))
1480 tfprintf (afile, "\t!extern\n", sym->rname);
1483 /*-----------------------------------------------------------------*/
1484 /* emitOverlay - will emit code for the overlay stuff */
1485 /*-----------------------------------------------------------------*/
1487 emitOverlay (struct dbuf_s * aBuf)
1491 if (!elementsInSet (ovrSetSets))
1492 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1494 /* for each of the sets in the overlay segment do */
1495 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1496 ovrset = setNextItem (ovrSetSets))
1501 if (elementsInSet (ovrset))
1503 /* output the area informtion */
1504 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1507 for (sym = setFirstItem (ovrset); sym;
1508 sym = setNextItem (ovrset))
1510 /* if extern then it is in the publics table: do nothing */
1511 if (IS_EXTERN (sym->etype))
1514 /* if allocation required check is needed
1515 then check if the symbol really requires
1516 allocation only for local variables */
1517 if (!IS_AGGREGATE (sym->type) &&
1518 !(sym->_isparm && !IS_REGPARM (sym->etype))
1519 && !sym->allocreq && sym->level)
1522 /* if global variable & not static or extern
1523 and addPublics allowed then add it to the public set */
1524 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1525 && !IS_STATIC (sym->etype))
1527 addSetHead (&publics, sym);
1530 /* if extern then do nothing or is a function
1532 if (IS_FUNC (sym->type))
1535 /* print extra debug info if required */
1540 if (IS_STATIC (sym->etype))
1541 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1543 dbuf_printf (aBuf, "G$"); /* scope is global */
1546 /* symbol is local */
1547 dbuf_printf (aBuf, "L%s$",
1548 (sym->localof ? sym->localof->name : "-null-"));
1549 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1552 /* if is has an absolute address then generate
1553 an equate for this no need to allocate space */
1554 if (SPEC_ABSA (sym->etype))
1558 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1560 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1562 SPEC_ADDR (sym->etype));
1566 int size = getSize(sym->type);
1569 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1572 dbuf_printf (aBuf, "==.\n");
1574 /* allocate space */
1575 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1576 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1583 /*-----------------------------------------------------------------*/
1584 /* glue - the final glue that hold the whole thing together */
1585 /*-----------------------------------------------------------------*/
1590 struct dbuf_s ovrBuf;
1594 dbuf_init (&vBuf, 4096);
1595 dbuf_init (&ovrBuf, 4096);
1597 mcs51_like = (port->general.glue_up_main &&
1598 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1600 /* print the global struct definitions */
1604 /* PENDING: this isn't the best place but it will do */
1605 if (port->general.glue_up_main)
1607 /* create the interrupt vector table */
1608 createInterruptVect (&vBuf);
1611 /* emit code for the all the variables declared */
1613 /* do the overlay segments */
1614 emitOverlay (&ovrBuf);
1616 outputDebugSymbols ();
1618 /* now put it all together into the assembler file */
1619 /* create the assembler file name */
1621 /* -o option overrides default name? */
1622 if ((noAssemble || options.c1mode) && fullDstFileName)
1624 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1628 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1629 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1632 if (!(asmFile = fopen (scratchFileName, "w")))
1634 werror (E_FILE_OPEN_ERR, scratchFileName);
1635 exit (EXIT_FAILURE);
1638 /* initial comments */
1639 initialComments (asmFile);
1641 /* print module name */
1642 tfprintf (asmFile, "\t!module\n", moduleName);
1645 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1647 switch(options.model)
1649 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1650 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1651 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1652 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1653 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1654 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1657 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1658 if(options.useXstack) fprintf (asmFile, " --xstack");
1659 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1660 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1661 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1662 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1663 fprintf (asmFile, "\n");
1665 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1667 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1670 tfprintf (asmFile, "\t!fileprelude\n");
1672 /* Let the port generate any global directives, etc. */
1673 if (port->genAssemblerPreamble)
1675 port->genAssemblerPreamble (asmFile);
1678 /* print the global variables in this module */
1679 printPublics (asmFile);
1680 if (port->assembler.externGlobal)
1681 printExterns (asmFile);
1684 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1686 /* copy the sfr segment */
1687 fprintf (asmFile, "%s", iComments2);
1688 fprintf (asmFile, "; special function registers\n");
1689 fprintf (asmFile, "%s", iComments2);
1690 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1695 /* copy the sbit segment */
1696 fprintf (asmFile, "%s", iComments2);
1697 fprintf (asmFile, "; special function bits\n");
1698 fprintf (asmFile, "%s", iComments2);
1699 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1701 /*JCF: Create the areas for the register banks*/
1702 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1704 fprintf (asmFile, "%s", iComments2);
1705 fprintf (asmFile, "; overlayable register banks\n");
1706 fprintf (asmFile, "%s", iComments2);
1708 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1709 if (RegBankUsed[1] || options.parms_in_bank1)
1710 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1712 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1714 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1718 fprintf (asmFile, "%s", iComments2);
1719 fprintf (asmFile, "; overlayable bit register bank\n");
1720 fprintf (asmFile, "%s", iComments2);
1721 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1722 fprintf (asmFile, "bits:\n\t.ds 1\n");
1723 fprintf (asmFile, "\tb0 = bits[0]\n");
1724 fprintf (asmFile, "\tb1 = bits[1]\n");
1725 fprintf (asmFile, "\tb2 = bits[2]\n");
1726 fprintf (asmFile, "\tb3 = bits[3]\n");
1727 fprintf (asmFile, "\tb4 = bits[4]\n");
1728 fprintf (asmFile, "\tb5 = bits[5]\n");
1729 fprintf (asmFile, "\tb6 = bits[6]\n");
1730 fprintf (asmFile, "\tb7 = bits[7]\n");
1734 /* copy the data segment */
1735 fprintf (asmFile, "%s", iComments2);
1736 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1737 fprintf (asmFile, "%s", iComments2);
1738 dbuf_write_and_destroy (&data->oBuf, asmFile);
1741 /* create the overlay segments */
1744 fprintf (asmFile, "%s", iComments2);
1745 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1746 fprintf (asmFile, "%s", iComments2);
1747 dbuf_write_and_destroy (&ovrBuf, asmFile);
1750 /* create the stack segment MOF */
1751 if (mainf && IFFUNC_HASBODY (mainf->type))
1753 fprintf (asmFile, "%s", iComments2);
1754 fprintf (asmFile, "; Stack segment in internal ram \n");
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1757 "__start__stack:\n\t.ds\t1\n\n");
1760 /* create the idata segment */
1761 if ((idata) && (mcs51_like))
1763 fprintf (asmFile, "%s", iComments2);
1764 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1765 fprintf (asmFile, "%s", iComments2);
1766 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1769 /* create the absolute idata/data segment */
1770 if ((i_abs) && (mcs51_like))
1772 fprintf (asmFile, "%s", iComments2);
1773 fprintf (asmFile, "; absolute internal ram data\n");
1774 fprintf (asmFile, "%s", iComments2);
1775 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1776 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1779 /* copy the bit segment */
1782 fprintf (asmFile, "%s", iComments2);
1783 fprintf (asmFile, "; bit data\n");
1784 fprintf (asmFile, "%s", iComments2);
1785 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1788 /* copy paged external ram data */
1791 fprintf (asmFile, "%s", iComments2);
1792 fprintf (asmFile, "; paged external ram data\n");
1793 fprintf (asmFile, "%s", iComments2);
1794 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1797 /* if external stack then reserve space for it */
1798 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1800 fprintf (asmFile, "%s", iComments2);
1801 fprintf (asmFile, "; external stack \n");
1802 fprintf (asmFile, "%s", iComments2);
1803 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1804 "__start__xstack:\n\t.ds\t1\n\n");
1807 /* copy external ram data */
1810 fprintf (asmFile, "%s", iComments2);
1811 fprintf (asmFile, "; external ram data\n");
1812 fprintf (asmFile, "%s", iComments2);
1813 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1816 /* create the absolute xdata segment */
1817 if (mcs51_like || TARGET_IS_HC08)
1819 fprintf (asmFile, "%s", iComments2);
1820 fprintf (asmFile, "; absolute external ram data\n");
1821 fprintf (asmFile, "%s", iComments2);
1822 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1825 /* copy external initialized ram data */
1826 fprintf (asmFile, "%s", iComments2);
1827 fprintf (asmFile, "; external initialized ram data\n");
1828 fprintf (asmFile, "%s", iComments2);
1829 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1831 /* If the port wants to generate any extra areas, let it do so. */
1832 if (port->extraAreas.genExtraAreaDeclaration)
1834 port->extraAreas.genExtraAreaDeclaration(asmFile,
1835 mainf && IFFUNC_HASBODY(mainf->type));
1838 /* copy the interrupt vector table */
1839 if (mainf && IFFUNC_HASBODY (mainf->type))
1841 fprintf (asmFile, "%s", iComments2);
1842 fprintf (asmFile, "; interrupt vector \n");
1843 fprintf (asmFile, "%s", iComments2);
1844 dbuf_write_and_destroy (&vBuf, asmFile);
1847 /* copy global & static initialisations */
1848 fprintf (asmFile, "%s", iComments2);
1849 fprintf (asmFile, "; global & static initialisations\n");
1850 fprintf (asmFile, "%s", iComments2);
1852 /* Everywhere we generate a reference to the static_name area,
1853 * (which is currently only here), we immediately follow it with a
1854 * definition of the post_static_name area. This guarantees that
1855 * the post_static_name area will immediately follow the static_name
1858 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1859 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1860 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1861 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1863 if (mainf && IFFUNC_HASBODY (mainf->type))
1865 if (port->genInitStartup)
1867 port->genInitStartup (asmFile);
1871 assert (mcs51_like);
1872 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1873 /* if external stack is specified then the
1874 higher order byte of the xdatalocation is
1875 going into P2 and the lower order going into
1877 if (options.useXstack)
1879 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1880 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1881 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1882 (unsigned int) options.xdata_loc & 0xff);
1885 // This should probably be a port option, but I'm being lazy.
1886 // on the 400, the firmware boot loader gives us a valid stack
1887 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1888 if (!TARGET_IS_DS400)
1890 /* initialise the stack pointer. JCF: aslink takes care of the location */
1891 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1894 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1895 fprintf (asmFile, "\tmov\ta,dpl\n");
1896 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1897 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1898 fprintf (asmFile, "__sdcc_init_data:\n");
1900 // if the port can copy the XINIT segment to XISEG
1903 port->genXINIT (asmFile);
1907 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1909 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1911 /* This code is generated in the post-static area.
1912 * This area is guaranteed to follow the static area
1913 * by the ugly shucking and jiving about 20 lines ago.
1915 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1916 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1922 "%s", iComments2, iComments2);
1923 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1924 dbuf_write_and_destroy (&home->oBuf, asmFile);
1926 if (mainf && IFFUNC_HASBODY (mainf->type))
1928 /* entry point @ start of HOME */
1929 fprintf (asmFile, "__sdcc_program_startup:\n");
1931 /* put in jump or call to main */
1932 if (options.mainreturn)
1934 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1935 fprintf (asmFile, ";\treturn from main will return to caller\n");
1939 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1940 fprintf (asmFile, ";\treturn from main will lock up\n");
1941 fprintf (asmFile, "\tsjmp .\n");
1944 /* copy over code */
1945 fprintf (asmFile, "%s", iComments2);
1946 fprintf (asmFile, "; code\n");
1947 fprintf (asmFile, "%s", iComments2);
1948 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1949 dbuf_write_and_destroy (&code->oBuf, asmFile);
1951 if (port->genAssemblerEnd)
1953 port->genAssemblerEnd (asmFile);