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 copyFile (FILE * dest, FILE * src);
74 extern void pic16_InlinepCode(void);
75 extern void pic16_writeUsedRegs(FILE *);
77 extern void initialComments (FILE * afile);
78 extern void printPublics (FILE * afile);
80 void pic16_pCodeInitRegisters(void);
81 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
82 extern void pic16_pCodeConstString(char *name, char *value);
85 /*-----------------------------------------------------------------*/
86 /* aopLiteral - string from a literal value */
87 /*-----------------------------------------------------------------*/
88 int pic16aopLiteral (value *val, int offset)
95 /* if it is a float then it gets tricky */
96 /* otherwise it is fairly simple */
97 if (!IS_FLOAT(val->type)) {
98 unsigned long v = (unsigned long) floatFromVal(val);
100 return ( (v >> (offset * 8)) & 0xff);
103 /* it is type float */
104 fl.f = (float) floatFromVal(val);
105 #ifdef WORDS_BIGENDIAN
106 return fl.c[3-offset];
115 char tbuffer[512], *tbuf=tbuffer;;
118 /*-----------------------------------------------------------------*/
119 /* emitRegularMap - emit code for maps with no special cases */
120 /*-----------------------------------------------------------------*/
122 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
125 // int i, size, bitvars = 0;;
127 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
130 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
131 /* print the area name */
133 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
136 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
138 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
139 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
140 printTypeChain( sym->type, stderr );
141 fprintf(stderr, "\n");
144 /* if extern then add to externs */
145 if (IS_EXTERN (sym->etype)) {
146 /* reduce overhead while linking by not declaring
147 * extern unused external functions (usually declared
148 * in header files) */
149 if(IS_FUNC(sym->type) && !sym->used)continue;
151 /* make sure symbol is not in publics section */
152 if(!checkSym(publics, sym))
153 checkAddSym(&externs, sym);
157 /* if allocation required check is needed
158 * then check if the symbol really requires
159 * allocation only for local variables */
160 if (arFlag && !IS_AGGREGATE (sym->type) &&
161 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
162 !sym->allocreq && sym->level) {
164 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
169 /* if global variable & not static or extern
170 * and addPublics allowed then add it to the public set */
171 if ((sym->used) && (sym->level == 0 ||
172 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
174 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
176 checkAddSym(&publics, sym);
179 if(IS_STATIC(sym->etype)
180 && !sym->ival) /* && !sym->level*/ {
185 // debugf("adding symbol %s\n", sym->name);
186 #define SET_IMPLICIT 1
189 if(IS_STRUCT(sym->type))
193 reg = pic16_allocDirReg( operandFromSymbol( sym ));
196 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
197 if(!strcmp(ssym->name, reg->name))found=1;
201 checkAddReg(&pic16_rel_udata, reg);
204 debugf("Did find %s in pic16_rel_udata already. Check!\n", reg->name);
205 // checkAddSym(&publics, sym);
211 /* if extern then do nothing or is a function
213 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
214 if(SPEC_OCLS(sym->etype) == code) {
215 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
216 checkAddSym(&publics, sym);
221 /* if is has an absolute address then generate
222 an equate for this no need to allocate space */
223 if (SPEC_ABSA (sym->etype)) {
224 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
225 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
227 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
229 SPEC_ADDR (sym->etype));
231 /* emit only if it is global */
232 if(sym->level == 0) {
235 reg = pic16_dirregWithName( sym->name );
238 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
239 // __FUNCTION__, __LINE__, sym->name);
241 /* if IS_STRUCT is omitted the following
242 * fixes structures but break char/int etc */
244 if(IS_STRUCT(sym->type))
245 sym->implicit = 1; // mark as implicit
248 reg = pic16_allocDirReg( operandFromSymbol(sym) );
250 if(checkAddReg(&pic16_fix_udata, reg)) {
251 /* and add to globals list if not exist */
252 addSet(&publics, sym);
256 addSet(&publics, sym);
260 if(!sym->used && (sym->level == 0)) {
263 /* symbol not used, just declared probably, but its in
264 * level 0, so we must declare it fine as global */
266 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
269 if(IS_STRUCT(sym->type))
270 sym->implicit = 1; // mark as implicit
273 if(IS_AGGREGATE(sym->type)) {
274 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
276 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
284 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
285 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
289 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
290 if(!strcmp(ssym->name, reg->name))found=1;
294 if(checkAddReg(&pic16_rel_udata, reg)) {
295 addSetHead(&publics, sym);
304 addSetHead(&publics, sym);
309 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
310 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
311 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
312 if (IS_BITVAR (sym->etype)) {
315 fprintf (map->oFile, "\t%s\n", sym->rname);
316 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
317 for (i = 1; i < size; i++)
318 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
321 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
325 /* FIXME -- VR Fix the following, so that syms to be placed
326 * in the idata section and let linker decide about their fate */
328 /* if it has an initial value then do it only if
329 it is a global variable */
332 && ((sym->level == 0)
333 || IS_STATIC(sym->etype)) ) {
337 if(SPEC_OCLS(sym->etype)==data) {
338 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
341 if(SPEC_OCLS(sym->etype)==code) {
342 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
347 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
348 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
351 if (IS_AGGREGATE (sym->type)) {
352 if(SPEC_ABSA(sym->etype))
353 addSet(&fix_idataSymSet, copySymbol(sym));
355 addSet(&rel_idataSymSet, copySymbol(sym));
356 // ival = initAggregates (sym, sym->ival, NULL);
358 if(SPEC_ABSA(sym->etype))
359 addSet(&fix_idataSymSet, copySymbol(sym));
361 addSet(&rel_idataSymSet, copySymbol(sym));
363 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
364 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
368 setAstLineno(ival, sym->lineDef);
369 codeOutFile = statsg->oFile;
371 eBBlockFromiCode (iCodeFromAst (ival));
379 /*-----------------------------------------------------------------*/
380 /* pic16_initPointer - pointer initialization code massaging */
381 /*-----------------------------------------------------------------*/
382 value *pic16_initPointer (initList * ilist, sym_link *toType)
388 return valCastLiteral(toType, 0.0);
391 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
392 // expr = list2expr( ilist );
397 /* try it the old way first */
398 if ((val = constExprValue (expr, FALSE)))
401 /* ( ptr + constant ) */
402 if (IS_AST_OP (expr) &&
403 (expr->opval.op == '+' || expr->opval.op == '-') &&
404 IS_AST_SYM_VALUE (expr->left) &&
405 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
406 compareType(toType, expr->left->ftype) &&
407 IS_AST_LIT_VALUE (expr->right)) {
408 return valForCastAggr (expr->left, expr->left->ftype,
414 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
415 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
416 if (compareType(toType, expr->left->ftype)!=1) {
417 werror (W_INIT_WRONG);
418 printFromToType(expr->left->ftype, toType);
424 /* no then we have to do these cludgy checks */
425 /* pointers can be initialized with address of
426 a variable or address of an array element */
427 if (IS_AST_OP (expr) && expr->opval.op == '&') {
428 /* address of symbol */
429 if (IS_AST_SYM_VALUE (expr->left)) {
430 val = copyValue (AST_VALUE (expr->left));
431 val->type = newLink (DECLARATOR);
432 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
433 DCL_TYPE (val->type) = CPOINTER;
434 DCL_PTR_CONST (val->type) = port->mem.code_ro;
436 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
437 DCL_TYPE (val->type) = FPOINTER;
438 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
439 DCL_TYPE (val->type) = PPOINTER;
440 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
441 DCL_TYPE (val->type) = IPOINTER;
442 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
443 DCL_TYPE (val->type) = EEPPOINTER;
445 DCL_TYPE (val->type) = POINTER;
447 val->type->next = expr->left->ftype;
448 val->etype = getSpec (val->type);
452 /* if address of indexed array */
453 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
454 return valForArray (expr->left);
456 /* if address of structure element then
458 if (IS_AST_OP (expr->left) &&
459 expr->left->opval.op == '.') {
460 return valForStructElem (expr->left->left,
465 (&some_struct)->element */
466 if (IS_AST_OP (expr->left) &&
467 expr->left->opval.op == PTR_OP &&
468 IS_ADDRESS_OF_OP (expr->left->left)) {
469 return valForStructElem (expr->left->left->left,
473 /* case 3. (((char *) &a) +/- constant) */
474 if (IS_AST_OP (expr) &&
475 (expr->opval.op == '+' || expr->opval.op == '-') &&
476 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
477 IS_AST_OP (expr->left->right) &&
478 expr->left->right->opval.op == '&' &&
479 IS_AST_LIT_VALUE (expr->right)) {
481 return valForCastAggr (expr->left->right->left,
482 expr->left->left->opval.lnk,
483 expr->right, expr->opval.op);
486 /* case 4. (char *)(array type) */
487 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
488 IS_ARRAY(expr->right->ftype)) {
490 val = copyValue (AST_VALUE (expr->right));
491 val->type = newLink (DECLARATOR);
492 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
493 DCL_TYPE (val->type) = CPOINTER;
494 DCL_PTR_CONST (val->type) = port->mem.code_ro;
496 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
497 DCL_TYPE (val->type) = FPOINTER;
498 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
499 DCL_TYPE (val->type) = PPOINTER;
500 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
501 DCL_TYPE (val->type) = IPOINTER;
502 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
503 DCL_TYPE (val->type) = EEPPOINTER;
505 DCL_TYPE (val->type) = POINTER;
506 val->type->next = expr->right->ftype->next;
507 val->etype = getSpec (val->type);
513 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
515 werror (E_INCOMPAT_PTYPES);
521 /*-----------------------------------------------------------------*/
522 /* printPointerType - generates ival for pointer type */
523 /*-----------------------------------------------------------------*/
524 void _pic16_printPointerType (const char *name, char ptype, void *p)
528 sprintf(buf, "LOW(%s)", name);
529 pic16_emitDS(buf, ptype, p);
530 sprintf(buf, "HIGH(%s)", name);
531 pic16_emitDS(buf, ptype, p);
534 /*-----------------------------------------------------------------*/
535 /* printPointerType - generates ival for pointer type */
536 /*-----------------------------------------------------------------*/
537 void pic16_printPointerType (const char *name, char ptype, void *p)
539 _pic16_printPointerType (name, ptype, p);
540 pic16_flushDB(ptype, p);
543 /*-----------------------------------------------------------------*/
544 /* printGPointerType - generates ival for generic pointer type */
545 /*-----------------------------------------------------------------*/
546 void pic16_printGPointerType (const char *iname, const unsigned int itype,
551 _pic16_printPointerType (iname, ptype, p);
558 sprintf(buf, "UPPER(%s)", iname);
559 pic16_emitDS(buf, ptype, p);
563 sprintf(buf, "0x80");
564 pic16_emitDS(buf, ptype, p);
567 debugf("itype = %d\n", itype );
571 pic16_flushDB(ptype, p);
575 /* set to 0 to disable debug messages */
576 #define DEBUG_PRINTIVAL 0
578 /*-----------------------------------------------------------------*/
579 /* pic16_printIvalType - generates ival for int/char */
580 /*-----------------------------------------------------------------*/
582 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
586 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
589 fprintf(stderr, "%s\n",__FUNCTION__);
593 /* if initList is deep */
594 if (ilist && ilist->type == INIT_DEEP)
595 ilist = ilist->init.deep;
597 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
598 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
601 if (!(val = list2val (ilist))) {
602 // assuming a warning has been thrown
606 if (val->type != type) {
607 val = valCastLiteral(type, floatFromVal(val));
610 switch (getSize (type)) {
612 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
616 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
617 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
620 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
621 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
622 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
624 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
625 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
626 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
627 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
632 /*--------------------------------------------------------------------*/
633 /* pic16_printIvalChar - generates initital value for character array */
634 /*--------------------------------------------------------------------*/
636 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
645 fprintf(stderr, "%s\n",__FUNCTION__);
649 val = list2val (ilist);
650 /* if the value is a character string */
651 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
653 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
655 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
656 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
658 if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
660 pic16_emitDB(0x00, ptype, p);
666 for(remain=0; remain<strlen(s); remain++) {
667 pic16_emitDB(s[remain], ptype, p);
673 /*-----------------------------------------------------------------*/
674 /* pic16_printIvalArray - generates code for array initialization */
675 /*-----------------------------------------------------------------*/
677 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
681 int lcnt = 0, size = 0;
688 fprintf(stderr, "%s\n",__FUNCTION__);
690 /* take care of the special case */
691 /* array of characters can be init */
693 if (IS_CHAR (type->next)) {
694 if (!IS_LITERAL(list2val(ilist)->etype)) {
695 werror (W_INIT_WRONG);
699 if(pic16_printIvalChar (type,
700 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
701 SPEC_CVAL (sym->etype).v_char, ptype, p))
704 /* not the special case */
705 if (ilist && ilist->type != INIT_DEEP)
707 werror (E_INIT_STRUCT, sym->name);
711 iloop = ilist->init.deep;
712 lcnt = DCL_ELEM (type);
717 pic16_printIval (sym, type->next, iloop, ptype, p);
718 iloop = (iloop ? iloop->next : NULL);
721 /* if not array limits given & we */
722 /* are out of initialisers then */
723 if (!DCL_ELEM (type) && !iloop)
726 /* no of elements given and we */
727 /* have generated for all of them */
729 /* if initializers left */
731 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
737 /* if we have not been given a size */
738 if (!DCL_ELEM (type))
739 DCL_ELEM (type) = size;
744 /*-----------------------------------------------------------------*/
745 /* pic16_printIvalBitFields - generate initializer for bitfields */
746 /*-----------------------------------------------------------------*/
747 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
751 initList *lilist = *ilist ;
752 unsigned long ival = 0;
757 fprintf(stderr, "%s\n",__FUNCTION__);
763 val = list2val(lilist);
765 if (SPEC_BLEN(lsym->etype) > 8) {
766 size += ((SPEC_BLEN (lsym->etype) / 8) +
767 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
770 size = ((SPEC_BLEN (lsym->etype) / 8) +
771 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
773 i = (unsigned long)floatFromVal(val);
774 i <<= SPEC_BSTR (lsym->etype);
776 if (! ( lsym->next &&
777 (IS_BITFIELD(lsym->next->type)) &&
778 (SPEC_BSTR(lsym->next->etype)))) break;
780 lilist = lilist->next;
784 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
788 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
789 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
792 case 4: /* EEP: why is this db and not dw? */
793 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
794 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
795 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
796 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
799 /* VR - only 1,2,4 size long can be handled???? Why? */
800 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
808 /*-----------------------------------------------------------------*/
809 /* printIvalStruct - generates initial value for structures */
810 /*-----------------------------------------------------------------*/
811 void pic16_printIvalStruct (symbol * sym, sym_link * type,
812 initList * ilist, char ptype, void *p)
815 initList *iloop = NULL;
819 fprintf(stderr, "%s\n",__FUNCTION__);
822 sflds = SPEC_STRUCT (type)->fields;
825 if (ilist->type != INIT_DEEP) {
826 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
830 iloop = ilist->init.deep;
833 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
834 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
835 if (IS_BITFIELD(sflds->type)) {
836 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
838 pic16_printIval (sym, sflds->type, iloop, ptype, p);
842 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
847 /*--------------------------------------------------------------------------*/
848 /* pic16_printIvalCharPtr - generates initial values for character pointers */
849 /*--------------------------------------------------------------------------*/
850 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
854 /* PENDING: this is _very_ mcs51 specific, including a magic
856 It's also endin specific.
858 VR - Attempting to port this function to pic16 port - 8-Jun-2004
863 fprintf(stderr, "%s\n",__FUNCTION__);
866 size = getSize (type);
868 if (val->name && strlen (val->name))
870 if (size == 1) /* This appears to be Z80 specific?? */
872 pic16_emitDS(val->name, ptype, p);
876 pic16_printPointerType (val->name, ptype, p);
881 if (IS_PTR (val->type)) {
882 type = DCL_TYPE (val->type);
884 type = PTR_TYPE (SPEC_OCLS (val->etype));
886 if (val->sym && val->sym->isstrlit) {
887 // this is a literal string
890 pic16_printGPointerType(val->name, type, ptype, p);
894 fprintf (stderr, "*** internal error: unknown size in "
895 "printIvalCharPtr.\n");
901 // these are literals assigned to pointers
905 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
908 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
909 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
912 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
913 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
914 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
922 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
923 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
924 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
930 /*-----------------------------------------------------------------------*/
931 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
932 /*-----------------------------------------------------------------------*/
933 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
940 fprintf(stderr, "%s\n",__FUNCTION__);
944 val = list2val (ilist);
946 val = valCastLiteral(type, 0.0);
949 // an error has been thrown already
953 if (IS_LITERAL(val->etype)) {
954 if (compareType(type, val->etype) == 0) {
955 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
956 printFromToType (val->type, type);
958 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
962 /* check the types */
963 if ((dLvl = compareType (val->type, type->next)) <= 0)
965 pic16_emitDB(0x00, ptype, p);
969 /* now generate the name */
971 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
973 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
975 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
977 if(!checkSym(publics, val->sym))
978 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
979 /* this has not been declared as extern
980 * so declare it as a 'late extern' just after the symbol */
981 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
982 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
983 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
992 /*-----------------------------------------------------------------*/
993 /* pic16_printIvalPtr - generates initial value for pointers */
994 /*-----------------------------------------------------------------*/
995 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1001 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1002 sym->rname, getSize(sym->type));
1006 if (ilist && (ilist->type == INIT_DEEP))
1007 ilist = ilist->init.deep;
1009 /* function pointer */
1010 if (IS_FUNC (type->next))
1012 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1016 if (!(val = pic16_initPointer (ilist, type)))
1019 /* if character pointer */
1020 if (IS_CHAR (type->next))
1021 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1024 /* check the type */
1025 if (compareType (type, val->type) == 0) {
1026 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1027 printFromToType (val->type, type);
1030 /* if val is literal */
1031 if (IS_LITERAL (val->etype))
1033 switch (getSize (type))
1036 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1039 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1040 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1043 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1044 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1045 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1048 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1055 size = getSize (type);
1057 if (size == 1) /* Z80 specific?? */
1059 pic16_emitDS(val->name, ptype, p);
1063 pic16_printPointerType (val->name, ptype, p);
1067 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1076 /*-----------------------------------------------------------------*/
1077 /* pic16_printIval - generates code for initial value */
1078 /*-----------------------------------------------------------------*/
1079 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1087 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1088 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1089 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1092 /* if structure then */
1093 if (IS_STRUCT (type))
1095 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1096 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1100 /* if this is an array */
1101 if (IS_ARRAY (type))
1103 // fprintf(stderr,"%s array\n",__FUNCTION__);
1104 pic16_printIvalArray (sym, type, ilist, ptype, p);
1111 // not an aggregate, ilist must be a node
1112 if (ilist->type!=INIT_NODE) {
1113 // or a 1-element list
1114 if (ilist->init.deep->next) {
1115 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1118 ilist=ilist->init.deep;
1123 // and the type must match
1124 itype=ilist->init.node->ftype;
1126 if (compareType(type, itype)==0) {
1127 // special case for literal strings
1128 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1129 // which are really code pointers
1130 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1133 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1134 // printFromToType(itype, type);
1141 /* if this is a pointer */
1144 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1145 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1150 /* if type is SPECIFIER */
1153 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1154 pic16_printIvalType (sym, type, ilist, ptype, p);
1159 int PIC16_IS_CONFIG_ADDRESS(int address)
1161 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1164 int PIC16_IS_IDLOC_ADDRESS(int address)
1166 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1169 /* wrapper function for the above */
1170 int PIC16_IS_HWREG_ADDRESS(int address)
1172 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1176 /*-----------------------------------------------------------------*/
1177 /* emitStaticSeg - emitcode for the static segment */
1178 /*-----------------------------------------------------------------*/
1180 pic16emitStaticSeg (memmap * map)
1183 static int didcode=0;
1185 //fprintf(stderr, "%s\n",__FUNCTION__);
1189 /* for all variables in this segment do */
1190 for (sym = setFirstItem (map->syms); sym;
1191 sym = setNextItem (map->syms))
1195 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1196 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1197 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1198 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1199 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1200 printTypeChain( sym->type, stderr );
1201 fprintf(stderr, "\n");
1204 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1205 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1206 (int) floatFromVal(list2val(sym->ival)));
1211 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1212 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1213 (char) floatFromVal(list2val(sym->ival)));
1218 /* if it is "extern" then do nothing */
1219 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1220 checkAddSym(&externs, sym);
1224 /* if it is not static add it to the public
1226 if (!IS_STATIC (sym->etype)) {
1227 /* do not emit if it is a config word declaration */
1228 checkAddSym(&publics, sym);
1231 /* print extra debug info if required */
1232 if (options.debug || sym->level == 0) {
1233 /* NOTE to me - cdbFile may be null in which case,
1234 * the sym name will be printed to stdout. oh well */
1235 debugFile->writeSymbol(sym);
1238 /* if it has an absolute address */
1239 if (SPEC_ABSA (sym->etype)) {
1240 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1241 // __FILE__, __LINE__, sym->name);
1243 /* if it has an initial value */
1251 /* symbol has absolute address and initial value */
1253 resolveIvalSym (sym->ival, sym->type);
1254 asym = newSymbol(sym->rname, 0);
1255 abSym = Safe_calloc(1, sizeof(absSym));
1256 strcpy(abSym->name, sym->rname);
1257 abSym->address = SPEC_ADDR( sym->etype );
1258 addSet(&absSymSet, abSym);
1260 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1261 pic16_addpBlock(pb);
1263 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1264 PCF(pcf)->absblock = 1;
1266 pic16_addpCode2pBlock(pb,pcf);
1267 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1268 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1269 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1270 pic16_flushDB('p', (void *)pb);
1272 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1278 /* symbol has absolute address but no initial value */
1280 /* allocate space */
1281 fprintf (code->oFile, "%s:\n", sym->rname);
1283 /* special case for character strings */
1284 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1285 SPEC_CVAL (sym->etype).v_char) {
1287 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1289 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1296 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1297 // __FILE__, __LINE__, sym->name);
1300 /* if it has an initial value */
1304 /* symbol doesn't have absolute address but has initial value */
1305 fprintf (code->oFile, "%s:\n", sym->rname);
1307 resolveIvalSym (sym->ival, sym->type);
1309 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1310 pic16_addpBlock(pb);
1313 /* make sure that 'code' directive is emitted before, once */
1314 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1319 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1321 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1322 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1323 pic16_flushDB('p', (void *)pb);
1327 /* symbol doesn't have absolute address and no initial value */
1328 /* allocate space */
1329 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1330 fprintf (code->oFile, "%s:\n", sym->rname);
1331 /* special case for character strings */
1332 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1333 SPEC_CVAL (sym->etype).v_char) {
1335 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1337 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1348 /*-----------------------------------------------------------------*/
1349 /* pic16_emitConfigRegs - emits the configuration registers */
1350 /*-----------------------------------------------------------------*/
1351 void pic16_emitConfigRegs(FILE *of)
1355 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1356 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1357 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1358 pic16->cwInfo.confAddrStart+i,
1359 pic16->cwInfo.crInfo[i].value);
1362 void pic16_emitIDRegs(FILE *of)
1366 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1367 if(pic16->idInfo.irInfo[i].emit)
1368 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1369 pic16->idInfo.idAddrStart+i,
1370 pic16->idInfo.irInfo[i].value);
1377 /* no special considerations for the following
1378 data, idata & bit & xdata */
1379 pic16emitRegularMap (data, TRUE, TRUE);
1380 pic16emitRegularMap (idata, TRUE, TRUE);
1381 pic16emitRegularMap (bit, TRUE, FALSE);
1382 pic16emitRegularMap (xdata, TRUE, TRUE);
1383 pic16emitRegularMap (sfr, FALSE, FALSE);
1384 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1385 pic16emitRegularMap (code, TRUE, FALSE);
1386 pic16emitStaticSeg (statsg);
1389 /*-----------------------------------------------------------------*/
1390 /* createInterruptVect - creates the interrupt vector */
1391 /*-----------------------------------------------------------------*/
1393 pic16createInterruptVect (FILE * vFile)
1395 /* if the main is only a prototype ie. no body then do nothing */
1397 if (!IFFUNC_HASBODY(mainf->type)) {
1398 /* if ! compile only then main function should be present */
1399 if (!options.cc_only)
1405 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1406 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1407 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1409 /* this is an overkill since WE are the port,
1410 * and we know if we have a genIVT function! */
1412 port->genIVT(vFile, interrupts, maxInterrupts);
1419 /*-----------------------------------------------------------------*/
1420 /* pic16initialComments - puts in some initial comments */
1421 /*-----------------------------------------------------------------*/
1423 pic16initialComments (FILE * afile)
1425 initialComments (afile);
1426 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1427 if(pic16_mplab_comp)
1428 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1429 fprintf (afile, iComments2);
1432 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1433 SDCC_VERSION_STR, getBuildNumber() );
1437 /*-----------------------------------------------------------------*/
1438 /* printPublics - generates global declarations for publics */
1439 /*-----------------------------------------------------------------*/
1441 pic16printPublics (FILE *afile)
1445 fprintf (afile, "\n%s", iComments2);
1446 fprintf (afile, "; public variables in this module\n");
1447 fprintf (afile, "%s", iComments2);
1449 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1451 if(!IS_STATIC(sym->etype))
1452 fprintf(afile, "\tglobal %s\n", sym->rname);
1455 /*-----------------------------------------------------------------*/
1456 /* printExterns - generates extern declarations for externs */
1457 /*-----------------------------------------------------------------*/
1459 pic16_printExterns(FILE *afile)
1463 /* print nothing if no externs to declare */
1464 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1467 fprintf(afile, "\n%s", iComments2);
1468 fprintf(afile, "; extern variables in this module\n");
1469 fprintf(afile, "%s", iComments2);
1471 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1472 fprintf(afile, "\textern %s\n", sym->rname);
1474 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1475 fprintf(afile, "\textern _%s\n", sym->name);
1478 /*-----------------------------------------------------------------*/
1479 /* emitOverlay - will emit code for the overlay stuff */
1480 /*-----------------------------------------------------------------*/
1482 pic16emitOverlay (FILE * afile)
1486 if (!elementsInSet (ovrSetSets))
1487 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1489 /* for each of the sets in the overlay segment do */
1490 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1491 ovrset = setNextItem (ovrSetSets))
1496 if (elementsInSet (ovrset))
1498 /* this dummy area is used to fool the assembler
1499 otherwise the assembler will append each of these
1500 declarations into one chunk and will not overlay
1502 fprintf (afile, ";\t.area _DUMMY\n");
1503 /* output the area informtion */
1504 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1507 for (sym = setFirstItem (ovrset); sym;
1508 sym = setNextItem (ovrset))
1511 /* if extern then do nothing */
1512 if (IS_EXTERN (sym->etype))
1515 /* if allocation required check is needed
1516 then check if the symbol really requires
1517 allocation only for local variables */
1518 if (!IS_AGGREGATE (sym->type) &&
1519 !(sym->_isparm && !IS_REGPARM (sym->etype))
1520 && !sym->allocreq && sym->level)
1523 /* if global variable & not static or extern
1524 and addPublics allowed then add it to the public set */
1525 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1526 && !IS_STATIC (sym->etype)) {
1527 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1528 checkAddSym(&publics, sym);
1529 // addSetHead (&publics, sym);
1532 /* if extern then do nothing or is a function
1534 if (IS_FUNC (sym->type))
1538 /* if is has an absolute address then generate
1539 an equate for this no need to allocate space */
1540 if (SPEC_ABSA (sym->etype))
1543 if (options.debug || sym->level == 0)
1544 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1546 fprintf (afile, "%s\t=\t0x%04x\n",
1548 SPEC_ADDR (sym->etype));
1552 if (options.debug || sym->level == 0)
1553 fprintf (afile, "==.\n");
1555 /* allocate space */
1556 fprintf (afile, "%s:\n", sym->rname);
1557 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1564 void emitStatistics(FILE *asmFile)
1566 statistics.isize = pic16_countInstructions();
1568 fprintf (asmFile, "\n\n; Statistics:\n");
1569 fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
1570 statistics.isize, statistics.isize,
1571 statistics.isize>>1, statistics.isize>>1);
1572 fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n",
1573 statistics.udsize, statistics.udsize);
1574 fprintf (asmFile, "; access size:\t%ld (0x%lx) bytes\n",
1575 statistics.intsize, statistics.intsize);
1577 fprintf (asmFile, "\n\n");
1582 /*-----------------------------------------------------------------*/
1583 /* glue - the final glue that hold the whole thing together */
1584 /*-----------------------------------------------------------------*/
1590 FILE *ovrFile = tempfile();
1592 mainf = newSymbol ("main", 0);
1595 mainf = findSymWithLevel(SymbolTab, mainf);
1597 addSetHead(&tmpfileSet,ovrFile);
1598 pic16_pCodeInitRegisters();
1600 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1601 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1603 pic16_addpBlock(pb);
1605 /* entry point @ start of CSEG */
1606 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1609 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1610 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1611 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1612 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1615 /* put in the call to main */
1616 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1618 if (options.mainreturn) {
1619 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1620 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1622 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1623 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1627 /* At this point we've got all the code in the form of pCode structures */
1628 /* Now it needs to be rearranged into the order it should be placed in the */
1631 pic16_movepBlock2Head('P'); // Last
1632 pic16_movepBlock2Head(code->dbName);
1633 pic16_movepBlock2Head('X');
1634 pic16_movepBlock2Head(statsg->dbName); // First
1636 /* print the global struct definitions */
1639 /* PENDING: this isnt the best place but it will do */
1640 if (port->general.glue_up_main) {
1641 /* create the interrupt vector table */
1642 pic16createInterruptVect (vFile);
1645 addSetHead(&tmpfileSet,vFile);
1647 /* emit code for the all the variables declared */
1650 /* do the overlay segments */
1651 pic16emitOverlay(ovrFile);
1652 pic16_AnalyzepCode('*');
1655 if(pic16_options.dumpcalltree) {
1658 sprintf(buffer, dstFileName);
1659 strcat(buffer, ".calltree");
1660 cFile = fopen(buffer, "w");
1661 pic16_printCallTree( cFile );
1666 pic16_InlinepCode();
1667 pic16_AnalyzepCode('*');
1670 if(pic16_debug_verbose)
1673 /* now put it all together into the assembler file */
1674 /* create the assembler file name */
1675 if((noAssemble || options.c1mode) && fullDstFileName) {
1676 sprintf (buffer, fullDstFileName);
1678 sprintf (buffer, dstFileName);
1679 strcat (buffer, ".asm");
1682 if(!(asmFile = fopen (buffer, "w"))) {
1683 werror (E_FILE_OPEN_ERR, buffer);
1687 /* initial comments */
1688 pic16initialComments (asmFile);
1690 /* print module name */
1692 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1694 /* Let the port generate any global directives, etc. */
1695 if(port->genAssemblerPreamble) {
1696 port->genAssemblerPreamble(asmFile);
1699 /* Put all variables into a cblock */
1700 pic16_AnalyzeBanking();
1702 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1703 pic16_OptimizeLocalRegs();
1706 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1707 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1708 pic16_OptimizeJumps();
1711 /* print the extern variables to this module */
1712 pic16_printExterns(asmFile);
1714 /* print the global variables in this module */
1715 pic16printPublics (asmFile);
1717 pic16_writeUsedRegs(asmFile);
1720 /* no xdata in pic */
1721 /* if external stack then reserve space of it */
1722 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1723 fprintf (asmFile, "%s", iComments2);
1724 fprintf (asmFile, "; external stack \n");
1725 fprintf (asmFile, "%s", iComments2);
1726 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1727 fprintf (asmFile,";\t.ds 256\n");
1732 /* no xdata in pic */
1733 /* copy xtern ram data */
1734 fprintf (asmFile, "%s", iComments2);
1735 fprintf (asmFile, "; external ram data\n");
1736 fprintf (asmFile, "%s", iComments2);
1737 copyFile (asmFile, xdata->oFile);
1741 /* copy the bit segment */
1742 fprintf (asmFile, "%s", iComments2);
1743 fprintf (asmFile, "; bit data\n");
1744 fprintf (asmFile, "%s", iComments2);
1745 copyFile (asmFile, bit->oFile);
1748 /* copy the interrupt vector table */
1749 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1750 fprintf (asmFile, "\n%s", iComments2);
1751 fprintf (asmFile, "; interrupt vector \n");
1752 fprintf (asmFile, "%s", iComments2);
1753 copyFile (asmFile, vFile);
1756 /* copy global & static initialisations */
1757 fprintf (asmFile, "\n%s", iComments2);
1758 fprintf (asmFile, "; global & static initialisations\n");
1759 fprintf (asmFile, "%s", iComments2);
1761 if(pic16_debug_verbose)
1762 fprintf(asmFile, "; A code from now on!\n");
1764 pic16_copypCode(asmFile, 'A');
1766 if(pic16_options.no_crt) {
1767 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1768 fprintf(asmFile, "\tcode\n");
1769 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1773 // copyFile (stderr, code->oFile);
1775 fprintf(asmFile, "; I code from now on!\n");
1776 pic16_copypCode(asmFile, 'I');
1778 if(pic16_debug_verbose)
1779 fprintf(asmFile, "; dbName from now on!\n");
1781 pic16_copypCode(asmFile, statsg->dbName);
1783 if(pic16_options.no_crt) {
1784 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1785 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1789 if(pic16_debug_verbose)
1790 fprintf(asmFile, "; X code from now on!\n");
1792 pic16_copypCode(asmFile, 'X');
1794 if(pic16_debug_verbose)
1795 fprintf(asmFile, "; M code from now on!\n");
1797 pic16_copypCode(asmFile, 'M');
1799 pic16_copypCode(asmFile, code->dbName);
1801 pic16_copypCode(asmFile, 'P');
1803 emitStatistics(asmFile);
1805 fprintf (asmFile,"\tend\n");