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 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
82 extern void _debugf(char *f, int l, char *frm, ...);
84 /*-----------------------------------------------------------------*/
85 /* aopLiteral - string from a literal value */
86 /*-----------------------------------------------------------------*/
87 int pic16aopLiteral (value *val, int offset)
94 /* if it is a float then it gets tricky */
95 /* otherwise it is fairly simple */
96 if (!IS_FLOAT(val->type)) {
97 unsigned long v = (unsigned long) floatFromVal(val);
99 return ( (v >> (offset * 8)) & 0xff);
102 /* it is type float */
103 fl.f = (float) floatFromVal(val);
104 #ifdef WORDS_BIGENDIAN
105 return fl.c[3-offset];
114 char tbuffer[512], *tbuf=tbuffer;;
117 /*-----------------------------------------------------------------*/
118 /* emitRegularMap - emit code for maps with no special cases */
119 /*-----------------------------------------------------------------*/
121 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
124 // int i, size, bitvars = 0;;
126 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
129 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
130 /* print the area name */
132 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
135 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
137 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
138 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
139 printTypeChain( sym->type, stderr );
140 fprintf(stderr, "\n");
143 /* if extern then add to externs */
144 if (IS_EXTERN (sym->etype)) {
145 /* reduce overhead while linking by not declaring
146 * extern unused external functions (usually declared
147 * in header files) */
148 if(IS_FUNC(sym->type) && !sym->used)continue;
150 /* make sure symbol is not in publics section */
151 if(!checkSym(publics, sym))
152 checkAddSym(&externs, sym);
156 /* if allocation required check is needed
157 * then check if the symbol really requires
158 * allocation only for local variables */
159 if (arFlag && !IS_AGGREGATE (sym->type) &&
160 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
161 !sym->allocreq && sym->level) {
163 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
168 /* if global variable & not static or extern
169 * and addPublics allowed then add it to the public set */
170 if ((sym->used) && (sym->level == 0 ||
171 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
173 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
175 checkAddSym(&publics, sym);
177 if(IS_STATIC(sym->etype)
178 && !(sym->ival && !sym->level)
181 /* add it to udata list */
183 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
184 // sym->name, sym->rname, sym->remat);
186 //, OP_SYMBOL(operandFromSymbol(sym))->name);
187 #define SET_IMPLICIT 1
190 if(IS_STRUCT(sym->type))
194 reg = pic16_allocDirReg( operandFromSymbol( sym ));
201 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
202 if(!strcmp(ssym->name, reg->name))found=1;
207 checkAddReg(&pic16_rel_udata, reg);
209 checkAddSym(&publics, sym);
214 /* if extern then do nothing or is a function
216 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
217 if(SPEC_OCLS(sym->etype) == code) {
218 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
219 checkAddSym(&publics, sym);
225 /* print extra debug info if required */
226 if (options.debug || sym->level == 0) {
227 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
229 if (!sym->level) /* global */
230 if (IS_STATIC (sym->etype))
231 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
233 fprintf (map->oFile, "G_"); /* scope is global */
235 /* symbol is local */
236 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
237 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
242 /* if is has an absolute address then generate
243 an equate for this no need to allocate space */
244 if (SPEC_ABSA (sym->etype)) {
245 // if (options.debug || sym->level == 0)
246 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
247 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
249 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
251 SPEC_ADDR (sym->etype));
253 /* emit only if it is global */
254 if(sym->level == 0) {
257 reg = pic16_dirregWithName( sym->name );
260 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
261 // __FUNCTION__, __LINE__, sym->name);
263 /* if IS_STRUCT is omitted the following
264 * fixes structures but break char/int etc */
266 if(IS_STRUCT(sym->type))
267 sym->implicit = 1; // mark as implicit
270 reg = pic16_allocDirReg( operandFromSymbol(sym) );
272 if(checkAddReg(&pic16_fix_udata, reg)) {
273 /* and add to globals list if not exist */
274 addSet(&publics, sym);
278 addSet(&publics, sym);
282 if(!sym->used && (sym->level == 0)) {
285 /* symbol not used, just declared probably, but its in
286 * level 0, so we must declare it fine as global */
288 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
291 if(IS_STRUCT(sym->type))
292 sym->implicit = 1; // mark as implicit
295 if(IS_AGGREGATE(sym->type)) {
296 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
298 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
306 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
307 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
311 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
312 if(!strcmp(ssym->name, reg->name))found=1;
317 if(checkAddReg(&pic16_rel_udata, reg)) {
318 addSetHead(&publics, sym);
327 addSetHead(&publics, sym);
332 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
333 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
334 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
335 if (IS_BITVAR (sym->etype)) {
338 fprintf (map->oFile, "\t%s\n", sym->rname);
339 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
340 for (i = 1; i < size; i++)
341 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
344 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
348 /* FIXME -- VR Fix the following, so that syms to be placed
349 * in the idata section and let linker decide about their fate */
351 /* if it has an initial value then do it only if
352 it is a global variable */
354 if (sym->ival && sym->level == 0) {
358 if(SPEC_OCLS(sym->etype)==data) {
359 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
362 if(SPEC_OCLS(sym->etype)==code) {
363 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
368 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
369 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
372 if (IS_AGGREGATE (sym->type)) {
373 if(SPEC_ABSA(sym->etype))
374 addSet(&fix_idataSymSet, copySymbol(sym));
376 addSet(&rel_idataSymSet, copySymbol(sym));
377 // ival = initAggregates (sym, sym->ival, NULL);
379 if(SPEC_ABSA(sym->etype))
380 addSet(&fix_idataSymSet, copySymbol(sym));
382 addSet(&rel_idataSymSet, copySymbol(sym));
384 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
385 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
389 setAstLineno(ival, sym->lineDef);
390 codeOutFile = statsg->oFile;
392 eBBlockFromiCode (iCodeFromAst (ival));
400 /*-----------------------------------------------------------------*/
401 /* pic16_initPointer - pointer initialization code massaging */
402 /*-----------------------------------------------------------------*/
403 value *pic16_initPointer (initList * ilist, sym_link *toType)
409 return valCastLiteral(toType, 0.0);
412 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
413 // expr = list2expr( ilist );
418 /* try it the old way first */
419 if ((val = constExprValue (expr, FALSE)))
422 /* ( ptr + constant ) */
423 if (IS_AST_OP (expr) &&
424 (expr->opval.op == '+' || expr->opval.op == '-') &&
425 IS_AST_SYM_VALUE (expr->left) &&
426 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
427 compareType(toType, expr->left->ftype) &&
428 IS_AST_LIT_VALUE (expr->right)) {
429 return valForCastAggr (expr->left, expr->left->ftype,
435 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
436 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
437 if (compareType(toType, expr->left->ftype)!=1) {
438 werror (W_INIT_WRONG);
439 printFromToType(expr->left->ftype, toType);
445 /* no then we have to do these cludgy checks */
446 /* pointers can be initialized with address of
447 a variable or address of an array element */
448 if (IS_AST_OP (expr) && expr->opval.op == '&') {
449 /* address of symbol */
450 if (IS_AST_SYM_VALUE (expr->left)) {
451 val = copyValue (AST_VALUE (expr->left));
452 val->type = newLink (DECLARATOR);
453 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
454 DCL_TYPE (val->type) = CPOINTER;
455 DCL_PTR_CONST (val->type) = port->mem.code_ro;
457 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
458 DCL_TYPE (val->type) = FPOINTER;
459 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
460 DCL_TYPE (val->type) = PPOINTER;
461 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
462 DCL_TYPE (val->type) = IPOINTER;
463 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
464 DCL_TYPE (val->type) = EEPPOINTER;
466 DCL_TYPE (val->type) = POINTER;
468 val->type->next = expr->left->ftype;
469 val->etype = getSpec (val->type);
473 /* if address of indexed array */
474 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
475 return valForArray (expr->left);
477 /* if address of structure element then
479 if (IS_AST_OP (expr->left) &&
480 expr->left->opval.op == '.') {
481 return valForStructElem (expr->left->left,
486 (&some_struct)->element */
487 if (IS_AST_OP (expr->left) &&
488 expr->left->opval.op == PTR_OP &&
489 IS_ADDRESS_OF_OP (expr->left->left)) {
490 return valForStructElem (expr->left->left->left,
494 /* case 3. (((char *) &a) +/- constant) */
495 if (IS_AST_OP (expr) &&
496 (expr->opval.op == '+' || expr->opval.op == '-') &&
497 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
498 IS_AST_OP (expr->left->right) &&
499 expr->left->right->opval.op == '&' &&
500 IS_AST_LIT_VALUE (expr->right)) {
502 return valForCastAggr (expr->left->right->left,
503 expr->left->left->opval.lnk,
504 expr->right, expr->opval.op);
507 /* case 4. (char *)(array type) */
508 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
509 IS_ARRAY(expr->right->ftype)) {
511 val = copyValue (AST_VALUE (expr->right));
512 val->type = newLink (DECLARATOR);
513 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
514 DCL_TYPE (val->type) = CPOINTER;
515 DCL_PTR_CONST (val->type) = port->mem.code_ro;
517 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
518 DCL_TYPE (val->type) = FPOINTER;
519 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
520 DCL_TYPE (val->type) = PPOINTER;
521 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
522 DCL_TYPE (val->type) = IPOINTER;
523 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
524 DCL_TYPE (val->type) = EEPPOINTER;
526 DCL_TYPE (val->type) = POINTER;
527 val->type->next = expr->right->ftype->next;
528 val->etype = getSpec (val->type);
534 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
536 werror (E_INCOMPAT_PTYPES);
542 /*-----------------------------------------------------------------*/
543 /* printPointerType - generates ival for pointer type */
544 /*-----------------------------------------------------------------*/
545 void _pic16_printPointerType (const char *name, char ptype, void *p)
549 sprintf(buf, "LOW(%s)", name);
550 pic16_emitDS(buf, ptype, p);
551 sprintf(buf, "HIGH(%s)", name);
552 pic16_emitDS(buf, ptype, p);
555 /*-----------------------------------------------------------------*/
556 /* printPointerType - generates ival for pointer type */
557 /*-----------------------------------------------------------------*/
558 void pic16_printPointerType (const char *name, char ptype, void *p)
560 _pic16_printPointerType (name, ptype, p);
561 pic16_flushDB(ptype, p);
564 /*-----------------------------------------------------------------*/
565 /* printGPointerType - generates ival for generic pointer type */
566 /*-----------------------------------------------------------------*/
567 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
568 const unsigned int type, char ptype, void *p)
572 _pic16_printPointerType (iname, ptype, p);
578 sprintf(buf, "UPPER(%s)", iname);
579 pic16_emitDS(buf, ptype, p);
583 sprintf(buf, "0x80");
584 pic16_emitDS(buf, ptype, p);
588 pic16_flushDB(ptype, p);
592 /* set to 0 to disable debug messages */
593 #define DEBUG_PRINTIVAL 0
595 /*-----------------------------------------------------------------*/
596 /* pic16_printIvalType - generates ival for int/char */
597 /*-----------------------------------------------------------------*/
599 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
603 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
606 fprintf(stderr, "%s\n",__FUNCTION__);
610 /* if initList is deep */
611 if (ilist && ilist->type == INIT_DEEP)
612 ilist = ilist->init.deep;
614 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
615 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
618 if (!(val = list2val (ilist))) {
619 // assuming a warning has been thrown
623 if (val->type != type) {
624 val = valCastLiteral(type, floatFromVal(val));
627 switch (getSize (type)) {
629 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
633 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
634 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
637 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
638 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
639 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
641 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
642 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
643 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
644 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
649 /*--------------------------------------------------------------------*/
650 /* pic16_printIvalChar - generates initital value for character array */
651 /*--------------------------------------------------------------------*/
653 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
662 fprintf(stderr, "%s\n",__FUNCTION__);
666 val = list2val (ilist);
667 /* if the value is a character string */
668 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
670 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
672 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; 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);
683 for(remain=0; remain<strlen(s); remain++) {
684 pic16_emitDB(s[remain], ptype, p);
690 /*-----------------------------------------------------------------*/
691 /* pic16_printIvalArray - generates code for array initialization */
692 /*-----------------------------------------------------------------*/
694 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
698 int lcnt = 0, size = 0;
705 fprintf(stderr, "%s\n",__FUNCTION__);
707 /* take care of the special case */
708 /* array of characters can be init */
710 if (IS_CHAR (type->next)) {
711 if (!IS_LITERAL(list2val(ilist)->etype)) {
712 werror (W_INIT_WRONG);
716 if(pic16_printIvalChar (type,
717 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
718 SPEC_CVAL (sym->etype).v_char, ptype, p))
721 /* not the special case */
722 if (ilist && ilist->type != INIT_DEEP)
724 werror (E_INIT_STRUCT, sym->name);
728 iloop = ilist->init.deep;
729 lcnt = DCL_ELEM (type);
734 pic16_printIval (sym, type->next, iloop, ptype, p);
735 iloop = (iloop ? iloop->next : NULL);
738 /* if not array limits given & we */
739 /* are out of initialisers then */
740 if (!DCL_ELEM (type) && !iloop)
743 /* no of elements given and we */
744 /* have generated for all of them */
746 /* if initializers left */
748 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
754 /* if we have not been given a size */
755 if (!DCL_ELEM (type))
756 DCL_ELEM (type) = size;
761 /*-----------------------------------------------------------------*/
762 /* pic16_printIvalBitFields - generate initializer for bitfields */
763 /*-----------------------------------------------------------------*/
764 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
768 initList *lilist = *ilist ;
769 unsigned long ival = 0;
774 fprintf(stderr, "%s\n",__FUNCTION__);
780 val = list2val(lilist);
782 if (SPEC_BLEN(lsym->etype) > 8) {
783 size += ((SPEC_BLEN (lsym->etype) / 8) +
784 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
787 size = ((SPEC_BLEN (lsym->etype) / 8) +
788 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
790 i = (unsigned long)floatFromVal(val);
791 i <<= SPEC_BSTR (lsym->etype);
793 if (! ( lsym->next &&
794 (IS_BITFIELD(lsym->next->type)) &&
795 (SPEC_BSTR(lsym->next->etype)))) break;
797 lilist = lilist->next;
801 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
805 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
806 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
809 case 4: /* EEP: why is this db and not dw? */
810 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
811 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
812 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
813 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
816 /* VR - only 1,2,4 size long can be handled???? Why? */
817 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
825 /*-----------------------------------------------------------------*/
826 /* printIvalStruct - generates initial value for structures */
827 /*-----------------------------------------------------------------*/
828 void pic16_printIvalStruct (symbol * sym, sym_link * type,
829 initList * ilist, char ptype, void *p)
832 initList *iloop = NULL;
836 fprintf(stderr, "%s\n",__FUNCTION__);
839 sflds = SPEC_STRUCT (type)->fields;
842 if (ilist->type != INIT_DEEP) {
843 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
847 iloop = ilist->init.deep;
850 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
851 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
852 if (IS_BITFIELD(sflds->type)) {
853 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
855 pic16_printIval (sym, sflds->type, iloop, ptype, p);
859 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
864 /*--------------------------------------------------------------------------*/
865 /* pic16_printIvalCharPtr - generates initial values for character pointers */
866 /*--------------------------------------------------------------------------*/
867 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
871 /* PENDING: this is _very_ mcs51 specific, including a magic
873 It's also endin specific.
875 VR - Attempting to port this function to pic16 port - 8-Jun-2004
880 fprintf(stderr, "%s\n",__FUNCTION__);
883 size = getSize (type);
885 if (val->name && strlen (val->name))
887 if (size == 1) /* This appears to be Z80 specific?? */
889 pic16_emitDS(val->name, ptype, p);
893 pic16_printPointerType (val->name, ptype, p);
898 if (IS_PTR (val->type)) {
899 type = DCL_TYPE (val->type);
901 type = PTR_TYPE (SPEC_OCLS (val->etype));
903 if (val->sym && val->sym->isstrlit) {
904 // this is a literal string
907 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
911 fprintf (stderr, "*** internal error: unknown size in "
912 "printIvalCharPtr.\n");
918 // these are literals assigned to pointers
922 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
925 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
926 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
929 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
930 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
931 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
939 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
940 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
941 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
947 /*-----------------------------------------------------------------------*/
948 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
949 /*-----------------------------------------------------------------------*/
950 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
957 fprintf(stderr, "%s\n",__FUNCTION__);
961 val = list2val (ilist);
963 val = valCastLiteral(type, 0.0);
966 // an error has been thrown already
970 if (IS_LITERAL(val->etype)) {
971 if (compareType(type, val->etype) == 0) {
972 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
973 printFromToType (val->type, type);
975 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
979 /* check the types */
980 if ((dLvl = compareType (val->type, type->next)) <= 0)
982 pic16_emitDB(0x00, ptype, p);
986 /* now generate the name */
988 pic16_printPointerType (val->name, ptype, p);
990 pic16_printPointerType (val->sym->rname, ptype, p);
992 if(IS_FUNC(val->sym->type) && !val->sym->used) {
994 if(!checkSym(publics, val->sym))
995 checkAddSym(&externs, val->sym);
997 /* this has not been declared as extern
998 * so declare it as a 'late extern' just after the symbol */
1000 fprintf((FILE *)p, "declare symbol as extern");
1001 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1002 fprintf((FILE *)p, "continue variable declaration");
1011 /*-----------------------------------------------------------------*/
1012 /* pic16_printIvalPtr - generates initial value for pointers */
1013 /*-----------------------------------------------------------------*/
1014 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1020 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1021 sym->rname, getSize(sym->type));
1025 if (ilist && (ilist->type == INIT_DEEP))
1026 ilist = ilist->init.deep;
1028 /* function pointer */
1029 if (IS_FUNC (type->next))
1031 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1035 if (!(val = pic16_initPointer (ilist, type)))
1038 /* if character pointer */
1039 if (IS_CHAR (type->next))
1040 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1043 /* check the type */
1044 if (compareType (type, val->type) == 0) {
1045 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1046 printFromToType (val->type, type);
1049 /* if val is literal */
1050 if (IS_LITERAL (val->etype))
1052 switch (getSize (type))
1055 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1058 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1059 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1062 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1063 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1064 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1067 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1074 size = getSize (type);
1076 if (size == 1) /* Z80 specific?? */
1078 pic16_emitDS(val->name, ptype, p);
1082 pic16_printPointerType (val->name, ptype, p);
1086 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1087 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1088 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1096 /*-----------------------------------------------------------------*/
1097 /* pic16_printIval - generates code for initial value */
1098 /*-----------------------------------------------------------------*/
1099 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1107 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1108 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1109 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1112 /* if structure then */
1113 if (IS_STRUCT (type))
1115 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1116 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1120 /* if this is an array */
1121 if (IS_ARRAY (type))
1123 // fprintf(stderr,"%s array\n",__FUNCTION__);
1124 pic16_printIvalArray (sym, type, ilist, ptype, p);
1131 // not an aggregate, ilist must be a node
1132 if (ilist->type!=INIT_NODE) {
1133 // or a 1-element list
1134 if (ilist->init.deep->next) {
1135 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1138 ilist=ilist->init.deep;
1143 // and the type must match
1144 itype=ilist->init.node->ftype;
1146 if (compareType(type, itype)==0) {
1147 // special case for literal strings
1148 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1149 // which are really code pointers
1150 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1153 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1154 // printFromToType(itype, type);
1161 /* if this is a pointer */
1164 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1165 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1170 /* if type is SPECIFIER */
1173 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1174 pic16_printIvalType (sym, type, ilist, ptype, p);
1179 int PIC16_IS_CONFIG_ADDRESS(int address)
1181 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1184 int PIC16_IS_IDLOC_ADDRESS(int address)
1186 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1189 /* wrapper function for the above */
1190 int PIC16_IS_HWREG_ADDRESS(int address)
1192 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1196 /*-----------------------------------------------------------------*/
1197 /* emitStaticSeg - emitcode for the static segment */
1198 /*-----------------------------------------------------------------*/
1200 pic16emitStaticSeg (memmap * map)
1203 static int didcode=0;
1205 //fprintf(stderr, "%s\n",__FUNCTION__);
1209 /* for all variables in this segment do */
1210 for (sym = setFirstItem (map->syms); sym;
1211 sym = setNextItem (map->syms))
1215 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1216 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1217 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1218 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1219 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1220 printTypeChain( sym->type, stderr );
1221 fprintf(stderr, "\n");
1224 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1225 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1226 (int) floatFromVal(list2val(sym->ival)));
1231 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1232 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1233 (char) floatFromVal(list2val(sym->ival)));
1238 /* if it is "extern" then do nothing */
1239 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1240 checkAddSym(&externs, sym);
1244 /* if it is not static add it to the public
1246 if (!IS_STATIC (sym->etype)) {
1247 /* do not emit if it is a config word declaration */
1248 checkAddSym(&publics, sym);
1251 /* print extra debug info if required */
1252 if (options.debug || sym->level == 0) {
1253 /* NOTE to me - cdbFile may be null in which case,
1254 * the sym name will be printed to stdout. oh well */
1255 debugFile->writeSymbol(sym);
1258 /* if it has an absolute address */
1259 if (SPEC_ABSA (sym->etype)) {
1260 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1261 // __FILE__, __LINE__, sym->name);
1263 /* if it has an initial value */
1271 /* symbol has absolute address and initial value */
1273 resolveIvalSym (sym->ival, sym->type);
1274 asym = newSymbol(sym->rname, 0);
1275 abSym = Safe_calloc(1, sizeof(absSym));
1276 strcpy(abSym->name, sym->rname);
1277 abSym->address = SPEC_ADDR( sym->etype );
1278 addSet(&absSymSet, abSym);
1280 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1281 pic16_addpBlock(pb);
1283 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1284 PCF(pcf)->absblock = 1;
1286 pic16_addpCode2pBlock(pb,pcf);
1287 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1288 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1289 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1290 pic16_flushDB('p', (void *)pb);
1292 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1298 /* symbol has absolute address but no initial value */
1300 /* allocate space */
1301 fprintf (code->oFile, "%s:\n", sym->rname);
1303 /* special case for character strings */
1304 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1305 SPEC_CVAL (sym->etype).v_char) {
1307 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1309 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1316 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1317 // __FILE__, __LINE__, sym->name);
1320 /* if it has an initial value */
1324 /* symbol doesn't have absolute address but has initial value */
1325 fprintf (code->oFile, "%s:\n", sym->rname);
1327 resolveIvalSym (sym->ival, sym->type);
1329 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1330 pic16_addpBlock(pb);
1333 /* make sure that 'code' directive is emitted before, once */
1334 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1339 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1341 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1342 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1343 pic16_flushDB('p', (void *)pb);
1347 /* symbol doesn't have absolute address and no initial value */
1348 /* allocate space */
1349 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1350 fprintf (code->oFile, "%s:\n", sym->rname);
1351 /* special case for character strings */
1352 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1353 SPEC_CVAL (sym->etype).v_char) {
1355 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1357 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1368 /*-----------------------------------------------------------------*/
1369 /* pic16_emitConfigRegs - emits the configuration registers */
1370 /*-----------------------------------------------------------------*/
1371 void pic16_emitConfigRegs(FILE *of)
1375 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1376 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1377 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1378 pic16->cwInfo.confAddrStart+i,
1379 pic16->cwInfo.crInfo[i].value);
1382 void pic16_emitIDRegs(FILE *of)
1386 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1387 if(pic16->idInfo.irInfo[i].emit)
1388 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1389 pic16->idInfo.idAddrStart+i,
1390 pic16->idInfo.irInfo[i].value);
1397 /* no special considerations for the following
1398 data, idata & bit & xdata */
1399 pic16emitRegularMap (data, TRUE, TRUE);
1400 pic16emitRegularMap (idata, TRUE, TRUE);
1401 pic16emitRegularMap (bit, TRUE, FALSE);
1402 pic16emitRegularMap (xdata, TRUE, TRUE);
1403 pic16emitRegularMap (sfr, FALSE, FALSE);
1404 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1405 pic16emitRegularMap (code, TRUE, FALSE);
1406 pic16emitStaticSeg (statsg);
1409 /*-----------------------------------------------------------------*/
1410 /* createInterruptVect - creates the interrupt vector */
1411 /*-----------------------------------------------------------------*/
1413 pic16createInterruptVect (FILE * vFile)
1415 /* if the main is only a prototype ie. no body then do nothing */
1417 if (!IFFUNC_HASBODY(mainf->type)) {
1418 /* if ! compile only then main function should be present */
1419 if (!options.cc_only)
1425 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1426 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1427 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1429 /* this is an overkill since WE are the port,
1430 * and we know if we have a genIVT function! */
1432 port->genIVT(vFile, interrupts, maxInterrupts);
1439 /*-----------------------------------------------------------------*/
1440 /* pic16initialComments - puts in some initial comments */
1441 /*-----------------------------------------------------------------*/
1443 pic16initialComments (FILE * afile)
1445 initialComments (afile);
1446 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1447 if(pic16_mplab_comp)
1448 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1449 fprintf (afile, iComments2);
1452 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1453 SDCC_VERSION_STR, getBuildNumber() );
1457 /*-----------------------------------------------------------------*/
1458 /* printPublics - generates global declarations for publics */
1459 /*-----------------------------------------------------------------*/
1461 pic16printPublics (FILE *afile)
1465 fprintf (afile, "\n%s", iComments2);
1466 fprintf (afile, "; public variables in this module\n");
1467 fprintf (afile, "%s", iComments2);
1469 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1470 fprintf(afile, "\tglobal %s\n", sym->rname);
1473 /*-----------------------------------------------------------------*/
1474 /* printExterns - generates extern declarations for externs */
1475 /*-----------------------------------------------------------------*/
1477 pic16_printExterns(FILE *afile)
1481 /* print nothing if no externs to declare */
1482 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1485 fprintf(afile, "\n%s", iComments2);
1486 fprintf(afile, "; extern variables in this module\n");
1487 fprintf(afile, "%s", iComments2);
1489 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1490 fprintf(afile, "\textern %s\n", sym->rname);
1492 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1493 fprintf(afile, "\textern _%s\n", sym->name);
1496 /*-----------------------------------------------------------------*/
1497 /* emitOverlay - will emit code for the overlay stuff */
1498 /*-----------------------------------------------------------------*/
1500 pic16emitOverlay (FILE * afile)
1504 if (!elementsInSet (ovrSetSets))
1505 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1507 /* for each of the sets in the overlay segment do */
1508 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1509 ovrset = setNextItem (ovrSetSets))
1514 if (elementsInSet (ovrset))
1516 /* this dummy area is used to fool the assembler
1517 otherwise the assembler will append each of these
1518 declarations into one chunk and will not overlay
1520 fprintf (afile, ";\t.area _DUMMY\n");
1521 /* output the area informtion */
1522 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1525 for (sym = setFirstItem (ovrset); sym;
1526 sym = setNextItem (ovrset))
1529 /* if extern then do nothing */
1530 if (IS_EXTERN (sym->etype))
1533 /* if allocation required check is needed
1534 then check if the symbol really requires
1535 allocation only for local variables */
1536 if (!IS_AGGREGATE (sym->type) &&
1537 !(sym->_isparm && !IS_REGPARM (sym->etype))
1538 && !sym->allocreq && sym->level)
1541 /* if global variable & not static or extern
1542 and addPublics allowed then add it to the public set */
1543 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1544 && !IS_STATIC (sym->etype)) {
1545 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1546 checkAddSym(&publics, sym);
1547 // addSetHead (&publics, sym);
1550 /* if extern then do nothing or is a function
1552 if (IS_FUNC (sym->type))
1556 /* print extra debug info if required */
1557 if (options.debug || sym->level == 0)
1560 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1564 if (IS_STATIC (sym->etype))
1565 fprintf (afile, "F%s_", moduleName); /* scope is file */
1567 fprintf (afile, "G_"); /* scope is global */
1570 /* symbol is local */
1571 fprintf (afile, "L%s_",
1572 (sym->localof ? sym->localof->name : "-null-"));
1573 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1577 /* if is has an absolute address then generate
1578 an equate for this no need to allocate space */
1579 if (SPEC_ABSA (sym->etype))
1582 if (options.debug || sym->level == 0)
1583 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1585 fprintf (afile, "%s\t=\t0x%04x\n",
1587 SPEC_ADDR (sym->etype));
1591 if (options.debug || sym->level == 0)
1592 fprintf (afile, "==.\n");
1594 /* allocate space */
1595 fprintf (afile, "%s:\n", sym->rname);
1596 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1604 /*-----------------------------------------------------------------*/
1605 /* glue - the final glue that hold the whole thing together */
1606 /*-----------------------------------------------------------------*/
1612 FILE *ovrFile = tempfile();
1614 mainf = newSymbol ("main", 0);
1617 mainf = findSymWithLevel(SymbolTab, mainf);
1619 addSetHead(&tmpfileSet,ovrFile);
1620 pic16_pCodeInitRegisters();
1622 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1623 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1625 pic16_addpBlock(pb);
1627 /* entry point @ start of CSEG */
1628 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1631 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1632 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1633 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1634 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1637 /* put in the call to main */
1638 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1640 if (options.mainreturn) {
1641 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1642 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1644 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1645 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1649 /* At this point we've got all the code in the form of pCode structures */
1650 /* Now it needs to be rearranged into the order it should be placed in the */
1653 pic16_movepBlock2Head('P'); // Last
1654 pic16_movepBlock2Head(code->dbName);
1655 pic16_movepBlock2Head('X');
1656 pic16_movepBlock2Head(statsg->dbName); // First
1658 /* print the global struct definitions */
1661 /* PENDING: this isnt the best place but it will do */
1662 if (port->general.glue_up_main) {
1663 /* create the interrupt vector table */
1664 pic16createInterruptVect (vFile);
1667 addSetHead(&tmpfileSet,vFile);
1669 /* emit code for the all the variables declared */
1672 /* do the overlay segments */
1673 pic16emitOverlay(ovrFile);
1674 pic16_AnalyzepCode('*');
1677 if(pic16_options.dumpcalltree) {
1680 sprintf(buffer, dstFileName);
1681 strcat(buffer, ".calltree");
1682 cFile = fopen(buffer, "w");
1683 pic16_printCallTree( cFile );
1688 pic16_InlinepCode();
1689 pic16_AnalyzepCode('*');
1692 if(pic16_debug_verbose)
1695 /* now put it all together into the assembler file */
1696 /* create the assembler file name */
1697 if((noAssemble || options.c1mode) && fullDstFileName) {
1698 sprintf (buffer, fullDstFileName);
1700 sprintf (buffer, dstFileName);
1701 strcat (buffer, ".asm");
1704 if(!(asmFile = fopen (buffer, "w"))) {
1705 werror (E_FILE_OPEN_ERR, buffer);
1709 /* initial comments */
1710 pic16initialComments (asmFile);
1712 /* print module name */
1714 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1716 /* Let the port generate any global directives, etc. */
1717 if(port->genAssemblerPreamble) {
1718 port->genAssemblerPreamble(asmFile);
1721 /* Put all variables into a cblock */
1722 pic16_AnalyzeBanking();
1724 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1725 pic16_OptimizeLocalRegs();
1728 /* print the extern variables to this module */
1729 pic16_printExterns(asmFile);
1731 /* print the global variables in this module */
1732 pic16printPublics (asmFile);
1734 pic16_writeUsedRegs(asmFile);
1737 /* no xdata in pic */
1738 /* if external stack then reserve space of it */
1739 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1740 fprintf (asmFile, "%s", iComments2);
1741 fprintf (asmFile, "; external stack \n");
1742 fprintf (asmFile, "%s", iComments2);
1743 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1744 fprintf (asmFile,";\t.ds 256\n");
1749 /* no xdata in pic */
1750 /* copy xtern ram data */
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile, "; external ram data\n");
1753 fprintf (asmFile, "%s", iComments2);
1754 copyFile (asmFile, xdata->oFile);
1758 /* copy the bit segment */
1759 fprintf (asmFile, "%s", iComments2);
1760 fprintf (asmFile, "; bit data\n");
1761 fprintf (asmFile, "%s", iComments2);
1762 copyFile (asmFile, bit->oFile);
1765 /* copy the interrupt vector table */
1766 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1767 fprintf (asmFile, "\n%s", iComments2);
1768 fprintf (asmFile, "; interrupt vector \n");
1769 fprintf (asmFile, "%s", iComments2);
1770 copyFile (asmFile, vFile);
1773 /* copy global & static initialisations */
1774 fprintf (asmFile, "\n%s", iComments2);
1775 fprintf (asmFile, "; global & static initialisations\n");
1776 fprintf (asmFile, "%s", iComments2);
1778 if(pic16_debug_verbose)
1779 fprintf(asmFile, "; A code from now on!\n");
1781 pic16_copypCode(asmFile, 'A');
1783 if(pic16_options.no_crt) {
1784 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1785 fprintf(asmFile, "\tcode\n");
1786 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1790 // copyFile (stderr, code->oFile);
1792 fprintf(asmFile, "; I code from now on!\n");
1793 pic16_copypCode(asmFile, 'I');
1795 if(pic16_debug_verbose)
1796 fprintf(asmFile, "; dbName from now on!\n");
1798 pic16_copypCode(asmFile, statsg->dbName);
1800 if(pic16_options.no_crt) {
1801 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1802 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1806 if(pic16_debug_verbose)
1807 fprintf(asmFile, "; X code from now on!\n");
1809 pic16_copypCode(asmFile, 'X');
1811 if(pic16_debug_verbose)
1812 fprintf(asmFile, "; M code from now on!\n");
1814 pic16_copypCode(asmFile, 'M');
1816 pic16_copypCode(asmFile, code->dbName);
1818 pic16_copypCode(asmFile, 'P');
1820 fprintf (asmFile,"\tend\n");