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 *sfr = NULL; /* register space */
20 memmap *reg = NULL; /* register space */
21 memmap *sfrbit = NULL; /* sfr bit space */
22 memmap *generic = NULL; /* is a generic pointer */
23 memmap *overlay = NULL; /* overlay segment */
24 memmap *eeprom = NULL; /* eeprom location */
25 memmap *home = NULL; /* Unswitchable code bank */
27 /* this is a set of sets each set containing
28 symbols in a single overlay */
29 set *ovrSetSets = NULL;
32 int fatalError = 0; /* fatal error flag */
34 /*-----------------------------------------------------------------*/
35 /* allocMap - allocates a memory map */
36 /*-----------------------------------------------------------------*/
38 allocMap (char rspace, /* sfr space */
39 char farmap, /* far or near segment */
40 char paged, /* can this segment be paged */
41 char direct, /* directly addressable */
42 char bitaddr, /* bit addressable space */
43 char codemap, /* this is code space */
44 unsigned sloc, /* starting location */
45 const char *name, /* 2 character name */
46 char dbName, /* debug name */
47 int ptrType /* pointer type for this space */
52 if (!(map = Safe_alloc (sizeof (memmap))))
54 werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
58 memset (map, ZERO, sizeof (memmap));
64 map->codesp = codemap;
68 map->ptrType = ptrType;
69 if (!(map->oFile = tempfile ()))
71 werror (E_TMPFILE_FAILED);
74 addSetHead (&tmpfileSet, map->oFile);
79 /*-----------------------------------------------------------------*/
80 /* initMem - allocates and initializes all the segments */
81 /*-----------------------------------------------------------------*/
85 /* allocate all the segments */
86 /* xternal stack segment ;
94 POINTER-TYPE - FPOINTER
96 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
98 /* internal stack segment ;
106 POINTER-TYPE - POINTER
109 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc,
110 ISTACK_NAME, 'B', POINTER);
123 POINTER-TYPE - CPOINTER
125 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
135 POINTER-TYPE - CPOINTER
137 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
139 /* Static segment (code for variables );
147 POINTER-TYPE - CPOINTER
149 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
151 /* Data segment - internal storage segment ;
159 POINTER-TYPE - POINTER
161 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
163 /* overlay segment - same as internal storage segment ;
171 POINTER-TYPE - POINTER
174 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
179 /* Xternal paged segment ;
187 POINTER-TYPE - PPOINTER
190 pdata = allocMap (0, 0, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
195 /* Xternal Data segment -
203 POINTER-TYPE - FPOINTER
205 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
206 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
207 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
209 /* Indirectly addressed internal data segment
217 POINTER-TYPE - IPOINTER
220 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,
221 IDATA_NAME, 'G', IPOINTER);
234 POINTER-TYPE - _NONE_
236 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
238 /* Special function register space :-
246 POINTER-TYPE - _NONE_
248 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
258 POINTER-TYPE - _NONE_
260 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
270 POINTER-TYPE - _NONE_
272 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
282 POINTER-TYPE - EEPPOINTER
284 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
286 /* the unknown map */
287 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
291 /*-----------------------------------------------------------------*/
292 /* allocIntoSeg - puts a symbol into a memory segment */
293 /*-----------------------------------------------------------------*/
295 allocIntoSeg (symbol * sym)
297 memmap *segment = SPEC_OCLS (sym->etype);
298 addSet (&segment->syms, sym);
301 /*-----------------------------------------------------------------*/
302 /* deleteFromSeg - deletes a symbol from segment used when a var */
303 /* first declared as "extern" then no extern */
304 /*-----------------------------------------------------------------*/
305 void deleteFromSeg(symbol *sym)
307 if (SPEC_OCLS(sym->etype)) {
308 memmap *segment = SPEC_OCLS (sym->etype);
309 deleteSetItem(&segment->syms,sym);
314 /*-----------------------------------------------------------------*/
315 /* allocGlobal - assigns the output segment to a global var */
316 /*-----------------------------------------------------------------*/
318 allocGlobal (symbol * sym)
321 /* symbol name is internal name */
322 if (!sym->level) /* local statics can come here */
323 SNPRINTF (sym->rname, sizeof(sym->rname),
324 "%s%s", port->fun_prefix, sym->name);
326 /* add it to the operandKey reset */
327 if (!isinSet (operKeyReset, sym)) {
328 addSet(&operKeyReset, sym);
331 /* if this is a literal e.g. enumerated type */
332 /* put it in the data segment & do nothing */
333 if (IS_LITERAL (sym->etype))
335 SPEC_OCLS (sym->etype) = data;
339 /* if this is a function then assign code space */
340 if (IS_FUNC (sym->type))
342 SPEC_OCLS (sym->etype) = code;
343 /* if this is an interrupt service routine
344 then put it in the interrupt service array */
345 if (FUNC_ISISR (sym->type) && !options.noiv
346 && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
348 if (interrupts[FUNC_INTNO (sym->type)])
349 werror (E_INT_DEFINED,
350 FUNC_INTNO (sym->type),
351 interrupts[FUNC_INTNO (sym->type)]->name);
353 interrupts[FUNC_INTNO (sym->type)] = sym;
355 /* automagically extend the maximum interrupts */
356 if (FUNC_INTNO (sym->type) >= maxInterrupts)
357 maxInterrupts = FUNC_INTNO (sym->type) + 1;
359 /* if it is not compiler defined */
366 /* if this is a SFR or SBIT */
367 if (SPEC_SCLS (sym->etype) == S_SFR ||
368 SPEC_SCLS (sym->etype) == S_SBIT)
371 SPEC_OCLS (sym->etype) =
372 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
378 /* if this is a bit variable and no storage class */
379 if (SPEC_NOUN (sym->etype) == V_BIT
380 && SPEC_SCLS (sym->etype) == S_BIT)
382 SPEC_OCLS (sym->etype) = bit;
387 /* if bit storage class */
388 if (SPEC_SCLS (sym->etype) == S_SBIT)
390 SPEC_OCLS (sym->etype) = bit;
395 if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
396 /* register storage class ignored changed to FIXED */
397 if (SPEC_SCLS (sym->etype) == S_REGISTER)
398 SPEC_SCLS (sym->etype) = S_FIXED;
400 /* if data specified then */
401 if (SPEC_SCLS (sym->etype) == S_DATA)
403 /* set the output class */
404 SPEC_OCLS (sym->etype) = data;
405 /* generate the symbol */
410 /* if it is fixed, then allocate depending on the */
411 /* current memory model, same for automatics */
412 if (SPEC_SCLS (sym->etype) == S_FIXED ||
413 (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
414 SPEC_SCLS (sym->etype) == S_AUTO) {
415 if (port->mem.default_globl_map != xdata) {
416 /* set the output class */
417 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
418 /* generate the symbol */
422 SPEC_SCLS (sym->etype) = S_XDATA;
426 /* if code change to constant */
427 if (SPEC_SCLS (sym->etype) == S_CODE) {
428 SPEC_OCLS (sym->etype) = statsg;
433 if (SPEC_SCLS (sym->etype) == S_XDATA)
435 // should we move this to the initialized data segment?
436 if (port->genXINIT &&
437 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
438 SPEC_OCLS(sym->etype)=xidata;
440 SPEC_OCLS (sym->etype) = xdata;
446 if (SPEC_SCLS (sym->etype) == S_IDATA)
448 SPEC_OCLS (sym->etype) = idata;
454 if (SPEC_SCLS (sym->etype) == S_PDATA)
456 SPEC_OCLS (sym->etype) = pdata;
462 if (SPEC_SCLS (sym->etype) == S_EEPROM)
464 SPEC_OCLS (sym->etype) = eeprom;
472 /*-----------------------------------------------------------------*/
473 /* allocParms - parameters are always passed on stack */
474 /*-----------------------------------------------------------------*/
476 allocParms (value * val)
481 for (lval = val; lval; lval = lval->next, pNum++)
484 /* check the declaration */
485 checkDecl (lval->sym, 0);
487 /* if this a register parm then allocate
488 it as a local variable by adding it
489 to the first block we see in the body */
490 if (IS_REGPARM (lval->etype))
493 /* mark it as my parameter */
494 lval->sym->ismyparm = 1;
495 lval->sym->localof = currFunc;
498 /* if automatic variables r 2b stacked */
499 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
503 lval->sym->onStack = 1;
505 /* choose which stack 2 use */
506 /* use xternal stack */
507 if (options.useXstack)
509 /* PENDING: stack direction support */
510 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
511 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
512 xstackPtr - getSize (lval->type);
513 xstackPtr -= getSize (lval->type);
516 { /* use internal stack */
517 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
518 if (port->stack.direction > 0)
520 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
521 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
522 getSize (lval->type) -
523 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
524 stackPtr -= getSize (lval->type);
528 /* This looks like the wrong order but it turns out OK... */
529 /* PENDING: isr, bank overhead, ... */
530 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
532 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
533 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
535 stackPtr += getSize (lval->type);
538 allocIntoSeg (lval->sym);
541 { /* allocate them in the automatic space */
542 /* generate a unique name */
543 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
544 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
545 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
547 /* if declared in external storage */
548 if (SPEC_SCLS (lval->etype) == S_XDATA)
549 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
550 else if (SPEC_SCLS (lval->etype) == S_BIT)
551 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = bit;
553 /* otherwise depending on the memory model
554 note here that we put it into the overlay segment
555 first, we will remove it from the overlay segment
556 after the overlay determination has been done */
557 if (options.model == MODEL_SMALL)
559 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
560 (options.noOverlay ? port->mem.default_local_map
565 SPEC_SCLS (lval->etype) = S_XDATA;
566 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
568 allocIntoSeg (lval->sym);
575 /*-----------------------------------------------------------------*/
576 /* deallocParms - parameters are always passed on stack */
577 /*-----------------------------------------------------------------*/
579 deallocParms (value * val)
583 for (lval = val; lval; lval = lval->next)
586 /* unmark is myparm */
587 lval->sym->ismyparm = 0;
589 /* delete it from the symbol table */
590 deleteSym (SymbolTab, lval->sym, lval->sym->name);
592 if (!lval->sym->isref)
594 lval->sym->allocreq = 0;
595 werror (W_NO_REFERENCE,
596 currFunc ? currFunc->name : "(unknown)",
597 "function argument", lval->sym->name);
600 /* move the rname if any to the name for both val & sym */
601 /* and leave a copy of it in the symbol table */
602 if (lval->sym->rname[0])
604 char buffer[SDCC_NAME_MAX];
605 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
606 lval->sym = copySymbol (lval->sym);
607 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
608 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
609 strncpyz (lval->name, buffer, sizeof(lval->name));
610 addSym (SymbolTab, lval->sym, lval->sym->name,
611 lval->sym->level, lval->sym->block, 1);
612 lval->sym->_isparm = 1;
613 if (!isinSet (operKeyReset, lval->sym)) {
614 addSet(&operKeyReset, lval->sym);
623 /*-----------------------------------------------------------------*/
624 /* allocLocal - allocate local variables */
625 /*-----------------------------------------------------------------*/
627 allocLocal (symbol * sym)
630 /* generate an unique name */
631 SNPRINTF (sym->rname, sizeof(sym->rname),
634 currFunc->name, sym->name, sym->level, sym->block);
637 sym->localof = currFunc;
639 /* if this is a static variable */
640 if (IS_STATIC (sym->etype))
647 /* if volatile then */
648 if (IS_VOLATILE (sym->etype))
651 /* this is automatic */
653 /* if it's to be placed on the stack */
654 if (options.stackAuto || reentrant) {
656 if (options.useXstack) {
657 /* PENDING: stack direction for xstack */
658 SPEC_OCLS (sym->etype) = xstack;
659 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
660 xstackPtr += getSize (sym->type);
662 SPEC_OCLS (sym->etype) = istack;
663 if (port->stack.direction > 0) {
664 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
665 stackPtr += getSize (sym->type);
667 stackPtr -= getSize (sym->type);
668 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
675 /* else depending on the storage class specified */
676 if (SPEC_SCLS (sym->etype) == S_XDATA)
678 SPEC_OCLS (sym->etype) = xdata;
683 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
684 SPEC_OCLS (sym->etype) = statsg;
689 if (SPEC_SCLS (sym->etype) == S_IDATA)
691 SPEC_OCLS (sym->etype) = idata;
697 if (SPEC_SCLS (sym->etype) == S_PDATA)
699 SPEC_OCLS (sym->etype) = pdata;
705 /* if this is a function then assign code space */
706 if (IS_FUNC (sym->type))
708 SPEC_OCLS (sym->etype) = code;
712 /* if this is a SFR or SBIT */
713 if (SPEC_SCLS (sym->etype) == S_SFR ||
714 SPEC_SCLS (sym->etype) == S_SBIT)
716 SPEC_OCLS (sym->etype) =
717 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
723 /* if this is a bit variable and no storage class */
724 if (SPEC_NOUN (sym->etype) == V_BIT
725 && (SPEC_SCLS (sym->etype) == S_BIT))
727 SPEC_OCLS (sym->etype) = bit;
732 if (SPEC_SCLS (sym->etype) == S_DATA)
734 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
739 if (SPEC_SCLS (sym->etype) == S_EEPROM)
741 SPEC_OCLS (sym->etype) = eeprom;
746 /* again note that we have put it into the overlay segment
747 will remove and put into the 'data' segment if required after
748 overlay analysis has been done */
749 if (options.model == MODEL_SMALL) {
750 SPEC_OCLS (sym->etype) =
751 (options.noOverlay ? port->mem.default_local_map
754 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
759 /*-----------------------------------------------------------------*/
760 /* deallocLocal - deallocates the local variables */
761 /*-----------------------------------------------------------------*/
763 deallocLocal (symbol * csym)
767 for (sym = csym; sym; sym = sym->next)
772 /* if it is on the stack */
775 if (options.useXstack)
776 xstackPtr -= getSize (sym->type);
778 stackPtr -= getSize (sym->type);
780 /* if not used give a warning */
781 if (!sym->isref && !IS_STATIC (sym->etype))
782 werror (W_NO_REFERENCE,
783 currFunc ? currFunc->name : "(unknown)",
784 "local variable", sym->name);
785 /* now delete it from the symbol table */
786 deleteSym (SymbolTab, sym, sym->name);
790 /*-----------------------------------------------------------------*/
791 /* overlay2data - moves declarations from the overlay seg to data */
792 /*-----------------------------------------------------------------*/
798 for (sym = setFirstItem (overlay->syms); sym;
799 sym = setNextItem (overlay->syms))
802 SPEC_OCLS (sym->etype) = data;
806 setToNull ((void *) &overlay->syms);
810 /*-----------------------------------------------------------------*/
811 /* overlay2Set - will add all symbols from the overlay segment to */
812 /* the set of sets containing the overlable symbols */
813 /*-----------------------------------------------------------------*/
820 for (sym = setFirstItem (overlay->syms); sym;
821 sym = setNextItem (overlay->syms))
827 setToNull ((void *) &overlay->syms);
828 addSet (&ovrSetSets, oset);
832 /*-----------------------------------------------------------------*/
833 /* allocVariables - creates decl & assign storage class for a v */
834 /*-----------------------------------------------------------------*/
836 allocVariables (symbol * symChain)
843 /* go thru the symbol chain */
844 for (sym = symChain; sym; sym = sym->next)
847 /* if this is a typedef then add it */
848 /* to the typedef table */
849 if (IS_TYPEDEF (sym->etype))
851 /* check if the typedef already exists */
852 csym = findSym (TypedefTab, NULL, sym->name);
853 if (csym && csym->level == sym->level)
854 werror (E_DUPLICATE_TYPEDEF, sym->name);
856 SPEC_EXTR (sym->etype) = 0;
857 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
858 continue; /* go to the next one */
860 /* make sure it already exist */
861 csym = findSymWithLevel (SymbolTab, sym);
862 if (!csym || (csym && csym->level != sym->level))
865 /* check the declaration */
868 /* if this is a function or a pointer to function */
869 /* then args processing */
870 if (funcInChain (csym->type))
872 processFuncArgs (csym);
874 /* if register bank specified then update maxRegBank */
875 if (maxRegBank < FUNC_REGBANK (csym->type))
876 maxRegBank = FUNC_REGBANK (csym->type);
877 /*JCF: Mark the register bank as used*/
878 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
881 /* if this is a extern variable then change the */
882 /* level to zero temporarily */
883 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
885 saveLevel = csym->level;
889 /* if this is a literal then it is an enumerated */
890 /* type so need not allocate it space for it */
891 if (IS_LITERAL (sym->etype))
894 /* generate the actual declaration */
899 stack += getSize (csym->type);
904 /* restore the level */
905 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
906 csym->level = saveLevel;
912 /*-----------------------------------------------------------------*/
913 /* redoStackOffsets :- will reassign the values for stack offsets */
914 /*-----------------------------------------------------------------*/
916 redoStackOffsets (void)
922 /* after register allocation is complete we know
923 which variables will need to be assigned space
924 on the stack. We will eliminate those variables
925 which do not have the allocReq flag thus reducing
927 for (sym = setFirstItem (istack->syms); sym;
928 sym = setNextItem (istack->syms))
931 int size = getSize (sym->type);
932 /* nothing to do with parameters so continue */
933 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
936 if (IS_AGGREGATE (sym->type))
938 if (port->stack.direction > 0)
940 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
946 SPEC_STAK (sym->etype) = sym->stack = sPtr;
951 /* if allocation not required then subtract
952 size from overall stack size & continue */
955 currFunc->stack -= size;
956 SPEC_STAK (currFunc->etype) -= size;
960 if (port->stack.direction > 0)
962 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
968 SPEC_STAK (sym->etype) = sym->stack = sPtr;
972 /* do the same for the external stack */
974 for (sym = setFirstItem (xstack->syms); sym;
975 sym = setNextItem (xstack->syms))
978 int size = getSize (sym->type);
979 /* nothing to do with parameters so continue */
980 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
983 if (IS_AGGREGATE (sym->type))
985 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
990 /* if allocation not required then subtract
991 size from overall stack size & continue */
994 currFunc->xstack -= size;
995 SPEC_STAK (currFunc->etype) -= size;
999 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1005 /*-----------------------------------------------------------------*/
1006 /* printAllocInfoSeg- print the allocation for a given section */
1007 /*-----------------------------------------------------------------*/
1009 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
1018 for (sym = setFirstItem (map->syms); sym;
1019 sym = setNextItem (map->syms))
1022 if (sym->level == 0)
1024 if (sym->localof != func)
1027 fprintf (of, ";%-25s Allocated ", sym->name);
1029 /* if assigned to registers */
1030 if (!sym->allocreq && sym->reqv)
1034 sym = OP_SYMBOL (sym->reqv);
1035 if (!sym->isspilt || sym->remat)
1037 fprintf (of, "to registers ");
1038 for (i = 0; i < 4 && sym->regs[i]; i++)
1039 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1045 sym = sym->usl.spillLoc;
1052 fprintf (of, "to stack - offset %d\n", sym->stack);
1056 /* otherwise give rname */
1057 fprintf (of, "with name '%s'\n", sym->rname);
1061 /*-----------------------------------------------------------------*/
1062 /* canOverlayLocals - returns true if the local variables can overlayed */
1063 /*-----------------------------------------------------------------*/
1065 canOverlayLocals (eBBlock ** ebbs, int count)
1068 /* if staticAuto is in effect or the current function
1069 being compiled is reentrant or the overlay segment
1070 is empty or no overlay option is in effect then */
1071 if (options.noOverlay ||
1072 options.stackAuto ||
1074 (IFFUNC_ISREENT (currFunc->type) ||
1075 FUNC_ISISR (currFunc->type))) ||
1076 elementsInSet (overlay->syms) == 0)
1080 /* if this is a forces overlay */
1081 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1083 /* otherwise do thru the blocks and see if there
1084 any function calls if found then return false */
1085 for (i = 0; i < count; i++)
1089 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1091 if (ic->op == CALL) {
1092 sym_link *ftype = operandType(IC_LEFT(ic));
1093 /* builtins only can use overlays */
1094 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1095 } else if (ic->op == PCALL) return FALSE;
1099 /* no function calls found return TRUE */
1103 /*-----------------------------------------------------------------*/
1104 /* doOverlays - move the overlay segment to appropriate location */
1105 /*-----------------------------------------------------------------*/
1107 doOverlays (eBBlock ** ebbs, int count)
1113 /* check if the parameters and local variables
1114 of this function can be put in the overlay segment
1115 This check is essentially to see if the function
1116 calls any other functions if yes then we cannot
1118 if (canOverlayLocals (ebbs, count))
1119 /* if we can then put the parameters &
1120 local variables in the overlay set */
1123 /* otherwise put them into data where
1128 /*-----------------------------------------------------------------*/
1129 /* printAllocInfo - prints allocation information for a function */
1130 /*-----------------------------------------------------------------*/
1132 printAllocInfo (symbol * func, FILE * of)
1140 /* must be called after register allocation is complete */
1141 fprintf (of, ";------------------------------------------------------------\n");
1142 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1143 fprintf (of, ";------------------------------------------------------------\n");
1145 printAllocInfoSeg (xstack, func, of);
1146 printAllocInfoSeg (istack, func, of);
1147 printAllocInfoSeg (code, func, of);
1148 printAllocInfoSeg (data, func, of);
1149 printAllocInfoSeg (xdata, func, of);
1150 printAllocInfoSeg (idata, func, of);
1151 printAllocInfoSeg (sfr, func, of);
1152 printAllocInfoSeg (sfrbit, func, of);
1156 set *tempOverlaySyms = overlay->syms;
1158 /* search the set of overlay sets for local variables/parameters */
1159 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1160 ovrset = setNextItem (ovrSetSets))
1162 overlay->syms = ovrset;
1163 printAllocInfoSeg (overlay, func, of);
1165 overlay->syms = tempOverlaySyms;
1168 fprintf (of, ";------------------------------------------------------------\n");