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"
32 extern symbol *interrupts[256];
33 void printIval (symbol *, sym_link *, initList *, FILE *);
36 extern unsigned maxInterrupts;
37 extern int maxRegBank;
39 extern char *VersionString;
40 extern FILE *codeOutFile;
41 extern set *tmpfileSet;
42 extern set *tmpfileNameSet;
43 extern char *iComments1;
44 extern char *iComments2;
45 //extern void emitStaticSeg (memmap * map);
47 extern DEFSETFUNC (closeTmpFiles);
48 extern DEFSETFUNC (rmTmpFiles);
50 extern void copyFile (FILE * dest, FILE * src);
53 //extern void emitMaps ();
54 //extern void createInterruptVect (FILE * vFile);
55 extern void initialComments (FILE * afile);
56 extern void printPublics (FILE * afile);
58 extern void printChar (FILE * ofile, char *s, int plen);
62 aopLiteral (value * val, int offset)
63 static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
64 value *initPointer (initList * ilist)
65 void printIvalType (sym_link * type, initList * ilist, FILE * oFile)
66 void printIvalStruct (symbol * sym, sym_link * type,
67 initList * ilist, FILE * oFile)
68 int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
69 void printIvalArray (symbol * sym, sym_link * type, initList * ilist,
71 void printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
72 int printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
73 void printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
76 /*-----------------------------------------------------------------*/
77 /* Allocation macros that replace those in SDCCalloc.h */
78 /* Why? I dunno. I ran across a bug with those macros that */
79 /* I couldn't fix, but I could work around... */
80 /*-----------------------------------------------------------------*/
82 #define _ALLOC(x,sz) if (!(x = calloc((sz),1) )) \
84 werror(E_OUT_OF_MEM,__FILE__,(long) sz);\
88 #define _ALLOC_ATOMIC(x,y) if (!((x) = malloc(y))) \
90 werror(E_OUT_OF_MEM,__FILE__,(long) y); \
95 /*-----------------------------------------------------------------*/
96 /* aopLiteral - string from a literal value */
97 /*-----------------------------------------------------------------*/
98 int pic14aopLiteral (value *val, int offset)
105 /* if it is a float then it gets tricky */
106 /* otherwise it is fairly simple */
107 if (!IS_FLOAT(val->type)) {
108 unsigned long v = (unsigned long) floatFromVal(val);
110 //v >>= (offset * 8);
111 return ( (v >> (offset * 8)) & 0xff);
112 //sprintf(buffer,"0x%02x",((char) v) & 0xff);
113 //_ALLOC_ATOMIC(rs,strlen(buffer)+1);
114 //return strcpy (rs,buffer);
117 /* it is type float */
118 fl.f = (float) floatFromVal(val);
120 return fl.c[3-offset];
128 /*-----------------------------------------------------------------*/
129 /* emitRegularMap - emit code for maps with no special cases */
130 /*-----------------------------------------------------------------*/
132 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
135 int i, size, bitvars = 0;;
138 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
140 /* print the area name */
141 for (sym = setFirstItem (map->syms); sym;
142 sym = setNextItem (map->syms))
145 /* if extern then do nothing */
146 if (IS_EXTERN (sym->etype))
149 /* if allocation required check is needed
150 then check if the symbol really requires
151 allocation only for local variables */
152 if (arFlag && !IS_AGGREGATE (sym->type) &&
153 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
154 !sym->allocreq && sym->level)
157 /* if global variable & not static or extern
158 and addPublics allowed then add it to the public set */
159 if ((sym->level == 0 ||
160 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
162 !IS_STATIC (sym->etype))
163 addSetHead (&publics, sym);
165 /* if extern then do nothing or is a function
167 if (IS_FUNC (sym->type))
170 /* print extra debug info if required */
171 if (options.debug || sym->level == 0)
174 cdbSymbol (sym, cdbFile, FALSE, FALSE);
176 if (!sym->level) /* global */
177 if (IS_STATIC (sym->etype))
178 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
180 fprintf (map->oFile, "G_"); /* scope is global */
182 /* symbol is local */
183 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
184 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
188 /* if is has an absolute address then generate
189 an equate for this no need to allocate space */
190 if (SPEC_ABSA (sym->etype))
192 //if (options.debug || sym->level == 0)
193 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
195 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
197 SPEC_ADDR (sym->etype));
203 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
204 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
205 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
206 if (IS_BITVAR (sym->etype))
208 if ((bitvars % 8) == 0)
210 fprintf (map->oFile, " cblock\n");
211 fprintf (map->oFile, "\tbitfield%d\n", bitvars);
212 fprintf (map->oFile, " endc\n");
215 fprintf (map->oFile, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
224 fprintf (map->oFile, "\t%s\n", sym->rname);
225 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
227 for (i = 1; i < size; i++)
228 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
231 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
234 /* if it has a initial value then do it only if
235 it is a global variable */
236 if (sym->ival && sym->level == 0) {
239 if (IS_AGGREGATE (sym->type))
240 ival = initAggregates (sym, sym->ival, NULL);
242 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
243 decorateType (resolveSymbols (list2expr (sym->ival))));
244 codeOutFile = statsg->oFile;
246 eBBlockFromiCode (iCodeFromAst (ival));
254 /*-----------------------------------------------------------------*/
255 /* initPointer - pointer initialization code massaging */
256 /*-----------------------------------------------------------------*/
258 initPointer (initList * ilist)
261 ast *expr = list2expr (ilist);
266 /* try it the oldway first */
267 if ((val = constExprValue (expr, FALSE)))
270 /* no then we have to do these cludgy checks */
271 /* pointers can be initialized with address of
272 a variable or address of an array element */
273 if (IS_AST_OP (expr) && expr->opval.op == '&')
275 /* address of symbol */
276 if (IS_AST_SYM_VALUE (expr->left))
278 val = copyValue (AST_VALUE (expr->left));
279 val->type = newLink ();
280 if (SPEC_SCLS (expr->left->etype) == S_CODE)
282 DCL_TYPE (val->type) = CPOINTER;
283 DCL_PTR_CONST (val->type) = port->mem.code_ro;
285 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
286 DCL_TYPE (val->type) = FPOINTER;
287 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
288 DCL_TYPE (val->type) = PPOINTER;
289 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
290 DCL_TYPE (val->type) = IPOINTER;
291 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
292 DCL_TYPE (val->type) = EEPPOINTER;
294 DCL_TYPE (val->type) = POINTER;
295 val->type->next = expr->left->ftype;
296 val->etype = getSpec (val->type);
300 /* if address of indexed array */
301 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
302 return valForArray (expr->left);
304 /* if address of structure element then
306 if (IS_AST_OP (expr->left) &&
307 expr->left->opval.op == '.')
309 return valForStructElem (expr->left->left,
314 (&some_struct)->element */
315 if (IS_AST_OP (expr->left) &&
316 expr->left->opval.op == PTR_OP &&
317 IS_ADDRESS_OF_OP (expr->left->left))
318 return valForStructElem (expr->left->left->left,
323 werror (E_INIT_WRONG);
328 /*-----------------------------------------------------------------*/
329 /* printChar - formats and prints a characater string with DB */
330 /*-----------------------------------------------------------------*/
332 printChar (FILE * ofile, char *s, int plen)
335 int len = strlen (s);
338 while (len && pplen < plen)
341 fprintf (ofile, "\t.ascii /");
343 while (i && *s && pplen < plen)
345 if (*s < ' ' || *s == '/')
347 fprintf (ofile, "/\n\t.byte 0x%02x\n\t.ascii /", *s++);
350 fprintf (ofile, "%c", *s++);
354 fprintf (ofile, "/\n");
362 fprintf (ofile, "\t.byte\t0\n");
365 /*-----------------------------------------------------------------*/
366 /* printIvalType - generates ival for int/char */
367 /*-----------------------------------------------------------------*/
369 printIvalType (sym_link * type, initList * ilist, FILE * oFile)
373 /* if initList is deep */
374 if (ilist->type == INIT_DEEP)
375 ilist = ilist->init.deep;
377 val = list2val (ilist);
378 switch (getSize (type))
382 fprintf (oFile, "\t.byte 0\n");
384 fprintf (oFile, "\t.byte %s\n",
385 aopLiteral (val, 0));
390 fprintf (oFile, "\t.word 0\n");
392 fprintf (oFile, "\t.byte %s,%s\n",
393 aopLiteral (val, 0), aopLiteral (val, 1));
398 fprintf (oFile, "\t.word 0,0\n");
400 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
401 aopLiteral (val, 0), aopLiteral (val, 1),
402 aopLiteral (val, 2), aopLiteral (val, 3));
409 /*-----------------------------------------------------------------*/
410 /* printIvalStruct - generates initial value for structures */
411 /*-----------------------------------------------------------------*/
413 printIvalStruct (symbol * sym, sym_link * type,
414 initList * ilist, FILE * oFile)
419 sflds = SPEC_STRUCT (type)->fields;
420 if (ilist->type != INIT_DEEP)
422 werror (E_INIT_STRUCT, sym->name);
426 iloop = ilist->init.deep;
428 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
429 printIval (sflds, sflds->type, iloop, oFile);
434 /*-----------------------------------------------------------------*/
435 /* printIvalChar - generates initital value for character array */
436 /*-----------------------------------------------------------------*/
438 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
446 val = list2val (ilist);
447 /* if the value is a character string */
448 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
450 if (!DCL_ELEM (type))
451 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
453 /* if size mismatch */
454 /* if (DCL_ELEM (type) < ((int) strlen (SPEC_CVAL (val->etype).v_char) + 1)) */
455 /* werror (E_ARRAY_BOUND); */
457 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
459 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
461 fprintf (oFile, "\t.byte 0\n");
469 printChar (oFile, s, strlen (s) + 1);
473 /*-----------------------------------------------------------------*/
474 /* printIvalArray - generates code for array initialization */
475 /*-----------------------------------------------------------------*/
477 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
481 int lcnt = 0, size = 0;
483 /* take care of the special case */
484 /* array of characters can be init */
486 if (IS_CHAR (type->next))
487 if (printIvalChar (type,
488 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
489 oFile, SPEC_CVAL (sym->etype).v_char))
492 /* not the special case */
493 if (ilist->type != INIT_DEEP)
495 werror (E_INIT_STRUCT, sym->name);
499 iloop = ilist->init.deep;
500 lcnt = DCL_ELEM (type);
505 printIval (sym, type->next, iloop, oFile);
506 iloop = (iloop ? iloop->next : NULL);
509 /* if not array limits given & we */
510 /* are out of initialisers then */
511 if (!DCL_ELEM (type) && !iloop)
514 /* no of elements given and we */
515 /* have generated for all of them */
520 /* if we have not been given a size */
521 if (!DCL_ELEM (type))
522 DCL_ELEM (type) = size;
527 /*-----------------------------------------------------------------*/
528 /* printIvalFuncPtr - generate initial value for function pointers */
529 /*-----------------------------------------------------------------*/
531 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
536 val = list2val (ilist);
537 /* check the types */
538 if ((dLvl = checkType (val->type, type->next)) <= 0)
541 fprintf (oFile, "\t.word 0\n");
545 /* now generate the name */
548 if (IS_LITERAL (val->etype))
549 fprintf (oFile, "\t.byte %s,%s\n",
550 aopLiteral (val, 0), aopLiteral (val, 1));
552 fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
553 val->name, val->name);
556 fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
557 val->sym->rname, val->sym->rname);
562 /*-----------------------------------------------------------------*/
563 /* printIvalCharPtr - generates initial values for character pointers */
564 /*-----------------------------------------------------------------*/
566 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
570 size = getSize (type);
574 "\t.byte %s", val->name);
577 "\t.byte %s,(%s >> 8)",
578 val->name, val->name);
581 fprintf (oFile, ",#0x02\n");
583 fprintf (oFile, "\n");
585 if (val->sym && val->sym->isstrlit)
586 addSet (&statsg->syms, val->sym);
591 /*-----------------------------------------------------------------*/
592 /* printIvalPtr - generates initial value for pointers */
593 /*-----------------------------------------------------------------*/
595 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
600 if (ilist->type == INIT_DEEP)
601 ilist = ilist->init.deep;
603 /* function pointer */
604 if (IS_FUNC (type->next))
606 printIvalFuncPtr (type, ilist, oFile);
610 if (!(val = initPointer (ilist)))
613 /* if character pointer */
614 if (IS_CHAR (type->next))
615 if (printIvalCharPtr (sym, type, val, oFile))
619 if (checkType (type, val->type) != 1)
620 werror (E_INIT_WRONG);
622 /* if val is literal */
623 if (IS_LITERAL (val->etype))
625 switch (getSize (type))
628 fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff);
631 fprintf (oFile, "\t.byte %s,%s\n",
632 aopLiteral (val, 0), aopLiteral (val, 1));
636 fprintf (oFile, "\t.byte %s,%s,0x%02x\n",
637 aopLiteral (val, 0), aopLiteral (val, 1), CPOINTER);
643 switch (getSize (type))
646 fprintf (oFile, "\t.byte %s\n", val->name);
649 fprintf (oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
653 fprintf (oFile, "\t.byte %s,(%s >> 8),0x%02x\n",
654 val->name, val->name, DCL_TYPE (val->type));
659 /*-----------------------------------------------------------------*/
660 /* printIval - generates code for initial value */
661 /*-----------------------------------------------------------------*/
663 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
668 /* if structure then */
669 if (IS_STRUCT (type))
671 printIvalStruct (sym, type, ilist, oFile);
675 /* if this is a pointer */
678 printIvalPtr (sym, type, ilist, oFile);
682 /* if this is an array */
685 printIvalArray (sym, type, ilist, oFile);
689 /* if type is SPECIFIER */
692 printIvalType (type, ilist, oFile);
698 /*-----------------------------------------------------------------*/
699 /* emitStaticSeg - emitcode for the static segment */
700 /*-----------------------------------------------------------------*/
702 pic14emitStaticSeg (memmap * map)
706 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
709 /* for all variables in this segment do */
710 for (sym = setFirstItem (map->syms); sym;
711 sym = setNextItem (map->syms))
714 /* if it is "extern" then do nothing */
715 if (IS_EXTERN (sym->etype))
718 /* if it is not static add it to the public
720 if (!IS_STATIC (sym->etype))
721 addSetHead (&publics, sym);
723 /* print extra debug info if required */
724 if (options.debug || sym->level == 0)
727 cdbSymbol (sym, cdbFile, FALSE, FALSE);
731 if (IS_STATIC (sym->etype))
732 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
734 fprintf (code->oFile, "G_"); /* scope is global */
737 /* symbol is local */
738 fprintf (code->oFile, "L%s_",
739 (sym->localof ? sym->localof->name : "-null-"));
740 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
743 /* if it has an absolute address */
744 if (SPEC_ABSA (sym->etype))
746 if (options.debug || sym->level == 0)
747 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
749 fprintf (code->oFile, "%s\t=\t0x%04x\n",
751 SPEC_ADDR (sym->etype));
755 if (options.debug || sym->level == 0)
756 fprintf (code->oFile, " == .\n");
758 /* if it has an initial value */
761 fprintf (code->oFile, "%s:\n", sym->rname);
763 resolveIvalSym (sym->ival);
764 printIval (sym, sym->type, sym->ival, code->oFile);
770 fprintf (code->oFile, "%s:\n", sym->rname);
771 /* special case for character strings */
772 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
773 SPEC_CVAL (sym->etype).v_char)
774 printChar (code->oFile,
775 SPEC_CVAL (sym->etype).v_char,
776 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
778 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
785 /*-----------------------------------------------------------------*/
786 /* emitMaps - emits the code for the data portion the code */
787 /*-----------------------------------------------------------------*/
791 /* no special considerations for the following
792 data, idata & bit & xdata */
793 pic14emitRegularMap (data, TRUE, TRUE);
794 pic14emitRegularMap (idata, TRUE, TRUE);
795 pic14emitRegularMap (bit, TRUE, FALSE);
796 pic14emitRegularMap (xdata, TRUE, TRUE);
797 pic14emitRegularMap (sfr, FALSE, FALSE);
798 pic14emitRegularMap (sfrbit, FALSE, FALSE);
799 pic14emitRegularMap (code, TRUE, FALSE);
800 pic14emitStaticSeg (statsg);
803 /*-----------------------------------------------------------------*/
804 /* createInterruptVect - creates the interrupt vector */
805 /*-----------------------------------------------------------------*/
807 pic14createInterruptVect (FILE * vFile)
810 mainf = newSymbol ("main", 0);
813 /* only if the main function exists */
814 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
816 if (!options.cc_only)
821 /* if the main is only a prototype ie. no body then do nothing */
822 if (!IFFUNC_HASBODY(mainf->type))
824 /* if ! compile only then main function should be present */
825 if (!options.cc_only)
830 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
831 fprintf (vFile, ";__interrupt_vect:\n");
834 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
836 /* "generic" interrupt table header (if port doesn't specify one).
838 * Look suspiciously like 8051 code to me...
841 fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
844 /* now for the other interrupts */
845 for (; i < maxInterrupts; i++)
848 fprintf (vFile, ";\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
850 fprintf (vFile, ";\treti\n;\t.ds\t7\n");
856 /*-----------------------------------------------------------------*/
857 /* initialComments - puts in some initial comments */
858 /*-----------------------------------------------------------------*/
860 pic14initialComments (FILE * afile)
862 initialComments (afile);
863 fprintf (afile, "; PIC port for the 14-bit core\n");
864 fprintf (afile, iComments2);
868 /*-----------------------------------------------------------------*/
869 /* printPublics - generates .global for publics */
870 /*-----------------------------------------------------------------*/
872 pic14printPublics (FILE * afile)
876 fprintf (afile, "%s", iComments2);
877 fprintf (afile, "; publics variables in this module\n");
878 fprintf (afile, "%s", iComments2);
880 for (sym = setFirstItem (publics); sym;
881 sym = setNextItem (publics))
882 fprintf (afile, ";\t.globl %s\n", sym->rname);
887 /*-----------------------------------------------------------------*/
888 /* emitOverlay - will emit code for the overlay stuff */
889 /*-----------------------------------------------------------------*/
891 pic14emitOverlay (FILE * afile)
895 if (!elementsInSet (ovrSetSets))
896 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
898 /* for each of the sets in the overlay segment do */
899 for (ovrset = setFirstItem (ovrSetSets); ovrset;
900 ovrset = setNextItem (ovrSetSets))
905 if (elementsInSet (ovrset))
907 /* this dummy area is used to fool the assembler
908 otherwise the assembler will append each of these
909 declarations into one chunk and will not overlay
911 fprintf (afile, ";\t.area _DUMMY\n");
912 /* output the area informtion */
913 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
916 for (sym = setFirstItem (ovrset); sym;
917 sym = setNextItem (ovrset))
920 /* if extern then do nothing */
921 if (IS_EXTERN (sym->etype))
924 /* if allocation required check is needed
925 then check if the symbol really requires
926 allocation only for local variables */
927 if (!IS_AGGREGATE (sym->type) &&
928 !(sym->_isparm && !IS_REGPARM (sym->etype))
929 && !sym->allocreq && sym->level)
932 /* if global variable & not static or extern
933 and addPublics allowed then add it to the public set */
934 if ((sym->_isparm && !IS_REGPARM (sym->etype))
935 && !IS_STATIC (sym->etype))
936 addSetHead (&publics, sym);
938 /* if extern then do nothing or is a function
940 if (IS_FUNC (sym->type))
943 /* print extra debug info if required */
944 if (options.debug || sym->level == 0)
947 cdbSymbol (sym, cdbFile, FALSE, FALSE);
951 if (IS_STATIC (sym->etype))
952 fprintf (afile, "F%s_", moduleName); /* scope is file */
954 fprintf (afile, "G_"); /* scope is global */
957 /* symbol is local */
958 fprintf (afile, "L%s_",
959 (sym->localof ? sym->localof->name : "-null-"));
960 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
963 /* if is has an absolute address then generate
964 an equate for this no need to allocate space */
965 if (SPEC_ABSA (sym->etype))
968 if (options.debug || sym->level == 0)
969 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
971 fprintf (afile, "%s\t=\t0x%04x\n",
973 SPEC_ADDR (sym->etype));
977 if (options.debug || sym->level == 0)
978 fprintf (afile, "==.\n");
981 fprintf (afile, "%s:\n", sym->rname);
982 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
991 /*-----------------------------------------------------------------*/
992 /* glue - the final glue that hold the whole thing together */
993 /*-----------------------------------------------------------------*/
1000 FILE *ovrFile = tempfile();
1002 set *s=NULL,*t=NULL;
1010 DFPRINTF((stderr,"\n\n\n******************\n\n\n"));
1011 for(t=s; t; t=t->next) {
1013 DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
1017 for(t=s; t; t=t->next) {
1019 DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
1022 addSetHead(&tmpfileSet,ovrFile);
1025 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1027 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
1030 /* entry point @ start of CSEG */
1031 addpCode2pBlock(pb,newpCodeLabelStr("__sdcc_program_startup"));
1032 /* put in the call to main */
1033 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
1035 if (options.mainreturn) {
1037 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
1038 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
1042 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
1043 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
1049 /* At this point we've got all the code in the form of pCode structures */
1050 /* Now it needs to be rearranged into the order it should be placed in the */
1053 movepBlock2Head(code->dbName); // Last
1054 movepBlock2Head('X');
1055 movepBlock2Head(statsg->dbName); // First
1058 AnalyzepCode('*'); //code->dbName);
1060 printCallTree(stderr);
1063 /* print the global struct definitions */
1065 cdbStructBlock (0,cdbFile);
1068 /* PENDING: this isnt the best place but it will do */
1069 if (port->general.glue_up_main) {
1070 /* create the interrupt vector table */
1071 pic14createInterruptVect (vFile);
1074 addSetHead(&tmpfileSet,vFile);
1076 /* emit code for the all the variables declared */
1078 /* do the overlay segments */
1079 pic14emitOverlay(ovrFile);
1085 /* now put it all together into the assembler file */
1086 /* create the assembler file name */
1088 if (!options.c1mode) {
1089 sprintf (buffer, srcFileName);
1090 strcat (buffer, ".asm");
1093 strcpy(buffer, options.out_name);
1096 if (!(asmFile = fopen (buffer, "w"))) {
1097 werror (E_FILE_OPEN_ERR, buffer);
1101 /* initial comments */
1102 pic14initialComments (asmFile);
1104 /* print module name */
1105 fprintf (asmFile, ";\t.module %s\n", moduleName);
1107 /* Let the port generate any global directives, etc. */
1108 if (port->genAssemblerPreamble)
1110 port->genAssemblerPreamble(asmFile);
1113 /* print the global variables in this module */
1114 pic14printPublics (asmFile);
1117 /* copy the sfr segment */
1118 fprintf (asmFile, "%s", iComments2);
1119 fprintf (asmFile, "; special function registers\n");
1120 fprintf (asmFile, "%s", iComments2);
1121 copyFile (asmFile, sfr->oFile);
1124 /* Put all variables into a cblock */
1125 fprintf (asmFile, "\n\n\tcblock 0x20\n\n");
1127 for(i=0; i<pic14_nRegs; i++) {
1128 if(regspic14[i].wasUsed && (regspic14[i].offset>=0x0c) )
1129 fprintf (asmFile, "\t%s\n",regspic14[i].name);
1133 /* For now, create a "dpl" and a "dph" in the register space */
1134 /* of the pic so that we can use the same calling mechanism */
1135 /* as the 8051 port */
1136 fprintf (asmFile, "%s", iComments2);
1137 fprintf (asmFile, "; dpl and dph to emulate the 8051 calling mechanism \n");
1138 fprintf (asmFile, "%s", iComments2);
1141 /* copy the sbit segment */
1142 fprintf (asmFile, "%s", iComments2);
1143 fprintf (asmFile, "; special function bits \n");
1144 fprintf (asmFile, "%s", iComments2);
1145 copyFile (asmFile, sfrbit->oFile);
1147 /* copy the data segment */
1148 fprintf (asmFile, "%s", iComments2);
1149 fprintf (asmFile, "; internal ram data\n");
1150 fprintf (asmFile, "%s", iComments2);
1151 copyFile (asmFile, data->oFile);
1153 fprintf (asmFile, "\tendc\n");
1156 /* create the overlay segments */
1157 fprintf (asmFile, "%s", iComments2);
1158 fprintf (asmFile, "; overlayable items in internal ram \n");
1159 fprintf (asmFile, "%s", iComments2);
1160 copyFile (asmFile, ovrFile);
1162 /* create the stack segment MOF */
1163 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1164 fprintf (asmFile, "%s", iComments2);
1165 fprintf (asmFile, "; Stack segment in internal ram \n");
1166 fprintf (asmFile, "%s", iComments2);
1167 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1168 ";__start__stack:\n;\t.ds\t1\n\n");
1171 /* create the idata segment */
1172 fprintf (asmFile, "%s", iComments2);
1173 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1174 fprintf (asmFile, "%s", iComments2);
1175 copyFile (asmFile, idata->oFile);
1177 /* if external stack then reserve space of it */
1178 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1179 fprintf (asmFile, "%s", iComments2);
1180 fprintf (asmFile, "; external stack \n");
1181 fprintf (asmFile, "%s", iComments2);
1182 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1183 fprintf (asmFile,";\t.ds 256\n");
1187 /* copy xtern ram data */
1188 fprintf (asmFile, "%s", iComments2);
1189 fprintf (asmFile, "; external ram data\n");
1190 fprintf (asmFile, "%s", iComments2);
1191 copyFile (asmFile, xdata->oFile);
1194 /* copy the bit segment */
1195 fprintf (asmFile, "%s", iComments2);
1196 fprintf (asmFile, "; bit data\n");
1197 fprintf (asmFile, "%s", iComments2);
1198 copyFile (asmFile, bit->oFile);
1201 fprintf (asmFile, "\tORG 0\n");
1203 /* copy the interrupt vector table */
1204 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1205 fprintf (asmFile, "%s", iComments2);
1206 fprintf (asmFile, "; interrupt vector \n");
1207 fprintf (asmFile, "%s", iComments2);
1208 copyFile (asmFile, vFile);
1211 /* copy global & static initialisations */
1212 fprintf (asmFile, "%s", iComments2);
1213 fprintf (asmFile, "; global & static initialisations\n");
1214 fprintf (asmFile, "%s", iComments2);
1216 /* Everywhere we generate a reference to the static_name area,
1217 * (which is currently only here), we immediately follow it with a
1218 * definition of the post_static_name area. This guarantees that
1219 * the post_static_name area will immediately follow the static_name
1222 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
1223 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1224 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
1226 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1227 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
1228 /* if external stack is specified then the
1229 higher order byte of the xdatalocation is
1230 going into P2 and the lower order going into
1232 if (options.useXstack) {
1233 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1234 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1235 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1236 (unsigned int)options.xdata_loc & 0xff);
1241 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1243 /* This code is generated in the post-static area.
1244 * This area is guaranteed to follow the static area
1245 * by the ugly shucking and jiving about 20 lines ago.
1247 fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
1248 fprintf (asmFile,";\tljmp\t__sdcc_program_startup\n");
1251 /* copy over code */
1252 fprintf (asmFile, "%s", iComments2);
1253 fprintf (asmFile, "; code\n");
1254 fprintf (asmFile, "%s", iComments2);
1255 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
1257 //copyFile (asmFile, code->oFile);
1259 copypCode(asmFile, statsg->dbName);
1260 copypCode(asmFile, 'X');
1261 copypCode(asmFile, code->dbName);
1264 fprintf (asmFile,"\tend\n");
1267 applyToSet(tmpfileSet,closeTmpFiles);
1268 applyToSet(tmpfileNameSet, rmTmpFiles);