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