* as/mcs51/lkarea.c (lnkarea, lnkarea2): improved BSEG size calculation,
[fw/sdcc] / src / SDCCsymt.c
index dbcfd6630cdbf25ce093efed252442fc456aede3..91eb064fcfb71ccf79696f64a941cdfd8d4b68b2 100644 (file)
@@ -818,7 +818,7 @@ getSize (sym_link * p)
     case FPOINTER:
     case CPOINTER:
     case FUNCTION:
-      return (FPTRSIZE);
+      return (IFFUNC_BANKED (p) ? GPTRSIZE : FPTRSIZE);
     case GPOINTER:
       return (GPTRSIZE);
 
@@ -1005,10 +1005,11 @@ reverseLink (sym_link * type)
 /* addSymChain - adds a symbol chain to the symboltable             */
 /*------------------------------------------------------------------*/
 void 
-addSymChain (symbol * symHead)
+addSymChain (symbol ** symHead)
 {
-  symbol *sym = symHead;
+  symbol *sym = *symHead;
   symbol *csym = NULL;
+  symbol **symPtrPtr;
   int error = 0;
 
   for (; sym != NULL; sym = sym->next)
@@ -1086,6 +1087,13 @@ addSymChain (symbol * symHead)
         /* delete current entry */
         deleteSym (SymbolTab, csym, csym->name);
         deleteFromSeg(csym);
+        
+        symPtrPtr = symHead;
+        while (*symPtrPtr && *symPtrPtr != csym)
+          symPtrPtr = &(*symPtrPtr)->next;
+        if (*symPtrPtr == csym)
+          *symPtrPtr = csym->next;
+          
       }
       
       /* add new entry */
@@ -1365,6 +1373,26 @@ checkSClass (symbol * sym, int isProto)
     if (IS_ABSOLUTE (sym->etype))
       SPEC_VOLATILE (sym->etype) = 1;
   
+  if (TARGET_IS_MCS51 &&
+      IS_ABSOLUTE (sym->etype) &&
+      SPEC_SCLS (sym->etype) == S_SFR)
+    {
+      int n, size;
+      unsigned addr;
+
+      if (SPEC_NOUN (sym->etype) == V_CHAR)
+        size = 8;
+      else if (SPEC_LONG (sym->etype) == 0)
+        size = 16;
+      else
+        size = 32;
+
+      addr = SPEC_ADDR (sym->etype);
+      for (n=0; n<size; n+=8)
+        if (((addr >> n) & 0xFF) < 0x80)
+          werror (W_SFR_ABSRANGE, sym->name);
+    }
+
   /* If code memory is read only, then pointers to code memory */
   /* implicitly point to constants -- make this explicit       */
   t = sym->type;
@@ -1517,13 +1545,14 @@ changePointer (sym_link * p)
 
   /* go thru the chain of declarations   */
   /* if we find a pointer to a function  */
-  /* unconditionally change it to a ptr  */
-  /* to code area                        */
+  /* change it to a ptr to code area     */
+  /* unless the function is banked.      */
   for (; p; p = p->next)
     {
       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
         DCL_TYPE (p) = port->unqualified_pointer;
       if (IS_PTR (p) && IS_FUNC (p->next))
+        if (!IFFUNC_BANKED(p->next))
         DCL_TYPE (p) = CPOINTER;
     }
 }
@@ -1886,6 +1915,16 @@ compareType (sym_link * dest, sym_link * src)
     {
       if (IS_DECL (src))
         {
+          /* banked function pointer */
+          if (IS_GENPTR (dest) && IS_GENPTR (src))
+            {
+              if (IS_FUNC (src->next) && IS_VOID(dest->next))
+                return -1;
+              if (IS_FUNC (dest->next) && IS_VOID(src->next))
+                return -1;
+              return compareType (dest->next, src->next);
+            }
+
           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
             if (IS_FUNC(src)) {
               //checkFunction(src,dest);
@@ -2567,7 +2606,7 @@ processFuncArgs (symbol * func)
               SPEC_STAT (func->etype);
           }
           #endif
-          addSymChain (val->sym);
+          addSymChain (&val->sym);
 
         }
       else                      /* symbol name given create synth name */