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 *xdata = NULL; /* external data */
13 memmap *xidata = NULL; /* the initialized xdata */
14 memmap *xinit = NULL; /* the initializers for xidata */
15 memmap *idata = NULL; /* internal data upto 256 */
16 memmap *bit = NULL; /* bit addressable space */
17 memmap *statsg = NULL; /* the constant data segment */
18 memmap *sfr = NULL; /* register space */
19 memmap *reg = NULL; /* register space */
20 memmap *sfrbit = NULL; /* sfr bit space */
21 memmap *generic = NULL; /* is a generic pointer */
22 memmap *overlay = NULL; /* overlay segment */
23 memmap *eeprom = NULL; /* eeprom location */
24 memmap *home = NULL; /* Unswitchable code bank */
26 /* this is a set of sets each set containing
27 symbols in a single overlay */
28 set *ovrSetSets = NULL;
31 int fatalError = 0; /* fatal error flag */
33 /*-----------------------------------------------------------------*/
34 /* allocMap - allocates a memory map */
35 /*-----------------------------------------------------------------*/
37 allocMap (char rspace, /* sfr space */
38 char farmap, /* far or near segment */
39 char paged, /* can this segment be paged */
40 char direct, /* directly addressable */
41 char bitaddr, /* bit addressable space */
42 char codemap, /* this is code space */
43 unsigned sloc, /* starting location */
44 const char *name, /* 2 character name */
45 char dbName, /* debug name */
46 int ptrType /* pointer type for this space */
51 if (!(map = Safe_alloc (sizeof (memmap))))
53 werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
57 memset (map, ZERO, sizeof (memmap));
63 map->codesp = codemap;
67 map->ptrType = ptrType;
68 if (!(map->oFile = tempfile ()))
70 werror (E_TMPFILE_FAILED);
73 addSetHead (&tmpfileSet, map->oFile);
78 /*-----------------------------------------------------------------*/
79 /* initMem - allocates and initializes all the segments */
80 /*-----------------------------------------------------------------*/
84 /* allocate all the segments */
85 /* xternal stack segment ;
93 POINTER-TYPE - FPOINTER
95 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
97 /* internal stack segment ;
105 POINTER-TYPE - POINTER
107 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
117 POINTER-TYPE - CPOINTER
119 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
129 POINTER-TYPE - CPOINTER
131 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
133 /* Static segment (code for variables );
141 POINTER-TYPE - CPOINTER
143 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
145 /* Data segment - internal storage segment ;
153 POINTER-TYPE - POINTER
155 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
157 /* overlay segment - same as internal storage segment ;
165 POINTER-TYPE - POINTER
167 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
169 /* Xternal Data segment -
177 POINTER-TYPE - FPOINTER
179 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
180 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
181 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
183 /* Inderectly addressed internal data segment
191 POINTER-TYPE - IPOINTER
193 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
195 /* Static segment (code for variables );
203 POINTER-TYPE - _NONE_
205 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
207 /* Special function register space :-
215 POINTER-TYPE - _NONE_
217 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
227 POINTER-TYPE - _NONE_
229 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
239 POINTER-TYPE - _NONE_
241 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
251 POINTER-TYPE - EEPPOINTER
253 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
255 /* the unknown map */
256 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
260 /*-----------------------------------------------------------------*/
261 /* allocIntoSeg - puts a symbol into a memory segment */
262 /*-----------------------------------------------------------------*/
264 allocIntoSeg (symbol * sym)
266 memmap *segment = SPEC_OCLS (sym->etype);
267 addSet (&segment->syms, sym);
270 /*-----------------------------------------------------------------*/
271 /* allocGlobal - assigns the output segment to a global var */
272 /*-----------------------------------------------------------------*/
274 allocGlobal (symbol * sym)
277 /* symbol name is internal name */
278 if (!sym->level) /* local statics can come here */
279 sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
281 /* add it to the operandKey reset */
282 addSet (&operKeyReset, sym);
284 /* if this is a literal e.g. enumerated type */
285 /* put it in the data segment & do nothing */
286 if (IS_LITERAL (sym->etype))
288 SPEC_OCLS (sym->etype) = data;
292 /* if this is a function then assign code space */
293 if (IS_FUNC (sym->type))
295 SPEC_OCLS (sym->etype) = code;
296 /* if this is an interrupt service routine
297 then put it in the interrupt service array */
298 if (FUNC_ISISR (sym->type))
301 if (interrupts[FUNC_INTNO (sym->type)])
302 werror (E_INT_DEFINED,
303 FUNC_INTNO (sym->type),
304 interrupts[FUNC_INTNO (sym->type)]->name);
306 interrupts[FUNC_INTNO (sym->type)] = sym;
308 /* automagically extend the maximum interrupts */
309 if (FUNC_INTNO (sym->type) >= maxInterrupts)
310 maxInterrupts = FUNC_INTNO (sym->type) + 1;
312 /* if it is not compiler defined */
319 /* if this is a SFR or SBIT */
320 if (SPEC_SCLS (sym->etype) == S_SFR ||
321 SPEC_SCLS (sym->etype) == S_SBIT)
324 /* if both absolute address & initial */
325 /* value specified then error */
326 if (IS_ABSOLUTE (sym->etype) && sym->ival)
328 werror (E_SFR_INIT, sym->name);
332 SPEC_OCLS (sym->etype) =
333 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
339 /* if this is a bit variable and no storage class */
340 if (SPEC_NOUN (sym->etype) == V_BIT
341 && SPEC_SCLS (sym->etype) == S_BIT)
343 SPEC_OCLS (sym->etype) = bit;
348 /* if bit storage class */
349 if (SPEC_SCLS (sym->etype) == S_SBIT)
351 SPEC_OCLS (sym->etype) = bit;
356 /* register storage class ignored changed to FIXED */
357 if (SPEC_SCLS (sym->etype) == S_REGISTER)
358 SPEC_SCLS (sym->etype) = S_FIXED;
360 /* if data specified then */
361 if (SPEC_SCLS (sym->etype) == S_DATA)
363 /* set the output class */
364 SPEC_OCLS (sym->etype) = data;
365 /* generate the symbol */
370 /* if it is fixed, then allocate depending on the */
371 /* current memory model,same for automatics */
372 if (SPEC_SCLS (sym->etype) == S_FIXED ||
373 SPEC_SCLS (sym->etype) == S_AUTO)
375 /* set the output class */
376 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
377 /* generate the symbol */
382 /* if code change to constant */
383 if (SPEC_SCLS (sym->etype) == S_CODE) {
384 SPEC_OCLS (sym->etype) = statsg;
389 if (SPEC_SCLS (sym->etype) == S_XDATA)
391 SPEC_OCLS (sym->etype) = xdata;
392 // should we move this to the initialized data segment?
393 if (port->genXINIT &&
394 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
395 SPEC_OCLS(sym->etype)=xidata;
396 addSet(&xidata->syms, sym);
402 if (SPEC_SCLS (sym->etype) == S_IDATA)
404 SPEC_OCLS (sym->etype) = idata;
410 if (SPEC_SCLS (sym->etype) == S_EEPROM)
412 SPEC_OCLS (sym->etype) = eeprom;
420 /*-----------------------------------------------------------------*/
421 /* allocParms - parameters are always passed on stack */
422 /*-----------------------------------------------------------------*/
424 allocParms (value * val)
429 for (lval = val; lval; lval = lval->next, pNum++)
432 /* check the declaration */
433 checkDecl (lval->sym, 0);
435 /* if this a register parm then allocate
436 it as a local variable by adding it
437 to the first block we see in the body */
438 if (IS_REGPARM (lval->etype))
441 /* mark it as my parameter */
442 lval->sym->ismyparm = 1;
443 lval->sym->localof = currFunc;
446 /* if automatic variables r 2b stacked */
447 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
451 lval->sym->onStack = 1;
453 /* choose which stack 2 use */
454 /* use xternal stack */
455 if (options.useXstack)
457 /* PENDING: stack direction support */
458 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
459 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
460 xstackPtr - getSize (lval->type);
461 xstackPtr -= getSize (lval->type);
464 { /* use internal stack */
465 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
466 if (port->stack.direction > 0)
468 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
469 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
470 getSize (lval->type) -
471 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
472 stackPtr -= getSize (lval->type);
476 /* This looks like the wrong order but it turns out OK... */
477 /* PENDING: isr, bank overhead, ... */
478 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
480 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
481 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
483 stackPtr += getSize (lval->type);
486 allocIntoSeg (lval->sym);
489 { /* allocate them in the automatic space */
490 /* generate a unique name */
491 sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
492 strcpy (lval->name, lval->sym->rname);
494 /* if declared in external storage */
495 if (SPEC_SCLS (lval->etype) == S_XDATA)
496 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
498 /* other wise depending on the memory model
499 note here that we put it into the overlay segment
500 first, we will remove it from the overlay segment
501 after the overlay determination has been done */
502 if (options.model == MODEL_SMALL)
504 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
505 (options.noOverlay ? port->mem.default_local_map
510 SPEC_SCLS (lval->etype) = S_XDATA;
511 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
513 allocIntoSeg (lval->sym);
520 /*-----------------------------------------------------------------*/
521 /* deallocParms - parameters are always passed on stack */
522 /*-----------------------------------------------------------------*/
524 deallocParms (value * val)
528 for (lval = val; lval; lval = lval->next)
531 /* unmark is myparm */
532 lval->sym->ismyparm = 0;
533 /* if on stack then depending on which stack */
535 /* delete it from the symbol table */
536 deleteSym (SymbolTab, lval->sym, lval->sym->name);
538 if (!lval->sym->isref)
540 lval->sym->allocreq = 1;
541 werror (W_NO_REFERENCE, currFunc->name,
542 "function argument", lval->sym->name);
545 /* move the rname if any to the name for both val & sym */
546 /* and leave a copy of it in the symbol table */
547 if (lval->sym->rname[0])
549 char buffer[SDCC_NAME_MAX];
550 strcpy (buffer, lval->sym->rname);
551 lval->sym = copySymbol (lval->sym);
552 strcpy (lval->sym->rname, buffer);
553 strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
554 addSym (SymbolTab, lval->sym, lval->sym->name,
555 lval->sym->level, lval->sym->block, 1);
556 lval->sym->_isparm = 1;
557 addSet (&operKeyReset, lval->sym);
565 /*-----------------------------------------------------------------*/
566 /* allocLocal - allocate local variables */
567 /*-----------------------------------------------------------------*/
569 allocLocal (symbol * sym)
572 /* generate an unique name */
573 sprintf (sym->rname, "%s%s_%s_%d_%d",
575 currFunc->name, sym->name, sym->level, sym->block);
578 sym->localof = currFunc;
580 /* if this is a static variable */
581 if (IS_STATIC (sym->etype))
588 /* if volatile then */
589 if (IS_VOLATILE (sym->etype))
592 /* this is automatic */
594 /* if it to be placed on the stack */
595 if (options.stackAuto || reentrant) {
597 if (options.useXstack) {
598 /* PENDING: stack direction for xstack */
599 SPEC_OCLS (sym->etype) = xstack;
600 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
601 xstackPtr += getSize (sym->type);
603 SPEC_OCLS (sym->etype) = istack;
604 if (port->stack.direction > 0) {
605 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
606 stackPtr += getSize (sym->type);
608 stackPtr -= getSize (sym->type);
609 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
616 /* else depending on the storage class specified */
617 if (SPEC_SCLS (sym->etype) == S_XDATA)
619 SPEC_OCLS (sym->etype) = xdata;
624 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
625 SPEC_OCLS (sym->etype) = statsg;
630 if (SPEC_SCLS (sym->etype) == S_IDATA)
632 SPEC_OCLS (sym->etype) = idata;
638 /* if this is a function then assign code space */
639 if (IS_FUNC (sym->type))
641 SPEC_OCLS (sym->etype) = code;
645 /* if this is a SFR or SBIT */
646 if (SPEC_SCLS (sym->etype) == S_SFR ||
647 SPEC_SCLS (sym->etype) == S_SBIT)
650 /* if both absolute address & initial */
651 /* value specified then error */
652 if (IS_ABSOLUTE (sym->etype) && sym->ival)
654 werror (E_SFR_INIT, sym->name);
658 SPEC_OCLS (sym->etype) =
659 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
665 /* if this is a bit variable and no storage class */
666 if (SPEC_NOUN (sym->etype) == V_BIT
667 && (SPEC_SCLS (sym->etype) == S_BIT))
669 SPEC_OCLS (sym->etype) = bit;
674 if (SPEC_SCLS (sym->etype) == S_DATA)
676 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
681 if (SPEC_SCLS (sym->etype) == S_EEPROM)
683 SPEC_OCLS (sym->etype) = eeprom;
688 /* again note that we have put it into the overlay segment
689 will remove and put into the 'data' segment if required after
690 overlay analysis has been done */
691 if (options.model == MODEL_SMALL) {
692 SPEC_OCLS (sym->etype) =
693 (options.noOverlay ? port->mem.default_local_map
696 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
701 /*-----------------------------------------------------------------*/
702 /* deallocLocal - deallocates the local variables */
703 /*-----------------------------------------------------------------*/
705 deallocLocal (symbol * csym)
709 for (sym = csym; sym; sym = sym->next)
714 /* if it is on the stack */
717 if (options.useXstack)
718 xstackPtr -= getSize (sym->type);
720 stackPtr -= getSize (sym->type);
722 /* if not used give a warning */
723 if (!sym->isref && !IS_STATIC (sym->etype))
724 werror (W_NO_REFERENCE, currFunc->name,
725 "local variable", sym->name);
726 /* now delete it from the symbol table */
727 deleteSym (SymbolTab, sym, sym->name);
731 /*-----------------------------------------------------------------*/
732 /* overlay2data - moves declarations from the overlay seg to data */
733 /*-----------------------------------------------------------------*/
739 for (sym = setFirstItem (overlay->syms); sym;
740 sym = setNextItem (overlay->syms))
743 SPEC_OCLS (sym->etype) = data;
747 setToNull ((void **) &overlay->syms);
751 /*-----------------------------------------------------------------*/
752 /* overlay2Set - will add all symbols from the overlay segment to */
753 /* the set of sets containing the overlable symbols */
754 /*-----------------------------------------------------------------*/
761 for (sym = setFirstItem (overlay->syms); sym;
762 sym = setNextItem (overlay->syms))
768 setToNull ((void **) &overlay->syms);
769 addSet (&ovrSetSets, oset);
773 /*-----------------------------------------------------------------*/
774 /* allocVariables - creates decl & assign storage class for a v */
775 /*-----------------------------------------------------------------*/
777 allocVariables (symbol * symChain)
784 /* go thru the symbol chain */
785 for (sym = symChain; sym; sym = sym->next)
788 /* if this is a typedef then add it */
789 /* to the typedef table */
790 if (IS_TYPEDEF (sym->etype))
792 /* check if the typedef already exists */
793 csym = findSym (TypedefTab, NULL, sym->name);
794 if (csym && csym->level == sym->level)
795 werror (E_DUPLICATE_TYPEDEF, sym->name);
797 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
798 continue; /* go to the next one */
800 /* make sure it already exist */
801 csym = findSymWithLevel (SymbolTab, sym);
802 if (!csym || (csym && csym->level != sym->level))
805 /* check the declaration */
808 /* if this is a function or a pointer to function */
809 /* then args processing */
810 if (funcInChain (csym->type))
812 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
813 processFuncArgs (csym);
815 /* if register bank specified then update maxRegBank */
816 if (maxRegBank < FUNC_REGBANK (csym->type))
817 maxRegBank = FUNC_REGBANK (csym->type);
820 /* if this is a extern variable then change the */
821 /* level to zero temporarily */
822 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
824 saveLevel = csym->level;
828 /* if this is a literal then it is an enumerated */
829 /* type so need not allocate it space for it */
830 if (IS_LITERAL (sym->etype))
833 /* generate the actual declaration */
838 stack += getSize (csym->type);
843 /* restore the level */
844 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
845 csym->level = saveLevel;
851 /*-----------------------------------------------------------------*/
852 /* redoStackOffsets :- will reassign the values for stack offsets */
853 /*-----------------------------------------------------------------*/
855 redoStackOffsets (void)
861 /* after register allocation is complete we know
862 which variables will need to be assigned space
863 on the stack. We will eliminate those variables
864 which do not have the allocReq flag thus reducing
866 for (sym = setFirstItem (istack->syms); sym;
867 sym = setNextItem (istack->syms))
870 int size = getSize (sym->type);
871 /* nothing to do with parameters so continue */
872 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
875 if (IS_AGGREGATE (sym->type))
877 if (port->stack.direction > 0)
879 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
885 SPEC_STAK (sym->etype) = sym->stack = sPtr;
890 /* if allocation not required then subtract
891 size from overall stack size & continue */
894 currFunc->stack -= size;
895 SPEC_STAK (currFunc->etype) -= size;
899 if (port->stack.direction > 0)
901 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
907 SPEC_STAK (sym->etype) = sym->stack = sPtr;
911 /* do the same for the external stack */
913 for (sym = setFirstItem (xstack->syms); sym;
914 sym = setNextItem (xstack->syms))
917 int size = getSize (sym->type);
918 /* nothing to do with parameters so continue */
919 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
922 if (IS_AGGREGATE (sym->type))
924 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
929 /* if allocation not required then subtract
930 size from overall stack size & continue */
933 currFunc->xstack -= size;
934 SPEC_STAK (currFunc->etype) -= size;
938 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
942 /* if the debug option is set then output the
943 symbols to the map file */
946 for (sym = setFirstItem (istack->syms); sym;
947 sym = setNextItem (istack->syms))
948 cdbSymbol (sym, cdbFile, FALSE, FALSE);
950 for (sym = setFirstItem (xstack->syms); sym;
951 sym = setNextItem (xstack->syms))
952 cdbSymbol (sym, cdbFile, FALSE, FALSE);
956 /*-----------------------------------------------------------------*/
957 /* printAllocInfoSeg- print the allocation for a given section */
958 /*-----------------------------------------------------------------*/
960 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
969 for (sym = setFirstItem (map->syms); sym;
970 sym = setNextItem (map->syms))
975 if (sym->localof != func)
977 fprintf (of, ";%-25s Allocated to ", sym->name);
979 /* if assigned to registers */
980 if (!sym->allocreq && sym->reqv)
983 sym = OP_SYMBOL (sym->reqv);
984 fprintf (of, "registers ");
985 for (i = 0; i < 4 && sym->regs[i]; i++)
986 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
994 fprintf (of, "stack - offset %d\n", sym->stack);
998 /* otherwise give rname */
999 fprintf (of, "in memory with name '%s'\n", sym->rname);
1003 /*-----------------------------------------------------------------*/
1004 /* canOverlayLocals - returns true if the local variables can overlayed */
1005 /*-----------------------------------------------------------------*/
1007 canOverlayLocals (eBBlock ** ebbs, int count)
1010 /* if staticAuto is in effect or the current function
1011 being compiled is reentrant or the overlay segment
1012 is empty or no overlay option is in effect then */
1013 if (options.noOverlay ||
1014 options.stackAuto ||
1016 (IFFUNC_ISREENT (currFunc->type) ||
1017 FUNC_ISISR (currFunc->type))) ||
1018 elementsInSet (overlay->syms) == 0)
1022 /* if this is a forces overlay */
1023 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1025 /* otherwise do thru the blocks and see if there
1026 any function calls if found then return false */
1027 for (i = 0; i < count; i++)
1031 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1033 if (ic->op == CALL) {
1034 sym_link *ftype = operandType(IC_LEFT(ic));
1035 /* builtins only can use overlays */
1036 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1037 } else if (ic->op == PCALL) return FALSE;
1041 /* no function calls found return TRUE */
1045 /*-----------------------------------------------------------------*/
1046 /* doOverlays - move the overlay segment to appropriate location */
1047 /*-----------------------------------------------------------------*/
1049 doOverlays (eBBlock ** ebbs, int count)
1051 /* check if the parameters and local variables
1052 of this function can be put in the overlay segment
1053 This check is essentially to see if the function
1054 calls any other functions if yes then we cannot
1056 if (canOverlayLocals (ebbs, count))
1057 /* if we can then put the parameters &
1058 local variables in the overlay set */
1061 /* otherwise put them into data where
1066 /*-----------------------------------------------------------------*/
1067 /* printAllocInfo - prints allocation information for a function */
1068 /*-----------------------------------------------------------------*/
1070 printAllocInfo (symbol * func, FILE * of)
1075 /* must be called after register allocation is complete */
1076 fprintf (of, ";------------------------------------------------------------\n");
1077 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1078 fprintf (of, ";------------------------------------------------------------\n");
1080 printAllocInfoSeg (xstack, func, of);
1081 printAllocInfoSeg (istack, func, of);
1082 printAllocInfoSeg (code, func, of);
1083 printAllocInfoSeg (data, func, of);
1084 printAllocInfoSeg (xdata, func, of);
1085 printAllocInfoSeg (idata, func, of);
1086 printAllocInfoSeg (sfr, func, of);
1087 printAllocInfoSeg (sfrbit, func, of);