1 /*-------------------------------------------------------------------------
3 SDCCglue.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"
36 #ifdef WORDS_BIGENDIAN
37 #define _ENDIAN(x) (3-x)
39 #define _ENDIAN(x) (x)
42 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
44 extern symbol *interrupts[256];
45 static void showAllMemmaps(FILE *of); // XXX: emits initialized symbols
49 extern unsigned maxInterrupts;
50 extern int maxRegBank;
52 extern char *VersionString;
53 extern struct dbuf_s *codeOutBuf;
54 extern char *iComments1;
55 extern char *iComments2;
56 //extern void emitStaticSeg (memmap * map);
57 set *pic14_localFunctions = NULL;
59 extern DEFSETFUNC (closeTmpFiles);
60 extern DEFSETFUNC (rmTmpFiles);
62 extern void AnalyzeBanking (void);
63 extern void ReuseReg(void);
64 extern void InlinepCode(void);
65 extern void writeUsedRegs(FILE *);
67 extern void initialComments (FILE * afile);
68 extern void printPublics (FILE * afile);
70 extern void printChar (FILE * ofile, char *s, int plen);
71 void pCodeInitRegisters(void);
72 int getConfigWord(int address);
73 int getHasSecondConfigReg(void);
75 char *udata_section_name=0; // FIXME Temporary fix to change udata section name -- VR
76 int pic14_hasInterrupt = 0; // Indicates whether to emit interrupt handler or not
78 static set *emitted = NULL;
79 int pic14_stringInSet(const char *str, set **world, int autoAdd);
80 static void emitSymbol (struct dbuf_s *oBuf, const char *name, const char *section_type, int size, int addr, int useEQU, int globalize);
82 /*-----------------------------------------------------------------*/
83 /* aopLiteral - string from a literal value */
84 /*-----------------------------------------------------------------*/
85 unsigned int pic14aopLiteral (value *val, int offset)
92 /* if it is a float then it gets tricky */
93 /* otherwise it is fairly simple */
94 if (!IS_FLOAT(val->type)) {
95 unsigned long v = (unsigned long) floatFromVal(val);
97 return ( (v >> (offset * 8)) & 0xff);
100 /* it is type float */
101 fl.f = (float) floatFromVal(val);
102 #ifdef WORDS_BIGENDIAN
103 return fl.c[3-offset];
111 is_valid_identifier( const char *name )
117 /* only accept [a-zA-Z_][a-zA-Z0-9_] */
118 if (!((a >= 'a' && a <= 'z')
119 || (a >= 'A' && a <= 'z')
124 while ((a = *name++))
126 if (!((a >= 'a' && a <= 'z')
127 || (a >= 'A' && a <= 'Z')
128 || (a >= '0' && a <= '9')
133 /* valid identifier */
137 #define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype))
138 extern int IS_CONFIG_ADDRESS( int addr );
140 pic14_constructAbsMap (struct dbuf_s *oBuf)
142 memmap *maps[] = { data, sfr, NULL };
147 int addr, min=-1, max=-1;
150 int low, high, shared;
152 for (i=0; maps[i] != NULL; i++)
154 for (sym = (symbol *)setFirstItem (maps[i]->syms);
155 sym; sym = setNextItem (maps[i]->syms))
157 if (IS_DEFINED_HERE(sym) && SPEC_ABSA(sym->etype))
159 addr = SPEC_ADDR(sym->etype);
161 /* handle CONFIG words here */
162 if (IS_CONFIG_ADDRESS( addr ))
164 //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr );
165 //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) );
167 pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) );
169 fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name );
174 if (max == -1 || addr > max) max = addr;
175 if (min == -1 || addr < min) min = addr;
176 //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
177 aliases = hTabItemWithKey (ht, addr);
179 /* May not use addSetHead, as we cannot update the
180 * list's head in the hastable `ht'. */
181 addSet (&aliases, sym);
183 fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n",
184 __FUNCTION__, elementsInSet(aliases), sym->name, addr);
187 addSet (&aliases, sym);
188 hTabAddItem (&ht, addr, aliases);
194 /* now emit definitions for all absolute symbols */
195 dbuf_printf (oBuf, "%s", iComments2);
196 dbuf_printf (oBuf, "; absolute symbol definitions\n");
197 dbuf_printf (oBuf, "%s", iComments2);
198 for (addr=min; addr <= max; addr++)
201 aliases = hTabItemWithKey (ht, addr);
202 if (aliases && elementsInSet(aliases)) {
203 /* Make sure there is no initialized value at this location! */
204 for (sym = setFirstItem(aliases); sym; sym = setNextItem(aliases)) {
205 if (sym->ival) break;
209 dbuf_printf (oBuf, "udata_abs_%s_%x\tudata_ovr\t0x%04x\n",
210 moduleName, addr, addr);
211 for (sym = setFirstItem (aliases); sym;
212 sym = setNextItem (aliases))
214 if (getSize(sym->type) > size) {
215 size = getSize(sym->type);
218 /* initialized values are handled somewhere else */
219 if (sym->ival) continue;
221 /* emit STATUS as well as _STATUS, required for SFRs only */
222 dbuf_printf (oBuf, "%s\n", sym->name);
223 dbuf_printf (oBuf, "%s\n", sym->rname);
225 // global symbols must be emitted again as 'global sym->name'
226 pic14_stringInSet(sym->name, &emitted, 1);
227 pic14_stringInSet(sym->rname, &emitted, 1);
230 dbuf_printf (oBuf, "\tres\t%d\n", size);
234 /* also emit STK symbols
235 * XXX: This is ugly and fails as soon as devices start to get
236 * differently sized sharebanks, since STK12 will be
237 * required by larger devices but only up to STK03 might
238 * be defined using smaller devices. */
239 dbuf_printf (oBuf, "\n");
240 shared = pic14_getSharedStack(&low, &high, &size);
241 if (!pic14_options.isLibrarySource)
243 pic = pic14_getPIC();
245 dbuf_printf (oBuf, "\tglobal PSAVE\n");
246 dbuf_printf (oBuf, "\tglobal SSAVE\n");
247 dbuf_printf (oBuf, "\tglobal WSAVE\n");
248 for (i = size - 4; i >= 0; i--) {
249 dbuf_printf (oBuf, "\tglobal STK%02d\n", i);
252 // 16f84 has no SHAREBANK (in linkerscript) but memory aliased in two
255 // for single banked devices: use normal, "banked" RAM
256 dbuf_printf (oBuf, "sharebank udata_ovr 0x%04X\n", low);
258 // for devices with at least two banks, require a sharebank section
259 dbuf_printf (oBuf, "sharebank udata_shr\n");
261 dbuf_printf (oBuf, "PSAVE\tres 1\n");
262 dbuf_printf (oBuf, "SSAVE\tres 1\n");
263 dbuf_printf (oBuf, "WSAVE\tres 1\n"); // WSAVE *must* be in sharebank (IRQ handlers)
264 /* fill rest of sharebank with stack STKxx .. STK00 */
265 for (i = size - 4; i >= 0; i--) {
266 dbuf_printf (oBuf, "STK%02d\tres 1\n", i);
269 /* declare STKxx as extern for all files
270 * except the one containing main() */
271 dbuf_printf (oBuf, "\textern PSAVE\n");
272 dbuf_printf (oBuf, "\textern SSAVE\n");
273 dbuf_printf (oBuf, "\textern WSAVE\n");
274 for (i = size - 4; i >= 0; i--) {
276 SNPRINTF(&buffer[0], 127, "STK%02d", i);
277 dbuf_printf (oBuf, "\textern %s\n", &buffer[0]);
278 pic14_stringInSet(&buffer[0], &emitted, 1);
283 /*-----------------------------------------------------------------*/
284 /* emitRegularMap - emit code for maps with no special cases */
285 /*-----------------------------------------------------------------*/
287 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
292 /* print the area name */
294 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
296 for (sym = setFirstItem (map->syms); sym;
297 sym = setNextItem (map->syms)) {
299 //printf("%s\n",sym->name);
301 /* ignore if config word */
302 if (SPEC_ABSA(sym->etype)
303 && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
306 /* if extern then add it into the extern list */
307 if (IS_EXTERN (sym->etype)) {
308 addSetHead (&externs, sym);
312 /* if allocation required check is needed
313 then check if the symbol really requires
314 allocation only for local variables */
315 if (arFlag && !IS_AGGREGATE (sym->type) &&
316 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
317 !sym->allocreq && sym->level)
320 /* if global variable & not static or extern
321 and addPublics allowed then add it to the public set */
322 if ((sym->level == 0 ||
323 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
325 !IS_STATIC (sym->etype))
327 //fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name );
328 addSetHead (&publics, sym);
331 // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
334 /* if extern then do nothing or is a function
336 if (IS_FUNC (sym->type))
339 /* print extra debug info if required */
340 if (options.debug || sym->level == 0)
342 if (!sym->level) /* global */
343 if (IS_STATIC (sym->etype))
344 dbuf_printf (&map->oBuf, "F%s_", moduleName); /* scope is file */
346 dbuf_printf (&map->oBuf, "G_"); /* scope is global */
348 /* symbol is local */
349 dbuf_printf (&map->oBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
350 dbuf_printf (&map->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
353 /* absolute symbols are handled in pic14_constructAbsMap */
354 if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym))
357 /* if it has an absolute address then generate
358 an equate for this no need to allocate space */
359 if (0 && SPEC_ABSA (sym->etype))
361 //if (options.debug || sym->level == 0)
362 //dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
364 dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
366 SPEC_ADDR (sym->etype));
372 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
373 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
374 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
375 if (IS_BITVAR (sym->etype))
382 emitSymbol (&map->oBuf,
385 getSize (sym->type) & 0xffff,
386 SPEC_ABSA(sym->etype)
387 ? SPEC_ADDR(sym->etype)
396 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
398 for (i = 1; i < size; i++)
399 dbuf_printf (&map->oBuf, "\t%s_%d\n", sym->rname, i);
404 //dbuf_printf (&map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
408 /* if it has a initial value then do it only if
409 it is a global variable */
410 if (sym->ival && sym->level == 0) {
413 if (IS_AGGREGATE (sym->type))
414 ival = initAggregates (sym, sym->ival, NULL);
416 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
417 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
418 codeOutBuf = &statsg->oBuf;
420 eBBlockFromiCode (iCodeFromAst (ival));
429 /*-----------------------------------------------------------------*/
430 /* printIvalType - generates ival for int/char */
431 /*-----------------------------------------------------------------*/
433 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
438 //fprintf(stderr, "%s\n",__FUNCTION__);
440 /* if initList is deep */
441 if (ilist->type == INIT_DEEP)
442 ilist = ilist->init.deep;
444 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
445 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
448 if (!(val = list2val (ilist))) {
449 // assuming a warning has been thrown
453 if (val->type != type) {
454 val = valCastLiteral(type, floatFromVal(val));
458 ulval = (unsigned long) floatFromVal (val);
462 switch (getSize (type)) {
464 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
468 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
469 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
473 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
474 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
475 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
476 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
481 /*-----------------------------------------------------------------*/
482 /* printIvalBitFields - generate initializer for bitfields */
483 /*-----------------------------------------------------------------*/
484 static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
488 initList *lilist = *ilist ;
489 unsigned long ival = 0;
495 val = list2val(lilist);
497 if (SPEC_BLEN(lsym->etype) > 8) {
498 size += ((SPEC_BLEN (lsym->etype) / 8) +
499 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
502 size = ((SPEC_BLEN (lsym->etype) / 8) +
503 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
505 i = (unsigned long)floatFromVal(val);
506 i <<= SPEC_BSTR (lsym->etype);
508 if (! ( lsym->next &&
509 (IS_BITFIELD(lsym->next->type)) &&
510 (SPEC_BSTR(lsym->next->etype)))) break;
512 lilist = lilist->next;
516 //tfprintf (oFile, "\t!db !constbyte\n",ival);
517 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
521 //tfprintf (oFile, "\t!dw !constword\n",ival);
522 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
523 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
526 //tfprintf (oFile, "\t!db !constword,!constword\n",(ival >> 8) & 0xffff, (ival & 0xffff));
527 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>24)));
528 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>16)));
529 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
530 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
537 /*-----------------------------------------------------------------*/
538 /* printIvalStruct - generates initial value for structures */
539 /*-----------------------------------------------------------------*/
540 static void printIvalStruct (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
543 initList *iloop = NULL;
545 sflds = SPEC_STRUCT (type)->fields;
548 if (ilist->type != INIT_DEEP) {
549 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
553 iloop = ilist->init.deep;
556 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
557 if (IS_BITFIELD(sflds->type)) {
558 printIvalBitFields(&sflds,&iloop,pb);
560 printIval (sym, sflds->type, iloop, pb);
564 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
569 /*-----------------------------------------------------------------*/
570 /* printIvalChar - generates initital value for character array */
571 /*-----------------------------------------------------------------*/
573 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
581 //fprintf(stderr, "%s\n",__FUNCTION__);
585 val = list2val (ilist);
587 /* if the value is a character string */
588 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
590 ilen = DCL_ELEM(val->type);
592 if (!DCL_ELEM (type))
593 DCL_ELEM (type) = ilen;
595 /* emit string constant */
596 for (remain = 0; remain < ilen; remain++) {
597 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain])));
600 /* fill array up to desired size */
601 if ((remain = (DCL_ELEM (type) - ilen)) > 0)
603 //tfprintf (oFile, "\t!db !constbyte\n", 0);
604 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
611 //printChar (oFile, s, strlen (s) + 1);
613 for(remain=0; remain<(int)strlen(s); remain++) {
614 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
615 //fprintf(stderr,"0x%02x ",s[remain]);
617 //fprintf(stderr,"\n");
622 /*-----------------------------------------------------------------*/
623 /* printIvalArray - generates code for array initialization */
624 /*-----------------------------------------------------------------*/
626 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
635 /* take care of the special case */
636 /* array of characters can be init */
638 if (IS_CHAR (type->next)) {
639 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
640 if (!IS_LITERAL(list2val(ilist)->etype)) {
641 werror (W_INIT_WRONG);
644 if (printIvalChar (type,
645 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
646 pb, SPEC_CVAL (sym->etype).v_char))
649 /* not the special case */
650 if (ilist->type != INIT_DEEP) {
651 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
655 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
656 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
657 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
660 printIval (sym, type->next, iloop, pb);
664 if (DCL_ELEM(type)) {
665 // pad with zeros if needed
666 if (size<DCL_ELEM(type)) {
667 size = (DCL_ELEM(type) - size) * getSize(type->next);
669 //tfprintf (oFile, "\t!db !constbyte\n", 0);
670 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
674 // we have not been given a size, but we now know it
675 DCL_ELEM (type) = size;
681 /*-----------------------------------------------------------------*/
682 /* printIvalPtr - generates code for initial value of pointers */
683 /*-----------------------------------------------------------------*/
684 extern value *initPointer (initList *, sym_link *toType);
687 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
694 fprintf (stderr, "FIXME: initializers for pointers...\n");
695 printTypeChain (type, stderr);
697 fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
698 fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
700 if (ilist && (ilist->type == INIT_DEEP))
701 ilist = ilist->init.deep;
703 /* function pointers */
704 if (IS_FUNC (type->next))
706 assert ( !"function pointers not yet handled" );
707 //printIvalFuncPtr (type, ilist, pb);
710 if (!(val = initPointer (ilist, type)))
713 if (IS_CHAR (type->next))
715 if (printIvalChar (type, ilist, pb, NULL)) return;
719 if (compareType (type, val->type) == 0)
721 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
722 printFromToType (val->type, type);
725 if (IS_LITERAL (val->etype))
727 switch (getSize (type))
730 fprintf (stderr, "BYTE: %i\n", (unsigned char)floatFromVal (val) & 0x00FF);
733 fprintf (stderr, "WORD: %i\n", (unsigned int)floatFromVal (val) & 0x00FFFF);
735 case 3: /* gneric pointers */
736 assert ( !"generic pointers not yet handled" );
738 fprintf (stderr, "LONG: %i\n", (unsigned int)floatFromVal (val) & 0x0000FFFFFFFF);
741 assert ( !"invaild size of value -- aborting" );
747 /* now handle symbolic values */
748 switch (getSize (type))
751 fprintf (stderr, "BYTE: %s", val->name);
754 fprintf (stderr, "WORD: %s", val->name);
757 fprintf (stderr, "LONG: %s", val->name);
760 assert ( !"invalid size of (symbolic) value -- aborting" );
764 /*-----------------------------------------------------------------*/
765 /* printIval - generates code for initial value */
766 /*-----------------------------------------------------------------*/
768 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
773 /* if structure then */
774 if (IS_STRUCT (type))
776 //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname);
777 printIvalStruct (sym, type, ilist, pb);
781 /* if this is an array */
784 //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname);
785 printIvalArray (sym, type, ilist, pb);
789 /* if this is a pointer */
792 //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname);
793 printIvalPtr (sym, type, ilist, pb);
797 /* if type is SPECIFIER */
800 //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname);
801 printIvalType (sym, type, ilist, pb);
807 extern void pCodeConstString(char *name, char *value);
808 /*-----------------------------------------------------------------*/
809 /* emitStaticSeg - emitcode for the static segment */
810 /*-----------------------------------------------------------------*/
812 pic14emitStaticSeg (memmap * map)
816 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
818 //fprintf(stderr, "%s\n",__FUNCTION__);
820 /* for all variables in this segment do */
821 for (sym = setFirstItem (map->syms); sym;
822 sym = setNextItem (map->syms))
824 /* if extern then add it into the extern list */
825 if (IS_EXTERN (sym->etype)) {
826 addSetHead (&externs, sym);
830 /* if it is not static add it to the public
832 if (!IS_STATIC (sym->etype))
833 addSetHead (&publics, sym);
835 /* print extra debug info if required */
836 if (options.debug || sym->level == 0)
840 if (IS_STATIC (sym->etype))
841 dbuf_printf (&code->oBuf, "F%s_", moduleName); /* scope is file */
843 dbuf_printf (&code->oBuf, "G_"); /* scope is global */
846 /* symbol is local */
847 dbuf_printf (&code->oBuf, "L%s_",
848 (sym->localof ? sym->localof->name : "-null-"));
849 dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
853 /* if it has an absolute address */
854 if (SPEC_ABSA (sym->etype))
856 if (options.debug || sym->level == 0)
857 dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
859 dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n",
861 SPEC_ADDR (sym->etype));
865 if (options.debug || sym->level == 0)
866 dbuf_printf (&code->oBuf, " == .\n");
868 /* if it has an initial value */
874 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
876 resolveIvalSym (sym->ival, sym->type);
877 //printIval (sym, sym->type, sym->ival, &code->oBuf);
878 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
880 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
882 printIval (sym, sym->type, sym->ival, pb);
890 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
891 /* special case for character strings */
892 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
893 SPEC_CVAL (sym->etype).v_char)
894 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
895 /*printChar (code->oFile,
896 SPEC_CVAL (sym->etype).v_char,
897 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
899 dbuf_printf (&code->oBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
907 /*-----------------------------------------------------------------*/
908 /* emitMaps - emits the code for the data portion the code */
909 /*-----------------------------------------------------------------*/
913 pic14_constructAbsMap (&sfr->oBuf);
914 /* no special considerations for the following
915 data, idata & bit & xdata */
916 pic14emitRegularMap (data, TRUE, TRUE);
917 pic14emitRegularMap (idata, TRUE, TRUE);
918 pic14emitRegularMap (bit, TRUE, FALSE);
919 pic14emitRegularMap (xdata, TRUE, TRUE);
920 pic14emitRegularMap (sfr, TRUE, FALSE);
921 pic14emitRegularMap (sfrbit, FALSE, FALSE);
922 pic14emitRegularMap (code, TRUE, FALSE);
923 pic14emitStaticSeg (statsg);
924 pic14emitStaticSeg (c_abs);
927 /*-----------------------------------------------------------------*/
928 /* createInterruptVect - creates the interrupt vector */
929 /*-----------------------------------------------------------------*/
930 pCodeOp *popGetExternal (char *str);
932 pic14createInterruptVect (struct dbuf_s * vBuf)
934 mainf = newSymbol ("main", 0);
937 /* only if the main function exists */
938 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
940 struct options *op = &options;
941 if (!(op->cc_only || noAssemble))
942 // werror (E_NO_MAIN);
943 fprintf(stderr,"WARNING: function 'main' undefined\n");
947 /* if the main is only a prototype ie. no body then do nothing */
948 if (!IFFUNC_HASBODY(mainf->type))
950 /* if ! compile only then main function should be present */
951 if (!(options.cc_only || noAssemble))
952 // werror (E_NO_MAIN);
953 fprintf(stderr,"WARNING: function 'main' undefined\n");
957 dbuf_printf (vBuf, "%s", iComments2);
958 dbuf_printf (vBuf, "; reset vector \n");
959 dbuf_printf (vBuf, "%s", iComments2);
960 dbuf_printf (vBuf, "STARTUP\t%s\n", CODE_NAME); // Lkr file should place section STARTUP at address 0x0
961 dbuf_printf (vBuf, "\tnop\n"); /* first location for used by incircuit debugger */
962 dbuf_printf (vBuf, "\tpagesel __sdcc_gsinit_startup\n");
963 dbuf_printf (vBuf, "\tgoto\t__sdcc_gsinit_startup\n");
964 popGetExternal("__sdcc_gsinit_startup");
968 /*-----------------------------------------------------------------*/
969 /* initialComments - puts in some initial comments */
970 /*-----------------------------------------------------------------*/
972 pic14initialComments (FILE * afile)
974 initialComments (afile);
975 fprintf (afile, "; PIC port for the 14-bit core\n");
976 fprintf (afile, iComments2);
981 pic14_stringInSet(const char *str, set **world, int autoAdd)
988 for (s = setFirstItem(*world); s; s = setNextItem(*world))
991 if (0 == strcmp(s, str)) return 1;
995 if (autoAdd) addSet(world, Safe_strdup(str));
1000 pic14_emitSymbolIfNew(FILE *file, const char *fmt, const char *sym, int checkLocals)
1002 if (!pic14_stringInSet(sym, &emitted, 1)) {
1003 /* sym was not in emittedSymbols */
1004 if (!checkLocals || !pic14_stringInSet(sym, &pic14_localFunctions, 0)) {
1005 /* sym is not a locally defined function---avoid bug #1443651 */
1006 fprintf( file, fmt, sym );
1013 /*-------------------------------------------------------------------*/
1014 /* emitSymbol - write a symbol definition only if it is not */
1015 /* already present */
1016 /*-------------------------------------------------------------------*/
1019 emitSymbol (struct dbuf_s *oBuf, const char *name, const char *section_type, int size, int addr, int useEQU, int globalize)
1021 static unsigned int sec_idx = 0;
1023 /* workaround: variables declared via `sbit' result in a numeric
1024 * identifier (0xHH), EQU'ing them is invalid, so just ignore it.
1025 * sbit is heavily used in the inc2h-generated header files!
1027 if (!is_valid_identifier(name))
1029 //fprintf( stderr, "%s:%s:%u: ignored symbol: %s\n", __FILE__, __FUNCTION__, __LINE__, name );
1033 /* check whether the symbol is already defined */
1034 if (pic14_stringInSet(name, &emitted, 1)) return;
1036 /* new symbol -- define it */
1037 //fprintf (stderr, "%s: emitting %s (%d)\n", __FUNCTION__, name, size);
1039 dbuf_printf (oBuf, "%s\tEQU\t0x%04x\n", name, addr);
1041 /* we place each symbol into a section of its own to allow the linker
1042 * to distribute the data into all available memory banks */
1043 if (!section_type) section_type = "udata";
1046 /* absolute symbols are handled in pic14_constructAbsMap */
1049 if (globalize) dbuf_printf (oBuf, "\tglobal\t%s\n", name);
1050 dbuf_printf (oBuf, "udata_%s_%u\t%s\n", moduleName,
1051 sec_idx++, section_type);
1052 dbuf_printf (oBuf, "%s\tres\t%d\n", name, size);
1057 /*-----------------------------------------------------------------*/
1058 /* printExterns - generates extern for external variables */
1059 /*-----------------------------------------------------------------*/
1061 pic14printExterns (FILE * afile)
1065 fprintf (afile, "%s", iComments2);
1066 fprintf (afile, "; extern variables in this module\n");
1067 fprintf (afile, "%s", iComments2);
1069 for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
1070 pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
1073 /*-----------------------------------------------------------------*/
1074 /* printPublics - generates .global for publics */
1075 /*-----------------------------------------------------------------*/
1077 pic14printPublics (FILE * afile)
1081 fprintf (afile, "%s", iComments2);
1082 fprintf (afile, "; public variables in this module\n");
1083 fprintf (afile, "%s", iComments2);
1085 for (sym = setFirstItem (publics); sym;
1086 sym = setNextItem (publics)) {
1088 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) {
1089 if (!IS_BITVAR(sym->type))
1090 pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
1092 /* Absolute variables are defines in the asm file as equates and thus can not be made global. */
1093 /* Not any longer! */
1094 //if (!SPEC_ABSA (sym->etype))
1095 pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
1101 pic14printLocals (FILE * afile)
1103 set *allregs[6] = { dynAllocRegs, dynStackRegs, dynProcessorRegs, dynDirectRegs, dynDirectBitRegs, dynInternalRegs };
1108 dbuf_init(&dbuf, 1024);
1109 /* emit all registers from all possible sets */
1110 for (i = 0; i < 6; i++) {
1111 if (allregs[i] == NULL) continue;
1113 for (reg = setFirstItem(allregs[i]); reg; reg = setNextItem(allregs[i])) {
1114 if (reg->isEmitted) continue;
1116 if (reg->wasUsed && !reg->isExtern) {
1117 emitSymbol(&dbuf, reg->name, "udata", reg->size, reg->isFixed ? reg->address : -1, 0, reg->isPublic);
1122 dbuf_write_and_destroy(&dbuf, afile);
1125 /*-----------------------------------------------------------------*/
1126 /* emitOverlay - will emit code for the overlay stuff */
1127 /*-----------------------------------------------------------------*/
1129 pic14emitOverlay (struct dbuf_s * aBuf)
1133 /* if (!elementsInSet (ovrSetSets))*/
1135 /* the hack below, fixes translates for devices which
1136 * only have udata_shr memory */
1137 dbuf_printf (aBuf, "%s\t%s\n",
1138 (elementsInSet(ovrSetSets)?"":";"),
1139 port->mem.overlay_name);
1141 /* for each of the sets in the overlay segment do */
1142 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1143 ovrset = setNextItem (ovrSetSets))
1148 if (elementsInSet (ovrset))
1150 /* this dummy area is used to fool the assembler
1151 otherwise the assembler will append each of these
1152 declarations into one chunk and will not overlay
1155 /* I don't think this applies to us. We are using gpasm. CRF */
1157 dbuf_printf (aBuf, ";\t.area _DUMMY\n");
1158 /* output the area informtion */
1159 dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1162 for (sym = setFirstItem (ovrset); sym;
1163 sym = setNextItem (ovrset))
1166 /* if extern then do nothing */
1167 if (IS_EXTERN (sym->etype))
1170 /* if allocation required check is needed
1171 then check if the symbol really requires
1172 allocation only for local variables */
1173 if (!IS_AGGREGATE (sym->type) &&
1174 !(sym->_isparm && !IS_REGPARM (sym->etype))
1175 && !sym->allocreq && sym->level)
1178 /* if global variable & not static or extern
1179 and addPublics allowed then add it to the public set */
1180 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1181 && !IS_STATIC (sym->etype))
1182 addSetHead (&publics, sym);
1184 /* if extern then do nothing or is a function
1186 if (IS_FUNC (sym->type))
1189 /* print extra debug info if required */
1190 if (options.debug || sym->level == 0)
1194 if (IS_STATIC (sym->etype))
1195 dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */
1197 dbuf_printf (aBuf, "G_"); /* scope is global */
1200 /* symbol is local */
1201 dbuf_printf (aBuf, "L%s_",
1202 (sym->localof ? sym->localof->name : "-null-"));
1203 dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
1206 /* if is has an absolute address then generate
1207 an equate for this no need to allocate space */
1208 if (SPEC_ABSA (sym->etype))
1211 if (options.debug || sym->level == 0)
1212 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1214 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1216 SPEC_ADDR (sym->etype));
1220 if (options.debug || sym->level == 0)
1221 dbuf_printf (aBuf, "==.\n");
1223 /* allocate space */
1224 dbuf_printf (aBuf, "%s:\n", sym->rname);
1225 dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1234 pic14_emitInterruptHandler (FILE * asmFile)
1236 if (pic14_hasInterrupt)
1239 fprintf (asmFile, "%s", iComments2);
1240 fprintf (asmFile, "; interrupt and initialization code\n");
1241 fprintf (asmFile, "%s", iComments2);
1242 // Note - for mplink may have to enlarge section vectors in .lnk file
1243 // Note: Do NOT name this code_interrupt to avoid nameclashes with
1244 // source files's code segment (interrupt.c -> code_interrupt)
1245 fprintf (asmFile, "c_interrupt\t%s\t0x4\n", CODE_NAME);
1247 /* interrupt service routine */
1248 fprintf (asmFile, "__sdcc_interrupt\n");
1249 copypCode(asmFile, 'I');
1253 /*-----------------------------------------------------------------*/
1254 /* glue - the final glue that hold the whole thing together */
1255 /*-----------------------------------------------------------------*/
1259 char udata_name[80];
1261 struct dbuf_s ovrBuf;
1264 dbuf_init(&ovrBuf, 4096);
1265 dbuf_init(&vBuf, 4096);
1267 pCodeInitRegisters();
1269 /* check for main() */
1270 mainf = newSymbol ("main", 0);
1272 mainf = findSymWithLevel (SymbolTab, mainf);
1274 if (!mainf || !IFFUNC_HASBODY(mainf->type))
1276 /* main missing -- import stack from main module */
1277 //fprintf (stderr, "main() missing -- assuming we are NOT the main module\n");
1278 pic14_options.isLibrarySource = 1;
1282 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1284 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
1287 /* entry point @ start of CSEG */
1288 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
1289 /* put in the call to main */
1290 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
1292 if (options.mainreturn) {
1294 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
1295 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
1299 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
1300 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
1306 /* At this point we've got all the code in the form of pCode structures */
1307 /* Now it needs to be rearranged into the order it should be placed in the */
1310 movepBlock2Head('P'); // Last
1311 movepBlock2Head(code->dbName);
1312 movepBlock2Head('X');
1313 movepBlock2Head(statsg->dbName); // First
1316 /* print the global struct definitions */
1320 /* emit code for the all the variables declared */
1322 /* do the overlay segments */
1323 pic14emitOverlay(&ovrBuf);
1325 /* PENDING: this isnt the best place but it will do */
1326 if (port->general.glue_up_main) {
1327 /* create the interrupt vector table */
1328 pic14createInterruptVect (&vBuf);
1333 ReuseReg(); // ReuseReg where call tree permits
1342 /* now put it all together into the assembler file */
1343 /* create the assembler file name */
1345 if ((noAssemble || options.c1mode) && fullDstFileName)
1347 sprintf (buffer, fullDstFileName);
1351 sprintf (buffer, dstFileName);
1352 strcat (buffer, ".asm");
1355 if (!(asmFile = fopen (buffer, "w"))) {
1356 werror (E_FILE_OPEN_ERR, buffer);
1360 /* prepare statistics */
1361 resetpCodeStatistics ();
1363 /* initial comments */
1364 pic14initialComments (asmFile);
1366 /* print module name */
1367 fprintf (asmFile, ";\t.module %s\n", moduleName);
1369 /* Let the port generate any global directives, etc. */
1370 if (port->genAssemblerPreamble)
1372 port->genAssemblerPreamble(asmFile);
1375 /* Emit the __config directive */
1376 pic14_emitConfigWord (asmFile);
1378 /* print the global variables in this module */
1379 pic14printPublics (asmFile);
1381 /* print the extern variables in this module */
1382 pic14printExterns (asmFile);
1384 /* copy the sfr segment */
1385 fprintf (asmFile, "%s", iComments2);
1386 fprintf (asmFile, "; special function registers\n");
1387 fprintf (asmFile, "%s", iComments2);
1388 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1391 if (udata_section_name) {
1392 sprintf(udata_name,"%s",udata_section_name);
1394 sprintf(udata_name,"data_%s",moduleName);
1396 fprintf (asmFile, "%s", iComments2);
1397 fprintf (asmFile, "; udata\n");
1398 fprintf (asmFile, "%s", iComments2);
1399 fprintf (asmFile, "%s\tudata\n", udata_name);
1400 dbuf_write_and_destroy(&data->oBuf, asmFile);
1402 /* Put all variables into a cblock */
1405 /* print the locally defined variables in this module */
1406 writeUsedRegs(asmFile);
1407 pic14printLocals (asmFile);
1409 /* create the overlay segments */
1410 fprintf (asmFile, "%s", iComments2);
1411 fprintf (asmFile, "; overlayable items in internal ram \n");
1412 fprintf (asmFile, "%s", iComments2);
1413 dbuf_write_and_destroy (&ovrBuf, asmFile);
1417 /* create the stack segment MOF */
1418 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1419 fprintf (asmFile, "%s", iComments2);
1420 fprintf (asmFile, "; Stack segment in internal ram \n");
1421 fprintf (asmFile, "%s", iComments2);
1422 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1423 ";__start__stack:\n;\t.ds\t1\n\n");
1426 /* create the idata segment */
1427 fprintf (asmFile, "%s", iComments2);
1428 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1429 fprintf (asmFile, "%s", iComments2);
1430 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1432 /* if external stack then reserve space of it */
1433 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1434 fprintf (asmFile, "%s", iComments2);
1435 fprintf (asmFile, "; external stack \n");
1436 fprintf (asmFile, "%s", iComments2);
1437 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1438 fprintf (asmFile,";\t.ds 256\n");
1441 /* copy xtern ram data */
1442 fprintf (asmFile, "%s", iComments2);
1443 fprintf (asmFile, "; external ram data\n");
1444 fprintf (asmFile, "%s", iComments2);
1445 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1449 /* copy the bit segment */
1450 fprintf (asmFile, "%s", iComments2);
1451 fprintf (asmFile, "; bit data\n");
1452 fprintf (asmFile, "%s", iComments2);
1453 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1455 /* emit initialized data */
1456 showAllMemmaps(asmFile);
1458 /* copy the interrupt vector table */
1459 if (mainf && IFFUNC_HASBODY(mainf->type))
1460 dbuf_write_and_destroy (&vBuf, asmFile);
1462 dbuf_destroy(&vBuf);
1464 /* create interupt ventor handler */
1465 pic14_emitInterruptHandler (asmFile);
1467 /* copy over code */
1468 fprintf (asmFile, "%s", iComments2);
1469 fprintf (asmFile, "; code\n");
1470 fprintf (asmFile, "%s", iComments2);
1471 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
1474 copypCode(asmFile, 'X');
1476 /* _main function */
1477 copypCode(asmFile, 'M');
1479 /* other functions */
1480 copypCode(asmFile, code->dbName);
1483 copypCode(asmFile, 'P');
1485 dumppCodeStatistics (asmFile);
1487 fprintf (asmFile,"\tend\n");
1493 * Deal with initializers.
1498 #define DEBUGprintf printf
1501 #define DEBUGprintf 1 ? (void)0 : (void)printf
1505 void ast_print (ast * tree, FILE *outfile, int indent);
1512 showInitList(initList *list, int level)
1514 static const char *list_type[] = { "INIT_NODE", "INIT_DEEP", "INIT_HOLE" };
1515 static const char *ast_type[] = { "EX_OP", "EX_VALUE", "EX_LINK", "EX_OPERAND" };
1518 printf (" %d: type %u (%s), init %p, next %p\n", level, list->type, list_type[list->type], list->init.node, list->next);
1519 if (list->type == INIT_DEEP) {
1520 showInitList(list->init.deep, level + 1);
1521 } else if (list->type == INIT_NODE) {
1522 ast = list->init.node;
1523 printf (" type %u (%s), level %d, block %d, seqPoint %d\n",
1524 ast->type, ast_type[ast->type], ast->level, ast->block, ast->seqPoint);
1525 if (ast->type == EX_VALUE) {
1526 printf (" VAL %lf\n", floatFromVal(ast->opval.val));
1527 } else if (ast->type == EX_LINK) {
1528 printTypeChain(ast->opval.lnk, NULL);
1529 } else if (ast->type == EX_OP) {
1530 printf (" OP %u\n", ast->opval.op);
1539 * DEBUG: Print a value.
1542 printVal(value *val)
1544 printf ("value %p: name %s, type %p, etype %p, sym %s, vArgs %d, lit 0x%lx/%ld\n",
1545 val, val->name, val->type, val->etype,
1546 val->sym ? val->sym->name : NULL, val->vArgs,
1547 (long)floatFromVal(val), (long)floatFromVal(val));
1548 printTypeChain(val->type, stdout);
1550 printTypeChain(val->etype, stdout);
1554 //prototype from ../SDCCicode.c
1555 operand *operandFromAst (ast * tree,int lvl);
1558 parseIvalAst (ast *node, int *inCodeSpace) {
1560 char *buffer = NULL;
1563 if (IS_AST_VALUE(node)) {
1564 value *val = AST_VALUE(node);
1565 symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
1566 if (inCodeSpace && val->type
1567 && (IS_FUNC(val->type) || IS_CODE(getSpec(val->type))))
1571 if (inCodeSpace && sym
1572 && (IS_FUNC(sym->type)
1573 || IS_CODE(getSpec(sym->type))))
1578 DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
1579 if (IS_AST_LIT_VALUE(node)) {
1580 buffer = Safe_alloc(LEN);
1581 SNPRINTF(buffer, LEN, "0x%lx", (long)AST_LIT_VALUE(node));
1582 } else if (IS_AST_SYM_VALUE(node)) {
1583 assert ( AST_SYMBOL(node) );
1585 printf ("sym %s: ", AST_SYMBOL(node)->rname);
1586 printTypeChain(AST_SYMBOL(node)->type, stdout);
1587 printTypeChain(AST_SYMBOL(node)->etype, stdout);
1588 printf ("\n---sym %s: done\n", AST_SYMBOL(node)->rname);
1590 buffer = Safe_strdup(AST_SYMBOL(node)->rname);
1592 assert ( !"Invalid values type for initializers in AST." );
1594 } else if (IS_AST_OP(node)) {
1595 DEBUGprintf ("%s: AST_OP\n", __FUNCTION__);
1596 switch (node->opval.op) {
1598 assert (node->right);
1599 buffer = parseIvalAst(node->right, inCodeSpace);
1600 DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
1603 assert ( node->left && !node->right );
1604 buffer = parseIvalAst(node->left, inCodeSpace);
1605 DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
1608 assert (node->left && node->right );
1609 left = parseIvalAst(node->left, inCodeSpace);
1610 right = parseIvalAst(node->right, inCodeSpace);
1611 buffer = Safe_alloc(LEN);
1612 SNPRINTF(buffer, LEN, "(%s + %s)", left, right);
1613 DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
1618 assert ( node->left && node->right );
1619 assert ( IS_AST_VALUE(node->left) && AST_VALUE(node->left)->sym );
1620 right = parseIvalAst(node->right, inCodeSpace);
1621 buffer = Safe_alloc(LEN);
1622 SNPRINTF(buffer, LEN, "(%s + %u * %s)",
1623 AST_VALUE(node->left)->sym->rname, getSize(AST_VALUE(node->left)->type), right);
1625 DEBUGprintf ("%s: %s\n", __FUNCTION__, &buffer[0]);
1628 assert ( !"Unhandled operation in initializer." );
1632 assert ( !"Invalid construct in initializer." );
1639 * Emit the section preamble, absolute location (if any) and
1640 * symbol name(s) for intialized data.
1643 emitIvalLabel(FILE *of, symbol *sym)
1646 static int in_code = 0;
1649 // code or data space?
1650 if (IS_CODE(getSpec(sym->type))) {
1657 fprintf(of, "\nD_%s_%s\t%s", moduleName, sym->name, segname);
1658 if (SPEC_ABSA(getSpec(sym->type))) {
1659 // specify address for absolute symbols
1660 fprintf(of, "\t0x%04X", SPEC_ADDR(getSpec(sym->type)));
1662 fprintf(of, "\n%s\n", sym->rname);
1667 char *get_op(pCodeOp *pcop,char *buffer, size_t size);
1669 * Actually emit the initial values in .asm format.
1672 emitIvals(FILE *of, symbol *sym, initList *list, long lit, int size)
1678 int inCodeSpace = 0;
1682 assert (size <= sizeof(long));
1683 assert (!list || (list->type == INIT_NODE));
1684 node = list ? list->init.node : NULL;
1686 in_code = emitIvalLabel(of, sym);
1687 if (!in_code) fprintf (of, "\tdb\t");
1690 // initialize as zero
1691 for (i=0; i < size; i++) {
1693 fprintf (of, "\tretlw 0x00");
1695 fprintf (of, "%s0x00", (i == 0) ? "" : ", ");
1703 if (constExprTree(node) && (val = constExprValue(node, 0))) {
1704 op = operandFromValue(val);
1705 DEBUGprintf ("%s: constExpr ", __FUNCTION__);
1707 } else if (IS_AST_VALUE(node)) {
1708 op = operandFromAst(node, 0);
1709 } else if (IS_AST_OP(node)) {
1710 str = parseIvalAst(node, &inCodeSpace);
1711 DEBUGprintf("%s: AST_OP: %s\n", __FUNCTION__, str);
1714 assert ( !"Unhandled construct in intializer." );
1720 //printOperand(op, of);
1723 for (i=0; i < size; i++) {
1724 char *text = op ? aopGet(AOP(op), i, 0, 0)
1725 : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
1727 fprintf (of, "\tretlw %s\n", text);
1729 fprintf (of, "%s%s", (i == 0) ? "" : ", ", text);
1736 * For UNIONs, we first have to find the correct alternative to map the
1737 * initializer to. This function maps the structure of the initializer to
1738 * the UNION members recursively.
1739 * Returns the type of the first `fitting' member.
1742 matchIvalToUnion (initList *list, sym_link *type, int size)
1748 if (IS_PTR(type) || IS_CHAR(type) || IS_INT(type) || IS_LONG(type)
1751 if (!list || (list->type == INIT_NODE)) {
1752 DEBUGprintf ("OK, simple type\n");
1755 DEBUGprintf ("ERROR, simple type\n");
1758 } else if (IS_BITFIELD(type)) {
1759 if (!list || (list->type == INIT_NODE)) {
1760 DEBUGprintf ("OK, bitfield\n");
1763 DEBUGprintf ("ERROR, bitfield\n");
1766 } else if (IS_STRUCT(type) && SPEC_STRUCT(getSpec(type))->type == STRUCT) {
1767 if (!list || (list->type == INIT_DEEP)) {
1768 if (list) list = list->init.deep;
1769 sym = SPEC_STRUCT(type)->fields;
1771 DEBUGprintf ("Checking STRUCT member %s\n", sym->name);
1772 if (!matchIvalToUnion(list, sym->type, 0)) {
1773 DEBUGprintf ("ERROR, STRUCT member %s\n", sym->name);
1776 if (list) list = list->next;
1780 // excess initializers?
1782 DEBUGprintf ("ERROR, excess initializers\n");
1786 DEBUGprintf ("OK, struct\n");
1790 } else if (IS_STRUCT(type) && SPEC_STRUCT(getSpec(type))->type == UNION) {
1791 if (!list || (list->type == INIT_DEEP)) {
1792 if (list) list = list->init.deep;
1793 sym = SPEC_STRUCT(type)->fields;
1795 DEBUGprintf ("Checking UNION member %s.\n", sym->name);
1796 if (((IS_STRUCT(sym->type) || getSize(sym->type) == size))
1797 && matchIvalToUnion(list, sym->type, size))
1799 DEBUGprintf ("Matched UNION member %s.\n", sym->name);
1806 DEBUGprintf ("ERROR, no match found.\n");
1809 assert ( !"Unhandled type in UNION." );
1812 assert ( !"No match found in UNION for the given initializer structure." );
1817 * Parse the type and its initializer and emit it (recursively).
1820 emitInitVal(FILE *of, symbol *topsym, sym_link *my_type, initList *list)
1826 size = getSize(my_type);
1828 if (IS_PTR(my_type)) {
1829 DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL);
1830 emitIvals(of, topsym, list, 0, size);
1834 if (IS_ARRAY(my_type)) {
1835 DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
1836 assert (!list || list->type == INIT_DEEP);
1837 if (list) list = list->init.deep;
1838 for (i = 0; i < DCL_ELEM(my_type); i++) {
1839 emitInitVal(of, topsym, my_type->next, list);
1841 if (list) list = list->next;
1846 if (IS_FLOAT(my_type)) {
1848 DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
1849 emitIvals(of, topsym, list, 0, size);
1853 if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
1854 // integral type, 8, 16, or 32 bit
1855 DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
1856 emitIvals(of, topsym, list, 0, size);
1859 } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
1861 DEBUGprintf ("(struct, %d byte) handled below\n", size);
1862 assert (!list || (list->type == INIT_DEEP));
1864 // iterate over struct members and initList
1865 if (list) list = list->init.deep;
1866 sym = SPEC_STRUCT(my_type)->fields;
1870 if (IS_BITFIELD(sym->type)) {
1871 while (sym && IS_BITFIELD(sym->type)) {
1872 assert (!list || ((list->type == INIT_NODE)
1873 && IS_AST_LIT_VALUE(list->init.node)));
1874 lit = list ? list2int(list) : 0;
1875 DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
1876 lit, SPEC_BLEN(getSpec(sym->type)),
1877 SPEC_BSTR(getSpec(sym->type)), bitfield);
1878 bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << SPEC_BSTR(getSpec(sym->type));
1879 len += SPEC_BLEN(getSpec(sym->type));
1882 if (list) list = list->next;
1884 assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
1885 len = (len + 7) & ~0x07; // round up to full bytes
1886 emitIvals(of, topsym, NULL, bitfield, len / 8);
1891 emitInitVal(of, topsym, sym->type, list);
1894 if (list) list = list->next;
1898 assert ( !"Excess initializers." );
1902 } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
1904 DEBUGprintf ("(union, %d byte) handled below\n", size);
1905 assert (list && list->type == INIT_DEEP);
1907 // iterate over union members and initList, try to map number and type of fields and initializers
1908 my_type = matchIvalToUnion(list, my_type, size);
1910 emitInitVal(of, topsym, my_type, list->init.deep);
1912 size -= getSize(my_type);
1914 // pad with (leading) zeros
1915 emitIvals(of, NULL, NULL, 0, size);
1920 assert ( !"No UNION member matches the initializer structure.");
1921 } else if (IS_BITFIELD(my_type)) {
1922 assert ( !"bitfields should only occur in structs..." );
1925 printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
1926 assert( !"Unhandled initialized type.");
1931 * Iterate over all memmaps and emit their contents (attributes, symbols).
1934 showAllMemmaps(FILE *of)
1937 xstack, istack, code, data, pdata, xdata, xidata, xinit,
1938 idata, bit, statsg, c_abs, x_abs, i_abs, d_abs,
1939 sfr, sfrbit, reg, generic, overlay, eeprom, home };
1945 DEBUGprintf ("---begin memmaps---\n");
1946 for (i = 0; i < sizeof(maps) / sizeof (memmap *); i++) {
1948 //DEBUGprintf ("memmap %i: %p\n", i, map);
1951 DEBUGprintf (" pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
1952 map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
1953 map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
1954 map->codesp, map->regsp, map->syms);
1956 for (sym = setFirstItem(map->syms); sym; sym = setNextItem(map->syms)) {
1958 fprintf (of, "; name %s, rname %s, level %d, block %d, key %d, local %d, ival %p\n",
1959 sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival);
1962 //if (list) showInitList(list, 0);
1964 resolveIvalSym( list, sym->type );
1965 emitInitVal(of, sym, sym->type, sym->ival);
1970 DEBUGprintf ("---end of memmaps---\n");