Merge of the izt changes.
[fw/sdcc] / src / SDCCmem.c
1 /*-----------------------------------------------------------------*/
2 /* SDCCmem.c - 8051 memory management routines                     */
3 /*-----------------------------------------------------------------*/
4
5 #include "common.h"
6
7 /* memory segments */
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  *idata = NULL;   /* internal data upto 256     */
14 memmap  *bit   = NULL;   /* bit addressable space      */
15 memmap  *statsg= NULL;   /* the constant data segment  */
16 memmap  *sfr   = NULL;   /* register space              */
17 memmap  *reg   = NULL;   /* register space              */
18 memmap  *sfrbit= NULL;   /* sfr bit space               */
19 memmap  *generic=NULL;   /* is a generic pointer        */
20 memmap  *overlay=NULL;   /* overlay segment             */
21 memmap  *eeprom =NULL;   /* eeprom location             */
22 memmap  *home   =NULL;   /* Unswitchable code bank      */
23
24 /* this is a set of sets each set containing
25    symbols in a single overlay */
26 set *ovrSetSets = NULL;    
27
28 int maxRegBank = 0;
29 int fatalError = 0                       ;/* fatal error flag                   */
30
31 /*-----------------------------------------------------------------*/
32 /* allocMap - allocates a memory map                               */
33 /*-----------------------------------------------------------------*/
34 memmap *allocMap (char rspace,     /* sfr space            */
35                   char farmap,     /* far or near segment  */
36                   char paged ,     /* can this segment be paged  */
37                   char direct,     /* directly addressable */
38                   char bitaddr,    /* bit addressable space*/
39                   char codemap,    /* this is code space   */
40                   unsigned sloc,   /* starting location    */
41                   const char *name,      /* 2 character name     */
42                   char dbName    , /* debug name                 */
43                   int  ptrType     /* pointer type for this space */
44                   )
45 {
46         memmap *map ;
47
48         if (!(map = GC_malloc(sizeof(memmap)))) {
49                 werror(E_OUT_OF_MEM,__FILE__,sizeof(memmap));
50                 exit (1);
51         }
52
53         memset(map, ZERO, sizeof(memmap));
54         map->regsp  =  rspace   ;
55         map->fmap   =  farmap   ;
56         map->paged   =  paged    ;
57         map->direct  =  direct   ;
58         map->bitsp  =  bitaddr  ;
59         map->codesp =  codemap  ;
60         map->sloc   =  sloc ;
61         map->sname = name ;
62         map->dbName = dbName ;
63         map->ptrType= ptrType;
64         if (!(map->oFile = tempfile())) {
65                 werror(E_TMPFILE_FAILED);
66                 exit (1);
67         } 
68         addSetHead (&tmpfileSet,map->oFile);
69         map->syms = NULL ;
70         return map;
71 }
72
73 /*-----------------------------------------------------------------*/
74 /* initMem - allocates and initializes all the segments            */
75 /*-----------------------------------------------------------------*/
76 void initMem ()
77 {       
78         /* allocate all the segments */
79         /* xternal stack segment ;   
80                    SFRSPACE       -   NO
81                    FAR-SPACE      -   YES
82                    PAGED          -   YES
83                    DIRECT-ACCESS  -   NO
84                    BIT-ACCESS     -   NO
85                    CODE-ACESS     -   NO 
86                    DEBUG-NAME     -   'A'
87                    POINTER-TYPE   -   FPOINTER
88         */
89         xstack    = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME,'A',PPOINTER);
90
91         /* internal stack segment ;   
92                    SFRSPACE       -   NO
93                    FAR-SPACE      -   NO
94                    PAGED          -   NO
95                    DIRECT-ACCESS  -   NO
96                    BIT-ACCESS     -   NO
97                    CODE-ACESS     -   NO 
98                    DEBUG-NAME     -   'B'
99                    POINTER-TYPE   -   POINTER
100         */
101         istack    = allocMap (0, 0, 0, 0, 0, 0,options.stack_loc, ISTACK_NAME,'B',POINTER);
102
103         /* code  segment ;   
104                    SFRSPACE       -   NO
105                    FAR-SPACE      -   YES
106                    PAGED          -   NO
107                    DIRECT-ACCESS  -   NO
108                    BIT-ACCESS     -   NO
109                    CODE-ACESS     -   YES 
110                    DEBUG-NAME     -   'C'
111                    POINTER-TYPE   -   CPOINTER
112         */
113         code      = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
114
115         /* home  segment ;   
116                    SFRSPACE       -   NO
117                    FAR-SPACE      -   YES
118                    PAGED          -   NO
119                    DIRECT-ACCESS  -   NO
120                    BIT-ACCESS     -   NO
121                    CODE-ACESS     -   YES 
122                    DEBUG-NAME     -   'C'
123                    POINTER-TYPE   -   CPOINTER
124         */
125         home      = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
126
127         /* Static segment (code for variables );
128                    SFRSPACE       -   NO
129                    FAR-SPACE      -   YES
130                    PAGED          -   NO
131                    DIRECT-ACCESS  -   NO
132                    BIT-ACCESS     -   NO
133                    CODE-ACESS     -   YES 
134                    DEBUG-NAME     -   'D'
135                    POINTER-TYPE   -   CPOINTER
136         */
137         statsg    = allocMap (0, 1, 0, 0, 0, 1,0, STATIC_NAME,'D',CPOINTER);
138
139         /* Data segment - internal storage segment ;
140                    SFRSPACE       -   NO
141                    FAR-SPACE      -   NO
142                    PAGED          -   NO
143                    DIRECT-ACCESS  -   YES
144                    BIT-ACCESS     -   NO
145                    CODE-ACESS     -   NO 
146                    DEBUG-NAME     -   'E'
147                    POINTER-TYPE   -   POINTER
148         */      
149         data      = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
150
151         /* overlay segment - same as internal storage segment ;
152                    SFRSPACE       -   NO
153                    FAR-SPACE      -   NO
154                    PAGED          -   NO
155                    DIRECT-ACCESS  -   YES
156                    BIT-ACCESS     -   NO
157                    CODE-ACESS     -   NO 
158                    DEBUG-NAME     -   'E'
159                    POINTER-TYPE   -   POINTER
160         */
161         overlay   = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
162
163         /* Xternal Data segment - 
164                    SFRSPACE       -   NO
165                    FAR-SPACE      -   YES
166                    PAGED          -   NO
167                    DIRECT-ACCESS  -   NO
168                    BIT-ACCESS     -   NO
169                    CODE-ACESS     -   NO 
170                    DEBUG-NAME     -   'F'
171                    POINTER-TYPE   -   FPOINTER
172         */
173         xdata     = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME,'F',FPOINTER);
174
175         /* Inderectly addressed internal data segment
176                    SFRSPACE       -   NO
177                    FAR-SPACE      -   NO
178                    PAGED          -   NO
179                    DIRECT-ACCESS  -   NO
180                    BIT-ACCESS     -   NO
181                    CODE-ACESS     -   NO 
182                    DEBUG-NAME     -   'G'
183                    POINTER-TYPE   -   IPOINTER
184         */
185         idata     = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,IDATA_NAME,'G',IPOINTER);
186
187         /* Static segment (code for variables );
188                    SFRSPACE       -   NO
189                    FAR-SPACE      -   NO
190                    PAGED          -   NO
191                    DIRECT-ACCESS  -   YES
192                    BIT-ACCESS     -   YES
193                    CODE-ACESS     -   NO 
194                    DEBUG-NAME     -   'H'
195                    POINTER-TYPE   -  _NONE_
196         */
197         bit       = allocMap (0, 0, 0, 1, 1, 0,0, BIT_NAME,'H',0);
198         
199         /* Special function register space :-
200                    SFRSPACE       -   YES
201                    FAR-SPACE      -   NO
202                    PAGED          -   NO
203                    DIRECT-ACCESS  -   YES
204                    BIT-ACCESS     -   NO
205                    CODE-ACESS     -   NO 
206                    DEBUG-NAME     -   'I'
207                    POINTER-TYPE   -   _NONE_
208         */
209         sfr        = allocMap (1,0, 0, 1, 0, 0,0, REG_NAME,'I',0);
210
211         /* Register space ;
212                    SFRSPACE       -   YES
213                    FAR-SPACE      -   NO
214                    PAGED          -   NO
215                    DIRECT-ACCESS  -   NO
216                    BIT-ACCESS     -   NO
217                    CODE-ACESS     -   NO 
218                    DEBUG-NAME     -   ' '
219                    POINTER-TYPE   -   _NONE_
220         */
221         reg        = allocMap (1,0, 0, 0, 0, 0, 0,REG_NAME,' ',0);
222
223         /* SFR bit space 
224                    SFRSPACE       -   YES
225                    FAR-SPACE      -   NO
226                    PAGED          -   NO
227                    DIRECT-ACCESS  -   YES
228                    BIT-ACCESS     -   YES
229                    CODE-ACESS     -   NO 
230                    DEBUG-NAME     -   'J'
231                    POINTER-TYPE   -   _NONE_
232         */
233         sfrbit     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0);
234
235         /* EEPROM bit space 
236                    SFRSPACE       -   NO
237                    FAR-SPACE      -   YES
238                    PAGED          -   NO
239                    DIRECT-ACCESS  -   NO
240                    BIT-ACCESS     -   NO
241                    CODE-ACESS     -   NO 
242                    DEBUG-NAME     -   'K'
243                    POINTER-TYPE   -   EEPPOINTER
244         */
245         eeprom     = allocMap (0,1, 0, 0, 0, 0,0, REG_NAME,'K',EEPPOINTER);
246
247         /* the unknown map */
248         generic     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,' ',GPOINTER);
249        
250 }
251
252 /*-----------------------------------------------------------------*/
253 /* allocIntoSeg - puts a symbol into a memory segment              */
254 /*-----------------------------------------------------------------*/
255 void allocIntoSeg (symbol *sym) 
256 {
257     memmap *segment = SPEC_OCLS(sym->etype);
258     addSet (&segment->syms,sym);
259 }
260
261 /*-----------------------------------------------------------------*/
262 /* allocGlobal - aassigns the output segment to a global var       */
263 /*-----------------------------------------------------------------*/
264 void allocGlobal ( symbol *sym )
265 {
266         
267     /* symbol name is internal name  */
268     if (!sym->level) /* local statics can come here */
269             sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name);
270     
271     /* add it to the operandKey reset */
272     addSet(&operKeyReset,sym);
273         
274     /* if this is a literal e.g. enumerated type */
275     /* put it in the data segment & do nothing   */
276     if (IS_LITERAL(sym->etype)) {
277         SPEC_OCLS(sym->etype) = data ;
278         return ;
279     }
280        
281     /* if this is a function then assign code space    */
282     if (IS_FUNC(sym->type)) {
283         SPEC_OCLS(sym->etype)  = code ;
284         /* if this is an interrupt service routine
285            then put it in the interrupt service array */
286         if (IS_ISR(sym->etype)) { 
287
288             if (interrupts[SPEC_INTN(sym->etype)]) 
289                 werror(E_INT_DEFINED,
290                        SPEC_INTN(sym->etype),
291                        interrupts[SPEC_INTN(sym->etype)]->name);
292             else
293                 interrupts[SPEC_INTN(sym->etype)] = sym;        
294             
295             /* automagically extend the maximum interrupts */
296             if (SPEC_INTN(sym->etype) >= maxInterrupts )
297                 maxInterrupts = SPEC_INTN(sym->etype) + 1;
298         }
299         /* if it is not compiler defined */
300         if (!sym->cdef)
301             allocIntoSeg(sym);                     
302
303         return ;
304     }
305         
306     /* if this is a  SFR or SBIT */
307     if (  SPEC_SCLS(sym->etype) == S_SFR   ||
308           SPEC_SCLS(sym->etype) == S_SBIT  )  {
309         
310         /* if both absolute address & initial  */
311         /* value specified then error        */
312         if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
313             werror(E_SFR_INIT,sym->name);
314             sym->ival = NULL ;
315         }
316         
317         SPEC_OCLS(sym->etype) = 
318             (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
319         
320         allocIntoSeg (sym);
321         return ;
322     }
323     
324     /* if this is a bit variable and no storage class */
325     if ( SPEC_NOUN(sym->etype) == V_BIT  
326          && SPEC_SCLS(sym->etype) == S_BIT ) {       
327         SPEC_OCLS(sym->etype) = bit ;
328         allocIntoSeg (sym);
329         return  ;
330     }
331
332     /* if bit storage class */
333     if ( SPEC_SCLS(sym->etype) == S_SBIT ) {
334         SPEC_OCLS(sym->etype) = bit;
335         allocIntoSeg(sym);
336         return ;
337     }
338     
339     /* register storage class ignored changed to FIXED */
340     if ( SPEC_SCLS(sym->etype) == S_REGISTER   )
341         SPEC_SCLS(sym->etype) = S_FIXED ;
342     
343     /* if data specified then  */
344     if (SPEC_SCLS(sym->etype) == S_DATA)  {
345         /* set the output class */
346         SPEC_OCLS(sym->etype) = data  ;
347         /* generate the symbol  */
348         allocIntoSeg (sym) ;
349         return   ;
350     }
351     
352     /* if it is fixed, then allocate depending on the  */
353     /* current memory model,same for automatics        */
354     if ( SPEC_SCLS(sym->etype) == S_FIXED  ||
355          SPEC_SCLS(sym->etype) == S_AUTO   ) {
356         /* set the output class */
357         SPEC_OCLS(sym->etype) = port->mem.default_globl_map ;
358         /* generate the symbol  */
359         allocIntoSeg  (sym) ;
360         return   ;
361     }
362     
363     /* if code change to constant */
364     if ( SPEC_SCLS(sym->etype) == S_CODE   ||
365          SPEC_SCLS(sym->etype) == S_CONSTANT )  {
366         SPEC_OCLS(sym->etype) = statsg   ;
367         allocIntoSeg (sym)  ;
368         return ;
369     }
370     
371     if ( SPEC_SCLS(sym->etype) == S_XDATA  )    {
372         SPEC_OCLS(sym->etype) = xdata  ;
373         allocIntoSeg(sym)  ;
374         return ;
375     }
376     
377     if ( SPEC_SCLS(sym->etype) == S_IDATA  )    {
378         SPEC_OCLS(sym->etype) = idata ;
379         sym->iaccess = 1;
380         allocIntoSeg (sym)  ;
381         return ;
382     }
383
384     if ( SPEC_SCLS(sym->etype) == S_EEPROM  )    {
385         SPEC_OCLS(sym->etype) = eeprom ;
386         allocIntoSeg (sym)  ;
387         return ;
388     }
389     
390     return ;
391 }
392
393 /*-----------------------------------------------------------------*/
394 /* allocParms - parameters are always passed on stack              */
395 /*-----------------------------------------------------------------*/
396 void allocParms ( value  *val )
397 {
398     value    *lval ;   
399     int      pNum = 1;
400
401     for ( lval = val ; lval ; lval = lval->next, pNum++ ) {
402
403         /* check the declaration */
404         checkDecl (lval->sym);
405         
406         /* if this a register parm then allocate
407            it as a local variable by adding it
408            to the first block we see in the body */
409         if (IS_REGPARM(lval->etype)) 
410             continue ;
411
412         /* mark it as my parameter */
413         lval->sym->ismyparm = 1;
414         lval->sym->localof = currFunc;
415
416         
417         /* if automatic variables r 2b stacked */
418         if ( options.stackAuto || IS_RENT(currFunc->etype)) {
419
420             if (lval->sym)
421                 lval->sym->onStack = 1;
422
423             /* choose which stack 2 use   */
424             /*  use xternal stack */
425             if ( options.useXstack )    {
426                 /* PENDING: stack direction support */
427                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xstack ;
428                 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
429                     xstackPtr - getSize(lval->type);            
430                 xstackPtr -= getSize (lval->type);
431             }
432             else   {    /* use internal stack   */
433                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = istack ;
434                 if (port->stack.direction > 0) {
435                     SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = 
436                         stackPtr - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) - 
437                         getSize(lval->type) -
438                         (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0); 
439                     stackPtr -= getSize (lval->type);
440                 }
441                 else {
442                     /* This looks like the wrong order but it turns out OK... */
443                     /* PENDING: isr, bank overhead, ... */
444                     SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = 
445                         stackPtr +
446                         (IS_BANKEDCALL(currFunc->etype) ? port->stack.banked_overhead : 0) +
447                         (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0) +
448                         0;
449                     stackPtr += getSize (lval->type);
450                 }                   
451             }
452             allocIntoSeg(lval->sym);
453         }
454         else   {        /* allocate them in the automatic space */
455             /* generate a unique name  */
456             sprintf (lval->sym->rname,"%s%s_PARM_%d", port->fun_prefix, currFunc->name,pNum);
457             strcpy  (lval->name,lval->sym->rname);
458             
459             /* if declared in external storage */
460             if (SPEC_SCLS(lval->etype) == S_XDATA) 
461                  SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
462             else
463                 /* other wise depending on the memory model 
464                    note here that we put it into the overlay segment
465                    first, we will remove it from the overlay segment
466                    after the overlay determination has been done */
467                 if (options.model == MODEL_SMALL) {
468                     SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
469                         ( options.model == MODEL_SMALL ? port->mem.default_local_map : 
470                           (options.noOverlay ? port->mem.default_local_map
471                            :overlay ));
472                 } else {
473                     SPEC_SCLS(lval->etype) = S_XDATA;
474                     SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
475                 }
476             allocIntoSeg(lval->sym);
477         }
478     }
479     
480     return ;
481 }
482
483 /*-----------------------------------------------------------------*/
484 /* deallocParms - parameters are always passed on stack                */
485 /*-----------------------------------------------------------------*/
486 void  deallocParms ( value *val )
487 {
488     value    *lval ;
489     
490     for ( lval = val ; lval ; lval = lval->next ) {
491
492         /* unmark is myparm */
493         lval->sym->ismyparm = 0;
494         /* if on stack then depending on which stack */
495         
496         /* delete it from the symbol table  */
497         deleteSym (SymbolTab,lval->sym,lval->sym->name); 
498
499         if (!lval->sym->isref) {
500             lval->sym->allocreq = 1;
501             werror(W_NO_REFERENCE,currFunc->name,
502                    "function argument",lval->sym->name);
503         }
504
505         /* move the rname if any to the name for both val & sym */
506         /* and leave a copy of it in the symbol table           */
507         if (lval->sym->rname[0]) {
508             char buffer[SDCC_NAME_MAX];
509             strcpy(buffer,lval->sym->rname);
510             lval->sym = copySymbol(lval->sym);
511             strcpy(lval->sym->rname,buffer);
512             strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname));
513             addSym (SymbolTab, lval->sym, lval->sym->name, 
514                     lval->sym->level,lval->sym->block);     
515             lval->sym->_isparm = 1;
516             addSet(&operKeyReset,lval->sym);
517         }
518
519     }
520     
521     return ;
522 }
523
524 /*-----------------------------------------------------------------*/
525 /* allocLocal - allocate local variables                           */
526 /*-----------------------------------------------------------------*/
527 void allocLocal ( symbol *sym  )
528 {   
529     
530     /* generate an unique name */
531     sprintf(sym->rname,"%s%s_%s_%d_%d",
532             port->fun_prefix,
533             currFunc->name,sym->name,sym->level,sym->block);
534     
535     sym->islocal = 1;
536     sym->localof = currFunc;
537
538     /* if this is a static variable */
539     if ( IS_STATIC (sym->etype)) {
540         allocGlobal(sym);
541         sym->allocreq = 1;
542         return   ;
543     }
544     
545     /* if volatile then */
546     if (IS_VOLATILE(sym->etype))
547         sym->allocreq = 1;
548
549     /* this is automatic           */
550
551     /* if it to be placed on the stack */
552     if ( options.stackAuto || reentrant) {
553                
554         sym->onStack = 1;
555         if ( options.useXstack ) { 
556             /* PENDING: stack direction for xstack */
557             SPEC_OCLS(sym->etype) = xstack ;
558             SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1);
559             xstackPtr += getSize (sym->type) ;
560         }
561         else {
562             SPEC_OCLS(sym->etype) = istack ;
563             if (port->stack.direction > 0) {
564                 SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
565                 stackPtr += getSize (sym->type) ;
566             }
567             else {
568                 stackPtr -= getSize (sym->type);
569                 SPEC_STAK(sym->etype) = sym->stack = stackPtr;
570             }
571         }
572         allocIntoSeg(sym);
573         return ;
574     }
575     
576     /* else depending on the storage class specified */
577     if ( SPEC_SCLS(sym->etype) == S_XDATA  )    {
578         SPEC_OCLS(sym->etype) = xdata  ;
579         allocIntoSeg(sym)  ;
580         return ;
581     }
582
583     if ( (SPEC_SCLS(sym->etype) == S_CODE   ||
584           SPEC_SCLS(sym->etype) == S_CONSTANT) &&
585          !sym->_isparm)  {
586         SPEC_OCLS(sym->etype) = statsg   ;
587         allocIntoSeg (sym)  ;
588         return ;
589     }
590
591     if ( SPEC_SCLS(sym->etype) == S_IDATA  )    {
592         SPEC_OCLS(sym->etype) = idata ;
593         sym->iaccess = 1;
594         allocIntoSeg (sym)  ;
595         return ;
596     }    
597
598         /* if this is a function then assign code space    */
599     if (IS_FUNC(sym->type)) {
600         SPEC_OCLS(sym->etype)  = code ;
601         return ;
602     }
603         
604     /* if this is a  SFR or SBIT */
605     if (  SPEC_SCLS(sym->etype) == S_SFR   ||
606           SPEC_SCLS(sym->etype) == S_SBIT  )  {
607         
608         /* if both absolute address & initial  */
609         /* value specified then error        */
610         if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
611             werror(E_SFR_INIT,sym->name);
612             sym->ival = NULL ;
613         }
614         
615         SPEC_OCLS(sym->etype) = 
616             (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
617         
618         allocIntoSeg (sym);
619         return ;
620     }
621     
622     /* if this is a bit variable and no storage class */
623     if ( SPEC_NOUN(sym->etype) == V_BIT  
624          && (SPEC_SCLS(sym->etype) == S_BIT)) {       
625         SPEC_OCLS(sym->etype) = bit ;
626         allocIntoSeg (sym);
627         return  ;
628     }
629
630     if ( SPEC_SCLS(sym->etype) == S_DATA  ) {
631         SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay );
632         allocIntoSeg(sym)  ;
633         return ;
634     }
635
636     if ( SPEC_SCLS(sym->etype) == S_EEPROM  ) {
637         SPEC_OCLS(sym->etype) = eeprom;
638         allocIntoSeg(sym)  ;
639         return ;
640     }
641     
642     /* again note that we have put it into the overlay segment
643        will remove and put into the 'data' segment if required after 
644        overlay  analysis has been done */   
645     SPEC_OCLS(sym->etype) = ( options.model == MODEL_SMALL ? port->mem.default_local_map : 
646                               (options.noOverlay ? port->mem.default_local_map
647                                : overlay )) ;
648     allocIntoSeg (sym); 
649 }
650
651 /*-----------------------------------------------------------------*/
652 /* deallocLocal - deallocates the local variables                  */
653 /*-----------------------------------------------------------------*/
654 void  deallocLocal ( symbol *csym )
655 {
656     symbol *sym ;
657     
658     for ( sym = csym ; sym ; sym = sym->next) {
659         if (sym->_isparm)
660             continue ;
661
662         /* if it is on the stack */
663         if (sym->onStack) { 
664             if (options.useXstack)
665                 xstackPtr -= getSize(sym->type);
666             else
667                 stackPtr  -= getSize(sym->type);
668         }
669         /* if not used give a warning */
670         if (!sym->isref && !IS_STATIC(sym->etype))
671             werror(W_NO_REFERENCE,currFunc->name,
672                    "local variable",sym->name);
673         /* now delete it from the symbol table */
674         deleteSym (SymbolTab,sym,sym->name);    
675     }
676 }
677
678 /*-----------------------------------------------------------------*/
679 /* overlay2data - moves declarations from the overlay seg to data  */
680 /*-----------------------------------------------------------------*/
681 void overlay2data()
682 {
683     symbol *sym;
684
685     for (sym = setFirstItem(overlay->syms); sym;
686          sym = setNextItem(overlay->syms)) {
687
688         SPEC_OCLS(sym->etype) = data;
689         allocIntoSeg(sym);
690     }
691
692     setToNull((void **) &overlay->syms);
693         
694 }
695
696 /*-----------------------------------------------------------------*/
697 /* overlay2Set - will add all symbols from the overlay segment to  */
698 /*               the set of sets containing the overlable symbols  */
699 /*-----------------------------------------------------------------*/
700 void overlay2Set ()
701 {
702     symbol *sym;
703     set *oset = NULL;
704
705     for (sym = setFirstItem(overlay->syms); sym;
706          sym = setNextItem(overlay->syms)) {
707
708         addSet(&oset,sym);
709     }
710     
711     setToNull((void **) &overlay->syms);
712     addSet (&ovrSetSets,oset);
713
714 }
715
716 /*-----------------------------------------------------------------*/
717 /* allocVariables - creates decl & assign storage class for a v    */
718 /*-----------------------------------------------------------------*/
719 int allocVariables ( symbol *symChain )
720 {
721     symbol   *sym;
722     symbol   *csym;
723     int      stack = 0;    
724     int      saveLevel = 0 ;
725     
726     /* go thru the symbol chain   */
727     for ( sym = symChain ; sym ;  sym = sym->next   ) {
728         
729         /* if this is a typedef then add it */
730         /* to the typedef table             */
731         if (IS_TYPEDEF(sym->etype)) {
732             /* check if the typedef already exists    */
733             csym = findSym (TypedefTab, NULL, sym->name );
734             if ( csym && csym->level == sym->level )
735                 werror(E_DUPLICATE_TYPEDEF,sym->name);
736             
737             addSym (TypedefTab, sym , sym->name,sym->level,sym->block);
738             continue ;  /* go to the next one         */
739         }
740         /* make sure it already exist */
741         csym = findSymWithLevel (SymbolTab, sym);
742         if (! csym || (csym && csym->level != sym->level) )
743             csym = sym;
744                 
745         /* check the declaration */
746         checkDecl   (csym);
747                 
748         /* if this is a function or a pointer to function */
749         /* then args  processing  */
750         if (funcInChain(csym->type)) {
751
752             processFuncArgs (csym, 1);
753             /* if register bank specified then update maxRegBank */
754             if (maxRegBank < SPEC_BANK(csym->etype))
755                 maxRegBank = SPEC_BANK(csym->etype);
756         }
757         
758         /* if this is a extern variable then change the */
759         /* level to zero temporarily                                    */
760         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
761             saveLevel = csym->level ;
762             csym->level = 0 ;
763         }
764         
765         /* if this is a literal then it is an enumerated */
766         /* type so need not allocate it space for it     */
767         if (IS_LITERAL(sym->etype))
768             continue ;
769         
770         /* generate the actual declaration  */
771         if ( csym->level  ) {
772             allocLocal  (csym);
773             if (csym->onStack)
774                 stack += getSize(csym->type) ;              
775         }
776         else 
777             allocGlobal (csym);
778
779         /* restore the level */
780         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) 
781             csym->level = saveLevel;            
782     }
783     
784     return stack ;
785 }
786
787 /*-----------------------------------------------------------------*/
788 /* redoStackOffsets :- will reassign the values for stack offsets  */
789 /*-----------------------------------------------------------------*/
790 void redoStackOffsets(void)
791 {
792     symbol *sym;
793     int sPtr = 0;
794     int xsPtr=-1;
795
796     /* after register allocation is complete we know
797        which variables will need to be assigned space
798        on the stack. We will eliminate those variables
799        which do not have the allocReq flag thus reducing
800        the stack space */
801     for ( sym = setFirstItem(istack->syms); sym;
802           sym = setNextItem(istack->syms)) {
803         
804         int size = getSize(sym->type);
805         /* nothing to do with parameters so continue */
806         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
807             continue ;
808         
809         if ( IS_AGGREGATE(sym->type)) {
810             if (port->stack.direction > 0) {
811                 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
812                 sPtr += size;
813             }
814             else {
815                 sPtr -= size;
816                 SPEC_STAK(sym->etype) = sym->stack = sPtr;
817             }
818             continue;
819         }
820
821         /* if allocation not required then subtract
822            size from overall stack size & continue */   
823         if (!sym->allocreq) {
824             currFunc->stack -= size;
825             SPEC_STAK(currFunc->etype) -= size;
826             continue ;
827         }
828
829         if (port->stack.direction > 0) {
830             SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
831             sPtr += size ;
832         }
833         else {
834             sPtr -= size ;
835             SPEC_STAK(sym->etype) = sym->stack = sPtr;
836         }
837     }
838
839     /* do the same for the external stack */
840     
841     for ( sym = setFirstItem(xstack->syms); sym;
842           sym = setNextItem(xstack->syms)) {
843         
844         int size  = getSize(sym->type);
845         /* nothing to do with parameters so continue */
846         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
847             continue ;
848         
849         if (IS_AGGREGATE(sym->type)) {
850             SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
851             xsPtr += size ;
852             continue ;
853         }      
854
855         /* if allocation not required then subtract
856            size from overall stack size & continue */   
857         if (!sym->allocreq) {
858             currFunc->xstack -= size;
859             SPEC_STAK(currFunc->etype) -= size;
860             continue ;
861         }
862
863         SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
864         xsPtr += size ;
865     }
866
867     /* if the debug option is set then output the
868        symbols to the map file */
869     if (options.debug && !options.nodebug) {
870         for (sym = setFirstItem(istack->syms); sym;
871              sym = setNextItem(istack->syms))
872             cdbSymbol(sym,cdbFile,FALSE,FALSE);
873
874         for (sym = setFirstItem(xstack->syms); sym;
875              sym = setNextItem(xstack->syms))
876             cdbSymbol(sym,cdbFile,FALSE,FALSE); 
877     }
878 }
879
880 /*-----------------------------------------------------------------*/
881 /* printAllocInfoSeg- print the allocation for a given section     */
882 /*-----------------------------------------------------------------*/
883 static void printAllocInfoSeg ( memmap *map, symbol *func, FILE *of)
884 {
885     symbol *sym;
886     
887     if (!map) return;
888     if (!map->syms) return;
889
890     for (sym = setFirstItem(map->syms); sym;
891          sym = setNextItem(map->syms)) {
892         
893         if (sym->level == 0) continue;
894         if (sym->localof != func) continue ;
895         fprintf(of,";%-25s Allocated to ",sym->name);
896
897         /* if assigned to registers */
898         if (!sym->allocreq && sym->reqv) {
899             int i;
900             sym = OP_SYMBOL(sym->reqv);
901             fprintf(of,"registers ");
902             for (i = 0 ; i < 4 && sym->regs[i] ; i++)
903                 fprintf(of,"%s ",port->getRegName(sym->regs[i]));
904             fprintf(of,"\n");
905             continue ;
906         }
907
908         /* if on stack */
909         if (sym->onStack) {
910             fprintf(of,"stack - offset %d\n",sym->stack);
911             continue;
912         }
913         
914         /* otherwise give rname */
915         fprintf(of,"in memory with name '%s'\n",sym->rname);
916     }
917 }
918
919 /*-----------------------------------------------------------------*/
920 /* canOverlayLocals - returns true if the local variables can overlayed */
921 /*-----------------------------------------------------------------*/
922 static bool canOverlayLocals (eBBlock **ebbs, int count)
923 {
924     int i;
925     /* if staticAuto is in effect or the current function
926        being compiled is reentrant or the overlay segment
927        is empty or no overlay option is in effect then */
928     if (options.noOverlay ||
929         options.stackAuto ||
930         (currFunc &&
931          (IS_RENT(currFunc->etype) ||
932           IS_ISR(currFunc->etype))) ||
933         elementsInSet(overlay->syms) == 0)
934         
935         return FALSE;
936
937     /* otherwise do thru the blocks and see if there
938        any function calls if found then return false */
939     for (i = 0; i < count ; i++ ) {
940         iCode *ic;
941
942         for (ic = ebbs[i]->sch; ic ; ic = ic->next)
943             if (ic && ( ic->op == CALL || ic->op == PCALL))
944                 return FALSE;
945     }
946
947     /* no function calls found return TRUE */
948     return TRUE;
949 }
950
951 /*-----------------------------------------------------------------*/
952 /* doOverlays - move the overlay segment to appropriate location   */
953 /*-----------------------------------------------------------------*/
954 void doOverlays( eBBlock **ebbs, int count)
955 {
956     /* check if the parameters and local variables
957        of this function can be put in the overlay segment
958        This check is essentially to see if the function
959        calls any other functions if yes then we cannot
960        overlay */
961     if (canOverlayLocals(ebbs,count))
962         /* if we can then put the parameters &
963            local variables in the overlay set */
964         overlay2Set();       
965     else
966         /* otherwise put them into data where
967            they belong */
968         overlay2data();
969 }
970
971 /*-----------------------------------------------------------------*/
972 /* printAllocInfo - prints allocation information for a function   */
973 /*-----------------------------------------------------------------*/
974 void printAllocInfo( symbol * func, FILE *of)
975 {
976     if (!of) of = stdout;
977
978     /* must be called after register allocation is complete */
979     fprintf(of,";------------------------------------------------------------\n");
980     fprintf(of,";Allocation info for local variables in function '%s'\n",func->name);
981     fprintf(of,";------------------------------------------------------------\n");
982     
983     printAllocInfoSeg(xstack,func,of);
984     printAllocInfoSeg(istack,func,of);
985     printAllocInfoSeg(code,func,of);
986     printAllocInfoSeg(data,func,of);
987     printAllocInfoSeg(xdata,func,of);
988     printAllocInfoSeg(idata,func,of);
989     printAllocInfoSeg(sfr,func,of);
990     printAllocInfoSeg(sfrbit,func,of);
991 }