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