1 /*-----------------------------------------------------------------*/
2 /* SDCCmem.c - 8051 memory management routines */
3 /*-----------------------------------------------------------------*/
8 memmap *xstack = NULL; /* xternal stack data */
9 memmap *istack = NULL; /* internal stack */
10 memmap *code = NULL; /* code segment */
11 memmap *data = NULL; /* internal data upto 128 */
12 memmap *pdata = NULL; /* paged external data */
13 memmap *xdata = NULL; /* external data */
14 memmap *xidata = NULL; /* the initialized xdata */
15 memmap *xinit = NULL; /* the initializers for xidata */
16 memmap *idata = NULL; /* internal data upto 256 */
17 memmap *bit = NULL; /* bit addressable space */
18 memmap *statsg = NULL; /* the constant data segment */
19 memmap *c_abs = NULL; /* constant absolute data */
20 memmap *x_abs = NULL; /* absolute xdata/pdata */
21 memmap *i_abs = NULL; /* absolute idata upto 256 */
22 memmap *d_abs = NULL; /* absolute data upto 128 */
23 memmap *sfr = NULL; /* register space */
24 memmap *reg = NULL; /* register space */
25 memmap *sfrbit = NULL; /* sfr bit space */
26 memmap *generic = NULL; /* is a generic pointer */
27 memmap *overlay = NULL; /* overlay segment */
28 memmap *eeprom = NULL; /* eeprom location */
29 memmap *home = NULL; /* Unswitchable code bank */
31 /* this is a set of sets each set containing
32 symbols in a single overlay */
33 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;
73 if (!(map->oFile = tempfile ()))
75 werror (E_TMPFILE_FAILED);
78 addSetHead (&tmpfileSet, map->oFile);
83 /*-----------------------------------------------------------------*/
84 /* initMem - allocates and initializes all the segments */
85 /*-----------------------------------------------------------------*/
89 /* allocate all the segments */
90 /* xternal stack segment ;
98 POINTER-TYPE - FPOINTER
100 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
102 /* internal stack segment ;
110 POINTER-TYPE - POINTER
113 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc,
114 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
190 d_abs = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, IABS_NAME, 'E', POINTER);
195 /* overlay segment - same as internal storage segment ;
203 POINTER-TYPE - POINTER
206 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
211 /* Xternal paged segment ;
219 POINTER-TYPE - PPOINTER
222 pdata = allocMap (0, 0, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
227 /* Xternal Data segment -
235 POINTER-TYPE - FPOINTER
237 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
238 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
239 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
241 /* Indirectly addressed internal data segment
249 POINTER-TYPE - IPOINTER
252 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,
253 IDATA_NAME, 'G', IPOINTER);
258 /* Indirectly addressed absolute internal segment
266 POINTER-TYPE - IPOINTER
269 i_abs = allocMap (0, 0, 0, 0, 0, 0, options.data_loc, IABS_NAME, 'E', IPOINTER);
282 POINTER-TYPE - _NONE_
284 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
286 /* Special function register space :-
294 POINTER-TYPE - _NONE_
296 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
306 POINTER-TYPE - _NONE_
308 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
318 POINTER-TYPE - _NONE_
320 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
330 POINTER-TYPE - EEPPOINTER
332 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
334 /* the unknown map */
335 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
339 /*-----------------------------------------------------------------*/
340 /* allocIntoSeg - puts a symbol into a memory segment */
341 /*-----------------------------------------------------------------*/
343 allocIntoSeg (symbol * sym)
345 memmap *segment = SPEC_OCLS (sym->etype);
346 addSet (&segment->syms, sym);
347 if (segment == pdata)
351 /*-----------------------------------------------------------------*/
352 /* deleteFromSeg - deletes a symbol from segment used when a var */
353 /* first declared as "extern" then no extern */
354 /*-----------------------------------------------------------------*/
355 void deleteFromSeg(symbol *sym)
357 if (SPEC_OCLS(sym->etype)) {
358 memmap *segment = SPEC_OCLS (sym->etype);
359 deleteSetItem(&segment->syms,sym);
363 /*-----------------------------------------------------------------*/
364 /* allocDefault - assigns the output segment based on SCLASS */
365 /*-----------------------------------------------------------------*/
367 allocDefault (symbol * sym)
369 switch (SPEC_SCLS (sym->etype))
372 SPEC_OCLS (sym->etype) = sfr;
375 SPEC_OCLS (sym->etype) = sfrbit;
380 /* if code change to constant */
381 if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
382 SPEC_OCLS(sym->etype) = c_abs;
384 SPEC_OCLS (sym->etype) = statsg;
388 // should we move this to the initialized data segment?
389 if (port->genXINIT &&
390 sym->ival && (sym->level==0) && !SPEC_ABSA (sym->etype)) {
391 SPEC_OCLS(sym->etype) = xidata;
393 SPEC_OCLS (sym->etype) = xdata;
397 /* absolute initialized global */
398 if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
399 SPEC_OCLS(sym->etype) = d_abs;
401 SPEC_OCLS (sym->etype) = data;
405 /* absolute initialized global */
406 if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
407 SPEC_OCLS(sym->etype) = i_abs;
409 SPEC_OCLS (sym->etype) = idata;
414 SPEC_OCLS (sym->etype) = pdata;
418 SPEC_OCLS (sym->etype) = bit;
421 SPEC_OCLS (sym->etype) = eeprom;
430 /*-----------------------------------------------------------------*/
431 /* allocGlobal - assigns the output segment to a global var */
432 /*-----------------------------------------------------------------*/
434 allocGlobal (symbol * sym)
437 /* symbol name is internal name */
438 if (!sym->level) /* local statics can come here */
439 SNPRINTF (sym->rname, sizeof(sym->rname),
440 "%s%s", port->fun_prefix, sym->name);
442 /* add it to the operandKey reset */
443 if (!isinSet (operKeyReset, sym)) {
444 addSet(&operKeyReset, sym);
447 /* if this is a literal e.g. enumerated type */
448 /* put it in the data segment & do nothing */
449 if (IS_LITERAL (sym->etype))
451 SPEC_OCLS (sym->etype) = data;
455 /* if this is a function then assign code space */
456 if (IS_FUNC (sym->type))
458 SPEC_OCLS (sym->etype) = code;
459 /* if this is an interrupt service routine
460 then put it in the interrupt service array */
461 if (FUNC_ISISR (sym->type) && !options.noiv
462 && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
464 if (interrupts[FUNC_INTNO (sym->type)])
465 werror (E_INT_DEFINED,
466 FUNC_INTNO (sym->type),
467 interrupts[FUNC_INTNO (sym->type)]->name);
469 interrupts[FUNC_INTNO (sym->type)] = sym;
471 /* automagically extend the maximum interrupts */
472 if (FUNC_INTNO (sym->type) >= maxInterrupts)
473 maxInterrupts = FUNC_INTNO (sym->type) + 1;
475 /* if it is not compiler defined */
482 /* if this is a bit variable and no storage class */
483 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
484 /*&& SPEC_SCLS (sym->etype) == S_BIT*/
486 SPEC_OCLS (sym->type) = bit;
491 if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
492 /* register storage class ignored changed to FIXED */
493 if (SPEC_SCLS (sym->etype) == S_REGISTER)
494 SPEC_SCLS (sym->etype) = S_FIXED;
496 /* if it is fixed, then allocate depending on the */
497 /* current memory model, same for automatics */
498 if (SPEC_SCLS (sym->etype) == S_FIXED ||
499 (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
500 SPEC_SCLS (sym->etype) == S_AUTO) {
501 if (port->mem.default_globl_map != xdata) {
502 /* set the output class */
503 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
504 /* generate the symbol */
508 SPEC_SCLS (sym->etype) = S_XDATA;
516 /*-----------------------------------------------------------------*/
517 /* allocParms - parameters are always passed on stack */
518 /*-----------------------------------------------------------------*/
520 allocParms (value * val)
525 for (lval = val; lval; lval = lval->next, pNum++)
527 /* check the declaration */
528 checkDecl (lval->sym, 0);
530 /* if this a register parm then allocate
531 it as a local variable by adding it
532 to the first block we see in the body */
533 if (IS_REGPARM (lval->etype))
536 /* mark it as my parameter */
537 lval->sym->ismyparm = 1;
538 lval->sym->localof = currFunc;
540 /* if automatic variables r 2b stacked */
541 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
544 lval->sym->onStack = 1;
546 /* choose which stack 2 use */
547 /* use xternal stack */
548 if (options.useXstack)
550 /* PENDING: stack direction support */
551 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
552 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
553 xstackPtr - getSize (lval->type);
554 xstackPtr -= getSize (lval->type);
557 { /* use internal stack */
558 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
559 if (port->stack.direction > 0)
561 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
562 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
563 getSize (lval->type) -
564 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
565 stackPtr -= getSize (lval->type);
569 /* This looks like the wrong order but it turns out OK... */
570 /* PENDING: isr, bank overhead, ... */
571 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
573 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
574 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
576 stackPtr += getSize (lval->type);
579 allocIntoSeg (lval->sym);
582 { /* allocate them in the automatic space */
583 /* generate a unique name */
584 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
585 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
586 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
588 /* if declared in specific storage */
589 if (allocDefault (lval->sym))
591 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
595 /* otherwise depending on the memory model */
596 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
597 port->mem.default_local_map;
598 if (options.model == MODEL_SMALL)
600 /* note here that we put it into the overlay segment
601 first, we will remove it from the overlay segment
602 after the overlay determination has been done */
603 if (!options.noOverlay)
605 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
609 else if (options.model == MODEL_MEDIUM)
611 SPEC_SCLS (lval->etype) = S_PDATA;
615 SPEC_SCLS (lval->etype) = S_XDATA;
617 allocIntoSeg (lval->sym);
623 /*-----------------------------------------------------------------*/
624 /* deallocParms - parameters are always passed on stack */
625 /*-----------------------------------------------------------------*/
627 deallocParms (value * val)
631 for (lval = val; lval; lval = lval->next)
633 /* unmark is myparm */
634 lval->sym->ismyparm = 0;
636 /* delete it from the symbol table */
637 deleteSym (SymbolTab, lval->sym, lval->sym->name);
639 if (!lval->sym->isref)
641 lval->sym->allocreq = 0;
642 werror (W_NO_REFERENCE,
643 currFunc ? currFunc->name : "(unknown)",
644 "function argument", lval->sym->name);
647 /* move the rname if any to the name for both val & sym */
648 /* and leave a copy of it in the symbol table */
649 if (lval->sym->rname[0])
651 char buffer[SDCC_NAME_MAX];
652 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
653 lval->sym = copySymbol (lval->sym);
654 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
655 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
656 strncpyz (lval->name, buffer, sizeof(lval->name));
657 addSym (SymbolTab, lval->sym, lval->sym->name,
658 lval->sym->level, lval->sym->block, 1);
659 lval->sym->_isparm = 1;
660 if (!isinSet (operKeyReset, lval->sym))
662 addSet(&operKeyReset, lval->sym);
669 /*-----------------------------------------------------------------*/
670 /* allocLocal - allocate local variables */
671 /*-----------------------------------------------------------------*/
673 allocLocal (symbol * sym)
675 /* generate an unique name */
676 SNPRINTF (sym->rname, sizeof(sym->rname),
679 currFunc->name, sym->name, sym->level, sym->block);
682 sym->localof = currFunc;
684 /* if this is a static variable */
685 if (IS_STATIC (sym->etype))
692 /* if volatile then */
693 if (IS_VOLATILE (sym->etype))
696 /* this is automatic */
698 /* if it's to be placed on the stack */
699 if (options.stackAuto || reentrant) {
701 if (options.useXstack) {
702 /* PENDING: stack direction for xstack */
703 SPEC_OCLS (sym->etype) = xstack;
704 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
705 xstackPtr += getSize (sym->type);
707 SPEC_OCLS (sym->etype) = istack;
708 if (port->stack.direction > 0) {
709 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
710 stackPtr += getSize (sym->type);
712 stackPtr -= getSize (sym->type);
713 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
720 /* else depending on the storage class specified */
722 /* if this is a function then assign code space */
723 if (IS_FUNC (sym->type))
725 SPEC_OCLS (sym->etype) = code;
729 /* if this is a bit variable and no storage class */
730 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
732 SPEC_SCLS (sym->type) = S_BIT;
733 SPEC_OCLS (sym->type) = bit;
738 if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
740 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
745 if (allocDefault (sym))
750 /* again note that we have put it into the overlay segment
751 will remove and put into the 'data' segment if required after
752 overlay analysis has been done */
753 if (options.model == MODEL_SMALL) {
754 SPEC_OCLS (sym->etype) =
755 (options.noOverlay ? port->mem.default_local_map : overlay);
757 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
762 /*-----------------------------------------------------------------*/
763 /* deallocLocal - deallocates the local variables */
764 /*-----------------------------------------------------------------*/
766 deallocLocal (symbol * csym)
770 for (sym = csym; sym; sym = sym->next)
775 /* if it is on the stack */
778 if (options.useXstack)
779 xstackPtr -= getSize (sym->type);
781 stackPtr -= getSize (sym->type);
783 /* if not used give a warning */
784 if (!sym->isref && !IS_STATIC (sym->etype))
785 werror (W_NO_REFERENCE,
786 currFunc ? currFunc->name : "(unknown)",
787 "local variable", sym->name);
788 /* now delete it from the symbol table */
789 deleteSym (SymbolTab, sym, sym->name);
793 /*-----------------------------------------------------------------*/
794 /* overlay2data - moves declarations from the overlay seg to data */
795 /*-----------------------------------------------------------------*/
801 for (sym = setFirstItem (overlay->syms); sym;
802 sym = setNextItem (overlay->syms))
805 SPEC_OCLS (sym->etype) = data;
809 setToNull ((void *) &overlay->syms);
813 /*-----------------------------------------------------------------*/
814 /* overlay2Set - will add all symbols from the overlay segment to */
815 /* the set of sets containing the overlable symbols */
816 /*-----------------------------------------------------------------*/
823 for (sym = setFirstItem (overlay->syms); sym;
824 sym = setNextItem (overlay->syms))
830 setToNull ((void *) &overlay->syms);
831 addSet (&ovrSetSets, oset);
835 /*-----------------------------------------------------------------*/
836 /* allocVariables - creates decl & assign storage class for a v */
837 /*-----------------------------------------------------------------*/
839 allocVariables (symbol * symChain)
846 /* go thru the symbol chain */
847 for (sym = symChain; sym; sym = sym->next)
850 /* if this is a typedef then add it */
851 /* to the typedef table */
852 if (IS_TYPEDEF (sym->etype))
854 /* check if the typedef already exists */
855 csym = findSym (TypedefTab, NULL, sym->name);
856 if (csym && csym->level == sym->level)
857 werror (E_DUPLICATE_TYPEDEF, sym->name);
859 SPEC_EXTR (sym->etype) = 0;
860 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
861 continue; /* go to the next one */
863 /* make sure it already exist */
864 csym = findSymWithLevel (SymbolTab, sym);
865 if (!csym || (csym && csym->level != sym->level))
868 /* check the declaration */
871 /* if this is a function or a pointer to function */
872 /* then args processing */
873 if (funcInChain (csym->type))
875 processFuncArgs (csym);
877 /* if register bank specified then update maxRegBank */
878 if (maxRegBank < FUNC_REGBANK (csym->type))
879 maxRegBank = FUNC_REGBANK (csym->type);
880 /*JCF: Mark the register bank as used*/
881 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
884 /* if this is a extern variable then change the */
885 /* level to zero temporarily */
886 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
888 saveLevel = csym->level;
892 /* if this is a literal then it is an enumerated */
893 /* type so need not allocate it space for it */
894 if (IS_LITERAL (sym->etype))
897 /* generate the actual declaration */
902 stack += getSize (csym->type);
907 /* restore the level */
908 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
909 csym->level = saveLevel;
915 /*-----------------------------------------------------------------*/
916 /* redoStackOffsets :- will reassign the values for stack offsets */
917 /*-----------------------------------------------------------------*/
919 redoStackOffsets (void)
925 /* after register allocation is complete we know
926 which variables will need to be assigned space
927 on the stack. We will eliminate those variables
928 which do not have the allocReq flag thus reducing
930 for (sym = setFirstItem (istack->syms); sym;
931 sym = setNextItem (istack->syms))
934 int size = getSize (sym->type);
935 /* nothing to do with parameters so continue */
936 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
939 if (IS_AGGREGATE (sym->type))
941 if (port->stack.direction > 0)
943 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
949 SPEC_STAK (sym->etype) = sym->stack = sPtr;
954 /* if allocation not required then subtract
955 size from overall stack size & continue */
958 currFunc->stack -= size;
959 SPEC_STAK (currFunc->etype) -= size;
963 if (port->stack.direction > 0)
965 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
971 SPEC_STAK (sym->etype) = sym->stack = sPtr;
975 /* do the same for the external stack */
977 for (sym = setFirstItem (xstack->syms); sym;
978 sym = setNextItem (xstack->syms))
981 int size = getSize (sym->type);
982 /* nothing to do with parameters so continue */
983 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
986 if (IS_AGGREGATE (sym->type))
988 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
993 /* if allocation not required then subtract
994 size from overall stack size & continue */
997 currFunc->xstack -= size;
998 SPEC_STAK (currFunc->etype) -= size;
1002 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1008 /*-----------------------------------------------------------------*/
1009 /* printAllocInfoSeg- print the allocation for a given section */
1010 /*-----------------------------------------------------------------*/
1012 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
1021 for (sym = setFirstItem (map->syms); sym;
1022 sym = setNextItem (map->syms))
1025 if (sym->level == 0)
1027 if (sym->localof != func)
1030 fprintf (of, ";%-25s Allocated ", sym->name);
1032 /* if assigned to registers */
1033 if (!sym->allocreq && sym->reqv)
1037 sym = OP_SYMBOL (sym->reqv);
1038 if (!sym->isspilt || sym->remat)
1040 fprintf (of, "to registers ");
1041 for (i = 0; i < 4 && sym->regs[i]; i++)
1042 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1048 sym = sym->usl.spillLoc;
1055 fprintf (of, "to stack - offset %d\n", sym->stack);
1059 /* otherwise give rname */
1060 fprintf (of, "with name '%s'\n", sym->rname);
1064 /*-----------------------------------------------------------------*/
1065 /* canOverlayLocals - returns true if the local variables can overlayed */
1066 /*-----------------------------------------------------------------*/
1068 canOverlayLocals (eBBlock ** ebbs, int count)
1071 /* if staticAuto is in effect or the current function
1072 being compiled is reentrant or the overlay segment
1073 is empty or no overlay option is in effect then */
1074 if (options.noOverlay ||
1075 options.stackAuto ||
1077 (IFFUNC_ISREENT (currFunc->type) ||
1078 FUNC_ISISR (currFunc->type))) ||
1079 elementsInSet (overlay->syms) == 0)
1083 /* if this is a forces overlay */
1084 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1086 /* otherwise do thru the blocks and see if there
1087 any function calls if found then return false */
1088 for (i = 0; i < count; i++)
1092 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1094 if (ic->op == CALL) {
1095 sym_link *ftype = operandType(IC_LEFT(ic));
1096 /* builtins only can use overlays */
1097 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1098 } else if (ic->op == PCALL) return FALSE;
1102 /* no function calls found return TRUE */
1106 /*-----------------------------------------------------------------*/
1107 /* doOverlays - move the overlay segment to appropriate location */
1108 /*-----------------------------------------------------------------*/
1110 doOverlays (eBBlock ** ebbs, int count)
1116 /* check if the parameters and local variables
1117 of this function can be put in the overlay segment
1118 This check is essentially to see if the function
1119 calls any other functions if yes then we cannot
1121 if (canOverlayLocals (ebbs, count))
1122 /* if we can then put the parameters &
1123 local variables in the overlay set */
1126 /* otherwise put them into data where
1131 /*-----------------------------------------------------------------*/
1132 /* printAllocInfo - prints allocation information for a function */
1133 /*-----------------------------------------------------------------*/
1135 printAllocInfo (symbol * func, FILE * of)
1143 /* must be called after register allocation is complete */
1144 fprintf (of, ";------------------------------------------------------------\n");
1145 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1146 fprintf (of, ";------------------------------------------------------------\n");
1148 printAllocInfoSeg (xstack, func, of);
1149 printAllocInfoSeg (istack, func, of);
1150 printAllocInfoSeg (code, func, of);
1151 printAllocInfoSeg (data, func, of);
1152 printAllocInfoSeg (xdata, func, of);
1153 printAllocInfoSeg (idata, func, of);
1154 printAllocInfoSeg (sfr, func, of);
1155 printAllocInfoSeg (sfrbit, func, of);
1159 set *tempOverlaySyms = overlay->syms;
1161 /* search the set of overlay sets for local variables/parameters */
1162 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1163 ovrset = setNextItem (ovrSetSets))
1165 overlay->syms = ovrset;
1166 printAllocInfoSeg (overlay, func, of);
1168 overlay->syms = tempOverlaySyms;
1171 fprintf (of, ";------------------------------------------------------------\n");