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 (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 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
657 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
659 if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
661 pic16_emitDB(0x00, ptype, p);
667 for(remain=0; remain<strlen(s); remain++) {
668 pic16_emitDB(s[remain], ptype, p);
674 /*-----------------------------------------------------------------*/
675 /* pic16_printIvalArray - generates code for array initialization */
676 /*-----------------------------------------------------------------*/
678 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
682 int lcnt = 0, size = 0;
689 fprintf(stderr, "%s\n",__FUNCTION__);
691 /* take care of the special case */
692 /* array of characters can be init */
694 if (IS_CHAR (type->next)) {
695 if (!IS_LITERAL(list2val(ilist)->etype)) {
696 werror (W_INIT_WRONG);
700 if(pic16_printIvalChar (type,
701 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
702 SPEC_CVAL (sym->etype).v_char, ptype, p))
705 /* not the special case */
706 if (ilist && ilist->type != INIT_DEEP)
708 werror (E_INIT_STRUCT, sym->name);
712 iloop = ilist->init.deep;
713 lcnt = DCL_ELEM (type);
718 pic16_printIval (sym, type->next, iloop, ptype, p);
719 iloop = (iloop ? iloop->next : NULL);
722 /* if not array limits given & we */
723 /* are out of initialisers then */
724 if (!DCL_ELEM (type) && !iloop)
727 /* no of elements given and we */
728 /* have generated for all of them */
730 /* if initializers left */
732 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
738 /* if we have not been given a size */
739 if (!DCL_ELEM (type))
740 DCL_ELEM (type) = size;
745 /*-----------------------------------------------------------------*/
746 /* pic16_printIvalBitFields - generate initializer for bitfields */
747 /*-----------------------------------------------------------------*/
748 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
752 initList *lilist = *ilist ;
753 unsigned long ival = 0;
758 fprintf(stderr, "%s\n",__FUNCTION__);
764 val = list2val(lilist);
766 if (SPEC_BLEN(lsym->etype) > 8) {
767 size += ((SPEC_BLEN (lsym->etype) / 8) +
768 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
771 size = ((SPEC_BLEN (lsym->etype) / 8) +
772 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
774 i = (unsigned long)floatFromVal(val);
775 i <<= SPEC_BSTR (lsym->etype);
777 if (! ( lsym->next &&
778 (IS_BITFIELD(lsym->next->type)) &&
779 (SPEC_BSTR(lsym->next->etype)))) break;
781 lilist = lilist->next;
785 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
789 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
790 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
793 case 4: /* EEP: why is this db and not dw? */
794 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
795 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
796 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
797 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
800 /* VR - only 1,2,4 size long can be handled???? Why? */
801 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
809 /*-----------------------------------------------------------------*/
810 /* printIvalStruct - generates initial value for structures */
811 /*-----------------------------------------------------------------*/
812 void pic16_printIvalStruct (symbol * sym, sym_link * type,
813 initList * ilist, char ptype, void *p)
816 initList *iloop = NULL;
820 fprintf(stderr, "%s\n",__FUNCTION__);
823 sflds = SPEC_STRUCT (type)->fields;
826 if (ilist->type != INIT_DEEP) {
827 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
831 iloop = ilist->init.deep;
834 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
835 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
836 if (IS_BITFIELD(sflds->type)) {
837 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
839 pic16_printIval (sym, sflds->type, iloop, ptype, p);
843 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
848 /*--------------------------------------------------------------------------*/
849 /* pic16_printIvalCharPtr - generates initial values for character pointers */
850 /*--------------------------------------------------------------------------*/
851 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
855 /* PENDING: this is _very_ mcs51 specific, including a magic
857 It's also endin specific.
859 VR - Attempting to port this function to pic16 port - 8-Jun-2004
864 fprintf(stderr, "%s\n",__FUNCTION__);
867 size = getSize (type);
869 if (val->name && strlen (val->name))
871 if (size == 1) /* This appears to be Z80 specific?? */
873 pic16_emitDS(val->name, ptype, p);
877 pic16_printPointerType (val->name, ptype, p);
882 if (IS_PTR (val->type)) {
883 type = DCL_TYPE (val->type);
885 type = PTR_TYPE (SPEC_OCLS (val->etype));
887 if (val->sym && val->sym->isstrlit) {
888 // this is a literal string
891 pic16_printGPointerType(val->name, type, ptype, p);
895 fprintf (stderr, "*** internal error: unknown size in "
896 "printIvalCharPtr.\n");
902 // these are literals assigned to pointers
906 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
909 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
910 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
913 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
914 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
915 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
923 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
924 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
925 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
931 /*-----------------------------------------------------------------------*/
932 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
933 /*-----------------------------------------------------------------------*/
934 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
941 fprintf(stderr, "%s\n",__FUNCTION__);
945 val = list2val (ilist);
947 val = valCastLiteral(type, 0.0);
950 // an error has been thrown already
954 if (IS_LITERAL(val->etype)) {
955 if (compareType(type, val->etype) == 0) {
956 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
957 printFromToType (val->type, type);
959 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
963 /* check the types */
964 if ((dLvl = compareType (val->type, type->next)) <= 0)
966 pic16_emitDB(0x00, ptype, p);
970 /* now generate the name */
972 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
974 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
976 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
978 if(!checkSym(publics, val->sym))
979 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
980 /* this has not been declared as extern
981 * so declare it as a 'late extern' just after the symbol */
982 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
983 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
984 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
993 /*-----------------------------------------------------------------*/
994 /* pic16_printIvalPtr - generates initial value for pointers */
995 /*-----------------------------------------------------------------*/
996 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1002 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1003 sym->rname, getSize(sym->type));
1007 if (ilist && (ilist->type == INIT_DEEP))
1008 ilist = ilist->init.deep;
1010 /* function pointer */
1011 if (IS_FUNC (type->next))
1013 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1017 if (!(val = pic16_initPointer (ilist, type)))
1020 /* if character pointer */
1021 if (IS_CHAR (type->next))
1022 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1025 /* check the type */
1026 if (compareType (type, val->type) == 0) {
1027 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1028 printFromToType (val->type, type);
1031 /* if val is literal */
1032 if (IS_LITERAL (val->etype))
1034 switch (getSize (type))
1037 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1040 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1041 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1044 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1045 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1046 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1049 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1056 size = getSize (type);
1058 if (size == 1) /* Z80 specific?? */
1060 pic16_emitDS(val->name, ptype, p);
1064 pic16_printPointerType (val->name, ptype, p);
1068 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1077 /*-----------------------------------------------------------------*/
1078 /* pic16_printIval - generates code for initial value */
1079 /*-----------------------------------------------------------------*/
1080 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1088 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1089 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1090 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1093 /* if structure then */
1094 if (IS_STRUCT (type))
1096 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1097 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1101 /* if this is an array */
1102 if (IS_ARRAY (type))
1104 // fprintf(stderr,"%s array\n",__FUNCTION__);
1105 pic16_printIvalArray (sym, type, ilist, ptype, p);
1112 // not an aggregate, ilist must be a node
1113 if (ilist->type!=INIT_NODE) {
1114 // or a 1-element list
1115 if (ilist->init.deep->next) {
1116 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1119 ilist=ilist->init.deep;
1124 // and the type must match
1125 itype=ilist->init.node->ftype;
1127 if (compareType(type, itype)==0) {
1128 // special case for literal strings
1129 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1130 // which are really code pointers
1131 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1134 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1135 // printFromToType(itype, type);
1142 /* if this is a pointer */
1145 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1146 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1151 /* if type is SPECIFIER */
1154 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1155 pic16_printIvalType (sym, type, ilist, ptype, p);
1160 int PIC16_IS_CONFIG_ADDRESS(int address)
1162 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1165 int PIC16_IS_IDLOC_ADDRESS(int address)
1167 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1170 /* wrapper function for the above */
1171 int PIC16_IS_HWREG_ADDRESS(int address)
1173 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1177 /*-----------------------------------------------------------------*/
1178 /* emitStaticSeg - emitcode for the static segment */
1179 /*-----------------------------------------------------------------*/
1181 pic16emitStaticSeg (memmap * map)
1184 static int didcode=0;
1186 //fprintf(stderr, "%s\n",__FUNCTION__);
1190 /* for all variables in this segment do */
1191 for (sym = setFirstItem (map->syms); sym;
1192 sym = setNextItem (map->syms))
1196 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1197 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1198 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1199 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1200 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1201 printTypeChain( sym->type, stderr );
1202 fprintf(stderr, "\n");
1205 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1206 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1207 (int) floatFromVal(list2val(sym->ival)));
1212 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1213 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1214 (char) floatFromVal(list2val(sym->ival)));
1219 /* if it is "extern" then do nothing */
1220 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1221 checkAddSym(&externs, sym);
1225 /* if it is not static add it to the public
1227 if (!IS_STATIC (sym->etype)) {
1228 /* do not emit if it is a config word declaration */
1229 checkAddSym(&publics, sym);
1232 /* print extra debug info if required */
1233 if (options.debug || sym->level == 0) {
1234 /* NOTE to me - cdbFile may be null in which case,
1235 * the sym name will be printed to stdout. oh well */
1236 debugFile->writeSymbol(sym);
1239 /* if it has an absolute address */
1240 if (SPEC_ABSA (sym->etype)) {
1241 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1242 // __FILE__, __LINE__, sym->name);
1244 /* if it has an initial value */
1252 /* symbol has absolute address and initial value */
1254 resolveIvalSym (sym->ival, sym->type);
1255 asym = newSymbol(sym->rname, 0);
1256 abSym = Safe_calloc(1, sizeof(absSym));
1257 strcpy(abSym->name, sym->rname);
1258 abSym->address = SPEC_ADDR( sym->etype );
1259 addSet(&absSymSet, abSym);
1261 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1262 pic16_addpBlock(pb);
1264 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1265 PCF(pcf)->absblock = 1;
1267 pic16_addpCode2pBlock(pb,pcf);
1268 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1269 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1270 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1271 pic16_flushDB('p', (void *)pb);
1273 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1279 /* symbol has absolute address but no initial value */
1281 /* allocate space */
1282 fprintf (code->oFile, "%s:\n", sym->rname);
1284 /* special case for character strings */
1285 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1286 SPEC_CVAL (sym->etype).v_char) {
1288 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1290 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1297 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1298 // __FILE__, __LINE__, sym->name);
1301 /* if it has an initial value */
1305 /* symbol doesn't have absolute address but has initial value */
1306 fprintf (code->oFile, "%s:\n", sym->rname);
1308 resolveIvalSym (sym->ival, sym->type);
1310 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1311 pic16_addpBlock(pb);
1314 /* make sure that 'code' directive is emitted before, once */
1315 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1320 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1322 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1323 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1324 pic16_flushDB('p', (void *)pb);
1328 /* symbol doesn't have absolute address and no initial value */
1329 /* allocate space */
1330 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1331 fprintf (code->oFile, "%s:\n", sym->rname);
1332 /* special case for character strings */
1333 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1334 SPEC_CVAL (sym->etype).v_char) {
1336 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1338 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1349 /*-----------------------------------------------------------------*/
1350 /* pic16_emitConfigRegs - emits the configuration registers */
1351 /*-----------------------------------------------------------------*/
1352 void pic16_emitConfigRegs(FILE *of)
1356 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1357 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1358 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1359 pic16->cwInfo.confAddrStart+i,
1360 pic16->cwInfo.crInfo[i].value);
1363 void pic16_emitIDRegs(FILE *of)
1367 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1368 if(pic16->idInfo.irInfo[i].emit)
1369 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1370 pic16->idInfo.idAddrStart+i,
1371 pic16->idInfo.irInfo[i].value);
1378 /* no special considerations for the following
1379 data, idata & bit & xdata */
1380 pic16emitRegularMap (data, TRUE, TRUE);
1381 pic16emitRegularMap (idata, TRUE, TRUE);
1382 pic16emitRegularMap (bit, TRUE, FALSE);
1383 pic16emitRegularMap (xdata, TRUE, TRUE);
1384 pic16emitRegularMap (sfr, FALSE, FALSE);
1385 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1386 pic16emitRegularMap (code, TRUE, FALSE);
1387 pic16emitStaticSeg (statsg);
1390 /*-----------------------------------------------------------------*/
1391 /* createInterruptVect - creates the interrupt vector */
1392 /*-----------------------------------------------------------------*/
1394 pic16createInterruptVect (FILE * vFile)
1396 /* if the main is only a prototype ie. no body then do nothing */
1398 if (!IFFUNC_HASBODY(mainf->type)) {
1399 /* if ! compile only then main function should be present */
1400 if (!options.cc_only)
1406 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1407 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1408 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1410 /* this is an overkill since WE are the port,
1411 * and we know if we have a genIVT function! */
1413 port->genIVT(vFile, interrupts, maxInterrupts);
1420 /*-----------------------------------------------------------------*/
1421 /* pic16initialComments - puts in some initial comments */
1422 /*-----------------------------------------------------------------*/
1424 pic16initialComments (FILE * afile)
1426 initialComments (afile);
1427 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1428 if(pic16_mplab_comp)
1429 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1430 fprintf (afile, iComments2);
1433 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1434 SDCC_VERSION_STR, getBuildNumber() );
1438 /*-----------------------------------------------------------------*/
1439 /* printPublics - generates global declarations for publics */
1440 /*-----------------------------------------------------------------*/
1442 pic16printPublics (FILE *afile)
1446 fprintf (afile, "\n%s", iComments2);
1447 fprintf (afile, "; public variables in this module\n");
1448 fprintf (afile, "%s", iComments2);
1450 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1452 if(!IS_STATIC(sym->etype))
1453 fprintf(afile, "\tglobal %s\n", sym->rname);
1456 /*-----------------------------------------------------------------*/
1457 /* printExterns - generates extern declarations for externs */
1458 /*-----------------------------------------------------------------*/
1460 pic16_printExterns(FILE *afile)
1464 /* print nothing if no externs to declare */
1465 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1468 fprintf(afile, "\n%s", iComments2);
1469 fprintf(afile, "; extern variables in this module\n");
1470 fprintf(afile, "%s", iComments2);
1472 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1473 fprintf(afile, "\textern %s\n", sym->rname);
1475 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1476 fprintf(afile, "\textern _%s\n", sym->name);
1479 /*-----------------------------------------------------------------*/
1480 /* emitOverlay - will emit code for the overlay stuff */
1481 /*-----------------------------------------------------------------*/
1483 pic16emitOverlay (FILE * afile)
1487 if (!elementsInSet (ovrSetSets))
1488 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1490 /* for each of the sets in the overlay segment do */
1491 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1492 ovrset = setNextItem (ovrSetSets))
1497 if (elementsInSet (ovrset))
1499 /* this dummy area is used to fool the assembler
1500 otherwise the assembler will append each of these
1501 declarations into one chunk and will not overlay
1503 fprintf (afile, ";\t.area _DUMMY\n");
1504 /* output the area informtion */
1505 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1508 for (sym = setFirstItem (ovrset); sym;
1509 sym = setNextItem (ovrset))
1512 /* if extern then do nothing */
1513 if (IS_EXTERN (sym->etype))
1516 /* if allocation required check is needed
1517 then check if the symbol really requires
1518 allocation only for local variables */
1519 if (!IS_AGGREGATE (sym->type) &&
1520 !(sym->_isparm && !IS_REGPARM (sym->etype))
1521 && !sym->allocreq && sym->level)
1524 /* if global variable & not static or extern
1525 and addPublics allowed then add it to the public set */
1526 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1527 && !IS_STATIC (sym->etype)) {
1528 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1529 checkAddSym(&publics, sym);
1530 // addSetHead (&publics, sym);
1533 /* if extern then do nothing or is a function
1535 if (IS_FUNC (sym->type))
1539 /* if is has an absolute address then generate
1540 an equate for this no need to allocate space */
1541 if (SPEC_ABSA (sym->etype))
1544 if (options.debug || sym->level == 0)
1545 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1547 fprintf (afile, "%s\t=\t0x%04x\n",
1549 SPEC_ADDR (sym->etype));
1553 if (options.debug || sym->level == 0)
1554 fprintf (afile, "==.\n");
1556 /* allocate space */
1557 fprintf (afile, "%s:\n", sym->rname);
1558 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1565 void emitStatistics(FILE *asmFile)
1567 unsigned long isize, udsize;
1568 statistics.isize = pic16_countInstructions();
1569 isize = (statistics.isize >= 0) ? statistics.isize : 0;
1570 udsize = (statistics.udsize >= 0) ? statistics.udsize : 0;
1572 fprintf (asmFile, "\n\n; Statistics:\n");
1573 fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n; \t%5ld (0x%04lx) words\n",
1574 isize, isize, (isize*100.0)/(128 << 10),
1575 isize>>1, isize>>1);
1576 fprintf (asmFile, "; udata size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n",
1577 udsize, udsize, (udsize*100.0) / ((pic16 ? pic16->RAMsize : 0x200) -256));
1578 fprintf (asmFile, "; access size:\t%5ld (0x%04lx) bytes\n",
1579 statistics.intsize, statistics.intsize);
1581 fprintf (asmFile, "\n\n");
1586 /*-----------------------------------------------------------------*/
1587 /* glue - the final glue that hold the whole thing together */
1588 /*-----------------------------------------------------------------*/
1594 FILE *ovrFile = tempfile();
1596 mainf = newSymbol ("main", 0);
1599 mainf = findSymWithLevel(SymbolTab, mainf);
1601 addSetHead(&tmpfileSet,ovrFile);
1602 pic16_pCodeInitRegisters();
1604 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1605 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1607 pic16_addpBlock(pb);
1609 /* entry point @ start of CSEG */
1610 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1613 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1614 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1615 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1616 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1619 /* put in the call to main */
1620 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1622 if (options.mainreturn) {
1623 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1624 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1626 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1627 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1631 /* At this point we've got all the code in the form of pCode structures */
1632 /* Now it needs to be rearranged into the order it should be placed in the */
1635 pic16_movepBlock2Head('P'); // Last
1636 pic16_movepBlock2Head(code->dbName);
1637 pic16_movepBlock2Head('X');
1638 pic16_movepBlock2Head(statsg->dbName); // First
1640 /* print the global struct definitions */
1643 /* PENDING: this isnt the best place but it will do */
1644 if (port->general.glue_up_main) {
1645 /* create the interrupt vector table */
1646 pic16createInterruptVect (vFile);
1649 addSetHead(&tmpfileSet,vFile);
1651 /* emit code for the all the variables declared */
1654 /* do the overlay segments */
1655 pic16emitOverlay(ovrFile);
1656 pic16_AnalyzepCode('*');
1659 if(pic16_options.dumpcalltree) {
1662 sprintf(buffer, dstFileName);
1663 strcat(buffer, ".calltree");
1664 cFile = fopen(buffer, "w");
1665 pic16_printCallTree( cFile );
1670 pic16_InlinepCode();
1671 pic16_AnalyzepCode('*');
1674 if(pic16_debug_verbose)
1677 /* now put it all together into the assembler file */
1678 /* create the assembler file name */
1679 if((noAssemble || options.c1mode) && fullDstFileName) {
1680 sprintf (buffer, fullDstFileName);
1682 sprintf (buffer, dstFileName);
1683 strcat (buffer, ".asm");
1686 if(!(asmFile = fopen (buffer, "w"))) {
1687 werror (E_FILE_OPEN_ERR, buffer);
1691 /* initial comments */
1692 pic16initialComments (asmFile);
1694 /* print module name */
1696 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1698 /* Let the port generate any global directives, etc. */
1699 if(port->genAssemblerPreamble) {
1700 port->genAssemblerPreamble(asmFile);
1703 /* Put all variables into a cblock */
1704 pic16_AnalyzeBanking();
1706 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1707 pic16_OptimizeLocalRegs();
1710 /* remove redundant BANKSELs -- added by RN 2005-01-17 */
1711 if(pic16_options.opt_banksel > 1) {
1712 pic16_OptimizeBanksel();
1715 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1716 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1717 pic16_OptimizeJumps();
1720 /* print the extern variables to this module */
1721 pic16_printExterns(asmFile);
1723 /* print the global variables in this module */
1724 pic16printPublics (asmFile);
1726 pic16_writeUsedRegs(asmFile);
1729 /* no xdata in pic */
1730 /* if external stack then reserve space of it */
1731 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1732 fprintf (asmFile, "%s", iComments2);
1733 fprintf (asmFile, "; external stack \n");
1734 fprintf (asmFile, "%s", iComments2);
1735 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1736 fprintf (asmFile,";\t.ds 256\n");
1741 /* no xdata in pic */
1742 /* copy xtern ram data */
1743 fprintf (asmFile, "%s", iComments2);
1744 fprintf (asmFile, "; external ram data\n");
1745 fprintf (asmFile, "%s", iComments2);
1746 copyFile (asmFile, xdata->oFile);
1750 /* copy the bit segment */
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile, "; bit data\n");
1753 fprintf (asmFile, "%s", iComments2);
1754 copyFile (asmFile, bit->oFile);
1757 /* copy the interrupt vector table */
1758 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1759 fprintf (asmFile, "\n%s", iComments2);
1760 fprintf (asmFile, "; interrupt vector \n");
1761 fprintf (asmFile, "%s", iComments2);
1762 copyFile (asmFile, vFile);
1765 /* copy global & static initialisations */
1766 fprintf (asmFile, "\n%s", iComments2);
1767 fprintf (asmFile, "; global & static initialisations\n");
1768 fprintf (asmFile, "%s", iComments2);
1770 if(pic16_debug_verbose)
1771 fprintf(asmFile, "; A code from now on!\n");
1773 pic16_copypCode(asmFile, 'A');
1775 if(pic16_options.no_crt) {
1776 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1777 fprintf(asmFile, "\tcode\n");
1778 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1782 // copyFile (stderr, code->oFile);
1784 fprintf(asmFile, "; I code from now on!\n");
1785 pic16_copypCode(asmFile, 'I');
1787 if(pic16_debug_verbose)
1788 fprintf(asmFile, "; dbName from now on!\n");
1790 pic16_copypCode(asmFile, statsg->dbName);
1792 if(pic16_options.no_crt) {
1793 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1794 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1798 if(pic16_debug_verbose)
1799 fprintf(asmFile, "; X code from now on!\n");
1801 pic16_copypCode(asmFile, 'X');
1803 if(pic16_debug_verbose)
1804 fprintf(asmFile, "; M code from now on!\n");
1806 pic16_copypCode(asmFile, 'M');
1808 pic16_copypCode(asmFile, code->dbName);
1810 pic16_copypCode(asmFile, 'P');
1812 emitStatistics(asmFile);
1814 fprintf (asmFile,"\tend\n");