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;
711 val = list2val (lilist);
714 if (SPEC_BLEN (lsym->etype) > 8)
716 size += ((SPEC_BLEN (lsym->etype) / 8) +
717 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
722 size = ((SPEC_BLEN (lsym->etype) / 8) +
723 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
726 /* check if the literal value is within bounds */
728 checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
729 !options.lessPedantic)
731 werror (W_LIT_OVERFLOW);
735 i &= (1 << SPEC_BLEN (lsym->etype)) - 1;
736 i <<= SPEC_BSTR (lsym->etype);
739 (IS_BITFIELD (lsym->next->type)) &&
740 (SPEC_BSTR (lsym->next->etype))))
743 lilist = lilist ? lilist->next : NULL;
750 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
754 dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
758 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
759 (ival >> 16) & 0xffff, (ival & 0xffff));
766 /*-----------------------------------------------------------------*/
767 /* printIvalStruct - generates initial value for structures */
768 /*-----------------------------------------------------------------*/
770 printIvalStruct (symbol * sym, sym_link * type,
771 initList * ilist, struct dbuf_s * oBuf)
774 initList *iloop = NULL;
776 sflds = SPEC_STRUCT (type)->fields;
779 if (ilist->type != INIT_DEEP) {
780 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
784 iloop = ilist->init.deep;
787 if (SPEC_STRUCT (type)->type == UNION) {
788 printIval (sym, sflds->type, iloop, oBuf);
789 iloop = iloop ? iloop->next : NULL;
791 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
792 if (IS_BITFIELD(sflds->type)) {
793 printIvalBitFields(&sflds, &iloop, oBuf);
795 printIval (sym, sflds->type, iloop, oBuf);
800 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
805 /*-----------------------------------------------------------------*/
806 /* printIvalChar - generates initital value for character array */
807 /*-----------------------------------------------------------------*/
809 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
812 unsigned int size = DCL_ELEM (type);
816 val = list2val (ilist);
817 /* if the value is a character string */
818 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
822 /* we have not been given a size, but now we know it */
823 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
824 /* but first check, if it's a flexible array */
825 if (sym && IS_STRUCT (sym->type))
826 sym->flexArrayLength = size;
828 DCL_ELEM (type) = size;
831 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
839 printChar (oBuf, s, strlen (s) + 1);
843 /*-----------------------------------------------------------------*/
844 /* printIvalArray - generates code for array initialization */
845 /*-----------------------------------------------------------------*/
847 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
848 struct dbuf_s * oBuf)
852 unsigned int size = 0;
855 /* take care of the special case */
856 /* array of characters can be init */
858 if (IS_CHAR (type->next)) {
859 val = list2val(ilist);
861 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
864 if (!IS_LITERAL(val->etype)) {
865 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
868 if (printIvalChar (sym, type,
869 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
870 oBuf, SPEC_CVAL (sym->etype).v_char))
873 /* not the special case */
874 if (ilist->type != INIT_DEEP) {
875 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
879 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
880 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
881 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
884 printIval (sym, type->next, iloop, oBuf);
888 if (DCL_ELEM(type)) {
889 // pad with zeros if needed
890 if (size<DCL_ELEM(type)) {
891 size = (DCL_ELEM(type) - size) * getSize(type->next);
893 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
897 /* we have not been given a size, but now we know it */
898 /* but first check, if it's a flexible array */
899 if (IS_STRUCT (sym->type))
900 sym->flexArrayLength = size * getSize (type->next);
902 DCL_ELEM (type) = size;
908 /*-----------------------------------------------------------------*/
909 /* printIvalFuncPtr - generate initial value for function pointers */
910 /*-----------------------------------------------------------------*/
912 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
918 val = list2val (ilist);
920 val = valCastLiteral(type, 0.0);
923 // an error has been thrown already
924 val = constCharVal (0);
927 if (IS_LITERAL(val->etype)) {
928 if (compareType(type, val->etype) == 0) {
929 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
930 printFromToType (val->type, type);
932 printIvalCharPtr (NULL, type, val, oBuf);
936 /* check the types */
937 if ((dLvl = compareType (val->type, type->next)) <= 0)
939 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
943 /* now generate the name */
946 if (port->use_dw_for_init)
948 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
952 printPointerType (oBuf, val->name);
955 else if (port->use_dw_for_init)
957 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
961 printPointerType (oBuf, val->sym->rname);
967 /*-----------------------------------------------------------------*/
968 /* printIvalCharPtr - generates initial values for character pointers */
969 /*-----------------------------------------------------------------*/
971 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
975 /* PENDING: this is _very_ mcs51 specific, including a magic
977 It's also endian specific.
979 size = getSize (type);
981 if (val->name && strlen (val->name))
983 if (size == 1) /* This appears to be Z80 specific?? */
986 "\t!dbs\n", val->name);
988 else if (size == FPTRSIZE)
990 if (port->use_dw_for_init)
992 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
996 printPointerType (oBuf, val->name);
999 else if (size == GPTRSIZE)
1002 if (IS_PTR (val->type)) {
1003 type = DCL_TYPE (val->type);
1005 type = PTR_TYPE (SPEC_OCLS (val->etype));
1007 if (val->sym && val->sym->isstrlit) {
1008 // this is a literal string
1011 printGPointerType (oBuf, val->name, sym->name, type);
1015 fprintf (stderr, "*** internal error: unknown size in "
1016 "printIvalCharPtr.\n");
1021 // these are literals assigned to pointers
1025 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
1028 if (port->use_dw_for_init)
1029 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
1030 else if (port->little_endian)
1031 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1032 aopLiteral (val, 0), aopLiteral (val, 1));
1034 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1035 aopLiteral (val, 1), aopLiteral (val, 0));
1038 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1039 // non-zero mcs51 generic pointer
1040 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1042 if (port->little_endian) {
1043 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1044 aopLiteral (val, 0),
1045 aopLiteral (val, 1),
1046 aopLiteral (val, 2));
1048 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1049 aopLiteral (val, 2),
1050 aopLiteral (val, 1),
1051 aopLiteral (val, 0));
1055 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1056 // non-zero ds390 generic pointer
1057 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1059 if (port->little_endian) {
1060 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1061 aopLiteral (val, 0),
1062 aopLiteral (val, 1),
1063 aopLiteral (val, 2),
1064 aopLiteral (val, 3));
1066 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1067 aopLiteral (val, 3),
1068 aopLiteral (val, 2),
1069 aopLiteral (val, 1),
1070 aopLiteral (val, 0));
1078 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1079 addSet (&statsg->syms, val->sym);
1085 /*-----------------------------------------------------------------*/
1086 /* printIvalPtr - generates initial value for pointers */
1087 /*-----------------------------------------------------------------*/
1089 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1095 if (ilist && (ilist->type == INIT_DEEP))
1096 ilist = ilist->init.deep;
1098 /* function pointer */
1099 if (IS_FUNC (type->next))
1101 printIvalFuncPtr (type, ilist, oBuf);
1105 if (!(val = initPointer (ilist, type)))
1108 /* if character pointer */
1109 if (IS_CHAR (type->next))
1110 if (printIvalCharPtr (sym, type, val, oBuf))
1113 /* check the type */
1114 if (compareType (type, val->type) == 0) {
1115 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1116 printFromToType (val->type, type);
1119 /* if val is literal */
1120 if (IS_LITERAL (val->etype))
1122 switch (getSize (type))
1125 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1128 if (port->use_dw_for_init)
1129 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1130 else if (port->little_endian)
1131 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1133 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1135 case 3: // how about '390??
1136 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1137 if (port->little_endian)
1139 dbuf_printf (oBuf, "\t.byte %s,%s",
1140 aopLiteral (val, 0), aopLiteral (val, 1));
1144 dbuf_printf (oBuf, "\t.byte %s,%s",
1145 aopLiteral (val, 1), aopLiteral (val, 0));
1147 if (IS_GENPTR (val->type))
1148 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1149 else if (IS_PTR (val->type))
1150 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1152 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1158 size = getSize (type);
1160 if (size == 1) /* Z80 specific?? */
1162 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1164 else if (size == FPTRSIZE)
1166 if (port->use_dw_for_init) {
1167 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1169 printPointerType (oBuf, val->name);
1172 else if (size == GPTRSIZE)
1174 printGPointerType (oBuf, val->name, sym->name,
1175 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1176 PTR_TYPE (SPEC_OCLS (val->etype))));
1181 /*-----------------------------------------------------------------*/
1182 /* printIval - generates code for initial value */
1183 /*-----------------------------------------------------------------*/
1185 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1189 /* if structure then */
1190 if (IS_STRUCT (type))
1192 printIvalStruct (sym, type, ilist, oBuf);
1196 /* if this is an array */
1197 if (IS_ARRAY (type))
1199 printIvalArray (sym, type, ilist, oBuf);
1205 // not an aggregate, ilist must be a node
1206 if (ilist->type!=INIT_NODE) {
1207 // or a 1-element list
1208 if (ilist->init.deep->next) {
1209 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1212 ilist=ilist->init.deep;
1216 // and the type must match
1217 itype=ilist->init.node->ftype;
1219 if (compareType(type, itype)==0) {
1220 // special case for literal strings
1221 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1222 // which are really code pointers
1223 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1226 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1227 printFromToType(itype, type);
1232 /* if this is a pointer */
1235 printIvalPtr (sym, type, ilist, oBuf);
1239 /* if type is SPECIFIER */
1242 printIvalType (sym, type, ilist, oBuf);
1247 /*-----------------------------------------------------------------*/
1248 /* emitStaticSeg - emitcode for the static segment */
1249 /*-----------------------------------------------------------------*/
1251 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1255 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1257 /* for all variables in this segment do */
1258 for (sym = setFirstItem (map->syms); sym;
1259 sym = setNextItem (map->syms))
1262 /* if it is "extern" then do nothing */
1263 if (IS_EXTERN (sym->etype))
1266 /* if it is not static add it to the public table */
1267 if (!IS_STATIC (sym->etype))
1269 addSetHead (&publics, sym);
1272 /* print extra debug info if required */
1277 if (IS_STATIC (sym->etype))
1278 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1280 dbuf_printf (oBuf, "G$"); /* scope is global */
1284 /* symbol is local */
1285 dbuf_printf (oBuf, "L%s$",
1286 (sym->localof ? sym->localof->name : "-null-"));
1288 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1291 /* if it has an absolute address and no initializer */
1292 if (SPEC_ABSA (sym->etype) && !sym->ival)
1295 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1297 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1299 SPEC_ADDR (sym->etype));
1304 dbuf_printf (oBuf, " == .\n");
1306 /* if it has an initial value */
1309 if (SPEC_ABSA (sym->etype))
1311 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1313 dbuf_printf (oBuf, "%s:\n", sym->rname);
1315 resolveIvalSym (sym->ival, sym->type);
1316 printIval (sym, sym->type, sym->ival, oBuf);
1318 /* if sym is a simple string and sym->ival is a string,
1319 WE don't need it anymore */
1320 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1321 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1322 list2val(sym->ival)->sym->isstrlit) {
1323 freeStringSymbol(list2val(sym->ival)->sym);
1327 /* allocate space */
1328 int size = getSize (sym->type);
1331 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1333 dbuf_printf (oBuf, "%s:\n", sym->rname);
1334 /* special case for character strings */
1335 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1336 SPEC_CVAL (sym->etype).v_char)
1338 SPEC_CVAL (sym->etype).v_char,
1341 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1347 /*-----------------------------------------------------------------*/
1348 /* emitMaps - emits the code for the data portion the code */
1349 /*-----------------------------------------------------------------*/
1353 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1354 /* ports but let's be conservative - EEP */
1357 /* no special considerations for the following
1358 data, idata & bit & xdata */
1359 emitRegularMap (data, TRUE, TRUE);
1360 emitRegularMap (idata, TRUE, TRUE);
1361 emitRegularMap (d_abs, TRUE, TRUE);
1362 emitRegularMap (i_abs, TRUE, TRUE);
1363 emitRegularMap (bit, TRUE, TRUE);
1364 emitRegularMap (pdata, TRUE, TRUE);
1365 emitRegularMap (xdata, TRUE, TRUE);
1366 emitRegularMap (x_abs, TRUE, TRUE);
1367 if (port->genXINIT) {
1368 emitRegularMap (xidata, TRUE, TRUE);
1370 emitRegularMap (sfr, publicsfr, FALSE);
1371 emitRegularMap (sfrbit, publicsfr, FALSE);
1372 emitRegularMap (home, TRUE, FALSE);
1373 emitRegularMap (code, TRUE, FALSE);
1375 if (options.const_seg) {
1376 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1378 emitStaticSeg (statsg, &code->oBuf);
1379 if (port->genXINIT) {
1380 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1381 emitStaticSeg (xinit, &code->oBuf);
1383 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1384 emitStaticSeg (c_abs, &code->oBuf);
1388 /*-----------------------------------------------------------------*/
1389 /* flushStatics - flush all currently defined statics out to file */
1390 /* and delete. Temporary function */
1391 /*-----------------------------------------------------------------*/
1395 emitStaticSeg (statsg, codeOutBuf);
1396 statsg->syms = NULL;
1399 /*-----------------------------------------------------------------*/
1400 /* createInterruptVect - creates the interrupt vector */
1401 /*-----------------------------------------------------------------*/
1403 createInterruptVect (struct dbuf_s *vBuf)
1405 mainf = newSymbol ("main", 0);
1408 /* only if the main function exists */
1409 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1411 if (!options.cc_only && !noAssemble && !options.c1mode)
1416 /* if the main is only a prototype ie. no body then do nothing */
1417 if (!IFFUNC_HASBODY(mainf->type))
1419 /* if ! compile only then main function should be present */
1420 if (!options.cc_only && !noAssemble)
1425 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1426 dbuf_printf (vBuf, "__interrupt_vect:\n");
1429 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1431 /* There's no such thing as a "generic" interrupt table header. */
1438 ";--------------------------------------------------------\n"
1439 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1443 ";--------------------------------------------------------\n"};
1446 /*-----------------------------------------------------------------*/
1447 /* initialComments - puts in some initial comments */
1448 /*-----------------------------------------------------------------*/
1450 initialComments (FILE * afile)
1454 fprintf (afile, "%s", iComments1);
1455 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1456 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1457 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1458 fprintf (afile, "%s", iComments2);
1461 /*-----------------------------------------------------------------*/
1462 /* printPublics - generates .global for publics */
1463 /*-----------------------------------------------------------------*/
1465 printPublics (FILE * afile)
1469 fprintf (afile, "%s", iComments2);
1470 fprintf (afile, "; Public variables in this module\n");
1471 fprintf (afile, "%s", iComments2);
1473 for (sym = setFirstItem (publics); sym;
1474 sym = setNextItem (publics))
1475 tfprintf (afile, "\t!global\n", sym->rname);
1478 /*-----------------------------------------------------------------*/
1479 /* printExterns - generates .global for externs */
1480 /*-----------------------------------------------------------------*/
1482 printExterns (FILE * afile)
1486 fprintf (afile, "%s", iComments2);
1487 fprintf (afile, "; Externals used\n");
1488 fprintf (afile, "%s", iComments2);
1490 for (sym = setFirstItem (externs); sym;
1491 sym = setNextItem (externs))
1492 tfprintf (afile, "\t!extern\n", sym->rname);
1495 /*-----------------------------------------------------------------*/
1496 /* emitOverlay - will emit code for the overlay stuff */
1497 /*-----------------------------------------------------------------*/
1499 emitOverlay (struct dbuf_s * aBuf)
1503 if (!elementsInSet (ovrSetSets))
1504 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1506 /* for each of the sets in the overlay segment do */
1507 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1508 ovrset = setNextItem (ovrSetSets))
1513 if (elementsInSet (ovrset))
1515 /* output the area informtion */
1516 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1519 for (sym = setFirstItem (ovrset); sym;
1520 sym = setNextItem (ovrset))
1522 /* if extern then it is in the publics table: do nothing */
1523 if (IS_EXTERN (sym->etype))
1526 /* if allocation required check is needed
1527 then check if the symbol really requires
1528 allocation only for local variables */
1529 if (!IS_AGGREGATE (sym->type) &&
1530 !(sym->_isparm && !IS_REGPARM (sym->etype))
1531 && !sym->allocreq && sym->level)
1534 /* if global variable & not static or extern
1535 and addPublics allowed then add it to the public set */
1536 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1537 && !IS_STATIC (sym->etype))
1539 addSetHead (&publics, sym);
1542 /* if extern then do nothing or is a function
1544 if (IS_FUNC (sym->type))
1547 /* print extra debug info if required */
1552 if (IS_STATIC (sym->etype))
1553 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1555 dbuf_printf (aBuf, "G$"); /* scope is global */
1558 /* symbol is local */
1559 dbuf_printf (aBuf, "L%s$",
1560 (sym->localof ? sym->localof->name : "-null-"));
1561 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1564 /* if is has an absolute address then generate
1565 an equate for this no need to allocate space */
1566 if (SPEC_ABSA (sym->etype))
1570 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1572 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1574 SPEC_ADDR (sym->etype));
1578 int size = getSize(sym->type);
1581 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1584 dbuf_printf (aBuf, "==.\n");
1586 /* allocate space */
1587 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1588 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1595 /*-----------------------------------------------------------------*/
1596 /* glue - the final glue that hold the whole thing together */
1597 /*-----------------------------------------------------------------*/
1602 struct dbuf_s ovrBuf;
1606 dbuf_init (&vBuf, 4096);
1607 dbuf_init (&ovrBuf, 4096);
1609 mcs51_like = (port->general.glue_up_main &&
1610 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1612 /* print the global struct definitions */
1616 /* PENDING: this isn't the best place but it will do */
1617 if (port->general.glue_up_main)
1619 /* create the interrupt vector table */
1620 createInterruptVect (&vBuf);
1623 /* emit code for the all the variables declared */
1625 /* do the overlay segments */
1626 emitOverlay (&ovrBuf);
1628 outputDebugSymbols ();
1630 /* now put it all together into the assembler file */
1631 /* create the assembler file name */
1633 /* -o option overrides default name? */
1634 if ((noAssemble || options.c1mode) && fullDstFileName)
1636 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1640 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1641 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1644 if (!(asmFile = fopen (scratchFileName, "w")))
1646 werror (E_FILE_OPEN_ERR, scratchFileName);
1647 exit (EXIT_FAILURE);
1650 /* initial comments */
1651 initialComments (asmFile);
1653 /* print module name */
1654 tfprintf (asmFile, "\t!module\n", moduleName);
1657 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1659 switch(options.model)
1661 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1662 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1663 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1664 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1665 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1666 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1669 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1670 if(options.useXstack) fprintf (asmFile, " --xstack");
1671 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1672 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1673 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1674 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1675 fprintf (asmFile, "\n");
1677 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1679 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1682 tfprintf (asmFile, "\t!fileprelude\n");
1684 /* Let the port generate any global directives, etc. */
1685 if (port->genAssemblerPreamble)
1687 port->genAssemblerPreamble (asmFile);
1690 /* print the global variables in this module */
1691 printPublics (asmFile);
1692 if (port->assembler.externGlobal)
1693 printExterns (asmFile);
1696 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1698 /* copy the sfr segment */
1699 fprintf (asmFile, "%s", iComments2);
1700 fprintf (asmFile, "; special function registers\n");
1701 fprintf (asmFile, "%s", iComments2);
1702 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1707 /* copy the sbit segment */
1708 fprintf (asmFile, "%s", iComments2);
1709 fprintf (asmFile, "; special function bits\n");
1710 fprintf (asmFile, "%s", iComments2);
1711 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1713 /*JCF: Create the areas for the register banks*/
1714 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1716 fprintf (asmFile, "%s", iComments2);
1717 fprintf (asmFile, "; overlayable register banks\n");
1718 fprintf (asmFile, "%s", iComments2);
1720 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1721 if (RegBankUsed[1] || options.parms_in_bank1)
1722 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1724 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1726 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1730 fprintf (asmFile, "%s", iComments2);
1731 fprintf (asmFile, "; overlayable bit register bank\n");
1732 fprintf (asmFile, "%s", iComments2);
1733 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1734 fprintf (asmFile, "bits:\n\t.ds 1\n");
1735 fprintf (asmFile, "\tb0 = bits[0]\n");
1736 fprintf (asmFile, "\tb1 = bits[1]\n");
1737 fprintf (asmFile, "\tb2 = bits[2]\n");
1738 fprintf (asmFile, "\tb3 = bits[3]\n");
1739 fprintf (asmFile, "\tb4 = bits[4]\n");
1740 fprintf (asmFile, "\tb5 = bits[5]\n");
1741 fprintf (asmFile, "\tb6 = bits[6]\n");
1742 fprintf (asmFile, "\tb7 = bits[7]\n");
1746 /* copy the data segment */
1747 fprintf (asmFile, "%s", iComments2);
1748 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1749 fprintf (asmFile, "%s", iComments2);
1750 dbuf_write_and_destroy (&data->oBuf, asmFile);
1753 /* create the overlay segments */
1756 fprintf (asmFile, "%s", iComments2);
1757 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1758 fprintf (asmFile, "%s", iComments2);
1759 dbuf_write_and_destroy (&ovrBuf, asmFile);
1762 /* create the stack segment MOF */
1763 if (mainf && IFFUNC_HASBODY (mainf->type))
1765 fprintf (asmFile, "%s", iComments2);
1766 fprintf (asmFile, "; Stack segment in internal ram \n");
1767 fprintf (asmFile, "%s", iComments2);
1768 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1769 "__start__stack:\n\t.ds\t1\n\n");
1772 /* create the idata segment */
1773 if ((idata) && (mcs51_like))
1775 fprintf (asmFile, "%s", iComments2);
1776 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1777 fprintf (asmFile, "%s", iComments2);
1778 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1781 /* create the absolute idata/data segment */
1782 if ((i_abs) && (mcs51_like))
1784 fprintf (asmFile, "%s", iComments2);
1785 fprintf (asmFile, "; absolute internal ram data\n");
1786 fprintf (asmFile, "%s", iComments2);
1787 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1788 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1791 /* copy the bit segment */
1794 fprintf (asmFile, "%s", iComments2);
1795 fprintf (asmFile, "; bit data\n");
1796 fprintf (asmFile, "%s", iComments2);
1797 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1800 /* copy paged external ram data */
1803 fprintf (asmFile, "%s", iComments2);
1804 fprintf (asmFile, "; paged external ram data\n");
1805 fprintf (asmFile, "%s", iComments2);
1806 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1809 /* if external stack then reserve space for it */
1810 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1812 fprintf (asmFile, "%s", iComments2);
1813 fprintf (asmFile, "; external stack \n");
1814 fprintf (asmFile, "%s", iComments2);
1815 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1816 "__start__xstack:\n\t.ds\t1\n\n");
1819 /* copy external ram data */
1822 fprintf (asmFile, "%s", iComments2);
1823 fprintf (asmFile, "; external ram data\n");
1824 fprintf (asmFile, "%s", iComments2);
1825 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1828 /* create the absolute xdata segment */
1829 if (mcs51_like || TARGET_IS_HC08)
1831 fprintf (asmFile, "%s", iComments2);
1832 fprintf (asmFile, "; absolute external ram data\n");
1833 fprintf (asmFile, "%s", iComments2);
1834 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1837 /* copy external initialized ram data */
1838 fprintf (asmFile, "%s", iComments2);
1839 fprintf (asmFile, "; external initialized ram data\n");
1840 fprintf (asmFile, "%s", iComments2);
1841 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1843 /* If the port wants to generate any extra areas, let it do so. */
1844 if (port->extraAreas.genExtraAreaDeclaration)
1846 port->extraAreas.genExtraAreaDeclaration(asmFile,
1847 mainf && IFFUNC_HASBODY(mainf->type));
1850 /* copy the interrupt vector table */
1851 if (mainf && IFFUNC_HASBODY (mainf->type))
1853 fprintf (asmFile, "%s", iComments2);
1854 fprintf (asmFile, "; interrupt vector \n");
1855 fprintf (asmFile, "%s", iComments2);
1856 dbuf_write_and_destroy (&vBuf, asmFile);
1859 /* copy global & static initialisations */
1860 fprintf (asmFile, "%s", iComments2);
1861 fprintf (asmFile, "; global & static initialisations\n");
1862 fprintf (asmFile, "%s", iComments2);
1864 /* Everywhere we generate a reference to the static_name area,
1865 * (which is currently only here), we immediately follow it with a
1866 * definition of the post_static_name area. This guarantees that
1867 * the post_static_name area will immediately follow the static_name
1870 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1871 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1872 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1873 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1875 if (mainf && IFFUNC_HASBODY (mainf->type))
1877 if (port->genInitStartup)
1879 port->genInitStartup (asmFile);
1883 assert (mcs51_like);
1884 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1885 /* if external stack is specified then the
1886 higher order byte of the xdatalocation is
1887 going into P2 and the lower order going into
1889 if (options.useXstack)
1891 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1892 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1893 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1894 (unsigned int) options.xdata_loc & 0xff);
1897 // This should probably be a port option, but I'm being lazy.
1898 // on the 400, the firmware boot loader gives us a valid stack
1899 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1900 if (!TARGET_IS_DS400)
1902 /* initialise the stack pointer. JCF: aslink takes care of the location */
1903 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1906 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1907 fprintf (asmFile, "\tmov\ta,dpl\n");
1908 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1909 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1910 fprintf (asmFile, "__sdcc_init_data:\n");
1912 // if the port can copy the XINIT segment to XISEG
1915 port->genXINIT (asmFile);
1919 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1921 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1923 /* This code is generated in the post-static area.
1924 * This area is guaranteed to follow the static area
1925 * by the ugly shucking and jiving about 20 lines ago.
1927 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1928 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1934 "%s", iComments2, iComments2);
1935 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1936 dbuf_write_and_destroy (&home->oBuf, asmFile);
1938 if (mainf && IFFUNC_HASBODY (mainf->type))
1940 /* entry point @ start of HOME */
1941 fprintf (asmFile, "__sdcc_program_startup:\n");
1943 /* put in jump or call to main */
1944 if (options.mainreturn)
1946 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1947 fprintf (asmFile, ";\treturn from main will return to caller\n");
1951 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1952 fprintf (asmFile, ";\treturn from main will lock up\n");
1953 fprintf (asmFile, "\tsjmp .\n");
1956 /* copy over code */
1957 fprintf (asmFile, "%s", iComments2);
1958 fprintf (asmFile, "; code\n");
1959 fprintf (asmFile, "%s", iComments2);
1960 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1961 dbuf_write_and_destroy (&code->oBuf, asmFile);
1963 if (port->genAssemblerEnd)
1965 port->genAssemblerEnd (asmFile);