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;
63 set *rel_idataSymSet=NULL;
64 set *fix_idataSymSet=NULL;
66 extern DEFSETFUNC (closeTmpFiles);
67 extern DEFSETFUNC (rmTmpFiles);
69 extern void pic16_AnalyzeBanking (void);
70 extern void copyFile (FILE * dest, FILE * src);
71 extern void pic16_InlinepCode(void);
72 extern void pic16_writeUsedRegs(FILE *);
74 extern void initialComments (FILE * afile);
75 extern void printPublics (FILE * afile);
77 void pic16_pCodeInitRegisters(void);
78 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
79 extern void pic16_pCodeConstString(char *name, char *value);
81 /*-----------------------------------------------------------------*/
82 /* aopLiteral - string from a literal value */
83 /*-----------------------------------------------------------------*/
84 int pic16aopLiteral (value *val, int offset)
91 /* if it is a float then it gets tricky */
92 /* otherwise it is fairly simple */
93 if (!IS_FLOAT(val->type)) {
94 unsigned long v = (unsigned long) floatFromVal(val);
96 return ( (v >> (offset * 8)) & 0xff);
99 /* it is type float */
100 fl.f = (float) floatFromVal(val);
101 #ifdef WORDS_BIGENDIAN
102 return fl.c[3-offset];
111 char tbuffer[512], *tbuf=tbuffer;;
114 /*-----------------------------------------------------------------*/
115 /* emitRegularMap - emit code for maps with no special cases */
116 /*-----------------------------------------------------------------*/
118 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
121 // int i, size, bitvars = 0;;
123 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
126 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
127 /* print the area name */
129 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
132 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
134 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
135 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
136 printTypeChain( sym->type, stderr );
137 fprintf(stderr, "\n");
140 /* if extern then add to externs */
141 if (IS_EXTERN (sym->etype)) {
142 /* reduce overhead while linking by not declaring
143 * extern unused external functions (usually declared
144 * in header files) */
145 if(IS_FUNC(sym->type) && !sym->used)continue;
147 /* make sure symbol is not in publics section */
148 if(!checkSym(publics, sym))
149 checkAddSym(&externs, sym);
153 /* if allocation required check is needed
154 * then check if the symbol really requires
155 * allocation only for local variables */
156 if (arFlag && !IS_AGGREGATE (sym->type) &&
157 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
158 !sym->allocreq && sym->level) {
160 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
165 /* if global variable & not static or extern
166 * and addPublics allowed then add it to the public set */
167 if ((sym->used) && (sym->level == 0 ||
168 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
170 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
172 checkAddSym(&publics, sym);
174 if(IS_STATIC(sym->etype)
175 && !(sym->ival && !sym->level)
178 /* add it to udata list */
180 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
181 // sym->name, sym->rname, sym->remat);
183 //, OP_SYMBOL(operandFromSymbol(sym))->name);
184 #define SET_IMPLICIT 1
187 if(IS_STRUCT(sym->type))
191 reg = pic16_allocDirReg( operandFromSymbol( sym ));
198 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
199 if(!strcmp(ssym->name, reg->name))found=1;
204 checkAddReg(&pic16_rel_udata, reg);
206 checkAddSym(&publics, sym);
211 /* if extern then do nothing or is a function
213 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
214 if(SPEC_OCLS(sym->etype) == code) {
215 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
216 checkAddSym(&publics, sym);
222 /* print extra debug info if required */
223 if (options.debug || sym->level == 0) {
224 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
226 if (!sym->level) /* global */
227 if (IS_STATIC (sym->etype))
228 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
230 fprintf (map->oFile, "G_"); /* scope is global */
232 /* symbol is local */
233 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
234 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
239 /* if is has an absolute address then generate
240 an equate for this no need to allocate space */
241 if (SPEC_ABSA (sym->etype)) {
242 // if (options.debug || sym->level == 0)
243 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
244 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
246 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
248 SPEC_ADDR (sym->etype));
250 /* emit only if it is global */
251 if(sym->level == 0) {
254 reg = pic16_dirregWithName( sym->name );
257 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
258 // __FUNCTION__, __LINE__, sym->name);
260 /* if IS_STRUCT is omitted the following
261 * fixes structures but break char/int etc */
263 if(IS_STRUCT(sym->type))
264 sym->implicit = 1; // mark as implicit
267 reg = pic16_allocDirReg( operandFromSymbol(sym) );
269 if(checkAddReg(&pic16_fix_udata, reg)) {
270 /* and add to globals list if not exist */
271 addSet(&publics, sym);
275 addSet(&publics, sym);
279 if(!sym->used && (sym->level == 0)) {
282 /* symbol not used, just declared probably, but its in
283 * level 0, so we must declare it fine as global */
285 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
288 if(IS_STRUCT(sym->type))
289 sym->implicit = 1; // mark as implicit
292 if(IS_AGGREGATE(sym->type)) {
293 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
295 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
303 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
304 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
308 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
309 if(!strcmp(ssym->name, reg->name))found=1;
314 if(checkAddReg(&pic16_rel_udata, reg)) {
315 addSetHead(&publics, sym);
324 addSetHead(&publics, sym);
329 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
330 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
331 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
332 if (IS_BITVAR (sym->etype)) {
335 fprintf (map->oFile, "\t%s\n", sym->rname);
336 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
337 for (i = 1; i < size; i++)
338 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
341 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
345 /* FIXME -- VR Fix the following, so that syms to be placed
346 * in the idata section and let linker decide about their fate */
348 /* if it has an initial value then do it only if
349 it is a global variable */
351 if (sym->ival && sym->level == 0) {
355 if(SPEC_OCLS(sym->etype)==data) {
356 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
359 if(SPEC_OCLS(sym->etype)==code) {
360 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
365 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
366 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
369 if (IS_AGGREGATE (sym->type)) {
370 if(SPEC_ABSA(sym->etype))
371 addSet(&fix_idataSymSet, copySymbol(sym));
373 addSet(&rel_idataSymSet, copySymbol(sym));
374 // ival = initAggregates (sym, sym->ival, NULL);
376 if(SPEC_ABSA(sym->etype))
377 addSet(&fix_idataSymSet, copySymbol(sym));
379 addSet(&rel_idataSymSet, copySymbol(sym));
381 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
382 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
386 setAstLineno(ival, sym->lineDef);
387 codeOutFile = statsg->oFile;
389 eBBlockFromiCode (iCodeFromAst (ival));
397 /*-----------------------------------------------------------------*/
398 /* pic16_initPointer - pointer initialization code massaging */
399 /*-----------------------------------------------------------------*/
400 value *pic16_initPointer (initList * ilist, sym_link *toType)
406 return valCastLiteral(toType, 0.0);
409 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
410 // expr = list2expr( ilist );
415 /* try it the old way first */
416 if ((val = constExprValue (expr, FALSE)))
419 /* ( ptr + constant ) */
420 if (IS_AST_OP (expr) &&
421 (expr->opval.op == '+' || expr->opval.op == '-') &&
422 IS_AST_SYM_VALUE (expr->left) &&
423 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
424 compareType(toType, expr->left->ftype) &&
425 IS_AST_LIT_VALUE (expr->right)) {
426 return valForCastAggr (expr->left, expr->left->ftype,
432 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
433 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
434 if (compareType(toType, expr->left->ftype)!=1) {
435 werror (W_INIT_WRONG);
436 printFromToType(expr->left->ftype, toType);
442 /* no then we have to do these cludgy checks */
443 /* pointers can be initialized with address of
444 a variable or address of an array element */
445 if (IS_AST_OP (expr) && expr->opval.op == '&') {
446 /* address of symbol */
447 if (IS_AST_SYM_VALUE (expr->left)) {
448 val = copyValue (AST_VALUE (expr->left));
449 val->type = newLink (DECLARATOR);
450 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
451 DCL_TYPE (val->type) = CPOINTER;
452 DCL_PTR_CONST (val->type) = port->mem.code_ro;
454 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
455 DCL_TYPE (val->type) = FPOINTER;
456 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
457 DCL_TYPE (val->type) = PPOINTER;
458 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
459 DCL_TYPE (val->type) = IPOINTER;
460 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
461 DCL_TYPE (val->type) = EEPPOINTER;
463 DCL_TYPE (val->type) = POINTER;
465 val->type->next = expr->left->ftype;
466 val->etype = getSpec (val->type);
470 /* if address of indexed array */
471 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
472 return valForArray (expr->left);
474 /* if address of structure element then
476 if (IS_AST_OP (expr->left) &&
477 expr->left->opval.op == '.') {
478 return valForStructElem (expr->left->left,
483 (&some_struct)->element */
484 if (IS_AST_OP (expr->left) &&
485 expr->left->opval.op == PTR_OP &&
486 IS_ADDRESS_OF_OP (expr->left->left)) {
487 return valForStructElem (expr->left->left->left,
491 /* case 3. (((char *) &a) +/- constant) */
492 if (IS_AST_OP (expr) &&
493 (expr->opval.op == '+' || expr->opval.op == '-') &&
494 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
495 IS_AST_OP (expr->left->right) &&
496 expr->left->right->opval.op == '&' &&
497 IS_AST_LIT_VALUE (expr->right)) {
499 return valForCastAggr (expr->left->right->left,
500 expr->left->left->opval.lnk,
501 expr->right, expr->opval.op);
504 /* case 4. (char *)(array type) */
505 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
506 IS_ARRAY(expr->right->ftype)) {
508 val = copyValue (AST_VALUE (expr->right));
509 val->type = newLink (DECLARATOR);
510 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
511 DCL_TYPE (val->type) = CPOINTER;
512 DCL_PTR_CONST (val->type) = port->mem.code_ro;
514 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
515 DCL_TYPE (val->type) = FPOINTER;
516 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
517 DCL_TYPE (val->type) = PPOINTER;
518 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
519 DCL_TYPE (val->type) = IPOINTER;
520 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
521 DCL_TYPE (val->type) = EEPPOINTER;
523 DCL_TYPE (val->type) = POINTER;
524 val->type->next = expr->right->ftype->next;
525 val->etype = getSpec (val->type);
531 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
533 werror (E_INCOMPAT_PTYPES);
539 /*-----------------------------------------------------------------*/
540 /* printPointerType - generates ival for pointer type */
541 /*-----------------------------------------------------------------*/
542 void _pic16_printPointerType (const char *name, char ptype, void *p)
546 sprintf(buf, "LOW(%s)", name);
547 pic16_emitDS(buf, ptype, p);
548 sprintf(buf, "HIGH(%s)", name);
549 pic16_emitDS(buf, ptype, p);
552 /*-----------------------------------------------------------------*/
553 /* printPointerType - generates ival for pointer type */
554 /*-----------------------------------------------------------------*/
555 void pic16_printPointerType (const char *name, char ptype, void *p)
557 _pic16_printPointerType (name, ptype, p);
558 pic16_flushDB(ptype, p);
561 /*-----------------------------------------------------------------*/
562 /* printGPointerType - generates ival for generic pointer type */
563 /*-----------------------------------------------------------------*/
564 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
565 const unsigned int type, char ptype, void *p)
569 _pic16_printPointerType (iname, ptype, p);
575 sprintf(buf, "UPPER(%s)", iname);
576 pic16_emitDS(buf, ptype, p);
580 sprintf(buf, "0x80");
581 pic16_emitDS(buf, ptype, p);
585 pic16_flushDB(ptype, p);
589 /* set to 0 to disable debug messages */
590 #define DEBUG_PRINTIVAL 0
592 /*-----------------------------------------------------------------*/
593 /* pic16_printIvalType - generates ival for int/char */
594 /*-----------------------------------------------------------------*/
596 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
600 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
603 fprintf(stderr, "%s\n",__FUNCTION__);
607 /* if initList is deep */
608 if (ilist && ilist->type == INIT_DEEP)
609 ilist = ilist->init.deep;
611 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
612 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
615 if (!(val = list2val (ilist))) {
616 // assuming a warning has been thrown
620 if (val->type != type) {
621 val = valCastLiteral(type, floatFromVal(val));
624 switch (getSize (type)) {
626 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
630 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
631 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
634 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
635 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
636 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
638 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
639 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
640 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
641 pic16_emitDB(pic16aopLiteral(val, 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 */
1724 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1726 /* Let the port generate any global directives, etc. */
1727 if (port->genAssemblerPreamble) {
1728 port->genAssemblerPreamble(asmFile);
1731 /* print the extern variables to this module */
1732 pic16_printExterns(asmFile);
1734 /* print the global variables in this module */
1735 pic16printPublics (asmFile);
1738 /* copy the sfr segment */
1739 fprintf (asmFile, "%s", iComments2);
1740 fprintf (asmFile, "; special function registers\n");
1741 fprintf (asmFile, "%s", iComments2);
1742 copyFile (asmFile, sfr->oFile);
1745 /* Put all variables into a cblock */
1746 pic16_AnalyzeBanking();
1747 pic16_writeUsedRegs(asmFile);
1750 /* no xdata in pic */
1751 /* if external stack then reserve space of it */
1752 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1753 fprintf (asmFile, "%s", iComments2);
1754 fprintf (asmFile, "; external stack \n");
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1757 fprintf (asmFile,";\t.ds 256\n");
1762 /* no xdata in pic */
1763 /* copy xtern ram data */
1764 fprintf (asmFile, "%s", iComments2);
1765 fprintf (asmFile, "; external ram data\n");
1766 fprintf (asmFile, "%s", iComments2);
1767 copyFile (asmFile, xdata->oFile);
1771 /* copy the bit segment */
1772 fprintf (asmFile, "%s", iComments2);
1773 fprintf (asmFile, "; bit data\n");
1774 fprintf (asmFile, "%s", iComments2);
1775 copyFile (asmFile, bit->oFile);
1778 /* copy the interrupt vector table */
1779 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1780 fprintf (asmFile, "\n%s", iComments2);
1781 fprintf (asmFile, "; interrupt vector \n");
1782 fprintf (asmFile, "%s", iComments2);
1783 copyFile (asmFile, vFile);
1786 /* copy global & static initialisations */
1787 fprintf (asmFile, "\n%s", iComments2);
1788 fprintf (asmFile, "; global & static initialisations\n");
1789 fprintf (asmFile, "%s", iComments2);
1791 if(pic16_debug_verbose)
1792 fprintf(asmFile, "; A code from now on!\n");
1793 pic16_copypCode(asmFile, 'A');
1796 if(pic16_options.no_crt) {
1797 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1798 fprintf(asmFile, "\tcode\n");
1799 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1803 // copyFile (stderr, code->oFile);
1805 fprintf(asmFile, "; I code from now on!\n");
1806 pic16_copypCode(asmFile, 'I');
1808 if(pic16_debug_verbose)
1809 fprintf(asmFile, "; dbName from now on!\n");
1810 pic16_copypCode(asmFile, statsg->dbName);
1813 if(pic16_options.no_crt) {
1814 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1815 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1820 if(pic16_debug_verbose)
1821 fprintf(asmFile, "; X code from now on!\n");
1822 pic16_copypCode(asmFile, 'X');
1824 if(pic16_debug_verbose)
1825 fprintf(asmFile, "; M code from now on!\n");
1826 pic16_copypCode(asmFile, 'M');
1829 pic16_copypCode(asmFile, code->dbName);
1831 pic16_copypCode(asmFile, 'P');
1833 fprintf (asmFile,"\tend\n");