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"
33 #include "dbuf_string.h"
37 extern symbol *interrupts[256];
38 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
42 extern unsigned maxInterrupts;
44 extern char *VersionString;
45 extern struct dbuf_s *codeOutBuf;
46 extern char *iComments1;
47 extern char *iComments2;
50 extern unsigned long pFile_isize;
52 extern unsigned long pic16_countInstructions();
53 set *pic16_localFunctions = NULL;
54 set *rel_idataSymSet=NULL;
55 set *fix_idataSymSet=NULL;
57 extern DEFSETFUNC (closeTmpFiles);
58 extern DEFSETFUNC (rmTmpFiles);
60 extern void pic16_AnalyzeBanking (void);
61 extern void pic16_OptimizeJumps ();
62 extern void pic16_OptimizeBanksel ();
63 extern void pic16_InlinepCode(void);
64 extern void pic16_writeUsedRegs(FILE *);
66 extern void initialComments (FILE * afile);
67 extern void printPublics (FILE * afile);
69 void pic16_pCodeInitRegisters(void);
70 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
71 extern void pic16_pCodeConstString(char *name, char *value, unsigned length);
74 /*-----------------------------------------------------------------*/
75 /* aopLiteral - string from a literal value */
76 /*-----------------------------------------------------------------*/
77 unsigned int pic16aopLiteral (value *val, int offset)
84 /* if it is a float then it gets tricky */
85 /* otherwise it is fairly simple */
86 if (!(IS_FLOAT(val->type) || IS_FIXED(val->type))) {
87 unsigned long v = ulFromVal (val);
89 return ( (v >> (offset * 8)) & 0xff);
92 if(IS_FIXED16X16(val->type)) {
93 unsigned long v = (unsigned long)fixed16x16FromDouble( floatFromVal( val ) );
95 return ( (v >> (offset * 8)) & 0xff);
98 /* it is type float */
99 fl.f = (float) floatFromVal(val);
100 #ifdef WORDS_BIGENDIAN
101 return fl.c[3-offset];
110 char tbuffer[512], *tbuf=tbuffer;;
113 /*-----------------------------------------------------------------*/
114 /* emitRegularMap - emit code for maps with no special cases */
115 /*-----------------------------------------------------------------*/
117 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
120 // int i, size, bitvars = 0;;
122 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
125 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
126 /* print the area name */
128 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
131 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
133 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
134 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
135 printTypeChain( sym->type, stderr );
136 fprintf(stderr, "\n");
139 /* if extern then add to externs */
140 if (IS_EXTERN (sym->etype)) {
141 /* reduce overhead while linking by not declaring
142 * extern unused external functions (usually declared
143 * in header files) */
144 if(IS_FUNC(sym->type) && !sym->used)continue;
146 /* make sure symbol is not in publics section */
147 if(!checkSym(publics, sym))
148 checkAddSym(&externs, sym);
152 /* if allocation required check is needed
153 * then check if the symbol really requires
154 * allocation only for local variables */
155 if (arFlag && !IS_AGGREGATE (sym->type) &&
156 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
157 !sym->allocreq && sym->level) {
159 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
164 /* if global variable & not static or extern
165 * and addPublics allowed then add it to the public set */
166 if ((sym->used) && (sym->level == 0 ||
167 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
169 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
171 checkAddSym(&publics, sym);
174 if(IS_STATIC(sym->etype)
175 && !sym->ival) /* && !sym->level*/ {
180 // debugf("adding symbol %s\n", sym->name);
181 #define SET_IMPLICIT 1
184 if(IS_STRUCT(sym->type))
188 reg = pic16_allocDirReg( operandFromSymbol( sym ));
191 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
192 if(!strcmp(ssym->name, reg->name))found=1;
196 checkAddReg(&pic16_rel_udata, reg);
199 debugf("Did find %s in pic16_rel_udata already. Check!\n", reg->name);
200 // 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);
216 /* if is has an absolute address then generate
217 an equate for this no need to allocate space */
218 if (SPEC_ABSA (sym->etype)) {
219 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
220 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
222 dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
224 SPEC_ADDR (sym->etype));
226 /* emit only if it is global */
227 if(sym->level == 0) {
230 reg = pic16_dirregWithName( sym->name );
233 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
234 // __FUNCTION__, __LINE__, sym->name);
236 /* if IS_STRUCT is omitted the following
237 * fixes structures but break char/int etc */
239 if(IS_STRUCT(sym->type))
240 sym->implicit = 1; // mark as implicit
243 reg = pic16_allocDirReg( operandFromSymbol(sym) );
245 if(checkAddReg(&pic16_fix_udata, reg)) {
246 /* and add to globals list if not exist */
247 addSet(&publics, sym);
251 addSet(&publics, sym);
255 if(!sym->used && (sym->level == 0)) {
258 /* symbol not used, just declared probably, but its in
259 * level 0, so we must declare it fine as global */
261 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
264 if(IS_STRUCT(sym->type))
265 sym->implicit = 1; // mark as implicit
268 if(IS_AGGREGATE(sym->type)) {
269 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
271 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
279 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
280 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
284 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
285 if(!strcmp(ssym->name, reg->name))found=1;
289 if(checkAddReg(&pic16_rel_udata, reg)) {
290 addSetHead(&publics, sym);
299 addSetHead(&publics, sym);
304 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
305 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
306 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
307 if (IS_BITVAR (sym->etype)) {
310 dbuf_printf (map->oBuf, "\t%s\n", sym->rname);
311 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
312 for (i = 1; i < size; i++)
313 dbuf_printf (map->oBuf, "\t%s_%d\n", sym->rname, i);
316 dbuf_printf (map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
320 /* FIXME -- VR Fix the following, so that syms to be placed
321 * in the idata section and let linker decide about their fate */
323 /* if it has an initial value then do it only if
324 it is a global variable */
327 && ((sym->level == 0)
328 || IS_STATIC(sym->etype)) ) {
332 if(SPEC_OCLS(sym->etype)==data) {
333 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
336 if(SPEC_OCLS(sym->etype)==code) {
337 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
342 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
343 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
346 if (IS_AGGREGATE (sym->type)) {
347 if(SPEC_ABSA(sym->etype))
348 addSet(&fix_idataSymSet, copySymbol(sym));
350 addSet(&rel_idataSymSet, copySymbol(sym));
351 // ival = initAggregates (sym, sym->ival, NULL);
353 if(SPEC_ABSA(sym->etype))
354 addSet(&fix_idataSymSet, copySymbol(sym));
356 addSet(&rel_idataSymSet, copySymbol(sym));
358 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
359 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
363 setAstFileLine (ival, sym->fileDef, sym->lineDef);
364 codeOutBuf = &statsg->oBuf;
366 eBBlockFromiCode (iCodeFromAst (ival));
374 /*-----------------------------------------------------------------*/
375 /* pic16_initPointer - pointer initialization code massaging */
376 /*-----------------------------------------------------------------*/
378 pic16_initPointer (initList * ilist, sym_link *toType)
384 return valCastLiteral(toType, 0.0);
387 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
388 // expr = list2expr( ilist );
393 /* try it the old way first */
394 if (expr->etype && (val = constExprValue (expr, FALSE)))
397 /* ( ptr + constant ) */
398 if (IS_AST_OP (expr) &&
399 (expr->opval.op == '+' || expr->opval.op == '-') &&
400 IS_AST_SYM_VALUE (expr->left) &&
401 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
402 compareType(toType, expr->left->ftype) &&
403 IS_AST_LIT_VALUE (expr->right)) {
404 return valForCastAggr (expr->left, expr->left->ftype,
410 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
411 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
412 if (compareType(toType, expr->left->ftype)!=1) {
413 werror (W_INIT_WRONG);
414 printFromToType(expr->left->ftype, toType);
420 /* no then we have to do these cludgy checks */
421 /* pointers can be initialized with address of
422 a variable or address of an array element */
423 if (IS_AST_OP (expr) && expr->opval.op == '&') {
424 /* address of symbol */
425 if (IS_AST_SYM_VALUE (expr->left) && expr->left->etype) {
426 val = AST_VALUE (expr->left);
427 val->type = newLink (DECLARATOR);
428 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
429 DCL_TYPE (val->type) = CPOINTER;
430 DCL_PTR_CONST (val->type) = port->mem.code_ro;
432 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
433 DCL_TYPE (val->type) = FPOINTER;
434 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
435 DCL_TYPE (val->type) = PPOINTER;
436 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
437 DCL_TYPE (val->type) = IPOINTER;
438 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
439 DCL_TYPE (val->type) = EEPPOINTER;
441 DCL_TYPE (val->type) = POINTER;
443 val->type->next = expr->left->ftype;
444 val->etype = getSpec (val->type);
448 /* if address of indexed array */
449 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
450 return valForArray (expr->left);
452 /* if address of structure element then
454 if (IS_AST_OP (expr->left) &&
455 expr->left->opval.op == '.') {
456 return valForStructElem (expr->left->left,
461 (&some_struct)->element */
462 if (IS_AST_OP (expr->left) &&
463 expr->left->opval.op == PTR_OP &&
464 IS_ADDRESS_OF_OP (expr->left->left)) {
465 return valForStructElem (expr->left->left->left,
469 /* case 3. (((char *) &a) +/- constant) */
470 if (IS_AST_OP (expr) &&
471 (expr->opval.op == '+' || expr->opval.op == '-') &&
472 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
473 IS_AST_OP (expr->left->right) &&
474 expr->left->right->opval.op == '&' &&
475 IS_AST_LIT_VALUE (expr->right)) {
477 return valForCastAggr (expr->left->right->left,
478 expr->left->left->opval.lnk,
479 expr->right, expr->opval.op);
482 /* case 4. (char *)(array type) */
483 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
484 IS_ARRAY(expr->right->ftype)) {
486 val = copyValue (AST_VALUE (expr->right));
487 val->type = newLink (DECLARATOR);
488 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
489 DCL_TYPE (val->type) = CPOINTER;
490 DCL_PTR_CONST (val->type) = port->mem.code_ro;
492 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
493 DCL_TYPE (val->type) = FPOINTER;
494 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
495 DCL_TYPE (val->type) = PPOINTER;
496 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
497 DCL_TYPE (val->type) = IPOINTER;
498 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
499 DCL_TYPE (val->type) = EEPPOINTER;
501 DCL_TYPE (val->type) = POINTER;
502 val->type->next = expr->right->ftype->next;
503 val->etype = getSpec (val->type);
509 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
511 werror (E_INCOMPAT_PTYPES);
517 /*-----------------------------------------------------------------*/
518 /* printPointerType - generates ival for pointer type */
519 /*-----------------------------------------------------------------*/
521 _pic16_printPointerType (const char *name, char ptype, void *p)
525 sprintf (buf, "LOW(%s)", name);
526 pic16_emitDS (buf, ptype, p);
527 sprintf (buf, "HIGH(%s)", name);
528 pic16_emitDS (buf, ptype, p);
531 /*-----------------------------------------------------------------*/
532 /* printPointerType - generates ival for pointer type */
533 /*-----------------------------------------------------------------*/
535 pic16_printPointerType (const char *name, char ptype, void *p)
537 _pic16_printPointerType (name, ptype, p);
538 //pic16_flushDB(ptype, p); /* breaks char* const arr[] = {&c, &c, &c}; */
541 /*-----------------------------------------------------------------*/
542 /* printGPointerType - generates ival for generic pointer type */
543 /*-----------------------------------------------------------------*/
545 pic16_printGPointerType (const char *iname, const unsigned int itype,
550 _pic16_printPointerType (iname, ptype, p);
554 case CPOINTER: /* fall through */
555 case FUNCTION: /* fall through */
557 /* GPTRs pointing to __data space should be reported as POINTERs */
558 sprintf (buf, "UPPER(%s)", iname);
559 pic16_emitDS (buf, ptype, p);
562 case POINTER: /* __data space */
563 sprintf (buf, "0x%02x", GPTR_TAG_DATA);
564 pic16_emitDS (buf, ptype, p);
568 * FPOINTER and IPOINTER are not used in pic16 port
573 debugf ("itype = %d\n", itype );
577 if (itype == GPOINTER) {
578 fprintf(stderr, "%s: initialized generic pointer with unknown storage class assumes object in code space\n", __func__);
581 //pic16_flushDB(ptype, p); /* might break char* const arr[] = {...}; */
585 /* set to 0 to disable debug messages */
586 #define DEBUG_PRINTIVAL 0
588 /*-----------------------------------------------------------------*/
589 /* pic16_printIvalType - generates ival for int/char */
590 /*-----------------------------------------------------------------*/
592 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
596 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
599 fprintf(stderr, "%s\n",__FUNCTION__);
603 /* if initList is deep */
604 if (ilist && ilist->type == INIT_DEEP)
605 ilist = ilist->init.deep;
607 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
608 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
611 if (!(val = list2val (ilist))) {
612 // assuming a warning has been thrown
613 val = constCharVal (0);
616 if (val->type != type) {
617 val = valCastLiteral(type, floatFromVal(val));
620 switch (getSize (type)) {
622 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
626 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
627 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
630 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
631 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
632 pic16_emitDB(pic16aopLiteral(val, 2), 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);
637 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
642 /*--------------------------------------------------------------------*/
643 /* pic16_printIvalChar - generates initital value for character array */
644 /*--------------------------------------------------------------------*/
646 pic16_printIvalChar (symbol *sym, sym_link * type, initList * ilist, char *s, char ptype, void *p)
649 int remain, len, ilen;
655 fprintf(stderr, "%s\n",__FUNCTION__);
659 val = list2val (ilist);
661 /* if the value is a character string */
662 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
663 /* length of initializer string (might contain \0, so do not use strlen) */
664 ilen = DCL_ELEM(val->type);
667 DCL_ELEM (type) = ilen;
669 /* len is 0 if declartion equals initializer,
670 * >0 if declaration greater than initializer
671 * <0 if declaration less than initializer
672 * Strategy: if >0 emit 0x00 for the rest of the length,
673 * if <0 then emit only the length of declaration elements
676 len = DCL_ELEM (type) - ilen;
678 // fprintf(stderr, "%s:%d ilen = %i len = %i DCL_ELEM(type) = %i SPEC_CVAL-len = %i\n", __FILE__, __LINE__,
679 // ilen, len, DCL_ELEM(type), strlen(SPEC_CVAL(val->etype).v_char));
682 /* emit initializer */
683 for(remain=0; remain<ilen; remain++)
684 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
686 /* fill array with 0x00 */
688 pic16_emitDB(0x00, ptype, p);
691 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
693 for(remain=0; remain<DCL_ELEM (type); remain++)
694 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
698 // if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
703 for(remain=0; remain<strlen(s); remain++) {
704 pic16_emitDB(s[remain], ptype, p);
710 /*-----------------------------------------------------------------*/
711 /* pic16_printIvalArray - generates code for array initialization */
712 /*-----------------------------------------------------------------*/
714 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
718 int lcnt = 0, size = 0;
725 fprintf(stderr, "%s\n",__FUNCTION__);
727 /* take care of the special case */
728 /* array of characters can be init */
730 if (IS_CHAR (type->next)) {
731 if (!IS_LITERAL(list2val(ilist)->etype)) {
732 werror (W_INIT_WRONG);
736 if(pic16_printIvalChar (sym, type,
737 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
738 SPEC_CVAL (sym->etype).v_char, ptype, p))
741 /* not the special case */
742 if (ilist && ilist->type != INIT_DEEP)
744 werror (E_INIT_STRUCT, sym->name);
748 iloop = ilist->init.deep;
749 lcnt = DCL_ELEM (type);
754 pic16_printIval (sym, type->next, iloop, ptype, p);
755 iloop = (iloop ? iloop->next : NULL);
758 /* if not array limits given & we */
759 /* are out of initialisers then */
760 if (!DCL_ELEM (type) && !iloop)
763 /* no of elements given and we */
764 /* have generated for all of them */
766 /* if initializers left */
768 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
774 /* if we have not been given a size */
775 if (!DCL_ELEM (type))
776 DCL_ELEM (type) = size;
781 /*-----------------------------------------------------------------*/
782 /* pic16_printIvalBitFields - generate initializer for bitfields */
783 /*-----------------------------------------------------------------*/
785 pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
789 initList *lilist = *ilist ;
790 unsigned long ival = 0;
795 fprintf(stderr, "%s\n",__FUNCTION__);
801 val = list2val(lilist);
803 if (SPEC_BLEN(lsym->etype) > 8) {
804 size += ((SPEC_BLEN (lsym->etype) / 8) +
805 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
808 size = ((SPEC_BLEN (lsym->etype) / 8) +
809 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
812 i <<= SPEC_BSTR (lsym->etype);
814 if (! ( lsym->next &&
815 (lilist && lilist->next) &&
816 (IS_BITFIELD(lsym->next->type)) &&
817 (SPEC_BSTR(lsym->next->etype)))) break;
819 lilist = lilist->next;
823 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
827 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
828 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
831 case 4: /* EEP: why is this db and not dw? */
832 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
833 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
834 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
835 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
838 /* VR - only 1,2,4 size long can be handled???? Why? */
839 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
847 /*-----------------------------------------------------------------*/
848 /* printIvalStruct - generates initial value for structures */
849 /*-----------------------------------------------------------------*/
851 pic16_printIvalStruct (symbol * sym, sym_link * type,
852 initList * ilist, char ptype, void *p)
855 initList *iloop = NULL;
859 fprintf(stderr, "%s\n",__FUNCTION__);
862 sflds = SPEC_STRUCT (type)->fields;
865 if (ilist->type != INIT_DEEP) {
866 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
870 iloop = ilist->init.deep;
873 for (; (sflds && iloop); sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
874 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
875 if (IS_BITFIELD(sflds->type)) {
876 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
878 pic16_printIval (sym, sflds->type, iloop, ptype, p);
882 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
887 /*-----------------------------------------------------------------*/
888 /* printIvalUnion - generates initial value for unions */
889 /*-----------------------------------------------------------------*/
891 pic16_printIvalUnion (symbol * sym, sym_link * type,
892 initList * ilist, char ptype, void *p)
895 initList *iloop = NULL;
900 fprintf(stderr, "%s\n",__FUNCTION__);
912 if (type) size = SPEC_STRUCT(type)->size;
914 if (i == 1 && size >= 0 && size <= sizeof(long))
916 unsigned long val = ulFromVal (list2val(ilist));
919 pic16_emitDB(val, ptype, p);
925 fprintf( stderr, "INCOMPLETE SUPPORT FOR INITIALIZED union---FALLING BACK TO struct\n" );
926 fprintf( stderr, "This is a bug. Please file a bug-report with your source attached.\n" );
927 pic16_printIvalStruct( sym, type, ilist, ptype, p );
931 pic16_isUnion( symbol *sym, sym_link *type )
933 if (type && SPEC_STRUCT(type)->type == UNION) return 1;
937 /*--------------------------------------------------------------------------*/
938 /* pic16_printIvalCharPtr - generates initial values for character pointers */
939 /*--------------------------------------------------------------------------*/
941 pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
945 /* PENDING: this is _very_ mcs51 specific, including a magic
947 It's also endin specific.
949 VR - Attempting to port this function to pic16 port - 8-Jun-2004
954 fprintf(stderr, "%s\n",__FUNCTION__);
957 size = getSize (type);
959 if (val->name && strlen (val->name))
961 if (size == 1) /* This appears to be Z80 specific?? */
963 pic16_emitDS(val->name, ptype, p);
967 pic16_printPointerType (val->name, ptype, p);
972 type = PTR_TYPE (SPEC_OCLS (val->etype));
973 if (val->sym && val->sym->isstrlit) {
974 // this is a literal string
977 pic16_printGPointerType(val->name, type, ptype, p);
981 fprintf (stderr, "*** internal error: unknown size in "
982 "printIvalCharPtr.\n");
988 // these are literals assigned to pointers
992 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
995 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
996 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
999 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1000 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1001 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1009 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
1010 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
1011 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
1017 /*-----------------------------------------------------------------------*/
1018 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
1019 /*-----------------------------------------------------------------------*/
1021 pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
1028 fprintf(stderr, "%s\n",__FUNCTION__);
1032 val = list2val (ilist);
1034 val = valCastLiteral(type, 0.0);
1037 // an error has been thrown already
1038 val = constCharVal (0);
1041 if (IS_LITERAL(val->etype)) {
1042 if (0 && compareType(type, val->etype) == 0) {
1043 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
1044 printFromToType (val->type, type);
1046 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
1050 /* check the types */
1051 if ((dLvl = compareType (val->type, type->next)) <= 0)
1053 pic16_emitDB(0x00, ptype, p);
1057 /* now generate the name */
1059 pic16_printGPointerType (val->name, CPOINTER /*DCL_TYPE(val->type)*/, ptype, p);
1061 pic16_printGPointerType (val->sym->rname, CPOINTER /*DCL_TYPE(val->type)*/, ptype, p);
1063 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
1065 if(!checkSym(publics, val->sym))
1066 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
1067 /* this has not been declared as extern
1068 * so declare it as a 'late extern' just after the symbol */
1069 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
1070 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1071 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
1080 /*-----------------------------------------------------------------*/
1081 /* pic16_printIvalPtr - generates initial value for pointers */
1082 /*-----------------------------------------------------------------*/
1084 pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1090 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1091 sym->rname, getSize(sym->type));
1095 if (ilist && (ilist->type == INIT_DEEP))
1096 ilist = ilist->init.deep;
1098 /* function pointer */
1099 if (IS_FUNC (type->next))
1101 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1105 if (!(val = pic16_initPointer (ilist, type)))
1108 /* if character pointer */
1109 if (IS_CHAR (type->next))
1110 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1113 /* check the type */
1114 if (compareType (type, val->type) == 0) {
1115 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1116 printFromToType (val->type, type);
1119 /* if val is literal */
1120 if (IS_LITERAL (val->etype))
1122 switch (getSize (type))
1125 pic16_emitDB((unsigned int) ulFromVal (val) & 0xff, ptype, p);
1128 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1129 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1132 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1133 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1134 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1137 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1144 size = getSize (type);
1146 if (size == 1) /* Z80 specific?? */
1148 pic16_emitDS(val->name, ptype, p);
1152 pic16_printPointerType (val->name, ptype, p);
1157 itype = PTR_TYPE (SPEC_OCLS (val->etype));
1158 pic16_printGPointerType (val->name, itype, ptype, p);
1166 /*-----------------------------------------------------------------*/
1167 /* pic16_printIval - generates code for initial value */
1168 /*-----------------------------------------------------------------*/
1169 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1177 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1178 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1179 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1182 /* if structure then */
1183 if (IS_STRUCT (type))
1185 if (pic16_isUnion(sym, type))
1187 //fprintf(stderr,"%s union\n",__FUNCTION__);
1188 pic16_printIvalUnion (sym, type, ilist, ptype, p);
1190 //fprintf(stderr,"%s struct\n",__FUNCTION__);
1191 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1196 /* if this is an array */
1197 if (IS_ARRAY (type))
1199 // fprintf(stderr,"%s array\n",__FUNCTION__);
1200 pic16_printIvalArray (sym, type, ilist, ptype, p);
1207 // not an aggregate, ilist must be a node
1208 if (ilist->type!=INIT_NODE) {
1209 // or a 1-element list
1210 if (ilist->init.deep->next) {
1211 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1214 ilist=ilist->init.deep;
1219 // and the type must match
1220 itype=ilist->init.node->ftype;
1222 if (compareType(type, itype)==0) {
1223 // special case for literal strings
1224 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1225 // which are really code pointers
1226 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1229 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1230 // printFromToType(itype, type);
1237 /* if this is a pointer */
1240 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1241 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1246 /* if type is SPECIFIER */
1249 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1250 pic16_printIvalType (sym, type, ilist, ptype, p);
1256 PIC16_IS_CONFIG_ADDRESS(int address)
1258 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1262 PIC16_IS_IDLOC_ADDRESS(int address)
1264 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1267 /*-----------------------------------------------------------------*/
1268 /* emitStaticSeg - emitcode for the static segment */
1269 /*-----------------------------------------------------------------*/
1271 pic16emitStaticSeg (memmap * map)
1274 static int didcode=0;
1276 //fprintf(stderr, "%s\n",__FUNCTION__);
1280 /* for all variables in this segment do */
1281 for (sym = setFirstItem (map->syms); sym;
1282 sym = setNextItem (map->syms))
1286 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1287 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1288 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1289 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1290 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1291 printTypeChain( sym->type, stderr );
1292 fprintf(stderr, "\n");
1295 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1296 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1297 (int) ulFromVal (list2val(sym->ival)));
1302 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1303 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1304 (char) ulFromVal (list2val(sym->ival)));
1309 /* if it is "extern" then do nothing */
1310 if (IS_EXTERN (sym->etype)/* && !SPEC_ABSA(sym->etype)*/) {
1311 checkAddSym(&externs, sym);
1315 /* if it is not static add it to the public
1317 if (!IS_STATIC (sym->etype)) {
1318 /* do not emit if it is a config word declaration */
1319 checkAddSym(&publics, sym);
1322 /* print extra debug info if required */
1323 if (options.debug || sym->level == 0) {
1324 /* NOTE to me - cdbFile may be null in which case,
1325 * the sym name will be printed to stdout. oh well */
1326 debugFile->writeSymbol(sym);
1329 /* if it has an absolute address */
1330 if (SPEC_ABSA (sym->etype)) {
1331 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1332 // __FILE__, __LINE__, sym->name);
1334 /* if it has an initial value */
1342 /* symbol has absolute address and initial value */
1344 resolveIvalSym (sym->ival, sym->type);
1345 asym = newSymbol(sym->rname, 0);
1346 abSym = Safe_calloc(1, sizeof(absSym));
1347 strcpy(abSym->name, sym->rname);
1348 abSym->address = SPEC_ADDR( sym->etype );
1349 addSet(&absSymSet, abSym);
1351 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1352 pic16_addpBlock(pb);
1354 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1355 PCF(pcf)->absblock = 1;
1357 pic16_addpCode2pBlock(pb,pcf);
1358 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1359 //fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1360 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1361 pic16_flushDB('p', (void *)pb);
1363 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1369 /* symbol has absolute address but no initial value */
1371 /* allocate space */
1372 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
1374 /* special case for character strings */
1375 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1376 SPEC_CVAL (sym->etype).v_char) {
1378 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1380 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char, getSize(sym->type));
1382 fprintf (stderr, "%s:%u(%s): do not know how to intialize symbol %s\n", __FILE__, __LINE__, __FUNCTION__, sym->rname);
1388 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1389 // __FILE__, __LINE__, sym->name);
1392 /* if it has an initial value */
1396 /* symbol doesn't have absolute address but has initial value */
1397 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
1399 resolveIvalSym (sym->ival, sym->type);
1401 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1402 pic16_addpBlock(pb);
1405 /* make sure that 'code' directive is emitted before, once */
1406 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1411 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1412 //fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1413 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1414 pic16_flushDB('p', (void *)pb);
1418 /* symbol doesn't have absolute address and no initial value */
1419 /* allocate space */
1420 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1421 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
1422 /* special case for character strings */
1423 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1424 SPEC_CVAL (sym->etype).v_char) {
1426 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1428 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char, getSize(sym->type));
1439 /*-----------------------------------------------------------------*/
1440 /* pic16_emitConfigRegs - emits the configuration registers */
1441 /*-----------------------------------------------------------------*/
1442 void pic16_emitConfigRegs(FILE *of)
1446 for(i=0;i<=(pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart);i++)
1447 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1448 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1449 pic16->cwInfo.confAddrStart+i,
1450 pic16->cwInfo.crInfo[i].value);
1453 void pic16_emitIDRegs(FILE *of)
1457 for(i=0;i<=(pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart);i++)
1458 if(pic16->idInfo.irInfo[i].emit)
1459 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1460 pic16->idInfo.idAddrStart+i,
1461 pic16->idInfo.irInfo[i].value);
1468 /* no special considerations for the following
1469 data, idata & bit & xdata */
1470 pic16emitRegularMap (data, TRUE, TRUE);
1471 pic16emitRegularMap (idata, TRUE, TRUE);
1472 pic16emitRegularMap (bit, TRUE, FALSE);
1473 pic16emitRegularMap (xdata, TRUE, TRUE);
1474 pic16emitRegularMap (sfr, FALSE, FALSE);
1475 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1476 pic16emitRegularMap (code, TRUE, FALSE);
1477 pic16emitStaticSeg (statsg);
1478 pic16emitStaticSeg (c_abs);
1481 /*-----------------------------------------------------------------*/
1482 /* createInterruptVect - creates the interrupt vector */
1483 /*-----------------------------------------------------------------*/
1485 pic16createInterruptVect (struct dbuf_s * vBuf)
1487 /* if the main is only a prototype ie. no body then do nothing */
1489 if (!IFFUNC_HASBODY(mainf->type)) {
1490 /* if ! compile only then main function should be present */
1491 if (!options.cc_only)
1497 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1498 dbuf_printf (vBuf, ";\t.area\t%s\n", CODE_NAME);
1499 dbuf_printf (vBuf, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1501 /* this is an overkill since WE are the port,
1502 * and we know if we have a genIVT function! */
1504 port->genIVT(vFile, interrupts, maxInterrupts);
1512 /*-----------------------------------------------------------------*/
1513 /* pic16initialComments - puts in some initial comments */
1514 /*-----------------------------------------------------------------*/
1516 pic16initialComments (FILE * afile)
1518 initialComments (afile);
1519 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1520 if (pic16_options.xinst) {
1521 fprintf (afile, "; * Extended Instruction Set\n");
1524 if (pic16_mplab_comp) {
1525 fprintf(afile, "; * MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1527 fprintf (afile, iComments2);
1529 if (options.debug) {
1530 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n",
1531 SDCC_VERSION_STR, getBuildNumber(), (!pic16_options.xinst?"":" {extended}") );
1536 pic16_stringInSet(const char *str, set **world, int autoAdd)
1543 for (s = setFirstItem(*world); s; s = setNextItem(*world))
1546 if (0 == strcmp(s, str)) return 1;
1550 if (autoAdd) addSet(world, Safe_strdup(str));
1555 pic16_emitSymbolIfNew(FILE *file, const char *fmt, const char *sym, int checkLocals)
1557 static set *emitted = NULL;
1559 if (!pic16_stringInSet(sym, &emitted, 1)) {
1560 /* sym was not in emittedSymbols */
1561 if (!checkLocals || !pic16_stringInSet(sym, &pic16_localFunctions, 0)) {
1562 /* sym is not a locally defined function---avoid bug #1443651 */
1563 fprintf( file, fmt, sym );
1570 /*-----------------------------------------------------------------*/
1571 /* printPublics - generates global declarations for publics */
1572 /*-----------------------------------------------------------------*/
1574 pic16printPublics (FILE *afile)
1578 fprintf (afile, "\n%s", iComments2);
1579 fprintf (afile, "; public variables in this module\n");
1580 fprintf (afile, "%s", iComments2);
1582 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1584 if(!IS_STATIC(sym->etype))
1585 pic16_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
1588 /*-----------------------------------------------------------------*/
1589 /* printExterns - generates extern declarations for externs */
1590 /*-----------------------------------------------------------------*/
1592 pic16_printExterns(FILE *afile)
1596 /* print nothing if no externs to declare */
1597 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1600 fprintf(afile, "\n%s", iComments2);
1601 fprintf(afile, "; extern variables in this module\n");
1602 fprintf(afile, "%s", iComments2);
1604 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1605 pic16_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
1607 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1608 pic16_emitSymbolIfNew(afile, "\textern _%s\n", sym->name, 1);
1611 /*-----------------------------------------------------------------*/
1612 /* emitOverlay - will emit code for the overlay stuff */
1613 /*-----------------------------------------------------------------*/
1615 pic16emitOverlay (struct dbuf_s *aBuf)
1619 if (!elementsInSet (ovrSetSets))
1620 dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name);
1622 /* for each of the sets in the overlay segment do */
1623 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1624 ovrset = setNextItem (ovrSetSets))
1629 if (elementsInSet (ovrset))
1631 /* this dummy area is used to fool the assembler
1632 otherwise the assembler will append each of these
1633 declarations into one chunk and will not overlay
1635 dbuf_printf (aBuf, ";\t.area _DUMMY\n");
1636 /* output the area informtion */
1637 dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1640 for (sym = setFirstItem (ovrset); sym;
1641 sym = setNextItem (ovrset))
1644 /* if extern then do nothing */
1645 if (IS_EXTERN (sym->etype))
1648 /* if allocation required check is needed
1649 then check if the symbol really requires
1650 allocation only for local variables */
1651 if (!IS_AGGREGATE (sym->type) &&
1652 !(sym->_isparm && !IS_REGPARM (sym->etype))
1653 && !sym->allocreq && sym->level)
1656 /* if global variable & not static or extern
1657 and addPublics allowed then add it to the public set */
1658 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1659 && !IS_STATIC (sym->etype)) {
1660 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1661 checkAddSym(&publics, sym);
1662 // addSetHead (&publics, sym);
1665 /* if extern then do nothing or is a function
1667 if (IS_FUNC (sym->type))
1671 /* if is has an absolute address then generate
1672 an equate for this no need to allocate space */
1673 if (SPEC_ABSA (sym->etype))
1676 if (options.debug || sym->level == 0)
1677 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1679 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1681 SPEC_ADDR (sym->etype));
1685 if (options.debug || sym->level == 0)
1686 dbuf_printf (aBuf, "==.\n");
1688 /* allocate space */
1689 dbuf_printf (aBuf, "%s:\n", sym->rname);
1690 dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1698 emitStatistics(FILE *asmFile)
1700 unsigned long isize, udsize, ramsize;
1701 statistics.isize = pic16_countInstructions();
1702 isize = (statistics.isize >= 0) ? statistics.isize : 0;
1703 udsize = (statistics.udsize >= 0) ? statistics.udsize : 0;
1704 ramsize = pic16 ? pic16->RAMsize : 0x200;
1705 ramsize -= 256; /* ignore access bank and SFRs */
1706 if (ramsize == 0) ramsize = 64; /* prevent division by zero (below) */
1708 fprintf (asmFile, "\n\n; Statistics:\n");
1709 fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%5.2f%%)\n; \t%5ld (0x%04lx) words\n",
1710 isize, isize, (isize*100.0)/(128UL << 10),
1711 isize>>1, isize>>1);
1712 fprintf (asmFile, "; udata size:\t%5ld (0x%04lx) bytes (%5.2f%%)\n",
1713 udsize, udsize, (udsize*100.0) / (1.0 * ramsize));
1714 fprintf (asmFile, "; access size:\t%5ld (0x%04lx) bytes\n",
1715 statistics.intsize, statistics.intsize);
1717 fprintf (asmFile, "\n\n");
1722 /*-----------------------------------------------------------------*/
1723 /* glue - the final glue that hold the whole thing together */
1724 /*-----------------------------------------------------------------*/
1729 struct dbuf_s ovrBuf;
1732 dbuf_init(&ovrBuf, 4096);
1733 dbuf_init(&vBuf, 4096);
1735 mainf = newSymbol ("main", 0);
1738 mainf = findSymWithLevel(SymbolTab, mainf);
1740 pic16_pCodeInitRegisters();
1742 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1743 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1745 pic16_addpBlock(pb);
1747 /* entry point @ start of CSEG */
1748 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1751 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1752 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1753 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1754 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1757 /* put in the call to main */
1758 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1760 if (options.mainreturn) {
1761 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1762 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1764 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1765 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1769 /* At this point we've got all the code in the form of pCode structures */
1770 /* Now it needs to be rearranged into the order it should be placed in the */
1773 pic16_movepBlock2Head('P'); // Last
1774 pic16_movepBlock2Head(code->dbName);
1775 pic16_movepBlock2Head('X');
1776 pic16_movepBlock2Head(statsg->dbName); // First
1778 /* print the global struct definitions */
1780 /* PENDING: this isnt the best place but it will do */
1781 if (port->general.glue_up_main) {
1782 /* create the interrupt vector table */
1783 pic16createInterruptVect (&vBuf);
1786 /* emit code for the all the variables declared */
1789 /* do the overlay segments */
1790 pic16emitOverlay(&ovrBuf);
1791 pic16_AnalyzepCode('*');
1794 if(pic16_options.dumpcalltree) {
1797 sprintf(buffer, dstFileName);
1798 strcat(buffer, ".calltree");
1799 cFile = fopen(buffer, "w");
1800 pic16_printCallTree( cFile );
1805 pic16_InlinepCode();
1806 pic16_AnalyzepCode('*');
1809 if(pic16_debug_verbose)
1812 /* now put it all together into the assembler file */
1813 /* create the assembler file name */
1814 if((noAssemble || options.c1mode) && fullDstFileName) {
1815 sprintf (buffer, fullDstFileName);
1817 sprintf (buffer, dstFileName);
1818 strcat (buffer, ".asm");
1821 if(!(asmFile = fopen (buffer, "w"))) {
1822 werror (E_FILE_OPEN_ERR, buffer);
1826 /* initial comments */
1827 pic16initialComments (asmFile);
1829 /* print module name */
1831 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1833 /* Let the port generate any global directives, etc. */
1834 if(port->genAssemblerPreamble) {
1835 port->genAssemblerPreamble(asmFile);
1838 /* Put all variables into a cblock */
1839 pic16_AnalyzeBanking();
1842 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1843 pic16_OptimizeLocalRegs();
1847 /* remove redundant BANKSELs -- added by RN 2005-01-17 */
1848 if(pic16_options.opt_banksel > 1) {
1849 pic16_OptimizeBanksel();
1852 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1853 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1854 pic16_OptimizeJumps();
1857 /* print the global variables in this module */
1858 pic16printPublics (asmFile);
1860 /* print the extern variables to this module */
1861 pic16_printExterns(asmFile);
1863 pic16_writeUsedRegs(asmFile);
1866 /* no xdata in pic */
1867 /* if external stack then reserve space of it */
1868 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1869 fprintf (asmFile, "%s", iComments2);
1870 fprintf (asmFile, "; external stack \n");
1871 fprintf (asmFile, "%s", iComments2);
1872 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1873 fprintf (asmFile,";\t.ds 256\n");
1878 /* no xdata in pic */
1879 /* copy xtern ram data */
1880 fprintf (asmFile, "%s", iComments2);
1881 fprintf (asmFile, "; external ram data\n");
1882 fprintf (asmFile, "%s", iComments2);
1883 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1887 /* copy the bit segment */
1888 fprintf (asmFile, "%s", iComments2);
1889 fprintf (asmFile, "; bit data\n");
1890 fprintf (asmFile, "%s", iComments2);
1891 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1894 /* copy the interrupt vector table */
1895 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1896 fprintf (asmFile, "\n%s", iComments2);
1897 fprintf (asmFile, "; interrupt vector \n");
1898 fprintf (asmFile, "%s", iComments2);
1899 dbuf_write_and_destroy (&vBuf, asmFile);
1902 /* copy global & static initialisations */
1903 fprintf (asmFile, "\n%s", iComments2);
1904 fprintf (asmFile, "; global & static initialisations\n");
1905 fprintf (asmFile, "%s", iComments2);
1907 if(pic16_debug_verbose)
1908 fprintf(asmFile, "; A code from now on!\n");
1910 pic16_copypCode(asmFile, 'A');
1912 if(pic16_options.no_crt) {
1913 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1914 fprintf(asmFile, "\tcode\n");
1915 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1919 // dbuf_write_and_destroy (&code->oBuf, stderr);
1921 fprintf(asmFile, "; I code from now on!\n");
1922 pic16_copypCode(asmFile, 'I');
1924 if(pic16_debug_verbose)
1925 fprintf(asmFile, "; dbName from now on!\n");
1927 pic16_copypCode(asmFile, statsg->dbName);
1929 if(pic16_options.no_crt) {
1930 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1931 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1935 if(pic16_debug_verbose)
1936 fprintf(asmFile, "; X code from now on!\n");
1938 pic16_copypCode(asmFile, 'X');
1940 if(pic16_debug_verbose)
1941 fprintf(asmFile, "; M code from now on!\n");
1943 pic16_copypCode(asmFile, 'M');
1945 pic16_copypCode(asmFile, code->dbName);
1947 pic16_copypCode(asmFile, 'P');
1949 emitStatistics(asmFile);
1951 fprintf (asmFile,"\tend\n");