Added initial stack direction support. Didnt convert xstack but are
[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                   const 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                 /* PENDING: stack direction support */
366                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xstack ;
367                 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
368                     xstackPtr - getSize(lval->type);            
369                 xstackPtr -= getSize (lval->type);
370             }
371             else   {    /* use internal stack   */
372                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = istack ;
373                 if (port->stack.direction > 0) {
374                     SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = 
375                         stackPtr - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) - 
376                         getSize(lval->type) -
377                         (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0); 
378                     stackPtr -= getSize (lval->type);
379                 }
380                 else {
381                     /* This looks like the wrong order but it turns out OK... */
382                     /* PENDING: isr, bank overhead, ... */
383                     SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = stackPtr;
384                     stackPtr += getSize (lval->type);
385                 }                   
386             }
387             allocIntoSeg(lval->sym);
388         }
389         else   {        /* allocate them in the automatic space */
390             /* generate a unique name  */
391             sprintf (lval->sym->rname,"_%s_PARM_%d",currFunc->name,pNum);
392             strcpy  (lval->name,lval->sym->rname);
393             
394             /* if declared in external storage */
395             if (SPEC_SCLS(lval->etype) == S_XDATA) 
396                  SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
397             else
398                 /* other wise depending on the memory model 
399                    note here that we put it into the overlay segment
400                    first, we will remove it from the overlay segment
401                    after the overlay determination has been done */
402                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
403                     ( options.model  ? xdata : (options.noOverlay ? data :overlay ));
404             
405             allocIntoSeg(lval->sym);
406         }
407     }
408     
409     return ;
410 }
411
412 /*-----------------------------------------------------------------*/
413 /* deallocParms - parameters are always passed on stack                */
414 /*-----------------------------------------------------------------*/
415 void  deallocParms ( value *val )
416 {
417     value    *lval ;
418     
419     for ( lval = val ; lval ; lval = lval->next ) {
420
421         /* unmark is myparm */
422         lval->sym->ismyparm = 0;
423         /* if on stack then depending on which stack */
424         
425         /* delete it from the symbol table  */
426         deleteSym (SymbolTab,lval->sym,lval->sym->name); 
427
428         if (!lval->sym->isref) {
429             lval->sym->allocreq = 1;
430             werror(W_NO_REFERENCE,currFunc->name,
431                    "function argument",lval->sym->name);
432         }
433
434         /* move the rname if any to the name for both val & sym */
435         /* and leave a copy of it in the symbol table           */
436         if (lval->sym->rname[0]) {
437             char buffer[SDCC_NAME_MAX];
438             strcpy(buffer,lval->sym->rname);
439             lval->sym = copySymbol(lval->sym);
440             strcpy(lval->sym->rname,buffer);
441             strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname));
442             addSym (SymbolTab, lval->sym, lval->sym->name, 
443                     lval->sym->level,lval->sym->block);     
444             lval->sym->_isparm = 1;
445             addSet(&operKeyReset,lval->sym);
446         }
447
448     }
449     
450     return ;
451 }
452
453 /*-----------------------------------------------------------------*/
454 /* allocLocal - allocate local variables                           */
455 /*-----------------------------------------------------------------*/
456 void allocLocal ( symbol *sym  )
457 {   
458     
459     /* generate an unique name */
460     sprintf(sym->rname,"_%s_%s_%d_%d",
461             currFunc->name,sym->name,sym->level,sym->block);
462     
463     sym->islocal = 1;
464     sym->localof = currFunc;
465
466     /* if this is a static variable */
467     if ( IS_STATIC (sym->etype)) {
468         SPEC_OCLS(sym->etype) = (options.model ? xdata : data );
469         allocIntoSeg (sym);
470         sym->allocreq = 1;
471         return   ;
472     }
473     
474     /* if volatile then */
475     if (IS_VOLATILE(sym->etype))
476         sym->allocreq = 1;
477
478     /* this is automatic           */
479
480     /* if it to be placed on the stack */
481     if ( options.stackAuto || reentrant) {
482                
483         sym->onStack = 1;
484         if ( options.useXstack ) { 
485             /* PENDING: stack direction for xstack */
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             if (port->stack.direction > 0) {
493                 SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
494                 stackPtr += getSize (sym->type) ;
495             }
496             else {
497                 stackPtr -= getSize (sym->type);
498                 SPEC_STAK(sym->etype) = sym->stack = stackPtr;
499             }
500         }
501         allocIntoSeg(sym);
502         return ;
503     }
504     
505     /* else depending on the storage class specified */
506     if ( SPEC_SCLS(sym->etype) == S_XDATA  )    {
507         SPEC_OCLS(sym->etype) = xdata  ;
508         allocIntoSeg(sym)  ;
509         return ;
510     }
511
512     if ( (SPEC_SCLS(sym->etype) == S_CODE   ||
513           SPEC_SCLS(sym->etype) == S_CONSTANT) &&
514          !sym->_isparm)  {
515         SPEC_OCLS(sym->etype) = statsg   ;
516         allocIntoSeg (sym)  ;
517         return ;
518     }
519
520     if ( SPEC_SCLS(sym->etype) == S_IDATA  )    {
521         SPEC_OCLS(sym->etype) = idata ;
522         sym->iaccess = 1;
523         allocIntoSeg (sym)  ;
524         return ;
525     }    
526
527         /* if this is a function then assign code space    */
528     if (IS_FUNC(sym->type)) {
529         SPEC_OCLS(sym->etype)  = code ;
530         return ;
531     }
532         
533     /* if this is a  SFR or SBIT */
534     if (  SPEC_SCLS(sym->etype) == S_SFR   ||
535           SPEC_SCLS(sym->etype) == S_SBIT  )  {
536         
537         /* if both absolute address & initial  */
538         /* value specified then error        */
539         if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
540             werror(E_SFR_INIT,sym->name);
541             sym->ival = NULL ;
542         }
543         
544         SPEC_OCLS(sym->etype) = 
545             (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
546         
547         allocIntoSeg (sym);
548         return ;
549     }
550     
551     /* if this is a bit variable and no storage class */
552     if ( SPEC_NOUN(sym->etype) == V_BIT  
553          && (SPEC_SCLS(sym->etype) == S_BIT)) {       
554         SPEC_OCLS(sym->etype) = bit ;
555         allocIntoSeg (sym);
556         return  ;
557     }
558
559     /* again note that we have put it into the overlay segment
560        will remove and put into the 'data' segment if required after 
561        overlay  analysis has been done */   
562     SPEC_OCLS(sym->etype) = ( options.model  ? xdata : 
563                               (options.noOverlay ? data : overlay )) ;
564     allocIntoSeg (sym); 
565 }
566
567 /*-----------------------------------------------------------------*/
568 /* deallocLocal - deallocates the local variables                  */
569 /*-----------------------------------------------------------------*/
570 void  deallocLocal ( symbol *csym )
571 {
572     symbol *sym ;
573     
574     for ( sym = csym ; sym ; sym = sym->next) {
575         if (sym->_isparm)
576             continue ;
577
578         /* if it is on the stack */
579         if (sym->onStack) { 
580             if (options.useXstack)
581                 xstackPtr -= getSize(sym->type);
582             else
583                 stackPtr  -= getSize(sym->type);
584         }
585         /* if not used give a warning */
586         if (!sym->isref && !IS_STATIC(sym->etype))
587             werror(W_NO_REFERENCE,currFunc->name,
588                    "local variable",sym->name);
589         /* now delete it from the symbol table */
590         deleteSym (SymbolTab,sym,sym->name);    
591     }
592 }
593
594 /*-----------------------------------------------------------------*/
595 /* overlay2data - moves declarations from the overlay seg to data  */
596 /*-----------------------------------------------------------------*/
597 void overlay2data()
598 {
599     symbol *sym;
600
601     for (sym = setFirstItem(overlay->syms); sym;
602          sym = setNextItem(overlay->syms)) {
603
604         SPEC_OCLS(sym->etype) = data;
605         allocIntoSeg(sym);
606     }
607
608     setToNull((void **) &overlay->syms);
609         
610 }
611
612 /*-----------------------------------------------------------------*/
613 /* overlay2Set - will add all symbols from the overlay segment to  */
614 /*               the set of sets containing the overlable symbols  */
615 /*-----------------------------------------------------------------*/
616 void overlay2Set ()
617 {
618     symbol *sym;
619     set *oset = NULL;
620
621     for (sym = setFirstItem(overlay->syms); sym;
622          sym = setNextItem(overlay->syms)) {
623
624         addSet(&oset,sym);
625     }
626     
627     setToNull((void **) &overlay->syms);
628     addSet (&ovrSetSets,oset);
629
630 }
631
632 /*-----------------------------------------------------------------*/
633 /* allocVariables - creates decl & assign storage class for a v    */
634 /*-----------------------------------------------------------------*/
635 int allocVariables ( symbol *symChain )
636 {
637     symbol   *sym;
638     symbol   *csym;
639     int      stack = 0;    
640     int      saveLevel = 0 ;
641     
642     /* go thru the symbol chain   */
643     for ( sym = symChain ; sym ;  sym = sym->next   ) {
644         
645         /* if this is a typedef then add it */
646         /* to the typedef table             */
647         if (IS_TYPEDEF(sym->etype)) {
648             /* check if the typedef already exists    */
649             csym = findSym (TypedefTab, NULL, sym->name );
650             if ( csym && csym->level == sym->level )
651                 werror(E_DUPLICATE_TYPEDEF,sym->name);
652             
653             addSym (TypedefTab, sym , sym->name,sym->level,sym->block);
654             continue ;  /* go to the next one         */
655         }
656         /* make sure it already exist */
657         csym = findSymWithLevel (SymbolTab, sym);
658         if (! csym || (csym && csym->level != sym->level) )
659             csym = sym;
660                 
661         /* check the declaration */
662         checkDecl   (csym);
663                 
664         /* if this is a function or a pointer to function */
665         /* then args  processing  */
666         if (funcInChain(csym->type)) {
667
668             processFuncArgs (csym, 1);
669             /* if register bank specified then update maxRegBank */
670             if (maxRegBank < SPEC_BANK(csym->etype))
671                 maxRegBank = SPEC_BANK(csym->etype);
672         }
673         
674         /* if this is a extern variable then change the */
675         /* level to zero temporarily                                    */
676         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
677             saveLevel = csym->level ;
678             csym->level = 0 ;
679         }
680         
681         /* if this is a literal then it is an enumerated */
682         /* type so need not allocate it space for it     */
683         if (IS_LITERAL(sym->etype))
684             continue ;
685         
686         /* generate the actual declaration  */
687         if ( csym->level  ) {
688             allocLocal  (csym);
689             if (csym->onStack)
690                 stack += getSize(csym->type) ;              
691         }
692         else 
693             allocGlobal (csym);
694
695         /* restore the level */
696         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) 
697             csym->level = saveLevel;            
698     }
699     
700     return stack ;
701 }
702
703 /*-----------------------------------------------------------------*/
704 /* redoStackOffsets :- will reassign the values for stack offsets  */
705 /*-----------------------------------------------------------------*/
706 void redoStackOffsets ()
707 {
708     symbol *sym;
709     int sPtr = 0;
710     int xsPtr=-1;
711
712     /* after register allocation is complete we know
713        which variables will need to be assigned space
714        on the stack. We will eliminate those variables
715        which do not have the allocReq flag thus reducing
716        the stack space */
717     for ( sym = setFirstItem(istack->syms); sym;
718           sym = setNextItem(istack->syms)) {
719         
720         int size = getSize(sym->type);
721         /* nothing to do with parameters so continue */
722         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
723             continue ;
724         
725         if ( IS_AGGREGATE(sym->type)) {
726             if (port->stack.direction > 0) {
727                 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
728                 sPtr += size;
729             }
730             else {
731                 sPtr -= size;
732                 SPEC_STAK(sym->etype) = sym->stack = sPtr;
733             }
734             continue;
735         }
736
737         /* if allocation not required then subtract
738            size from overall stack size & continue */   
739         if (!sym->allocreq) {
740             currFunc->stack -= size;
741             SPEC_STAK(currFunc->etype) -= size;
742             continue ;
743         }
744
745         if (port->stack.direction > 0) {
746             SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
747             sPtr += size ;
748         }
749         else {
750             sPtr -= size ;
751             SPEC_STAK(sym->etype) = sym->stack = sPtr;
752         }
753     }
754
755     /* do the same for the external stack */
756     
757     for ( sym = setFirstItem(xstack->syms); sym;
758           sym = setNextItem(xstack->syms)) {
759         
760         int size  = getSize(sym->type);
761         /* nothing to do with parameters so continue */
762         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
763             continue ;
764         
765         if (IS_AGGREGATE(sym->type)) {
766             SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
767             xsPtr += size ;
768             continue ;
769         }      
770
771         /* if allocation not required then subtract
772            size from overall stack size & continue */   
773         if (!sym->allocreq) {
774             currFunc->xstack -= size;
775             SPEC_STAK(currFunc->etype) -= size;
776             continue ;
777         }
778
779         SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
780         xsPtr += size ;
781     }
782
783     /* if the debug option is set then output the
784        symbols to the map file */
785     if (options.debug) {
786         for (sym = setFirstItem(istack->syms); sym;
787              sym = setNextItem(istack->syms))
788             cdbSymbol(sym,cdbFile,FALSE,FALSE);
789
790         for (sym = setFirstItem(xstack->syms); sym;
791              sym = setNextItem(xstack->syms))
792             cdbSymbol(sym,cdbFile,FALSE,FALSE); 
793     }
794 }