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