1 /*-------------------------------------------------------------------------
3 glue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #include "../common.h"
38 #ifdef WORDS_BIGENDIAN
39 #define _ENDIAN(x) (3-x)
41 #define _ENDIAN(x) (x)
44 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
46 extern symbol *interrupts[256];
47 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
51 extern unsigned maxInterrupts;
52 extern int maxRegBank;
54 extern char *VersionString;
55 extern FILE *codeOutFile;
56 extern set *tmpfileSet;
57 extern set *tmpfileNameSet;
58 extern char *iComments1;
59 extern char *iComments2;
62 extern unsigned long pFile_isize;
64 extern unsigned long pic16_countInstructions();
65 set *rel_idataSymSet=NULL;
66 set *fix_idataSymSet=NULL;
68 extern DEFSETFUNC (closeTmpFiles);
69 extern DEFSETFUNC (rmTmpFiles);
71 extern void pic16_AnalyzeBanking (void);
72 extern void copyFile (FILE * dest, FILE * src);
73 extern void pic16_InlinepCode(void);
74 extern void pic16_writeUsedRegs(FILE *);
76 extern void initialComments (FILE * afile);
77 extern void printPublics (FILE * afile);
79 void pic16_pCodeInitRegisters(void);
80 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
81 extern void pic16_pCodeConstString(char *name, char *value);
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)
183 #define SET_IMPLICIT 1
186 if(IS_STRUCT(sym->type))
190 reg = pic16_allocDirReg( operandFromSymbol( sym ));
194 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
195 if(!strcmp(ssym->name, reg->name))found=1;
199 checkAddReg(&pic16_rel_udata, reg);
201 checkAddSym(&publics, sym);
206 /* if extern then do nothing or is a function
208 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
209 if(SPEC_OCLS(sym->etype) == code) {
210 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
211 checkAddSym(&publics, sym);
217 /* print extra debug info if required */
218 if (options.debug || sym->level == 0) {
219 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
221 if (!sym->level) /* global */
222 if (IS_STATIC (sym->etype))
223 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
225 fprintf (map->oFile, "G_"); /* scope is global */
227 /* symbol is local */
228 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
229 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
234 /* if is has an absolute address then generate
235 an equate for this no need to allocate space */
236 if (SPEC_ABSA (sym->etype)) {
237 // if (options.debug || sym->level == 0)
238 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
239 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
241 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
243 SPEC_ADDR (sym->etype));
245 /* emit only if it is global */
246 if(sym->level == 0) {
249 reg = pic16_dirregWithName( sym->name );
252 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
253 // __FUNCTION__, __LINE__, sym->name);
255 /* if IS_STRUCT is omitted the following
256 * fixes structures but break char/int etc */
258 if(IS_STRUCT(sym->type))
259 sym->implicit = 1; // mark as implicit
262 reg = pic16_allocDirReg( operandFromSymbol(sym) );
264 if(checkAddReg(&pic16_fix_udata, reg)) {
265 /* and add to globals list if not exist */
266 addSet(&publics, sym);
270 addSet(&publics, sym);
274 if(!sym->used && (sym->level == 0)) {
277 /* symbol not used, just declared probably, but its in
278 * level 0, so we must declare it fine as global */
280 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
283 if(IS_STRUCT(sym->type))
284 sym->implicit = 1; // mark as implicit
287 if(IS_AGGREGATE(sym->type)) {
288 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
290 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
298 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
299 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
303 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
304 if(!strcmp(ssym->name, reg->name))found=1;
308 if(checkAddReg(&pic16_rel_udata, reg)) {
309 addSetHead(&publics, sym);
318 addSetHead(&publics, sym);
323 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
324 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
325 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
326 if (IS_BITVAR (sym->etype)) {
329 fprintf (map->oFile, "\t%s\n", sym->rname);
330 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
331 for (i = 1; i < size; i++)
332 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
335 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
339 /* FIXME -- VR Fix the following, so that syms to be placed
340 * in the idata section and let linker decide about their fate */
342 /* if it has an initial value then do it only if
343 it is a global variable */
345 if (sym->ival && sym->level == 0) {
349 if(SPEC_OCLS(sym->etype)==data) {
350 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
353 if(SPEC_OCLS(sym->etype)==code) {
354 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
359 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
360 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
363 if (IS_AGGREGATE (sym->type)) {
364 if(SPEC_ABSA(sym->etype))
365 addSet(&fix_idataSymSet, copySymbol(sym));
367 addSet(&rel_idataSymSet, copySymbol(sym));
368 // ival = initAggregates (sym, sym->ival, NULL);
370 if(SPEC_ABSA(sym->etype))
371 addSet(&fix_idataSymSet, copySymbol(sym));
373 addSet(&rel_idataSymSet, copySymbol(sym));
375 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
376 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
380 setAstLineno(ival, sym->lineDef);
381 codeOutFile = statsg->oFile;
383 eBBlockFromiCode (iCodeFromAst (ival));
391 /*-----------------------------------------------------------------*/
392 /* pic16_initPointer - pointer initialization code massaging */
393 /*-----------------------------------------------------------------*/
394 value *pic16_initPointer (initList * ilist, sym_link *toType)
400 return valCastLiteral(toType, 0.0);
403 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
404 // expr = list2expr( ilist );
409 /* try it the old way first */
410 if ((val = constExprValue (expr, FALSE)))
413 /* ( ptr + constant ) */
414 if (IS_AST_OP (expr) &&
415 (expr->opval.op == '+' || expr->opval.op == '-') &&
416 IS_AST_SYM_VALUE (expr->left) &&
417 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
418 compareType(toType, expr->left->ftype) &&
419 IS_AST_LIT_VALUE (expr->right)) {
420 return valForCastAggr (expr->left, expr->left->ftype,
426 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
427 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
428 if (compareType(toType, expr->left->ftype)!=1) {
429 werror (W_INIT_WRONG);
430 printFromToType(expr->left->ftype, toType);
436 /* no then we have to do these cludgy checks */
437 /* pointers can be initialized with address of
438 a variable or address of an array element */
439 if (IS_AST_OP (expr) && expr->opval.op == '&') {
440 /* address of symbol */
441 if (IS_AST_SYM_VALUE (expr->left)) {
442 val = copyValue (AST_VALUE (expr->left));
443 val->type = newLink (DECLARATOR);
444 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
445 DCL_TYPE (val->type) = CPOINTER;
446 DCL_PTR_CONST (val->type) = port->mem.code_ro;
448 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
449 DCL_TYPE (val->type) = FPOINTER;
450 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
451 DCL_TYPE (val->type) = PPOINTER;
452 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
453 DCL_TYPE (val->type) = IPOINTER;
454 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
455 DCL_TYPE (val->type) = EEPPOINTER;
457 DCL_TYPE (val->type) = POINTER;
459 val->type->next = expr->left->ftype;
460 val->etype = getSpec (val->type);
464 /* if address of indexed array */
465 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
466 return valForArray (expr->left);
468 /* if address of structure element then
470 if (IS_AST_OP (expr->left) &&
471 expr->left->opval.op == '.') {
472 return valForStructElem (expr->left->left,
477 (&some_struct)->element */
478 if (IS_AST_OP (expr->left) &&
479 expr->left->opval.op == PTR_OP &&
480 IS_ADDRESS_OF_OP (expr->left->left)) {
481 return valForStructElem (expr->left->left->left,
485 /* case 3. (((char *) &a) +/- constant) */
486 if (IS_AST_OP (expr) &&
487 (expr->opval.op == '+' || expr->opval.op == '-') &&
488 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
489 IS_AST_OP (expr->left->right) &&
490 expr->left->right->opval.op == '&' &&
491 IS_AST_LIT_VALUE (expr->right)) {
493 return valForCastAggr (expr->left->right->left,
494 expr->left->left->opval.lnk,
495 expr->right, expr->opval.op);
498 /* case 4. (char *)(array type) */
499 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
500 IS_ARRAY(expr->right->ftype)) {
502 val = copyValue (AST_VALUE (expr->right));
503 val->type = newLink (DECLARATOR);
504 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
505 DCL_TYPE (val->type) = CPOINTER;
506 DCL_PTR_CONST (val->type) = port->mem.code_ro;
508 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
509 DCL_TYPE (val->type) = FPOINTER;
510 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
511 DCL_TYPE (val->type) = PPOINTER;
512 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
513 DCL_TYPE (val->type) = IPOINTER;
514 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
515 DCL_TYPE (val->type) = EEPPOINTER;
517 DCL_TYPE (val->type) = POINTER;
518 val->type->next = expr->right->ftype->next;
519 val->etype = getSpec (val->type);
525 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
527 werror (E_INCOMPAT_PTYPES);
533 /*-----------------------------------------------------------------*/
534 /* printPointerType - generates ival for pointer type */
535 /*-----------------------------------------------------------------*/
536 void _pic16_printPointerType (const char *name, char ptype, void *p)
540 sprintf(buf, "LOW(%s)", name);
541 pic16_emitDS(buf, ptype, p);
542 sprintf(buf, "HIGH(%s)", name);
543 pic16_emitDS(buf, ptype, p);
546 /*-----------------------------------------------------------------*/
547 /* printPointerType - generates ival for pointer type */
548 /*-----------------------------------------------------------------*/
549 void pic16_printPointerType (const char *name, char ptype, void *p)
551 _pic16_printPointerType (name, ptype, p);
552 pic16_flushDB(ptype, p);
555 /*-----------------------------------------------------------------*/
556 /* printGPointerType - generates ival for generic pointer type */
557 /*-----------------------------------------------------------------*/
558 void pic16_printGPointerType (const char *iname, const unsigned int itype,
563 _pic16_printPointerType (iname, ptype, p);
570 sprintf(buf, "UPPER(%s)", iname);
571 pic16_emitDS(buf, ptype, p);
575 sprintf(buf, "0x80");
576 pic16_emitDS(buf, ptype, p);
579 // debugf("itype = %d\n", itype );
583 pic16_flushDB(ptype, p);
587 /* set to 0 to disable debug messages */
588 #define DEBUG_PRINTIVAL 0
590 /*-----------------------------------------------------------------*/
591 /* pic16_printIvalType - generates ival for int/char */
592 /*-----------------------------------------------------------------*/
594 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
598 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
601 fprintf(stderr, "%s\n",__FUNCTION__);
605 /* if initList is deep */
606 if (ilist && ilist->type == INIT_DEEP)
607 ilist = ilist->init.deep;
609 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
610 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
613 if (!(val = list2val (ilist))) {
614 // assuming a warning has been thrown
618 if (val->type != type) {
619 val = valCastLiteral(type, floatFromVal(val));
622 switch (getSize (type)) {
624 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
628 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
629 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
632 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
633 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
634 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
636 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
637 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
638 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
639 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
644 /*--------------------------------------------------------------------*/
645 /* pic16_printIvalChar - generates initital value for character array */
646 /*--------------------------------------------------------------------*/
648 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
657 fprintf(stderr, "%s\n",__FUNCTION__);
661 val = list2val (ilist);
662 /* if the value is a character string */
663 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
665 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
667 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
668 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
670 if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
672 pic16_emitDB(0x00, ptype, p);
678 for(remain=0; remain<strlen(s); remain++) {
679 pic16_emitDB(s[remain], ptype, p);
685 /*-----------------------------------------------------------------*/
686 /* pic16_printIvalArray - generates code for array initialization */
687 /*-----------------------------------------------------------------*/
689 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
693 int lcnt = 0, size = 0;
700 fprintf(stderr, "%s\n",__FUNCTION__);
702 /* take care of the special case */
703 /* array of characters can be init */
705 if (IS_CHAR (type->next)) {
706 if (!IS_LITERAL(list2val(ilist)->etype)) {
707 werror (W_INIT_WRONG);
711 if(pic16_printIvalChar (type,
712 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
713 SPEC_CVAL (sym->etype).v_char, ptype, p))
716 /* not the special case */
717 if (ilist && ilist->type != INIT_DEEP)
719 werror (E_INIT_STRUCT, sym->name);
723 iloop = ilist->init.deep;
724 lcnt = DCL_ELEM (type);
729 pic16_printIval (sym, type->next, iloop, ptype, p);
730 iloop = (iloop ? iloop->next : NULL);
733 /* if not array limits given & we */
734 /* are out of initialisers then */
735 if (!DCL_ELEM (type) && !iloop)
738 /* no of elements given and we */
739 /* have generated for all of them */
741 /* if initializers left */
743 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
749 /* if we have not been given a size */
750 if (!DCL_ELEM (type))
751 DCL_ELEM (type) = size;
756 /*-----------------------------------------------------------------*/
757 /* pic16_printIvalBitFields - generate initializer for bitfields */
758 /*-----------------------------------------------------------------*/
759 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
763 initList *lilist = *ilist ;
764 unsigned long ival = 0;
769 fprintf(stderr, "%s\n",__FUNCTION__);
775 val = list2val(lilist);
777 if (SPEC_BLEN(lsym->etype) > 8) {
778 size += ((SPEC_BLEN (lsym->etype) / 8) +
779 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
782 size = ((SPEC_BLEN (lsym->etype) / 8) +
783 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
785 i = (unsigned long)floatFromVal(val);
786 i <<= SPEC_BSTR (lsym->etype);
788 if (! ( lsym->next &&
789 (IS_BITFIELD(lsym->next->type)) &&
790 (SPEC_BSTR(lsym->next->etype)))) break;
792 lilist = lilist->next;
796 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
800 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
801 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
804 case 4: /* EEP: why is this db and not dw? */
805 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
806 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
807 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
808 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
811 /* VR - only 1,2,4 size long can be handled???? Why? */
812 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
820 /*-----------------------------------------------------------------*/
821 /* printIvalStruct - generates initial value for structures */
822 /*-----------------------------------------------------------------*/
823 void pic16_printIvalStruct (symbol * sym, sym_link * type,
824 initList * ilist, char ptype, void *p)
827 initList *iloop = NULL;
831 fprintf(stderr, "%s\n",__FUNCTION__);
834 sflds = SPEC_STRUCT (type)->fields;
837 if (ilist->type != INIT_DEEP) {
838 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
842 iloop = ilist->init.deep;
845 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
846 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
847 if (IS_BITFIELD(sflds->type)) {
848 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
850 pic16_printIval (sym, sflds->type, iloop, ptype, p);
854 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
859 /*--------------------------------------------------------------------------*/
860 /* pic16_printIvalCharPtr - generates initial values for character pointers */
861 /*--------------------------------------------------------------------------*/
862 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
866 /* PENDING: this is _very_ mcs51 specific, including a magic
868 It's also endin specific.
870 VR - Attempting to port this function to pic16 port - 8-Jun-2004
875 fprintf(stderr, "%s\n",__FUNCTION__);
878 size = getSize (type);
880 if (val->name && strlen (val->name))
882 if (size == 1) /* This appears to be Z80 specific?? */
884 pic16_emitDS(val->name, ptype, p);
888 pic16_printPointerType (val->name, ptype, p);
893 if (IS_PTR (val->type)) {
894 type = DCL_TYPE (val->type);
896 type = PTR_TYPE (SPEC_OCLS (val->etype));
898 if (val->sym && val->sym->isstrlit) {
899 // this is a literal string
902 pic16_printGPointerType(val->name, type, ptype, p);
906 fprintf (stderr, "*** internal error: unknown size in "
907 "printIvalCharPtr.\n");
913 // these are literals assigned to pointers
917 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
920 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
921 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
924 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
925 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
926 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
934 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
935 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
936 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
942 /*-----------------------------------------------------------------------*/
943 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
944 /*-----------------------------------------------------------------------*/
945 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
952 fprintf(stderr, "%s\n",__FUNCTION__);
956 val = list2val (ilist);
958 val = valCastLiteral(type, 0.0);
961 // an error has been thrown already
965 if (IS_LITERAL(val->etype)) {
966 if (compareType(type, val->etype) == 0) {
967 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
968 printFromToType (val->type, type);
970 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
974 /* check the types */
975 if ((dLvl = compareType (val->type, type->next)) <= 0)
977 pic16_emitDB(0x00, ptype, p);
981 /* now generate the name */
983 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
985 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
987 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
989 if(!checkSym(publics, val->sym))
990 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
991 /* this has not been declared as extern
992 * so declare it as a 'late extern' just after the symbol */
993 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
994 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
995 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
1004 /*-----------------------------------------------------------------*/
1005 /* pic16_printIvalPtr - generates initial value for pointers */
1006 /*-----------------------------------------------------------------*/
1007 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1013 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1014 sym->rname, getSize(sym->type));
1018 if (ilist && (ilist->type == INIT_DEEP))
1019 ilist = ilist->init.deep;
1021 /* function pointer */
1022 if (IS_FUNC (type->next))
1024 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1028 if (!(val = pic16_initPointer (ilist, type)))
1031 /* if character pointer */
1032 if (IS_CHAR (type->next))
1033 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1036 /* check the type */
1037 if (compareType (type, val->type) == 0) {
1038 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1039 printFromToType (val->type, type);
1042 /* if val is literal */
1043 if (IS_LITERAL (val->etype))
1045 switch (getSize (type))
1048 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1051 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1052 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1055 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1056 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1057 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1060 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1067 size = getSize (type);
1069 if (size == 1) /* Z80 specific?? */
1071 pic16_emitDS(val->name, ptype, p);
1075 pic16_printPointerType (val->name, ptype, p);
1079 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1088 /*-----------------------------------------------------------------*/
1089 /* pic16_printIval - generates code for initial value */
1090 /*-----------------------------------------------------------------*/
1091 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1099 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1100 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1101 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1104 /* if structure then */
1105 if (IS_STRUCT (type))
1107 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1108 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1112 /* if this is an array */
1113 if (IS_ARRAY (type))
1115 // fprintf(stderr,"%s array\n",__FUNCTION__);
1116 pic16_printIvalArray (sym, type, ilist, ptype, p);
1123 // not an aggregate, ilist must be a node
1124 if (ilist->type!=INIT_NODE) {
1125 // or a 1-element list
1126 if (ilist->init.deep->next) {
1127 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1130 ilist=ilist->init.deep;
1135 // and the type must match
1136 itype=ilist->init.node->ftype;
1138 if (compareType(type, itype)==0) {
1139 // special case for literal strings
1140 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1141 // which are really code pointers
1142 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1145 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1146 // printFromToType(itype, type);
1153 /* if this is a pointer */
1156 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1157 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1162 /* if type is SPECIFIER */
1165 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1166 pic16_printIvalType (sym, type, ilist, ptype, p);
1171 int PIC16_IS_CONFIG_ADDRESS(int address)
1173 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1176 int PIC16_IS_IDLOC_ADDRESS(int address)
1178 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1181 /* wrapper function for the above */
1182 int PIC16_IS_HWREG_ADDRESS(int address)
1184 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1188 /*-----------------------------------------------------------------*/
1189 /* emitStaticSeg - emitcode for the static segment */
1190 /*-----------------------------------------------------------------*/
1192 pic16emitStaticSeg (memmap * map)
1195 static int didcode=0;
1197 //fprintf(stderr, "%s\n",__FUNCTION__);
1201 /* for all variables in this segment do */
1202 for (sym = setFirstItem (map->syms); sym;
1203 sym = setNextItem (map->syms))
1207 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1208 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1209 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1210 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1211 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1212 printTypeChain( sym->type, stderr );
1213 fprintf(stderr, "\n");
1216 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1217 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1218 (int) floatFromVal(list2val(sym->ival)));
1223 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1224 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1225 (char) floatFromVal(list2val(sym->ival)));
1230 /* if it is "extern" then do nothing */
1231 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1232 checkAddSym(&externs, sym);
1236 /* if it is not static add it to the public
1238 if (!IS_STATIC (sym->etype)) {
1239 /* do not emit if it is a config word declaration */
1240 checkAddSym(&publics, sym);
1243 /* print extra debug info if required */
1244 if (options.debug || sym->level == 0) {
1245 /* NOTE to me - cdbFile may be null in which case,
1246 * the sym name will be printed to stdout. oh well */
1247 debugFile->writeSymbol(sym);
1250 /* if it has an absolute address */
1251 if (SPEC_ABSA (sym->etype)) {
1252 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1253 // __FILE__, __LINE__, sym->name);
1255 /* if it has an initial value */
1263 /* symbol has absolute address and initial value */
1265 resolveIvalSym (sym->ival, sym->type);
1266 asym = newSymbol(sym->rname, 0);
1267 abSym = Safe_calloc(1, sizeof(absSym));
1268 strcpy(abSym->name, sym->rname);
1269 abSym->address = SPEC_ADDR( sym->etype );
1270 addSet(&absSymSet, abSym);
1272 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1273 pic16_addpBlock(pb);
1275 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1276 PCF(pcf)->absblock = 1;
1278 pic16_addpCode2pBlock(pb,pcf);
1279 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1280 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1281 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1282 pic16_flushDB('p', (void *)pb);
1284 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1290 /* symbol has absolute address but no initial value */
1292 /* allocate space */
1293 fprintf (code->oFile, "%s:\n", sym->rname);
1295 /* special case for character strings */
1296 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1297 SPEC_CVAL (sym->etype).v_char) {
1299 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1301 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1308 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1309 // __FILE__, __LINE__, sym->name);
1312 /* if it has an initial value */
1316 /* symbol doesn't have absolute address but has initial value */
1317 fprintf (code->oFile, "%s:\n", sym->rname);
1319 resolveIvalSym (sym->ival, sym->type);
1321 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1322 pic16_addpBlock(pb);
1325 /* make sure that 'code' directive is emitted before, once */
1326 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1331 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1333 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1334 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1335 pic16_flushDB('p', (void *)pb);
1339 /* symbol doesn't have absolute address and no initial value */
1340 /* allocate space */
1341 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1342 fprintf (code->oFile, "%s:\n", sym->rname);
1343 /* special case for character strings */
1344 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1345 SPEC_CVAL (sym->etype).v_char) {
1347 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1349 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1360 /*-----------------------------------------------------------------*/
1361 /* pic16_emitConfigRegs - emits the configuration registers */
1362 /*-----------------------------------------------------------------*/
1363 void pic16_emitConfigRegs(FILE *of)
1367 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1368 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1369 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1370 pic16->cwInfo.confAddrStart+i,
1371 pic16->cwInfo.crInfo[i].value);
1374 void pic16_emitIDRegs(FILE *of)
1378 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1379 if(pic16->idInfo.irInfo[i].emit)
1380 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1381 pic16->idInfo.idAddrStart+i,
1382 pic16->idInfo.irInfo[i].value);
1389 /* no special considerations for the following
1390 data, idata & bit & xdata */
1391 pic16emitRegularMap (data, TRUE, TRUE);
1392 pic16emitRegularMap (idata, TRUE, TRUE);
1393 pic16emitRegularMap (bit, TRUE, FALSE);
1394 pic16emitRegularMap (xdata, TRUE, TRUE);
1395 pic16emitRegularMap (sfr, FALSE, FALSE);
1396 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1397 pic16emitRegularMap (code, TRUE, FALSE);
1398 pic16emitStaticSeg (statsg);
1401 /*-----------------------------------------------------------------*/
1402 /* createInterruptVect - creates the interrupt vector */
1403 /*-----------------------------------------------------------------*/
1405 pic16createInterruptVect (FILE * vFile)
1407 /* if the main is only a prototype ie. no body then do nothing */
1409 if (!IFFUNC_HASBODY(mainf->type)) {
1410 /* if ! compile only then main function should be present */
1411 if (!options.cc_only)
1417 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1418 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1419 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1421 /* this is an overkill since WE are the port,
1422 * and we know if we have a genIVT function! */
1424 port->genIVT(vFile, interrupts, maxInterrupts);
1431 /*-----------------------------------------------------------------*/
1432 /* pic16initialComments - puts in some initial comments */
1433 /*-----------------------------------------------------------------*/
1435 pic16initialComments (FILE * afile)
1437 initialComments (afile);
1438 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1439 if(pic16_mplab_comp)
1440 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1441 fprintf (afile, iComments2);
1444 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1445 SDCC_VERSION_STR, getBuildNumber() );
1449 /*-----------------------------------------------------------------*/
1450 /* printPublics - generates global declarations for publics */
1451 /*-----------------------------------------------------------------*/
1453 pic16printPublics (FILE *afile)
1457 fprintf (afile, "\n%s", iComments2);
1458 fprintf (afile, "; public variables in this module\n");
1459 fprintf (afile, "%s", iComments2);
1461 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1462 fprintf(afile, "\tglobal %s\n", sym->rname);
1465 /*-----------------------------------------------------------------*/
1466 /* printExterns - generates extern declarations for externs */
1467 /*-----------------------------------------------------------------*/
1469 pic16_printExterns(FILE *afile)
1473 /* print nothing if no externs to declare */
1474 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1477 fprintf(afile, "\n%s", iComments2);
1478 fprintf(afile, "; extern variables in this module\n");
1479 fprintf(afile, "%s", iComments2);
1481 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1482 fprintf(afile, "\textern %s\n", sym->rname);
1484 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1485 fprintf(afile, "\textern _%s\n", sym->name);
1488 /*-----------------------------------------------------------------*/
1489 /* emitOverlay - will emit code for the overlay stuff */
1490 /*-----------------------------------------------------------------*/
1492 pic16emitOverlay (FILE * afile)
1496 if (!elementsInSet (ovrSetSets))
1497 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1499 /* for each of the sets in the overlay segment do */
1500 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1501 ovrset = setNextItem (ovrSetSets))
1506 if (elementsInSet (ovrset))
1508 /* this dummy area is used to fool the assembler
1509 otherwise the assembler will append each of these
1510 declarations into one chunk and will not overlay
1512 fprintf (afile, ";\t.area _DUMMY\n");
1513 /* output the area informtion */
1514 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1517 for (sym = setFirstItem (ovrset); sym;
1518 sym = setNextItem (ovrset))
1521 /* if extern then do nothing */
1522 if (IS_EXTERN (sym->etype))
1525 /* if allocation required check is needed
1526 then check if the symbol really requires
1527 allocation only for local variables */
1528 if (!IS_AGGREGATE (sym->type) &&
1529 !(sym->_isparm && !IS_REGPARM (sym->etype))
1530 && !sym->allocreq && sym->level)
1533 /* if global variable & not static or extern
1534 and addPublics allowed then add it to the public set */
1535 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1536 && !IS_STATIC (sym->etype)) {
1537 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1538 checkAddSym(&publics, sym);
1539 // addSetHead (&publics, sym);
1542 /* if extern then do nothing or is a function
1544 if (IS_FUNC (sym->type))
1548 /* print extra debug info if required */
1549 if (options.debug || sym->level == 0)
1552 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1556 if (IS_STATIC (sym->etype))
1557 fprintf (afile, "F%s_", moduleName); /* scope is file */
1559 fprintf (afile, "G_"); /* scope is global */
1562 /* symbol is local */
1563 fprintf (afile, "L%s_",
1564 (sym->localof ? sym->localof->name : "-null-"));
1565 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1569 /* if is has an absolute address then generate
1570 an equate for this no need to allocate space */
1571 if (SPEC_ABSA (sym->etype))
1574 if (options.debug || sym->level == 0)
1575 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1577 fprintf (afile, "%s\t=\t0x%04x\n",
1579 SPEC_ADDR (sym->etype));
1583 if (options.debug || sym->level == 0)
1584 fprintf (afile, "==.\n");
1586 /* allocate space */
1587 fprintf (afile, "%s:\n", sym->rname);
1588 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1595 void emitStatistics(FILE *asmFile)
1597 statistics.isize = pic16_countInstructions();
1599 fprintf (asmFile, "\n\n; Statistics:\n");
1600 fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
1601 statistics.isize, statistics.isize,
1602 statistics.isize>>1, statistics.isize>>1);
1603 fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n",
1604 statistics.udsize, statistics.udsize);
1605 fprintf (asmFile, "; access size:\t%ld (0x%lx) bytes\n",
1606 statistics.intsize, statistics.intsize);
1608 fprintf (asmFile, "\n\n");
1613 /*-----------------------------------------------------------------*/
1614 /* glue - the final glue that hold the whole thing together */
1615 /*-----------------------------------------------------------------*/
1621 FILE *ovrFile = tempfile();
1623 mainf = newSymbol ("main", 0);
1626 mainf = findSymWithLevel(SymbolTab, mainf);
1628 addSetHead(&tmpfileSet,ovrFile);
1629 pic16_pCodeInitRegisters();
1631 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1632 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1634 pic16_addpBlock(pb);
1636 /* entry point @ start of CSEG */
1637 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1640 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1641 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1642 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1643 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1646 /* put in the call to main */
1647 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1649 if (options.mainreturn) {
1650 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1651 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1653 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1654 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1658 /* At this point we've got all the code in the form of pCode structures */
1659 /* Now it needs to be rearranged into the order it should be placed in the */
1662 pic16_movepBlock2Head('P'); // Last
1663 pic16_movepBlock2Head(code->dbName);
1664 pic16_movepBlock2Head('X');
1665 pic16_movepBlock2Head(statsg->dbName); // First
1667 /* print the global struct definitions */
1670 /* PENDING: this isnt the best place but it will do */
1671 if (port->general.glue_up_main) {
1672 /* create the interrupt vector table */
1673 pic16createInterruptVect (vFile);
1676 addSetHead(&tmpfileSet,vFile);
1678 /* emit code for the all the variables declared */
1681 /* do the overlay segments */
1682 pic16emitOverlay(ovrFile);
1683 pic16_AnalyzepCode('*');
1686 if(pic16_options.dumpcalltree) {
1689 sprintf(buffer, dstFileName);
1690 strcat(buffer, ".calltree");
1691 cFile = fopen(buffer, "w");
1692 pic16_printCallTree( cFile );
1697 pic16_InlinepCode();
1698 pic16_AnalyzepCode('*');
1701 if(pic16_debug_verbose)
1704 /* now put it all together into the assembler file */
1705 /* create the assembler file name */
1706 if((noAssemble || options.c1mode) && fullDstFileName) {
1707 sprintf (buffer, fullDstFileName);
1709 sprintf (buffer, dstFileName);
1710 strcat (buffer, ".asm");
1713 if(!(asmFile = fopen (buffer, "w"))) {
1714 werror (E_FILE_OPEN_ERR, buffer);
1718 /* initial comments */
1719 pic16initialComments (asmFile);
1721 /* print module name */
1723 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1725 /* Let the port generate any global directives, etc. */
1726 if(port->genAssemblerPreamble) {
1727 port->genAssemblerPreamble(asmFile);
1730 /* Put all variables into a cblock */
1731 pic16_AnalyzeBanking();
1733 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1734 pic16_OptimizeLocalRegs();
1737 /* print the extern variables to this module */
1738 pic16_printExterns(asmFile);
1740 /* print the global variables in this module */
1741 pic16printPublics (asmFile);
1743 pic16_writeUsedRegs(asmFile);
1746 /* no xdata in pic */
1747 /* if external stack then reserve space of it */
1748 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1749 fprintf (asmFile, "%s", iComments2);
1750 fprintf (asmFile, "; external stack \n");
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1753 fprintf (asmFile,";\t.ds 256\n");
1758 /* no xdata in pic */
1759 /* copy xtern ram data */
1760 fprintf (asmFile, "%s", iComments2);
1761 fprintf (asmFile, "; external ram data\n");
1762 fprintf (asmFile, "%s", iComments2);
1763 copyFile (asmFile, xdata->oFile);
1767 /* copy the bit segment */
1768 fprintf (asmFile, "%s", iComments2);
1769 fprintf (asmFile, "; bit data\n");
1770 fprintf (asmFile, "%s", iComments2);
1771 copyFile (asmFile, bit->oFile);
1774 /* copy the interrupt vector table */
1775 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1776 fprintf (asmFile, "\n%s", iComments2);
1777 fprintf (asmFile, "; interrupt vector \n");
1778 fprintf (asmFile, "%s", iComments2);
1779 copyFile (asmFile, vFile);
1782 /* copy global & static initialisations */
1783 fprintf (asmFile, "\n%s", iComments2);
1784 fprintf (asmFile, "; global & static initialisations\n");
1785 fprintf (asmFile, "%s", iComments2);
1787 if(pic16_debug_verbose)
1788 fprintf(asmFile, "; A code from now on!\n");
1790 pic16_copypCode(asmFile, 'A');
1792 if(pic16_options.no_crt) {
1793 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1794 fprintf(asmFile, "\tcode\n");
1795 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1799 // copyFile (stderr, code->oFile);
1801 fprintf(asmFile, "; I code from now on!\n");
1802 pic16_copypCode(asmFile, 'I');
1804 if(pic16_debug_verbose)
1805 fprintf(asmFile, "; dbName from now on!\n");
1807 pic16_copypCode(asmFile, statsg->dbName);
1809 if(pic16_options.no_crt) {
1810 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1811 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1815 if(pic16_debug_verbose)
1816 fprintf(asmFile, "; X code from now on!\n");
1818 pic16_copypCode(asmFile, 'X');
1820 if(pic16_debug_verbose)
1821 fprintf(asmFile, "; M code from now on!\n");
1823 pic16_copypCode(asmFile, 'M');
1825 pic16_copypCode(asmFile, code->dbName);
1827 pic16_copypCode(asmFile, 'P');
1829 emitStatistics(asmFile);
1831 fprintf (asmFile,"\tend\n");