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;
203 if(!found)checkAddReg(&pic16_rel_udata, reg);
207 /* if extern then do nothing or is a function
209 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
210 if(SPEC_OCLS(sym->etype) == code) {
211 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
212 checkAddSym(&publics, sym);
218 /* print extra debug info if required */
219 if (options.debug || sym->level == 0) {
220 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
222 if (!sym->level) /* global */
223 if (IS_STATIC (sym->etype))
224 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
226 fprintf (map->oFile, "G_"); /* scope is global */
228 /* symbol is local */
229 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
230 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
235 /* if is has an absolute address then generate
236 an equate for this no need to allocate space */
237 if (SPEC_ABSA (sym->etype)) {
238 // if (options.debug || sym->level == 0)
239 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
240 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
242 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
244 SPEC_ADDR (sym->etype));
246 /* emit only if it is global */
247 if(sym->level == 0) {
250 reg = pic16_dirregWithName( sym->name );
253 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
254 // __FUNCTION__, __LINE__, sym->name);
256 /* if IS_STRUCT is omitted the following
257 * fixes structures but break char/int etc */
259 if(IS_STRUCT(sym->type))
260 sym->implicit = 1; // mark as implicit
263 reg = pic16_allocDirReg( operandFromSymbol(sym) );
265 if(checkAddReg(&pic16_fix_udata, reg)) {
266 /* and add to globals list if not exist */
267 addSet(&publics, sym);
271 addSet(&publics, sym);
275 if(!sym->used && (sym->level == 0)) {
278 /* symbol not used, just declared probably, but its in
279 * level 0, so we must declare it fine as global */
281 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
284 if(IS_STRUCT(sym->type))
285 sym->implicit = 1; // mark as implicit
288 if(IS_AGGREGATE(sym->type)) {
289 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
291 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
299 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
300 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_TYPE_NONE));
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)
565 _pic16_printPointerType (iname, ptype, p);
571 sprintf(buf, "UPPER(%s)", iname);
572 pic16_emitDS(buf, ptype, p);
576 sprintf(buf, "0x80");
577 pic16_emitDS(buf, ptype, p);
581 pic16_flushDB(ptype, p);
585 /* set to 0 to disable debug messages */
586 #define DEBUG_PRINTIVAL 0
588 /*-----------------------------------------------------------------*/
589 /* pic16_printIvalType - generates ival for int/char */
590 /*-----------------------------------------------------------------*/
592 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
597 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
600 fprintf(stderr, "%s\n",__FUNCTION__);
604 /* if initList is deep */
605 if (ilist && ilist->type == INIT_DEEP)
606 ilist = ilist->init.deep;
608 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
609 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
612 if (!(val = list2val (ilist))) {
613 // assuming a warning has been thrown
617 if (val->type != type) {
618 val = valCastLiteral(type, floatFromVal(val));
622 ulval = (unsigned long) floatFromVal (val);
626 switch (getSize (type)) {
628 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
632 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
633 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
637 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
638 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
639 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
640 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
645 /*--------------------------------------------------------------------*/
646 /* pic16_printIvalChar - generates initital value for character array */
647 /*--------------------------------------------------------------------*/
649 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
658 fprintf(stderr, "%s\n",__FUNCTION__);
664 val = list2val (ilist);
665 /* if the value is a character string */
666 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
668 if (!DCL_ELEM (type))
669 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
671 for(remain=0; remain<DCL_ELEM(type); remain++)
672 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
674 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
676 pic16_emitDB(0x00, ptype, p);
685 for(remain=0; remain<strlen(s); remain++) {
686 pic16_emitDB(s[remain], ptype, p);
692 /*-----------------------------------------------------------------*/
693 /* pic16_printIvalArray - generates code for array initialization */
694 /*-----------------------------------------------------------------*/
696 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
700 int lcnt = 0, size = 0;
707 fprintf(stderr, "%s\n",__FUNCTION__);
709 /* take care of the special case */
710 /* array of characters can be init */
712 if (IS_CHAR (type->next)) {
713 if (!IS_LITERAL(list2val(ilist)->etype)) {
714 werror (W_INIT_WRONG);
718 if(pic16_printIvalChar (type,
719 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
720 SPEC_CVAL (sym->etype).v_char, ptype, p))
723 /* not the special case */
724 if (ilist && ilist->type != INIT_DEEP)
726 werror (E_INIT_STRUCT, sym->name);
730 iloop = ilist->init.deep;
731 lcnt = DCL_ELEM (type);
736 pic16_printIval (sym, type->next, iloop, ptype, p);
737 iloop = (iloop ? iloop->next : NULL);
740 /* if not array limits given & we */
741 /* are out of initialisers then */
742 if (!DCL_ELEM (type) && !iloop)
745 /* no of elements given and we */
746 /* have generated for all of them */
748 /* if initializers left */
750 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
756 /* if we have not been given a size */
757 if (!DCL_ELEM (type))
758 DCL_ELEM (type) = size;
763 /*-----------------------------------------------------------------*/
764 /* pic16_printIvalBitFields - generate initializer for bitfields */
765 /*-----------------------------------------------------------------*/
766 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
770 initList *lilist = *ilist ;
771 unsigned long ival = 0;
776 fprintf(stderr, "%s\n",__FUNCTION__);
782 val = list2val(lilist);
784 if (SPEC_BLEN(lsym->etype) > 8) {
785 size += ((SPEC_BLEN (lsym->etype) / 8) +
786 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
789 size = ((SPEC_BLEN (lsym->etype) / 8) +
790 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
792 i = (unsigned long)floatFromVal(val);
793 i <<= SPEC_BSTR (lsym->etype);
795 if (! ( lsym->next &&
796 (IS_BITFIELD(lsym->next->type)) &&
797 (SPEC_BSTR(lsym->next->etype)))) break;
799 lilist = lilist->next;
803 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
807 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
808 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
811 case 4: /* EEP: why is this db and not dw? */
812 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
813 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
814 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
815 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
818 /* VR - only 1,2,4 size long can be handled???? Why? */
819 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
827 /*-----------------------------------------------------------------*/
828 /* printIvalStruct - generates initial value for structures */
829 /*-----------------------------------------------------------------*/
830 void pic16_printIvalStruct (symbol * sym, sym_link * type,
831 initList * ilist, char ptype, void *p)
834 initList *iloop = NULL;
838 fprintf(stderr, "%s\n",__FUNCTION__);
841 sflds = SPEC_STRUCT (type)->fields;
844 if (ilist->type != INIT_DEEP) {
845 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
849 iloop = ilist->init.deep;
852 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
853 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
854 if (IS_BITFIELD(sflds->type)) {
855 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
857 pic16_printIval (sym, sflds->type, iloop, ptype, p);
861 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
866 /*--------------------------------------------------------------------------*/
867 /* pic16_printIvalCharPtr - generates initial values for character pointers */
868 /*--------------------------------------------------------------------------*/
869 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
873 /* PENDING: this is _very_ mcs51 specific, including a magic
875 It's also endin specific.
877 VR - Attempting to port this function to pic16 port - 8-Jun-2004
882 fprintf(stderr, "%s\n",__FUNCTION__);
885 size = getSize (type);
887 if (val->name && strlen (val->name))
889 if (size == 1) /* This appears to be Z80 specific?? */
891 pic16_emitDS(val->name, ptype, p);
895 pic16_printPointerType (val->name, ptype, p);
900 if (IS_PTR (val->type)) {
901 type = DCL_TYPE (val->type);
903 type = PTR_TYPE (SPEC_OCLS (val->etype));
905 if (val->sym && val->sym->isstrlit) {
906 // this is a literal string
909 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
913 fprintf (stderr, "*** internal error: unknown size in "
914 "printIvalCharPtr.\n");
920 // these are literals assigned to pointers
924 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
927 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
928 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
931 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
932 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
933 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
941 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
942 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
943 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
949 /*-----------------------------------------------------------------------*/
950 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
951 /*-----------------------------------------------------------------------*/
952 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
959 fprintf(stderr, "%s\n",__FUNCTION__);
963 val = list2val (ilist);
965 val = valCastLiteral(type, 0.0);
968 // an error has been thrown already
972 if (IS_LITERAL(val->etype)) {
973 if (compareType(type, val->etype) == 0) {
974 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
975 printFromToType (val->type, type);
977 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
981 /* check the types */
982 if ((dLvl = compareType (val->type, type->next)) <= 0)
984 pic16_emitDB(0x00, ptype, p);
988 /* now generate the name */
990 pic16_printPointerType (val->name, ptype, p);
992 pic16_printPointerType (val->sym->rname, ptype, p);
994 if(IS_FUNC(val->sym->type) && !val->sym->used) {
996 if(!checkSym(publics, val->sym))
997 checkAddSym(&externs, val->sym);
999 /* this has not been declared as extern
1000 * so declare it as a 'late extern' just after the symbol */
1002 fprintf((FILE *)p, "declare symbol as extern");
1003 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1004 fprintf((FILE *)p, "continue variable declaration");
1013 /*-----------------------------------------------------------------*/
1014 /* pic16_printIvalPtr - generates initial value for pointers */
1015 /*-----------------------------------------------------------------*/
1016 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1022 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1023 sym->rname, getSize(sym->type));
1027 if (ilist && (ilist->type == INIT_DEEP))
1028 ilist = ilist->init.deep;
1030 /* function pointer */
1031 if (IS_FUNC (type->next))
1033 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1037 if (!(val = pic16_initPointer (ilist, type)))
1040 /* if character pointer */
1041 if (IS_CHAR (type->next))
1042 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1045 /* check the type */
1046 if (compareType (type, val->type) == 0) {
1047 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1048 printFromToType (val->type, type);
1051 /* if val is literal */
1052 if (IS_LITERAL (val->etype))
1054 switch (getSize (type))
1057 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1060 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1061 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1064 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1065 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1066 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1069 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1076 size = getSize (type);
1078 if (size == 1) /* Z80 specific?? */
1080 pic16_emitDS(val->name, ptype, p);
1084 pic16_printPointerType (val->name, ptype, p);
1088 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1089 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1090 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1098 /*-----------------------------------------------------------------*/
1099 /* pic16_printIval - generates code for initial value */
1100 /*-----------------------------------------------------------------*/
1101 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1109 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1110 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1111 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1114 /* if structure then */
1115 if (IS_STRUCT (type))
1117 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1118 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1122 /* if this is an array */
1123 if (IS_ARRAY (type))
1125 // fprintf(stderr,"%s array\n",__FUNCTION__);
1126 pic16_printIvalArray (sym, type, ilist, ptype, p);
1133 // not an aggregate, ilist must be a node
1134 if (ilist->type!=INIT_NODE) {
1135 // or a 1-element list
1136 if (ilist->init.deep->next) {
1137 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1140 ilist=ilist->init.deep;
1145 // and the type must match
1146 itype=ilist->init.node->ftype;
1148 if (compareType(type, itype)==0) {
1149 // special case for literal strings
1150 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1151 // which are really code pointers
1152 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1155 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1156 // printFromToType(itype, type);
1163 /* if this is a pointer */
1166 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1167 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1172 /* if type is SPECIFIER */
1175 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1176 pic16_printIvalType (sym, type, ilist, ptype, p);
1181 int PIC16_IS_CONFIG_ADDRESS(int address)
1183 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1186 int PIC16_IS_IDLOC_ADDRESS(int address)
1188 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1191 /* wrapper function for the above */
1192 int PIC16_IS_HWREG_ADDRESS(int address)
1194 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1198 /*-----------------------------------------------------------------*/
1199 /* emitStaticSeg - emitcode for the static segment */
1200 /*-----------------------------------------------------------------*/
1202 pic16emitStaticSeg (memmap * map)
1205 static int didcode=0;
1207 //fprintf(stderr, "%s\n",__FUNCTION__);
1211 /* for all variables in this segment do */
1212 for (sym = setFirstItem (map->syms); sym;
1213 sym = setNextItem (map->syms))
1217 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1218 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1219 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1220 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1221 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1222 printTypeChain( sym->type, stderr );
1223 fprintf(stderr, "\n");
1226 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1227 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1228 (int) floatFromVal(list2val(sym->ival)));
1233 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1234 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1235 (char) floatFromVal(list2val(sym->ival)));
1240 /* if it is "extern" then do nothing */
1241 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1242 checkAddSym(&externs, sym);
1246 /* if it is not static add it to the public
1248 if (!IS_STATIC (sym->etype)) {
1249 /* do not emit if it is a config word declaration */
1250 checkAddSym(&publics, sym);
1253 /* print extra debug info if required */
1254 if (options.debug || sym->level == 0) {
1255 /* NOTE to me - cdbFile may be null in which case,
1256 * the sym name will be printed to stdout. oh well */
1257 debugFile->writeSymbol(sym);
1260 /* if it has an absolute address */
1261 if (SPEC_ABSA (sym->etype)) {
1262 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1263 // __FILE__, __LINE__, sym->name);
1265 /* if it has an initial value */
1273 /* symbol has absolute address and initial value */
1275 resolveIvalSym (sym->ival, sym->type);
1276 asym = newSymbol(sym->rname, 0);
1277 abSym = Safe_calloc(1, sizeof(absSym));
1278 abSym->name = Safe_strdup( sym->rname );
1279 abSym->address = SPEC_ADDR( sym->etype );
1280 addSet(&absSymSet, abSym);
1282 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1283 pic16_addpBlock(pb);
1285 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1286 PCF(pcf)->absblock = 1;
1288 pic16_addpCode2pBlock(pb,pcf);
1289 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1290 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1291 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1292 pic16_flushDB('p', (void *)pb);
1294 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1300 /* symbol has absolute address but no initial value */
1302 /* allocate space */
1303 fprintf (code->oFile, "%s:\n", sym->rname);
1305 /* special case for character strings */
1306 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1307 SPEC_CVAL (sym->etype).v_char) {
1309 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1311 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1318 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1319 // __FILE__, __LINE__, sym->name);
1322 /* if it has an initial value */
1326 /* symbol doesn't have absolute address but has initial value */
1327 fprintf (code->oFile, "%s:\n", sym->rname);
1329 resolveIvalSym (sym->ival, sym->type);
1331 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1332 pic16_addpBlock(pb);
1335 /* make sure that 'code' directive is emitted before, once */
1336 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1341 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1343 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1344 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1345 pic16_flushDB('p', (void *)pb);
1349 /* symbol doesn't have absolute address and no initial value */
1350 /* allocate space */
1351 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1352 fprintf (code->oFile, "%s:\n", sym->rname);
1353 /* special case for character strings */
1354 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1355 SPEC_CVAL (sym->etype).v_char) {
1357 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1359 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1370 /*-----------------------------------------------------------------*/
1371 /* pic16_emitConfigRegs - emits the configuration registers */
1372 /*-----------------------------------------------------------------*/
1373 void pic16_emitConfigRegs(FILE *of)
1377 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1378 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1379 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1380 pic16->cwInfo.confAddrStart+i,
1381 pic16->cwInfo.crInfo[i].value);
1384 void pic16_emitIDRegs(FILE *of)
1388 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1389 if(pic16->idInfo.irInfo[i].emit)
1390 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1391 pic16->idInfo.idAddrStart+i,
1392 pic16->idInfo.irInfo[i].value);
1399 /* no special considerations for the following
1400 data, idata & bit & xdata */
1401 pic16emitRegularMap (data, TRUE, TRUE);
1402 pic16emitRegularMap (idata, TRUE, TRUE);
1403 pic16emitRegularMap (bit, TRUE, FALSE);
1404 pic16emitRegularMap (xdata, TRUE, TRUE);
1405 pic16emitRegularMap (sfr, FALSE, FALSE);
1406 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1407 pic16emitRegularMap (code, TRUE, FALSE);
1408 pic16emitStaticSeg (statsg);
1411 /*-----------------------------------------------------------------*/
1412 /* createInterruptVect - creates the interrupt vector */
1413 /*-----------------------------------------------------------------*/
1415 pic16createInterruptVect (FILE * vFile)
1417 /* if the main is only a prototype ie. no body then do nothing */
1419 if (!IFFUNC_HASBODY(mainf->type)) {
1420 /* if ! compile only then main function should be present */
1421 if (!options.cc_only)
1427 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1428 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1429 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1431 /* this is an overkill since WE are the port,
1432 * and we know if we have a genIVT function! */
1434 port->genIVT(vFile, interrupts, maxInterrupts);
1441 /*-----------------------------------------------------------------*/
1442 /* pic16initialComments - puts in some initial comments */
1443 /*-----------------------------------------------------------------*/
1445 pic16initialComments (FILE * afile)
1447 initialComments (afile);
1448 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1449 if(pic16_mplab_comp)
1450 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1451 fprintf (afile, iComments2);
1454 /*-----------------------------------------------------------------*/
1455 /* printPublics - generates global declarations for publics */
1456 /*-----------------------------------------------------------------*/
1458 pic16printPublics (FILE *afile)
1462 fprintf (afile, "\n%s", iComments2);
1463 fprintf (afile, "; public variables in this module\n");
1464 fprintf (afile, "%s", iComments2);
1466 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1467 fprintf(afile, "\tglobal %s\n", sym->rname);
1470 /*-----------------------------------------------------------------*/
1471 /* printExterns - generates extern declarations for externs */
1472 /*-----------------------------------------------------------------*/
1474 pic16_printExterns(FILE *afile)
1478 /* print nothing if no externs to declare */
1479 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1482 fprintf(afile, "\n%s", iComments2);
1483 fprintf(afile, "; extern variables in this module\n");
1484 fprintf(afile, "%s", iComments2);
1486 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1487 fprintf(afile, "\textern %s\n", sym->rname);
1489 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1490 fprintf(afile, "\textern _%s\n", sym->name);
1493 /*-----------------------------------------------------------------*/
1494 /* emitOverlay - will emit code for the overlay stuff */
1495 /*-----------------------------------------------------------------*/
1497 pic16emitOverlay (FILE * afile)
1501 if (!elementsInSet (ovrSetSets))
1502 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1504 /* for each of the sets in the overlay segment do */
1505 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1506 ovrset = setNextItem (ovrSetSets))
1511 if (elementsInSet (ovrset))
1513 /* this dummy area is used to fool the assembler
1514 otherwise the assembler will append each of these
1515 declarations into one chunk and will not overlay
1517 fprintf (afile, ";\t.area _DUMMY\n");
1518 /* output the area informtion */
1519 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1522 for (sym = setFirstItem (ovrset); sym;
1523 sym = setNextItem (ovrset))
1526 /* if extern then do nothing */
1527 if (IS_EXTERN (sym->etype))
1530 /* if allocation required check is needed
1531 then check if the symbol really requires
1532 allocation only for local variables */
1533 if (!IS_AGGREGATE (sym->type) &&
1534 !(sym->_isparm && !IS_REGPARM (sym->etype))
1535 && !sym->allocreq && sym->level)
1538 /* if global variable & not static or extern
1539 and addPublics allowed then add it to the public set */
1540 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1541 && !IS_STATIC (sym->etype)) {
1542 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1543 checkAddSym(&publics, sym);
1544 // addSetHead (&publics, sym);
1547 /* if extern then do nothing or is a function
1549 if (IS_FUNC (sym->type))
1553 /* print extra debug info if required */
1554 if (options.debug || sym->level == 0)
1557 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1561 if (IS_STATIC (sym->etype))
1562 fprintf (afile, "F%s_", moduleName); /* scope is file */
1564 fprintf (afile, "G_"); /* scope is global */
1567 /* symbol is local */
1568 fprintf (afile, "L%s_",
1569 (sym->localof ? sym->localof->name : "-null-"));
1570 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1574 /* if is has an absolute address then generate
1575 an equate for this no need to allocate space */
1576 if (SPEC_ABSA (sym->etype))
1579 if (options.debug || sym->level == 0)
1580 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1582 fprintf (afile, "%s\t=\t0x%04x\n",
1584 SPEC_ADDR (sym->etype));
1588 if (options.debug || sym->level == 0)
1589 fprintf (afile, "==.\n");
1591 /* allocate space */
1592 fprintf (afile, "%s:\n", sym->rname);
1593 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1601 /*-----------------------------------------------------------------*/
1602 /* glue - the final glue that hold the whole thing together */
1603 /*-----------------------------------------------------------------*/
1610 FILE *ovrFile = tempfile();
1613 mainf = newSymbol ("main", 0);
1616 mainf = findSymWithLevel(SymbolTab, mainf);
1618 /* only if the main function exists */
1619 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1620 if (!options.cc_only)
1626 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1628 addSetHead(&tmpfileSet,ovrFile);
1629 pic16_pCodeInitRegisters();
1632 if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1633 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1635 pic16_addpBlock(pb);
1637 /* entry point @ start of CSEG */
1638 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1641 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1642 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1643 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1644 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1647 /* put in the call to main */
1648 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1650 if (options.mainreturn) {
1651 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1652 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1654 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1655 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1659 /* At this point we've got all the code in the form of pCode structures */
1660 /* Now it needs to be rearranged into the order it should be placed in the */
1663 pic16_movepBlock2Head('P'); // Last
1664 pic16_movepBlock2Head(code->dbName);
1665 pic16_movepBlock2Head('X');
1666 pic16_movepBlock2Head(statsg->dbName); // First
1668 /* print the global struct definitions */
1669 // if (options.debug)
1670 // cdbStructBlock (0); //,cdbFile);
1673 /* PENDING: this isnt the best place but it will do */
1674 if (port->general.glue_up_main) {
1675 /* create the interrupt vector table */
1676 pic16createInterruptVect (vFile);
1679 addSetHead(&tmpfileSet,vFile);
1681 /* emit code for the all the variables declared */
1683 /* do the overlay segments */
1684 pic16emitOverlay(ovrFile);
1685 pic16_AnalyzepCode('*');
1688 if(pic16_options.dumpcalltree) {
1690 sprintf(buffer, dstFileName);
1691 strcat(buffer, ".calltree");
1692 cFile = fopen(buffer, "w");
1693 pic16_printCallTree( cFile );
1698 pic16_InlinepCode();
1699 pic16_AnalyzepCode('*');
1701 if(pic16_debug_verbose)
1704 /* now put it all together into the assembler file */
1705 /* create the assembler file name */
1706 if ((noAssemble || options.c1mode) && fullDstFileName) {
1707 sprintf (buffer, fullDstFileName);
1709 sprintf (buffer, dstFileName);
1710 strcat (buffer, ".asm");
1713 if (!(asmFile = fopen (buffer, "w"))) {
1714 werror (E_FILE_OPEN_ERR, buffer);
1718 /* initial comments */
1719 pic16initialComments (asmFile);
1721 /* print module name */
1723 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1725 /* Let the port generate any global directives, etc. */
1726 if (port->genAssemblerPreamble) {
1727 port->genAssemblerPreamble(asmFile);
1730 /* print the extern variables to this module */
1731 pic16_printExterns(asmFile);
1733 /* print the global variables in this module */
1734 pic16printPublics (asmFile);
1737 /* copy the sfr segment */
1738 fprintf (asmFile, "%s", iComments2);
1739 fprintf (asmFile, "; special function registers\n");
1740 fprintf (asmFile, "%s", iComments2);
1741 copyFile (asmFile, sfr->oFile);
1744 /* Put all variables into a cblock */
1745 pic16_AnalyzeBanking();
1746 pic16_writeUsedRegs(asmFile);
1749 /* no xdata in pic */
1750 /* if external stack then reserve space of it */
1751 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1752 fprintf (asmFile, "%s", iComments2);
1753 fprintf (asmFile, "; external stack \n");
1754 fprintf (asmFile, "%s", iComments2);
1755 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1756 fprintf (asmFile,";\t.ds 256\n");
1761 /* no xdata in pic */
1762 /* copy xtern ram data */
1763 fprintf (asmFile, "%s", iComments2);
1764 fprintf (asmFile, "; external ram data\n");
1765 fprintf (asmFile, "%s", iComments2);
1766 copyFile (asmFile, xdata->oFile);
1770 /* copy the bit segment */
1771 fprintf (asmFile, "%s", iComments2);
1772 fprintf (asmFile, "; bit data\n");
1773 fprintf (asmFile, "%s", iComments2);
1774 copyFile (asmFile, bit->oFile);
1777 /* copy the interrupt vector table */
1778 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1779 fprintf (asmFile, "\n%s", iComments2);
1780 fprintf (asmFile, "; interrupt vector \n");
1781 fprintf (asmFile, "%s", iComments2);
1782 copyFile (asmFile, vFile);
1785 /* copy global & static initialisations */
1786 fprintf (asmFile, "\n%s", iComments2);
1787 fprintf (asmFile, "; global & static initialisations\n");
1788 fprintf (asmFile, "%s", iComments2);
1790 if(pic16_debug_verbose)
1791 fprintf(asmFile, "; A code from now on!\n");
1792 pic16_copypCode(asmFile, 'A');
1795 if(pic16_options.no_crt) {
1796 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1797 fprintf(asmFile, "\tcode\n");
1798 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1802 // copyFile (stderr, code->oFile);
1804 fprintf(asmFile, "; I code from now on!\n");
1805 pic16_copypCode(asmFile, 'I');
1807 if(pic16_debug_verbose)
1808 fprintf(asmFile, "; dbName from now on!\n");
1809 pic16_copypCode(asmFile, statsg->dbName);
1812 if(pic16_options.no_crt) {
1813 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1814 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1819 if(pic16_debug_verbose)
1820 fprintf(asmFile, "; X code from now on!\n");
1821 pic16_copypCode(asmFile, 'X');
1823 if(pic16_debug_verbose)
1824 fprintf(asmFile, "; M code from now on!\n");
1825 pic16_copypCode(asmFile, 'M');
1828 pic16_copypCode(asmFile, code->dbName);
1830 pic16_copypCode(asmFile, 'P');
1832 fprintf (asmFile,"\tend\n");