fixed a sprintf() bug, only visible in the ds390 port
[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 memmap *home = NULL;            /* Unswitchable code bank      */
23
24 /* this is a set of sets each set containing
25    symbols in a single overlay */
26 set *ovrSetSets = NULL;
27
28 int maxRegBank = 0;
29 int fatalError = 0;             /* fatal error flag                   */
30
31 /*-----------------------------------------------------------------*/
32 /* allocMap - allocates a memory map                               */
33 /*-----------------------------------------------------------------*/
34 memmap *
35 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,          /* debug name                 */
44           int ptrType           /* pointer type for this space */
45 )
46 {
47   memmap *map;
48
49   if (!(map = Safe_alloc (sizeof (memmap))))
50     {
51       werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
52       exit (1);
53     }
54
55   memset (map, ZERO, sizeof (memmap));
56   map->regsp = rspace;
57   map->fmap = farmap;
58   map->paged = paged;
59   map->direct = direct;
60   map->bitsp = bitaddr;
61   map->codesp = codemap;
62   map->sloc = sloc;
63   map->sname = name;
64   map->dbName = dbName;
65   map->ptrType = ptrType;
66   if (!(map->oFile = tempfile ()))
67     {
68       werror (E_TMPFILE_FAILED);
69       exit (1);
70     }
71   addSetHead (&tmpfileSet, map->oFile);
72   map->syms = NULL;
73   return map;
74 }
75
76 /*-----------------------------------------------------------------*/
77 /* initMem - allocates and initializes all the segments            */
78 /*-----------------------------------------------------------------*/
79 void 
80 initMem ()
81 {
82   /* allocate all the segments */
83   /* xternal stack segment ;   
84      SFRSPACE       -   NO
85      FAR-SPACE      -   YES
86      PAGED          -   YES
87      DIRECT-ACCESS  -   NO
88      BIT-ACCESS     -   NO
89      CODE-ACESS     -   NO 
90      DEBUG-NAME     -   'A'
91      POINTER-TYPE   -   FPOINTER
92    */
93   xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
94
95   /* internal stack segment ;   
96      SFRSPACE       -   NO
97      FAR-SPACE      -   NO
98      PAGED          -   NO
99      DIRECT-ACCESS  -   NO
100      BIT-ACCESS     -   NO
101      CODE-ACESS     -   NO 
102      DEBUG-NAME     -   'B'
103      POINTER-TYPE   -   POINTER
104    */
105   istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
106
107   /* code  segment ;   
108      SFRSPACE       -   NO
109      FAR-SPACE      -   YES
110      PAGED          -   NO
111      DIRECT-ACCESS  -   NO
112      BIT-ACCESS     -   NO
113      CODE-ACESS     -   YES 
114      DEBUG-NAME     -   'C'
115      POINTER-TYPE   -   CPOINTER
116    */
117   code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
118
119   /* home  segment ;   
120      SFRSPACE       -   NO
121      FAR-SPACE      -   YES
122      PAGED          -   NO
123      DIRECT-ACCESS  -   NO
124      BIT-ACCESS     -   NO
125      CODE-ACESS     -   YES 
126      DEBUG-NAME     -   'C'
127      POINTER-TYPE   -   CPOINTER
128    */
129   home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
130
131   /* Static segment (code for variables );
132      SFRSPACE       -   NO
133      FAR-SPACE      -   YES
134      PAGED          -   NO
135      DIRECT-ACCESS  -   NO
136      BIT-ACCESS     -   NO
137      CODE-ACESS     -   YES 
138      DEBUG-NAME     -   'D'
139      POINTER-TYPE   -   CPOINTER
140    */
141   statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
142
143   /* Data segment - internal storage segment ;
144      SFRSPACE       -   NO
145      FAR-SPACE      -   NO
146      PAGED          -   NO
147      DIRECT-ACCESS  -   YES
148      BIT-ACCESS     -   NO
149      CODE-ACESS     -   NO 
150      DEBUG-NAME     -   'E'
151      POINTER-TYPE   -   POINTER
152    */
153   data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
154
155   /* overlay segment - same as internal storage segment ;
156      SFRSPACE       -   NO
157      FAR-SPACE      -   NO
158      PAGED          -   NO
159      DIRECT-ACCESS  -   YES
160      BIT-ACCESS     -   NO
161      CODE-ACESS     -   NO 
162      DEBUG-NAME     -   'E'
163      POINTER-TYPE   -   POINTER
164    */
165   overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
166
167   /* Xternal Data segment - 
168      SFRSPACE       -   NO
169      FAR-SPACE      -   YES
170      PAGED          -   NO
171      DIRECT-ACCESS  -   NO
172      BIT-ACCESS     -   NO
173      CODE-ACESS     -   NO 
174      DEBUG-NAME     -   'F'
175      POINTER-TYPE   -   FPOINTER
176    */
177   xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
178
179   /* Inderectly addressed internal data segment
180      SFRSPACE       -   NO
181      FAR-SPACE      -   NO
182      PAGED          -   NO
183      DIRECT-ACCESS  -   NO
184      BIT-ACCESS     -   NO
185      CODE-ACESS     -   NO 
186      DEBUG-NAME     -   'G'
187      POINTER-TYPE   -   IPOINTER
188    */
189   idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
190
191   /* Static segment (code for variables );
192      SFRSPACE       -   NO
193      FAR-SPACE      -   NO
194      PAGED          -   NO
195      DIRECT-ACCESS  -   YES
196      BIT-ACCESS     -   YES
197      CODE-ACESS     -   NO 
198      DEBUG-NAME     -   'H'
199      POINTER-TYPE   -  _NONE_
200    */
201   bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
202
203   /* Special function register space :-
204      SFRSPACE       -   YES
205      FAR-SPACE      -   NO
206      PAGED          -   NO
207      DIRECT-ACCESS  -   YES
208      BIT-ACCESS     -   NO
209      CODE-ACESS     -   NO 
210      DEBUG-NAME     -   'I'
211      POINTER-TYPE   -   _NONE_
212    */
213   sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
214
215   /* Register space ;
216      SFRSPACE       -   YES
217      FAR-SPACE      -   NO
218      PAGED          -   NO
219      DIRECT-ACCESS  -   NO
220      BIT-ACCESS     -   NO
221      CODE-ACESS     -   NO 
222      DEBUG-NAME     -   ' '
223      POINTER-TYPE   -   _NONE_
224    */
225   reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
226
227   /* SFR bit space 
228      SFRSPACE       -   YES
229      FAR-SPACE      -   NO
230      PAGED          -   NO
231      DIRECT-ACCESS  -   YES
232      BIT-ACCESS     -   YES
233      CODE-ACESS     -   NO 
234      DEBUG-NAME     -   'J'
235      POINTER-TYPE   -   _NONE_
236    */
237   sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
238
239   /* EEPROM bit space 
240      SFRSPACE       -   NO
241      FAR-SPACE      -   YES
242      PAGED          -   NO
243      DIRECT-ACCESS  -   NO
244      BIT-ACCESS     -   NO
245      CODE-ACESS     -   NO 
246      DEBUG-NAME     -   'K'
247      POINTER-TYPE   -   EEPPOINTER
248    */
249   eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
250
251   /* the unknown map */
252   generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
253
254 }
255
256 /*-----------------------------------------------------------------*/
257 /* allocIntoSeg - puts a symbol into a memory segment              */
258 /*-----------------------------------------------------------------*/
259 void 
260 allocIntoSeg (symbol * sym)
261 {
262   memmap *segment = SPEC_OCLS (sym->etype);
263   addSet (&segment->syms, sym);
264 }
265
266 /*-----------------------------------------------------------------*/
267 /* allocGlobal - aassigns the output segment to a global var       */
268 /*-----------------------------------------------------------------*/
269 void 
270 allocGlobal (symbol * sym)
271 {
272
273   /* symbol name is internal name  */
274   if (!sym->level)              /* local statics can come here */
275     sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
276
277   /* add it to the operandKey reset */
278   addSet (&operKeyReset, sym);
279
280   /* if this is a literal e.g. enumerated type */
281   /* put it in the data segment & do nothing   */
282   if (IS_LITERAL (sym->etype))
283     {
284       SPEC_OCLS (sym->etype) = data;
285       return;
286     }
287
288   /* if this is a function then assign code space    */
289   if (IS_FUNC (sym->type))
290     {
291       SPEC_OCLS (sym->etype) = code;
292       /* if this is an interrupt service routine
293          then put it in the interrupt service array */
294       if (FUNC_ISISR (sym->type))
295         {
296
297           if (interrupts[FUNC_INTNO (sym->type)])
298             werror (E_INT_DEFINED,
299                     FUNC_INTNO (sym->type),
300                     interrupts[FUNC_INTNO (sym->type)]->name);
301           else
302             interrupts[FUNC_INTNO (sym->type)] = sym;
303
304           /* automagically extend the maximum interrupts */
305           if (FUNC_INTNO (sym->type) >= maxInterrupts)
306             maxInterrupts = FUNC_INTNO (sym->type) + 1;
307         }
308       /* if it is not compiler defined */
309       if (!sym->cdef)
310         allocIntoSeg (sym);
311
312       return;
313     }
314
315   /* if this is a  SFR or SBIT */
316   if (SPEC_SCLS (sym->etype) == S_SFR ||
317       SPEC_SCLS (sym->etype) == S_SBIT)
318     {
319
320       /* if both absolute address & initial  */
321       /* value specified then error        */
322       if (IS_ABSOLUTE (sym->etype) && sym->ival)
323         {
324           werror (E_SFR_INIT, sym->name);
325           sym->ival = NULL;
326         }
327
328       SPEC_OCLS (sym->etype) =
329         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
330
331       allocIntoSeg (sym);
332       return;
333     }
334
335   /* if this is a bit variable and no storage class */
336   if (SPEC_NOUN (sym->etype) == V_BIT
337       && SPEC_SCLS (sym->etype) == S_BIT)
338     {
339       SPEC_OCLS (sym->etype) = bit;
340       allocIntoSeg (sym);
341       return;
342     }
343
344   /* if bit storage class */
345   if (SPEC_SCLS (sym->etype) == S_SBIT)
346     {
347       SPEC_OCLS (sym->etype) = bit;
348       allocIntoSeg (sym);
349       return;
350     }
351
352   /* register storage class ignored changed to FIXED */
353   if (SPEC_SCLS (sym->etype) == S_REGISTER)
354     SPEC_SCLS (sym->etype) = S_FIXED;
355
356   /* if data specified then  */
357   if (SPEC_SCLS (sym->etype) == S_DATA)
358     {
359       /* set the output class */
360       SPEC_OCLS (sym->etype) = data;
361       /* generate the symbol  */
362       allocIntoSeg (sym);
363       return;
364     }
365
366   /* if it is fixed, then allocate depending on the  */
367   /* current memory model,same for automatics        */
368   if (SPEC_SCLS (sym->etype) == S_FIXED ||
369       SPEC_SCLS (sym->etype) == S_AUTO)
370     {
371       /* set the output class */
372       SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
373       // jwk: we need to set SPEC_SCLS now !!!!
374       /* generate the symbol  */
375       allocIntoSeg (sym);
376       return;
377     }
378
379   /* if code change to constant */
380   if (SPEC_SCLS (sym->etype) == S_CODE) {
381     SPEC_OCLS (sym->etype) = statsg;
382     allocIntoSeg (sym);
383     return;
384   }
385
386   if (SPEC_SCLS (sym->etype) == S_XDATA)
387     {
388       SPEC_OCLS (sym->etype) = xdata;
389       allocIntoSeg (sym);
390       return;
391     }
392
393   if (SPEC_SCLS (sym->etype) == S_IDATA)
394     {
395       SPEC_OCLS (sym->etype) = idata;
396       sym->iaccess = 1;
397       allocIntoSeg (sym);
398       return;
399     }
400
401   if (SPEC_SCLS (sym->etype) == S_EEPROM)
402     {
403       SPEC_OCLS (sym->etype) = eeprom;
404       allocIntoSeg (sym);
405       return;
406     }
407
408   return;
409 }
410
411 /*-----------------------------------------------------------------*/
412 /* allocParms - parameters are always passed on stack              */
413 /*-----------------------------------------------------------------*/
414 void 
415 allocParms (value * val)
416 {
417   value *lval;
418   int pNum = 1;
419
420   for (lval = val; lval; lval = lval->next, pNum++)
421     {
422
423       /* check the declaration */
424       checkDecl (lval->sym, 0);
425
426       /* if this a register parm then allocate
427          it as a local variable by adding it
428          to the first block we see in the body */
429       if (IS_REGPARM (lval->etype))
430         continue;
431
432       /* mark it as my parameter */
433       lval->sym->ismyparm = 1;
434       lval->sym->localof = currFunc;
435
436
437       /* if automatic variables r 2b stacked */
438       if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
439         {
440
441           if (lval->sym)
442             lval->sym->onStack = 1;
443
444           /* choose which stack 2 use   */
445           /*  use xternal stack */
446           if (options.useXstack)
447             {
448               /* PENDING: stack direction support */
449               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
450               SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
451                 xstackPtr - getSize (lval->type);
452               xstackPtr -= getSize (lval->type);
453             }
454           else
455             {                   /* use internal stack   */
456               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
457               if (port->stack.direction > 0)
458                 {
459                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
460                     stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
461                     getSize (lval->type) -
462                     (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
463                   stackPtr -= getSize (lval->type);
464                 }
465               else
466                 {
467                   /* This looks like the wrong order but it turns out OK... */
468                   /* PENDING: isr, bank overhead, ... */
469                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
470                     stackPtr +
471                     ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
472                     (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
473                     0;
474                   stackPtr += getSize (lval->type);
475                 }
476             }
477           allocIntoSeg (lval->sym);
478         }
479       else
480         { /* allocate them in the automatic space */
481           /* generate a unique name  */
482           sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
483           strcpy (lval->name, lval->sym->rname);
484           
485           /* if declared in external storage */
486           if (SPEC_SCLS (lval->etype) == S_XDATA)
487             SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
488           else
489             /* other wise depending on the memory model 
490                note here that we put it into the overlay segment
491                first, we will remove it from the overlay segment
492                after the overlay determination has been done */
493             if (options.model == MODEL_SMALL)
494               {
495                 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
496                   (options.noOverlay ? port->mem.default_local_map
497                    : overlay);
498               }
499             else
500               {
501                 SPEC_SCLS (lval->etype) = S_XDATA;
502                 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
503               }
504           allocIntoSeg (lval->sym);
505         }
506     }
507
508   return;
509 }
510
511 /*-----------------------------------------------------------------*/
512 /* deallocParms - parameters are always passed on stack                */
513 /*-----------------------------------------------------------------*/
514 void 
515 deallocParms (value * val)
516 {
517   value *lval;
518
519   for (lval = val; lval; lval = lval->next)
520     {
521
522       /* unmark is myparm */
523       lval->sym->ismyparm = 0;
524       /* if on stack then depending on which stack */
525
526       /* delete it from the symbol table  */
527       deleteSym (SymbolTab, lval->sym, lval->sym->name);
528
529       if (!lval->sym->isref)
530         {
531           lval->sym->allocreq = 1;
532           werror (W_NO_REFERENCE, currFunc->name,
533                   "function argument", lval->sym->name);
534         }
535
536       /* move the rname if any to the name for both val & sym */
537       /* and leave a copy of it in the symbol table           */
538       if (lval->sym->rname[0])
539         {
540           char buffer[SDCC_NAME_MAX];
541           strcpy (buffer, lval->sym->rname);
542           lval->sym = copySymbol (lval->sym);
543           strcpy (lval->sym->rname, buffer);
544           strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
545           addSym (SymbolTab, lval->sym, lval->sym->name,
546                   lval->sym->level, lval->sym->block, 1);
547           lval->sym->_isparm = 1;
548           addSet (&operKeyReset, lval->sym);
549         }
550
551     }
552
553   return;
554 }
555
556 /*-----------------------------------------------------------------*/
557 /* allocLocal - allocate local variables                           */
558 /*-----------------------------------------------------------------*/
559 void 
560 allocLocal (symbol * sym)
561 {
562
563   /* generate an unique name */
564   sprintf (sym->rname, "%s%s_%s_%d_%d",
565            port->fun_prefix,
566            currFunc->name, sym->name, sym->level, sym->block);
567
568   sym->islocal = 1;
569   sym->localof = currFunc;
570
571   /* if this is a static variable */
572   if (IS_STATIC (sym->etype))
573     {
574       allocGlobal (sym);
575       sym->allocreq = 1;
576       return;
577     }
578
579   /* if volatile then */
580   if (IS_VOLATILE (sym->etype))
581     sym->allocreq = 1;
582
583   /* this is automatic           */
584
585   /* if it to be placed on the stack */
586   if (options.stackAuto || reentrant) {
587     sym->onStack = 1;
588     if (options.useXstack) {
589       /* PENDING: stack direction for xstack */
590       SPEC_OCLS (sym->etype) = xstack;
591       SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
592       xstackPtr += getSize (sym->type);
593     } else {
594       SPEC_OCLS (sym->etype) = istack;
595       if (port->stack.direction > 0) {
596         SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
597         stackPtr += getSize (sym->type);
598       } else {
599         stackPtr -= getSize (sym->type);
600         SPEC_STAK (sym->etype) = sym->stack = stackPtr;
601       }
602     }
603     allocIntoSeg (sym);
604     return;
605   }
606   
607   /* else depending on the storage class specified */
608   if (SPEC_SCLS (sym->etype) == S_XDATA)
609     {
610       SPEC_OCLS (sym->etype) = xdata;
611       allocIntoSeg (sym);
612       return;
613     }
614
615   if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
616     SPEC_OCLS (sym->etype) = statsg;
617     allocIntoSeg (sym);
618     return;
619   }
620   
621   if (SPEC_SCLS (sym->etype) == S_IDATA)
622     {
623       SPEC_OCLS (sym->etype) = idata;
624       sym->iaccess = 1;
625       allocIntoSeg (sym);
626       return;
627     }
628
629   /* if this is a function then assign code space    */
630   if (IS_FUNC (sym->type))
631     {
632       SPEC_OCLS (sym->etype) = code;
633       return;
634     }
635
636   /* if this is a  SFR or SBIT */
637   if (SPEC_SCLS (sym->etype) == S_SFR ||
638       SPEC_SCLS (sym->etype) == S_SBIT)
639     {
640
641       /* if both absolute address & initial  */
642       /* value specified then error        */
643       if (IS_ABSOLUTE (sym->etype) && sym->ival)
644         {
645           werror (E_SFR_INIT, sym->name);
646           sym->ival = NULL;
647         }
648
649       SPEC_OCLS (sym->etype) =
650         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
651
652       allocIntoSeg (sym);
653       return;
654     }
655
656   /* if this is a bit variable and no storage class */
657   if (SPEC_NOUN (sym->etype) == V_BIT
658       && (SPEC_SCLS (sym->etype) == S_BIT))
659     {
660       SPEC_OCLS (sym->etype) = bit;
661       allocIntoSeg (sym);
662       return;
663     }
664
665   if (SPEC_SCLS (sym->etype) == S_DATA)
666     {
667       SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
668       allocIntoSeg (sym);
669       return;
670     }
671
672   if (SPEC_SCLS (sym->etype) == S_EEPROM)
673     {
674       SPEC_OCLS (sym->etype) = eeprom;
675       allocIntoSeg (sym);
676       return;
677     }
678
679   /* again note that we have put it into the overlay segment
680      will remove and put into the 'data' segment if required after 
681      overlay  analysis has been done */
682   if (options.model == MODEL_SMALL) {
683     SPEC_OCLS (sym->etype) = 
684       (options.noOverlay ? port->mem.default_local_map
685        : overlay);
686   } else {
687     SPEC_OCLS (sym->etype) = port->mem.default_local_map;
688   }
689   allocIntoSeg (sym);
690 }
691
692 /*-----------------------------------------------------------------*/
693 /* deallocLocal - deallocates the local variables                  */
694 /*-----------------------------------------------------------------*/
695 void 
696 deallocLocal (symbol * csym)
697 {
698   symbol *sym;
699
700   for (sym = csym; sym; sym = sym->next)
701     {
702       if (sym->_isparm)
703         continue;
704
705       /* if it is on the stack */
706       if (sym->onStack)
707         {
708           if (options.useXstack)
709             xstackPtr -= getSize (sym->type);
710           else
711             stackPtr -= getSize (sym->type);
712         }
713       /* if not used give a warning */
714       if (!sym->isref && !IS_STATIC (sym->etype))
715         werror (W_NO_REFERENCE, currFunc->name,
716                 "local variable", sym->name);
717       /* now delete it from the symbol table */
718       deleteSym (SymbolTab, sym, sym->name);
719     }
720 }
721
722 /*-----------------------------------------------------------------*/
723 /* overlay2data - moves declarations from the overlay seg to data  */
724 /*-----------------------------------------------------------------*/
725 void 
726 overlay2data ()
727 {
728   symbol *sym;
729
730   for (sym = setFirstItem (overlay->syms); sym;
731        sym = setNextItem (overlay->syms))
732     {
733
734       SPEC_OCLS (sym->etype) = data;
735       allocIntoSeg (sym);
736     }
737
738   setToNull ((void **) &overlay->syms);
739
740 }
741
742 /*-----------------------------------------------------------------*/
743 /* overlay2Set - will add all symbols from the overlay segment to  */
744 /*               the set of sets containing the overlable symbols  */
745 /*-----------------------------------------------------------------*/
746 void 
747 overlay2Set ()
748 {
749   symbol *sym;
750   set *oset = NULL;
751
752   for (sym = setFirstItem (overlay->syms); sym;
753        sym = setNextItem (overlay->syms))
754     {
755
756       addSet (&oset, sym);
757     }
758
759   setToNull ((void **) &overlay->syms);
760   addSet (&ovrSetSets, oset);
761
762 }
763
764 /*-----------------------------------------------------------------*/
765 /* allocVariables - creates decl & assign storage class for a v    */
766 /*-----------------------------------------------------------------*/
767 int 
768 allocVariables (symbol * symChain)
769 {
770   symbol *sym;
771   symbol *csym;
772   int stack = 0;
773   int saveLevel = 0;
774
775   /* go thru the symbol chain   */
776   for (sym = symChain; sym; sym = sym->next)
777     {
778
779       /* if this is a typedef then add it */
780       /* to the typedef table             */
781       if (IS_TYPEDEF (sym->etype))
782         {
783           /* check if the typedef already exists    */
784           csym = findSym (TypedefTab, NULL, sym->name);
785           if (csym && csym->level == sym->level)
786             werror (E_DUPLICATE_TYPEDEF, sym->name);
787
788           addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
789           continue;             /* go to the next one         */
790         }
791       /* make sure it already exist */
792       csym = findSymWithLevel (SymbolTab, sym);
793       if (!csym || (csym && csym->level != sym->level))
794         csym = sym;
795
796       /* check the declaration */
797       checkDecl (csym,0);
798
799       /* if this is a function or a pointer to function */
800       /* then args  processing  */
801       if (funcInChain (csym->type))
802         {
803
804           processFuncArgs (csym, 1);
805           /* if register bank specified then update maxRegBank */
806           if (maxRegBank < FUNC_REGBANK (csym->type))
807             maxRegBank = FUNC_REGBANK (csym->type);
808         }
809
810       /* if this is a extern variable then change the */
811       /* level to zero temporarily                                    */
812       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
813         {
814           saveLevel = csym->level;
815           csym->level = 0;
816         }
817
818       /* if this is a literal then it is an enumerated */
819       /* type so need not allocate it space for it     */
820       if (IS_LITERAL (sym->etype))
821         continue;
822
823       /* generate the actual declaration  */
824       if (csym->level)
825         {
826           allocLocal (csym);
827           if (csym->onStack)
828             stack += getSize (csym->type);
829         }
830       else
831         allocGlobal (csym);
832
833       /* restore the level */
834       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
835         csym->level = saveLevel;
836     }
837
838   return stack;
839 }
840
841 /*-----------------------------------------------------------------*/
842 /* redoStackOffsets :- will reassign the values for stack offsets  */
843 /*-----------------------------------------------------------------*/
844 void 
845 redoStackOffsets (void)
846 {
847   symbol *sym;
848   int sPtr = 0;
849   int xsPtr = -1;
850
851   /* after register allocation is complete we know
852      which variables will need to be assigned space
853      on the stack. We will eliminate those variables
854      which do not have the allocReq flag thus reducing
855      the stack space */
856   for (sym = setFirstItem (istack->syms); sym;
857        sym = setNextItem (istack->syms))
858     {
859
860       int size = getSize (sym->type);
861       /* nothing to do with parameters so continue */
862       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
863         continue;
864
865       if (IS_AGGREGATE (sym->type))
866         {
867           if (port->stack.direction > 0)
868             {
869               SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
870               sPtr += size;
871             }
872           else
873             {
874               sPtr -= size;
875               SPEC_STAK (sym->etype) = sym->stack = sPtr;
876             }
877           continue;
878         }
879
880       /* if allocation not required then subtract
881          size from overall stack size & continue */
882       if (!sym->allocreq)
883         {
884           currFunc->stack -= size;
885           SPEC_STAK (currFunc->etype) -= size;
886           continue;
887         }
888
889       if (port->stack.direction > 0)
890         {
891           SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
892           sPtr += size;
893         }
894       else
895         {
896           sPtr -= size;
897           SPEC_STAK (sym->etype) = sym->stack = sPtr;
898         }
899     }
900
901   /* do the same for the external stack */
902
903   for (sym = setFirstItem (xstack->syms); sym;
904        sym = setNextItem (xstack->syms))
905     {
906
907       int size = getSize (sym->type);
908       /* nothing to do with parameters so continue */
909       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
910         continue;
911
912       if (IS_AGGREGATE (sym->type))
913         {
914           SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
915           xsPtr += size;
916           continue;
917         }
918
919       /* if allocation not required then subtract
920          size from overall stack size & continue */
921       if (!sym->allocreq)
922         {
923           currFunc->xstack -= size;
924           SPEC_STAK (currFunc->etype) -= size;
925           continue;
926         }
927
928       SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
929       xsPtr += size;
930     }
931
932   /* if the debug option is set then output the
933      symbols to the map file */
934   if (options.debug)
935     {
936       for (sym = setFirstItem (istack->syms); sym;
937            sym = setNextItem (istack->syms))
938         cdbSymbol (sym, cdbFile, FALSE, FALSE);
939
940       for (sym = setFirstItem (xstack->syms); sym;
941            sym = setNextItem (xstack->syms))
942         cdbSymbol (sym, cdbFile, FALSE, FALSE);
943     }
944 }
945
946 /*-----------------------------------------------------------------*/
947 /* printAllocInfoSeg- print the allocation for a given section     */
948 /*-----------------------------------------------------------------*/
949 static void 
950 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
951 {
952   symbol *sym;
953
954   if (!map)
955     return;
956   if (!map->syms)
957     return;
958
959   for (sym = setFirstItem (map->syms); sym;
960        sym = setNextItem (map->syms))
961     {
962
963       if (sym->level == 0)
964         continue;
965       if (sym->localof != func)
966         continue;
967       fprintf (of, ";%-25s Allocated to ", sym->name);
968
969       /* if assigned to registers */
970       if (!sym->allocreq && sym->reqv)
971         {
972           int i;
973           sym = OP_SYMBOL (sym->reqv);
974           fprintf (of, "registers ");
975           for (i = 0; i < 4 && sym->regs[i]; i++)
976             fprintf (of, "%s ", port->getRegName (sym->regs[i]));
977           fprintf (of, "\n");
978           continue;
979         }
980
981       /* if on stack */
982       if (sym->onStack)
983         {
984           fprintf (of, "stack - offset %d\n", sym->stack);
985           continue;
986         }
987
988       /* otherwise give rname */
989       fprintf (of, "in memory with name '%s'\n", sym->rname);
990     }
991 }
992
993 /*-----------------------------------------------------------------*/
994 /* canOverlayLocals - returns true if the local variables can overlayed */
995 /*-----------------------------------------------------------------*/
996 static bool 
997 canOverlayLocals (eBBlock ** ebbs, int count)
998 {
999   int i;
1000   /* if staticAuto is in effect or the current function
1001      being compiled is reentrant or the overlay segment
1002      is empty or no overlay option is in effect then */
1003   if (options.noOverlay ||
1004       options.stackAuto ||
1005       (currFunc &&
1006        (IFFUNC_ISREENT (currFunc->type) ||
1007         FUNC_ISISR (currFunc->type))) ||
1008       elementsInSet (overlay->syms) == 0)
1009
1010     return FALSE;
1011
1012   /* otherwise do thru the blocks and see if there
1013      any function calls if found then return false */
1014   for (i = 0; i < count; i++)
1015     {
1016       iCode *ic;
1017
1018       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1019         if (ic && (ic->op == CALL || ic->op == PCALL))
1020           return FALSE;
1021     }
1022
1023   /* no function calls found return TRUE */
1024   return TRUE;
1025 }
1026
1027 /*-----------------------------------------------------------------*/
1028 /* doOverlays - move the overlay segment to appropriate location   */
1029 /*-----------------------------------------------------------------*/
1030 void 
1031 doOverlays (eBBlock ** ebbs, int count)
1032 {
1033   /* check if the parameters and local variables
1034      of this function can be put in the overlay segment
1035      This check is essentially to see if the function
1036      calls any other functions if yes then we cannot
1037      overlay */
1038   if (canOverlayLocals (ebbs, count))
1039     /* if we can then put the parameters &
1040        local variables in the overlay set */
1041     overlay2Set ();
1042   else
1043     /* otherwise put them into data where
1044        they belong */
1045     overlay2data ();
1046 }
1047
1048 /*-----------------------------------------------------------------*/
1049 /* printAllocInfo - prints allocation information for a function   */
1050 /*-----------------------------------------------------------------*/
1051 void 
1052 printAllocInfo (symbol * func, FILE * of)
1053 {
1054   if (!of)
1055     of = stdout;
1056
1057   /* must be called after register allocation is complete */
1058   fprintf (of, ";------------------------------------------------------------\n");
1059   fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1060   fprintf (of, ";------------------------------------------------------------\n");
1061
1062   printAllocInfoSeg (xstack, func, of);
1063   printAllocInfoSeg (istack, func, of);
1064   printAllocInfoSeg (code, func, of);
1065   printAllocInfoSeg (data, func, of);
1066   printAllocInfoSeg (xdata, func, of);
1067   printAllocInfoSeg (idata, func, of);
1068   printAllocInfoSeg (sfr, func, of);
1069   printAllocInfoSeg (sfrbit, func, of);
1070 }