1 /*-------------------------------------------------------------------------
3 glue.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 -------------------------------------------------------------------------*/
25 #include "../common.h"
38 #ifdef WORDS_BIGENDIAN
39 #define _ENDIAN(x) (3-x)
41 #define _ENDIAN(x) (x)
44 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
46 extern symbol *interrupts[256];
47 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
51 extern unsigned maxInterrupts;
52 extern int maxRegBank;
54 extern char *VersionString;
55 extern FILE *codeOutFile;
56 extern set *tmpfileSet;
57 extern set *tmpfileNameSet;
58 extern char *iComments1;
59 extern char *iComments2;
60 //extern void emitStaticSeg (memmap * map);
64 set *rel_idataSymSet=NULL;
65 set *fix_idataSymSet=NULL;
67 extern DEFSETFUNC (closeTmpFiles);
68 extern DEFSETFUNC (rmTmpFiles);
70 extern void pic16_AnalyzeBanking (void);
71 extern void copyFile (FILE * dest, FILE * src);
72 extern void pic16_InlinepCode(void);
73 extern void pic16_writeUsedRegs(FILE *);
75 extern void initialComments (FILE * afile);
76 extern void printPublics (FILE * afile);
78 void pic16_pCodeInitRegisters(void);
79 pCodeOp *pic16_popGetLit(unsigned int lit);
80 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
81 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
82 extern void pic16_pCodeConstString(char *name, char *value);
84 /*-----------------------------------------------------------------*/
85 /* aopLiteral - string from a literal value */
86 /*-----------------------------------------------------------------*/
87 int pic16aopLiteral (value *val, int offset)
94 /* if it is a float then it gets tricky */
95 /* otherwise it is fairly simple */
96 if (!IS_FLOAT(val->type)) {
97 unsigned long v = (unsigned long) floatFromVal(val);
99 return ( (v >> (offset * 8)) & 0xff);
102 /* it is type float */
103 fl.f = (float) floatFromVal(val);
104 #ifdef WORDS_BIGENDIAN
105 return fl.c[3-offset];
114 char tbuffer[512], *tbuf=tbuffer;;
117 /*-----------------------------------------------------------------*/
118 /* emitRegularMap - emit code for maps with no special cases */
119 /*-----------------------------------------------------------------*/
121 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
124 // int i, size, bitvars = 0;;
126 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
129 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
130 /* print the area name */
132 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
135 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\n",
137 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
138 IS_AGGREGATE(sym->type));
139 printTypeChain( sym->type, stderr );
140 fprintf(stderr, "\n");
143 // if(PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
147 /* if extern then add to externs */
148 if (IS_EXTERN (sym->etype)) {
149 checkAddSym(&externs, sym);
153 /* if allocation required check is needed
154 * then check if the symbol really requires
155 * allocation only for local variables */
156 if (arFlag && !IS_AGGREGATE (sym->type) &&
157 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
158 !sym->allocreq && sym->level) {
160 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
165 /* if global variable & not static or extern
166 * and addPublics allowed then add it to the public set */
167 if ((sym->used) && (sym->level == 0 ||
168 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
170 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
172 checkAddSym(&publics, sym);
174 if(IS_STATIC(sym->etype)
175 && !(sym->ival && !sym->level)
178 /* add it to udata list */
180 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
181 // sym->name, sym->rname, sym->remat);
183 //, OP_SYMBOL(operandFromSymbol(sym))->name);
184 #define SET_IMPLICIT 1
187 if(IS_STRUCT(sym->type))
191 reg = pic16_allocDirReg( operandFromSymbol( sym ));
192 // addSet(&pic16_dynAllocRegs, reg);
198 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
199 if(!strcmp(ssym->name, reg->name))found=1;
202 if(!found)checkAddReg(&pic16_rel_udata, reg);
206 /* if extern then do nothing or is a function
208 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
209 if(SPEC_OCLS(sym->etype) == code) {
210 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
211 checkAddSym(&publics, sym);
217 /* print extra debug info if required */
218 if (options.debug || sym->level == 0) {
219 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
221 if (!sym->level) /* global */
222 if (IS_STATIC (sym->etype))
223 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
225 fprintf (map->oFile, "G_"); /* scope is global */
227 /* symbol is local */
228 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
229 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
234 /* if is has an absolute address then generate
235 an equate for this no need to allocate space */
236 if (SPEC_ABSA (sym->etype)) {
237 // if (options.debug || sym->level == 0)
238 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
239 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
241 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
243 SPEC_ADDR (sym->etype));
245 /* emit only if it is global */
246 if(sym->level == 0) {
249 reg = pic16_dirregWithName( sym->name );
252 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
253 // __FUNCTION__, __LINE__, sym->name);
255 /* if IS_STRUCT is omitted the following
256 * fixes structures but break char/int etc */
258 if(IS_STRUCT(sym->type))
259 sym->implicit = 1; // mark as implicit
262 reg = pic16_allocDirReg( operandFromSymbol(sym) );
264 if(checkAddReg(&pic16_fix_udata, reg)) {
265 /* and add to globals list if not exist */
266 addSet(&publics, sym);
270 addSet(&publics, sym);
274 if(!sym->used && (sym->level == 0)) {
277 /* symbol not used, just declared probably, but its in
278 * level 0, so we must declare it fine as global */
280 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
283 if(IS_STRUCT(sym->type))
284 sym->implicit = 1; // mark as implicit
287 if(IS_AGGREGATE(sym->type)) {
288 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
290 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
297 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
298 if(!strcmp(ssym->name, reg->name))found=1;
302 if(checkAddReg(&pic16_rel_udata, reg)) {
303 addSetHead(&publics, sym);
312 addSetHead(&publics, sym);
317 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
318 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
319 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
320 if (IS_BITVAR (sym->etype)) {
323 fprintf (map->oFile, "\t%s\n", sym->rname);
324 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
325 for (i = 1; i < size; i++)
326 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
329 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
333 /* FIXME -- VR Fix the following, so that syms to be placed
334 * in the idata section and let linker decide about their fate */
336 /* if it has an initial value then do it only if
337 it is a global variable */
339 if (sym->ival && sym->level == 0) {
343 if(SPEC_OCLS(sym->etype)==data) {
344 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
347 if(SPEC_OCLS(sym->etype)==code) {
348 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
353 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
354 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
357 if (IS_AGGREGATE (sym->type)) {
358 if(SPEC_ABSA(sym->etype))
359 addSet(&fix_idataSymSet, copySymbol(sym));
361 addSet(&rel_idataSymSet, copySymbol(sym));
362 // ival = initAggregates (sym, sym->ival, NULL);
364 if(SPEC_ABSA(sym->etype))
365 addSet(&fix_idataSymSet, copySymbol(sym));
367 addSet(&rel_idataSymSet, copySymbol(sym));
369 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
370 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
374 setAstLineno(ival, sym->lineDef);
375 codeOutFile = statsg->oFile;
377 eBBlockFromiCode (iCodeFromAst (ival));
385 /*-----------------------------------------------------------------*/
386 /* pic16_initPointer - pointer initialization code massaging */
387 /*-----------------------------------------------------------------*/
388 value *pic16_initPointer (initList * ilist, sym_link *toType)
394 return valCastLiteral(toType, 0.0);
397 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
398 // expr = list2expr( ilist );
403 /* try it the old way first */
404 if ((val = constExprValue (expr, FALSE)))
407 /* ( ptr + constant ) */
408 if (IS_AST_OP (expr) &&
409 (expr->opval.op == '+' || expr->opval.op == '-') &&
410 IS_AST_SYM_VALUE (expr->left) &&
411 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
412 compareType(toType, expr->left->ftype) &&
413 IS_AST_LIT_VALUE (expr->right)) {
414 return valForCastAggr (expr->left, expr->left->ftype,
420 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
421 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
422 if (compareType(toType, expr->left->ftype)!=1) {
423 werror (W_INIT_WRONG);
424 printFromToType(expr->left->ftype, toType);
430 /* no then we have to do these cludgy checks */
431 /* pointers can be initialized with address of
432 a variable or address of an array element */
433 if (IS_AST_OP (expr) && expr->opval.op == '&') {
434 /* address of symbol */
435 if (IS_AST_SYM_VALUE (expr->left)) {
436 val = copyValue (AST_VALUE (expr->left));
437 val->type = newLink (DECLARATOR);
438 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
439 DCL_TYPE (val->type) = CPOINTER;
440 DCL_PTR_CONST (val->type) = port->mem.code_ro;
442 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
443 DCL_TYPE (val->type) = FPOINTER;
444 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
445 DCL_TYPE (val->type) = PPOINTER;
446 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
447 DCL_TYPE (val->type) = IPOINTER;
448 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
449 DCL_TYPE (val->type) = EEPPOINTER;
451 DCL_TYPE (val->type) = POINTER;
453 val->type->next = expr->left->ftype;
454 val->etype = getSpec (val->type);
458 /* if address of indexed array */
459 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
460 return valForArray (expr->left);
462 /* if address of structure element then
464 if (IS_AST_OP (expr->left) &&
465 expr->left->opval.op == '.') {
466 return valForStructElem (expr->left->left,
471 (&some_struct)->element */
472 if (IS_AST_OP (expr->left) &&
473 expr->left->opval.op == PTR_OP &&
474 IS_ADDRESS_OF_OP (expr->left->left)) {
475 return valForStructElem (expr->left->left->left,
479 /* case 3. (((char *) &a) +/- constant) */
480 if (IS_AST_OP (expr) &&
481 (expr->opval.op == '+' || expr->opval.op == '-') &&
482 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
483 IS_AST_OP (expr->left->right) &&
484 expr->left->right->opval.op == '&' &&
485 IS_AST_LIT_VALUE (expr->right)) {
487 return valForCastAggr (expr->left->right->left,
488 expr->left->left->opval.lnk,
489 expr->right, expr->opval.op);
492 /* case 4. (char *)(array type) */
493 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
494 IS_ARRAY(expr->right->ftype)) {
496 val = copyValue (AST_VALUE (expr->right));
497 val->type = newLink (DECLARATOR);
498 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
499 DCL_TYPE (val->type) = CPOINTER;
500 DCL_PTR_CONST (val->type) = port->mem.code_ro;
502 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
503 DCL_TYPE (val->type) = FPOINTER;
504 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
505 DCL_TYPE (val->type) = PPOINTER;
506 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
507 DCL_TYPE (val->type) = IPOINTER;
508 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
509 DCL_TYPE (val->type) = EEPPOINTER;
511 DCL_TYPE (val->type) = POINTER;
512 val->type->next = expr->right->ftype->next;
513 val->etype = getSpec (val->type);
519 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
521 werror (E_INCOMPAT_PTYPES);
527 /*-----------------------------------------------------------------*/
528 /* printPointerType - generates ival for pointer type */
529 /*-----------------------------------------------------------------*/
530 void _pic16_printPointerType (const char *name, char ptype, void *p)
534 sprintf(buf, "LOW(%s)", name);
535 pic16_emitDS(buf, ptype, p);
536 sprintf(buf, "HIGH(%s)", name);
537 pic16_emitDS(buf, ptype, p);
540 /*-----------------------------------------------------------------*/
541 /* printPointerType - generates ival for pointer type */
542 /*-----------------------------------------------------------------*/
543 void pic16_printPointerType (const char *name, char ptype, void *p)
545 _pic16_printPointerType (name, ptype, p);
546 pic16_flushDB(ptype, p);
549 /*-----------------------------------------------------------------*/
550 /* printGPointerType - generates ival for generic pointer type */
551 /*-----------------------------------------------------------------*/
552 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
553 const unsigned int type, char ptype, void *p)
555 _pic16_printPointerType (iname, ptype, p);
557 if(itype == FPOINTER || itype == CPOINTER) { // || itype == GPOINTER) {
560 sprintf(buf, "UPPER(%s)", iname);
561 pic16_emitDS(buf, ptype, p);
564 pic16_flushDB(ptype, p);
569 /*-----------------------------------------------------------------*/
570 /* pic16_printIvalType - generates ival for int/char */
571 /*-----------------------------------------------------------------*/
573 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
578 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
580 /* if initList is deep */
581 if (ilist && ilist->type == INIT_DEEP)
582 ilist = ilist->init.deep;
584 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
585 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
588 if (!(val = list2val (ilist))) {
589 // assuming a warning has been thrown
593 if (val->type != type) {
594 val = valCastLiteral(type, floatFromVal(val));
598 ulval = (unsigned long) floatFromVal (val);
602 switch (getSize (type)) {
604 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
608 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
609 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
613 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
614 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
615 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
616 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
621 /*--------------------------------------------------------------------*/
622 /* pic16_printIvalChar - generates initital value for character array */
623 /*--------------------------------------------------------------------*/
625 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
634 // fprintf(stderr, "%s\n",__FUNCTION__);
638 val = list2val (ilist);
639 /* if the value is a character string */
640 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
642 if (!DCL_ELEM (type))
643 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
645 for(remain=0; remain<DCL_ELEM(type); remain++)
646 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
648 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
650 pic16_emitDB(0x00, ptype, p);
659 for(remain=0; remain<strlen(s); remain++) {
660 pic16_emitDB(s[remain], ptype, p);
666 /*-----------------------------------------------------------------*/
667 /* pic16_printIvalArray - generates code for array initialization */
668 /*-----------------------------------------------------------------*/
670 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
674 int lcnt = 0, size = 0;
680 /* take care of the special case */
681 /* array of characters can be init */
683 if (IS_CHAR (type->next)) {
684 if (!IS_LITERAL(list2val(ilist)->etype)) {
685 werror (W_INIT_WRONG);
689 if(pic16_printIvalChar (type,
690 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
691 SPEC_CVAL (sym->etype).v_char, ptype, p))
694 /* not the special case */
695 if (ilist && ilist->type != INIT_DEEP)
697 werror (E_INIT_STRUCT, sym->name);
701 iloop = ilist->init.deep;
702 lcnt = DCL_ELEM (type);
707 pic16_printIval (sym, type->next, iloop, ptype, p);
708 iloop = (iloop ? iloop->next : NULL);
711 /* if not array limits given & we */
712 /* are out of initialisers then */
713 if (!DCL_ELEM (type) && !iloop)
716 /* no of elements given and we */
717 /* have generated for all of them */
719 /* if initializers left */
721 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
727 /* if we have not been given a size */
728 if (!DCL_ELEM (type))
729 DCL_ELEM (type) = size;
734 /*-----------------------------------------------------------------*/
735 /* pic16_printIvalBitFields - generate initializer for bitfields */
736 /*-----------------------------------------------------------------*/
737 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
741 initList *lilist = *ilist ;
742 unsigned long ival = 0;
748 val = list2val(lilist);
750 if (SPEC_BLEN(lsym->etype) > 8) {
751 size += ((SPEC_BLEN (lsym->etype) / 8) +
752 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
755 size = ((SPEC_BLEN (lsym->etype) / 8) +
756 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
758 i = (unsigned long)floatFromVal(val);
759 i <<= SPEC_BSTR (lsym->etype);
761 if (! ( lsym->next &&
762 (IS_BITFIELD(lsym->next->type)) &&
763 (SPEC_BSTR(lsym->next->etype)))) break;
765 lilist = lilist->next;
769 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
773 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
774 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
777 case 4: /* EEP: why is this db and not dw? */
778 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
779 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
780 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
781 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
784 /* VR - only 1,2,4 size long can be handled???? Why? */
785 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
793 /*-----------------------------------------------------------------*/
794 /* printIvalStruct - generates initial value for structures */
795 /*-----------------------------------------------------------------*/
796 void pic16_printIvalStruct (symbol * sym, sym_link * type,
797 initList * ilist, char ptype, void *p)
800 initList *iloop = NULL;
802 sflds = SPEC_STRUCT (type)->fields;
805 if (ilist->type != INIT_DEEP) {
806 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
810 iloop = ilist->init.deep;
813 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
814 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
815 if (IS_BITFIELD(sflds->type)) {
816 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
818 pic16_printIval (sym, sflds->type, iloop, ptype, p);
822 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
827 /*--------------------------------------------------------------------------*/
828 /* pic16_printIvalCharPtr - generates initial values for character pointers */
829 /*--------------------------------------------------------------------------*/
830 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
834 /* PENDING: this is _very_ mcs51 specific, including a magic
836 It's also endin specific.
838 VR - Attempting to port this function to pic16 port - 8-Jun-2004
841 // fprintf(stderr, "%s\n",__FUNCTION__);
843 size = getSize (type);
845 if (val->name && strlen (val->name))
847 if (size == 1) /* This appears to be Z80 specific?? */
849 pic16_emitDS(val->name, ptype, p);
853 pic16_printPointerType (val->name, ptype, p);
858 if (IS_PTR (val->type)) {
859 type = DCL_TYPE (val->type);
861 type = PTR_TYPE (SPEC_OCLS (val->etype));
863 if (val->sym && val->sym->isstrlit) {
864 // this is a literal string
867 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
871 fprintf (stderr, "*** internal error: unknown size in "
872 "printIvalCharPtr.\n");
878 // these are literals assigned to pointers
882 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
885 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
886 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
889 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
890 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
891 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
899 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
900 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
901 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
907 /*-----------------------------------------------------------------------*/
908 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
909 /*-----------------------------------------------------------------------*/
910 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
916 val = list2val (ilist);
918 val = valCastLiteral(type, 0.0);
921 // an error has been thrown already
925 if (IS_LITERAL(val->etype)) {
926 if (compareType(type, val->etype) == 0) {
927 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
928 printFromToType (val->type, type);
930 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
934 /* check the types */
935 if ((dLvl = compareType (val->type, type->next)) <= 0)
937 pic16_emitDB(0x00, ptype, p);
941 /* now generate the name */
943 pic16_printPointerType (val->name, ptype, p);
945 pic16_printPointerType (val->sym->rname, ptype, p);
952 /*-----------------------------------------------------------------*/
953 /* pic16_printIvalPtr - generates initial value for pointers */
954 /*-----------------------------------------------------------------*/
955 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
961 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
962 sym->rname, getSize(sym->type));
966 if (ilist && (ilist->type == INIT_DEEP))
967 ilist = ilist->init.deep;
969 /* function pointer */
970 if (IS_FUNC (type->next))
972 pic16_printIvalFuncPtr (type, ilist, ptype, p);
976 if (!(val = pic16_initPointer (ilist, type)))
979 /* if character pointer */
980 if (IS_CHAR (type->next))
981 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
985 if (compareType (type, val->type) == 0) {
986 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
987 printFromToType (val->type, type);
990 /* if val is literal */
991 if (IS_LITERAL (val->etype))
993 switch (getSize (type))
996 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
999 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1000 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1003 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1004 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1005 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1013 size = getSize (type);
1015 if (size == 1) /* Z80 specific?? */
1017 pic16_emitDS(val->name, ptype, p);
1021 pic16_printPointerType (val->name, ptype, p);
1025 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1026 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1027 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1035 /*-----------------------------------------------------------------*/
1036 /* pic16_printIval - generates code for initial value */
1037 /*-----------------------------------------------------------------*/
1038 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1046 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1047 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1048 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1051 /* if structure then */
1052 if (IS_STRUCT (type))
1054 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1055 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1059 /* if this is an array */
1060 if (IS_ARRAY (type))
1062 // fprintf(stderr,"%s array\n",__FUNCTION__);
1063 pic16_printIvalArray (sym, type, ilist, ptype, p);
1070 // not an aggregate, ilist must be a node
1071 if (ilist->type!=INIT_NODE) {
1072 // or a 1-element list
1073 if (ilist->init.deep->next) {
1074 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1077 ilist=ilist->init.deep;
1082 // and the type must match
1083 itype=ilist->init.node->ftype;
1085 if (compareType(type, itype)==0) {
1086 // special case for literal strings
1087 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1088 // which are really code pointers
1089 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1092 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1093 // printFromToType(itype, type);
1100 /* if this is a pointer */
1103 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1104 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1109 /* if type is SPECIFIER */
1112 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1113 pic16_printIvalType (sym, type, ilist, ptype, p);
1118 int PIC16_IS_CONFIG_ADDRESS(int address)
1121 return (address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd);
1124 /*-----------------------------------------------------------------*/
1125 /* emitStaticSeg - emitcode for the static segment */
1126 /*-----------------------------------------------------------------*/
1128 pic16emitStaticSeg (memmap * map)
1132 //fprintf(stderr, "%s\n",__FUNCTION__);
1136 /* for all variables in this segment do */
1137 for (sym = setFirstItem (map->syms); sym;
1138 sym = setNextItem (map->syms))
1142 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1143 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1144 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1145 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1146 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1147 printTypeChain( sym->type, stderr );
1148 fprintf(stderr, "\n");
1151 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1152 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1153 (int) floatFromVal(list2val(sym->ival)));
1158 /* if it is "extern" then do nothing */
1159 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1160 checkAddSym(&externs, sym);
1164 /* if it is not static add it to the public
1166 if (!IS_STATIC (sym->etype)) {
1167 /* do not emit if it is a config word declaration */
1168 checkAddSym(&publics, sym);
1171 /* print extra debug info if required */
1172 if (options.debug || sym->level == 0) {
1173 /* NOTE to me - cdbFile may be null in which case,
1174 * the sym name will be printed to stdout. oh well */
1175 debugFile->writeSymbol(sym);
1178 /* if it has an absolute address */
1179 if (SPEC_ABSA (sym->etype)) {
1180 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1181 // __FILE__, __LINE__, sym->name);
1183 /* if it has an initial value */
1191 /* symbol has absolute address and initial value */
1193 resolveIvalSym (sym->ival, sym->type);
1194 asym = newSymbol(sym->rname, 0);
1195 abSym = Safe_calloc(1, sizeof(absSym));
1196 abSym->name = Safe_strdup( sym->rname );
1197 abSym->address = SPEC_ADDR( sym->etype );
1198 addSet(&absSymSet, abSym);
1200 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1201 pic16_addpBlock(pb);
1203 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1204 PCF(pcf)->absblock = 1;
1206 pic16_addpCode2pBlock(pb,pcf);
1207 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1208 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1209 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1210 pic16_flushDB('p', (void *)pb);
1212 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1218 /* symbol has absolute address but no initial value */
1220 /* allocate space */
1221 fprintf (code->oFile, "%s:\n", sym->rname);
1223 /* special case for character strings */
1224 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1225 SPEC_CVAL (sym->etype).v_char) {
1227 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1229 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1236 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1237 // __FILE__, __LINE__, sym->name);
1239 /* if it has an initial value */
1243 /* symbol doesn't have absolute address but has initial value */
1244 fprintf (code->oFile, "%s:\n", sym->rname);
1246 resolveIvalSym (sym->ival, sym->type);
1248 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1249 pic16_addpBlock(pb);
1251 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1253 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1254 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1255 pic16_flushDB('p', (void *)pb);
1259 /* symbol doesn't have absolute address and no initial value */
1260 /* allocate space */
1261 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1262 fprintf (code->oFile, "%s:\n", sym->rname);
1263 /* special case for character strings */
1264 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1265 SPEC_CVAL (sym->etype).v_char) {
1267 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1269 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1280 /*-----------------------------------------------------------------*/
1281 /* pic16_emitConfigRegs - emits the configuration registers */
1282 /*-----------------------------------------------------------------*/
1283 void pic16_emitConfigRegs(FILE *of)
1287 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1288 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1289 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1290 pic16->cwInfo.confAddrStart+i,
1291 pic16->cwInfo.crInfo[i].value);
1298 /* no special considerations for the following
1299 data, idata & bit & xdata */
1300 pic16emitRegularMap (data, TRUE, TRUE);
1301 pic16emitRegularMap (idata, TRUE, TRUE);
1302 pic16emitRegularMap (bit, TRUE, FALSE);
1303 pic16emitRegularMap (xdata, TRUE, TRUE);
1304 pic16emitRegularMap (sfr, FALSE, FALSE);
1305 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1306 pic16emitRegularMap (code, TRUE, FALSE);
1307 pic16emitStaticSeg (statsg);
1310 /*-----------------------------------------------------------------*/
1311 /* createInterruptVect - creates the interrupt vector */
1312 /*-----------------------------------------------------------------*/
1314 pic16createInterruptVect (FILE * vFile)
1316 /* if the main is only a prototype ie. no body then do nothing */
1318 if (!IFFUNC_HASBODY(mainf->type)) {
1319 /* if ! compile only then main function should be present */
1320 if (!options.cc_only)
1326 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1327 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1328 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1330 /* this is an overkill since WE are the port,
1331 * and we know if we have a genIVT function! */
1333 port->genIVT(vFile, interrupts, maxInterrupts);
1340 /*-----------------------------------------------------------------*/
1341 /* pic16initialComments - puts in some initial comments */
1342 /*-----------------------------------------------------------------*/
1344 pic16initialComments (FILE * afile)
1346 initialComments (afile);
1347 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1348 fprintf (afile, iComments2);
1352 /*-----------------------------------------------------------------*/
1353 /* printPublics - generates global declarations for publics */
1354 /*-----------------------------------------------------------------*/
1356 pic16printPublics (FILE *afile)
1360 fprintf (afile, "%s", iComments2);
1361 fprintf (afile, "; public variables in this module\n");
1362 fprintf (afile, "%s", iComments2);
1364 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1365 fprintf(afile, "\tglobal %s\n", sym->rname);
1368 /*-----------------------------------------------------------------*/
1369 /* printExterns - generates extern declarations for externs */
1370 /*-----------------------------------------------------------------*/
1372 pic16_printExterns(FILE *afile)
1376 fprintf(afile, "%s", iComments2);
1377 fprintf(afile, "; extern variables in this module\n");
1378 fprintf(afile, "%s", iComments2);
1380 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1381 fprintf(afile, "\textern %s\n", sym->rname);
1383 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1384 fprintf(afile, "\textern _%s\n", sym->name);
1387 /*-----------------------------------------------------------------*/
1388 /* emitOverlay - will emit code for the overlay stuff */
1389 /*-----------------------------------------------------------------*/
1391 pic16emitOverlay (FILE * afile)
1395 if (!elementsInSet (ovrSetSets))
1396 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1398 /* for each of the sets in the overlay segment do */
1399 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1400 ovrset = setNextItem (ovrSetSets))
1405 if (elementsInSet (ovrset))
1407 /* this dummy area is used to fool the assembler
1408 otherwise the assembler will append each of these
1409 declarations into one chunk and will not overlay
1411 fprintf (afile, ";\t.area _DUMMY\n");
1412 /* output the area informtion */
1413 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1416 for (sym = setFirstItem (ovrset); sym;
1417 sym = setNextItem (ovrset))
1420 /* if extern then do nothing */
1421 if (IS_EXTERN (sym->etype))
1424 /* if allocation required check is needed
1425 then check if the symbol really requires
1426 allocation only for local variables */
1427 if (!IS_AGGREGATE (sym->type) &&
1428 !(sym->_isparm && !IS_REGPARM (sym->etype))
1429 && !sym->allocreq && sym->level)
1432 /* if global variable & not static or extern
1433 and addPublics allowed then add it to the public set */
1434 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1435 && !IS_STATIC (sym->etype)) {
1436 checkAddSym(&publics, sym);
1437 // addSetHead (&publics, sym);
1440 /* if extern then do nothing or is a function
1442 if (IS_FUNC (sym->type))
1446 /* print extra debug info if required */
1447 if (options.debug || sym->level == 0)
1450 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1454 if (IS_STATIC (sym->etype))
1455 fprintf (afile, "F%s_", moduleName); /* scope is file */
1457 fprintf (afile, "G_"); /* scope is global */
1460 /* symbol is local */
1461 fprintf (afile, "L%s_",
1462 (sym->localof ? sym->localof->name : "-null-"));
1463 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1467 /* if is has an absolute address then generate
1468 an equate for this no need to allocate space */
1469 if (SPEC_ABSA (sym->etype))
1472 if (options.debug || sym->level == 0)
1473 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1475 fprintf (afile, "%s\t=\t0x%04x\n",
1477 SPEC_ADDR (sym->etype));
1481 if (options.debug || sym->level == 0)
1482 fprintf (afile, "==.\n");
1484 /* allocate space */
1485 fprintf (afile, "%s:\n", sym->rname);
1486 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1494 /*-----------------------------------------------------------------*/
1495 /* glue - the final glue that hold the whole thing together */
1496 /*-----------------------------------------------------------------*/
1503 FILE *ovrFile = tempfile();
1506 mainf = newSymbol ("main", 0);
1509 mainf = findSymWithLevel(SymbolTab, mainf);
1511 /* only if the main function exists */
1512 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1513 if (!options.cc_only)
1519 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1521 addSetHead(&tmpfileSet,ovrFile);
1522 pic16_pCodeInitRegisters();
1524 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1525 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1527 pic16_addpBlock(pb);
1529 /* entry point @ start of CSEG */
1530 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1533 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1534 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack"))));
1535 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1536 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack"))));
1539 /* put in the call to main */
1540 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1542 if (options.mainreturn) {
1543 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1544 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1546 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1547 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1551 /* At this point we've got all the code in the form of pCode structures */
1552 /* Now it needs to be rearranged into the order it should be placed in the */
1555 pic16_movepBlock2Head('P'); // Last
1556 pic16_movepBlock2Head(code->dbName);
1557 pic16_movepBlock2Head('X');
1558 pic16_movepBlock2Head(statsg->dbName); // First
1560 /* print the global struct definitions */
1561 // if (options.debug)
1562 // cdbStructBlock (0); //,cdbFile);
1565 /* PENDING: this isnt the best place but it will do */
1566 if (port->general.glue_up_main) {
1567 /* create the interrupt vector table */
1568 pic16createInterruptVect (vFile);
1571 addSetHead(&tmpfileSet,vFile);
1573 /* emit code for the all the variables declared */
1575 /* do the overlay segments */
1576 pic16emitOverlay(ovrFile);
1577 pic16_AnalyzepCode('*');
1582 sprintf(buffer, dstFileName);
1583 strcat(buffer, ".calltree");
1584 cFile = fopen(buffer, "w");
1585 pic16_printCallTree( cFile );
1590 pic16_InlinepCode();
1591 pic16_AnalyzepCode('*');
1593 if(pic16_debug_verbose)
1596 /* now put it all together into the assembler file */
1597 /* create the assembler file name */
1598 if ((noAssemble || options.c1mode) && fullDstFileName) {
1599 sprintf (buffer, fullDstFileName);
1601 sprintf (buffer, dstFileName);
1602 strcat (buffer, ".asm");
1605 if (!(asmFile = fopen (buffer, "w"))) {
1606 werror (E_FILE_OPEN_ERR, buffer);
1610 /* initial comments */
1611 pic16initialComments (asmFile);
1613 /* print module name */
1614 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1616 /* Let the port generate any global directives, etc. */
1617 if (port->genAssemblerPreamble) {
1618 port->genAssemblerPreamble(asmFile);
1621 /* print the extern variables to this module */
1622 pic16_printExterns(asmFile);
1624 /* print the global variables in this module */
1625 pic16printPublics (asmFile);
1628 /* copy the sfr segment */
1629 fprintf (asmFile, "%s", iComments2);
1630 fprintf (asmFile, "; special function registers\n");
1631 fprintf (asmFile, "%s", iComments2);
1632 copyFile (asmFile, sfr->oFile);
1636 /* Put all variables into a cblock */
1637 pic16_AnalyzeBanking();
1638 pic16_writeUsedRegs(asmFile);
1641 /* create the overlay segments */
1642 fprintf (asmFile, "%s", iComments2);
1643 fprintf (asmFile, "; overlayable items in internal ram \n");
1644 fprintf (asmFile, "%s", iComments2);
1645 copyFile (asmFile, ovrFile);
1650 /* create the stack segment MOF */
1651 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1652 fprintf (asmFile, "%s", iComments2);
1653 fprintf (asmFile, "; Stack segment in internal ram \n");
1654 fprintf (asmFile, "%s", iComments2);
1655 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1656 ";__start__stack:\n;\t.ds\t1\n\n");
1661 /* no indirect data in pic */
1662 /* create the idata segment */
1663 fprintf (asmFile, "%s", iComments2);
1664 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1665 fprintf (asmFile, "%s", iComments2);
1666 copyFile (asmFile, idata->oFile);
1671 /* no xdata in pic */
1672 /* if external stack then reserve space of it */
1673 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1674 fprintf (asmFile, "%s", iComments2);
1675 fprintf (asmFile, "; external stack \n");
1676 fprintf (asmFile, "%s", iComments2);
1677 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1678 fprintf (asmFile,";\t.ds 256\n");
1683 /* no xdata in pic */
1684 /* copy xtern ram data */
1685 fprintf (asmFile, "%s", iComments2);
1686 fprintf (asmFile, "; external ram data\n");
1687 fprintf (asmFile, "%s", iComments2);
1688 copyFile (asmFile, xdata->oFile);
1692 /* copy the bit segment */
1693 fprintf (asmFile, "%s", iComments2);
1694 fprintf (asmFile, "; bit data\n");
1695 fprintf (asmFile, "%s", iComments2);
1696 copyFile (asmFile, bit->oFile);
1699 /* copy the interrupt vector table */
1700 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1701 fprintf (asmFile, "%s", iComments2);
1702 fprintf (asmFile, "; interrupt vector \n");
1703 fprintf (asmFile, "%s", iComments2);
1704 copyFile (asmFile, vFile);
1707 /* copy global & static initialisations */
1708 fprintf (asmFile, "%s", iComments2);
1709 fprintf (asmFile, "; global & static initialisations\n");
1710 fprintf (asmFile, "%s", iComments2);
1713 /* copy over code */
1714 fprintf (asmFile, "%s", iComments2);
1715 fprintf (asmFile, "\tcode\n");
1716 fprintf (asmFile, "%s", iComments2);
1719 if(pic16_debug_verbose)
1720 fprintf(asmFile, "; A code from now on!\n");
1721 pic16_copypCode(asmFile, 'A');
1724 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1725 fprintf(asmFile, "\tcode\n");
1726 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1729 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1730 /* if external stack is specified then the
1731 * higher order byte of the xdatalocation is
1732 * going into P2 and the lower order going into */
1734 if (options.useXstack) {
1735 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1736 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1737 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1738 (unsigned int)options.xdata_loc & 0xff);
1743 // copyFile (stderr, code->oFile);
1745 fprintf(asmFile, "; I code from now on!\n");
1746 pic16_copypCode(asmFile, 'I');
1748 if(pic16_debug_verbose)
1749 fprintf(asmFile, "; dbName from now on!\n");
1750 pic16_copypCode(asmFile, statsg->dbName);
1753 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1754 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1758 if(pic16_debug_verbose)
1759 fprintf(asmFile, "; X code from now on!\n");
1760 pic16_copypCode(asmFile, 'X');
1762 if(pic16_debug_verbose)
1763 fprintf(asmFile, "; M code from now on!\n");
1764 pic16_copypCode(asmFile, 'M');
1767 pic16_copypCode(asmFile, code->dbName);
1769 pic16_copypCode(asmFile, 'P');
1771 fprintf (asmFile,"\tend\n");