1 /*-------------------------------------------------------------------------
3 glue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #include "../common.h"
38 #ifdef WORDS_BIGENDIAN
39 #define _ENDIAN(x) (3-x)
41 #define _ENDIAN(x) (x)
44 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
46 extern symbol *interrupts[256];
47 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
51 extern unsigned maxInterrupts;
52 extern int maxRegBank;
54 extern char *VersionString;
55 extern FILE *codeOutFile;
56 extern set *tmpfileSet;
57 extern set *tmpfileNameSet;
58 extern char *iComments1;
59 extern char *iComments2;
62 extern unsigned long pFile_isize;
64 extern unsigned long pic16_countInstructions();
65 set *rel_idataSymSet=NULL;
66 set *fix_idataSymSet=NULL;
68 extern DEFSETFUNC (closeTmpFiles);
69 extern DEFSETFUNC (rmTmpFiles);
71 extern void pic16_AnalyzeBanking (void);
72 extern void pic16_OptimizeJumps ();
73 extern void pic16_OptimizeBanksel ();
74 extern void copyFile (FILE * dest, FILE * src);
75 extern void pic16_InlinepCode(void);
76 extern void pic16_writeUsedRegs(FILE *);
78 extern void initialComments (FILE * afile);
79 extern void printPublics (FILE * afile);
81 void pic16_pCodeInitRegisters(void);
82 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
83 extern void pic16_pCodeConstString(char *name, char *value);
86 /*-----------------------------------------------------------------*/
87 /* aopLiteral - string from a literal value */
88 /*-----------------------------------------------------------------*/
89 int pic16aopLiteral (value *val, int offset)
96 /* if it is a float then it gets tricky */
97 /* otherwise it is fairly simple */
98 if (!IS_FLOAT(val->type)) {
99 unsigned long v = (unsigned long) floatFromVal(val);
101 return ( (v >> (offset * 8)) & 0xff);
104 /* it is type float */
105 fl.f = (float) floatFromVal(val);
106 #ifdef WORDS_BIGENDIAN
107 return fl.c[3-offset];
116 char tbuffer[512], *tbuf=tbuffer;;
119 /*-----------------------------------------------------------------*/
120 /* emitRegularMap - emit code for maps with no special cases */
121 /*-----------------------------------------------------------------*/
123 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
126 // int i, size, bitvars = 0;;
128 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
131 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
132 /* print the area name */
134 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
137 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
139 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
140 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
141 printTypeChain( sym->type, stderr );
142 fprintf(stderr, "\n");
145 /* if extern then add to externs */
146 if (IS_EXTERN (sym->etype)) {
147 /* reduce overhead while linking by not declaring
148 * extern unused external functions (usually declared
149 * in header files) */
150 if(IS_FUNC(sym->type) && !sym->used)continue;
152 /* make sure symbol is not in publics section */
153 if(!checkSym(publics, sym))
154 checkAddSym(&externs, sym);
158 /* if allocation required check is needed
159 * then check if the symbol really requires
160 * allocation only for local variables */
161 if (arFlag && !IS_AGGREGATE (sym->type) &&
162 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
163 !sym->allocreq && sym->level) {
165 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
170 /* if global variable & not static or extern
171 * and addPublics allowed then add it to the public set */
172 if ((sym->used) && (sym->level == 0 ||
173 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
175 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
177 checkAddSym(&publics, sym);
180 if(IS_STATIC(sym->etype)
181 && !sym->ival) /* && !sym->level*/ {
186 // debugf("adding symbol %s\n", sym->name);
187 #define SET_IMPLICIT 1
190 if(IS_STRUCT(sym->type))
194 reg = pic16_allocDirReg( operandFromSymbol( sym ));
197 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
198 if(!strcmp(ssym->name, reg->name))found=1;
202 checkAddReg(&pic16_rel_udata, reg);
205 debugf("Did find %s in pic16_rel_udata already. Check!\n", reg->name);
206 // checkAddSym(&publics, sym);
212 /* if extern then do nothing or is a function
214 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
215 if(SPEC_OCLS(sym->etype) == code) {
216 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
217 checkAddSym(&publics, sym);
222 /* if is has an absolute address then generate
223 an equate for this no need to allocate space */
224 if (SPEC_ABSA (sym->etype)) {
225 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
226 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
228 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
230 SPEC_ADDR (sym->etype));
232 /* emit only if it is global */
233 if(sym->level == 0) {
236 reg = pic16_dirregWithName( sym->name );
239 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
240 // __FUNCTION__, __LINE__, sym->name);
242 /* if IS_STRUCT is omitted the following
243 * fixes structures but break char/int etc */
245 if(IS_STRUCT(sym->type))
246 sym->implicit = 1; // mark as implicit
249 reg = pic16_allocDirReg( operandFromSymbol(sym) );
251 if(checkAddReg(&pic16_fix_udata, reg)) {
252 /* and add to globals list if not exist */
253 addSet(&publics, sym);
257 addSet(&publics, sym);
261 if(!sym->used && (sym->level == 0)) {
264 /* symbol not used, just declared probably, but its in
265 * level 0, so we must declare it fine as global */
267 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
270 if(IS_STRUCT(sym->type))
271 sym->implicit = 1; // mark as implicit
274 if(IS_AGGREGATE(sym->type)) {
275 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
277 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
285 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
286 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
290 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
291 if(!strcmp(ssym->name, reg->name))found=1;
295 if(checkAddReg(&pic16_rel_udata, reg)) {
296 addSetHead(&publics, sym);
305 addSetHead(&publics, sym);
310 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
311 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
312 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
313 if (IS_BITVAR (sym->etype)) {
316 fprintf (map->oFile, "\t%s\n", sym->rname);
317 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
318 for (i = 1; i < size; i++)
319 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
322 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
326 /* FIXME -- VR Fix the following, so that syms to be placed
327 * in the idata section and let linker decide about their fate */
329 /* if it has an initial value then do it only if
330 it is a global variable */
333 && ((sym->level == 0)
334 || IS_STATIC(sym->etype)) ) {
338 if(SPEC_OCLS(sym->etype)==data) {
339 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
342 if(SPEC_OCLS(sym->etype)==code) {
343 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
348 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
349 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
352 if (IS_AGGREGATE (sym->type)) {
353 if(SPEC_ABSA(sym->etype))
354 addSet(&fix_idataSymSet, copySymbol(sym));
356 addSet(&rel_idataSymSet, copySymbol(sym));
357 // ival = initAggregates (sym, sym->ival, NULL);
359 if(SPEC_ABSA(sym->etype))
360 addSet(&fix_idataSymSet, copySymbol(sym));
362 addSet(&rel_idataSymSet, copySymbol(sym));
364 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
365 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
369 setAstLineno(ival, sym->lineDef);
370 codeOutFile = statsg->oFile;
372 eBBlockFromiCode (iCodeFromAst (ival));
380 /*-----------------------------------------------------------------*/
381 /* pic16_initPointer - pointer initialization code massaging */
382 /*-----------------------------------------------------------------*/
383 value *pic16_initPointer (initList * ilist, sym_link *toType)
389 return valCastLiteral(toType, 0.0);
392 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
393 // expr = list2expr( ilist );
398 /* try it the old way first */
399 if ((val = constExprValue (expr, FALSE)))
402 /* ( ptr + constant ) */
403 if (IS_AST_OP (expr) &&
404 (expr->opval.op == '+' || expr->opval.op == '-') &&
405 IS_AST_SYM_VALUE (expr->left) &&
406 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
407 compareType(toType, expr->left->ftype) &&
408 IS_AST_LIT_VALUE (expr->right)) {
409 return valForCastAggr (expr->left, expr->left->ftype,
415 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
416 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
417 if (compareType(toType, expr->left->ftype)!=1) {
418 werror (W_INIT_WRONG);
419 printFromToType(expr->left->ftype, toType);
425 /* no then we have to do these cludgy checks */
426 /* pointers can be initialized with address of
427 a variable or address of an array element */
428 if (IS_AST_OP (expr) && expr->opval.op == '&') {
429 /* address of symbol */
430 if (IS_AST_SYM_VALUE (expr->left)) {
431 val = copyValue (AST_VALUE (expr->left));
432 val->type = newLink (DECLARATOR);
433 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
434 DCL_TYPE (val->type) = CPOINTER;
435 DCL_PTR_CONST (val->type) = port->mem.code_ro;
437 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
438 DCL_TYPE (val->type) = FPOINTER;
439 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
440 DCL_TYPE (val->type) = PPOINTER;
441 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
442 DCL_TYPE (val->type) = IPOINTER;
443 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
444 DCL_TYPE (val->type) = EEPPOINTER;
446 DCL_TYPE (val->type) = POINTER;
448 val->type->next = expr->left->ftype;
449 val->etype = getSpec (val->type);
453 /* if address of indexed array */
454 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
455 return valForArray (expr->left);
457 /* if address of structure element then
459 if (IS_AST_OP (expr->left) &&
460 expr->left->opval.op == '.') {
461 return valForStructElem (expr->left->left,
466 (&some_struct)->element */
467 if (IS_AST_OP (expr->left) &&
468 expr->left->opval.op == PTR_OP &&
469 IS_ADDRESS_OF_OP (expr->left->left)) {
470 return valForStructElem (expr->left->left->left,
474 /* case 3. (((char *) &a) +/- constant) */
475 if (IS_AST_OP (expr) &&
476 (expr->opval.op == '+' || expr->opval.op == '-') &&
477 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
478 IS_AST_OP (expr->left->right) &&
479 expr->left->right->opval.op == '&' &&
480 IS_AST_LIT_VALUE (expr->right)) {
482 return valForCastAggr (expr->left->right->left,
483 expr->left->left->opval.lnk,
484 expr->right, expr->opval.op);
487 /* case 4. (char *)(array type) */
488 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
489 IS_ARRAY(expr->right->ftype)) {
491 val = copyValue (AST_VALUE (expr->right));
492 val->type = newLink (DECLARATOR);
493 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
494 DCL_TYPE (val->type) = CPOINTER;
495 DCL_PTR_CONST (val->type) = port->mem.code_ro;
497 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
498 DCL_TYPE (val->type) = FPOINTER;
499 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
500 DCL_TYPE (val->type) = PPOINTER;
501 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
502 DCL_TYPE (val->type) = IPOINTER;
503 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
504 DCL_TYPE (val->type) = EEPPOINTER;
506 DCL_TYPE (val->type) = POINTER;
507 val->type->next = expr->right->ftype->next;
508 val->etype = getSpec (val->type);
514 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
516 werror (E_INCOMPAT_PTYPES);
522 /*-----------------------------------------------------------------*/
523 /* printPointerType - generates ival for pointer type */
524 /*-----------------------------------------------------------------*/
525 void _pic16_printPointerType (const char *name, char ptype, void *p)
529 sprintf(buf, "LOW(%s)", name);
530 pic16_emitDS(buf, ptype, p);
531 sprintf(buf, "HIGH(%s)", name);
532 pic16_emitDS(buf, ptype, p);
535 /*-----------------------------------------------------------------*/
536 /* printPointerType - generates ival for pointer type */
537 /*-----------------------------------------------------------------*/
538 void pic16_printPointerType (const char *name, char ptype, void *p)
540 _pic16_printPointerType (name, ptype, p);
541 pic16_flushDB(ptype, p);
544 /*-----------------------------------------------------------------*/
545 /* printGPointerType - generates ival for generic pointer type */
546 /*-----------------------------------------------------------------*/
547 void pic16_printGPointerType (const char *iname, const unsigned int itype,
552 _pic16_printPointerType (iname, ptype, p);
559 sprintf(buf, "UPPER(%s)", iname);
560 pic16_emitDS(buf, ptype, p);
564 sprintf(buf, "0x80");
565 pic16_emitDS(buf, ptype, p);
568 debugf("itype = %d\n", itype );
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)
587 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
590 fprintf(stderr, "%s\n",__FUNCTION__);
594 /* if initList is deep */
595 if (ilist && ilist->type == INIT_DEEP)
596 ilist = ilist->init.deep;
598 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
599 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
602 if (!(val = list2val (ilist))) {
603 // assuming a warning has been thrown
607 if (val->type != type) {
608 val = valCastLiteral(type, floatFromVal(val));
611 switch (getSize (type)) {
613 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
617 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
618 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
621 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
622 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
623 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
625 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
626 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
627 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
628 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
633 /*--------------------------------------------------------------------*/
634 /* pic16_printIvalChar - generates initital value for character array */
635 /*--------------------------------------------------------------------*/
637 pic16_printIvalChar (symbol *sym, sym_link * type, initList * ilist, char *s, char ptype, void *p)
646 fprintf(stderr, "%s\n",__FUNCTION__);
650 val = list2val (ilist);
651 /* if the value is a character string */
652 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
654 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
656 /* len is 0 if declartion equals initializer,
657 * >0 if declaration greater than initializer
658 * <0 if declaration less than initializer
659 * Strategy: if >0 emit 0x00 for the rest of the length,
660 * if <0 then emit only the length of declaration elements
663 len = DCL_ELEM (type) - (strlen (SPEC_CVAL (val->etype).v_char)+1);
665 // fprintf(stderr, "%s:%d len = %i DCL_ELEM(type) = %i SPEC_CVAL-len = %i\n", __FILE__, __LINE__,
666 // len, DCL_ELEM(type), strlen(SPEC_CVAL(val->etype).v_char));
670 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
671 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
676 pic16_emitDB(0x00, ptype, p);
681 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
683 for(remain=0; remain<DCL_ELEM (type); remain++)
684 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
688 // if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
693 for(remain=0; remain<strlen(s); remain++) {
694 pic16_emitDB(s[remain], ptype, p);
700 /*-----------------------------------------------------------------*/
701 /* pic16_printIvalArray - generates code for array initialization */
702 /*-----------------------------------------------------------------*/
704 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
708 int lcnt = 0, size = 0;
715 fprintf(stderr, "%s\n",__FUNCTION__);
717 /* take care of the special case */
718 /* array of characters can be init */
720 if (IS_CHAR (type->next)) {
721 if (!IS_LITERAL(list2val(ilist)->etype)) {
722 werror (W_INIT_WRONG);
726 if(pic16_printIvalChar (sym, type,
727 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
728 SPEC_CVAL (sym->etype).v_char, ptype, p))
731 /* not the special case */
732 if (ilist && ilist->type != INIT_DEEP)
734 werror (E_INIT_STRUCT, sym->name);
738 iloop = ilist->init.deep;
739 lcnt = DCL_ELEM (type);
744 pic16_printIval (sym, type->next, iloop, ptype, p);
745 iloop = (iloop ? iloop->next : NULL);
748 /* if not array limits given & we */
749 /* are out of initialisers then */
750 if (!DCL_ELEM (type) && !iloop)
753 /* no of elements given and we */
754 /* have generated for all of them */
756 /* if initializers left */
758 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
764 /* if we have not been given a size */
765 if (!DCL_ELEM (type))
766 DCL_ELEM (type) = size;
771 /*-----------------------------------------------------------------*/
772 /* pic16_printIvalBitFields - generate initializer for bitfields */
773 /*-----------------------------------------------------------------*/
774 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
778 initList *lilist = *ilist ;
779 unsigned long ival = 0;
784 fprintf(stderr, "%s\n",__FUNCTION__);
790 val = list2val(lilist);
792 if (SPEC_BLEN(lsym->etype) > 8) {
793 size += ((SPEC_BLEN (lsym->etype) / 8) +
794 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
797 size = ((SPEC_BLEN (lsym->etype) / 8) +
798 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
800 i = (unsigned long)floatFromVal(val);
801 i <<= SPEC_BSTR (lsym->etype);
803 if (! ( lsym->next &&
804 (IS_BITFIELD(lsym->next->type)) &&
805 (SPEC_BSTR(lsym->next->etype)))) break;
807 lilist = lilist->next;
811 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
815 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
816 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
819 case 4: /* EEP: why is this db and not dw? */
820 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
821 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
822 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
823 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
826 /* VR - only 1,2,4 size long can be handled???? Why? */
827 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
835 /*-----------------------------------------------------------------*/
836 /* printIvalStruct - generates initial value for structures */
837 /*-----------------------------------------------------------------*/
838 void pic16_printIvalStruct (symbol * sym, sym_link * type,
839 initList * ilist, char ptype, void *p)
842 initList *iloop = NULL;
846 fprintf(stderr, "%s\n",__FUNCTION__);
849 sflds = SPEC_STRUCT (type)->fields;
852 if (ilist->type != INIT_DEEP) {
853 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
857 iloop = ilist->init.deep;
860 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
861 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
862 if (IS_BITFIELD(sflds->type)) {
863 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
865 pic16_printIval (sym, sflds->type, iloop, ptype, p);
869 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
874 /*--------------------------------------------------------------------------*/
875 /* pic16_printIvalCharPtr - generates initial values for character pointers */
876 /*--------------------------------------------------------------------------*/
877 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
881 /* PENDING: this is _very_ mcs51 specific, including a magic
883 It's also endin specific.
885 VR - Attempting to port this function to pic16 port - 8-Jun-2004
890 fprintf(stderr, "%s\n",__FUNCTION__);
893 size = getSize (type);
895 if (val->name && strlen (val->name))
897 if (size == 1) /* This appears to be Z80 specific?? */
899 pic16_emitDS(val->name, ptype, p);
903 pic16_printPointerType (val->name, ptype, p);
908 if (IS_PTR (val->type)) {
909 type = DCL_TYPE (val->type);
911 type = PTR_TYPE (SPEC_OCLS (val->etype));
913 if (val->sym && val->sym->isstrlit) {
914 // this is a literal string
917 pic16_printGPointerType(val->name, type, ptype, p);
921 fprintf (stderr, "*** internal error: unknown size in "
922 "printIvalCharPtr.\n");
928 // these are literals assigned to pointers
932 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
935 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
936 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
939 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
940 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
941 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
949 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
950 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
951 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
957 /*-----------------------------------------------------------------------*/
958 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
959 /*-----------------------------------------------------------------------*/
960 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
967 fprintf(stderr, "%s\n",__FUNCTION__);
971 val = list2val (ilist);
973 val = valCastLiteral(type, 0.0);
976 // an error has been thrown already
980 if (IS_LITERAL(val->etype)) {
981 if (compareType(type, val->etype) == 0) {
982 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
983 printFromToType (val->type, type);
985 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
989 /* check the types */
990 if ((dLvl = compareType (val->type, type->next)) <= 0)
992 pic16_emitDB(0x00, ptype, p);
996 /* now generate the name */
998 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
1000 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
1002 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
1004 if(!checkSym(publics, val->sym))
1005 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
1006 /* this has not been declared as extern
1007 * so declare it as a 'late extern' just after the symbol */
1008 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
1009 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1010 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
1019 /*-----------------------------------------------------------------*/
1020 /* pic16_printIvalPtr - generates initial value for pointers */
1021 /*-----------------------------------------------------------------*/
1022 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1028 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1029 sym->rname, getSize(sym->type));
1033 if (ilist && (ilist->type == INIT_DEEP))
1034 ilist = ilist->init.deep;
1036 /* function pointer */
1037 if (IS_FUNC (type->next))
1039 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1043 if (!(val = pic16_initPointer (ilist, type)))
1046 /* if character pointer */
1047 if (IS_CHAR (type->next))
1048 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1051 /* check the type */
1052 if (compareType (type, val->type) == 0) {
1053 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1054 printFromToType (val->type, type);
1057 /* if val is literal */
1058 if (IS_LITERAL (val->etype))
1060 switch (getSize (type))
1063 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1066 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1067 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1070 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1071 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1072 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1075 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1082 size = getSize (type);
1084 if (size == 1) /* Z80 specific?? */
1086 pic16_emitDS(val->name, ptype, p);
1090 pic16_printPointerType (val->name, ptype, p);
1094 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1103 /*-----------------------------------------------------------------*/
1104 /* pic16_printIval - generates code for initial value */
1105 /*-----------------------------------------------------------------*/
1106 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1114 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1115 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1116 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1119 /* if structure then */
1120 if (IS_STRUCT (type))
1122 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1123 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1127 /* if this is an array */
1128 if (IS_ARRAY (type))
1130 // fprintf(stderr,"%s array\n",__FUNCTION__);
1131 pic16_printIvalArray (sym, type, ilist, ptype, p);
1138 // not an aggregate, ilist must be a node
1139 if (ilist->type!=INIT_NODE) {
1140 // or a 1-element list
1141 if (ilist->init.deep->next) {
1142 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1145 ilist=ilist->init.deep;
1150 // and the type must match
1151 itype=ilist->init.node->ftype;
1153 if (compareType(type, itype)==0) {
1154 // special case for literal strings
1155 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1156 // which are really code pointers
1157 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1160 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1161 // printFromToType(itype, type);
1168 /* if this is a pointer */
1171 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1172 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1177 /* if type is SPECIFIER */
1180 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1181 pic16_printIvalType (sym, type, ilist, ptype, p);
1186 int PIC16_IS_CONFIG_ADDRESS(int address)
1188 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1191 int PIC16_IS_IDLOC_ADDRESS(int address)
1193 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1196 /* wrapper function for the above */
1197 int PIC16_IS_HWREG_ADDRESS(int address)
1199 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1203 /*-----------------------------------------------------------------*/
1204 /* emitStaticSeg - emitcode for the static segment */
1205 /*-----------------------------------------------------------------*/
1207 pic16emitStaticSeg (memmap * map)
1210 static int didcode=0;
1212 //fprintf(stderr, "%s\n",__FUNCTION__);
1216 /* for all variables in this segment do */
1217 for (sym = setFirstItem (map->syms); sym;
1218 sym = setNextItem (map->syms))
1222 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1223 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1224 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1225 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1226 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1227 printTypeChain( sym->type, stderr );
1228 fprintf(stderr, "\n");
1231 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1232 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1233 (int) floatFromVal(list2val(sym->ival)));
1238 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1239 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1240 (char) floatFromVal(list2val(sym->ival)));
1245 /* if it is "extern" then do nothing */
1246 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1247 checkAddSym(&externs, sym);
1251 /* if it is not static add it to the public
1253 if (!IS_STATIC (sym->etype)) {
1254 /* do not emit if it is a config word declaration */
1255 checkAddSym(&publics, sym);
1258 /* print extra debug info if required */
1259 if (options.debug || sym->level == 0) {
1260 /* NOTE to me - cdbFile may be null in which case,
1261 * the sym name will be printed to stdout. oh well */
1262 debugFile->writeSymbol(sym);
1265 /* if it has an absolute address */
1266 if (SPEC_ABSA (sym->etype)) {
1267 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1268 // __FILE__, __LINE__, sym->name);
1270 /* if it has an initial value */
1278 /* symbol has absolute address and initial value */
1280 resolveIvalSym (sym->ival, sym->type);
1281 asym = newSymbol(sym->rname, 0);
1282 abSym = Safe_calloc(1, sizeof(absSym));
1283 strcpy(abSym->name, sym->rname);
1284 abSym->address = SPEC_ADDR( sym->etype );
1285 addSet(&absSymSet, abSym);
1287 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1288 pic16_addpBlock(pb);
1290 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1291 PCF(pcf)->absblock = 1;
1293 pic16_addpCode2pBlock(pb,pcf);
1294 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1295 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1296 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1297 pic16_flushDB('p', (void *)pb);
1299 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1305 /* symbol has absolute address but no initial value */
1307 /* allocate space */
1308 fprintf (code->oFile, "%s:\n", sym->rname);
1310 /* special case for character strings */
1311 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1312 SPEC_CVAL (sym->etype).v_char) {
1314 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1316 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1323 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1324 // __FILE__, __LINE__, sym->name);
1327 /* if it has an initial value */
1331 /* symbol doesn't have absolute address but has initial value */
1332 fprintf (code->oFile, "%s:\n", sym->rname);
1334 resolveIvalSym (sym->ival, sym->type);
1336 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1337 pic16_addpBlock(pb);
1340 /* make sure that 'code' directive is emitted before, once */
1341 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1346 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1348 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1349 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1350 pic16_flushDB('p', (void *)pb);
1354 /* symbol doesn't have absolute address and no initial value */
1355 /* allocate space */
1356 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1357 fprintf (code->oFile, "%s:\n", sym->rname);
1358 /* special case for character strings */
1359 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1360 SPEC_CVAL (sym->etype).v_char) {
1362 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1364 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1375 /*-----------------------------------------------------------------*/
1376 /* pic16_emitConfigRegs - emits the configuration registers */
1377 /*-----------------------------------------------------------------*/
1378 void pic16_emitConfigRegs(FILE *of)
1382 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1383 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1384 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1385 pic16->cwInfo.confAddrStart+i,
1386 pic16->cwInfo.crInfo[i].value);
1389 void pic16_emitIDRegs(FILE *of)
1393 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1394 if(pic16->idInfo.irInfo[i].emit)
1395 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1396 pic16->idInfo.idAddrStart+i,
1397 pic16->idInfo.irInfo[i].value);
1404 /* no special considerations for the following
1405 data, idata & bit & xdata */
1406 pic16emitRegularMap (data, TRUE, TRUE);
1407 pic16emitRegularMap (idata, TRUE, TRUE);
1408 pic16emitRegularMap (bit, TRUE, FALSE);
1409 pic16emitRegularMap (xdata, TRUE, TRUE);
1410 pic16emitRegularMap (sfr, FALSE, FALSE);
1411 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1412 pic16emitRegularMap (code, TRUE, FALSE);
1413 pic16emitStaticSeg (statsg);
1416 /*-----------------------------------------------------------------*/
1417 /* createInterruptVect - creates the interrupt vector */
1418 /*-----------------------------------------------------------------*/
1420 pic16createInterruptVect (FILE * vFile)
1422 /* if the main is only a prototype ie. no body then do nothing */
1424 if (!IFFUNC_HASBODY(mainf->type)) {
1425 /* if ! compile only then main function should be present */
1426 if (!options.cc_only)
1432 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1433 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1434 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1436 /* this is an overkill since WE are the port,
1437 * and we know if we have a genIVT function! */
1439 port->genIVT(vFile, interrupts, maxInterrupts);
1447 /*-----------------------------------------------------------------*/
1448 /* pic16initialComments - puts in some initial comments */
1449 /*-----------------------------------------------------------------*/
1451 pic16initialComments (FILE * afile)
1453 initialComments (afile);
1454 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1455 if(pic16_mplab_comp)
1456 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1457 fprintf (afile, iComments2);
1460 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1461 SDCC_VERSION_STR, getBuildNumber() );
1465 /*-----------------------------------------------------------------*/
1466 /* printPublics - generates global declarations for publics */
1467 /*-----------------------------------------------------------------*/
1469 pic16printPublics (FILE *afile)
1473 fprintf (afile, "\n%s", iComments2);
1474 fprintf (afile, "; public variables in this module\n");
1475 fprintf (afile, "%s", iComments2);
1477 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1479 if(!IS_STATIC(sym->etype))
1480 fprintf(afile, "\tglobal %s\n", sym->rname);
1483 /*-----------------------------------------------------------------*/
1484 /* printExterns - generates extern declarations for externs */
1485 /*-----------------------------------------------------------------*/
1487 pic16_printExterns(FILE *afile)
1491 /* print nothing if no externs to declare */
1492 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1495 fprintf(afile, "\n%s", iComments2);
1496 fprintf(afile, "; extern variables in this module\n");
1497 fprintf(afile, "%s", iComments2);
1499 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1500 fprintf(afile, "\textern %s\n", sym->rname);
1502 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1503 fprintf(afile, "\textern _%s\n", sym->name);
1506 /*-----------------------------------------------------------------*/
1507 /* emitOverlay - will emit code for the overlay stuff */
1508 /*-----------------------------------------------------------------*/
1510 pic16emitOverlay (FILE * afile)
1514 if (!elementsInSet (ovrSetSets))
1515 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1517 /* for each of the sets in the overlay segment do */
1518 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1519 ovrset = setNextItem (ovrSetSets))
1524 if (elementsInSet (ovrset))
1526 /* this dummy area is used to fool the assembler
1527 otherwise the assembler will append each of these
1528 declarations into one chunk and will not overlay
1530 fprintf (afile, ";\t.area _DUMMY\n");
1531 /* output the area informtion */
1532 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1535 for (sym = setFirstItem (ovrset); sym;
1536 sym = setNextItem (ovrset))
1539 /* if extern then do nothing */
1540 if (IS_EXTERN (sym->etype))
1543 /* if allocation required check is needed
1544 then check if the symbol really requires
1545 allocation only for local variables */
1546 if (!IS_AGGREGATE (sym->type) &&
1547 !(sym->_isparm && !IS_REGPARM (sym->etype))
1548 && !sym->allocreq && sym->level)
1551 /* if global variable & not static or extern
1552 and addPublics allowed then add it to the public set */
1553 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1554 && !IS_STATIC (sym->etype)) {
1555 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1556 checkAddSym(&publics, sym);
1557 // addSetHead (&publics, sym);
1560 /* if extern then do nothing or is a function
1562 if (IS_FUNC (sym->type))
1566 /* if is has an absolute address then generate
1567 an equate for this no need to allocate space */
1568 if (SPEC_ABSA (sym->etype))
1571 if (options.debug || sym->level == 0)
1572 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1574 fprintf (afile, "%s\t=\t0x%04x\n",
1576 SPEC_ADDR (sym->etype));
1580 if (options.debug || sym->level == 0)
1581 fprintf (afile, "==.\n");
1583 /* allocate space */
1584 fprintf (afile, "%s:\n", sym->rname);
1585 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1592 void emitStatistics(FILE *asmFile)
1594 unsigned long isize, udsize;
1595 statistics.isize = pic16_countInstructions();
1596 isize = (statistics.isize >= 0) ? statistics.isize : 0;
1597 udsize = (statistics.udsize >= 0) ? statistics.udsize : 0;
1599 fprintf (asmFile, "\n\n; Statistics:\n");
1600 fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n; \t%5ld (0x%04lx) words\n",
1601 isize, isize, (isize*100.0)/(128 << 10),
1602 isize>>1, isize>>1);
1603 fprintf (asmFile, "; udata size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n",
1604 udsize, udsize, (udsize*100.0) / ((pic16 ? pic16->RAMsize : 0x200) -256));
1605 fprintf (asmFile, "; access size:\t%5ld (0x%04lx) bytes\n",
1606 statistics.intsize, statistics.intsize);
1608 fprintf (asmFile, "\n\n");
1613 /*-----------------------------------------------------------------*/
1614 /* glue - the final glue that hold the whole thing together */
1615 /*-----------------------------------------------------------------*/
1621 FILE *ovrFile = tempfile();
1623 mainf = newSymbol ("main", 0);
1626 mainf = findSymWithLevel(SymbolTab, mainf);
1628 addSetHead(&tmpfileSet,ovrFile);
1629 pic16_pCodeInitRegisters();
1631 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1632 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1634 pic16_addpBlock(pb);
1636 /* entry point @ start of CSEG */
1637 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1640 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1641 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1642 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1643 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1646 /* put in the call to main */
1647 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1649 if (options.mainreturn) {
1650 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1651 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1653 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1654 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1658 /* At this point we've got all the code in the form of pCode structures */
1659 /* Now it needs to be rearranged into the order it should be placed in the */
1662 pic16_movepBlock2Head('P'); // Last
1663 pic16_movepBlock2Head(code->dbName);
1664 pic16_movepBlock2Head('X');
1665 pic16_movepBlock2Head(statsg->dbName); // First
1667 /* print the global struct definitions */
1670 /* PENDING: this isnt the best place but it will do */
1671 if (port->general.glue_up_main) {
1672 /* create the interrupt vector table */
1673 pic16createInterruptVect (vFile);
1676 addSetHead(&tmpfileSet,vFile);
1678 /* emit code for the all the variables declared */
1681 /* do the overlay segments */
1682 pic16emitOverlay(ovrFile);
1683 pic16_AnalyzepCode('*');
1686 if(pic16_options.dumpcalltree) {
1689 sprintf(buffer, dstFileName);
1690 strcat(buffer, ".calltree");
1691 cFile = fopen(buffer, "w");
1692 pic16_printCallTree( cFile );
1697 pic16_InlinepCode();
1698 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 /* Put all variables into a cblock */
1731 pic16_AnalyzeBanking();
1734 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1735 pic16_OptimizeLocalRegs();
1739 /* remove redundant BANKSELs -- added by RN 2005-01-17 */
1740 if(pic16_options.opt_banksel > 1) {
1741 pic16_OptimizeBanksel();
1744 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1745 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1746 pic16_OptimizeJumps();
1749 /* print the extern variables to this module */
1750 pic16_printExterns(asmFile);
1752 /* print the global variables in this module */
1753 pic16printPublics (asmFile);
1755 pic16_writeUsedRegs(asmFile);
1758 /* no xdata in pic */
1759 /* if external stack then reserve space of it */
1760 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1761 fprintf (asmFile, "%s", iComments2);
1762 fprintf (asmFile, "; external stack \n");
1763 fprintf (asmFile, "%s", iComments2);
1764 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1765 fprintf (asmFile,";\t.ds 256\n");
1770 /* no xdata in pic */
1771 /* copy xtern ram data */
1772 fprintf (asmFile, "%s", iComments2);
1773 fprintf (asmFile, "; external ram data\n");
1774 fprintf (asmFile, "%s", iComments2);
1775 copyFile (asmFile, xdata->oFile);
1779 /* copy the bit segment */
1780 fprintf (asmFile, "%s", iComments2);
1781 fprintf (asmFile, "; bit data\n");
1782 fprintf (asmFile, "%s", iComments2);
1783 copyFile (asmFile, bit->oFile);
1786 /* copy the interrupt vector table */
1787 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1788 fprintf (asmFile, "\n%s", iComments2);
1789 fprintf (asmFile, "; interrupt vector \n");
1790 fprintf (asmFile, "%s", iComments2);
1791 copyFile (asmFile, vFile);
1794 /* copy global & static initialisations */
1795 fprintf (asmFile, "\n%s", iComments2);
1796 fprintf (asmFile, "; global & static initialisations\n");
1797 fprintf (asmFile, "%s", iComments2);
1799 if(pic16_debug_verbose)
1800 fprintf(asmFile, "; A code from now on!\n");
1802 pic16_copypCode(asmFile, 'A');
1804 if(pic16_options.no_crt) {
1805 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1806 fprintf(asmFile, "\tcode\n");
1807 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1811 // copyFile (stderr, code->oFile);
1813 fprintf(asmFile, "; I code from now on!\n");
1814 pic16_copypCode(asmFile, 'I');
1816 if(pic16_debug_verbose)
1817 fprintf(asmFile, "; dbName from now on!\n");
1819 pic16_copypCode(asmFile, statsg->dbName);
1821 if(pic16_options.no_crt) {
1822 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1823 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1827 if(pic16_debug_verbose)
1828 fprintf(asmFile, "; X code from now on!\n");
1830 pic16_copypCode(asmFile, 'X');
1832 if(pic16_debug_verbose)
1833 fprintf(asmFile, "; M code from now on!\n");
1835 pic16_copypCode(asmFile, 'M');
1837 pic16_copypCode(asmFile, code->dbName);
1839 pic16_copypCode(asmFile, 'P');
1841 emitStatistics(asmFile);
1843 fprintf (asmFile,"\tend\n");