1 /*-------------------------------------------------------------------------
3 glue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #include "../common.h"
38 #ifdef WORDS_BIGENDIAN
39 #define _ENDIAN(x) (3-x)
41 #define _ENDIAN(x) (x)
44 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
46 extern symbol *interrupts[256];
47 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
51 extern unsigned maxInterrupts;
52 extern int maxRegBank;
54 extern char *VersionString;
55 extern FILE *codeOutFile;
56 extern set *tmpfileSet;
57 extern set *tmpfileNameSet;
58 extern char *iComments1;
59 extern char *iComments2;
60 //extern void emitStaticSeg (memmap * map);
64 set *rel_idataSymSet=NULL;
65 set *fix_idataSymSet=NULL;
67 extern DEFSETFUNC (closeTmpFiles);
68 extern DEFSETFUNC (rmTmpFiles);
70 extern void pic16_AnalyzeBanking (void);
71 extern void copyFile (FILE * dest, FILE * src);
72 extern void pic16_InlinepCode(void);
73 extern void pic16_writeUsedRegs(FILE *);
75 extern void initialComments (FILE * afile);
76 extern void printPublics (FILE * afile);
78 void pic16_pCodeInitRegisters(void);
79 pCodeOp *pic16_popGetLit(unsigned int lit);
80 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
81 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
82 extern void pic16_pCodeConstString(char *name, char *value);
84 /*-----------------------------------------------------------------*/
85 /* aopLiteral - string from a literal value */
86 /*-----------------------------------------------------------------*/
87 int pic16aopLiteral (value *val, int offset)
94 /* if it is a float then it gets tricky */
95 /* otherwise it is fairly simple */
96 if (!IS_FLOAT(val->type)) {
97 unsigned long v = (unsigned long) floatFromVal(val);
99 return ( (v >> (offset * 8)) & 0xff);
102 /* it is type float */
103 fl.f = (float) floatFromVal(val);
104 #ifdef WORDS_BIGENDIAN
105 return fl.c[3-offset];
114 char tbuffer[512], *tbuf=tbuffer;;
117 /*-----------------------------------------------------------------*/
118 /* emitRegularMap - emit code for maps with no special cases */
119 /*-----------------------------------------------------------------*/
121 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
124 // int i, size, bitvars = 0;;
126 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
129 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
130 /* print the area name */
132 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
135 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
137 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
138 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
139 printTypeChain( sym->type, stderr );
140 fprintf(stderr, "\n");
143 /* if extern then add to externs */
144 if (IS_EXTERN (sym->etype)) {
145 /* reduce overhead while linking by not declaring
146 * extern unused external functions (usually declared
147 * in header files) */
148 if(IS_FUNC(sym->type) && !sym->used)continue;
150 /* make sure symbol is not in publics section */
151 if(!checkSym(publics, sym))
152 checkAddSym(&externs, sym);
156 /* if allocation required check is needed
157 * then check if the symbol really requires
158 * allocation only for local variables */
159 if (arFlag && !IS_AGGREGATE (sym->type) &&
160 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
161 !sym->allocreq && sym->level) {
163 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
168 /* if global variable & not static or extern
169 * and addPublics allowed then add it to the public set */
170 if ((sym->used) && (sym->level == 0 ||
171 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
173 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
175 checkAddSym(&publics, sym);
177 if(IS_STATIC(sym->etype)
178 && !(sym->ival && !sym->level)
181 /* add it to udata list */
183 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
184 // sym->name, sym->rname, sym->remat);
186 //, OP_SYMBOL(operandFromSymbol(sym))->name);
187 #define SET_IMPLICIT 1
190 if(IS_STRUCT(sym->type))
194 reg = pic16_allocDirReg( operandFromSymbol( sym ));
201 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
202 if(!strcmp(ssym->name, reg->name))found=1;
206 if(!found)checkAddReg(&pic16_rel_udata, reg);
210 /* if extern then do nothing or is a function
212 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
213 if(SPEC_OCLS(sym->etype) == code) {
214 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
215 checkAddSym(&publics, sym);
221 /* print extra debug info if required */
222 if (options.debug || sym->level == 0) {
223 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
225 if (!sym->level) /* global */
226 if (IS_STATIC (sym->etype))
227 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
229 fprintf (map->oFile, "G_"); /* scope is global */
231 /* symbol is local */
232 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
233 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
238 /* if is has an absolute address then generate
239 an equate for this no need to allocate space */
240 if (SPEC_ABSA (sym->etype)) {
241 // if (options.debug || sym->level == 0)
242 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
243 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
245 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
247 SPEC_ADDR (sym->etype));
249 /* emit only if it is global */
250 if(sym->level == 0) {
253 reg = pic16_dirregWithName( sym->name );
256 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
257 // __FUNCTION__, __LINE__, sym->name);
259 /* if IS_STRUCT is omitted the following
260 * fixes structures but break char/int etc */
262 if(IS_STRUCT(sym->type))
263 sym->implicit = 1; // mark as implicit
266 reg = pic16_allocDirReg( operandFromSymbol(sym) );
268 if(checkAddReg(&pic16_fix_udata, reg)) {
269 /* and add to globals list if not exist */
270 addSet(&publics, sym);
274 addSet(&publics, sym);
278 if(!sym->used && (sym->level == 0)) {
281 /* symbol not used, just declared probably, but its in
282 * level 0, so we must declare it fine as global */
284 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
287 if(IS_STRUCT(sym->type))
288 sym->implicit = 1; // mark as implicit
291 if(IS_AGGREGATE(sym->type)) {
292 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
294 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
301 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
302 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
304 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
305 if(!strcmp(ssym->name, reg->name))found=1;
310 if(checkAddReg(&pic16_rel_udata, reg)) {
311 addSetHead(&publics, sym);
320 addSetHead(&publics, sym);
325 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
326 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
327 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
328 if (IS_BITVAR (sym->etype)) {
331 fprintf (map->oFile, "\t%s\n", sym->rname);
332 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
333 for (i = 1; i < size; i++)
334 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
337 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
341 /* FIXME -- VR Fix the following, so that syms to be placed
342 * in the idata section and let linker decide about their fate */
344 /* if it has an initial value then do it only if
345 it is a global variable */
347 if (sym->ival && sym->level == 0) {
351 if(SPEC_OCLS(sym->etype)==data) {
352 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
355 if(SPEC_OCLS(sym->etype)==code) {
356 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
361 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
362 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
365 if (IS_AGGREGATE (sym->type)) {
366 if(SPEC_ABSA(sym->etype))
367 addSet(&fix_idataSymSet, copySymbol(sym));
369 addSet(&rel_idataSymSet, copySymbol(sym));
370 // ival = initAggregates (sym, sym->ival, NULL);
372 if(SPEC_ABSA(sym->etype))
373 addSet(&fix_idataSymSet, copySymbol(sym));
375 addSet(&rel_idataSymSet, copySymbol(sym));
377 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
378 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
382 setAstLineno(ival, sym->lineDef);
383 codeOutFile = statsg->oFile;
385 eBBlockFromiCode (iCodeFromAst (ival));
393 /*-----------------------------------------------------------------*/
394 /* pic16_initPointer - pointer initialization code massaging */
395 /*-----------------------------------------------------------------*/
396 value *pic16_initPointer (initList * ilist, sym_link *toType)
402 return valCastLiteral(toType, 0.0);
405 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
406 // expr = list2expr( ilist );
411 /* try it the old way first */
412 if ((val = constExprValue (expr, FALSE)))
415 /* ( ptr + constant ) */
416 if (IS_AST_OP (expr) &&
417 (expr->opval.op == '+' || expr->opval.op == '-') &&
418 IS_AST_SYM_VALUE (expr->left) &&
419 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
420 compareType(toType, expr->left->ftype) &&
421 IS_AST_LIT_VALUE (expr->right)) {
422 return valForCastAggr (expr->left, expr->left->ftype,
428 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
429 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
430 if (compareType(toType, expr->left->ftype)!=1) {
431 werror (W_INIT_WRONG);
432 printFromToType(expr->left->ftype, toType);
438 /* no then we have to do these cludgy checks */
439 /* pointers can be initialized with address of
440 a variable or address of an array element */
441 if (IS_AST_OP (expr) && expr->opval.op == '&') {
442 /* address of symbol */
443 if (IS_AST_SYM_VALUE (expr->left)) {
444 val = copyValue (AST_VALUE (expr->left));
445 val->type = newLink (DECLARATOR);
446 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
447 DCL_TYPE (val->type) = CPOINTER;
448 DCL_PTR_CONST (val->type) = port->mem.code_ro;
450 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
451 DCL_TYPE (val->type) = FPOINTER;
452 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
453 DCL_TYPE (val->type) = PPOINTER;
454 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
455 DCL_TYPE (val->type) = IPOINTER;
456 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
457 DCL_TYPE (val->type) = EEPPOINTER;
459 DCL_TYPE (val->type) = POINTER;
461 val->type->next = expr->left->ftype;
462 val->etype = getSpec (val->type);
466 /* if address of indexed array */
467 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
468 return valForArray (expr->left);
470 /* if address of structure element then
472 if (IS_AST_OP (expr->left) &&
473 expr->left->opval.op == '.') {
474 return valForStructElem (expr->left->left,
479 (&some_struct)->element */
480 if (IS_AST_OP (expr->left) &&
481 expr->left->opval.op == PTR_OP &&
482 IS_ADDRESS_OF_OP (expr->left->left)) {
483 return valForStructElem (expr->left->left->left,
487 /* case 3. (((char *) &a) +/- constant) */
488 if (IS_AST_OP (expr) &&
489 (expr->opval.op == '+' || expr->opval.op == '-') &&
490 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
491 IS_AST_OP (expr->left->right) &&
492 expr->left->right->opval.op == '&' &&
493 IS_AST_LIT_VALUE (expr->right)) {
495 return valForCastAggr (expr->left->right->left,
496 expr->left->left->opval.lnk,
497 expr->right, expr->opval.op);
500 /* case 4. (char *)(array type) */
501 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
502 IS_ARRAY(expr->right->ftype)) {
504 val = copyValue (AST_VALUE (expr->right));
505 val->type = newLink (DECLARATOR);
506 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
507 DCL_TYPE (val->type) = CPOINTER;
508 DCL_PTR_CONST (val->type) = port->mem.code_ro;
510 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
511 DCL_TYPE (val->type) = FPOINTER;
512 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
513 DCL_TYPE (val->type) = PPOINTER;
514 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
515 DCL_TYPE (val->type) = IPOINTER;
516 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
517 DCL_TYPE (val->type) = EEPPOINTER;
519 DCL_TYPE (val->type) = POINTER;
520 val->type->next = expr->right->ftype->next;
521 val->etype = getSpec (val->type);
527 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
529 werror (E_INCOMPAT_PTYPES);
535 /*-----------------------------------------------------------------*/
536 /* printPointerType - generates ival for pointer type */
537 /*-----------------------------------------------------------------*/
538 void _pic16_printPointerType (const char *name, char ptype, void *p)
542 sprintf(buf, "LOW(%s)", name);
543 pic16_emitDS(buf, ptype, p);
544 sprintf(buf, "HIGH(%s)", name);
545 pic16_emitDS(buf, ptype, p);
548 /*-----------------------------------------------------------------*/
549 /* printPointerType - generates ival for pointer type */
550 /*-----------------------------------------------------------------*/
551 void pic16_printPointerType (const char *name, char ptype, void *p)
553 _pic16_printPointerType (name, ptype, p);
554 pic16_flushDB(ptype, p);
557 /*-----------------------------------------------------------------*/
558 /* printGPointerType - generates ival for generic pointer type */
559 /*-----------------------------------------------------------------*/
560 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
561 const unsigned int type, char ptype, void *p)
563 _pic16_printPointerType (iname, ptype, p);
565 if(itype == FPOINTER || itype == CPOINTER) { // || itype == GPOINTER) {
568 sprintf(buf, "UPPER(%s)", iname);
569 pic16_emitDS(buf, ptype, p);
572 pic16_flushDB(ptype, p);
576 /* set to 0 to disable debug messages */
577 #define DEBUG_PRINTIVAL 0
579 /*-----------------------------------------------------------------*/
580 /* pic16_printIvalType - generates ival for int/char */
581 /*-----------------------------------------------------------------*/
583 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
588 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
591 fprintf(stderr, "%s\n",__FUNCTION__);
595 /* if initList is deep */
596 if (ilist && ilist->type == INIT_DEEP)
597 ilist = ilist->init.deep;
599 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
600 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
603 if (!(val = list2val (ilist))) {
604 // assuming a warning has been thrown
608 if (val->type != type) {
609 val = valCastLiteral(type, floatFromVal(val));
613 ulval = (unsigned long) floatFromVal (val);
617 switch (getSize (type)) {
619 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
623 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
624 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
628 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
629 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
630 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
631 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
636 /*--------------------------------------------------------------------*/
637 /* pic16_printIvalChar - generates initital value for character array */
638 /*--------------------------------------------------------------------*/
640 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
649 fprintf(stderr, "%s\n",__FUNCTION__);
655 val = list2val (ilist);
656 /* if the value is a character string */
657 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
659 if (!DCL_ELEM (type))
660 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
662 for(remain=0; remain<DCL_ELEM(type); remain++)
663 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
665 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
667 pic16_emitDB(0x00, ptype, p);
676 for(remain=0; remain<strlen(s); remain++) {
677 pic16_emitDB(s[remain], ptype, p);
683 /*-----------------------------------------------------------------*/
684 /* pic16_printIvalArray - generates code for array initialization */
685 /*-----------------------------------------------------------------*/
687 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
691 int lcnt = 0, size = 0;
698 fprintf(stderr, "%s\n",__FUNCTION__);
700 /* take care of the special case */
701 /* array of characters can be init */
703 if (IS_CHAR (type->next)) {
704 if (!IS_LITERAL(list2val(ilist)->etype)) {
705 werror (W_INIT_WRONG);
709 if(pic16_printIvalChar (type,
710 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
711 SPEC_CVAL (sym->etype).v_char, ptype, p))
714 /* not the special case */
715 if (ilist && ilist->type != INIT_DEEP)
717 werror (E_INIT_STRUCT, sym->name);
721 iloop = ilist->init.deep;
722 lcnt = DCL_ELEM (type);
727 pic16_printIval (sym, type->next, iloop, ptype, p);
728 iloop = (iloop ? iloop->next : NULL);
731 /* if not array limits given & we */
732 /* are out of initialisers then */
733 if (!DCL_ELEM (type) && !iloop)
736 /* no of elements given and we */
737 /* have generated for all of them */
739 /* if initializers left */
741 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
747 /* if we have not been given a size */
748 if (!DCL_ELEM (type))
749 DCL_ELEM (type) = size;
754 /*-----------------------------------------------------------------*/
755 /* pic16_printIvalBitFields - generate initializer for bitfields */
756 /*-----------------------------------------------------------------*/
757 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
761 initList *lilist = *ilist ;
762 unsigned long ival = 0;
767 fprintf(stderr, "%s\n",__FUNCTION__);
773 val = list2val(lilist);
775 if (SPEC_BLEN(lsym->etype) > 8) {
776 size += ((SPEC_BLEN (lsym->etype) / 8) +
777 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
780 size = ((SPEC_BLEN (lsym->etype) / 8) +
781 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
783 i = (unsigned long)floatFromVal(val);
784 i <<= SPEC_BSTR (lsym->etype);
786 if (! ( lsym->next &&
787 (IS_BITFIELD(lsym->next->type)) &&
788 (SPEC_BSTR(lsym->next->etype)))) break;
790 lilist = lilist->next;
794 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
798 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
799 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
802 case 4: /* EEP: why is this db and not dw? */
803 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
804 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
805 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
806 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
809 /* VR - only 1,2,4 size long can be handled???? Why? */
810 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
818 /*-----------------------------------------------------------------*/
819 /* printIvalStruct - generates initial value for structures */
820 /*-----------------------------------------------------------------*/
821 void pic16_printIvalStruct (symbol * sym, sym_link * type,
822 initList * ilist, char ptype, void *p)
825 initList *iloop = NULL;
829 fprintf(stderr, "%s\n",__FUNCTION__);
832 sflds = SPEC_STRUCT (type)->fields;
835 if (ilist->type != INIT_DEEP) {
836 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
840 iloop = ilist->init.deep;
843 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
844 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
845 if (IS_BITFIELD(sflds->type)) {
846 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
848 pic16_printIval (sym, sflds->type, iloop, ptype, p);
852 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
857 /*--------------------------------------------------------------------------*/
858 /* pic16_printIvalCharPtr - generates initial values for character pointers */
859 /*--------------------------------------------------------------------------*/
860 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
864 /* PENDING: this is _very_ mcs51 specific, including a magic
866 It's also endin specific.
868 VR - Attempting to port this function to pic16 port - 8-Jun-2004
873 fprintf(stderr, "%s\n",__FUNCTION__);
876 size = getSize (type);
878 if (val->name && strlen (val->name))
880 if (size == 1) /* This appears to be Z80 specific?? */
882 pic16_emitDS(val->name, ptype, p);
886 pic16_printPointerType (val->name, ptype, p);
891 if (IS_PTR (val->type)) {
892 type = DCL_TYPE (val->type);
894 type = PTR_TYPE (SPEC_OCLS (val->etype));
896 if (val->sym && val->sym->isstrlit) {
897 // this is a literal string
900 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
904 fprintf (stderr, "*** internal error: unknown size in "
905 "printIvalCharPtr.\n");
911 // these are literals assigned to pointers
915 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
918 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
919 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
922 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
923 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
924 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
932 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
933 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
934 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
940 /*-----------------------------------------------------------------------*/
941 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
942 /*-----------------------------------------------------------------------*/
943 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
950 fprintf(stderr, "%s\n",__FUNCTION__);
954 val = list2val (ilist);
956 val = valCastLiteral(type, 0.0);
959 // an error has been thrown already
963 if (IS_LITERAL(val->etype)) {
964 if (compareType(type, val->etype) == 0) {
965 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
966 printFromToType (val->type, type);
968 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
972 /* check the types */
973 if ((dLvl = compareType (val->type, type->next)) <= 0)
975 pic16_emitDB(0x00, ptype, p);
979 /* now generate the name */
981 pic16_printPointerType (val->name, ptype, p);
983 pic16_printPointerType (val->sym->rname, ptype, p);
985 if(IS_FUNC(val->sym->type) && !val->sym->used) {
987 if(!checkSym(publics, val->sym))
988 checkAddSym(&externs, val->sym);
990 /* this has not been declared as extern
991 * so declare it as a 'late extern' just after the symbol */
993 fprintf((FILE *)p, "declare symbol as extern");
994 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
995 fprintf((FILE *)p, "continue variable declaration");
1004 /*-----------------------------------------------------------------*/
1005 /* pic16_printIvalPtr - generates initial value for pointers */
1006 /*-----------------------------------------------------------------*/
1007 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1013 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1014 sym->rname, getSize(sym->type));
1018 if (ilist && (ilist->type == INIT_DEEP))
1019 ilist = ilist->init.deep;
1021 /* function pointer */
1022 if (IS_FUNC (type->next))
1024 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1028 if (!(val = pic16_initPointer (ilist, type)))
1031 /* if character pointer */
1032 if (IS_CHAR (type->next))
1033 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1036 /* check the type */
1037 if (compareType (type, val->type) == 0) {
1038 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1039 printFromToType (val->type, type);
1042 /* if val is literal */
1043 if (IS_LITERAL (val->etype))
1045 switch (getSize (type))
1048 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1051 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1052 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1055 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1056 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1057 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1065 size = getSize (type);
1067 if (size == 1) /* Z80 specific?? */
1069 pic16_emitDS(val->name, ptype, p);
1073 pic16_printPointerType (val->name, ptype, p);
1077 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1078 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1079 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1087 /*-----------------------------------------------------------------*/
1088 /* pic16_printIval - generates code for initial value */
1089 /*-----------------------------------------------------------------*/
1090 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1098 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1099 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1100 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1103 /* if structure then */
1104 if (IS_STRUCT (type))
1106 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1107 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1111 /* if this is an array */
1112 if (IS_ARRAY (type))
1114 // fprintf(stderr,"%s array\n",__FUNCTION__);
1115 pic16_printIvalArray (sym, type, ilist, ptype, p);
1122 // not an aggregate, ilist must be a node
1123 if (ilist->type!=INIT_NODE) {
1124 // or a 1-element list
1125 if (ilist->init.deep->next) {
1126 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1129 ilist=ilist->init.deep;
1134 // and the type must match
1135 itype=ilist->init.node->ftype;
1137 if (compareType(type, itype)==0) {
1138 // special case for literal strings
1139 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1140 // which are really code pointers
1141 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1144 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1145 // printFromToType(itype, type);
1152 /* if this is a pointer */
1155 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1156 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1161 /* if type is SPECIFIER */
1164 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1165 pic16_printIvalType (sym, type, ilist, ptype, p);
1170 int PIC16_IS_CONFIG_ADDRESS(int address)
1172 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1175 int PIC16_IS_IDLOC_ADDRESS(int address)
1177 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1180 /* wrapper function for the above */
1181 int PIC16_IS_HWREG_ADDRESS(int address)
1183 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1187 /*-----------------------------------------------------------------*/
1188 /* emitStaticSeg - emitcode for the static segment */
1189 /*-----------------------------------------------------------------*/
1191 pic16emitStaticSeg (memmap * map)
1194 static int didcode=0;
1196 //fprintf(stderr, "%s\n",__FUNCTION__);
1200 /* for all variables in this segment do */
1201 for (sym = setFirstItem (map->syms); sym;
1202 sym = setNextItem (map->syms))
1206 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1207 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1208 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1209 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1210 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1211 printTypeChain( sym->type, stderr );
1212 fprintf(stderr, "\n");
1215 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1216 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1217 (int) floatFromVal(list2val(sym->ival)));
1222 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1223 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1224 (char) floatFromVal(list2val(sym->ival)));
1229 /* if it is "extern" then do nothing */
1230 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1231 checkAddSym(&externs, sym);
1235 /* if it is not static add it to the public
1237 if (!IS_STATIC (sym->etype)) {
1238 /* do not emit if it is a config word declaration */
1239 checkAddSym(&publics, sym);
1242 /* print extra debug info if required */
1243 if (options.debug || sym->level == 0) {
1244 /* NOTE to me - cdbFile may be null in which case,
1245 * the sym name will be printed to stdout. oh well */
1246 debugFile->writeSymbol(sym);
1249 /* if it has an absolute address */
1250 if (SPEC_ABSA (sym->etype)) {
1251 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1252 // __FILE__, __LINE__, sym->name);
1254 /* if it has an initial value */
1262 /* symbol has absolute address and initial value */
1264 resolveIvalSym (sym->ival, sym->type);
1265 asym = newSymbol(sym->rname, 0);
1266 abSym = Safe_calloc(1, sizeof(absSym));
1267 abSym->name = Safe_strdup( sym->rname );
1268 abSym->address = SPEC_ADDR( sym->etype );
1269 addSet(&absSymSet, abSym);
1271 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1272 pic16_addpBlock(pb);
1274 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1275 PCF(pcf)->absblock = 1;
1277 pic16_addpCode2pBlock(pb,pcf);
1278 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1279 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1280 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1281 pic16_flushDB('p', (void *)pb);
1283 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1289 /* symbol has absolute address but no initial value */
1291 /* allocate space */
1292 fprintf (code->oFile, "%s:\n", sym->rname);
1294 /* special case for character strings */
1295 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1296 SPEC_CVAL (sym->etype).v_char) {
1298 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1300 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1307 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1308 // __FILE__, __LINE__, sym->name);
1311 /* if it has an initial value */
1315 /* symbol doesn't have absolute address but has initial value */
1316 fprintf (code->oFile, "%s:\n", sym->rname);
1318 resolveIvalSym (sym->ival, sym->type);
1320 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1321 pic16_addpBlock(pb);
1324 /* make sure that 'code' directive is emitted before, once */
1325 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1330 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1332 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1333 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1334 pic16_flushDB('p', (void *)pb);
1338 /* symbol doesn't have absolute address and no initial value */
1339 /* allocate space */
1340 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1341 fprintf (code->oFile, "%s:\n", sym->rname);
1342 /* special case for character strings */
1343 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1344 SPEC_CVAL (sym->etype).v_char) {
1346 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1348 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1359 /*-----------------------------------------------------------------*/
1360 /* pic16_emitConfigRegs - emits the configuration registers */
1361 /*-----------------------------------------------------------------*/
1362 void pic16_emitConfigRegs(FILE *of)
1366 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1367 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1368 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1369 pic16->cwInfo.confAddrStart+i,
1370 pic16->cwInfo.crInfo[i].value);
1373 void pic16_emitIDRegs(FILE *of)
1377 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1378 if(pic16->idInfo.irInfo[i].emit)
1379 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1380 pic16->idInfo.idAddrStart+i,
1381 pic16->idInfo.irInfo[i].value);
1388 /* no special considerations for the following
1389 data, idata & bit & xdata */
1390 pic16emitRegularMap (data, TRUE, TRUE);
1391 pic16emitRegularMap (idata, TRUE, TRUE);
1392 pic16emitRegularMap (bit, TRUE, FALSE);
1393 pic16emitRegularMap (xdata, TRUE, TRUE);
1394 pic16emitRegularMap (sfr, FALSE, FALSE);
1395 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1396 pic16emitRegularMap (code, TRUE, FALSE);
1397 pic16emitStaticSeg (statsg);
1400 /*-----------------------------------------------------------------*/
1401 /* createInterruptVect - creates the interrupt vector */
1402 /*-----------------------------------------------------------------*/
1404 pic16createInterruptVect (FILE * vFile)
1406 /* if the main is only a prototype ie. no body then do nothing */
1408 if (!IFFUNC_HASBODY(mainf->type)) {
1409 /* if ! compile only then main function should be present */
1410 if (!options.cc_only)
1416 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1417 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1418 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1420 /* this is an overkill since WE are the port,
1421 * and we know if we have a genIVT function! */
1423 port->genIVT(vFile, interrupts, maxInterrupts);
1430 /*-----------------------------------------------------------------*/
1431 /* pic16initialComments - puts in some initial comments */
1432 /*-----------------------------------------------------------------*/
1434 pic16initialComments (FILE * afile)
1436 initialComments (afile);
1437 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1438 if(pic16_mplab_comp)
1439 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1440 fprintf (afile, iComments2);
1443 /*-----------------------------------------------------------------*/
1444 /* printPublics - generates global declarations for publics */
1445 /*-----------------------------------------------------------------*/
1447 pic16printPublics (FILE *afile)
1451 fprintf (afile, "\n%s", iComments2);
1452 fprintf (afile, "; public variables in this module\n");
1453 fprintf (afile, "%s", iComments2);
1455 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1456 fprintf(afile, "\tglobal %s\n", sym->rname);
1459 /*-----------------------------------------------------------------*/
1460 /* printExterns - generates extern declarations for externs */
1461 /*-----------------------------------------------------------------*/
1463 pic16_printExterns(FILE *afile)
1467 /* print nothing if no externs to declare */
1468 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1471 fprintf(afile, "\n%s", iComments2);
1472 fprintf(afile, "; extern variables in this module\n");
1473 fprintf(afile, "%s", iComments2);
1475 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1476 fprintf(afile, "\textern %s\n", sym->rname);
1478 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1479 fprintf(afile, "\textern _%s\n", sym->name);
1482 /*-----------------------------------------------------------------*/
1483 /* emitOverlay - will emit code for the overlay stuff */
1484 /*-----------------------------------------------------------------*/
1486 pic16emitOverlay (FILE * afile)
1490 if (!elementsInSet (ovrSetSets))
1491 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1493 /* for each of the sets in the overlay segment do */
1494 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1495 ovrset = setNextItem (ovrSetSets))
1500 if (elementsInSet (ovrset))
1502 /* this dummy area is used to fool the assembler
1503 otherwise the assembler will append each of these
1504 declarations into one chunk and will not overlay
1506 fprintf (afile, ";\t.area _DUMMY\n");
1507 /* output the area informtion */
1508 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1511 for (sym = setFirstItem (ovrset); sym;
1512 sym = setNextItem (ovrset))
1515 /* if extern then do nothing */
1516 if (IS_EXTERN (sym->etype))
1519 /* if allocation required check is needed
1520 then check if the symbol really requires
1521 allocation only for local variables */
1522 if (!IS_AGGREGATE (sym->type) &&
1523 !(sym->_isparm && !IS_REGPARM (sym->etype))
1524 && !sym->allocreq && sym->level)
1527 /* if global variable & not static or extern
1528 and addPublics allowed then add it to the public set */
1529 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1530 && !IS_STATIC (sym->etype)) {
1531 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1532 checkAddSym(&publics, sym);
1533 // addSetHead (&publics, sym);
1536 /* if extern then do nothing or is a function
1538 if (IS_FUNC (sym->type))
1542 /* print extra debug info if required */
1543 if (options.debug || sym->level == 0)
1546 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1550 if (IS_STATIC (sym->etype))
1551 fprintf (afile, "F%s_", moduleName); /* scope is file */
1553 fprintf (afile, "G_"); /* scope is global */
1556 /* symbol is local */
1557 fprintf (afile, "L%s_",
1558 (sym->localof ? sym->localof->name : "-null-"));
1559 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1563 /* if is has an absolute address then generate
1564 an equate for this no need to allocate space */
1565 if (SPEC_ABSA (sym->etype))
1568 if (options.debug || sym->level == 0)
1569 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1571 fprintf (afile, "%s\t=\t0x%04x\n",
1573 SPEC_ADDR (sym->etype));
1577 if (options.debug || sym->level == 0)
1578 fprintf (afile, "==.\n");
1580 /* allocate space */
1581 fprintf (afile, "%s:\n", sym->rname);
1582 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1590 /*-----------------------------------------------------------------*/
1591 /* glue - the final glue that hold the whole thing together */
1592 /*-----------------------------------------------------------------*/
1599 FILE *ovrFile = tempfile();
1602 mainf = newSymbol ("main", 0);
1605 mainf = findSymWithLevel(SymbolTab, mainf);
1607 /* only if the main function exists */
1608 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1609 if (!options.cc_only)
1615 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1617 addSetHead(&tmpfileSet,ovrFile);
1618 pic16_pCodeInitRegisters();
1621 if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1622 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1624 pic16_addpBlock(pb);
1626 /* entry point @ start of CSEG */
1627 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1630 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1631 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1632 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1633 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1636 /* put in the call to main */
1637 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1639 if (options.mainreturn) {
1640 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1641 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1643 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1644 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1648 /* At this point we've got all the code in the form of pCode structures */
1649 /* Now it needs to be rearranged into the order it should be placed in the */
1652 pic16_movepBlock2Head('P'); // Last
1653 pic16_movepBlock2Head(code->dbName);
1654 pic16_movepBlock2Head('X');
1655 pic16_movepBlock2Head(statsg->dbName); // First
1657 /* print the global struct definitions */
1658 // if (options.debug)
1659 // cdbStructBlock (0); //,cdbFile);
1662 /* PENDING: this isnt the best place but it will do */
1663 if (port->general.glue_up_main) {
1664 /* create the interrupt vector table */
1665 pic16createInterruptVect (vFile);
1668 addSetHead(&tmpfileSet,vFile);
1670 /* emit code for the all the variables declared */
1672 /* do the overlay segments */
1673 pic16emitOverlay(ovrFile);
1674 pic16_AnalyzepCode('*');
1677 if(pic16_options.dumpcalltree) {
1679 sprintf(buffer, dstFileName);
1680 strcat(buffer, ".calltree");
1681 cFile = fopen(buffer, "w");
1682 pic16_printCallTree( cFile );
1687 pic16_InlinepCode();
1688 pic16_AnalyzepCode('*');
1690 if(pic16_debug_verbose)
1693 /* now put it all together into the assembler file */
1694 /* create the assembler file name */
1695 if ((noAssemble || options.c1mode) && fullDstFileName) {
1696 sprintf (buffer, fullDstFileName);
1698 sprintf (buffer, dstFileName);
1699 strcat (buffer, ".asm");
1702 if (!(asmFile = fopen (buffer, "w"))) {
1703 werror (E_FILE_OPEN_ERR, buffer);
1707 /* initial comments */
1708 pic16initialComments (asmFile);
1710 /* print module name */
1711 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1713 /* Let the port generate any global directives, etc. */
1714 if (port->genAssemblerPreamble) {
1715 port->genAssemblerPreamble(asmFile);
1718 /* print the extern variables to this module */
1719 pic16_printExterns(asmFile);
1721 /* print the global variables in this module */
1722 pic16printPublics (asmFile);
1725 /* copy the sfr segment */
1726 fprintf (asmFile, "%s", iComments2);
1727 fprintf (asmFile, "; special function registers\n");
1728 fprintf (asmFile, "%s", iComments2);
1729 copyFile (asmFile, sfr->oFile);
1732 /* Put all variables into a cblock */
1733 pic16_AnalyzeBanking();
1734 pic16_writeUsedRegs(asmFile);
1737 /* no xdata in pic */
1738 /* if external stack then reserve space of it */
1739 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1740 fprintf (asmFile, "%s", iComments2);
1741 fprintf (asmFile, "; external stack \n");
1742 fprintf (asmFile, "%s", iComments2);
1743 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1744 fprintf (asmFile,";\t.ds 256\n");
1749 /* no xdata in pic */
1750 /* copy xtern ram data */
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile, "; external ram data\n");
1753 fprintf (asmFile, "%s", iComments2);
1754 copyFile (asmFile, xdata->oFile);
1758 /* copy the bit segment */
1759 fprintf (asmFile, "%s", iComments2);
1760 fprintf (asmFile, "; bit data\n");
1761 fprintf (asmFile, "%s", iComments2);
1762 copyFile (asmFile, bit->oFile);
1765 /* copy the interrupt vector table */
1766 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1767 fprintf (asmFile, "\n%s", iComments2);
1768 fprintf (asmFile, "; interrupt vector \n");
1769 fprintf (asmFile, "%s", iComments2);
1770 copyFile (asmFile, vFile);
1773 /* copy global & static initialisations */
1774 fprintf (asmFile, "\n%s", iComments2);
1775 fprintf (asmFile, "; global & static initialisations\n");
1776 fprintf (asmFile, "%s", iComments2);
1778 if(pic16_debug_verbose)
1779 fprintf(asmFile, "; A code from now on!\n");
1780 pic16_copypCode(asmFile, 'A');
1783 if(pic16_options.no_crt) {
1784 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1785 fprintf(asmFile, "\tcode\n");
1786 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1790 // copyFile (stderr, code->oFile);
1792 fprintf(asmFile, "; I code from now on!\n");
1793 pic16_copypCode(asmFile, 'I');
1795 if(pic16_debug_verbose)
1796 fprintf(asmFile, "; dbName from now on!\n");
1797 pic16_copypCode(asmFile, statsg->dbName);
1800 if(pic16_options.no_crt) {
1801 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1802 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1807 if(pic16_debug_verbose)
1808 fprintf(asmFile, "; X code from now on!\n");
1809 pic16_copypCode(asmFile, 'X');
1811 if(pic16_debug_verbose)
1812 fprintf(asmFile, "; M code from now on!\n");
1813 pic16_copypCode(asmFile, 'M');
1816 pic16_copypCode(asmFile, code->dbName);
1818 pic16_copypCode(asmFile, 'P');
1820 fprintf (asmFile,"\tend\n");