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;
62 extern unsigned long pFile_isize;
64 extern unsigned long pic16_countInstructions();
65 set *rel_idataSymSet=NULL;
66 set *fix_idataSymSet=NULL;
68 extern DEFSETFUNC (closeTmpFiles);
69 extern DEFSETFUNC (rmTmpFiles);
71 extern void pic16_AnalyzeBanking (void);
72 extern void copyFile (FILE * dest, FILE * src);
73 extern void pic16_InlinepCode(void);
74 extern void pic16_writeUsedRegs(FILE *);
76 extern void initialComments (FILE * afile);
77 extern void printPublics (FILE * afile);
79 void pic16_pCodeInitRegisters(void);
80 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
81 extern void pic16_pCodeConstString(char *name, char *value);
83 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
84 extern void _debugf(char *f, int l, char *frm, ...);
86 /*-----------------------------------------------------------------*/
87 /* aopLiteral - string from a literal value */
88 /*-----------------------------------------------------------------*/
89 int pic16aopLiteral (value *val, int offset)
96 /* if it is a float then it gets tricky */
97 /* otherwise it is fairly simple */
98 if (!IS_FLOAT(val->type)) {
99 unsigned long v = (unsigned long) floatFromVal(val);
101 return ( (v >> (offset * 8)) & 0xff);
104 /* it is type float */
105 fl.f = (float) floatFromVal(val);
106 #ifdef WORDS_BIGENDIAN
107 return fl.c[3-offset];
116 char tbuffer[512], *tbuf=tbuffer;;
119 /*-----------------------------------------------------------------*/
120 /* emitRegularMap - emit code for maps with no special cases */
121 /*-----------------------------------------------------------------*/
123 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
126 // int i, size, bitvars = 0;;
128 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
131 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
132 /* print the area name */
134 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
137 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
139 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
140 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
141 printTypeChain( sym->type, stderr );
142 fprintf(stderr, "\n");
145 /* if extern then add to externs */
146 if (IS_EXTERN (sym->etype)) {
147 /* reduce overhead while linking by not declaring
148 * extern unused external functions (usually declared
149 * in header files) */
150 if(IS_FUNC(sym->type) && !sym->used)continue;
152 /* make sure symbol is not in publics section */
153 if(!checkSym(publics, sym))
154 checkAddSym(&externs, sym);
158 /* if allocation required check is needed
159 * then check if the symbol really requires
160 * allocation only for local variables */
161 if (arFlag && !IS_AGGREGATE (sym->type) &&
162 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
163 !sym->allocreq && sym->level) {
165 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
170 /* if global variable & not static or extern
171 * and addPublics allowed then add it to the public set */
172 if ((sym->used) && (sym->level == 0 ||
173 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
175 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
177 checkAddSym(&publics, sym);
179 if(IS_STATIC(sym->etype)
180 && !(sym->ival && !sym->level)
183 /* add it to udata list */
185 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
186 // sym->name, sym->rname, sym->remat);
188 //, OP_SYMBOL(operandFromSymbol(sym))->name);
189 #define SET_IMPLICIT 1
192 if(IS_STRUCT(sym->type))
196 reg = pic16_allocDirReg( operandFromSymbol( sym ));
203 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
204 if(!strcmp(ssym->name, reg->name))found=1;
209 checkAddReg(&pic16_rel_udata, reg);
211 checkAddSym(&publics, sym);
216 /* if extern then do nothing or is a function
218 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
219 if(SPEC_OCLS(sym->etype) == code) {
220 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
221 checkAddSym(&publics, sym);
227 /* print extra debug info if required */
228 if (options.debug || sym->level == 0) {
229 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
231 if (!sym->level) /* global */
232 if (IS_STATIC (sym->etype))
233 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
235 fprintf (map->oFile, "G_"); /* scope is global */
237 /* symbol is local */
238 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
239 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
244 /* if is has an absolute address then generate
245 an equate for this no need to allocate space */
246 if (SPEC_ABSA (sym->etype)) {
247 // if (options.debug || sym->level == 0)
248 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
249 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
251 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
253 SPEC_ADDR (sym->etype));
255 /* emit only if it is global */
256 if(sym->level == 0) {
259 reg = pic16_dirregWithName( sym->name );
262 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
263 // __FUNCTION__, __LINE__, sym->name);
265 /* if IS_STRUCT is omitted the following
266 * fixes structures but break char/int etc */
268 if(IS_STRUCT(sym->type))
269 sym->implicit = 1; // mark as implicit
272 reg = pic16_allocDirReg( operandFromSymbol(sym) );
274 if(checkAddReg(&pic16_fix_udata, reg)) {
275 /* and add to globals list if not exist */
276 addSet(&publics, sym);
280 addSet(&publics, sym);
284 if(!sym->used && (sym->level == 0)) {
287 /* symbol not used, just declared probably, but its in
288 * level 0, so we must declare it fine as global */
290 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
293 if(IS_STRUCT(sym->type))
294 sym->implicit = 1; // mark as implicit
297 if(IS_AGGREGATE(sym->type)) {
298 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
300 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
308 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
309 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
313 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
314 if(!strcmp(ssym->name, reg->name))found=1;
319 if(checkAddReg(&pic16_rel_udata, reg)) {
320 addSetHead(&publics, sym);
329 addSetHead(&publics, sym);
334 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
335 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
336 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
337 if (IS_BITVAR (sym->etype)) {
340 fprintf (map->oFile, "\t%s\n", sym->rname);
341 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
342 for (i = 1; i < size; i++)
343 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
346 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
350 /* FIXME -- VR Fix the following, so that syms to be placed
351 * in the idata section and let linker decide about their fate */
353 /* if it has an initial value then do it only if
354 it is a global variable */
356 if (sym->ival && sym->level == 0) {
360 if(SPEC_OCLS(sym->etype)==data) {
361 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
364 if(SPEC_OCLS(sym->etype)==code) {
365 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
370 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
371 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
374 if (IS_AGGREGATE (sym->type)) {
375 if(SPEC_ABSA(sym->etype))
376 addSet(&fix_idataSymSet, copySymbol(sym));
378 addSet(&rel_idataSymSet, copySymbol(sym));
379 // ival = initAggregates (sym, sym->ival, NULL);
381 if(SPEC_ABSA(sym->etype))
382 addSet(&fix_idataSymSet, copySymbol(sym));
384 addSet(&rel_idataSymSet, copySymbol(sym));
386 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
387 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
391 setAstLineno(ival, sym->lineDef);
392 codeOutFile = statsg->oFile;
394 eBBlockFromiCode (iCodeFromAst (ival));
402 /*-----------------------------------------------------------------*/
403 /* pic16_initPointer - pointer initialization code massaging */
404 /*-----------------------------------------------------------------*/
405 value *pic16_initPointer (initList * ilist, sym_link *toType)
411 return valCastLiteral(toType, 0.0);
414 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
415 // expr = list2expr( ilist );
420 /* try it the old way first */
421 if ((val = constExprValue (expr, FALSE)))
424 /* ( ptr + constant ) */
425 if (IS_AST_OP (expr) &&
426 (expr->opval.op == '+' || expr->opval.op == '-') &&
427 IS_AST_SYM_VALUE (expr->left) &&
428 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
429 compareType(toType, expr->left->ftype) &&
430 IS_AST_LIT_VALUE (expr->right)) {
431 return valForCastAggr (expr->left, expr->left->ftype,
437 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
438 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
439 if (compareType(toType, expr->left->ftype)!=1) {
440 werror (W_INIT_WRONG);
441 printFromToType(expr->left->ftype, toType);
447 /* no then we have to do these cludgy checks */
448 /* pointers can be initialized with address of
449 a variable or address of an array element */
450 if (IS_AST_OP (expr) && expr->opval.op == '&') {
451 /* address of symbol */
452 if (IS_AST_SYM_VALUE (expr->left)) {
453 val = copyValue (AST_VALUE (expr->left));
454 val->type = newLink (DECLARATOR);
455 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
456 DCL_TYPE (val->type) = CPOINTER;
457 DCL_PTR_CONST (val->type) = port->mem.code_ro;
459 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
460 DCL_TYPE (val->type) = FPOINTER;
461 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
462 DCL_TYPE (val->type) = PPOINTER;
463 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
464 DCL_TYPE (val->type) = IPOINTER;
465 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
466 DCL_TYPE (val->type) = EEPPOINTER;
468 DCL_TYPE (val->type) = POINTER;
470 val->type->next = expr->left->ftype;
471 val->etype = getSpec (val->type);
475 /* if address of indexed array */
476 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
477 return valForArray (expr->left);
479 /* if address of structure element then
481 if (IS_AST_OP (expr->left) &&
482 expr->left->opval.op == '.') {
483 return valForStructElem (expr->left->left,
488 (&some_struct)->element */
489 if (IS_AST_OP (expr->left) &&
490 expr->left->opval.op == PTR_OP &&
491 IS_ADDRESS_OF_OP (expr->left->left)) {
492 return valForStructElem (expr->left->left->left,
496 /* case 3. (((char *) &a) +/- constant) */
497 if (IS_AST_OP (expr) &&
498 (expr->opval.op == '+' || expr->opval.op == '-') &&
499 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
500 IS_AST_OP (expr->left->right) &&
501 expr->left->right->opval.op == '&' &&
502 IS_AST_LIT_VALUE (expr->right)) {
504 return valForCastAggr (expr->left->right->left,
505 expr->left->left->opval.lnk,
506 expr->right, expr->opval.op);
509 /* case 4. (char *)(array type) */
510 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
511 IS_ARRAY(expr->right->ftype)) {
513 val = copyValue (AST_VALUE (expr->right));
514 val->type = newLink (DECLARATOR);
515 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
516 DCL_TYPE (val->type) = CPOINTER;
517 DCL_PTR_CONST (val->type) = port->mem.code_ro;
519 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
520 DCL_TYPE (val->type) = FPOINTER;
521 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
522 DCL_TYPE (val->type) = PPOINTER;
523 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
524 DCL_TYPE (val->type) = IPOINTER;
525 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
526 DCL_TYPE (val->type) = EEPPOINTER;
528 DCL_TYPE (val->type) = POINTER;
529 val->type->next = expr->right->ftype->next;
530 val->etype = getSpec (val->type);
536 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
538 werror (E_INCOMPAT_PTYPES);
544 /*-----------------------------------------------------------------*/
545 /* printPointerType - generates ival for pointer type */
546 /*-----------------------------------------------------------------*/
547 void _pic16_printPointerType (const char *name, char ptype, void *p)
551 sprintf(buf, "LOW(%s)", name);
552 pic16_emitDS(buf, ptype, p);
553 sprintf(buf, "HIGH(%s)", name);
554 pic16_emitDS(buf, ptype, p);
557 /*-----------------------------------------------------------------*/
558 /* printPointerType - generates ival for pointer type */
559 /*-----------------------------------------------------------------*/
560 void pic16_printPointerType (const char *name, char ptype, void *p)
562 _pic16_printPointerType (name, ptype, p);
563 pic16_flushDB(ptype, p);
566 /*-----------------------------------------------------------------*/
567 /* printGPointerType - generates ival for generic pointer type */
568 /*-----------------------------------------------------------------*/
569 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
570 const unsigned int type, char ptype, void *p)
574 _pic16_printPointerType (iname, ptype, p);
580 sprintf(buf, "UPPER(%s)", iname);
581 pic16_emitDS(buf, ptype, p);
585 sprintf(buf, "0x80");
586 pic16_emitDS(buf, ptype, p);
590 pic16_flushDB(ptype, p);
594 /* set to 0 to disable debug messages */
595 #define DEBUG_PRINTIVAL 0
597 /*-----------------------------------------------------------------*/
598 /* pic16_printIvalType - generates ival for int/char */
599 /*-----------------------------------------------------------------*/
601 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
605 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
608 fprintf(stderr, "%s\n",__FUNCTION__);
612 /* if initList is deep */
613 if (ilist && ilist->type == INIT_DEEP)
614 ilist = ilist->init.deep;
616 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
617 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
620 if (!(val = list2val (ilist))) {
621 // assuming a warning has been thrown
625 if (val->type != type) {
626 val = valCastLiteral(type, floatFromVal(val));
629 switch (getSize (type)) {
631 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
635 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
636 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
639 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
640 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
641 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
643 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
644 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
645 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
646 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
651 /*--------------------------------------------------------------------*/
652 /* pic16_printIvalChar - generates initital value for character array */
653 /*--------------------------------------------------------------------*/
655 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
664 fprintf(stderr, "%s\n",__FUNCTION__);
668 val = list2val (ilist);
669 /* if the value is a character string */
670 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
672 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
674 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
675 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
677 if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
679 pic16_emitDB(0x00, ptype, p);
685 for(remain=0; remain<strlen(s); remain++) {
686 pic16_emitDB(s[remain], ptype, p);
692 /*-----------------------------------------------------------------*/
693 /* pic16_printIvalArray - generates code for array initialization */
694 /*-----------------------------------------------------------------*/
696 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
700 int lcnt = 0, size = 0;
707 fprintf(stderr, "%s\n",__FUNCTION__);
709 /* take care of the special case */
710 /* array of characters can be init */
712 if (IS_CHAR (type->next)) {
713 if (!IS_LITERAL(list2val(ilist)->etype)) {
714 werror (W_INIT_WRONG);
718 if(pic16_printIvalChar (type,
719 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
720 SPEC_CVAL (sym->etype).v_char, ptype, p))
723 /* not the special case */
724 if (ilist && ilist->type != INIT_DEEP)
726 werror (E_INIT_STRUCT, sym->name);
730 iloop = ilist->init.deep;
731 lcnt = DCL_ELEM (type);
736 pic16_printIval (sym, type->next, iloop, ptype, p);
737 iloop = (iloop ? iloop->next : NULL);
740 /* if not array limits given & we */
741 /* are out of initialisers then */
742 if (!DCL_ELEM (type) && !iloop)
745 /* no of elements given and we */
746 /* have generated for all of them */
748 /* if initializers left */
750 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
756 /* if we have not been given a size */
757 if (!DCL_ELEM (type))
758 DCL_ELEM (type) = size;
763 /*-----------------------------------------------------------------*/
764 /* pic16_printIvalBitFields - generate initializer for bitfields */
765 /*-----------------------------------------------------------------*/
766 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
770 initList *lilist = *ilist ;
771 unsigned long ival = 0;
776 fprintf(stderr, "%s\n",__FUNCTION__);
782 val = list2val(lilist);
784 if (SPEC_BLEN(lsym->etype) > 8) {
785 size += ((SPEC_BLEN (lsym->etype) / 8) +
786 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
789 size = ((SPEC_BLEN (lsym->etype) / 8) +
790 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
792 i = (unsigned long)floatFromVal(val);
793 i <<= SPEC_BSTR (lsym->etype);
795 if (! ( lsym->next &&
796 (IS_BITFIELD(lsym->next->type)) &&
797 (SPEC_BSTR(lsym->next->etype)))) break;
799 lilist = lilist->next;
803 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
807 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
808 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
811 case 4: /* EEP: why is this db and not dw? */
812 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
813 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
814 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
815 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
818 /* VR - only 1,2,4 size long can be handled???? Why? */
819 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
827 /*-----------------------------------------------------------------*/
828 /* printIvalStruct - generates initial value for structures */
829 /*-----------------------------------------------------------------*/
830 void pic16_printIvalStruct (symbol * sym, sym_link * type,
831 initList * ilist, char ptype, void *p)
834 initList *iloop = NULL;
838 fprintf(stderr, "%s\n",__FUNCTION__);
841 sflds = SPEC_STRUCT (type)->fields;
844 if (ilist->type != INIT_DEEP) {
845 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
849 iloop = ilist->init.deep;
852 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
853 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
854 if (IS_BITFIELD(sflds->type)) {
855 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
857 pic16_printIval (sym, sflds->type, iloop, ptype, p);
861 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
866 /*--------------------------------------------------------------------------*/
867 /* pic16_printIvalCharPtr - generates initial values for character pointers */
868 /*--------------------------------------------------------------------------*/
869 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
873 /* PENDING: this is _very_ mcs51 specific, including a magic
875 It's also endin specific.
877 VR - Attempting to port this function to pic16 port - 8-Jun-2004
882 fprintf(stderr, "%s\n",__FUNCTION__);
885 size = getSize (type);
887 if (val->name && strlen (val->name))
889 if (size == 1) /* This appears to be Z80 specific?? */
891 pic16_emitDS(val->name, ptype, p);
895 pic16_printPointerType (val->name, ptype, p);
900 if (IS_PTR (val->type)) {
901 type = DCL_TYPE (val->type);
903 type = PTR_TYPE (SPEC_OCLS (val->etype));
905 if (val->sym && val->sym->isstrlit) {
906 // this is a literal string
909 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
913 fprintf (stderr, "*** internal error: unknown size in "
914 "printIvalCharPtr.\n");
920 // these are literals assigned to pointers
924 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
927 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
928 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
931 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
932 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
933 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
941 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
942 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
943 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
949 /*-----------------------------------------------------------------------*/
950 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
951 /*-----------------------------------------------------------------------*/
952 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
959 fprintf(stderr, "%s\n",__FUNCTION__);
963 val = list2val (ilist);
965 val = valCastLiteral(type, 0.0);
968 // an error has been thrown already
972 if (IS_LITERAL(val->etype)) {
973 if (compareType(type, val->etype) == 0) {
974 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
975 printFromToType (val->type, type);
977 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
981 /* check the types */
982 if ((dLvl = compareType (val->type, type->next)) <= 0)
984 pic16_emitDB(0x00, ptype, p);
988 /* now generate the name */
990 pic16_printPointerType (val->name, ptype, p);
992 pic16_printPointerType (val->sym->rname, ptype, p);
994 if(IS_FUNC(val->sym->type) && !val->sym->used) {
996 if(!checkSym(publics, val->sym))
997 checkAddSym(&externs, val->sym);
999 /* this has not been declared as extern
1000 * so declare it as a 'late extern' just after the symbol */
1002 fprintf((FILE *)p, "declare symbol as extern");
1003 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1004 fprintf((FILE *)p, "continue variable declaration");
1013 /*-----------------------------------------------------------------*/
1014 /* pic16_printIvalPtr - generates initial value for pointers */
1015 /*-----------------------------------------------------------------*/
1016 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1022 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1023 sym->rname, getSize(sym->type));
1027 if (ilist && (ilist->type == INIT_DEEP))
1028 ilist = ilist->init.deep;
1030 /* function pointer */
1031 if (IS_FUNC (type->next))
1033 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1037 if (!(val = pic16_initPointer (ilist, type)))
1040 /* if character pointer */
1041 if (IS_CHAR (type->next))
1042 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1045 /* check the type */
1046 if (compareType (type, val->type) == 0) {
1047 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1048 printFromToType (val->type, type);
1051 /* if val is literal */
1052 if (IS_LITERAL (val->etype))
1054 switch (getSize (type))
1057 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1060 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1061 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1064 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1065 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1066 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1069 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1076 size = getSize (type);
1078 if (size == 1) /* Z80 specific?? */
1080 pic16_emitDS(val->name, ptype, p);
1084 pic16_printPointerType (val->name, ptype, p);
1088 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1089 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1090 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1098 /*-----------------------------------------------------------------*/
1099 /* pic16_printIval - generates code for initial value */
1100 /*-----------------------------------------------------------------*/
1101 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1109 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1110 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1111 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1114 /* if structure then */
1115 if (IS_STRUCT (type))
1117 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1118 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1122 /* if this is an array */
1123 if (IS_ARRAY (type))
1125 // fprintf(stderr,"%s array\n",__FUNCTION__);
1126 pic16_printIvalArray (sym, type, ilist, ptype, p);
1133 // not an aggregate, ilist must be a node
1134 if (ilist->type!=INIT_NODE) {
1135 // or a 1-element list
1136 if (ilist->init.deep->next) {
1137 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1140 ilist=ilist->init.deep;
1145 // and the type must match
1146 itype=ilist->init.node->ftype;
1148 if (compareType(type, itype)==0) {
1149 // special case for literal strings
1150 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1151 // which are really code pointers
1152 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1155 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1156 // printFromToType(itype, type);
1163 /* if this is a pointer */
1166 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1167 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1172 /* if type is SPECIFIER */
1175 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1176 pic16_printIvalType (sym, type, ilist, ptype, p);
1181 int PIC16_IS_CONFIG_ADDRESS(int address)
1183 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1186 int PIC16_IS_IDLOC_ADDRESS(int address)
1188 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1191 /* wrapper function for the above */
1192 int PIC16_IS_HWREG_ADDRESS(int address)
1194 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1198 /*-----------------------------------------------------------------*/
1199 /* emitStaticSeg - emitcode for the static segment */
1200 /*-----------------------------------------------------------------*/
1202 pic16emitStaticSeg (memmap * map)
1205 static int didcode=0;
1207 //fprintf(stderr, "%s\n",__FUNCTION__);
1211 /* for all variables in this segment do */
1212 for (sym = setFirstItem (map->syms); sym;
1213 sym = setNextItem (map->syms))
1217 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1218 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1219 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1220 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1221 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1222 printTypeChain( sym->type, stderr );
1223 fprintf(stderr, "\n");
1226 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1227 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1228 (int) floatFromVal(list2val(sym->ival)));
1233 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1234 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1235 (char) floatFromVal(list2val(sym->ival)));
1240 /* if it is "extern" then do nothing */
1241 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1242 checkAddSym(&externs, sym);
1246 /* if it is not static add it to the public
1248 if (!IS_STATIC (sym->etype)) {
1249 /* do not emit if it is a config word declaration */
1250 checkAddSym(&publics, sym);
1253 /* print extra debug info if required */
1254 if (options.debug || sym->level == 0) {
1255 /* NOTE to me - cdbFile may be null in which case,
1256 * the sym name will be printed to stdout. oh well */
1257 debugFile->writeSymbol(sym);
1260 /* if it has an absolute address */
1261 if (SPEC_ABSA (sym->etype)) {
1262 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1263 // __FILE__, __LINE__, sym->name);
1265 /* if it has an initial value */
1273 /* symbol has absolute address and initial value */
1275 resolveIvalSym (sym->ival, sym->type);
1276 asym = newSymbol(sym->rname, 0);
1277 abSym = Safe_calloc(1, sizeof(absSym));
1278 strcpy(abSym->name, sym->rname);
1279 abSym->address = SPEC_ADDR( sym->etype );
1280 addSet(&absSymSet, abSym);
1282 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1283 pic16_addpBlock(pb);
1285 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1286 PCF(pcf)->absblock = 1;
1288 pic16_addpCode2pBlock(pb,pcf);
1289 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1290 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1291 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1292 pic16_flushDB('p', (void *)pb);
1294 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1300 /* symbol has absolute address but no initial value */
1302 /* allocate space */
1303 fprintf (code->oFile, "%s:\n", sym->rname);
1305 /* special case for character strings */
1306 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1307 SPEC_CVAL (sym->etype).v_char) {
1309 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1311 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1318 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1319 // __FILE__, __LINE__, sym->name);
1322 /* if it has an initial value */
1326 /* symbol doesn't have absolute address but has initial value */
1327 fprintf (code->oFile, "%s:\n", sym->rname);
1329 resolveIvalSym (sym->ival, sym->type);
1331 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1332 pic16_addpBlock(pb);
1335 /* make sure that 'code' directive is emitted before, once */
1336 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1341 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1343 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1344 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1345 pic16_flushDB('p', (void *)pb);
1349 /* symbol doesn't have absolute address and no initial value */
1350 /* allocate space */
1351 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1352 fprintf (code->oFile, "%s:\n", sym->rname);
1353 /* special case for character strings */
1354 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1355 SPEC_CVAL (sym->etype).v_char) {
1357 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1359 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1370 /*-----------------------------------------------------------------*/
1371 /* pic16_emitConfigRegs - emits the configuration registers */
1372 /*-----------------------------------------------------------------*/
1373 void pic16_emitConfigRegs(FILE *of)
1377 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1378 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1379 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1380 pic16->cwInfo.confAddrStart+i,
1381 pic16->cwInfo.crInfo[i].value);
1384 void pic16_emitIDRegs(FILE *of)
1388 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1389 if(pic16->idInfo.irInfo[i].emit)
1390 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1391 pic16->idInfo.idAddrStart+i,
1392 pic16->idInfo.irInfo[i].value);
1399 /* no special considerations for the following
1400 data, idata & bit & xdata */
1401 pic16emitRegularMap (data, TRUE, TRUE);
1402 pic16emitRegularMap (idata, TRUE, TRUE);
1403 pic16emitRegularMap (bit, TRUE, FALSE);
1404 pic16emitRegularMap (xdata, TRUE, TRUE);
1405 pic16emitRegularMap (sfr, FALSE, FALSE);
1406 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1407 pic16emitRegularMap (code, TRUE, FALSE);
1408 pic16emitStaticSeg (statsg);
1411 /*-----------------------------------------------------------------*/
1412 /* createInterruptVect - creates the interrupt vector */
1413 /*-----------------------------------------------------------------*/
1415 pic16createInterruptVect (FILE * vFile)
1417 /* if the main is only a prototype ie. no body then do nothing */
1419 if (!IFFUNC_HASBODY(mainf->type)) {
1420 /* if ! compile only then main function should be present */
1421 if (!options.cc_only)
1427 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1428 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1429 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1431 /* this is an overkill since WE are the port,
1432 * and we know if we have a genIVT function! */
1434 port->genIVT(vFile, interrupts, maxInterrupts);
1441 /*-----------------------------------------------------------------*/
1442 /* pic16initialComments - puts in some initial comments */
1443 /*-----------------------------------------------------------------*/
1445 pic16initialComments (FILE * afile)
1447 initialComments (afile);
1448 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1449 if(pic16_mplab_comp)
1450 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1451 fprintf (afile, iComments2);
1454 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1455 SDCC_VERSION_STR, getBuildNumber() );
1459 /*-----------------------------------------------------------------*/
1460 /* printPublics - generates global declarations for publics */
1461 /*-----------------------------------------------------------------*/
1463 pic16printPublics (FILE *afile)
1467 fprintf (afile, "\n%s", iComments2);
1468 fprintf (afile, "; public variables in this module\n");
1469 fprintf (afile, "%s", iComments2);
1471 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1472 fprintf(afile, "\tglobal %s\n", sym->rname);
1475 /*-----------------------------------------------------------------*/
1476 /* printExterns - generates extern declarations for externs */
1477 /*-----------------------------------------------------------------*/
1479 pic16_printExterns(FILE *afile)
1483 /* print nothing if no externs to declare */
1484 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1487 fprintf(afile, "\n%s", iComments2);
1488 fprintf(afile, "; extern variables in this module\n");
1489 fprintf(afile, "%s", iComments2);
1491 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1492 fprintf(afile, "\textern %s\n", sym->rname);
1494 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1495 fprintf(afile, "\textern _%s\n", sym->name);
1498 /*-----------------------------------------------------------------*/
1499 /* emitOverlay - will emit code for the overlay stuff */
1500 /*-----------------------------------------------------------------*/
1502 pic16emitOverlay (FILE * afile)
1506 if (!elementsInSet (ovrSetSets))
1507 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1509 /* for each of the sets in the overlay segment do */
1510 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1511 ovrset = setNextItem (ovrSetSets))
1516 if (elementsInSet (ovrset))
1518 /* this dummy area is used to fool the assembler
1519 otherwise the assembler will append each of these
1520 declarations into one chunk and will not overlay
1522 fprintf (afile, ";\t.area _DUMMY\n");
1523 /* output the area informtion */
1524 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1527 for (sym = setFirstItem (ovrset); sym;
1528 sym = setNextItem (ovrset))
1531 /* if extern then do nothing */
1532 if (IS_EXTERN (sym->etype))
1535 /* if allocation required check is needed
1536 then check if the symbol really requires
1537 allocation only for local variables */
1538 if (!IS_AGGREGATE (sym->type) &&
1539 !(sym->_isparm && !IS_REGPARM (sym->etype))
1540 && !sym->allocreq && sym->level)
1543 /* if global variable & not static or extern
1544 and addPublics allowed then add it to the public set */
1545 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1546 && !IS_STATIC (sym->etype)) {
1547 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1548 checkAddSym(&publics, sym);
1549 // addSetHead (&publics, sym);
1552 /* if extern then do nothing or is a function
1554 if (IS_FUNC (sym->type))
1558 /* print extra debug info if required */
1559 if (options.debug || sym->level == 0)
1562 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1566 if (IS_STATIC (sym->etype))
1567 fprintf (afile, "F%s_", moduleName); /* scope is file */
1569 fprintf (afile, "G_"); /* scope is global */
1572 /* symbol is local */
1573 fprintf (afile, "L%s_",
1574 (sym->localof ? sym->localof->name : "-null-"));
1575 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1579 /* if is has an absolute address then generate
1580 an equate for this no need to allocate space */
1581 if (SPEC_ABSA (sym->etype))
1584 if (options.debug || sym->level == 0)
1585 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1587 fprintf (afile, "%s\t=\t0x%04x\n",
1589 SPEC_ADDR (sym->etype));
1593 if (options.debug || sym->level == 0)
1594 fprintf (afile, "==.\n");
1596 /* allocate space */
1597 fprintf (afile, "%s:\n", sym->rname);
1598 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1605 void emitStatistics(FILE *asmFile)
1607 statistics.isize = pic16_countInstructions();
1609 fprintf (asmFile, "\n\n; Statistics:\n");
1610 fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
1611 statistics.isize, statistics.isize,
1612 statistics.isize>>1, statistics.isize>>1);
1613 fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n",
1614 statistics.udsize, statistics.udsize);
1615 fprintf (asmFile, "; access size:\t%ld (0x%lx) bytes\n",
1616 statistics.intsize, statistics.intsize);
1618 fprintf (asmFile, "\n\n");
1623 /*-----------------------------------------------------------------*/
1624 /* glue - the final glue that hold the whole thing together */
1625 /*-----------------------------------------------------------------*/
1631 FILE *ovrFile = tempfile();
1633 mainf = newSymbol ("main", 0);
1636 mainf = findSymWithLevel(SymbolTab, mainf);
1638 addSetHead(&tmpfileSet,ovrFile);
1639 pic16_pCodeInitRegisters();
1641 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1642 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1644 pic16_addpBlock(pb);
1646 /* entry point @ start of CSEG */
1647 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1650 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1651 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1652 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1653 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1656 /* put in the call to main */
1657 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1659 if (options.mainreturn) {
1660 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1661 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1663 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1664 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1668 /* At this point we've got all the code in the form of pCode structures */
1669 /* Now it needs to be rearranged into the order it should be placed in the */
1672 pic16_movepBlock2Head('P'); // Last
1673 pic16_movepBlock2Head(code->dbName);
1674 pic16_movepBlock2Head('X');
1675 pic16_movepBlock2Head(statsg->dbName); // First
1677 /* print the global struct definitions */
1680 /* PENDING: this isnt the best place but it will do */
1681 if (port->general.glue_up_main) {
1682 /* create the interrupt vector table */
1683 pic16createInterruptVect (vFile);
1686 addSetHead(&tmpfileSet,vFile);
1688 /* emit code for the all the variables declared */
1691 /* do the overlay segments */
1692 pic16emitOverlay(ovrFile);
1693 pic16_AnalyzepCode('*');
1696 if(pic16_options.dumpcalltree) {
1699 sprintf(buffer, dstFileName);
1700 strcat(buffer, ".calltree");
1701 cFile = fopen(buffer, "w");
1702 pic16_printCallTree( cFile );
1707 pic16_InlinepCode();
1708 pic16_AnalyzepCode('*');
1711 if(pic16_debug_verbose)
1714 /* now put it all together into the assembler file */
1715 /* create the assembler file name */
1716 if((noAssemble || options.c1mode) && fullDstFileName) {
1717 sprintf (buffer, fullDstFileName);
1719 sprintf (buffer, dstFileName);
1720 strcat (buffer, ".asm");
1723 if(!(asmFile = fopen (buffer, "w"))) {
1724 werror (E_FILE_OPEN_ERR, buffer);
1728 /* initial comments */
1729 pic16initialComments (asmFile);
1731 /* print module name */
1733 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1735 /* Let the port generate any global directives, etc. */
1736 if(port->genAssemblerPreamble) {
1737 port->genAssemblerPreamble(asmFile);
1740 /* Put all variables into a cblock */
1741 pic16_AnalyzeBanking();
1743 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1744 pic16_OptimizeLocalRegs();
1747 /* print the extern variables to this module */
1748 pic16_printExterns(asmFile);
1750 /* print the global variables in this module */
1751 pic16printPublics (asmFile);
1753 pic16_writeUsedRegs(asmFile);
1756 /* no xdata in pic */
1757 /* if external stack then reserve space of it */
1758 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1759 fprintf (asmFile, "%s", iComments2);
1760 fprintf (asmFile, "; external stack \n");
1761 fprintf (asmFile, "%s", iComments2);
1762 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1763 fprintf (asmFile,";\t.ds 256\n");
1768 /* no xdata in pic */
1769 /* copy xtern ram data */
1770 fprintf (asmFile, "%s", iComments2);
1771 fprintf (asmFile, "; external ram data\n");
1772 fprintf (asmFile, "%s", iComments2);
1773 copyFile (asmFile, xdata->oFile);
1777 /* copy the bit segment */
1778 fprintf (asmFile, "%s", iComments2);
1779 fprintf (asmFile, "; bit data\n");
1780 fprintf (asmFile, "%s", iComments2);
1781 copyFile (asmFile, bit->oFile);
1784 /* copy the interrupt vector table */
1785 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1786 fprintf (asmFile, "\n%s", iComments2);
1787 fprintf (asmFile, "; interrupt vector \n");
1788 fprintf (asmFile, "%s", iComments2);
1789 copyFile (asmFile, vFile);
1792 /* copy global & static initialisations */
1793 fprintf (asmFile, "\n%s", iComments2);
1794 fprintf (asmFile, "; global & static initialisations\n");
1795 fprintf (asmFile, "%s", iComments2);
1797 if(pic16_debug_verbose)
1798 fprintf(asmFile, "; A code from now on!\n");
1800 pic16_copypCode(asmFile, 'A');
1802 if(pic16_options.no_crt) {
1803 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1804 fprintf(asmFile, "\tcode\n");
1805 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1809 // copyFile (stderr, code->oFile);
1811 fprintf(asmFile, "; I code from now on!\n");
1812 pic16_copypCode(asmFile, 'I');
1814 if(pic16_debug_verbose)
1815 fprintf(asmFile, "; dbName from now on!\n");
1817 pic16_copypCode(asmFile, statsg->dbName);
1819 if(pic16_options.no_crt) {
1820 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1821 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1825 if(pic16_debug_verbose)
1826 fprintf(asmFile, "; X code from now on!\n");
1828 pic16_copypCode(asmFile, 'X');
1830 if(pic16_debug_verbose)
1831 fprintf(asmFile, "; M code from now on!\n");
1833 pic16_copypCode(asmFile, 'M');
1835 pic16_copypCode(asmFile, code->dbName);
1837 pic16_copypCode(asmFile, 'P');
1839 emitStatistics(asmFile);
1841 fprintf (asmFile,"\tend\n");