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);
180 if(IS_STATIC(sym->etype)
181 && !sym->ival) /* && !sym->level*/ {
184 if(IS_STATIC(sym->etype)
185 && !(sym->ival && !sym->level)) {
191 // debugf("adding symbol %s\n", sym->name);
192 #define SET_IMPLICIT 1
195 if(IS_STRUCT(sym->type))
199 reg = pic16_allocDirReg( operandFromSymbol( sym ));
202 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
203 if(!strcmp(ssym->name, reg->name))found=1;
207 checkAddReg(&pic16_rel_udata, reg);
209 debugf("Coudld not find %s in pic16_rel_udata. Check!\n", reg->name);
210 // checkAddSym(&publics, sym);
215 /* if extern then do nothing or is a function
217 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
218 if(SPEC_OCLS(sym->etype) == code) {
219 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
220 checkAddSym(&publics, sym);
225 /* if is has an absolute address then generate
226 an equate for this no need to allocate space */
227 if (SPEC_ABSA (sym->etype)) {
228 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
229 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
231 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
233 SPEC_ADDR (sym->etype));
235 /* emit only if it is global */
236 if(sym->level == 0) {
239 reg = pic16_dirregWithName( sym->name );
242 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
243 // __FUNCTION__, __LINE__, sym->name);
245 /* if IS_STRUCT is omitted the following
246 * fixes structures but break char/int etc */
248 if(IS_STRUCT(sym->type))
249 sym->implicit = 1; // mark as implicit
252 reg = pic16_allocDirReg( operandFromSymbol(sym) );
254 if(checkAddReg(&pic16_fix_udata, reg)) {
255 /* and add to globals list if not exist */
256 addSet(&publics, sym);
260 addSet(&publics, sym);
264 if(!sym->used && (sym->level == 0)) {
267 /* symbol not used, just declared probably, but its in
268 * level 0, so we must declare it fine as global */
270 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
273 if(IS_STRUCT(sym->type))
274 sym->implicit = 1; // mark as implicit
277 if(IS_AGGREGATE(sym->type)) {
278 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
280 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
288 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
289 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
293 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
294 if(!strcmp(ssym->name, reg->name))found=1;
298 if(checkAddReg(&pic16_rel_udata, reg)) {
299 addSetHead(&publics, sym);
308 addSetHead(&publics, sym);
313 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
314 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
315 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
316 if (IS_BITVAR (sym->etype)) {
319 fprintf (map->oFile, "\t%s\n", sym->rname);
320 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
321 for (i = 1; i < size; i++)
322 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
325 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
329 /* FIXME -- VR Fix the following, so that syms to be placed
330 * in the idata section and let linker decide about their fate */
332 /* if it has an initial value then do it only if
333 it is a global variable */
336 && ((sym->level == 0)
337 || IS_STATIC(sym->etype)) ) {
341 if(SPEC_OCLS(sym->etype)==data) {
342 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
345 if(SPEC_OCLS(sym->etype)==code) {
346 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
351 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
352 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
355 if (IS_AGGREGATE (sym->type)) {
356 if(SPEC_ABSA(sym->etype))
357 addSet(&fix_idataSymSet, copySymbol(sym));
359 addSet(&rel_idataSymSet, copySymbol(sym));
360 // ival = initAggregates (sym, sym->ival, NULL);
362 if(SPEC_ABSA(sym->etype))
363 addSet(&fix_idataSymSet, copySymbol(sym));
365 addSet(&rel_idataSymSet, copySymbol(sym));
367 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
368 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
372 setAstLineno(ival, sym->lineDef);
373 codeOutFile = statsg->oFile;
375 eBBlockFromiCode (iCodeFromAst (ival));
383 /*-----------------------------------------------------------------*/
384 /* pic16_initPointer - pointer initialization code massaging */
385 /*-----------------------------------------------------------------*/
386 value *pic16_initPointer (initList * ilist, sym_link *toType)
392 return valCastLiteral(toType, 0.0);
395 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
396 // expr = list2expr( ilist );
401 /* try it the old way first */
402 if ((val = constExprValue (expr, FALSE)))
405 /* ( ptr + constant ) */
406 if (IS_AST_OP (expr) &&
407 (expr->opval.op == '+' || expr->opval.op == '-') &&
408 IS_AST_SYM_VALUE (expr->left) &&
409 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
410 compareType(toType, expr->left->ftype) &&
411 IS_AST_LIT_VALUE (expr->right)) {
412 return valForCastAggr (expr->left, expr->left->ftype,
418 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
419 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
420 if (compareType(toType, expr->left->ftype)!=1) {
421 werror (W_INIT_WRONG);
422 printFromToType(expr->left->ftype, toType);
428 /* no then we have to do these cludgy checks */
429 /* pointers can be initialized with address of
430 a variable or address of an array element */
431 if (IS_AST_OP (expr) && expr->opval.op == '&') {
432 /* address of symbol */
433 if (IS_AST_SYM_VALUE (expr->left)) {
434 val = copyValue (AST_VALUE (expr->left));
435 val->type = newLink (DECLARATOR);
436 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
437 DCL_TYPE (val->type) = CPOINTER;
438 DCL_PTR_CONST (val->type) = port->mem.code_ro;
440 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
441 DCL_TYPE (val->type) = FPOINTER;
442 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
443 DCL_TYPE (val->type) = PPOINTER;
444 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
445 DCL_TYPE (val->type) = IPOINTER;
446 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
447 DCL_TYPE (val->type) = EEPPOINTER;
449 DCL_TYPE (val->type) = POINTER;
451 val->type->next = expr->left->ftype;
452 val->etype = getSpec (val->type);
456 /* if address of indexed array */
457 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
458 return valForArray (expr->left);
460 /* if address of structure element then
462 if (IS_AST_OP (expr->left) &&
463 expr->left->opval.op == '.') {
464 return valForStructElem (expr->left->left,
469 (&some_struct)->element */
470 if (IS_AST_OP (expr->left) &&
471 expr->left->opval.op == PTR_OP &&
472 IS_ADDRESS_OF_OP (expr->left->left)) {
473 return valForStructElem (expr->left->left->left,
477 /* case 3. (((char *) &a) +/- constant) */
478 if (IS_AST_OP (expr) &&
479 (expr->opval.op == '+' || expr->opval.op == '-') &&
480 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
481 IS_AST_OP (expr->left->right) &&
482 expr->left->right->opval.op == '&' &&
483 IS_AST_LIT_VALUE (expr->right)) {
485 return valForCastAggr (expr->left->right->left,
486 expr->left->left->opval.lnk,
487 expr->right, expr->opval.op);
490 /* case 4. (char *)(array type) */
491 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
492 IS_ARRAY(expr->right->ftype)) {
494 val = copyValue (AST_VALUE (expr->right));
495 val->type = newLink (DECLARATOR);
496 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
497 DCL_TYPE (val->type) = CPOINTER;
498 DCL_PTR_CONST (val->type) = port->mem.code_ro;
500 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
501 DCL_TYPE (val->type) = FPOINTER;
502 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
503 DCL_TYPE (val->type) = PPOINTER;
504 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
505 DCL_TYPE (val->type) = IPOINTER;
506 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
507 DCL_TYPE (val->type) = EEPPOINTER;
509 DCL_TYPE (val->type) = POINTER;
510 val->type->next = expr->right->ftype->next;
511 val->etype = getSpec (val->type);
517 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
519 werror (E_INCOMPAT_PTYPES);
525 /*-----------------------------------------------------------------*/
526 /* printPointerType - generates ival for pointer type */
527 /*-----------------------------------------------------------------*/
528 void _pic16_printPointerType (const char *name, char ptype, void *p)
532 sprintf(buf, "LOW(%s)", name);
533 pic16_emitDS(buf, ptype, p);
534 sprintf(buf, "HIGH(%s)", name);
535 pic16_emitDS(buf, ptype, p);
538 /*-----------------------------------------------------------------*/
539 /* printPointerType - generates ival for pointer type */
540 /*-----------------------------------------------------------------*/
541 void pic16_printPointerType (const char *name, char ptype, void *p)
543 _pic16_printPointerType (name, ptype, p);
544 pic16_flushDB(ptype, p);
547 /*-----------------------------------------------------------------*/
548 /* printGPointerType - generates ival for generic pointer type */
549 /*-----------------------------------------------------------------*/
550 void pic16_printGPointerType (const char *iname, const unsigned int itype,
555 _pic16_printPointerType (iname, ptype, p);
562 sprintf(buf, "UPPER(%s)", iname);
563 pic16_emitDS(buf, ptype, p);
567 sprintf(buf, "0x80");
568 pic16_emitDS(buf, ptype, p);
571 debugf("itype = %d\n", itype );
575 pic16_flushDB(ptype, p);
579 /* set to 0 to disable debug messages */
580 #define DEBUG_PRINTIVAL 0
582 /*-----------------------------------------------------------------*/
583 /* pic16_printIvalType - generates ival for int/char */
584 /*-----------------------------------------------------------------*/
586 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
590 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
593 fprintf(stderr, "%s\n",__FUNCTION__);
597 /* if initList is deep */
598 if (ilist && ilist->type == INIT_DEEP)
599 ilist = ilist->init.deep;
601 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
602 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
605 if (!(val = list2val (ilist))) {
606 // assuming a warning has been thrown
610 if (val->type != type) {
611 val = valCastLiteral(type, floatFromVal(val));
614 switch (getSize (type)) {
616 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
620 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
621 pic16_emitDB(pic16aopLiteral(val, 1), 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);
628 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
629 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
630 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
631 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
636 /*--------------------------------------------------------------------*/
637 /* pic16_printIvalChar - generates initital value for character array */
638 /*--------------------------------------------------------------------*/
640 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
649 fprintf(stderr, "%s\n",__FUNCTION__);
653 val = list2val (ilist);
654 /* if the value is a character string */
655 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
657 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
659 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
660 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
662 if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
664 pic16_emitDB(0x00, ptype, p);
670 for(remain=0; remain<strlen(s); remain++) {
671 pic16_emitDB(s[remain], ptype, p);
677 /*-----------------------------------------------------------------*/
678 /* pic16_printIvalArray - generates code for array initialization */
679 /*-----------------------------------------------------------------*/
681 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
685 int lcnt = 0, size = 0;
692 fprintf(stderr, "%s\n",__FUNCTION__);
694 /* take care of the special case */
695 /* array of characters can be init */
697 if (IS_CHAR (type->next)) {
698 if (!IS_LITERAL(list2val(ilist)->etype)) {
699 werror (W_INIT_WRONG);
703 if(pic16_printIvalChar (type,
704 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
705 SPEC_CVAL (sym->etype).v_char, ptype, p))
708 /* not the special case */
709 if (ilist && ilist->type != INIT_DEEP)
711 werror (E_INIT_STRUCT, sym->name);
715 iloop = ilist->init.deep;
716 lcnt = DCL_ELEM (type);
721 pic16_printIval (sym, type->next, iloop, ptype, p);
722 iloop = (iloop ? iloop->next : NULL);
725 /* if not array limits given & we */
726 /* are out of initialisers then */
727 if (!DCL_ELEM (type) && !iloop)
730 /* no of elements given and we */
731 /* have generated for all of them */
733 /* if initializers left */
735 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
741 /* if we have not been given a size */
742 if (!DCL_ELEM (type))
743 DCL_ELEM (type) = size;
748 /*-----------------------------------------------------------------*/
749 /* pic16_printIvalBitFields - generate initializer for bitfields */
750 /*-----------------------------------------------------------------*/
751 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
755 initList *lilist = *ilist ;
756 unsigned long ival = 0;
761 fprintf(stderr, "%s\n",__FUNCTION__);
767 val = list2val(lilist);
769 if (SPEC_BLEN(lsym->etype) > 8) {
770 size += ((SPEC_BLEN (lsym->etype) / 8) +
771 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
774 size = ((SPEC_BLEN (lsym->etype) / 8) +
775 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
777 i = (unsigned long)floatFromVal(val);
778 i <<= SPEC_BSTR (lsym->etype);
780 if (! ( lsym->next &&
781 (IS_BITFIELD(lsym->next->type)) &&
782 (SPEC_BSTR(lsym->next->etype)))) break;
784 lilist = lilist->next;
788 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
792 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
793 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
796 case 4: /* EEP: why is this db and not dw? */
797 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
798 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
799 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
800 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
803 /* VR - only 1,2,4 size long can be handled???? Why? */
804 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
812 /*-----------------------------------------------------------------*/
813 /* printIvalStruct - generates initial value for structures */
814 /*-----------------------------------------------------------------*/
815 void pic16_printIvalStruct (symbol * sym, sym_link * type,
816 initList * ilist, char ptype, void *p)
819 initList *iloop = NULL;
823 fprintf(stderr, "%s\n",__FUNCTION__);
826 sflds = SPEC_STRUCT (type)->fields;
829 if (ilist->type != INIT_DEEP) {
830 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
834 iloop = ilist->init.deep;
837 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
838 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
839 if (IS_BITFIELD(sflds->type)) {
840 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
842 pic16_printIval (sym, sflds->type, iloop, ptype, p);
846 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
851 /*--------------------------------------------------------------------------*/
852 /* pic16_printIvalCharPtr - generates initial values for character pointers */
853 /*--------------------------------------------------------------------------*/
854 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
858 /* PENDING: this is _very_ mcs51 specific, including a magic
860 It's also endin specific.
862 VR - Attempting to port this function to pic16 port - 8-Jun-2004
867 fprintf(stderr, "%s\n",__FUNCTION__);
870 size = getSize (type);
872 if (val->name && strlen (val->name))
874 if (size == 1) /* This appears to be Z80 specific?? */
876 pic16_emitDS(val->name, ptype, p);
880 pic16_printPointerType (val->name, ptype, p);
885 if (IS_PTR (val->type)) {
886 type = DCL_TYPE (val->type);
888 type = PTR_TYPE (SPEC_OCLS (val->etype));
890 if (val->sym && val->sym->isstrlit) {
891 // this is a literal string
894 pic16_printGPointerType(val->name, type, ptype, p);
898 fprintf (stderr, "*** internal error: unknown size in "
899 "printIvalCharPtr.\n");
905 // these are literals assigned to pointers
909 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
912 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
913 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
916 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
917 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
918 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
926 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
927 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
928 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
934 /*-----------------------------------------------------------------------*/
935 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
936 /*-----------------------------------------------------------------------*/
937 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
944 fprintf(stderr, "%s\n",__FUNCTION__);
948 val = list2val (ilist);
950 val = valCastLiteral(type, 0.0);
953 // an error has been thrown already
957 if (IS_LITERAL(val->etype)) {
958 if (compareType(type, val->etype) == 0) {
959 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
960 printFromToType (val->type, type);
962 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
966 /* check the types */
967 if ((dLvl = compareType (val->type, type->next)) <= 0)
969 pic16_emitDB(0x00, ptype, p);
973 /* now generate the name */
975 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
977 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
979 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
981 if(!checkSym(publics, val->sym))
982 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
983 /* this has not been declared as extern
984 * so declare it as a 'late extern' just after the symbol */
985 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
986 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
987 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
996 /*-----------------------------------------------------------------*/
997 /* pic16_printIvalPtr - generates initial value for pointers */
998 /*-----------------------------------------------------------------*/
999 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1005 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1006 sym->rname, getSize(sym->type));
1010 if (ilist && (ilist->type == INIT_DEEP))
1011 ilist = ilist->init.deep;
1013 /* function pointer */
1014 if (IS_FUNC (type->next))
1016 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1020 if (!(val = pic16_initPointer (ilist, type)))
1023 /* if character pointer */
1024 if (IS_CHAR (type->next))
1025 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1028 /* check the type */
1029 if (compareType (type, val->type) == 0) {
1030 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1031 printFromToType (val->type, type);
1034 /* if val is literal */
1035 if (IS_LITERAL (val->etype))
1037 switch (getSize (type))
1040 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1043 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1044 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1047 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1048 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1049 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1052 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1059 size = getSize (type);
1061 if (size == 1) /* Z80 specific?? */
1063 pic16_emitDS(val->name, ptype, p);
1067 pic16_printPointerType (val->name, ptype, p);
1071 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1080 /*-----------------------------------------------------------------*/
1081 /* pic16_printIval - generates code for initial value */
1082 /*-----------------------------------------------------------------*/
1083 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1091 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1092 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1093 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1096 /* if structure then */
1097 if (IS_STRUCT (type))
1099 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1100 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1104 /* if this is an array */
1105 if (IS_ARRAY (type))
1107 // fprintf(stderr,"%s array\n",__FUNCTION__);
1108 pic16_printIvalArray (sym, type, ilist, ptype, p);
1115 // not an aggregate, ilist must be a node
1116 if (ilist->type!=INIT_NODE) {
1117 // or a 1-element list
1118 if (ilist->init.deep->next) {
1119 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1122 ilist=ilist->init.deep;
1127 // and the type must match
1128 itype=ilist->init.node->ftype;
1130 if (compareType(type, itype)==0) {
1131 // special case for literal strings
1132 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1133 // which are really code pointers
1134 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1137 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1138 // printFromToType(itype, type);
1145 /* if this is a pointer */
1148 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1149 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1154 /* if type is SPECIFIER */
1157 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1158 pic16_printIvalType (sym, type, ilist, ptype, p);
1163 int PIC16_IS_CONFIG_ADDRESS(int address)
1165 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1168 int PIC16_IS_IDLOC_ADDRESS(int address)
1170 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1173 /* wrapper function for the above */
1174 int PIC16_IS_HWREG_ADDRESS(int address)
1176 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1180 /*-----------------------------------------------------------------*/
1181 /* emitStaticSeg - emitcode for the static segment */
1182 /*-----------------------------------------------------------------*/
1184 pic16emitStaticSeg (memmap * map)
1187 static int didcode=0;
1189 //fprintf(stderr, "%s\n",__FUNCTION__);
1193 /* for all variables in this segment do */
1194 for (sym = setFirstItem (map->syms); sym;
1195 sym = setNextItem (map->syms))
1199 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1200 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1201 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1202 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1203 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1204 printTypeChain( sym->type, stderr );
1205 fprintf(stderr, "\n");
1208 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1209 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1210 (int) floatFromVal(list2val(sym->ival)));
1215 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1216 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1217 (char) floatFromVal(list2val(sym->ival)));
1222 /* if it is "extern" then do nothing */
1223 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1224 checkAddSym(&externs, sym);
1228 /* if it is not static add it to the public
1230 if (!IS_STATIC (sym->etype)) {
1231 /* do not emit if it is a config word declaration */
1232 checkAddSym(&publics, sym);
1235 /* print extra debug info if required */
1236 if (options.debug || sym->level == 0) {
1237 /* NOTE to me - cdbFile may be null in which case,
1238 * the sym name will be printed to stdout. oh well */
1239 debugFile->writeSymbol(sym);
1242 /* if it has an absolute address */
1243 if (SPEC_ABSA (sym->etype)) {
1244 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1245 // __FILE__, __LINE__, sym->name);
1247 /* if it has an initial value */
1255 /* symbol has absolute address and initial value */
1257 resolveIvalSym (sym->ival, sym->type);
1258 asym = newSymbol(sym->rname, 0);
1259 abSym = Safe_calloc(1, sizeof(absSym));
1260 strcpy(abSym->name, sym->rname);
1261 abSym->address = SPEC_ADDR( sym->etype );
1262 addSet(&absSymSet, abSym);
1264 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1265 pic16_addpBlock(pb);
1267 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1268 PCF(pcf)->absblock = 1;
1270 pic16_addpCode2pBlock(pb,pcf);
1271 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1272 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1273 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1274 pic16_flushDB('p', (void *)pb);
1276 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1282 /* symbol has absolute address but no initial value */
1284 /* allocate space */
1285 fprintf (code->oFile, "%s:\n", sym->rname);
1287 /* special case for character strings */
1288 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1289 SPEC_CVAL (sym->etype).v_char) {
1291 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1293 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1300 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1301 // __FILE__, __LINE__, sym->name);
1304 /* if it has an initial value */
1308 /* symbol doesn't have absolute address but has initial value */
1309 fprintf (code->oFile, "%s:\n", sym->rname);
1311 resolveIvalSym (sym->ival, sym->type);
1313 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1314 pic16_addpBlock(pb);
1317 /* make sure that 'code' directive is emitted before, once */
1318 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1323 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1325 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1326 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1327 pic16_flushDB('p', (void *)pb);
1331 /* symbol doesn't have absolute address and no initial value */
1332 /* allocate space */
1333 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1334 fprintf (code->oFile, "%s:\n", sym->rname);
1335 /* special case for character strings */
1336 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1337 SPEC_CVAL (sym->etype).v_char) {
1339 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1341 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1352 /*-----------------------------------------------------------------*/
1353 /* pic16_emitConfigRegs - emits the configuration registers */
1354 /*-----------------------------------------------------------------*/
1355 void pic16_emitConfigRegs(FILE *of)
1359 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1360 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1361 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1362 pic16->cwInfo.confAddrStart+i,
1363 pic16->cwInfo.crInfo[i].value);
1366 void pic16_emitIDRegs(FILE *of)
1370 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1371 if(pic16->idInfo.irInfo[i].emit)
1372 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1373 pic16->idInfo.idAddrStart+i,
1374 pic16->idInfo.irInfo[i].value);
1381 /* no special considerations for the following
1382 data, idata & bit & xdata */
1383 pic16emitRegularMap (data, TRUE, TRUE);
1384 pic16emitRegularMap (idata, TRUE, TRUE);
1385 pic16emitRegularMap (bit, TRUE, FALSE);
1386 pic16emitRegularMap (xdata, TRUE, TRUE);
1387 pic16emitRegularMap (sfr, FALSE, FALSE);
1388 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1389 pic16emitRegularMap (code, TRUE, FALSE);
1390 pic16emitStaticSeg (statsg);
1393 /*-----------------------------------------------------------------*/
1394 /* createInterruptVect - creates the interrupt vector */
1395 /*-----------------------------------------------------------------*/
1397 pic16createInterruptVect (FILE * vFile)
1399 /* if the main is only a prototype ie. no body then do nothing */
1401 if (!IFFUNC_HASBODY(mainf->type)) {
1402 /* if ! compile only then main function should be present */
1403 if (!options.cc_only)
1409 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1410 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1411 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1413 /* this is an overkill since WE are the port,
1414 * and we know if we have a genIVT function! */
1416 port->genIVT(vFile, interrupts, maxInterrupts);
1423 /*-----------------------------------------------------------------*/
1424 /* pic16initialComments - puts in some initial comments */
1425 /*-----------------------------------------------------------------*/
1427 pic16initialComments (FILE * afile)
1429 initialComments (afile);
1430 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1431 if(pic16_mplab_comp)
1432 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1433 fprintf (afile, iComments2);
1436 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1437 SDCC_VERSION_STR, getBuildNumber() );
1441 /*-----------------------------------------------------------------*/
1442 /* printPublics - generates global declarations for publics */
1443 /*-----------------------------------------------------------------*/
1445 pic16printPublics (FILE *afile)
1449 fprintf (afile, "\n%s", iComments2);
1450 fprintf (afile, "; public variables in this module\n");
1451 fprintf (afile, "%s", iComments2);
1453 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1455 if(!IS_STATIC(sym->etype))
1456 fprintf(afile, "\tglobal %s\n", sym->rname);
1459 /*-----------------------------------------------------------------*/
1460 /* printExterns - generates extern declarations for externs */
1461 /*-----------------------------------------------------------------*/
1463 pic16_printExterns(FILE *afile)
1467 /* print nothing if no externs to declare */
1468 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1471 fprintf(afile, "\n%s", iComments2);
1472 fprintf(afile, "; extern variables in this module\n");
1473 fprintf(afile, "%s", iComments2);
1475 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1476 fprintf(afile, "\textern %s\n", sym->rname);
1478 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1479 fprintf(afile, "\textern _%s\n", sym->name);
1482 /*-----------------------------------------------------------------*/
1483 /* emitOverlay - will emit code for the overlay stuff */
1484 /*-----------------------------------------------------------------*/
1486 pic16emitOverlay (FILE * afile)
1490 if (!elementsInSet (ovrSetSets))
1491 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1493 /* for each of the sets in the overlay segment do */
1494 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1495 ovrset = setNextItem (ovrSetSets))
1500 if (elementsInSet (ovrset))
1502 /* this dummy area is used to fool the assembler
1503 otherwise the assembler will append each of these
1504 declarations into one chunk and will not overlay
1506 fprintf (afile, ";\t.area _DUMMY\n");
1507 /* output the area informtion */
1508 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1511 for (sym = setFirstItem (ovrset); sym;
1512 sym = setNextItem (ovrset))
1515 /* if extern then do nothing */
1516 if (IS_EXTERN (sym->etype))
1519 /* if allocation required check is needed
1520 then check if the symbol really requires
1521 allocation only for local variables */
1522 if (!IS_AGGREGATE (sym->type) &&
1523 !(sym->_isparm && !IS_REGPARM (sym->etype))
1524 && !sym->allocreq && sym->level)
1527 /* if global variable & not static or extern
1528 and addPublics allowed then add it to the public set */
1529 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1530 && !IS_STATIC (sym->etype)) {
1531 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1532 checkAddSym(&publics, sym);
1533 // addSetHead (&publics, sym);
1536 /* if extern then do nothing or is a function
1538 if (IS_FUNC (sym->type))
1542 /* if is has an absolute address then generate
1543 an equate for this no need to allocate space */
1544 if (SPEC_ABSA (sym->etype))
1547 if (options.debug || sym->level == 0)
1548 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1550 fprintf (afile, "%s\t=\t0x%04x\n",
1552 SPEC_ADDR (sym->etype));
1556 if (options.debug || sym->level == 0)
1557 fprintf (afile, "==.\n");
1559 /* allocate space */
1560 fprintf (afile, "%s:\n", sym->rname);
1561 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1568 void emitStatistics(FILE *asmFile)
1570 statistics.isize = pic16_countInstructions();
1572 fprintf (asmFile, "\n\n; Statistics:\n");
1573 fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
1574 statistics.isize, statistics.isize,
1575 statistics.isize>>1, statistics.isize>>1);
1576 fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n",
1577 statistics.udsize, statistics.udsize);
1578 fprintf (asmFile, "; access size:\t%ld (0x%lx) 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 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1711 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1712 pic16_OptimizeJumps();
1715 /* print the extern variables to this module */
1716 pic16_printExterns(asmFile);
1718 /* print the global variables in this module */
1719 pic16printPublics (asmFile);
1721 pic16_writeUsedRegs(asmFile);
1724 /* no xdata in pic */
1725 /* if external stack then reserve space of it */
1726 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1727 fprintf (asmFile, "%s", iComments2);
1728 fprintf (asmFile, "; external stack \n");
1729 fprintf (asmFile, "%s", iComments2);
1730 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1731 fprintf (asmFile,";\t.ds 256\n");
1736 /* no xdata in pic */
1737 /* copy xtern ram data */
1738 fprintf (asmFile, "%s", iComments2);
1739 fprintf (asmFile, "; external ram data\n");
1740 fprintf (asmFile, "%s", iComments2);
1741 copyFile (asmFile, xdata->oFile);
1745 /* copy the bit segment */
1746 fprintf (asmFile, "%s", iComments2);
1747 fprintf (asmFile, "; bit data\n");
1748 fprintf (asmFile, "%s", iComments2);
1749 copyFile (asmFile, bit->oFile);
1752 /* copy the interrupt vector table */
1753 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1754 fprintf (asmFile, "\n%s", iComments2);
1755 fprintf (asmFile, "; interrupt vector \n");
1756 fprintf (asmFile, "%s", iComments2);
1757 copyFile (asmFile, vFile);
1760 /* copy global & static initialisations */
1761 fprintf (asmFile, "\n%s", iComments2);
1762 fprintf (asmFile, "; global & static initialisations\n");
1763 fprintf (asmFile, "%s", iComments2);
1765 if(pic16_debug_verbose)
1766 fprintf(asmFile, "; A code from now on!\n");
1768 pic16_copypCode(asmFile, 'A');
1770 if(pic16_options.no_crt) {
1771 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1772 fprintf(asmFile, "\tcode\n");
1773 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1777 // copyFile (stderr, code->oFile);
1779 fprintf(asmFile, "; I code from now on!\n");
1780 pic16_copypCode(asmFile, 'I');
1782 if(pic16_debug_verbose)
1783 fprintf(asmFile, "; dbName from now on!\n");
1785 pic16_copypCode(asmFile, statsg->dbName);
1787 if(pic16_options.no_crt) {
1788 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1789 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1793 if(pic16_debug_verbose)
1794 fprintf(asmFile, "; X code from now on!\n");
1796 pic16_copypCode(asmFile, 'X');
1798 if(pic16_debug_verbose)
1799 fprintf(asmFile, "; M code from now on!\n");
1801 pic16_copypCode(asmFile, 'M');
1803 pic16_copypCode(asmFile, code->dbName);
1805 pic16_copypCode(asmFile, 'P');
1807 emitStatistics(asmFile);
1809 fprintf (asmFile,"\tend\n");