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);
675 pic16_emitDB(0x00, ptype, p);
679 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
681 for(remain=0; remain<DCL_ELEM (type); remain++)
682 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
686 // if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
691 for(remain=0; remain<strlen(s); remain++) {
692 pic16_emitDB(s[remain], ptype, p);
698 /*-----------------------------------------------------------------*/
699 /* pic16_printIvalArray - generates code for array initialization */
700 /*-----------------------------------------------------------------*/
702 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
706 int lcnt = 0, size = 0;
713 fprintf(stderr, "%s\n",__FUNCTION__);
715 /* take care of the special case */
716 /* array of characters can be init */
718 if (IS_CHAR (type->next)) {
719 if (!IS_LITERAL(list2val(ilist)->etype)) {
720 werror (W_INIT_WRONG);
724 if(pic16_printIvalChar (sym, type,
725 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
726 SPEC_CVAL (sym->etype).v_char, ptype, p))
729 /* not the special case */
730 if (ilist && ilist->type != INIT_DEEP)
732 werror (E_INIT_STRUCT, sym->name);
736 iloop = ilist->init.deep;
737 lcnt = DCL_ELEM (type);
742 pic16_printIval (sym, type->next, iloop, ptype, p);
743 iloop = (iloop ? iloop->next : NULL);
746 /* if not array limits given & we */
747 /* are out of initialisers then */
748 if (!DCL_ELEM (type) && !iloop)
751 /* no of elements given and we */
752 /* have generated for all of them */
754 /* if initializers left */
756 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
762 /* if we have not been given a size */
763 if (!DCL_ELEM (type))
764 DCL_ELEM (type) = size;
769 /*-----------------------------------------------------------------*/
770 /* pic16_printIvalBitFields - generate initializer for bitfields */
771 /*-----------------------------------------------------------------*/
772 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
776 initList *lilist = *ilist ;
777 unsigned long ival = 0;
782 fprintf(stderr, "%s\n",__FUNCTION__);
788 val = list2val(lilist);
790 if (SPEC_BLEN(lsym->etype) > 8) {
791 size += ((SPEC_BLEN (lsym->etype) / 8) +
792 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
795 size = ((SPEC_BLEN (lsym->etype) / 8) +
796 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
798 i = (unsigned long)floatFromVal(val);
799 i <<= SPEC_BSTR (lsym->etype);
801 if (! ( lsym->next &&
802 (IS_BITFIELD(lsym->next->type)) &&
803 (SPEC_BSTR(lsym->next->etype)))) break;
805 lilist = lilist->next;
809 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
813 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
814 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
817 case 4: /* EEP: why is this db and not dw? */
818 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
819 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
820 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
821 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
824 /* VR - only 1,2,4 size long can be handled???? Why? */
825 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
833 /*-----------------------------------------------------------------*/
834 /* printIvalStruct - generates initial value for structures */
835 /*-----------------------------------------------------------------*/
836 void pic16_printIvalStruct (symbol * sym, sym_link * type,
837 initList * ilist, char ptype, void *p)
840 initList *iloop = NULL;
844 fprintf(stderr, "%s\n",__FUNCTION__);
847 sflds = SPEC_STRUCT (type)->fields;
850 if (ilist->type != INIT_DEEP) {
851 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
855 iloop = ilist->init.deep;
858 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
859 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
860 if (IS_BITFIELD(sflds->type)) {
861 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
863 pic16_printIval (sym, sflds->type, iloop, ptype, p);
867 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
872 /*--------------------------------------------------------------------------*/
873 /* pic16_printIvalCharPtr - generates initial values for character pointers */
874 /*--------------------------------------------------------------------------*/
875 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
879 /* PENDING: this is _very_ mcs51 specific, including a magic
881 It's also endin specific.
883 VR - Attempting to port this function to pic16 port - 8-Jun-2004
888 fprintf(stderr, "%s\n",__FUNCTION__);
891 size = getSize (type);
893 if (val->name && strlen (val->name))
895 if (size == 1) /* This appears to be Z80 specific?? */
897 pic16_emitDS(val->name, ptype, p);
901 pic16_printPointerType (val->name, ptype, p);
906 if (IS_PTR (val->type)) {
907 type = DCL_TYPE (val->type);
909 type = PTR_TYPE (SPEC_OCLS (val->etype));
911 if (val->sym && val->sym->isstrlit) {
912 // this is a literal string
915 pic16_printGPointerType(val->name, type, ptype, p);
919 fprintf (stderr, "*** internal error: unknown size in "
920 "printIvalCharPtr.\n");
926 // these are literals assigned to pointers
930 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
933 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
934 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
937 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
938 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
939 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
947 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
948 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
949 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
955 /*-----------------------------------------------------------------------*/
956 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
957 /*-----------------------------------------------------------------------*/
958 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
965 fprintf(stderr, "%s\n",__FUNCTION__);
969 val = list2val (ilist);
971 val = valCastLiteral(type, 0.0);
974 // an error has been thrown already
978 if (IS_LITERAL(val->etype)) {
979 if (compareType(type, val->etype) == 0) {
980 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
981 printFromToType (val->type, type);
983 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
987 /* check the types */
988 if ((dLvl = compareType (val->type, type->next)) <= 0)
990 pic16_emitDB(0x00, ptype, p);
994 /* now generate the name */
996 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
998 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
1000 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
1002 if(!checkSym(publics, val->sym))
1003 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
1004 /* this has not been declared as extern
1005 * so declare it as a 'late extern' just after the symbol */
1006 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
1007 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1008 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
1017 /*-----------------------------------------------------------------*/
1018 /* pic16_printIvalPtr - generates initial value for pointers */
1019 /*-----------------------------------------------------------------*/
1020 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1026 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1027 sym->rname, getSize(sym->type));
1031 if (ilist && (ilist->type == INIT_DEEP))
1032 ilist = ilist->init.deep;
1034 /* function pointer */
1035 if (IS_FUNC (type->next))
1037 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1041 if (!(val = pic16_initPointer (ilist, type)))
1044 /* if character pointer */
1045 if (IS_CHAR (type->next))
1046 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1049 /* check the type */
1050 if (compareType (type, val->type) == 0) {
1051 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1052 printFromToType (val->type, type);
1055 /* if val is literal */
1056 if (IS_LITERAL (val->etype))
1058 switch (getSize (type))
1061 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1064 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1065 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1068 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1069 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1070 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1073 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1080 size = getSize (type);
1082 if (size == 1) /* Z80 specific?? */
1084 pic16_emitDS(val->name, ptype, p);
1088 pic16_printPointerType (val->name, ptype, p);
1092 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1101 /*-----------------------------------------------------------------*/
1102 /* pic16_printIval - generates code for initial value */
1103 /*-----------------------------------------------------------------*/
1104 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1112 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1113 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1114 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1117 /* if structure then */
1118 if (IS_STRUCT (type))
1120 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1121 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1125 /* if this is an array */
1126 if (IS_ARRAY (type))
1128 // fprintf(stderr,"%s array\n",__FUNCTION__);
1129 pic16_printIvalArray (sym, type, ilist, ptype, p);
1136 // not an aggregate, ilist must be a node
1137 if (ilist->type!=INIT_NODE) {
1138 // or a 1-element list
1139 if (ilist->init.deep->next) {
1140 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1143 ilist=ilist->init.deep;
1148 // and the type must match
1149 itype=ilist->init.node->ftype;
1151 if (compareType(type, itype)==0) {
1152 // special case for literal strings
1153 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1154 // which are really code pointers
1155 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1158 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1159 // printFromToType(itype, type);
1166 /* if this is a pointer */
1169 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1170 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1175 /* if type is SPECIFIER */
1178 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1179 pic16_printIvalType (sym, type, ilist, ptype, p);
1184 int PIC16_IS_CONFIG_ADDRESS(int address)
1186 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1189 int PIC16_IS_IDLOC_ADDRESS(int address)
1191 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1194 /* wrapper function for the above */
1195 int PIC16_IS_HWREG_ADDRESS(int address)
1197 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1201 /*-----------------------------------------------------------------*/
1202 /* emitStaticSeg - emitcode for the static segment */
1203 /*-----------------------------------------------------------------*/
1205 pic16emitStaticSeg (memmap * map)
1208 static int didcode=0;
1210 //fprintf(stderr, "%s\n",__FUNCTION__);
1214 /* for all variables in this segment do */
1215 for (sym = setFirstItem (map->syms); sym;
1216 sym = setNextItem (map->syms))
1220 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1221 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1222 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1223 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1224 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1225 printTypeChain( sym->type, stderr );
1226 fprintf(stderr, "\n");
1229 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1230 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1231 (int) floatFromVal(list2val(sym->ival)));
1236 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1237 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1238 (char) floatFromVal(list2val(sym->ival)));
1243 /* if it is "extern" then do nothing */
1244 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1245 checkAddSym(&externs, sym);
1249 /* if it is not static add it to the public
1251 if (!IS_STATIC (sym->etype)) {
1252 /* do not emit if it is a config word declaration */
1253 checkAddSym(&publics, sym);
1256 /* print extra debug info if required */
1257 if (options.debug || sym->level == 0) {
1258 /* NOTE to me - cdbFile may be null in which case,
1259 * the sym name will be printed to stdout. oh well */
1260 debugFile->writeSymbol(sym);
1263 /* if it has an absolute address */
1264 if (SPEC_ABSA (sym->etype)) {
1265 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1266 // __FILE__, __LINE__, sym->name);
1268 /* if it has an initial value */
1276 /* symbol has absolute address and initial value */
1278 resolveIvalSym (sym->ival, sym->type);
1279 asym = newSymbol(sym->rname, 0);
1280 abSym = Safe_calloc(1, sizeof(absSym));
1281 strcpy(abSym->name, sym->rname);
1282 abSym->address = SPEC_ADDR( sym->etype );
1283 addSet(&absSymSet, abSym);
1285 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1286 pic16_addpBlock(pb);
1288 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1289 PCF(pcf)->absblock = 1;
1291 pic16_addpCode2pBlock(pb,pcf);
1292 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1293 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1294 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1295 pic16_flushDB('p', (void *)pb);
1297 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1303 /* symbol has absolute address but no initial value */
1305 /* allocate space */
1306 fprintf (code->oFile, "%s:\n", sym->rname);
1308 /* special case for character strings */
1309 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1310 SPEC_CVAL (sym->etype).v_char) {
1312 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1314 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1321 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1322 // __FILE__, __LINE__, sym->name);
1325 /* if it has an initial value */
1329 /* symbol doesn't have absolute address but has initial value */
1330 fprintf (code->oFile, "%s:\n", sym->rname);
1332 resolveIvalSym (sym->ival, sym->type);
1334 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1335 pic16_addpBlock(pb);
1338 /* make sure that 'code' directive is emitted before, once */
1339 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1344 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1346 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1347 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1348 pic16_flushDB('p', (void *)pb);
1352 /* symbol doesn't have absolute address and no initial value */
1353 /* allocate space */
1354 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1355 fprintf (code->oFile, "%s:\n", sym->rname);
1356 /* special case for character strings */
1357 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1358 SPEC_CVAL (sym->etype).v_char) {
1360 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1362 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1373 /*-----------------------------------------------------------------*/
1374 /* pic16_emitConfigRegs - emits the configuration registers */
1375 /*-----------------------------------------------------------------*/
1376 void pic16_emitConfigRegs(FILE *of)
1380 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1381 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1382 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1383 pic16->cwInfo.confAddrStart+i,
1384 pic16->cwInfo.crInfo[i].value);
1387 void pic16_emitIDRegs(FILE *of)
1391 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1392 if(pic16->idInfo.irInfo[i].emit)
1393 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1394 pic16->idInfo.idAddrStart+i,
1395 pic16->idInfo.irInfo[i].value);
1402 /* no special considerations for the following
1403 data, idata & bit & xdata */
1404 pic16emitRegularMap (data, TRUE, TRUE);
1405 pic16emitRegularMap (idata, TRUE, TRUE);
1406 pic16emitRegularMap (bit, TRUE, FALSE);
1407 pic16emitRegularMap (xdata, TRUE, TRUE);
1408 pic16emitRegularMap (sfr, FALSE, FALSE);
1409 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1410 pic16emitRegularMap (code, TRUE, FALSE);
1411 pic16emitStaticSeg (statsg);
1414 /*-----------------------------------------------------------------*/
1415 /* createInterruptVect - creates the interrupt vector */
1416 /*-----------------------------------------------------------------*/
1418 pic16createInterruptVect (FILE * vFile)
1420 /* if the main is only a prototype ie. no body then do nothing */
1422 if (!IFFUNC_HASBODY(mainf->type)) {
1423 /* if ! compile only then main function should be present */
1424 if (!options.cc_only)
1430 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1431 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1432 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1434 /* this is an overkill since WE are the port,
1435 * and we know if we have a genIVT function! */
1437 port->genIVT(vFile, interrupts, maxInterrupts);
1445 /*-----------------------------------------------------------------*/
1446 /* pic16initialComments - puts in some initial comments */
1447 /*-----------------------------------------------------------------*/
1449 pic16initialComments (FILE * afile)
1451 initialComments (afile);
1452 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1453 if(pic16_mplab_comp)
1454 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1455 fprintf (afile, iComments2);
1458 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1459 SDCC_VERSION_STR, getBuildNumber() );
1463 /*-----------------------------------------------------------------*/
1464 /* printPublics - generates global declarations for publics */
1465 /*-----------------------------------------------------------------*/
1467 pic16printPublics (FILE *afile)
1471 fprintf (afile, "\n%s", iComments2);
1472 fprintf (afile, "; public variables in this module\n");
1473 fprintf (afile, "%s", iComments2);
1475 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1477 if(!IS_STATIC(sym->etype))
1478 fprintf(afile, "\tglobal %s\n", sym->rname);
1481 /*-----------------------------------------------------------------*/
1482 /* printExterns - generates extern declarations for externs */
1483 /*-----------------------------------------------------------------*/
1485 pic16_printExterns(FILE *afile)
1489 /* print nothing if no externs to declare */
1490 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1493 fprintf(afile, "\n%s", iComments2);
1494 fprintf(afile, "; extern variables in this module\n");
1495 fprintf(afile, "%s", iComments2);
1497 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1498 fprintf(afile, "\textern %s\n", sym->rname);
1500 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1501 fprintf(afile, "\textern _%s\n", sym->name);
1504 /*-----------------------------------------------------------------*/
1505 /* emitOverlay - will emit code for the overlay stuff */
1506 /*-----------------------------------------------------------------*/
1508 pic16emitOverlay (FILE * afile)
1512 if (!elementsInSet (ovrSetSets))
1513 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1515 /* for each of the sets in the overlay segment do */
1516 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1517 ovrset = setNextItem (ovrSetSets))
1522 if (elementsInSet (ovrset))
1524 /* this dummy area is used to fool the assembler
1525 otherwise the assembler will append each of these
1526 declarations into one chunk and will not overlay
1528 fprintf (afile, ";\t.area _DUMMY\n");
1529 /* output the area informtion */
1530 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1533 for (sym = setFirstItem (ovrset); sym;
1534 sym = setNextItem (ovrset))
1537 /* if extern then do nothing */
1538 if (IS_EXTERN (sym->etype))
1541 /* if allocation required check is needed
1542 then check if the symbol really requires
1543 allocation only for local variables */
1544 if (!IS_AGGREGATE (sym->type) &&
1545 !(sym->_isparm && !IS_REGPARM (sym->etype))
1546 && !sym->allocreq && sym->level)
1549 /* if global variable & not static or extern
1550 and addPublics allowed then add it to the public set */
1551 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1552 && !IS_STATIC (sym->etype)) {
1553 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1554 checkAddSym(&publics, sym);
1555 // addSetHead (&publics, sym);
1558 /* if extern then do nothing or is a function
1560 if (IS_FUNC (sym->type))
1564 /* if is has an absolute address then generate
1565 an equate for this no need to allocate space */
1566 if (SPEC_ABSA (sym->etype))
1569 if (options.debug || sym->level == 0)
1570 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1572 fprintf (afile, "%s\t=\t0x%04x\n",
1574 SPEC_ADDR (sym->etype));
1578 if (options.debug || sym->level == 0)
1579 fprintf (afile, "==.\n");
1581 /* allocate space */
1582 fprintf (afile, "%s:\n", sym->rname);
1583 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1590 void emitStatistics(FILE *asmFile)
1592 unsigned long isize, udsize;
1593 statistics.isize = pic16_countInstructions();
1594 isize = (statistics.isize >= 0) ? statistics.isize : 0;
1595 udsize = (statistics.udsize >= 0) ? statistics.udsize : 0;
1597 fprintf (asmFile, "\n\n; Statistics:\n");
1598 fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n; \t%5ld (0x%04lx) words\n",
1599 isize, isize, (isize*100.0)/(128 << 10),
1600 isize>>1, isize>>1);
1601 fprintf (asmFile, "; udata size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n",
1602 udsize, udsize, (udsize*100.0) / ((pic16 ? pic16->RAMsize : 0x200) -256));
1603 fprintf (asmFile, "; access size:\t%5ld (0x%04lx) bytes\n",
1604 statistics.intsize, statistics.intsize);
1606 fprintf (asmFile, "\n\n");
1611 /*-----------------------------------------------------------------*/
1612 /* glue - the final glue that hold the whole thing together */
1613 /*-----------------------------------------------------------------*/
1619 FILE *ovrFile = tempfile();
1621 mainf = newSymbol ("main", 0);
1624 mainf = findSymWithLevel(SymbolTab, mainf);
1626 addSetHead(&tmpfileSet,ovrFile);
1627 pic16_pCodeInitRegisters();
1629 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1630 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1632 pic16_addpBlock(pb);
1634 /* entry point @ start of CSEG */
1635 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1638 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1639 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1640 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1641 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1644 /* put in the call to main */
1645 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1647 if (options.mainreturn) {
1648 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1649 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1651 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1652 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1656 /* At this point we've got all the code in the form of pCode structures */
1657 /* Now it needs to be rearranged into the order it should be placed in the */
1660 pic16_movepBlock2Head('P'); // Last
1661 pic16_movepBlock2Head(code->dbName);
1662 pic16_movepBlock2Head('X');
1663 pic16_movepBlock2Head(statsg->dbName); // First
1665 /* print the global struct definitions */
1668 /* PENDING: this isnt the best place but it will do */
1669 if (port->general.glue_up_main) {
1670 /* create the interrupt vector table */
1671 pic16createInterruptVect (vFile);
1674 addSetHead(&tmpfileSet,vFile);
1676 /* emit code for the all the variables declared */
1679 /* do the overlay segments */
1680 pic16emitOverlay(ovrFile);
1681 pic16_AnalyzepCode('*');
1684 if(pic16_options.dumpcalltree) {
1687 sprintf(buffer, dstFileName);
1688 strcat(buffer, ".calltree");
1689 cFile = fopen(buffer, "w");
1690 pic16_printCallTree( cFile );
1695 pic16_InlinepCode();
1696 pic16_AnalyzepCode('*');
1699 if(pic16_debug_verbose)
1702 /* now put it all together into the assembler file */
1703 /* create the assembler file name */
1704 if((noAssemble || options.c1mode) && fullDstFileName) {
1705 sprintf (buffer, fullDstFileName);
1707 sprintf (buffer, dstFileName);
1708 strcat (buffer, ".asm");
1711 if(!(asmFile = fopen (buffer, "w"))) {
1712 werror (E_FILE_OPEN_ERR, buffer);
1716 /* initial comments */
1717 pic16initialComments (asmFile);
1719 /* print module name */
1721 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1723 /* Let the port generate any global directives, etc. */
1724 if(port->genAssemblerPreamble) {
1725 port->genAssemblerPreamble(asmFile);
1728 /* Put all variables into a cblock */
1729 pic16_AnalyzeBanking();
1732 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1733 pic16_OptimizeLocalRegs();
1737 /* remove redundant BANKSELs -- added by RN 2005-01-17 */
1738 if(pic16_options.opt_banksel > 1) {
1739 pic16_OptimizeBanksel();
1742 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1743 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1744 pic16_OptimizeJumps();
1747 /* print the extern variables to this module */
1748 pic16_printExterns(asmFile);
1750 /* print the global variables in this module */
1751 pic16printPublics (asmFile);
1753 pic16_writeUsedRegs(asmFile);
1756 /* no xdata in pic */
1757 /* if external stack then reserve space of it */
1758 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1759 fprintf (asmFile, "%s", iComments2);
1760 fprintf (asmFile, "; external stack \n");
1761 fprintf (asmFile, "%s", iComments2);
1762 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1763 fprintf (asmFile,";\t.ds 256\n");
1768 /* no xdata in pic */
1769 /* copy xtern ram data */
1770 fprintf (asmFile, "%s", iComments2);
1771 fprintf (asmFile, "; external ram data\n");
1772 fprintf (asmFile, "%s", iComments2);
1773 copyFile (asmFile, xdata->oFile);
1777 /* copy the bit segment */
1778 fprintf (asmFile, "%s", iComments2);
1779 fprintf (asmFile, "; bit data\n");
1780 fprintf (asmFile, "%s", iComments2);
1781 copyFile (asmFile, bit->oFile);
1784 /* copy the interrupt vector table */
1785 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1786 fprintf (asmFile, "\n%s", iComments2);
1787 fprintf (asmFile, "; interrupt vector \n");
1788 fprintf (asmFile, "%s", iComments2);
1789 copyFile (asmFile, vFile);
1792 /* copy global & static initialisations */
1793 fprintf (asmFile, "\n%s", iComments2);
1794 fprintf (asmFile, "; global & static initialisations\n");
1795 fprintf (asmFile, "%s", iComments2);
1797 if(pic16_debug_verbose)
1798 fprintf(asmFile, "; A code from now on!\n");
1800 pic16_copypCode(asmFile, 'A');
1802 if(pic16_options.no_crt) {
1803 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1804 fprintf(asmFile, "\tcode\n");
1805 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1809 // copyFile (stderr, code->oFile);
1811 fprintf(asmFile, "; I code from now on!\n");
1812 pic16_copypCode(asmFile, 'I');
1814 if(pic16_debug_verbose)
1815 fprintf(asmFile, "; dbName from now on!\n");
1817 pic16_copypCode(asmFile, statsg->dbName);
1819 if(pic16_options.no_crt) {
1820 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1821 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1825 if(pic16_debug_verbose)
1826 fprintf(asmFile, "; X code from now on!\n");
1828 pic16_copypCode(asmFile, 'X');
1830 if(pic16_debug_verbose)
1831 fprintf(asmFile, "; M code from now on!\n");
1833 pic16_copypCode(asmFile, 'M');
1835 pic16_copypCode(asmFile, code->dbName);
1837 pic16_copypCode(asmFile, 'P');
1839 emitStatistics(asmFile);
1841 fprintf (asmFile,"\tend\n");