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"
30 extern symbol *interrupts[256];
31 void printIval (symbol *, sym_link *, initList *, FILE *);
34 extern int maxInterrupts;
35 extern int maxRegBank;
37 extern char *VersionString;
38 extern FILE *codeOutFile;
39 extern set *tmpfileSet;
40 extern set *tmpfileNameSet;
41 extern char *iComments1;
42 extern char *iComments2;
43 //extern void emitStaticSeg (memmap * map);
45 extern DEFSETFUNC (closeTmpFiles);
46 extern DEFSETFUNC (rmTmpFiles);
48 extern void copyFile (FILE * dest, FILE * src);
51 //extern void emitMaps ();
52 //extern void createInterruptVect (FILE * vFile);
53 extern void initialComments (FILE * afile);
54 extern void printPublics (FILE * afile);
56 extern void printChar (FILE * ofile, char *s, int plen);
60 aopLiteral (value * val, int offset)
61 static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
62 value *initPointer (initList * ilist)
63 void printIvalType (sym_link * type, initList * ilist, FILE * oFile)
64 void printIvalStruct (symbol * sym, sym_link * type,
65 initList * ilist, FILE * oFile)
66 int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
67 void printIvalArray (symbol * sym, sym_link * type, initList * ilist,
69 void printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
70 int printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
71 void printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
75 /*-----------------------------------------------------------------*/
76 /* aopLiteral - string from a literal value */
77 /*-----------------------------------------------------------------*/
78 char *pic14aopLiteral (value * val, int offset)
88 /* if it is a float then it gets tricky */
89 /* otherwise it is fairly simple */
90 if (!IS_FLOAT (val->type))
92 unsigned long v = floatFromVal (val);
95 sprintf (buffer, "0x%02x", ((char) v) & 0xff);
96 rs = Safe_calloc (1, strlen (buffer) + 1);
97 return strcpy (rs, buffer);
100 /* it is type float */
101 fl.f = (float) floatFromVal (val);
103 sprintf (buffer, "0x%02x", fl.c[3 - offset]);
105 sprintf (buffer, "0x%02x", fl.c[offset]);
107 rs = Safe_calloc (1, strlen (buffer) + 1);
108 return strcpy (rs, buffer);
112 /*-----------------------------------------------------------------*/
113 /* emitRegularMap - emit code for maps with no special cases */
114 /*-----------------------------------------------------------------*/
116 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
119 int i, size, bitvars = 0;;
122 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
124 /* print the area name */
125 for (sym = setFirstItem (map->syms); sym;
126 sym = setNextItem (map->syms))
129 /* if extern then do nothing */
130 if (IS_EXTERN (sym->etype))
133 /* if allocation required check is needed
134 then check if the symbol really requires
135 allocation only for local variables */
136 if (arFlag && !IS_AGGREGATE (sym->type) &&
137 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
138 !sym->allocreq && sym->level)
141 /* if global variable & not static or extern
142 and addPublics allowed then add it to the public set */
143 if ((sym->level == 0 ||
144 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
146 !IS_STATIC (sym->etype))
147 addSetHead (&publics, sym);
149 /* if extern then do nothing or is a function
151 if (IS_FUNC (sym->type))
154 /* print extra debug info if required */
155 if (options.debug || sym->level == 0)
158 cdbSymbol (sym, cdbFile, FALSE, FALSE);
160 if (!sym->level) /* global */
161 if (IS_STATIC (sym->etype))
162 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
164 fprintf (map->oFile, "G_"); /* scope is global */
166 /* symbol is local */
167 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
168 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
172 /* if is has an absolute address then generate
173 an equate for this no need to allocate space */
174 if (SPEC_ABSA (sym->etype))
176 //if (options.debug || sym->level == 0)
177 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
179 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
181 SPEC_ADDR (sym->etype));
187 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
188 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
189 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
190 if (IS_BITVAR (sym->etype))
192 if ((bitvars % 8) == 0)
194 fprintf (map->oFile, " cblock\n");
195 fprintf (map->oFile, "\tbitfield%d\n", bitvars);
196 fprintf (map->oFile, " endc\n");
199 fprintf (map->oFile, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
208 fprintf (map->oFile, "\t%s\n", sym->rname);
209 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
211 for (i = 1; i < size; i++)
212 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
215 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
218 /* if it has a initial value then do it only if
219 it is a global variable */
220 if (sym->ival && sym->level == 0)
224 if (IS_AGGREGATE (sym->type))
225 ival = initAggregates (sym, sym->ival, NULL);
227 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
228 decorateType (resolveSymbols (list2expr (sym->ival))));
229 codeOutFile = statsg->oFile;
230 eBBlockFromiCode (iCodeFromAst (ival));
238 /*-----------------------------------------------------------------*/
239 /* initPointer - pointer initialization code massaging */
240 /*-----------------------------------------------------------------*/
242 initPointer (initList * ilist)
245 ast *expr = list2expr (ilist);
250 /* try it the oldway first */
251 if ((val = constExprValue (expr, FALSE)))
254 /* no then we have to do these cludgy checks */
255 /* pointers can be initialized with address of
256 a variable or address of an array element */
257 if (IS_AST_OP (expr) && expr->opval.op == '&')
259 /* address of symbol */
260 if (IS_AST_SYM_VALUE (expr->left))
262 val = copyValue (AST_VALUE (expr->left));
263 val->type = newLink ();
264 if (SPEC_SCLS (expr->left->etype) == S_CODE)
266 DCL_TYPE (val->type) = CPOINTER;
267 DCL_PTR_CONST (val->type) = port->mem.code_ro;
269 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
270 DCL_TYPE (val->type) = FPOINTER;
271 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
272 DCL_TYPE (val->type) = PPOINTER;
273 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
274 DCL_TYPE (val->type) = IPOINTER;
275 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
276 DCL_TYPE (val->type) = EEPPOINTER;
278 DCL_TYPE (val->type) = POINTER;
279 val->type->next = expr->left->ftype;
280 val->etype = getSpec (val->type);
284 /* if address of indexed array */
285 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
286 return valForArray (expr->left);
288 /* if address of structure element then
290 if (IS_AST_OP (expr->left) &&
291 expr->left->opval.op == '.')
293 return valForStructElem (expr->left->left,
298 (&some_struct)->element */
299 if (IS_AST_OP (expr->left) &&
300 expr->left->opval.op == PTR_OP &&
301 IS_ADDRESS_OF_OP (expr->left->left))
302 return valForStructElem (expr->left->left->left,
307 werror (E_INIT_WRONG);
312 /*-----------------------------------------------------------------*/
313 /* printChar - formats and prints a characater string with DB */
314 /*-----------------------------------------------------------------*/
316 printChar (FILE * ofile, char *s, int plen)
319 int len = strlen (s);
322 while (len && pplen < plen)
325 fprintf (ofile, "\t.ascii /");
327 while (i && *s && pplen < plen)
329 if (*s < ' ' || *s == '/')
331 fprintf (ofile, "/\n\t.byte 0x%02x\n\t.ascii /", *s++);
334 fprintf (ofile, "%c", *s++);
338 fprintf (ofile, "/\n");
346 fprintf (ofile, "\t.byte\t0\n");
349 /*-----------------------------------------------------------------*/
350 /* printIvalType - generates ival for int/char */
351 /*-----------------------------------------------------------------*/
353 printIvalType (sym_link * type, initList * ilist, FILE * oFile)
357 /* if initList is deep */
358 if (ilist->type == INIT_DEEP)
359 ilist = ilist->init.deep;
361 val = list2val (ilist);
362 switch (getSize (type))
366 fprintf (oFile, "\t.byte 0\n");
368 fprintf (oFile, "\t.byte %s\n",
369 aopLiteral (val, 0));
374 fprintf (oFile, "\t.word 0\n");
376 fprintf (oFile, "\t.byte %s,%s\n",
377 aopLiteral (val, 0), aopLiteral (val, 1));
382 fprintf (oFile, "\t.word 0,0\n");
384 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
385 aopLiteral (val, 0), aopLiteral (val, 1),
386 aopLiteral (val, 2), aopLiteral (val, 3));
393 /*-----------------------------------------------------------------*/
394 /* printIvalStruct - generates initial value for structures */
395 /*-----------------------------------------------------------------*/
397 printIvalStruct (symbol * sym, sym_link * type,
398 initList * ilist, FILE * oFile)
403 sflds = SPEC_STRUCT (type)->fields;
404 if (ilist->type != INIT_DEEP)
406 werror (E_INIT_STRUCT, sym->name);
410 iloop = ilist->init.deep;
412 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
413 printIval (sflds, sflds->type, iloop, oFile);
418 /*-----------------------------------------------------------------*/
419 /* printIvalChar - generates initital value for character array */
420 /*-----------------------------------------------------------------*/
422 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
430 val = list2val (ilist);
431 /* if the value is a character string */
432 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
434 if (!DCL_ELEM (type))
435 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
437 /* if size mismatch */
438 /* if (DCL_ELEM (type) < ((int) strlen (SPEC_CVAL (val->etype).v_char) + 1)) */
439 /* werror (E_ARRAY_BOUND); */
441 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
443 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
445 fprintf (oFile, "\t.byte 0\n");
453 printChar (oFile, s, strlen (s) + 1);
457 /*-----------------------------------------------------------------*/
458 /* printIvalArray - generates code for array initialization */
459 /*-----------------------------------------------------------------*/
461 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
465 int lcnt = 0, size = 0;
467 /* take care of the special case */
468 /* array of characters can be init */
470 if (IS_CHAR (type->next))
471 if (printIvalChar (type,
472 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
473 oFile, SPEC_CVAL (sym->etype).v_char))
476 /* not the special case */
477 if (ilist->type != INIT_DEEP)
479 werror (E_INIT_STRUCT, sym->name);
483 iloop = ilist->init.deep;
484 lcnt = DCL_ELEM (type);
489 printIval (sym, type->next, iloop, oFile);
490 iloop = (iloop ? iloop->next : NULL);
493 /* if not array limits given & we */
494 /* are out of initialisers then */
495 if (!DCL_ELEM (type) && !iloop)
498 /* no of elements given and we */
499 /* have generated for all of them */
504 /* if we have not been given a size */
505 if (!DCL_ELEM (type))
506 DCL_ELEM (type) = size;
511 /*-----------------------------------------------------------------*/
512 /* printIvalFuncPtr - generate initial value for function pointers */
513 /*-----------------------------------------------------------------*/
515 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
520 val = list2val (ilist);
521 /* check the types */
522 if ((dLvl = checkType (val->type, type->next)) <= 0)
525 fprintf (oFile, "\t.word 0\n");
529 /* now generate the name */
532 if (IS_LITERAL (val->etype))
533 fprintf (oFile, "\t.byte %s,%s\n",
534 aopLiteral (val, 0), aopLiteral (val, 1));
536 fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
537 val->name, val->name);
540 fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
541 val->sym->rname, val->sym->rname);
546 /*-----------------------------------------------------------------*/
547 /* printIvalCharPtr - generates initial values for character pointers */
548 /*-----------------------------------------------------------------*/
550 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
554 size = getSize (type);
558 "\t.byte %s", val->name);
561 "\t.byte %s,(%s >> 8)",
562 val->name, val->name);
565 fprintf (oFile, ",#0x02\n");
567 fprintf (oFile, "\n");
569 if (val->sym && val->sym->isstrlit)
570 addSet (&statsg->syms, val->sym);
575 /*-----------------------------------------------------------------*/
576 /* printIvalPtr - generates initial value for pointers */
577 /*-----------------------------------------------------------------*/
579 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
584 if (ilist->type == INIT_DEEP)
585 ilist = ilist->init.deep;
587 /* function pointer */
588 if (IS_FUNC (type->next))
590 printIvalFuncPtr (type, ilist, oFile);
594 if (!(val = initPointer (ilist)))
597 /* if character pointer */
598 if (IS_CHAR (type->next))
599 if (printIvalCharPtr (sym, type, val, oFile))
603 if (checkType (type, val->type) != 1)
604 werror (E_INIT_WRONG);
606 /* if val is literal */
607 if (IS_LITERAL (val->etype))
609 switch (getSize (type))
612 fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff);
615 fprintf (oFile, "\t.byte %s,%s\n",
616 aopLiteral (val, 0), aopLiteral (val, 1));
620 fprintf (oFile, "\t.byte %s,%s,0x%02x\n",
621 aopLiteral (val, 0), aopLiteral (val, 1), CPOINTER);
627 switch (getSize (type))
630 fprintf (oFile, "\t.byte %s\n", val->name);
633 fprintf (oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
637 fprintf (oFile, "\t.byte %s,(%s >> 8),0x%02x\n",
638 val->name, val->name, DCL_TYPE (val->type));
643 /*-----------------------------------------------------------------*/
644 /* printIval - generates code for initial value */
645 /*-----------------------------------------------------------------*/
647 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
652 /* if structure then */
653 if (IS_STRUCT (type))
655 printIvalStruct (sym, type, ilist, oFile);
659 /* if this is a pointer */
662 printIvalPtr (sym, type, ilist, oFile);
666 /* if this is an array */
669 printIvalArray (sym, type, ilist, oFile);
673 /* if type is SPECIFIER */
676 printIvalType (type, ilist, oFile);
682 /*-----------------------------------------------------------------*/
683 /* emitStaticSeg - emitcode for the static segment */
684 /*-----------------------------------------------------------------*/
686 pic14emitStaticSeg (memmap * map)
690 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
693 /* for all variables in this segment do */
694 for (sym = setFirstItem (map->syms); sym;
695 sym = setNextItem (map->syms))
698 /* if it is "extern" then do nothing */
699 if (IS_EXTERN (sym->etype))
702 /* if it is not static add it to the public
704 if (!IS_STATIC (sym->etype))
705 addSetHead (&publics, sym);
707 /* print extra debug info if required */
708 if (options.debug || sym->level == 0)
711 cdbSymbol (sym, cdbFile, FALSE, FALSE);
715 if (IS_STATIC (sym->etype))
716 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
718 fprintf (code->oFile, "G_"); /* scope is global */
721 /* symbol is local */
722 fprintf (code->oFile, "L%s_",
723 (sym->localof ? sym->localof->name : "-null-"));
724 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
727 /* if it has an absolute address */
728 if (SPEC_ABSA (sym->etype))
730 if (options.debug || sym->level == 0)
731 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
733 fprintf (code->oFile, "%s\t=\t0x%04x\n",
735 SPEC_ADDR (sym->etype));
739 if (options.debug || sym->level == 0)
740 fprintf (code->oFile, " == .\n");
742 /* if it has an initial value */
745 fprintf (code->oFile, "%s:\n", sym->rname);
747 resolveIvalSym (sym->ival);
748 printIval (sym, sym->type, sym->ival, code->oFile);
754 fprintf (code->oFile, "%s:\n", sym->rname);
755 /* special case for character strings */
756 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
757 SPEC_CVAL (sym->etype).v_char)
758 printChar (code->oFile,
759 SPEC_CVAL (sym->etype).v_char,
760 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
762 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
769 /*-----------------------------------------------------------------*/
770 /* emitMaps - emits the code for the data portion the code */
771 /*-----------------------------------------------------------------*/
775 /* no special considerations for the following
776 data, idata & bit & xdata */
777 pic14emitRegularMap (data, TRUE, TRUE);
778 pic14emitRegularMap (idata, TRUE, TRUE);
779 pic14emitRegularMap (bit, TRUE, FALSE);
780 pic14emitRegularMap (xdata, TRUE, TRUE);
781 pic14emitRegularMap (sfr, FALSE, FALSE);
782 pic14emitRegularMap (sfrbit, FALSE, FALSE);
783 pic14emitRegularMap (code, TRUE, FALSE);
784 pic14emitStaticSeg (statsg);
787 /*-----------------------------------------------------------------*/
788 /* createInterruptVect - creates the interrupt vector */
789 /*-----------------------------------------------------------------*/
791 pic14createInterruptVect (FILE * vFile)
794 mainf = newSymbol ("main", 0);
797 /* only if the main function exists */
798 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
800 if (!options.cc_only)
805 /* if the main is only a prototype ie. no body then do nothing */
808 /* if ! compile only then main function should be present */
809 if (!options.cc_only)
814 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
815 fprintf (vFile, ";__interrupt_vect:\n");
818 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
820 /* "generic" interrupt table header (if port doesn't specify one).
822 * Look suspiciously like 8051 code to me...
825 fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
828 /* now for the other interrupts */
829 for (; i < maxInterrupts; i++)
832 fprintf (vFile, ";\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
834 fprintf (vFile, ";\treti\n;\t.ds\t7\n");
840 /*-----------------------------------------------------------------*/
841 /* initialComments - puts in some initial comments */
842 /*-----------------------------------------------------------------*/
844 pic14initialComments (FILE * afile)
846 initialComments (afile);
847 fprintf (afile, "; PIC port for the 14-bit core\n");
848 fprintf (afile, iComments2);
852 /*-----------------------------------------------------------------*/
853 /* printPublics - generates .global for publics */
854 /*-----------------------------------------------------------------*/
856 pic14printPublics (FILE * afile)
860 fprintf (afile, "%s", iComments2);
861 fprintf (afile, "; publics variables in this module\n");
862 fprintf (afile, "%s", iComments2);
864 for (sym = setFirstItem (publics); sym;
865 sym = setNextItem (publics))
866 fprintf (afile, ";\t.globl %s\n", sym->rname);
871 /*-----------------------------------------------------------------*/
872 /* emitOverlay - will emit code for the overlay stuff */
873 /*-----------------------------------------------------------------*/
875 pic14emitOverlay (FILE * afile)
879 if (!elementsInSet (ovrSetSets))
880 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
882 /* for each of the sets in the overlay segment do */
883 for (ovrset = setFirstItem (ovrSetSets); ovrset;
884 ovrset = setNextItem (ovrSetSets))
889 if (elementsInSet (ovrset))
891 /* this dummy area is used to fool the assembler
892 otherwise the assembler will append each of these
893 declarations into one chunk and will not overlay
895 fprintf (afile, ";\t.area _DUMMY\n");
896 /* output the area informtion */
897 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
900 for (sym = setFirstItem (ovrset); sym;
901 sym = setNextItem (ovrset))
904 /* if extern then do nothing */
905 if (IS_EXTERN (sym->etype))
908 /* if allocation required check is needed
909 then check if the symbol really requires
910 allocation only for local variables */
911 if (!IS_AGGREGATE (sym->type) &&
912 !(sym->_isparm && !IS_REGPARM (sym->etype))
913 && !sym->allocreq && sym->level)
916 /* if global variable & not static or extern
917 and addPublics allowed then add it to the public set */
918 if ((sym->_isparm && !IS_REGPARM (sym->etype))
919 && !IS_STATIC (sym->etype))
920 addSetHead (&publics, sym);
922 /* if extern then do nothing or is a function
924 if (IS_FUNC (sym->type))
927 /* print extra debug info if required */
928 if (options.debug || sym->level == 0)
931 cdbSymbol (sym, cdbFile, FALSE, FALSE);
935 if (IS_STATIC (sym->etype))
936 fprintf (afile, "F%s_", moduleName); /* scope is file */
938 fprintf (afile, "G_"); /* scope is global */
941 /* symbol is local */
942 fprintf (afile, "L%s_",
943 (sym->localof ? sym->localof->name : "-null-"));
944 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
947 /* if is has an absolute address then generate
948 an equate for this no need to allocate space */
949 if (SPEC_ABSA (sym->etype))
952 if (options.debug || sym->level == 0)
953 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
955 fprintf (afile, "%s\t=\t0x%04x\n",
957 SPEC_ADDR (sym->etype));
961 if (options.debug || sym->level == 0)
962 fprintf (afile, "==.\n");
965 fprintf (afile, "%s:\n", sym->rname);
966 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
975 /*-----------------------------------------------------------------*/
976 /* glue - the final glue that hold the whole thing together */
977 /*-----------------------------------------------------------------*/
983 FILE *ovrFile = tempfile ();
986 addSetHead (&tmpfileSet, ovrFile);
987 /* print the global struct definitions */
989 cdbStructBlock (0, cdbFile);
992 /* PENDING: this isnt the best place but it will do */
993 if (port->general.glue_up_main)
995 /* create the interrupt vector table */
996 pic14createInterruptVect (vFile);
999 addSetHead (&tmpfileSet, vFile);
1001 /* emit code for the all the variables declared */
1003 /* do the overlay segments */
1004 pic14emitOverlay (ovrFile);
1006 /* now put it all together into the assembler file */
1007 /* create the assembler file name */
1009 if (!options.c1mode)
1011 sprintf (buffer, srcFileName);
1012 strcat (buffer, ".asm");
1016 strcpy (buffer, options.out_name);
1019 if (!(asmFile = fopen (buffer, "w")))
1021 werror (E_FILE_OPEN_ERR, buffer);
1025 /* initial comments */
1026 pic14initialComments (asmFile);
1028 /* print module name */
1029 fprintf (asmFile, ";\t.module %s\n", moduleName);
1031 /* Let the port generate any global directives, etc. */
1032 if (port->genAssemblerPreamble)
1034 port->genAssemblerPreamble (asmFile);
1037 /* print the global variables in this module */
1038 pic14printPublics (asmFile);
1041 /* copy the sfr segment */
1042 fprintf (asmFile, "%s", iComments2);
1043 fprintf (asmFile, "; special function registers\n");
1044 fprintf (asmFile, "%s", iComments2);
1045 copyFile (asmFile, sfr->oFile);
1048 /* Put all variables into a cblock */
1049 fprintf (asmFile, "\n\n\tcblock 0x13\n\n");
1051 for (i = 0; i < pic14_nRegs; i++)
1053 if (regspic14[i].wasUsed && (regspic14[i].offset >= 0x0c))
1054 fprintf (asmFile, "\t%s\n", regspic14[i].name);
1056 //fprintf (asmFile, "\tr0x0C\n");
1057 //fprintf (asmFile, "\tr0x0D\n");
1059 /* For now, create a "dpl" and a "dph" in the register space */
1060 /* of the pic so that we can use the same calling mechanism */
1061 /* as the 8051 port */
1062 fprintf (asmFile, "%s", iComments2);
1063 fprintf (asmFile, "; dpl and dph to emulate the 8051 calling mechanism \n");
1064 fprintf (asmFile, "%s", iComments2);
1066 fprintf (asmFile, "\tdph\n");
1070 /* copy the sbit segment */
1071 fprintf (asmFile, "%s", iComments2);
1072 fprintf (asmFile, "; special function bits \n");
1073 fprintf (asmFile, "%s", iComments2);
1074 copyFile (asmFile, sfrbit->oFile);
1076 /* copy the data segment */
1077 fprintf (asmFile, "%s", iComments2);
1078 fprintf (asmFile, "; internal ram data\n");
1079 fprintf (asmFile, "%s", iComments2);
1080 copyFile (asmFile, data->oFile);
1083 /* create the overlay segments */
1084 fprintf (asmFile, "%s", iComments2);
1085 fprintf (asmFile, "; overlayable items in internal ram \n");
1086 fprintf (asmFile, "%s", iComments2);
1087 copyFile (asmFile, ovrFile);
1089 /* create the stack segment MOF */
1090 if (mainf && mainf->fbody)
1092 fprintf (asmFile, "%s", iComments2);
1093 fprintf (asmFile, "; Stack segment in internal ram \n");
1094 fprintf (asmFile, "%s", iComments2);
1095 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1096 ";__start__stack:\n;\t.ds\t1\n\n");
1099 /* create the idata segment */
1100 fprintf (asmFile, "%s", iComments2);
1101 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1102 fprintf (asmFile, "%s", iComments2);
1103 copyFile (asmFile, idata->oFile);
1105 /* if external stack then reserve space of it */
1106 if (mainf && mainf->fbody && options.useXstack)
1108 fprintf (asmFile, "%s", iComments2);
1109 fprintf (asmFile, "; external stack \n");
1110 fprintf (asmFile, "%s", iComments2);
1111 fprintf (asmFile, ";\t.area XSEG (XDATA)\n"); /* MOF */
1112 fprintf (asmFile, ";\t.ds 256\n");
1116 /* copy xtern ram data */
1117 fprintf (asmFile, "%s", iComments2);
1118 fprintf (asmFile, "; external ram data\n");
1119 fprintf (asmFile, "%s", iComments2);
1120 copyFile (asmFile, xdata->oFile);
1123 fprintf (asmFile, "\tendc\n");
1126 /* copy the bit segment */
1127 fprintf (asmFile, "%s", iComments2);
1128 fprintf (asmFile, "; bit data\n");
1129 fprintf (asmFile, "%s", iComments2);
1130 copyFile (asmFile, bit->oFile);
1133 fprintf (asmFile, "\tORG 0\n");
1135 /* copy the interrupt vector table */
1136 if (mainf && mainf->fbody)
1138 fprintf (asmFile, "%s", iComments2);
1139 fprintf (asmFile, "; interrupt vector \n");
1140 fprintf (asmFile, "%s", iComments2);
1141 copyFile (asmFile, vFile);
1144 /* copy global & static initialisations */
1145 fprintf (asmFile, "%s", iComments2);
1146 fprintf (asmFile, "; global & static initialisations\n");
1147 fprintf (asmFile, "%s", iComments2);
1149 /* Everywhere we generate a reference to the static_name area,
1150 * (which is currently only here), we immediately follow it with a
1151 * definition of the post_static_name area. This guarantees that
1152 * the post_static_name area will immediately follow the static_name
1155 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
1156 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1157 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
1159 if (mainf && mainf->fbody)
1161 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1162 /* if external stack is specified then the
1163 higher order byte of the xdatalocation is
1164 going into P2 and the lower order going into
1166 if (options.useXstack)
1168 fprintf (asmFile, ";\tmov\tP2,#0x%02x\n",
1169 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1170 fprintf (asmFile, ";\tmov\t_spx,#0x%02x\n",
1171 (unsigned int) options.xdata_loc & 0xff);
1174 /* initialise the stack pointer */
1175 /* if the user specified a value then use it */
1176 if (options.stack_loc)
1177 fprintf (asmFile, ";\tmov\tsp,#%d\n", options.stack_loc);
1179 /* no: we have to compute it */
1180 if (!options.stackOnData && maxRegBank <= 3)
1181 fprintf (asmFile, ";\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1);
1183 fprintf (asmFile, ";\tmov\tsp,#__start__stack\n"); /* MOF */
1185 fprintf (asmFile, ";\tlcall\t__sdcc_external_startup\n");
1186 fprintf (asmFile, ";\tmov\ta,dpl\n");
1187 fprintf (asmFile, ";\tjz\t__sdcc_init_data\n");
1188 fprintf (asmFile, ";\tljmp\t__sdcc_program_startup\n");
1189 fprintf (asmFile, ";__sdcc_init_data:\n");
1192 copyFile (asmFile, statsg->oFile);
1194 if (port->general.glue_up_main && mainf && mainf->fbody)
1196 /* This code is generated in the post-static area.
1197 * This area is guaranteed to follow the static area
1198 * by the ugly shucking and jiving about 20 lines ago.
1200 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1201 fprintf (asmFile, ";\tljmp\t__sdcc_program_startup\n");
1204 /* copy over code */
1205 fprintf (asmFile, "%s", iComments2);
1206 fprintf (asmFile, "; code\n");
1207 fprintf (asmFile, "%s", iComments2);
1208 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
1209 if (mainf && mainf->fbody)
1212 /* entry point @ start of CSEG */
1213 fprintf (asmFile, "__sdcc_program_startup:\n");
1215 /* put in the call to main */
1216 fprintf (asmFile, "\tcall\t_main\n");
1217 if (options.mainreturn)
1220 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1221 fprintf (asmFile, "\treturn\n");
1227 fprintf (asmFile, ";\treturn from main will lock up\n");
1228 fprintf (asmFile, "\tgoto\t$\n");
1231 copyFile (asmFile, code->oFile);
1233 fprintf (asmFile, "\tend\n");
1236 applyToSet (tmpfileSet, closeTmpFiles);
1237 applyToSet (tmpfileNameSet, rmTmpFiles);