1 /*-----------------------------------------------------------------*/
2 /* SDCCmem.c - 8051 memory management routines */
3 /*-----------------------------------------------------------------*/
6 #include "dbuf_string.h"
9 memmap *xstack = NULL; /* xternal stack data */
10 memmap *istack = NULL; /* internal stack */
11 memmap *code = NULL; /* code segment */
12 memmap *data = NULL; /* internal data upto 128 */
13 memmap *pdata = NULL; /* paged external data */
14 memmap *xdata = NULL; /* external data */
15 memmap *xidata = NULL; /* the initialized xdata */
16 memmap *xinit = NULL; /* the initializers for xidata */
17 memmap *idata = NULL; /* internal data upto 256 */
18 memmap *bit = NULL; /* bit addressable space */
19 memmap *statsg = NULL; /* the constant data segment */
20 memmap *c_abs = NULL; /* constant absolute data */
21 memmap *x_abs = NULL; /* absolute xdata/pdata */
22 memmap *i_abs = NULL; /* absolute idata upto 256 */
23 memmap *d_abs = NULL; /* absolute data upto 128 */
24 memmap *sfr = NULL; /* register space */
25 memmap *reg = NULL; /* register space */
26 memmap *sfrbit = NULL; /* sfr bit space */
27 memmap *generic = NULL; /* is a generic pointer */
28 memmap *overlay = NULL; /* overlay segment */
29 memmap *eeprom = NULL; /* eeprom location */
30 memmap *home = NULL; /* Unswitchable code bank */
32 /* this is a set of sets each set containing
33 symbols in a single overlay */
34 set *ovrSetSets = NULL;
36 int fatalError = 0; /* fatal error flag */
38 /*-----------------------------------------------------------------*/
39 /* allocMap - allocates a memory map */
40 /*-----------------------------------------------------------------*/
42 allocMap (char rspace, /* sfr space */
43 char farmap, /* far or near segment */
44 char paged, /* can this segment be paged */
45 char direct, /* directly addressable */
46 char bitaddr, /* bit addressable space */
47 char codemap, /* this is code space */
48 unsigned sloc, /* starting location */
49 const char *name, /* 2 character name */
50 char dbName, /* debug name */
51 int ptrType /* pointer type for this space */
56 if (!(map = Safe_alloc (sizeof (memmap))))
58 werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
62 memset (map, ZERO, sizeof (memmap));
68 map->codesp = codemap;
72 map->ptrType = ptrType;
75 dbuf_init(&map->oBuf, 4096);
80 /*-----------------------------------------------------------------*/
81 /* initMem - allocates and initializes all the segments */
82 /*-----------------------------------------------------------------*/
86 /* allocate all the segments */
87 /* xternal stack segment ;
95 POINTER-TYPE - FPOINTER
97 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
99 /* internal stack segment ;
107 POINTER-TYPE - POINTER
111 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
126 POINTER-TYPE - CPOINTER
128 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
138 POINTER-TYPE - CPOINTER
140 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER);
142 /* Static segment (code for variables );
150 POINTER-TYPE - CPOINTER
152 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
154 /* Constant Absolute Data segment (for variables );
162 POINTER-TYPE - CPOINTER
164 c_abs = allocMap (0, 1, 0, 0, 0, 1, 0, CABS_NAME, 'D', CPOINTER);
166 /* Data segment - internal storage segment ;
174 POINTER-TYPE - POINTER
176 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
178 /* Absolute internal storage segment ;
186 POINTER-TYPE - POINTER
190 d_abs = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, IABS_NAME, 'E', POINTER);
197 /* overlay segment - same as internal storage segment ;
205 POINTER-TYPE - POINTER
209 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
216 /* Xternal paged segment ;
224 POINTER-TYPE - PPOINTER
228 pdata = allocMap (0, 0, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
235 /* Xternal Data segment -
243 POINTER-TYPE - FPOINTER
245 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
246 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
247 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
249 /* Absolute external storage segment ;
257 POINTER-TYPE - FPOINTER
261 x_abs = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XABS_NAME, 'F', FPOINTER);
268 /* Indirectly addressed internal data segment
276 POINTER-TYPE - IPOINTER
280 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
287 /* Indirectly addressed absolute internal segment
295 POINTER-TYPE - IPOINTER
299 i_abs = allocMap (0, 0, 0, 0, 0, 0, options.data_loc, IABS_NAME, 'E', IPOINTER);
314 POINTER-TYPE - _NONE_
316 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
318 /* Special function register space :-
326 POINTER-TYPE - _NONE_
328 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
338 POINTER-TYPE - _NONE_
340 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
350 POINTER-TYPE - _NONE_
352 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
362 POINTER-TYPE - EEPPOINTER
364 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
366 /* the unknown map */
367 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
371 /*-----------------------------------------------------------------*/
372 /* allocIntoSeg - puts a symbol into a memory segment */
373 /*-----------------------------------------------------------------*/
375 allocIntoSeg (symbol * sym)
377 memmap *segment = SPEC_OCLS (sym->etype);
378 addSet (&segment->syms, sym);
379 if (segment == pdata)
383 /*-----------------------------------------------------------------*/
384 /* deleteFromSeg - deletes a symbol from segment used when a var */
385 /* first declared as "extern" then no extern */
386 /*-----------------------------------------------------------------*/
387 void deleteFromSeg(symbol *sym)
389 if (SPEC_OCLS(sym->etype)) {
390 memmap *segment = SPEC_OCLS (sym->etype);
391 deleteSetItem(&segment->syms,sym);
395 /*-----------------------------------------------------------------*/
396 /* allocDefault - assigns the output segment based on SCLASS */
397 /*-----------------------------------------------------------------*/
399 allocDefault (symbol * sym)
401 switch (SPEC_SCLS (sym->etype))
404 SPEC_OCLS (sym->etype) = sfr;
407 SPEC_OCLS (sym->etype) = sfrbit;
412 /* if code change to constant */
413 if (sym->ival && SPEC_ABSA (sym->etype))
415 SPEC_OCLS(sym->etype) = c_abs;
419 SPEC_OCLS (sym->etype) = statsg;
423 /* absolute initialized global */
424 if (sym->ival && SPEC_ABSA (sym->etype))
426 SPEC_OCLS(sym->etype) = x_abs;
428 /* or should we move this to the initialized data segment? */
429 else if (port->genXINIT && sym->ival && (sym->level==0))
431 SPEC_OCLS(sym->etype) = xidata;
435 SPEC_OCLS (sym->etype) = xdata;
439 /* absolute initialized global */
440 if (sym->ival && SPEC_ABSA (sym->etype))
442 SPEC_OCLS(sym->etype) = d_abs;
446 SPEC_OCLS (sym->etype) = data;
450 /* absolute initialized global */
451 if (sym->ival && SPEC_ABSA (sym->etype))
453 SPEC_OCLS(sym->etype) = i_abs;
457 SPEC_OCLS (sym->etype) = idata;
462 SPEC_OCLS (sym->etype) = pdata;
466 SPEC_OCLS (sym->etype) = bit;
469 SPEC_OCLS (sym->etype) = eeprom;
478 /*-----------------------------------------------------------------*/
479 /* allocGlobal - assigns the output segment to a global var */
480 /*-----------------------------------------------------------------*/
482 allocGlobal (symbol * sym)
485 /* symbol name is internal name */
486 if (!sym->level) /* local statics can come here */
487 SNPRINTF (sym->rname, sizeof(sym->rname),
488 "%s%s", port->fun_prefix, sym->name);
490 /* add it to the operandKey reset */
491 if (!isinSet (operKeyReset, sym)) {
492 addSet(&operKeyReset, sym);
495 /* if this is a literal e.g. enumerated type */
496 /* put it in the data segment & do nothing */
497 if (IS_LITERAL (sym->etype))
499 SPEC_OCLS (sym->etype) = data;
503 /* if this is a function then assign code space */
504 if (IS_FUNC (sym->type))
506 SPEC_OCLS (sym->etype) = code;
507 /* if this is an interrupt service routine
508 then put it in the interrupt service array */
509 if (FUNC_ISISR (sym->type) && !options.noiv
510 && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
512 if (interrupts[FUNC_INTNO (sym->type)])
513 werror (E_INT_DEFINED,
514 FUNC_INTNO (sym->type),
515 interrupts[FUNC_INTNO (sym->type)]->name);
517 interrupts[FUNC_INTNO (sym->type)] = sym;
519 /* automagically extend the maximum interrupts */
520 if (FUNC_INTNO (sym->type) >= maxInterrupts)
521 maxInterrupts = FUNC_INTNO (sym->type) + 1;
523 /* if it is not compiler defined */
530 /* if this is a bit variable and no storage class */
531 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
532 /*&& SPEC_SCLS (sym->etype) == S_BIT*/
534 SPEC_OCLS (sym->type) = bit;
539 if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
540 /* register storage class ignored changed to FIXED */
541 if (SPEC_SCLS (sym->etype) == S_REGISTER)
542 SPEC_SCLS (sym->etype) = S_FIXED;
544 /* if it is fixed, then allocate depending on the */
545 /* current memory model, same for automatics */
546 if (SPEC_SCLS (sym->etype) == S_FIXED ||
547 (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
548 SPEC_SCLS (sym->etype) == S_AUTO) {
549 if (port->mem.default_globl_map != xdata) {
550 /* set the output class */
551 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
552 /* generate the symbol */
556 SPEC_SCLS (sym->etype) = S_XDATA;
564 /*-----------------------------------------------------------------*/
565 /* allocParms - parameters are always passed on stack */
566 /*-----------------------------------------------------------------*/
568 allocParms (value * val)
573 for (lval = val; lval; lval = lval->next, pNum++)
575 /* check the declaration */
576 checkDecl (lval->sym, 0);
578 /* if this a register parm then allocate
579 it as a local variable by adding it
580 to the first block we see in the body */
581 if (IS_REGPARM (lval->etype))
584 /* mark it as my parameter */
585 lval->sym->ismyparm = 1;
586 lval->sym->localof = currFunc;
588 /* if automatic variables r 2b stacked */
589 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
592 lval->sym->onStack = 1;
594 /* choose which stack 2 use */
595 /* use xternal stack */
596 if (options.useXstack)
598 /* PENDING: stack direction support */
599 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
600 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
601 xstackPtr - getSize (lval->type);
602 xstackPtr -= getSize (lval->type);
605 { /* use internal stack */
606 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
607 if (port->stack.direction > 0)
609 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
610 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
611 getSize (lval->type) -
612 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
613 stackPtr -= getSize (lval->type);
617 /* This looks like the wrong order but it turns out OK... */
618 /* PENDING: isr, bank overhead, ... */
619 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
621 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
622 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
624 stackPtr += getSize (lval->type);
627 allocIntoSeg (lval->sym);
630 { /* allocate them in the automatic space */
631 /* generate a unique name */
632 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
633 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
634 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
636 /* if declared in specific storage */
637 if (allocDefault (lval->sym))
639 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
643 /* otherwise depending on the memory model */
644 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
645 port->mem.default_local_map;
646 if (options.model == MODEL_SMALL)
648 /* note here that we put it into the overlay segment
649 first, we will remove it from the overlay segment
650 after the overlay determination has been done */
651 if (!options.noOverlay)
653 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
657 else if (options.model == MODEL_MEDIUM)
659 SPEC_SCLS (lval->etype) = S_PDATA;
663 SPEC_SCLS (lval->etype) = S_XDATA;
665 allocIntoSeg (lval->sym);
671 /*-----------------------------------------------------------------*/
672 /* deallocParms - parameters are always passed on stack */
673 /*-----------------------------------------------------------------*/
675 deallocParms (value * val)
679 for (lval = val; lval; lval = lval->next)
681 /* unmark is myparm */
682 lval->sym->ismyparm = 0;
684 /* delete it from the symbol table */
685 deleteSym (SymbolTab, lval->sym, lval->sym->name);
687 if (!lval->sym->isref)
689 lval->sym->allocreq = 0;
690 werror (W_NO_REFERENCE,
691 currFunc ? currFunc->name : "(unknown)",
692 "function argument", lval->sym->name);
695 /* move the rname if any to the name for both val & sym */
696 /* and leave a copy of it in the symbol table */
697 if (lval->sym->rname[0])
699 char buffer[SDCC_NAME_MAX];
700 symbol * argsym = lval->sym;
702 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
703 lval->sym = copySymbol (lval->sym);
704 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
706 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
707 /* need to keep the original name for inlining to work */
708 /*strncpyz (lval->name, buffer, sizeof(lval->name)); */
710 addSym (SymbolTab, lval->sym, lval->sym->name,
711 lval->sym->level, lval->sym->block, 1);
712 lval->sym->_isparm = 1;
713 if (!isinSet (operKeyReset, lval->sym))
715 addSet(&operKeyReset, lval->sym);
718 /* restore the original symbol */
725 /*-----------------------------------------------------------------*/
726 /* allocLocal - allocate local variables */
727 /*-----------------------------------------------------------------*/
729 allocLocal (symbol * sym)
731 /* generate an unique name */
732 SNPRINTF (sym->rname, sizeof(sym->rname),
735 currFunc->name, sym->name, sym->level, sym->block);
738 sym->localof = currFunc;
740 /* if this is a static variable */
741 if (IS_STATIC (sym->etype))
748 /* if volatile then */
749 if (IS_VOLATILE (sym->etype))
752 /* this is automatic */
754 /* if it's to be placed on the stack */
755 if (options.stackAuto || reentrant) {
757 if (options.useXstack) {
758 /* PENDING: stack direction for xstack */
759 SPEC_OCLS (sym->etype) = xstack;
760 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
761 xstackPtr += getSize (sym->type);
763 SPEC_OCLS (sym->etype) = istack;
764 if (port->stack.direction > 0) {
765 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
766 stackPtr += getSize (sym->type);
768 stackPtr -= getSize (sym->type);
769 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
776 /* else depending on the storage class specified */
778 /* if this is a function then assign code space */
779 if (IS_FUNC (sym->type))
781 SPEC_OCLS (sym->etype) = code;
785 /* if this is a bit variable and no storage class */
786 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
788 SPEC_SCLS (sym->type) = S_BIT;
789 SPEC_OCLS (sym->type) = bit;
794 if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
796 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
801 if (allocDefault (sym))
806 /* again note that we have put it into the overlay segment
807 will remove and put into the 'data' segment if required after
808 overlay analysis has been done */
809 if (options.model == MODEL_SMALL) {
810 SPEC_OCLS (sym->etype) =
811 (options.noOverlay ? port->mem.default_local_map : overlay);
813 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
818 /*-----------------------------------------------------------------*/
819 /* deallocLocal - deallocates the local variables */
820 /*-----------------------------------------------------------------*/
822 deallocLocal (symbol * csym)
826 for (sym = csym; sym; sym = sym->next)
831 /* if it is on the stack */
834 if (options.useXstack)
835 xstackPtr -= getSize (sym->type);
837 stackPtr -= getSize (sym->type);
839 /* if not used give a warning */
840 if (!sym->isref && !IS_STATIC (sym->etype))
841 werror (W_NO_REFERENCE,
842 currFunc ? currFunc->name : "(unknown)",
843 "local variable", sym->name);
844 /* now delete it from the symbol table */
845 deleteSym (SymbolTab, sym, sym->name);
849 /*-----------------------------------------------------------------*/
850 /* overlay2data - moves declarations from the overlay seg to data */
851 /*-----------------------------------------------------------------*/
857 for (sym = setFirstItem (overlay->syms); sym;
858 sym = setNextItem (overlay->syms))
861 SPEC_OCLS (sym->etype) = data;
865 setToNull ((void *) &overlay->syms);
869 /*-----------------------------------------------------------------*/
870 /* overlay2Set - will add all symbols from the overlay segment to */
871 /* the set of sets containing the overlable symbols */
872 /*-----------------------------------------------------------------*/
879 for (sym = setFirstItem (overlay->syms); sym;
880 sym = setNextItem (overlay->syms))
886 setToNull ((void *) &overlay->syms);
887 addSet (&ovrSetSets, oset);
891 /*-----------------------------------------------------------------*/
892 /* allocVariables - creates decl & assign storage class for a v */
893 /*-----------------------------------------------------------------*/
895 allocVariables (symbol * symChain)
902 /* go thru the symbol chain */
903 for (sym = symChain; sym; sym = sym->next)
906 /* if this is a typedef then add it */
907 /* to the typedef table */
908 if (IS_TYPEDEF (sym->etype))
910 /* check if the typedef already exists */
911 csym = findSym (TypedefTab, NULL, sym->name);
912 if (csym && csym->level == sym->level)
913 werror (E_DUPLICATE_TYPEDEF, sym->name);
915 SPEC_EXTR (sym->etype) = 0;
916 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
917 continue; /* go to the next one */
919 /* make sure it already exists */
920 csym = findSymWithLevel (SymbolTab, sym);
921 if (!csym || (csym && csym->level != sym->level))
924 /* check the declaration */
927 /* if this is a function or a pointer to a */
928 /* function then do args processing */
929 if (funcInChain (csym->type))
931 processFuncArgs (csym);
934 /* if this is a extern variable then change the */
935 /* level to zero temporarily */
936 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
938 saveLevel = csym->level;
942 /* if this is a literal then it is an enumerated */
943 /* type so need not allocate it space for it */
944 if (IS_LITERAL (sym->etype))
947 /* generate the actual declaration */
952 stack += getSize (csym->type);
957 /* restore the level */
958 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
959 csym->level = saveLevel;
965 /*-----------------------------------------------------------------*/
966 /* redoStackOffsets :- will reassign the values for stack offsets */
967 /*-----------------------------------------------------------------*/
969 redoStackOffsets (void)
975 /* after register allocation is complete we know
976 which variables will need to be assigned space
977 on the stack. We will eliminate those variables
978 which do not have the allocReq flag thus reducing
980 for (sym = setFirstItem (istack->syms); sym;
981 sym = setNextItem (istack->syms))
984 int size = getSize (sym->type);
985 /* nothing to do with parameters so continue */
986 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
989 if (IS_AGGREGATE (sym->type))
991 if (port->stack.direction > 0)
993 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
999 SPEC_STAK (sym->etype) = sym->stack = sPtr;
1004 /* if allocation not required then subtract
1005 size from overall stack size & continue */
1008 currFunc->stack -= size;
1009 SPEC_STAK (currFunc->etype) -= size;
1013 if (port->stack.direction > 0)
1015 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
1021 SPEC_STAK (sym->etype) = sym->stack = sPtr;
1025 /* do the same for the external stack */
1027 for (sym = setFirstItem (xstack->syms); sym;
1028 sym = setNextItem (xstack->syms))
1031 int size = getSize (sym->type);
1032 /* nothing to do with parameters so continue */
1033 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
1036 if (IS_AGGREGATE (sym->type))
1038 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1043 /* if allocation not required then subtract
1044 size from overall stack size & continue */
1047 currFunc->xstack -= size;
1048 SPEC_STAK (currFunc->etype) -= size;
1052 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1058 /*-----------------------------------------------------------------*/
1059 /* printAllocInfoSeg- print the allocation for a given section */
1060 /*-----------------------------------------------------------------*/
1062 printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
1071 for (sym = setFirstItem (map->syms); sym;
1072 sym = setNextItem (map->syms))
1075 if (sym->level == 0)
1077 if (sym->localof != func)
1080 dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
1082 /* if assigned to registers */
1083 if (!sym->allocreq && sym->reqv)
1087 sym = OP_SYMBOL (sym->reqv);
1088 if (!sym->isspilt || sym->remat)
1090 dbuf_append_str (oBuf, "to registers ");
1091 for (i = 0; i < 4 && sym->regs[i]; i++)
1092 dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
1093 dbuf_append_char (oBuf, '\n');
1098 sym = sym->usl.spillLoc;
1105 dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
1109 /* otherwise give rname */
1110 dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
1114 /*-----------------------------------------------------------------*/
1115 /* canOverlayLocals - returns true if the local variables can overlayed */
1116 /*-----------------------------------------------------------------*/
1118 canOverlayLocals (eBBlock ** ebbs, int count)
1121 /* if staticAuto is in effect or the current function
1122 being compiled is reentrant or the overlay segment
1123 is empty or no overlay option is in effect then */
1124 if (options.noOverlay ||
1125 options.stackAuto ||
1127 (IFFUNC_ISREENT (currFunc->type) ||
1128 FUNC_ISISR (currFunc->type))) ||
1129 elementsInSet (overlay->syms) == 0)
1133 /* if this is a forces overlay */
1134 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1136 /* otherwise do thru the blocks and see if there
1137 any function calls if found then return false */
1138 for (i = 0; i < count; i++)
1142 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1144 if (ic->op == CALL) {
1145 sym_link *ftype = operandType(IC_LEFT(ic));
1146 /* builtins only can use overlays */
1147 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1148 } else if (ic->op == PCALL) return FALSE;
1152 /* no function calls found return TRUE */
1156 /*-----------------------------------------------------------------*/
1157 /* doOverlays - move the overlay segment to appropriate location */
1158 /*-----------------------------------------------------------------*/
1160 doOverlays (eBBlock ** ebbs, int count)
1166 /* check if the parameters and local variables
1167 of this function can be put in the overlay segment
1168 This check is essentially to see if the function
1169 calls any other functions if yes then we cannot
1171 if (canOverlayLocals (ebbs, count))
1172 /* if we can then put the parameters &
1173 local variables in the overlay set */
1176 /* otherwise put them into data where
1181 /*-----------------------------------------------------------------*/
1182 /* printAllocInfo - prints allocation information for a function */
1183 /*-----------------------------------------------------------------*/
1185 printAllocInfo (symbol * func, struct dbuf_s * oBuf)
1190 /* must be called after register allocation is complete */
1191 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
1192 dbuf_printf (oBuf, ";Allocation info for local variables in function '%s'\n", func->name);
1193 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
1195 printAllocInfoSeg (xstack, func, oBuf);
1196 printAllocInfoSeg (istack, func, oBuf);
1197 printAllocInfoSeg (code, func, oBuf);
1198 printAllocInfoSeg (data, func, oBuf);
1199 printAllocInfoSeg (xdata, func, oBuf);
1200 printAllocInfoSeg (idata, func, oBuf);
1201 printAllocInfoSeg (sfr, func, oBuf);
1202 printAllocInfoSeg (sfrbit, func, oBuf);
1206 set *tempOverlaySyms = overlay->syms;
1208 /* search the set of overlay sets for local variables/parameters */
1209 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1210 ovrset = setNextItem (ovrSetSets))
1212 overlay->syms = ovrset;
1213 printAllocInfoSeg (overlay, func, oBuf);
1215 overlay->syms = tempOverlaySyms;
1218 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");