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;
37 int fatalError = 0; /* fatal error flag */
39 /*-----------------------------------------------------------------*/
40 /* allocMap - allocates a memory map */
41 /*-----------------------------------------------------------------*/
43 allocMap (char rspace, /* sfr space */
44 char farmap, /* far or near segment */
45 char paged, /* can this segment be paged */
46 char direct, /* directly addressable */
47 char bitaddr, /* bit addressable space */
48 char codemap, /* this is code space */
49 unsigned sloc, /* starting location */
50 const char *name, /* 2 character name */
51 char dbName, /* debug name */
52 int ptrType /* pointer type for this space */
57 if (!(map = Safe_alloc (sizeof (memmap))))
59 werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
63 memset (map, ZERO, sizeof (memmap));
69 map->codesp = codemap;
73 map->ptrType = ptrType;
76 dbuf_init(&map->oBuf, 4096);
81 /*-----------------------------------------------------------------*/
82 /* initMem - allocates and initializes all the segments */
83 /*-----------------------------------------------------------------*/
87 /* allocate all the segments */
88 /* xternal stack segment ;
96 POINTER-TYPE - FPOINTER
98 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
100 /* internal stack segment ;
108 POINTER-TYPE - POINTER
112 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
127 POINTER-TYPE - CPOINTER
129 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
139 POINTER-TYPE - CPOINTER
141 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER);
143 /* Static segment (code for variables );
151 POINTER-TYPE - CPOINTER
153 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
155 /* Constant Absolute Data segment (for variables );
163 POINTER-TYPE - CPOINTER
165 c_abs = allocMap (0, 1, 0, 0, 0, 1, 0, CABS_NAME, 'D', CPOINTER);
167 /* Data segment - internal storage segment ;
175 POINTER-TYPE - POINTER
177 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
179 /* Absolute internal storage segment ;
187 POINTER-TYPE - POINTER
191 d_abs = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, IABS_NAME, 'E', POINTER);
198 /* overlay segment - same as internal storage segment ;
206 POINTER-TYPE - POINTER
210 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
217 /* Xternal paged segment ;
225 POINTER-TYPE - PPOINTER
229 pdata = allocMap (0, 0, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
236 /* Xternal Data segment -
244 POINTER-TYPE - FPOINTER
246 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
247 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
248 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
250 /* Absolute external storage segment ;
258 POINTER-TYPE - FPOINTER
262 x_abs = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XABS_NAME, 'F', FPOINTER);
269 /* Indirectly addressed internal data segment
277 POINTER-TYPE - IPOINTER
281 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
288 /* Indirectly addressed absolute internal segment
296 POINTER-TYPE - IPOINTER
300 i_abs = allocMap (0, 0, 0, 0, 0, 0, options.data_loc, IABS_NAME, 'E', IPOINTER);
315 POINTER-TYPE - _NONE_
317 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
319 /* Special function register space :-
327 POINTER-TYPE - _NONE_
329 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
339 POINTER-TYPE - _NONE_
341 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
351 POINTER-TYPE - _NONE_
353 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
363 POINTER-TYPE - EEPPOINTER
365 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
367 /* the unknown map */
368 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
372 /*-----------------------------------------------------------------*/
373 /* allocIntoSeg - puts a symbol into a memory segment */
374 /*-----------------------------------------------------------------*/
376 allocIntoSeg (symbol * sym)
378 memmap *segment = SPEC_OCLS (sym->etype);
379 addSet (&segment->syms, sym);
380 if (segment == pdata)
384 /*-----------------------------------------------------------------*/
385 /* deleteFromSeg - deletes a symbol from segment used when a var */
386 /* first declared as "extern" then no extern */
387 /*-----------------------------------------------------------------*/
388 void deleteFromSeg(symbol *sym)
390 if (SPEC_OCLS(sym->etype)) {
391 memmap *segment = SPEC_OCLS (sym->etype);
392 deleteSetItem(&segment->syms,sym);
396 /*-----------------------------------------------------------------*/
397 /* allocDefault - assigns the output segment based on SCLASS */
398 /*-----------------------------------------------------------------*/
400 allocDefault (symbol * sym)
402 switch (SPEC_SCLS (sym->etype))
405 SPEC_OCLS (sym->etype) = sfr;
408 SPEC_OCLS (sym->etype) = sfrbit;
413 /* if code change to constant */
414 if (sym->ival && SPEC_ABSA (sym->etype))
416 SPEC_OCLS(sym->etype) = c_abs;
420 SPEC_OCLS (sym->etype) = statsg;
424 /* absolute initialized global */
425 if (sym->ival && SPEC_ABSA (sym->etype))
427 SPEC_OCLS(sym->etype) = x_abs;
429 /* or should we move this to the initialized data segment? */
430 else if (port->genXINIT && sym->ival && (sym->level==0))
432 SPEC_OCLS(sym->etype) = xidata;
436 SPEC_OCLS (sym->etype) = xdata;
440 /* absolute initialized global */
441 if (sym->ival && SPEC_ABSA (sym->etype))
443 SPEC_OCLS(sym->etype) = d_abs;
447 SPEC_OCLS (sym->etype) = data;
451 /* absolute initialized global */
452 if (sym->ival && SPEC_ABSA (sym->etype))
454 SPEC_OCLS(sym->etype) = i_abs;
458 SPEC_OCLS (sym->etype) = idata;
463 SPEC_OCLS (sym->etype) = pdata;
467 SPEC_OCLS (sym->etype) = bit;
470 SPEC_OCLS (sym->etype) = eeprom;
479 /*-----------------------------------------------------------------*/
480 /* allocGlobal - assigns the output segment to a global var */
481 /*-----------------------------------------------------------------*/
483 allocGlobal (symbol * sym)
486 /* symbol name is internal name */
487 if (!sym->level) /* local statics can come here */
488 SNPRINTF (sym->rname, sizeof(sym->rname),
489 "%s%s", port->fun_prefix, sym->name);
491 /* add it to the operandKey reset */
492 if (!isinSet (operKeyReset, sym)) {
493 addSet(&operKeyReset, sym);
496 /* if this is a literal e.g. enumerated type */
497 /* put it in the data segment & do nothing */
498 if (IS_LITERAL (sym->etype))
500 SPEC_OCLS (sym->etype) = data;
504 /* if this is a function then assign code space */
505 if (IS_FUNC (sym->type))
507 SPEC_OCLS (sym->etype) = code;
508 /* if this is an interrupt service routine
509 then put it in the interrupt service array */
510 if (FUNC_ISISR (sym->type) && !options.noiv
511 && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
513 if (interrupts[FUNC_INTNO (sym->type)])
514 werror (E_INT_DEFINED,
515 FUNC_INTNO (sym->type),
516 interrupts[FUNC_INTNO (sym->type)]->name);
518 interrupts[FUNC_INTNO (sym->type)] = sym;
520 /* automagically extend the maximum interrupts */
521 if (FUNC_INTNO (sym->type) >= maxInterrupts)
522 maxInterrupts = FUNC_INTNO (sym->type) + 1;
524 /* if it is not compiler defined */
531 /* if this is a bit variable and no storage class */
532 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
533 /*&& SPEC_SCLS (sym->etype) == S_BIT*/
535 SPEC_OCLS (sym->type) = bit;
540 if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
541 /* register storage class ignored changed to FIXED */
542 if (SPEC_SCLS (sym->etype) == S_REGISTER)
543 SPEC_SCLS (sym->etype) = S_FIXED;
545 /* if it is fixed, then allocate depending on the */
546 /* current memory model, same for automatics */
547 if (SPEC_SCLS (sym->etype) == S_FIXED ||
548 (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
549 SPEC_SCLS (sym->etype) == S_AUTO) {
550 if (port->mem.default_globl_map != xdata) {
551 /* set the output class */
552 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
553 /* generate the symbol */
557 SPEC_SCLS (sym->etype) = S_XDATA;
565 /*-----------------------------------------------------------------*/
566 /* allocParms - parameters are always passed on stack */
567 /*-----------------------------------------------------------------*/
569 allocParms (value * val)
574 for (lval = val; lval; lval = lval->next, pNum++)
576 /* check the declaration */
577 checkDecl (lval->sym, 0);
579 /* if this a register parm then allocate
580 it as a local variable by adding it
581 to the first block we see in the body */
582 if (IS_REGPARM (lval->etype))
585 /* mark it as my parameter */
586 lval->sym->ismyparm = 1;
587 lval->sym->localof = currFunc;
589 /* if automatic variables r 2b stacked */
590 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
593 lval->sym->onStack = 1;
595 /* choose which stack 2 use */
596 /* use xternal stack */
597 if (options.useXstack)
599 /* PENDING: stack direction support */
600 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
601 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
602 xstackPtr - getSize (lval->type);
603 xstackPtr -= getSize (lval->type);
606 { /* use internal stack */
607 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
608 if (port->stack.direction > 0)
610 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
611 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
612 getSize (lval->type) -
613 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
614 stackPtr -= getSize (lval->type);
618 /* This looks like the wrong order but it turns out OK... */
619 /* PENDING: isr, bank overhead, ... */
620 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
622 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
623 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
625 stackPtr += getSize (lval->type);
628 allocIntoSeg (lval->sym);
631 { /* allocate them in the automatic space */
632 /* generate a unique name */
633 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
634 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
635 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
637 /* if declared in specific storage */
638 if (allocDefault (lval->sym))
640 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
644 /* otherwise depending on the memory model */
645 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
646 port->mem.default_local_map;
647 if (options.model == MODEL_SMALL)
649 /* note here that we put it into the overlay segment
650 first, we will remove it from the overlay segment
651 after the overlay determination has been done */
652 if (!options.noOverlay)
654 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
658 else if (options.model == MODEL_MEDIUM)
660 SPEC_SCLS (lval->etype) = S_PDATA;
664 SPEC_SCLS (lval->etype) = S_XDATA;
666 allocIntoSeg (lval->sym);
672 /*-----------------------------------------------------------------*/
673 /* deallocParms - parameters are always passed on stack */
674 /*-----------------------------------------------------------------*/
676 deallocParms (value * val)
680 for (lval = val; lval; lval = lval->next)
682 /* unmark is myparm */
683 lval->sym->ismyparm = 0;
685 /* delete it from the symbol table */
686 deleteSym (SymbolTab, lval->sym, lval->sym->name);
688 if (!lval->sym->isref)
690 lval->sym->allocreq = 0;
691 werror (W_NO_REFERENCE,
692 currFunc ? currFunc->name : "(unknown)",
693 "function argument", lval->sym->name);
696 /* move the rname if any to the name for both val & sym */
697 /* and leave a copy of it in the symbol table */
698 if (lval->sym->rname[0])
700 char buffer[SDCC_NAME_MAX];
701 symbol * argsym = lval->sym;
703 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
704 lval->sym = copySymbol (lval->sym);
705 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
707 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
708 /* need to keep the original name for inlining to work */
709 /*strncpyz (lval->name, buffer, sizeof(lval->name)); */
711 addSym (SymbolTab, lval->sym, lval->sym->name,
712 lval->sym->level, lval->sym->block, 1);
713 lval->sym->_isparm = 1;
714 if (!isinSet (operKeyReset, lval->sym))
716 addSet(&operKeyReset, lval->sym);
719 /* restore the original symbol */
726 /*-----------------------------------------------------------------*/
727 /* allocLocal - allocate local variables */
728 /*-----------------------------------------------------------------*/
730 allocLocal (symbol * sym)
732 /* generate an unique name */
733 SNPRINTF (sym->rname, sizeof(sym->rname),
736 currFunc->name, sym->name, sym->level, sym->block);
739 sym->localof = currFunc;
741 /* if this is a static variable */
742 if (IS_STATIC (sym->etype))
749 /* if volatile then */
750 if (IS_VOLATILE (sym->etype))
753 /* this is automatic */
755 /* if it's to be placed on the stack */
756 if (options.stackAuto || reentrant) {
758 if (options.useXstack) {
759 /* PENDING: stack direction for xstack */
760 SPEC_OCLS (sym->etype) = xstack;
761 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
762 xstackPtr += getSize (sym->type);
764 SPEC_OCLS (sym->etype) = istack;
765 if (port->stack.direction > 0) {
766 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
767 stackPtr += getSize (sym->type);
769 stackPtr -= getSize (sym->type);
770 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
777 /* else depending on the storage class specified */
779 /* if this is a function then assign code space */
780 if (IS_FUNC (sym->type))
782 SPEC_OCLS (sym->etype) = code;
786 /* if this is a bit variable and no storage class */
787 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
789 SPEC_SCLS (sym->type) = S_BIT;
790 SPEC_OCLS (sym->type) = bit;
795 if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
797 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
802 if (allocDefault (sym))
807 /* again note that we have put it into the overlay segment
808 will remove and put into the 'data' segment if required after
809 overlay analysis has been done */
810 if (options.model == MODEL_SMALL) {
811 SPEC_OCLS (sym->etype) =
812 (options.noOverlay ? port->mem.default_local_map : overlay);
814 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
819 /*-----------------------------------------------------------------*/
820 /* deallocLocal - deallocates the local variables */
821 /*-----------------------------------------------------------------*/
823 deallocLocal (symbol * csym)
827 for (sym = csym; sym; sym = sym->next)
832 /* if it is on the stack */
835 if (options.useXstack)
836 xstackPtr -= getSize (sym->type);
838 stackPtr -= getSize (sym->type);
840 /* if not used give a warning */
841 if (!sym->isref && !IS_STATIC (sym->etype))
842 werror (W_NO_REFERENCE,
843 currFunc ? currFunc->name : "(unknown)",
844 "local variable", sym->name);
845 /* now delete it from the symbol table */
846 deleteSym (SymbolTab, sym, sym->name);
850 /*-----------------------------------------------------------------*/
851 /* overlay2data - moves declarations from the overlay seg to data */
852 /*-----------------------------------------------------------------*/
858 for (sym = setFirstItem (overlay->syms); sym;
859 sym = setNextItem (overlay->syms))
862 SPEC_OCLS (sym->etype) = data;
866 setToNull ((void *) &overlay->syms);
870 /*-----------------------------------------------------------------*/
871 /* overlay2Set - will add all symbols from the overlay segment to */
872 /* the set of sets containing the overlable symbols */
873 /*-----------------------------------------------------------------*/
880 for (sym = setFirstItem (overlay->syms); sym;
881 sym = setNextItem (overlay->syms))
887 setToNull ((void *) &overlay->syms);
888 addSet (&ovrSetSets, oset);
892 /*-----------------------------------------------------------------*/
893 /* allocVariables - creates decl & assign storage class for a v */
894 /*-----------------------------------------------------------------*/
896 allocVariables (symbol * symChain)
903 /* go thru the symbol chain */
904 for (sym = symChain; sym; sym = sym->next)
907 /* if this is a typedef then add it */
908 /* to the typedef table */
909 if (IS_TYPEDEF (sym->etype))
911 /* check if the typedef already exists */
912 csym = findSym (TypedefTab, NULL, sym->name);
913 if (csym && csym->level == sym->level)
914 werror (E_DUPLICATE_TYPEDEF, sym->name);
916 SPEC_EXTR (sym->etype) = 0;
917 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
918 continue; /* go to the next one */
920 /* make sure it already exist */
921 csym = findSymWithLevel (SymbolTab, sym);
922 if (!csym || (csym && csym->level != sym->level))
925 /* check the declaration */
928 /* if this is a function or a pointer to function */
929 /* then args processing */
930 if (funcInChain (csym->type))
932 processFuncArgs (csym);
934 /* if register bank specified then update maxRegBank */
935 if (maxRegBank < FUNC_REGBANK (csym->type))
936 maxRegBank = FUNC_REGBANK (csym->type);
937 /*JCF: Mark the register bank as used*/
938 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
941 /* if this is a extern variable then change the */
942 /* level to zero temporarily */
943 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
945 saveLevel = csym->level;
949 /* if this is a literal then it is an enumerated */
950 /* type so need not allocate it space for it */
951 if (IS_LITERAL (sym->etype))
954 /* generate the actual declaration */
959 stack += getSize (csym->type);
964 /* restore the level */
965 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
966 csym->level = saveLevel;
972 /*-----------------------------------------------------------------*/
973 /* redoStackOffsets :- will reassign the values for stack offsets */
974 /*-----------------------------------------------------------------*/
976 redoStackOffsets (void)
982 /* after register allocation is complete we know
983 which variables will need to be assigned space
984 on the stack. We will eliminate those variables
985 which do not have the allocReq flag thus reducing
987 for (sym = setFirstItem (istack->syms); sym;
988 sym = setNextItem (istack->syms))
991 int size = getSize (sym->type);
992 /* nothing to do with parameters so continue */
993 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
996 if (IS_AGGREGATE (sym->type))
998 if (port->stack.direction > 0)
1000 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
1006 SPEC_STAK (sym->etype) = sym->stack = sPtr;
1011 /* if allocation not required then subtract
1012 size from overall stack size & continue */
1015 currFunc->stack -= size;
1016 SPEC_STAK (currFunc->etype) -= size;
1020 if (port->stack.direction > 0)
1022 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
1028 SPEC_STAK (sym->etype) = sym->stack = sPtr;
1032 /* do the same for the external stack */
1034 for (sym = setFirstItem (xstack->syms); sym;
1035 sym = setNextItem (xstack->syms))
1038 int size = getSize (sym->type);
1039 /* nothing to do with parameters so continue */
1040 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
1043 if (IS_AGGREGATE (sym->type))
1045 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1050 /* if allocation not required then subtract
1051 size from overall stack size & continue */
1054 currFunc->xstack -= size;
1055 SPEC_STAK (currFunc->etype) -= size;
1059 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1065 /*-----------------------------------------------------------------*/
1066 /* printAllocInfoSeg- print the allocation for a given section */
1067 /*-----------------------------------------------------------------*/
1069 printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
1078 for (sym = setFirstItem (map->syms); sym;
1079 sym = setNextItem (map->syms))
1082 if (sym->level == 0)
1084 if (sym->localof != func)
1087 dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
1089 /* if assigned to registers */
1090 if (!sym->allocreq && sym->reqv)
1094 sym = OP_SYMBOL (sym->reqv);
1095 if (!sym->isspilt || sym->remat)
1097 dbuf_append_str (oBuf, "to registers ");
1098 for (i = 0; i < 4 && sym->regs[i]; i++)
1099 dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
1100 dbuf_append_char (oBuf, '\n');
1105 sym = sym->usl.spillLoc;
1112 dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
1116 /* otherwise give rname */
1117 dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
1121 /*-----------------------------------------------------------------*/
1122 /* canOverlayLocals - returns true if the local variables can overlayed */
1123 /*-----------------------------------------------------------------*/
1125 canOverlayLocals (eBBlock ** ebbs, int count)
1128 /* if staticAuto is in effect or the current function
1129 being compiled is reentrant or the overlay segment
1130 is empty or no overlay option is in effect then */
1131 if (options.noOverlay ||
1132 options.stackAuto ||
1134 (IFFUNC_ISREENT (currFunc->type) ||
1135 FUNC_ISISR (currFunc->type))) ||
1136 elementsInSet (overlay->syms) == 0)
1140 /* if this is a forces overlay */
1141 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1143 /* otherwise do thru the blocks and see if there
1144 any function calls if found then return false */
1145 for (i = 0; i < count; i++)
1149 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1151 if (ic->op == CALL) {
1152 sym_link *ftype = operandType(IC_LEFT(ic));
1153 /* builtins only can use overlays */
1154 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1155 } else if (ic->op == PCALL) return FALSE;
1159 /* no function calls found return TRUE */
1163 /*-----------------------------------------------------------------*/
1164 /* doOverlays - move the overlay segment to appropriate location */
1165 /*-----------------------------------------------------------------*/
1167 doOverlays (eBBlock ** ebbs, int count)
1173 /* check if the parameters and local variables
1174 of this function can be put in the overlay segment
1175 This check is essentially to see if the function
1176 calls any other functions if yes then we cannot
1178 if (canOverlayLocals (ebbs, count))
1179 /* if we can then put the parameters &
1180 local variables in the overlay set */
1183 /* otherwise put them into data where
1188 /*-----------------------------------------------------------------*/
1189 /* printAllocInfo - prints allocation information for a function */
1190 /*-----------------------------------------------------------------*/
1192 printAllocInfo (symbol * func, struct dbuf_s * oBuf)
1197 /* must be called after register allocation is complete */
1198 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
1199 dbuf_printf (oBuf, ";Allocation info for local variables in function '%s'\n", func->name);
1200 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
1202 printAllocInfoSeg (xstack, func, oBuf);
1203 printAllocInfoSeg (istack, func, oBuf);
1204 printAllocInfoSeg (code, func, oBuf);
1205 printAllocInfoSeg (data, func, oBuf);
1206 printAllocInfoSeg (xdata, func, oBuf);
1207 printAllocInfoSeg (idata, func, oBuf);
1208 printAllocInfoSeg (sfr, func, oBuf);
1209 printAllocInfoSeg (sfrbit, func, oBuf);
1213 set *tempOverlaySyms = overlay->syms;
1215 /* search the set of overlay sets for local variables/parameters */
1216 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1217 ovrset = setNextItem (ovrSetSets))
1219 overlay->syms = ovrset;
1220 printAllocInfoSeg (overlay, func, oBuf);
1222 overlay->syms = tempOverlaySyms;
1225 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");