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