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