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;
63 set *rel_idataSymSet=NULL;
64 set *fix_idataSymSet=NULL;
66 extern DEFSETFUNC (closeTmpFiles);
67 extern DEFSETFUNC (rmTmpFiles);
69 extern void pic16_AnalyzeBanking (void);
70 extern void copyFile (FILE * dest, FILE * src);
71 extern void pic16_InlinepCode(void);
72 extern void pic16_writeUsedRegs(FILE *);
74 extern void initialComments (FILE * afile);
75 extern void printPublics (FILE * afile);
77 void pic16_pCodeInitRegisters(void);
78 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
79 extern void pic16_pCodeConstString(char *name, char *value);
81 /*-----------------------------------------------------------------*/
82 /* aopLiteral - string from a literal value */
83 /*-----------------------------------------------------------------*/
84 int pic16aopLiteral (value *val, int offset)
91 /* if it is a float then it gets tricky */
92 /* otherwise it is fairly simple */
93 if (!IS_FLOAT(val->type)) {
94 unsigned long v = (unsigned long) floatFromVal(val);
96 return ( (v >> (offset * 8)) & 0xff);
99 /* it is type float */
100 fl.f = (float) floatFromVal(val);
101 #ifdef WORDS_BIGENDIAN
102 return fl.c[3-offset];
111 char tbuffer[512], *tbuf=tbuffer;;
114 /*-----------------------------------------------------------------*/
115 /* emitRegularMap - emit code for maps with no special cases */
116 /*-----------------------------------------------------------------*/
118 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
121 // int i, size, bitvars = 0;;
123 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
126 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
127 /* print the area name */
129 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
132 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
134 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
135 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
136 printTypeChain( sym->type, stderr );
137 fprintf(stderr, "\n");
140 /* if extern then add to externs */
141 if (IS_EXTERN (sym->etype)) {
142 /* reduce overhead while linking by not declaring
143 * extern unused external functions (usually declared
144 * in header files) */
145 if(IS_FUNC(sym->type) && !sym->used)continue;
147 /* make sure symbol is not in publics section */
148 if(!checkSym(publics, sym))
149 checkAddSym(&externs, sym);
153 /* if allocation required check is needed
154 * then check if the symbol really requires
155 * allocation only for local variables */
156 if (arFlag && !IS_AGGREGATE (sym->type) &&
157 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
158 !sym->allocreq && sym->level) {
160 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
165 /* if global variable & not static or extern
166 * and addPublics allowed then add it to the public set */
167 if ((sym->used) && (sym->level == 0 ||
168 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
170 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
172 checkAddSym(&publics, sym);
174 if(IS_STATIC(sym->etype)
175 && !(sym->ival && !sym->level)
178 /* add it to udata list */
180 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
181 // sym->name, sym->rname, sym->remat);
183 //, OP_SYMBOL(operandFromSymbol(sym))->name);
184 #define SET_IMPLICIT 1
187 if(IS_STRUCT(sym->type))
191 reg = pic16_allocDirReg( operandFromSymbol( sym ));
198 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
199 if(!strcmp(ssym->name, reg->name))found=1;
204 checkAddReg(&pic16_rel_udata, reg);
206 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);
222 /* print extra debug info if required */
223 if (options.debug || sym->level == 0) {
224 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
226 if (!sym->level) /* global */
227 if (IS_STATIC (sym->etype))
228 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
230 fprintf (map->oFile, "G_"); /* scope is global */
232 /* symbol is local */
233 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
234 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
239 /* if is has an absolute address then generate
240 an equate for this no need to allocate space */
241 if (SPEC_ABSA (sym->etype)) {
242 // if (options.debug || sym->level == 0)
243 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
244 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
246 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
248 SPEC_ADDR (sym->etype));
250 /* emit only if it is global */
251 if(sym->level == 0) {
254 reg = pic16_dirregWithName( sym->name );
257 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
258 // __FUNCTION__, __LINE__, sym->name);
260 /* if IS_STRUCT is omitted the following
261 * fixes structures but break char/int etc */
263 if(IS_STRUCT(sym->type))
264 sym->implicit = 1; // mark as implicit
267 reg = pic16_allocDirReg( operandFromSymbol(sym) );
269 if(checkAddReg(&pic16_fix_udata, reg)) {
270 /* and add to globals list if not exist */
271 addSet(&publics, sym);
275 addSet(&publics, sym);
279 if(!sym->used && (sym->level == 0)) {
282 /* symbol not used, just declared probably, but its in
283 * level 0, so we must declare it fine as global */
285 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
288 if(IS_STRUCT(sym->type))
289 sym->implicit = 1; // mark as implicit
292 if(IS_AGGREGATE(sym->type)) {
293 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
295 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
303 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
304 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
308 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
309 if(!strcmp(ssym->name, reg->name))found=1;
314 if(checkAddReg(&pic16_rel_udata, reg)) {
315 addSetHead(&publics, sym);
324 addSetHead(&publics, sym);
329 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
330 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
331 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
332 if (IS_BITVAR (sym->etype)) {
335 fprintf (map->oFile, "\t%s\n", sym->rname);
336 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
337 for (i = 1; i < size; i++)
338 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
341 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
345 /* FIXME -- VR Fix the following, so that syms to be placed
346 * in the idata section and let linker decide about their fate */
348 /* if it has an initial value then do it only if
349 it is a global variable */
351 if (sym->ival && sym->level == 0) {
355 if(SPEC_OCLS(sym->etype)==data) {
356 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
359 if(SPEC_OCLS(sym->etype)==code) {
360 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
365 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
366 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
369 if (IS_AGGREGATE (sym->type)) {
370 if(SPEC_ABSA(sym->etype))
371 addSet(&fix_idataSymSet, copySymbol(sym));
373 addSet(&rel_idataSymSet, copySymbol(sym));
374 // ival = initAggregates (sym, sym->ival, NULL);
376 if(SPEC_ABSA(sym->etype))
377 addSet(&fix_idataSymSet, copySymbol(sym));
379 addSet(&rel_idataSymSet, copySymbol(sym));
381 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
382 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
386 setAstLineno(ival, sym->lineDef);
387 codeOutFile = statsg->oFile;
389 eBBlockFromiCode (iCodeFromAst (ival));
397 /*-----------------------------------------------------------------*/
398 /* pic16_initPointer - pointer initialization code massaging */
399 /*-----------------------------------------------------------------*/
400 value *pic16_initPointer (initList * ilist, sym_link *toType)
406 return valCastLiteral(toType, 0.0);
409 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
410 // expr = list2expr( ilist );
415 /* try it the old way first */
416 if ((val = constExprValue (expr, FALSE)))
419 /* ( ptr + constant ) */
420 if (IS_AST_OP (expr) &&
421 (expr->opval.op == '+' || expr->opval.op == '-') &&
422 IS_AST_SYM_VALUE (expr->left) &&
423 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
424 compareType(toType, expr->left->ftype) &&
425 IS_AST_LIT_VALUE (expr->right)) {
426 return valForCastAggr (expr->left, expr->left->ftype,
432 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
433 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
434 if (compareType(toType, expr->left->ftype)!=1) {
435 werror (W_INIT_WRONG);
436 printFromToType(expr->left->ftype, toType);
442 /* no then we have to do these cludgy checks */
443 /* pointers can be initialized with address of
444 a variable or address of an array element */
445 if (IS_AST_OP (expr) && expr->opval.op == '&') {
446 /* address of symbol */
447 if (IS_AST_SYM_VALUE (expr->left)) {
448 val = copyValue (AST_VALUE (expr->left));
449 val->type = newLink (DECLARATOR);
450 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
451 DCL_TYPE (val->type) = CPOINTER;
452 DCL_PTR_CONST (val->type) = port->mem.code_ro;
454 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
455 DCL_TYPE (val->type) = FPOINTER;
456 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
457 DCL_TYPE (val->type) = PPOINTER;
458 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
459 DCL_TYPE (val->type) = IPOINTER;
460 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
461 DCL_TYPE (val->type) = EEPPOINTER;
463 DCL_TYPE (val->type) = POINTER;
465 val->type->next = expr->left->ftype;
466 val->etype = getSpec (val->type);
470 /* if address of indexed array */
471 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
472 return valForArray (expr->left);
474 /* if address of structure element then
476 if (IS_AST_OP (expr->left) &&
477 expr->left->opval.op == '.') {
478 return valForStructElem (expr->left->left,
483 (&some_struct)->element */
484 if (IS_AST_OP (expr->left) &&
485 expr->left->opval.op == PTR_OP &&
486 IS_ADDRESS_OF_OP (expr->left->left)) {
487 return valForStructElem (expr->left->left->left,
491 /* case 3. (((char *) &a) +/- constant) */
492 if (IS_AST_OP (expr) &&
493 (expr->opval.op == '+' || expr->opval.op == '-') &&
494 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
495 IS_AST_OP (expr->left->right) &&
496 expr->left->right->opval.op == '&' &&
497 IS_AST_LIT_VALUE (expr->right)) {
499 return valForCastAggr (expr->left->right->left,
500 expr->left->left->opval.lnk,
501 expr->right, expr->opval.op);
504 /* case 4. (char *)(array type) */
505 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
506 IS_ARRAY(expr->right->ftype)) {
508 val = copyValue (AST_VALUE (expr->right));
509 val->type = newLink (DECLARATOR);
510 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
511 DCL_TYPE (val->type) = CPOINTER;
512 DCL_PTR_CONST (val->type) = port->mem.code_ro;
514 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
515 DCL_TYPE (val->type) = FPOINTER;
516 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
517 DCL_TYPE (val->type) = PPOINTER;
518 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
519 DCL_TYPE (val->type) = IPOINTER;
520 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
521 DCL_TYPE (val->type) = EEPPOINTER;
523 DCL_TYPE (val->type) = POINTER;
524 val->type->next = expr->right->ftype->next;
525 val->etype = getSpec (val->type);
531 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
533 werror (E_INCOMPAT_PTYPES);
539 /*-----------------------------------------------------------------*/
540 /* printPointerType - generates ival for pointer type */
541 /*-----------------------------------------------------------------*/
542 void _pic16_printPointerType (const char *name, char ptype, void *p)
546 sprintf(buf, "LOW(%s)", name);
547 pic16_emitDS(buf, ptype, p);
548 sprintf(buf, "HIGH(%s)", name);
549 pic16_emitDS(buf, ptype, p);
552 /*-----------------------------------------------------------------*/
553 /* printPointerType - generates ival for pointer type */
554 /*-----------------------------------------------------------------*/
555 void pic16_printPointerType (const char *name, char ptype, void *p)
557 _pic16_printPointerType (name, ptype, p);
558 pic16_flushDB(ptype, p);
561 /*-----------------------------------------------------------------*/
562 /* printGPointerType - generates ival for generic pointer type */
563 /*-----------------------------------------------------------------*/
564 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
565 const unsigned int type, char ptype, void *p)
569 _pic16_printPointerType (iname, ptype, p);
575 sprintf(buf, "UPPER(%s)", iname);
576 pic16_emitDS(buf, ptype, p);
580 sprintf(buf, "0x80");
581 pic16_emitDS(buf, ptype, p);
585 pic16_flushDB(ptype, p);
589 /* set to 0 to disable debug messages */
590 #define DEBUG_PRINTIVAL 0
592 /*-----------------------------------------------------------------*/
593 /* pic16_printIvalType - generates ival for int/char */
594 /*-----------------------------------------------------------------*/
596 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
600 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
603 fprintf(stderr, "%s\n",__FUNCTION__);
607 /* if initList is deep */
608 if (ilist && ilist->type == INIT_DEEP)
609 ilist = ilist->init.deep;
611 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
612 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
615 if (!(val = list2val (ilist))) {
616 // assuming a warning has been thrown
620 if (val->type != type) {
621 val = valCastLiteral(type, floatFromVal(val));
624 switch (getSize (type)) {
626 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
630 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
631 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
634 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
635 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
636 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
638 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
639 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
640 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
641 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
646 /*--------------------------------------------------------------------*/
647 /* pic16_printIvalChar - generates initital value for character array */
648 /*--------------------------------------------------------------------*/
650 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
659 fprintf(stderr, "%s\n",__FUNCTION__);
665 val = list2val (ilist);
666 /* if the value is a character string */
667 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
669 if (!DCL_ELEM (type))
670 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
672 for(remain=0; remain<DCL_ELEM(type); remain++)
673 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
675 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
677 pic16_emitDB(0x00, ptype, p);
686 for(remain=0; remain<strlen(s); remain++) {
687 pic16_emitDB(s[remain], ptype, p);
693 /*-----------------------------------------------------------------*/
694 /* pic16_printIvalArray - generates code for array initialization */
695 /*-----------------------------------------------------------------*/
697 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
701 int lcnt = 0, size = 0;
708 fprintf(stderr, "%s\n",__FUNCTION__);
710 /* take care of the special case */
711 /* array of characters can be init */
713 if (IS_CHAR (type->next)) {
714 if (!IS_LITERAL(list2val(ilist)->etype)) {
715 werror (W_INIT_WRONG);
719 if(pic16_printIvalChar (type,
720 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
721 SPEC_CVAL (sym->etype).v_char, ptype, p))
724 /* not the special case */
725 if (ilist && ilist->type != INIT_DEEP)
727 werror (E_INIT_STRUCT, sym->name);
731 iloop = ilist->init.deep;
732 lcnt = DCL_ELEM (type);
737 pic16_printIval (sym, type->next, iloop, ptype, p);
738 iloop = (iloop ? iloop->next : NULL);
741 /* if not array limits given & we */
742 /* are out of initialisers then */
743 if (!DCL_ELEM (type) && !iloop)
746 /* no of elements given and we */
747 /* have generated for all of them */
749 /* if initializers left */
751 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
757 /* if we have not been given a size */
758 if (!DCL_ELEM (type))
759 DCL_ELEM (type) = size;
764 /*-----------------------------------------------------------------*/
765 /* pic16_printIvalBitFields - generate initializer for bitfields */
766 /*-----------------------------------------------------------------*/
767 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
771 initList *lilist = *ilist ;
772 unsigned long ival = 0;
777 fprintf(stderr, "%s\n",__FUNCTION__);
783 val = list2val(lilist);
785 if (SPEC_BLEN(lsym->etype) > 8) {
786 size += ((SPEC_BLEN (lsym->etype) / 8) +
787 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
790 size = ((SPEC_BLEN (lsym->etype) / 8) +
791 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
793 i = (unsigned long)floatFromVal(val);
794 i <<= SPEC_BSTR (lsym->etype);
796 if (! ( lsym->next &&
797 (IS_BITFIELD(lsym->next->type)) &&
798 (SPEC_BSTR(lsym->next->etype)))) break;
800 lilist = lilist->next;
804 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
808 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
809 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
812 case 4: /* EEP: why is this db and not dw? */
813 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
814 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
815 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
816 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
819 /* VR - only 1,2,4 size long can be handled???? Why? */
820 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
828 /*-----------------------------------------------------------------*/
829 /* printIvalStruct - generates initial value for structures */
830 /*-----------------------------------------------------------------*/
831 void pic16_printIvalStruct (symbol * sym, sym_link * type,
832 initList * ilist, char ptype, void *p)
835 initList *iloop = NULL;
839 fprintf(stderr, "%s\n",__FUNCTION__);
842 sflds = SPEC_STRUCT (type)->fields;
845 if (ilist->type != INIT_DEEP) {
846 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
850 iloop = ilist->init.deep;
853 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
854 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
855 if (IS_BITFIELD(sflds->type)) {
856 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
858 pic16_printIval (sym, sflds->type, iloop, ptype, p);
862 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
867 /*--------------------------------------------------------------------------*/
868 /* pic16_printIvalCharPtr - generates initial values for character pointers */
869 /*--------------------------------------------------------------------------*/
870 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
874 /* PENDING: this is _very_ mcs51 specific, including a magic
876 It's also endin specific.
878 VR - Attempting to port this function to pic16 port - 8-Jun-2004
883 fprintf(stderr, "%s\n",__FUNCTION__);
886 size = getSize (type);
888 if (val->name && strlen (val->name))
890 if (size == 1) /* This appears to be Z80 specific?? */
892 pic16_emitDS(val->name, ptype, p);
896 pic16_printPointerType (val->name, ptype, p);
901 if (IS_PTR (val->type)) {
902 type = DCL_TYPE (val->type);
904 type = PTR_TYPE (SPEC_OCLS (val->etype));
906 if (val->sym && val->sym->isstrlit) {
907 // this is a literal string
910 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
914 fprintf (stderr, "*** internal error: unknown size in "
915 "printIvalCharPtr.\n");
921 // these are literals assigned to pointers
925 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
928 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
929 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
932 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
933 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
934 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
942 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
943 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
944 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
950 /*-----------------------------------------------------------------------*/
951 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
952 /*-----------------------------------------------------------------------*/
953 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
960 fprintf(stderr, "%s\n",__FUNCTION__);
964 val = list2val (ilist);
966 val = valCastLiteral(type, 0.0);
969 // an error has been thrown already
973 if (IS_LITERAL(val->etype)) {
974 if (compareType(type, val->etype) == 0) {
975 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
976 printFromToType (val->type, type);
978 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
982 /* check the types */
983 if ((dLvl = compareType (val->type, type->next)) <= 0)
985 pic16_emitDB(0x00, ptype, p);
989 /* now generate the name */
991 pic16_printPointerType (val->name, ptype, p);
993 pic16_printPointerType (val->sym->rname, ptype, p);
995 if(IS_FUNC(val->sym->type) && !val->sym->used) {
997 if(!checkSym(publics, val->sym))
998 checkAddSym(&externs, val->sym);
1000 /* this has not been declared as extern
1001 * so declare it as a 'late extern' just after the symbol */
1003 fprintf((FILE *)p, "declare symbol as extern");
1004 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1005 fprintf((FILE *)p, "continue variable declaration");
1014 /*-----------------------------------------------------------------*/
1015 /* pic16_printIvalPtr - generates initial value for pointers */
1016 /*-----------------------------------------------------------------*/
1017 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1023 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1024 sym->rname, getSize(sym->type));
1028 if (ilist && (ilist->type == INIT_DEEP))
1029 ilist = ilist->init.deep;
1031 /* function pointer */
1032 if (IS_FUNC (type->next))
1034 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1038 if (!(val = pic16_initPointer (ilist, type)))
1041 /* if character pointer */
1042 if (IS_CHAR (type->next))
1043 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1046 /* check the type */
1047 if (compareType (type, val->type) == 0) {
1048 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1049 printFromToType (val->type, type);
1052 /* if val is literal */
1053 if (IS_LITERAL (val->etype))
1055 switch (getSize (type))
1058 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1061 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1062 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1065 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1066 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1067 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1070 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1077 size = getSize (type);
1079 if (size == 1) /* Z80 specific?? */
1081 pic16_emitDS(val->name, ptype, p);
1085 pic16_printPointerType (val->name, ptype, p);
1089 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1090 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1091 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1099 /*-----------------------------------------------------------------*/
1100 /* pic16_printIval - generates code for initial value */
1101 /*-----------------------------------------------------------------*/
1102 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1110 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1111 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1112 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1115 /* if structure then */
1116 if (IS_STRUCT (type))
1118 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1119 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1123 /* if this is an array */
1124 if (IS_ARRAY (type))
1126 // fprintf(stderr,"%s array\n",__FUNCTION__);
1127 pic16_printIvalArray (sym, type, ilist, ptype, p);
1134 // not an aggregate, ilist must be a node
1135 if (ilist->type!=INIT_NODE) {
1136 // or a 1-element list
1137 if (ilist->init.deep->next) {
1138 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1141 ilist=ilist->init.deep;
1146 // and the type must match
1147 itype=ilist->init.node->ftype;
1149 if (compareType(type, itype)==0) {
1150 // special case for literal strings
1151 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1152 // which are really code pointers
1153 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1156 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1157 // printFromToType(itype, type);
1164 /* if this is a pointer */
1167 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1168 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1173 /* if type is SPECIFIER */
1176 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1177 pic16_printIvalType (sym, type, ilist, ptype, p);
1182 int PIC16_IS_CONFIG_ADDRESS(int address)
1184 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1187 int PIC16_IS_IDLOC_ADDRESS(int address)
1189 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1192 /* wrapper function for the above */
1193 int PIC16_IS_HWREG_ADDRESS(int address)
1195 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1199 /*-----------------------------------------------------------------*/
1200 /* emitStaticSeg - emitcode for the static segment */
1201 /*-----------------------------------------------------------------*/
1203 pic16emitStaticSeg (memmap * map)
1206 static int didcode=0;
1208 //fprintf(stderr, "%s\n",__FUNCTION__);
1212 /* for all variables in this segment do */
1213 for (sym = setFirstItem (map->syms); sym;
1214 sym = setNextItem (map->syms))
1218 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1219 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1220 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1221 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1222 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1223 printTypeChain( sym->type, stderr );
1224 fprintf(stderr, "\n");
1227 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1228 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1229 (int) floatFromVal(list2val(sym->ival)));
1234 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1235 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1236 (char) floatFromVal(list2val(sym->ival)));
1241 /* if it is "extern" then do nothing */
1242 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1243 checkAddSym(&externs, sym);
1247 /* if it is not static add it to the public
1249 if (!IS_STATIC (sym->etype)) {
1250 /* do not emit if it is a config word declaration */
1251 checkAddSym(&publics, sym);
1254 /* print extra debug info if required */
1255 if (options.debug || sym->level == 0) {
1256 /* NOTE to me - cdbFile may be null in which case,
1257 * the sym name will be printed to stdout. oh well */
1258 debugFile->writeSymbol(sym);
1261 /* if it has an absolute address */
1262 if (SPEC_ABSA (sym->etype)) {
1263 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1264 // __FILE__, __LINE__, sym->name);
1266 /* if it has an initial value */
1274 /* symbol has absolute address and initial value */
1276 resolveIvalSym (sym->ival, sym->type);
1277 asym = newSymbol(sym->rname, 0);
1278 abSym = Safe_calloc(1, sizeof(absSym));
1279 strcpy(abSym->name, sym->rname);
1280 abSym->address = SPEC_ADDR( sym->etype );
1281 addSet(&absSymSet, abSym);
1283 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1284 pic16_addpBlock(pb);
1286 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1287 PCF(pcf)->absblock = 1;
1289 pic16_addpCode2pBlock(pb,pcf);
1290 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1291 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1292 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1293 pic16_flushDB('p', (void *)pb);
1295 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1301 /* symbol has absolute address but no initial value */
1303 /* allocate space */
1304 fprintf (code->oFile, "%s:\n", sym->rname);
1306 /* special case for character strings */
1307 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1308 SPEC_CVAL (sym->etype).v_char) {
1310 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1312 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1319 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1320 // __FILE__, __LINE__, sym->name);
1323 /* if it has an initial value */
1327 /* symbol doesn't have absolute address but has initial value */
1328 fprintf (code->oFile, "%s:\n", sym->rname);
1330 resolveIvalSym (sym->ival, sym->type);
1332 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1333 pic16_addpBlock(pb);
1336 /* make sure that 'code' directive is emitted before, once */
1337 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1342 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1344 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1345 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1346 pic16_flushDB('p', (void *)pb);
1350 /* symbol doesn't have absolute address and no initial value */
1351 /* allocate space */
1352 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1353 fprintf (code->oFile, "%s:\n", sym->rname);
1354 /* special case for character strings */
1355 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1356 SPEC_CVAL (sym->etype).v_char) {
1358 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1360 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1371 /*-----------------------------------------------------------------*/
1372 /* pic16_emitConfigRegs - emits the configuration registers */
1373 /*-----------------------------------------------------------------*/
1374 void pic16_emitConfigRegs(FILE *of)
1378 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1379 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1380 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1381 pic16->cwInfo.confAddrStart+i,
1382 pic16->cwInfo.crInfo[i].value);
1385 void pic16_emitIDRegs(FILE *of)
1389 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1390 if(pic16->idInfo.irInfo[i].emit)
1391 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1392 pic16->idInfo.idAddrStart+i,
1393 pic16->idInfo.irInfo[i].value);
1400 /* no special considerations for the following
1401 data, idata & bit & xdata */
1402 pic16emitRegularMap (data, TRUE, TRUE);
1403 pic16emitRegularMap (idata, TRUE, TRUE);
1404 pic16emitRegularMap (bit, TRUE, FALSE);
1405 pic16emitRegularMap (xdata, TRUE, TRUE);
1406 pic16emitRegularMap (sfr, FALSE, FALSE);
1407 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1408 pic16emitRegularMap (code, TRUE, FALSE);
1409 pic16emitStaticSeg (statsg);
1412 /*-----------------------------------------------------------------*/
1413 /* createInterruptVect - creates the interrupt vector */
1414 /*-----------------------------------------------------------------*/
1416 pic16createInterruptVect (FILE * vFile)
1418 /* if the main is only a prototype ie. no body then do nothing */
1420 if (!IFFUNC_HASBODY(mainf->type)) {
1421 /* if ! compile only then main function should be present */
1422 if (!options.cc_only)
1428 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1429 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1430 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1432 /* this is an overkill since WE are the port,
1433 * and we know if we have a genIVT function! */
1435 port->genIVT(vFile, interrupts, maxInterrupts);
1442 /*-----------------------------------------------------------------*/
1443 /* pic16initialComments - puts in some initial comments */
1444 /*-----------------------------------------------------------------*/
1446 pic16initialComments (FILE * afile)
1448 initialComments (afile);
1449 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1450 if(pic16_mplab_comp)
1451 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1452 fprintf (afile, iComments2);
1455 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1456 SDCC_VERSION_STR, getBuildNumber() );
1460 /*-----------------------------------------------------------------*/
1461 /* printPublics - generates global declarations for publics */
1462 /*-----------------------------------------------------------------*/
1464 pic16printPublics (FILE *afile)
1468 fprintf (afile, "\n%s", iComments2);
1469 fprintf (afile, "; public variables in this module\n");
1470 fprintf (afile, "%s", iComments2);
1472 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1473 fprintf(afile, "\tglobal %s\n", sym->rname);
1476 /*-----------------------------------------------------------------*/
1477 /* printExterns - generates extern declarations for externs */
1478 /*-----------------------------------------------------------------*/
1480 pic16_printExterns(FILE *afile)
1484 /* print nothing if no externs to declare */
1485 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1488 fprintf(afile, "\n%s", iComments2);
1489 fprintf(afile, "; extern variables in this module\n");
1490 fprintf(afile, "%s", iComments2);
1492 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1493 fprintf(afile, "\textern %s\n", sym->rname);
1495 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1496 fprintf(afile, "\textern _%s\n", sym->name);
1499 /*-----------------------------------------------------------------*/
1500 /* emitOverlay - will emit code for the overlay stuff */
1501 /*-----------------------------------------------------------------*/
1503 pic16emitOverlay (FILE * afile)
1507 if (!elementsInSet (ovrSetSets))
1508 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1510 /* for each of the sets in the overlay segment do */
1511 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1512 ovrset = setNextItem (ovrSetSets))
1517 if (elementsInSet (ovrset))
1519 /* this dummy area is used to fool the assembler
1520 otherwise the assembler will append each of these
1521 declarations into one chunk and will not overlay
1523 fprintf (afile, ";\t.area _DUMMY\n");
1524 /* output the area informtion */
1525 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1528 for (sym = setFirstItem (ovrset); sym;
1529 sym = setNextItem (ovrset))
1532 /* if extern then do nothing */
1533 if (IS_EXTERN (sym->etype))
1536 /* if allocation required check is needed
1537 then check if the symbol really requires
1538 allocation only for local variables */
1539 if (!IS_AGGREGATE (sym->type) &&
1540 !(sym->_isparm && !IS_REGPARM (sym->etype))
1541 && !sym->allocreq && sym->level)
1544 /* if global variable & not static or extern
1545 and addPublics allowed then add it to the public set */
1546 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1547 && !IS_STATIC (sym->etype)) {
1548 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1549 checkAddSym(&publics, sym);
1550 // addSetHead (&publics, sym);
1553 /* if extern then do nothing or is a function
1555 if (IS_FUNC (sym->type))
1559 /* print extra debug info if required */
1560 if (options.debug || sym->level == 0)
1563 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1567 if (IS_STATIC (sym->etype))
1568 fprintf (afile, "F%s_", moduleName); /* scope is file */
1570 fprintf (afile, "G_"); /* scope is global */
1573 /* symbol is local */
1574 fprintf (afile, "L%s_",
1575 (sym->localof ? sym->localof->name : "-null-"));
1576 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1580 /* if is has an absolute address then generate
1581 an equate for this no need to allocate space */
1582 if (SPEC_ABSA (sym->etype))
1585 if (options.debug || sym->level == 0)
1586 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1588 fprintf (afile, "%s\t=\t0x%04x\n",
1590 SPEC_ADDR (sym->etype));
1594 if (options.debug || sym->level == 0)
1595 fprintf (afile, "==.\n");
1597 /* allocate space */
1598 fprintf (afile, "%s:\n", sym->rname);
1599 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1607 /*-----------------------------------------------------------------*/
1608 /* glue - the final glue that hold the whole thing together */
1609 /*-----------------------------------------------------------------*/
1616 FILE *ovrFile = tempfile();
1619 mainf = newSymbol ("main", 0);
1622 mainf = findSymWithLevel(SymbolTab, mainf);
1624 /* only if the main function exists */
1625 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1626 if (!options.cc_only)
1632 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1634 addSetHead(&tmpfileSet,ovrFile);
1635 pic16_pCodeInitRegisters();
1638 if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1639 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1641 pic16_addpBlock(pb);
1643 /* entry point @ start of CSEG */
1644 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1647 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1648 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1649 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1650 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1653 /* put in the call to main */
1654 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1656 if (options.mainreturn) {
1657 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1658 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1660 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1661 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1665 /* At this point we've got all the code in the form of pCode structures */
1666 /* Now it needs to be rearranged into the order it should be placed in the */
1669 pic16_movepBlock2Head('P'); // Last
1670 pic16_movepBlock2Head(code->dbName);
1671 pic16_movepBlock2Head('X');
1672 pic16_movepBlock2Head(statsg->dbName); // First
1674 /* print the global struct definitions */
1675 // if (options.debug)
1676 // cdbStructBlock (0); //,cdbFile);
1679 /* PENDING: this isnt the best place but it will do */
1680 if (port->general.glue_up_main) {
1681 /* create the interrupt vector table */
1682 pic16createInterruptVect (vFile);
1685 addSetHead(&tmpfileSet,vFile);
1687 /* emit code for the all the variables declared */
1689 /* do the overlay segments */
1690 pic16emitOverlay(ovrFile);
1691 pic16_AnalyzepCode('*');
1694 if(pic16_options.dumpcalltree) {
1696 sprintf(buffer, dstFileName);
1697 strcat(buffer, ".calltree");
1698 cFile = fopen(buffer, "w");
1699 pic16_printCallTree( cFile );
1704 pic16_InlinepCode();
1705 pic16_AnalyzepCode('*');
1707 if(pic16_debug_verbose)
1710 /* now put it all together into the assembler file */
1711 /* create the assembler file name */
1712 if ((noAssemble || options.c1mode) && fullDstFileName) {
1713 sprintf (buffer, fullDstFileName);
1715 sprintf (buffer, dstFileName);
1716 strcat (buffer, ".asm");
1719 if (!(asmFile = fopen (buffer, "w"))) {
1720 werror (E_FILE_OPEN_ERR, buffer);
1724 /* initial comments */
1725 pic16initialComments (asmFile);
1727 /* print module name */
1729 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1731 /* Let the port generate any global directives, etc. */
1732 if (port->genAssemblerPreamble) {
1733 port->genAssemblerPreamble(asmFile);
1736 /* print the extern variables to this module */
1737 pic16_printExterns(asmFile);
1739 /* print the global variables in this module */
1740 pic16printPublics (asmFile);
1743 /* copy the sfr segment */
1744 fprintf (asmFile, "%s", iComments2);
1745 fprintf (asmFile, "; special function registers\n");
1746 fprintf (asmFile, "%s", iComments2);
1747 copyFile (asmFile, sfr->oFile);
1750 /* Put all variables into a cblock */
1751 pic16_AnalyzeBanking();
1752 pic16_writeUsedRegs(asmFile);
1755 /* no xdata in pic */
1756 /* if external stack then reserve space of it */
1757 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1758 fprintf (asmFile, "%s", iComments2);
1759 fprintf (asmFile, "; external stack \n");
1760 fprintf (asmFile, "%s", iComments2);
1761 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1762 fprintf (asmFile,";\t.ds 256\n");
1767 /* no xdata in pic */
1768 /* copy xtern ram data */
1769 fprintf (asmFile, "%s", iComments2);
1770 fprintf (asmFile, "; external ram data\n");
1771 fprintf (asmFile, "%s", iComments2);
1772 copyFile (asmFile, xdata->oFile);
1776 /* copy the bit segment */
1777 fprintf (asmFile, "%s", iComments2);
1778 fprintf (asmFile, "; bit data\n");
1779 fprintf (asmFile, "%s", iComments2);
1780 copyFile (asmFile, bit->oFile);
1783 /* copy the interrupt vector table */
1784 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1785 fprintf (asmFile, "\n%s", iComments2);
1786 fprintf (asmFile, "; interrupt vector \n");
1787 fprintf (asmFile, "%s", iComments2);
1788 copyFile (asmFile, vFile);
1791 /* copy global & static initialisations */
1792 fprintf (asmFile, "\n%s", iComments2);
1793 fprintf (asmFile, "; global & static initialisations\n");
1794 fprintf (asmFile, "%s", iComments2);
1796 if(pic16_debug_verbose)
1797 fprintf(asmFile, "; A code from now on!\n");
1798 pic16_copypCode(asmFile, 'A');
1801 if(pic16_options.no_crt) {
1802 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1803 fprintf(asmFile, "\tcode\n");
1804 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1808 // copyFile (stderr, code->oFile);
1810 fprintf(asmFile, "; I code from now on!\n");
1811 pic16_copypCode(asmFile, 'I');
1813 if(pic16_debug_verbose)
1814 fprintf(asmFile, "; dbName from now on!\n");
1815 pic16_copypCode(asmFile, statsg->dbName);
1818 if(pic16_options.no_crt) {
1819 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1820 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1825 if(pic16_debug_verbose)
1826 fprintf(asmFile, "; X code from now on!\n");
1827 pic16_copypCode(asmFile, 'X');
1829 if(pic16_debug_verbose)
1830 fprintf(asmFile, "; M code from now on!\n");
1831 pic16_copypCode(asmFile, 'M');
1834 pic16_copypCode(asmFile, code->dbName);
1836 pic16_copypCode(asmFile, 'P');
1838 fprintf (asmFile,"\tend\n");