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_popCopyReg(pCodeOpReg *pc);
80 extern void pic16_pCodeConstString(char *name, char *value);
82 /*-----------------------------------------------------------------*/
83 /* aopLiteral - string from a literal value */
84 /*-----------------------------------------------------------------*/
85 int pic16aopLiteral (value *val, int offset)
92 /* if it is a float then it gets tricky */
93 /* otherwise it is fairly simple */
94 if (!IS_FLOAT(val->type)) {
95 unsigned long v = (unsigned long) floatFromVal(val);
97 return ( (v >> (offset * 8)) & 0xff);
100 /* it is type float */
101 fl.f = (float) floatFromVal(val);
102 #ifdef WORDS_BIGENDIAN
103 return fl.c[3-offset];
112 char tbuffer[512], *tbuf=tbuffer;;
115 /*-----------------------------------------------------------------*/
116 /* emitRegularMap - emit code for maps with no special cases */
117 /*-----------------------------------------------------------------*/
119 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
122 // int i, size, bitvars = 0;;
124 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
127 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
128 /* print the area name */
130 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
133 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
135 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
136 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
137 printTypeChain( sym->type, stderr );
138 fprintf(stderr, "\n");
141 /* if extern then add to externs */
142 if (IS_EXTERN (sym->etype)) {
143 /* reduce overhead while linking by not declaring
144 * extern unused external functions (usually declared
145 * in header files) */
146 if(IS_FUNC(sym->type) && !sym->used)continue;
148 /* make sure symbol is not in publics section */
149 if(!checkSym(publics, sym))
150 checkAddSym(&externs, sym);
154 /* if allocation required check is needed
155 * then check if the symbol really requires
156 * allocation only for local variables */
157 if (arFlag && !IS_AGGREGATE (sym->type) &&
158 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
159 !sym->allocreq && sym->level) {
161 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
166 /* if global variable & not static or extern
167 * and addPublics allowed then add it to the public set */
168 if ((sym->used) && (sym->level == 0 ||
169 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
171 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
173 checkAddSym(&publics, sym);
175 if(IS_STATIC(sym->etype)
176 && !(sym->ival && !sym->level)
179 /* add it to udata list */
181 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
182 // sym->name, sym->rname, sym->remat);
184 //, OP_SYMBOL(operandFromSymbol(sym))->name);
185 #define SET_IMPLICIT 1
188 if(IS_STRUCT(sym->type))
192 reg = pic16_allocDirReg( operandFromSymbol( sym ));
199 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
200 if(!strcmp(ssym->name, reg->name))found=1;
204 if(!found)checkAddReg(&pic16_rel_udata, reg);
208 /* if extern then do nothing or is a function
210 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
211 if(SPEC_OCLS(sym->etype) == code) {
212 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
213 checkAddSym(&publics, sym);
219 /* print extra debug info if required */
220 if (options.debug || sym->level == 0) {
221 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
223 if (!sym->level) /* global */
224 if (IS_STATIC (sym->etype))
225 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
227 fprintf (map->oFile, "G_"); /* scope is global */
229 /* symbol is local */
230 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
231 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
236 /* if is has an absolute address then generate
237 an equate for this no need to allocate space */
238 if (SPEC_ABSA (sym->etype)) {
239 // if (options.debug || sym->level == 0)
240 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
241 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
243 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
245 SPEC_ADDR (sym->etype));
247 /* emit only if it is global */
248 if(sym->level == 0) {
251 reg = pic16_dirregWithName( sym->name );
254 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
255 // __FUNCTION__, __LINE__, sym->name);
257 /* if IS_STRUCT is omitted the following
258 * fixes structures but break char/int etc */
260 if(IS_STRUCT(sym->type))
261 sym->implicit = 1; // mark as implicit
264 reg = pic16_allocDirReg( operandFromSymbol(sym) );
266 if(checkAddReg(&pic16_fix_udata, reg)) {
267 /* and add to globals list if not exist */
268 addSet(&publics, sym);
272 addSet(&publics, sym);
276 if(!sym->used && (sym->level == 0)) {
279 /* symbol not used, just declared probably, but its in
280 * level 0, so we must declare it fine as global */
282 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
285 if(IS_STRUCT(sym->type))
286 sym->implicit = 1; // mark as implicit
289 if(IS_AGGREGATE(sym->type)) {
290 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
292 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
300 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
301 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
305 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
306 if(!strcmp(ssym->name, reg->name))found=1;
311 if(checkAddReg(&pic16_rel_udata, reg)) {
312 addSetHead(&publics, sym);
321 addSetHead(&publics, sym);
326 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
327 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
328 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
329 if (IS_BITVAR (sym->etype)) {
332 fprintf (map->oFile, "\t%s\n", sym->rname);
333 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
334 for (i = 1; i < size; i++)
335 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
338 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
342 /* FIXME -- VR Fix the following, so that syms to be placed
343 * in the idata section and let linker decide about their fate */
345 /* if it has an initial value then do it only if
346 it is a global variable */
348 if (sym->ival && sym->level == 0) {
352 if(SPEC_OCLS(sym->etype)==data) {
353 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
356 if(SPEC_OCLS(sym->etype)==code) {
357 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
362 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
363 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
366 if (IS_AGGREGATE (sym->type)) {
367 if(SPEC_ABSA(sym->etype))
368 addSet(&fix_idataSymSet, copySymbol(sym));
370 addSet(&rel_idataSymSet, copySymbol(sym));
371 // ival = initAggregates (sym, sym->ival, NULL);
373 if(SPEC_ABSA(sym->etype))
374 addSet(&fix_idataSymSet, copySymbol(sym));
376 addSet(&rel_idataSymSet, copySymbol(sym));
378 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
379 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
383 setAstLineno(ival, sym->lineDef);
384 codeOutFile = statsg->oFile;
386 eBBlockFromiCode (iCodeFromAst (ival));
394 /*-----------------------------------------------------------------*/
395 /* pic16_initPointer - pointer initialization code massaging */
396 /*-----------------------------------------------------------------*/
397 value *pic16_initPointer (initList * ilist, sym_link *toType)
403 return valCastLiteral(toType, 0.0);
406 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
407 // expr = list2expr( ilist );
412 /* try it the old way first */
413 if ((val = constExprValue (expr, FALSE)))
416 /* ( ptr + constant ) */
417 if (IS_AST_OP (expr) &&
418 (expr->opval.op == '+' || expr->opval.op == '-') &&
419 IS_AST_SYM_VALUE (expr->left) &&
420 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
421 compareType(toType, expr->left->ftype) &&
422 IS_AST_LIT_VALUE (expr->right)) {
423 return valForCastAggr (expr->left, expr->left->ftype,
429 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
430 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
431 if (compareType(toType, expr->left->ftype)!=1) {
432 werror (W_INIT_WRONG);
433 printFromToType(expr->left->ftype, toType);
439 /* no then we have to do these cludgy checks */
440 /* pointers can be initialized with address of
441 a variable or address of an array element */
442 if (IS_AST_OP (expr) && expr->opval.op == '&') {
443 /* address of symbol */
444 if (IS_AST_SYM_VALUE (expr->left)) {
445 val = copyValue (AST_VALUE (expr->left));
446 val->type = newLink (DECLARATOR);
447 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
448 DCL_TYPE (val->type) = CPOINTER;
449 DCL_PTR_CONST (val->type) = port->mem.code_ro;
451 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
452 DCL_TYPE (val->type) = FPOINTER;
453 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
454 DCL_TYPE (val->type) = PPOINTER;
455 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
456 DCL_TYPE (val->type) = IPOINTER;
457 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
458 DCL_TYPE (val->type) = EEPPOINTER;
460 DCL_TYPE (val->type) = POINTER;
462 val->type->next = expr->left->ftype;
463 val->etype = getSpec (val->type);
467 /* if address of indexed array */
468 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
469 return valForArray (expr->left);
471 /* if address of structure element then
473 if (IS_AST_OP (expr->left) &&
474 expr->left->opval.op == '.') {
475 return valForStructElem (expr->left->left,
480 (&some_struct)->element */
481 if (IS_AST_OP (expr->left) &&
482 expr->left->opval.op == PTR_OP &&
483 IS_ADDRESS_OF_OP (expr->left->left)) {
484 return valForStructElem (expr->left->left->left,
488 /* case 3. (((char *) &a) +/- constant) */
489 if (IS_AST_OP (expr) &&
490 (expr->opval.op == '+' || expr->opval.op == '-') &&
491 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
492 IS_AST_OP (expr->left->right) &&
493 expr->left->right->opval.op == '&' &&
494 IS_AST_LIT_VALUE (expr->right)) {
496 return valForCastAggr (expr->left->right->left,
497 expr->left->left->opval.lnk,
498 expr->right, expr->opval.op);
501 /* case 4. (char *)(array type) */
502 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
503 IS_ARRAY(expr->right->ftype)) {
505 val = copyValue (AST_VALUE (expr->right));
506 val->type = newLink (DECLARATOR);
507 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
508 DCL_TYPE (val->type) = CPOINTER;
509 DCL_PTR_CONST (val->type) = port->mem.code_ro;
511 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
512 DCL_TYPE (val->type) = FPOINTER;
513 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
514 DCL_TYPE (val->type) = PPOINTER;
515 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
516 DCL_TYPE (val->type) = IPOINTER;
517 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
518 DCL_TYPE (val->type) = EEPPOINTER;
520 DCL_TYPE (val->type) = POINTER;
521 val->type->next = expr->right->ftype->next;
522 val->etype = getSpec (val->type);
528 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
530 werror (E_INCOMPAT_PTYPES);
536 /*-----------------------------------------------------------------*/
537 /* printPointerType - generates ival for pointer type */
538 /*-----------------------------------------------------------------*/
539 void _pic16_printPointerType (const char *name, char ptype, void *p)
543 sprintf(buf, "LOW(%s)", name);
544 pic16_emitDS(buf, ptype, p);
545 sprintf(buf, "HIGH(%s)", name);
546 pic16_emitDS(buf, ptype, p);
549 /*-----------------------------------------------------------------*/
550 /* printPointerType - generates ival for pointer type */
551 /*-----------------------------------------------------------------*/
552 void pic16_printPointerType (const char *name, char ptype, void *p)
554 _pic16_printPointerType (name, ptype, p);
555 pic16_flushDB(ptype, p);
558 /*-----------------------------------------------------------------*/
559 /* printGPointerType - generates ival for generic pointer type */
560 /*-----------------------------------------------------------------*/
561 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
562 const unsigned int type, char ptype, void *p)
566 _pic16_printPointerType (iname, ptype, p);
572 sprintf(buf, "UPPER(%s)", iname);
573 pic16_emitDS(buf, ptype, p);
577 sprintf(buf, "0x80");
578 pic16_emitDS(buf, ptype, p);
582 pic16_flushDB(ptype, p);
586 /* set to 0 to disable debug messages */
587 #define DEBUG_PRINTIVAL 0
589 /*-----------------------------------------------------------------*/
590 /* pic16_printIvalType - generates ival for int/char */
591 /*-----------------------------------------------------------------*/
593 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
598 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
601 fprintf(stderr, "%s\n",__FUNCTION__);
605 /* if initList is deep */
606 if (ilist && ilist->type == INIT_DEEP)
607 ilist = ilist->init.deep;
609 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
610 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
613 if (!(val = list2val (ilist))) {
614 // assuming a warning has been thrown
618 if (val->type != type) {
619 val = valCastLiteral(type, floatFromVal(val));
623 ulval = (unsigned long) floatFromVal (val);
627 switch (getSize (type)) {
629 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
633 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
634 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
638 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
639 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
640 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
641 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
646 /*--------------------------------------------------------------------*/
647 /* pic16_printIvalChar - generates initital value for character array */
648 /*--------------------------------------------------------------------*/
650 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
659 fprintf(stderr, "%s\n",__FUNCTION__);
665 val = list2val (ilist);
666 /* if the value is a character string */
667 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
669 if (!DCL_ELEM (type))
670 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
672 for(remain=0; remain<DCL_ELEM(type); remain++)
673 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
675 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
677 pic16_emitDB(0x00, ptype, p);
686 for(remain=0; remain<strlen(s); remain++) {
687 pic16_emitDB(s[remain], ptype, p);
693 /*-----------------------------------------------------------------*/
694 /* pic16_printIvalArray - generates code for array initialization */
695 /*-----------------------------------------------------------------*/
697 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
701 int lcnt = 0, size = 0;
708 fprintf(stderr, "%s\n",__FUNCTION__);
710 /* take care of the special case */
711 /* array of characters can be init */
713 if (IS_CHAR (type->next)) {
714 if (!IS_LITERAL(list2val(ilist)->etype)) {
715 werror (W_INIT_WRONG);
719 if(pic16_printIvalChar (type,
720 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
721 SPEC_CVAL (sym->etype).v_char, ptype, p))
724 /* not the special case */
725 if (ilist && ilist->type != INIT_DEEP)
727 werror (E_INIT_STRUCT, sym->name);
731 iloop = ilist->init.deep;
732 lcnt = DCL_ELEM (type);
737 pic16_printIval (sym, type->next, iloop, ptype, p);
738 iloop = (iloop ? iloop->next : NULL);
741 /* if not array limits given & we */
742 /* are out of initialisers then */
743 if (!DCL_ELEM (type) && !iloop)
746 /* no of elements given and we */
747 /* have generated for all of them */
749 /* if initializers left */
751 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
757 /* if we have not been given a size */
758 if (!DCL_ELEM (type))
759 DCL_ELEM (type) = size;
764 /*-----------------------------------------------------------------*/
765 /* pic16_printIvalBitFields - generate initializer for bitfields */
766 /*-----------------------------------------------------------------*/
767 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
771 initList *lilist = *ilist ;
772 unsigned long ival = 0;
777 fprintf(stderr, "%s\n",__FUNCTION__);
783 val = list2val(lilist);
785 if (SPEC_BLEN(lsym->etype) > 8) {
786 size += ((SPEC_BLEN (lsym->etype) / 8) +
787 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
790 size = ((SPEC_BLEN (lsym->etype) / 8) +
791 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
793 i = (unsigned long)floatFromVal(val);
794 i <<= SPEC_BSTR (lsym->etype);
796 if (! ( lsym->next &&
797 (IS_BITFIELD(lsym->next->type)) &&
798 (SPEC_BSTR(lsym->next->etype)))) break;
800 lilist = lilist->next;
804 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
808 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
809 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
812 case 4: /* EEP: why is this db and not dw? */
813 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
814 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
815 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
816 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
819 /* VR - only 1,2,4 size long can be handled???? Why? */
820 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
828 /*-----------------------------------------------------------------*/
829 /* printIvalStruct - generates initial value for structures */
830 /*-----------------------------------------------------------------*/
831 void pic16_printIvalStruct (symbol * sym, sym_link * type,
832 initList * ilist, char ptype, void *p)
835 initList *iloop = NULL;
839 fprintf(stderr, "%s\n",__FUNCTION__);
842 sflds = SPEC_STRUCT (type)->fields;
845 if (ilist->type != INIT_DEEP) {
846 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
850 iloop = ilist->init.deep;
853 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
854 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
855 if (IS_BITFIELD(sflds->type)) {
856 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
858 pic16_printIval (sym, sflds->type, iloop, ptype, p);
862 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
867 /*--------------------------------------------------------------------------*/
868 /* pic16_printIvalCharPtr - generates initial values for character pointers */
869 /*--------------------------------------------------------------------------*/
870 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
874 /* PENDING: this is _very_ mcs51 specific, including a magic
876 It's also endin specific.
878 VR - Attempting to port this function to pic16 port - 8-Jun-2004
883 fprintf(stderr, "%s\n",__FUNCTION__);
886 size = getSize (type);
888 if (val->name && strlen (val->name))
890 if (size == 1) /* This appears to be Z80 specific?? */
892 pic16_emitDS(val->name, ptype, p);
896 pic16_printPointerType (val->name, ptype, p);
901 if (IS_PTR (val->type)) {
902 type = DCL_TYPE (val->type);
904 type = PTR_TYPE (SPEC_OCLS (val->etype));
906 if (val->sym && val->sym->isstrlit) {
907 // this is a literal string
910 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
914 fprintf (stderr, "*** internal error: unknown size in "
915 "printIvalCharPtr.\n");
921 // these are literals assigned to pointers
925 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
928 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
929 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
932 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
933 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
934 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
942 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
943 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
944 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
950 /*-----------------------------------------------------------------------*/
951 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
952 /*-----------------------------------------------------------------------*/
953 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
960 fprintf(stderr, "%s\n",__FUNCTION__);
964 val = list2val (ilist);
966 val = valCastLiteral(type, 0.0);
969 // an error has been thrown already
973 if (IS_LITERAL(val->etype)) {
974 if (compareType(type, val->etype) == 0) {
975 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
976 printFromToType (val->type, type);
978 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
982 /* check the types */
983 if ((dLvl = compareType (val->type, type->next)) <= 0)
985 pic16_emitDB(0x00, ptype, p);
989 /* now generate the name */
991 pic16_printPointerType (val->name, ptype, p);
993 pic16_printPointerType (val->sym->rname, ptype, p);
995 if(IS_FUNC(val->sym->type) && !val->sym->used) {
997 if(!checkSym(publics, val->sym))
998 checkAddSym(&externs, val->sym);
1000 /* this has not been declared as extern
1001 * so declare it as a 'late extern' just after the symbol */
1003 fprintf((FILE *)p, "declare symbol as extern");
1004 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1005 fprintf((FILE *)p, "continue variable declaration");
1014 /*-----------------------------------------------------------------*/
1015 /* pic16_printIvalPtr - generates initial value for pointers */
1016 /*-----------------------------------------------------------------*/
1017 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1023 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1024 sym->rname, getSize(sym->type));
1028 if (ilist && (ilist->type == INIT_DEEP))
1029 ilist = ilist->init.deep;
1031 /* function pointer */
1032 if (IS_FUNC (type->next))
1034 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1038 if (!(val = pic16_initPointer (ilist, type)))
1041 /* if character pointer */
1042 if (IS_CHAR (type->next))
1043 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1046 /* check the type */
1047 if (compareType (type, val->type) == 0) {
1048 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1049 printFromToType (val->type, type);
1052 /* if val is literal */
1053 if (IS_LITERAL (val->etype))
1055 switch (getSize (type))
1058 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1061 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1062 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1065 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1066 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1067 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1070 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1077 size = getSize (type);
1079 if (size == 1) /* Z80 specific?? */
1081 pic16_emitDS(val->name, ptype, p);
1085 pic16_printPointerType (val->name, ptype, p);
1089 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1090 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1091 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1099 /*-----------------------------------------------------------------*/
1100 /* pic16_printIval - generates code for initial value */
1101 /*-----------------------------------------------------------------*/
1102 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1110 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1111 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1112 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1115 /* if structure then */
1116 if (IS_STRUCT (type))
1118 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1119 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1123 /* if this is an array */
1124 if (IS_ARRAY (type))
1126 // fprintf(stderr,"%s array\n",__FUNCTION__);
1127 pic16_printIvalArray (sym, type, ilist, ptype, p);
1134 // not an aggregate, ilist must be a node
1135 if (ilist->type!=INIT_NODE) {
1136 // or a 1-element list
1137 if (ilist->init.deep->next) {
1138 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1141 ilist=ilist->init.deep;
1146 // and the type must match
1147 itype=ilist->init.node->ftype;
1149 if (compareType(type, itype)==0) {
1150 // special case for literal strings
1151 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1152 // which are really code pointers
1153 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1156 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1157 // printFromToType(itype, type);
1164 /* if this is a pointer */
1167 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1168 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1173 /* if type is SPECIFIER */
1176 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1177 pic16_printIvalType (sym, type, ilist, ptype, p);
1182 int PIC16_IS_CONFIG_ADDRESS(int address)
1184 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1187 int PIC16_IS_IDLOC_ADDRESS(int address)
1189 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1192 /* wrapper function for the above */
1193 int PIC16_IS_HWREG_ADDRESS(int address)
1195 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1199 /*-----------------------------------------------------------------*/
1200 /* emitStaticSeg - emitcode for the static segment */
1201 /*-----------------------------------------------------------------*/
1203 pic16emitStaticSeg (memmap * map)
1206 static int didcode=0;
1208 //fprintf(stderr, "%s\n",__FUNCTION__);
1212 /* for all variables in this segment do */
1213 for (sym = setFirstItem (map->syms); sym;
1214 sym = setNextItem (map->syms))
1218 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1219 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1220 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1221 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1222 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1223 printTypeChain( sym->type, stderr );
1224 fprintf(stderr, "\n");
1227 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1228 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1229 (int) floatFromVal(list2val(sym->ival)));
1234 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1235 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1236 (char) floatFromVal(list2val(sym->ival)));
1241 /* if it is "extern" then do nothing */
1242 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1243 checkAddSym(&externs, sym);
1247 /* if it is not static add it to the public
1249 if (!IS_STATIC (sym->etype)) {
1250 /* do not emit if it is a config word declaration */
1251 checkAddSym(&publics, sym);
1254 /* print extra debug info if required */
1255 if (options.debug || sym->level == 0) {
1256 /* NOTE to me - cdbFile may be null in which case,
1257 * the sym name will be printed to stdout. oh well */
1258 debugFile->writeSymbol(sym);
1261 /* if it has an absolute address */
1262 if (SPEC_ABSA (sym->etype)) {
1263 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1264 // __FILE__, __LINE__, sym->name);
1266 /* if it has an initial value */
1274 /* symbol has absolute address and initial value */
1276 resolveIvalSym (sym->ival, sym->type);
1277 asym = newSymbol(sym->rname, 0);
1278 abSym = Safe_calloc(1, sizeof(absSym));
1279 abSym->name = Safe_strdup( sym->rname );
1280 abSym->address = SPEC_ADDR( sym->etype );
1281 addSet(&absSymSet, abSym);
1283 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1284 pic16_addpBlock(pb);
1286 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1287 PCF(pcf)->absblock = 1;
1289 pic16_addpCode2pBlock(pb,pcf);
1290 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1291 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1292 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1293 pic16_flushDB('p', (void *)pb);
1295 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1301 /* symbol has absolute address but no initial value */
1303 /* allocate space */
1304 fprintf (code->oFile, "%s:\n", sym->rname);
1306 /* special case for character strings */
1307 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1308 SPEC_CVAL (sym->etype).v_char) {
1310 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1312 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1319 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1320 // __FILE__, __LINE__, sym->name);
1323 /* if it has an initial value */
1327 /* symbol doesn't have absolute address but has initial value */
1328 fprintf (code->oFile, "%s:\n", sym->rname);
1330 resolveIvalSym (sym->ival, sym->type);
1332 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1333 pic16_addpBlock(pb);
1336 /* make sure that 'code' directive is emitted before, once */
1337 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1342 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1344 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1345 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1346 pic16_flushDB('p', (void *)pb);
1350 /* symbol doesn't have absolute address and no initial value */
1351 /* allocate space */
1352 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1353 fprintf (code->oFile, "%s:\n", sym->rname);
1354 /* special case for character strings */
1355 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1356 SPEC_CVAL (sym->etype).v_char) {
1358 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1360 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1371 /*-----------------------------------------------------------------*/
1372 /* pic16_emitConfigRegs - emits the configuration registers */
1373 /*-----------------------------------------------------------------*/
1374 void pic16_emitConfigRegs(FILE *of)
1378 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1379 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1380 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1381 pic16->cwInfo.confAddrStart+i,
1382 pic16->cwInfo.crInfo[i].value);
1385 void pic16_emitIDRegs(FILE *of)
1389 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1390 if(pic16->idInfo.irInfo[i].emit)
1391 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1392 pic16->idInfo.idAddrStart+i,
1393 pic16->idInfo.irInfo[i].value);
1400 /* no special considerations for the following
1401 data, idata & bit & xdata */
1402 pic16emitRegularMap (data, TRUE, TRUE);
1403 pic16emitRegularMap (idata, TRUE, TRUE);
1404 pic16emitRegularMap (bit, TRUE, FALSE);
1405 pic16emitRegularMap (xdata, TRUE, TRUE);
1406 pic16emitRegularMap (sfr, FALSE, FALSE);
1407 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1408 pic16emitRegularMap (code, TRUE, FALSE);
1409 pic16emitStaticSeg (statsg);
1412 /*-----------------------------------------------------------------*/
1413 /* createInterruptVect - creates the interrupt vector */
1414 /*-----------------------------------------------------------------*/
1416 pic16createInterruptVect (FILE * vFile)
1418 /* if the main is only a prototype ie. no body then do nothing */
1420 if (!IFFUNC_HASBODY(mainf->type)) {
1421 /* if ! compile only then main function should be present */
1422 if (!options.cc_only)
1428 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1429 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1430 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1432 /* this is an overkill since WE are the port,
1433 * and we know if we have a genIVT function! */
1435 port->genIVT(vFile, interrupts, maxInterrupts);
1442 /*-----------------------------------------------------------------*/
1443 /* pic16initialComments - puts in some initial comments */
1444 /*-----------------------------------------------------------------*/
1446 pic16initialComments (FILE * afile)
1448 initialComments (afile);
1449 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1450 if(pic16_mplab_comp)
1451 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1452 fprintf (afile, iComments2);
1455 /*-----------------------------------------------------------------*/
1456 /* printPublics - generates global declarations for publics */
1457 /*-----------------------------------------------------------------*/
1459 pic16printPublics (FILE *afile)
1463 fprintf (afile, "\n%s", iComments2);
1464 fprintf (afile, "; public variables in this module\n");
1465 fprintf (afile, "%s", iComments2);
1467 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1468 fprintf(afile, "\tglobal %s\n", sym->rname);
1471 /*-----------------------------------------------------------------*/
1472 /* printExterns - generates extern declarations for externs */
1473 /*-----------------------------------------------------------------*/
1475 pic16_printExterns(FILE *afile)
1479 /* print nothing if no externs to declare */
1480 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1483 fprintf(afile, "\n%s", iComments2);
1484 fprintf(afile, "; extern variables in this module\n");
1485 fprintf(afile, "%s", iComments2);
1487 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1488 fprintf(afile, "\textern %s\n", sym->rname);
1490 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1491 fprintf(afile, "\textern _%s\n", sym->name);
1494 /*-----------------------------------------------------------------*/
1495 /* emitOverlay - will emit code for the overlay stuff */
1496 /*-----------------------------------------------------------------*/
1498 pic16emitOverlay (FILE * afile)
1502 if (!elementsInSet (ovrSetSets))
1503 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1505 /* for each of the sets in the overlay segment do */
1506 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1507 ovrset = setNextItem (ovrSetSets))
1512 if (elementsInSet (ovrset))
1514 /* this dummy area is used to fool the assembler
1515 otherwise the assembler will append each of these
1516 declarations into one chunk and will not overlay
1518 fprintf (afile, ";\t.area _DUMMY\n");
1519 /* output the area informtion */
1520 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1523 for (sym = setFirstItem (ovrset); sym;
1524 sym = setNextItem (ovrset))
1527 /* if extern then do nothing */
1528 if (IS_EXTERN (sym->etype))
1531 /* if allocation required check is needed
1532 then check if the symbol really requires
1533 allocation only for local variables */
1534 if (!IS_AGGREGATE (sym->type) &&
1535 !(sym->_isparm && !IS_REGPARM (sym->etype))
1536 && !sym->allocreq && sym->level)
1539 /* if global variable & not static or extern
1540 and addPublics allowed then add it to the public set */
1541 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1542 && !IS_STATIC (sym->etype)) {
1543 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1544 checkAddSym(&publics, sym);
1545 // addSetHead (&publics, sym);
1548 /* if extern then do nothing or is a function
1550 if (IS_FUNC (sym->type))
1554 /* print extra debug info if required */
1555 if (options.debug || sym->level == 0)
1558 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1562 if (IS_STATIC (sym->etype))
1563 fprintf (afile, "F%s_", moduleName); /* scope is file */
1565 fprintf (afile, "G_"); /* scope is global */
1568 /* symbol is local */
1569 fprintf (afile, "L%s_",
1570 (sym->localof ? sym->localof->name : "-null-"));
1571 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1575 /* if is has an absolute address then generate
1576 an equate for this no need to allocate space */
1577 if (SPEC_ABSA (sym->etype))
1580 if (options.debug || sym->level == 0)
1581 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1583 fprintf (afile, "%s\t=\t0x%04x\n",
1585 SPEC_ADDR (sym->etype));
1589 if (options.debug || sym->level == 0)
1590 fprintf (afile, "==.\n");
1592 /* allocate space */
1593 fprintf (afile, "%s:\n", sym->rname);
1594 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1602 /*-----------------------------------------------------------------*/
1603 /* glue - the final glue that hold the whole thing together */
1604 /*-----------------------------------------------------------------*/
1611 FILE *ovrFile = tempfile();
1614 mainf = newSymbol ("main", 0);
1617 mainf = findSymWithLevel(SymbolTab, mainf);
1619 /* only if the main function exists */
1620 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1621 if (!options.cc_only)
1627 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1629 addSetHead(&tmpfileSet,ovrFile);
1630 pic16_pCodeInitRegisters();
1633 if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1634 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1636 pic16_addpBlock(pb);
1638 /* entry point @ start of CSEG */
1639 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1642 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1643 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1644 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1645 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1648 /* put in the call to main */
1649 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1651 if (options.mainreturn) {
1652 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1653 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1655 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1656 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1660 /* At this point we've got all the code in the form of pCode structures */
1661 /* Now it needs to be rearranged into the order it should be placed in the */
1664 pic16_movepBlock2Head('P'); // Last
1665 pic16_movepBlock2Head(code->dbName);
1666 pic16_movepBlock2Head('X');
1667 pic16_movepBlock2Head(statsg->dbName); // First
1669 /* print the global struct definitions */
1670 // if (options.debug)
1671 // cdbStructBlock (0); //,cdbFile);
1674 /* PENDING: this isnt the best place but it will do */
1675 if (port->general.glue_up_main) {
1676 /* create the interrupt vector table */
1677 pic16createInterruptVect (vFile);
1680 addSetHead(&tmpfileSet,vFile);
1682 /* emit code for the all the variables declared */
1684 /* do the overlay segments */
1685 pic16emitOverlay(ovrFile);
1686 pic16_AnalyzepCode('*');
1689 if(pic16_options.dumpcalltree) {
1691 sprintf(buffer, dstFileName);
1692 strcat(buffer, ".calltree");
1693 cFile = fopen(buffer, "w");
1694 pic16_printCallTree( cFile );
1699 pic16_InlinepCode();
1700 pic16_AnalyzepCode('*');
1702 if(pic16_debug_verbose)
1705 /* now put it all together into the assembler file */
1706 /* create the assembler file name */
1707 if ((noAssemble || options.c1mode) && fullDstFileName) {
1708 sprintf (buffer, fullDstFileName);
1710 sprintf (buffer, dstFileName);
1711 strcat (buffer, ".asm");
1714 if (!(asmFile = fopen (buffer, "w"))) {
1715 werror (E_FILE_OPEN_ERR, buffer);
1719 /* initial comments */
1720 pic16initialComments (asmFile);
1722 /* print module name */
1723 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1725 /* Let the port generate any global directives, etc. */
1726 if (port->genAssemblerPreamble) {
1727 port->genAssemblerPreamble(asmFile);
1730 /* print the extern variables to this module */
1731 pic16_printExterns(asmFile);
1733 /* print the global variables in this module */
1734 pic16printPublics (asmFile);
1737 /* copy the sfr segment */
1738 fprintf (asmFile, "%s", iComments2);
1739 fprintf (asmFile, "; special function registers\n");
1740 fprintf (asmFile, "%s", iComments2);
1741 copyFile (asmFile, sfr->oFile);
1744 /* Put all variables into a cblock */
1745 pic16_AnalyzeBanking();
1746 pic16_writeUsedRegs(asmFile);
1749 /* no xdata in pic */
1750 /* if external stack then reserve space of it */
1751 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1752 fprintf (asmFile, "%s", iComments2);
1753 fprintf (asmFile, "; external stack \n");
1754 fprintf (asmFile, "%s", iComments2);
1755 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1756 fprintf (asmFile,";\t.ds 256\n");
1761 /* no xdata in pic */
1762 /* copy xtern ram data */
1763 fprintf (asmFile, "%s", iComments2);
1764 fprintf (asmFile, "; external ram data\n");
1765 fprintf (asmFile, "%s", iComments2);
1766 copyFile (asmFile, xdata->oFile);
1770 /* copy the bit segment */
1771 fprintf (asmFile, "%s", iComments2);
1772 fprintf (asmFile, "; bit data\n");
1773 fprintf (asmFile, "%s", iComments2);
1774 copyFile (asmFile, bit->oFile);
1777 /* copy the interrupt vector table */
1778 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1779 fprintf (asmFile, "\n%s", iComments2);
1780 fprintf (asmFile, "; interrupt vector \n");
1781 fprintf (asmFile, "%s", iComments2);
1782 copyFile (asmFile, vFile);
1785 /* copy global & static initialisations */
1786 fprintf (asmFile, "\n%s", iComments2);
1787 fprintf (asmFile, "; global & static initialisations\n");
1788 fprintf (asmFile, "%s", iComments2);
1790 if(pic16_debug_verbose)
1791 fprintf(asmFile, "; A code from now on!\n");
1792 pic16_copypCode(asmFile, 'A');
1795 if(pic16_options.no_crt) {
1796 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1797 fprintf(asmFile, "\tcode\n");
1798 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1802 // copyFile (stderr, code->oFile);
1804 fprintf(asmFile, "; I code from now on!\n");
1805 pic16_copypCode(asmFile, 'I');
1807 if(pic16_debug_verbose)
1808 fprintf(asmFile, "; dbName from now on!\n");
1809 pic16_copypCode(asmFile, statsg->dbName);
1812 if(pic16_options.no_crt) {
1813 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1814 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1819 if(pic16_debug_verbose)
1820 fprintf(asmFile, "; X code from now on!\n");
1821 pic16_copypCode(asmFile, 'X');
1823 if(pic16_debug_verbose)
1824 fprintf(asmFile, "; M code from now on!\n");
1825 pic16_copypCode(asmFile, 'M');
1828 pic16_copypCode(asmFile, code->dbName);
1830 pic16_copypCode(asmFile, 'P');
1832 fprintf (asmFile,"\tend\n");