* as/mcs51/lkarea.c (lnkarea, lnkarea2): improved BSEG size calculation,
[fw/sdcc] / src / SDCCast.c
index 2ba8dd0e7bf929b6c13f4e86b699aedbd824457e..3cfdde6a9c2754ad7548ec87b4ead54003e04547 100644 (file)
@@ -218,6 +218,7 @@ copyAst (ast * src)
   dest->lineno = src->lineno;
   dest->level = src->level;
   dest->funcName = src->funcName;
+  dest->reversed = src->reversed;
 
   if (src->ftype)
     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
@@ -572,7 +573,7 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
     }
 
   /* save it */
-  addSymChain (sym);
+  addSymChain (&sym);
   sym->cdef = 1;
   allocVariables (sym);
   return sym;
@@ -612,7 +613,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
     }
 
     /* save it */
-    addSymChain (sym);
+    addSymChain (&sym);
     sym->cdef = 1;
     allocVariables (sym);
     return sym;
@@ -630,11 +631,25 @@ reverseParms (ast * ptree)
     return;
 
   /* top down if we find a nonParm tree then quit */
-  if (ptree->type == EX_OP && ptree->opval.op == PARAM)
+  if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
     {
+      /* The various functions expect the parameter tree to be right heavy. */
+      /* Rotate the tree to be left heavy so that after reversal it is */
+      /* right heavy again. */
+      while ((ttree = ptree->right) && ttree->type == EX_OP &&
+             ttree->opval.op == PARAM)
+        {
+          ptree->right = ttree->right;
+          ttree->right = ttree->left;
+          ttree->left = ptree->left;
+          ptree->left = ttree;
+        }
+    
+      /* Now reverse */
       ttree = ptree->left;
       ptree->left = ptree->right;
       ptree->right = ttree;
+      ptree->reversed = 1;
       reverseParms (ptree->left);
       reverseParms (ptree->right);
     }
@@ -678,11 +693,15 @@ processParms (ast *func,
   /* if the function is being called via a pointer &   */
   /* it has not been defined a reentrant then we cannot */
   /* have parameters                                   */
-  if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
+  /* PIC16 port can... */
+  if (!TARGET_IS_PIC16)
     {
-      werror (W_NONRENT_ARGS);
-      fatalError++;
-      return 1;
+      if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
+        {
+          werror (W_NONRENT_ARGS);
+          fatalError++;
+          return 1;
+        }
     }
 
   /* if defined parameters ended but actual parameters */
@@ -1115,6 +1134,21 @@ gatherAutoInit (symbol * autoChain)
       if (sym->ival)
         resolveIvalSym (sym->ival, sym->type);
 
+#if 1
+      /* if we are PIC16 port,
+       * and this is a static,
+       * and have initial value,
+       * and not S_CODE, don't emit in gs segment,
+       * but allow glue.c:pic16emitRegularMap to put symbol
+       * in idata section */
+      if(TARGET_IS_PIC16 &&
+        IS_STATIC (sym->etype) && sym->ival
+        && SPEC_SCLS(sym->etype) != S_CODE) {
+        SPEC_SCLS (sym->etype) = S_DATA;
+        continue;
+      }
+#endif
+
       /* if this is a static variable & has an */
       /* initial value the code needs to be lifted */
       /* here to the main portion since they can be */
@@ -1249,7 +1283,7 @@ stringToSymbol (value * val)
   if (noAlloc == 0)
     {
       /* allocate it */
-      addSymChain (sym);
+      addSymChain (&sym);
       allocVariables (sym);
     }
   sym->ival = NULL;
@@ -1499,6 +1533,8 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
         }
 
     }
+  else
+    return FALSE;
 
   /* check loop expression is of the form <sym>++ */
   if (!IS_AST_OP (loopExpr))
@@ -3529,11 +3565,37 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       if (IS_ADDRESS_OF_OP(tree->right)
           && IS_AST_SYM_VALUE (tree->right->left)
           && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
+        
+        symbol * sym = AST_SYMBOL (tree->right->left);
+        unsigned int gptype = 0;
+        unsigned int addr = SPEC_ADDR (sym->etype);
 
+        if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
+          {
+            switch (SPEC_SCLS (sym->etype))
+              {
+              case S_CODE:
+                gptype = GPTYPE_CODE;
+                break;
+              case S_XDATA:
+                gptype = GPTYPE_FAR;
+                break;
+              case S_DATA:
+              case S_IDATA:
+                gptype = GPTYPE_NEAR;
+                break;
+              case S_PDATA:
+                gptype = GPTYPE_XSTACK;
+                break;
+              default:
+                gptype = 0;
+              }
+            addr |= gptype << (8*(GPTRSIZE - 1));
+          }
+        
         tree->type = EX_VALUE;
         tree->opval.val =
-          valCastLiteral (LTYPE (tree),
-                          SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
+          valCastLiteral (LTYPE (tree), addr);
         TTYPE (tree) = tree->opval.val->type;
         TETYPE (tree) = getSpec (TTYPE (tree));
         tree->left = NULL;
@@ -3899,7 +3961,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
 
     case ':':
       /* if they don't match we have a problem */
-      if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
+      if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
+          (compareType (RTYPE (tree), LTYPE (tree)) == 0))
         {
           werror (E_TYPE_MISMATCH, "conditional operator", " ");
           goto errorTreeReturn;
@@ -4115,8 +4178,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       /* require a function or pointer to function */
-      if (!IS_FUNC (LTYPE (tree))
-          && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
+      if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
         {
           werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
           goto errorTreeReturn;
@@ -4130,7 +4192,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           sym_link *functype;      
           parmNumber = 1;
 
-          if (IS_CODEPTR(LTYPE(tree)))
+          if (IS_FUNCPTR (LTYPE (tree)))
             functype = LTYPE (tree)->next;
           else
             functype = LTYPE (tree);
@@ -4416,7 +4478,6 @@ createBlock (symbol * decl, ast * body)
   ex = newNode (BLOCK, NULL, body);
   ex->values.sym = decl;
   
-  ex->right = ex->right;///?????
   ex->level++;
   ex->lineno = 0;
   return ex;
@@ -5279,21 +5340,26 @@ createFunction (symbol * name, ast * body)
     }
   else
     {
-      addSymChain (name);
+      addSymChain (&name);
       allocVariables (name);
     }
   name->lastLine = mylineno;
   currFunc = name;
 
   /* set the stack pointer */
-  /* PENDING: check this for the mcs51 */
-  stackPtr = -port->stack.direction * port->stack.call_overhead;
+  stackPtr  = -port->stack.direction * port->stack.call_overhead;
+  xstackPtr = 0;
+
   if (IFFUNC_ISISR (name->type))
     stackPtr -= port->stack.direction * port->stack.isr_overhead;
-  if (IFFUNC_ISREENT (name->type) || options.stackAuto)
-    stackPtr -= port->stack.direction * port->stack.reent_overhead;
 
-  xstackPtr = -port->stack.direction * port->stack.call_overhead;
+  if (IFFUNC_ISREENT (name->type) || options.stackAuto)
+    {
+      if (options.useXstack)
+        xstackPtr -= port->stack.direction * port->stack.reent_overhead;
+      else
+        stackPtr  -= port->stack.direction * port->stack.reent_overhead;
+    }
 
   fetype = getSpec (name->type);        /* get the specifier for the function */
   /* if this is a reentrant function then */