mmmm, that could be better
[fw/sdcc] / src / SDCCmem.c
index 4692be48e609842c9020b1e5f950311272e2c707..afbcdec2b62154360be9139a60a2f8527ff1a043 100644 (file)
@@ -5,14 +5,16 @@
 #include "common.h"
 
 /* memory segments */
-memmap *xstack = NULL;         /* xternal stack data         */
-memmap *istack = NULL;         /* internal stack             */
-memmap *code = NULL;           /* code segment               */
-memmap *data = NULL;           /* internal data upto 128     */
-memmap *xdata = NULL;          /* external data              */
-memmap *idata = NULL;          /* internal data upto 256     */
-memmap *bit = NULL;            /* bit addressable space      */
-memmap *statsg = NULL;         /* the constant data segment  */
+memmap *xstack = NULL;         /* xternal stack data          */
+memmap *istack = NULL;         /* internal stack              */
+memmap *code = NULL;           /* code segment                */
+memmap *data = NULL;           /* internal data upto 128      */
+memmap *xdata = NULL;          /* external data               */
+memmap *xidata = NULL;          /* the initialized xdata       */
+memmap *xinit = NULL;           /* the initializers for xidata */
+memmap *idata = NULL;          /* internal data upto 256      */
+memmap *bit = NULL;            /* bit addressable space       */
+memmap *statsg = NULL;         /* the constant data segment   */
 memmap *sfr = NULL;            /* register space              */
 memmap *reg = NULL;            /* register space              */
 memmap *sfrbit = NULL;         /* sfr bit space               */
@@ -46,7 +48,7 @@ allocMap (char rspace,                /* sfr space            */
 {
   memmap *map;
 
-  if (!(map = calloc (sizeof (memmap), 1)))
+  if (!(map = Safe_alloc (sizeof (memmap))))
     {
       werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
       exit (1);
@@ -175,6 +177,8 @@ initMem ()
      POINTER-TYPE   -   FPOINTER
    */
   xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
+  xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
+  xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
 
   /* Inderectly addressed internal data segment
      SFRSPACE       -   NO
@@ -264,7 +268,7 @@ allocIntoSeg (symbol * sym)
 }
 
 /*-----------------------------------------------------------------*/
-/* allocGlobal - aassigns the output segment to a global var       */
+/* allocGlobal - assigns the output segment to a global var       */
 /*-----------------------------------------------------------------*/
 void 
 allocGlobal (symbol * sym)
@@ -291,19 +295,19 @@ allocGlobal (symbol * sym)
       SPEC_OCLS (sym->etype) = code;
       /* if this is an interrupt service routine
          then put it in the interrupt service array */
-      if (IS_ISR (sym->etype))
+      if (FUNC_ISISR (sym->type))
        {
 
-         if (interrupts[SPEC_INTN (sym->etype)])
+         if (interrupts[FUNC_INTNO (sym->type)])
            werror (E_INT_DEFINED,
-                   SPEC_INTN (sym->etype),
-                   interrupts[SPEC_INTN (sym->etype)]->name);
+                   FUNC_INTNO (sym->type),
+                   interrupts[FUNC_INTNO (sym->type)]->name);
          else
-           interrupts[SPEC_INTN (sym->etype)] = sym;
+           interrupts[FUNC_INTNO (sym->type)] = sym;
 
          /* automagically extend the maximum interrupts */
-         if (SPEC_INTN (sym->etype) >= maxInterrupts)
-           maxInterrupts = SPEC_INTN (sym->etype) + 1;
+         if (FUNC_INTNO (sym->type) >= maxInterrupts)
+           maxInterrupts = FUNC_INTNO (sym->type) + 1;
        }
       /* if it is not compiler defined */
       if (!sym->cdef)
@@ -385,6 +389,12 @@ allocGlobal (symbol * sym)
   if (SPEC_SCLS (sym->etype) == S_XDATA)
     {
       SPEC_OCLS (sym->etype) = xdata;
+      // should we move this to the initialized data segment?
+      if (port->genXINIT &&
+         sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
+       SPEC_OCLS(sym->etype)=xidata;
+       addSet(&xidata->syms, sym);
+      }
       allocIntoSeg (sym);
       return;
     }
@@ -434,7 +444,7 @@ allocParms (value * val)
 
 
       /* if automatic variables r 2b stacked */
-      if (options.stackAuto || IS_RENT (currFunc->etype))
+      if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
        {
 
          if (lval->sym)
@@ -456,9 +466,9 @@ allocParms (value * val)
              if (port->stack.direction > 0)
                {
                  SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
-                   stackPtr - (SPEC_BANK (currFunc->etype) ? port->stack.bank_overhead : 0) -
+                   stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
                    getSize (lval->type) -
-                   (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0);
+                   (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
                  stackPtr -= getSize (lval->type);
                }
              else
@@ -467,8 +477,8 @@ allocParms (value * val)
                  /* PENDING: isr, bank overhead, ... */
                  SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
                    stackPtr +
-                   (IS_BANKEDCALL (currFunc->etype) ? port->stack.banked_overhead : 0) +
-                   (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0) +
+                   ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
+                   (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
                    0;
                  stackPtr += getSize (lval->type);
                }
@@ -799,11 +809,12 @@ allocVariables (symbol * symChain)
       /* then args  processing  */
       if (funcInChain (csym->type))
        {
-
-         processFuncArgs (csym, 1);
+#if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
+         processFuncArgs (csym);
+#endif
          /* if register bank specified then update maxRegBank */
-         if (maxRegBank < SPEC_BANK (csym->etype))
-           maxRegBank = SPEC_BANK (csym->etype);
+         if (maxRegBank < FUNC_REGBANK (csym->type))
+           maxRegBank = FUNC_REGBANK (csym->type);
        }
 
       /* if this is a extern variable then change the */
@@ -1002,8 +1013,8 @@ canOverlayLocals (eBBlock ** ebbs, int count)
   if (options.noOverlay ||
       options.stackAuto ||
       (currFunc &&
-       (IS_RENT (currFunc->etype) ||
-       IS_ISR (currFunc->etype))) ||
+       (IFFUNC_ISREENT (currFunc->type) ||
+       FUNC_ISISR (currFunc->type))) ||
       elementsInSet (overlay->syms) == 0)
 
     return FALSE;
@@ -1015,8 +1026,13 @@ canOverlayLocals (eBBlock ** ebbs, int count)
       iCode *ic;
 
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       if (ic && (ic->op == CALL || ic->op == PCALL))
-         return FALSE;
+         if (ic) {
+             if (ic->op == CALL) {
+                 sym_link *ftype = operandType(IC_LEFT(ic));
+                 /* builtins only can use overlays */
+                 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE; 
+             } else if (ic->op == PCALL) return FALSE;
+         }
     }
 
   /* no function calls found return TRUE */