* device/lib/pic16/startup/crt0i.c (_cinit): local variables where
[fw/sdcc] / src / SDCCicode.c
index c024091a67f105c2a90d3aa5c7c956126e5b6975..4d0a9f4bf1d4a488b6c1c19f077fe91c19ffca2d 100644 (file)
@@ -233,7 +233,8 @@ printOperand (operand * op, FILE * file)
 
     case SYMBOL:
 #define REGA 1
-#ifdef REGA
+//#if REGA     /* { */
+    if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
       fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}",          /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
               (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
               op->key,
@@ -276,21 +277,53 @@ printOperand (operand * op, FILE * file)
              fprintf (file, "]");
            }
        }
-#else
-      fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
-                           OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
+//#else                /* } else { */
+    } else {
+      /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
+      fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
+
+      if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
+        {
+          fprintf (file, "[lr%d:%d so:%d]",
+              OP_LIVEFROM (op), OP_LIVETO (op),
+              OP_SYMBOL (op)->stack);
+        }
+
+      if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
+        {
+          fprintf (file, "{");
+          printTypeChain (operandType (op), file);
+          if (SPIL_LOC (op) && IS_ITEMP (op))
+              fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
+          fprintf (file, "}");
+        }
+
       /* if assigned to registers */
-      if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
+      if (OP_SYMBOL (op)->nRegs)
        {
-         int i;
-         fprintf (file, "[");
-         for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
-           fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
-                                  OP_SYMBOL (op)->regs[i]->name :
-                                  "err"));
-         fprintf (file, "]");
+         if (OP_SYMBOL (op)->isspilt)
+           {
+             if (!OP_SYMBOL (op)->remat)
+               if (OP_SYMBOL (op)->usl.spillLoc)
+                 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
+                                      OP_SYMBOL (op)->usl.spillLoc->rname :
+                                      OP_SYMBOL (op)->usl.spillLoc->name));
+               else
+                 fprintf (file, "[err]");
+             else
+               fprintf (file, "[remat]");
+           }
+         else
+           {
+             int i;
+             fprintf (file, "[");
+             for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
+               fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
+             fprintf (file, "]");
+           }
        }
-#endif
+//#endif               /* } */
+    }
       break;
 
     case TYPE:
@@ -399,6 +432,9 @@ PRINTFUNC (picGenericOne)
   if (ic->op == SEND || ic->op == RECEIVE) {
       fprintf(of,"{argreg = %d}",ic->argreg);
   }
+  if (ic->op == IPUSH) {
+      fprintf(of,"{parmPush = %d}",ic->parmPush);
+  }
   fprintf (of, "\n");
 }
 
@@ -514,7 +550,7 @@ piCode (void *item, FILE * of)
     of = stdout;
 
   icTab = getTableEntry (ic->op);
-  fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
+  fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
           ic->filename, ic->lineno,
           ic->seq, ic->key, ic->depth, ic->supportRtn);
   icTab->iCodePrint (of, ic, icTab->printName);
@@ -657,13 +693,13 @@ newiTempLabel (char *s)
 {
   symbol *itmplbl;
 
-  /* check if this alredy exists */
+  /* check if this already exists */
   if (s && (itmplbl = findSym (LabelTab, NULL, s)))
     return itmplbl;
 
   if (s)
     {
-       itmplbl = newSymbol (s, 1);
+      itmplbl = newSymbol (s, 1);
     }
   else
     {
@@ -1039,6 +1075,40 @@ isOclsExpensive (struct memmap *oclass)
   return IN_FARSPACE (oclass);
 }
 
+/*-----------------------------------------------------------------*/
+/* isiCodeInFunctionCall - return TRUE if an iCode is between a    */
+/*   CALL/PCALL and the first IPUSH/SEND associated with the call  */
+/*-----------------------------------------------------------------*/
+int
+isiCodeInFunctionCall (iCode * ic)
+{
+  iCode * lic = ic;
+  
+  /* Find the next CALL/PCALL */
+  while (lic)
+    {
+      if (lic->op == CALL || lic->op == PCALL)
+        break;
+      lic = lic->next;
+    }
+  
+  if (!lic)
+    return FALSE;
+
+  /* A function call was found. Scan backwards and see if an */
+  /* IPUSH or SEND is encountered */
+  while (ic)
+    {
+      if (lic != ic && (ic->op == CALL || ic->op == PCALL))
+        return FALSE;
+      if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
+        return TRUE;
+      ic = ic->prev;
+    }
+  
+  return FALSE;
+}
+
 /*-----------------------------------------------------------------*/
 /* operandLitValue - literal value of an operand                   */
 /*-----------------------------------------------------------------*/
@@ -1930,7 +2000,12 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
        // if not a pointer to a function
        if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
          if (implicit) { // if not to generic, they have to match
-           if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
+           if (!IS_GENPTR(type) &&
+                !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
+                  ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
+                 )
+               )
+            {
              werror(E_INCOMPAT_PTYPES);
              errors++;
            }
@@ -1990,9 +2065,10 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   restype = getSpec (operandType (IC_RESULT (ic)));
   if (!IS_LITERAL(opetype) &&
       !IS_BIT(opetype))
+    {
       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
-  SPEC_OCLS (restype) = SPEC_OCLS (opetype);
-
+      SPEC_OCLS (restype) = SPEC_OCLS (opetype);
+    }
   ADDTOCHAIN (ic);
   return IC_RESULT (ic);
 }
@@ -2057,8 +2133,8 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
   if (p2 && !IS_FLOAT (letype)
       && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
            && (port->support.muldiv == 1))
-      && strcmp (port->target, "pic14") != 0  /* don't shift for pic */
-      && strcmp (port->target, "pic16") != 0)
+      && strcmp (port->target, "pic16") != 0  /* don't shift for pic */
+      && strcmp (port->target, "pic14") != 0)
     {
       if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
        {
@@ -2495,6 +2571,8 @@ geniCodePostInc (operand * op)
   geniCodeAssign (rOp, rv, 0, 0);
 
   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
+  if (size == 0)
+    werror(W_SIZEOF_VOID);
   if (IS_FLOAT (rvtype))
     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
   else
@@ -2530,8 +2608,9 @@ geniCodePreInc (operand * op, bool lvalue)
       return op;
     }
 
-
   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
+  if (size == 0)
+    werror(W_SIZEOF_VOID);
   if (IS_FLOAT (roptype))
     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
   else
@@ -2578,6 +2657,8 @@ geniCodePostDec (operand * op)
   geniCodeAssign (rOp, rv, 0, 0);
 
   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
+  if (size == 0)
+    werror(W_SIZEOF_VOID);
   if (IS_FLOAT (rvtype))
     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
   else
@@ -2613,8 +2694,9 @@ geniCodePreDec (operand * op, bool lvalue)
       return op;
     }
 
-
   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
+  if (size == 0)
+    werror(W_SIZEOF_VOID);
   if (IS_FLOAT (roptype))
     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
   else
@@ -3194,12 +3276,12 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
       /* hack don't like this but too lazy to think of
          something better */
       if (IS_ADDRESS_OF_OP (parms))
-       parms->left->lvalue = 1;
+        parms->left->lvalue = 1;
 
       if (IS_CAST_OP (parms) &&
-         IS_PTR (parms->ftype) &&
-         IS_ADDRESS_OF_OP (parms->right))
-       parms->right->left->lvalue = 1;
+          IS_PTR (parms->ftype) &&
+          IS_ADDRESS_OF_OP (parms->right))
+        parms->right->left->lvalue = 1;
 
       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
     }
@@ -3217,24 +3299,24 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
     {
       /* now decide whether to push or assign */
       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
-       {
+        {
 
-         /* assign */
-         operand *top = operandFromSymbol (argVals->sym);
-         /* clear useDef and other bitVectors */
-         OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
-         geniCodeAssign (top, pval, 1, 0);
-       }
+          /* assign */
+          operand *top = operandFromSymbol (argVals->sym);
+          /* clear useDef and other bitVectors */
+          OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
+          geniCodeAssign (top, pval, 1, 0);
+        }
       else
-       {
-         sym_link *p = operandType (pval);
-         /* push */
-         ic = newiCode (IPUSH, pval, NULL);
-         ic->parmPush = 1;
-         /* update the stack adjustment */
-         *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
-         ADDTOCHAIN (ic);
-       }
+        {
+          sym_link *p = operandType (pval);
+          /* push */
+          ic = newiCode (IPUSH, pval, NULL);
+          ic->parmPush = 1;
+          /* update the stack adjustment */
+          *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
+          ADDTOCHAIN (ic);
+        }
     }
 
   argVals=argVals->next;
@@ -3297,6 +3379,8 @@ geniCodeCall (operand * left, ast * parms,int lvl)
 static void 
 geniCodeReceive (value * args)
 {
+  unsigned char paramByteCounter = 0;
+
   /* for all arguments that are passed in registers */
   while (args)
     {
@@ -3337,6 +3421,17 @@ geniCodeReceive (value * args)
              first = 0;
          }
          IC_RESULT (ic) = opr;
+         
+         /* misuse of parmBytes (normally used for functions) 
+          * to save estimated stack position of this argument.
+          * Normally this should be zero for RECEIVE iCodes.
+          * No idea if this causes side effects on other ports. - dw
+          */
+         ic->parmBytes = paramByteCounter;
+         
+         /* what stack position do we have? */
+         paramByteCounter += getSize (sym->type);
+
          ADDTOCHAIN (ic);
        }
 
@@ -3485,7 +3580,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   int needRangeCheck = !optimize.noJTabBoundary
                        || tree->values.switchVals.swDefault;
   sym_link *cetype = getSpec (operandType (cond));
-  int sizeofMinCost, sizeofMaxCost;
+  int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
   int sizeofMatchJump, sizeofJumpTable;
   int sizeIndex;
 
@@ -3521,11 +3616,14 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   
   /* Compute the size cost of the range check and subtraction. */
   sizeofMinCost = 0;
+  sizeofZeroMinCost = 0;
   sizeofMaxCost = 0;
   if (needRangeCheck)
     {
       if (!(min==0 && IS_UNSIGNED (cetype)))
         sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
+      if (!IS_UNSIGNED (cetype))
+        sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
       sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
     }
   if (min)
@@ -3534,11 +3632,18 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   /* If the size cost of handling a non-zero minimum exceeds the */
   /* cost of extending the range down to zero, then it might be */
   /* better to extend the range to zero. */
-  if (min > 0 && sizeofMinCost >= (min * port->jumptableCost.sizeofElement))
+  if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
+                 >= (min * port->jumptableCost.sizeofElement))
     {
       /* Only extend the jump table if it would still be manageable. */
       if (1 + max <= port->jumptableCost.maxCount)
-        min = 0;
+        {
+          min = 0;
+          if (IS_UNSIGNED (cetype))
+            sizeofMinCost = 0;
+          else
+            sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
+        }
     }
     
   /* Compute the total size cost of a jump table. */
@@ -3548,7 +3653,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
 
   /* Compute the total size cost of a match & jump sequence */
   sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
-  
+
   /* If the size cost of the jump table is uneconomical then exit */
   if (sizeofMatchJump <  sizeofJumpTable)
     return 0;
@@ -3764,11 +3869,23 @@ geniCodeCritical (ast *tree, int lvl)
 {
   iCode *ic;
   operand *op = NULL;
+  sym_link *type;
+
+  if (!options.stackAuto)
+    {
+      type = newLink(SPECIFIER);
+      SPEC_VOLATILE(type) = 1;
+      SPEC_NOUN(type) = V_BIT;
+      SPEC_SCLS(type) = S_BIT;
+      SPEC_BLEN(type) = 1;
+      SPEC_BSTR(type) = 0;
+      op = newiTempOperand(type, 1);
+    }
 
   /* If op is NULL, the original interrupt state will saved on */
   /* the stack. Otherwise, it will be saved in op. */
   
-  /* Generate a save of the current interrupt state & disabled */
+  /* Generate a save of the current interrupt state & disable */
   ic = newiCode (CRITICAL, NULL, NULL);
   IC_RESULT (ic) = op;
   ADDTOCHAIN (ic);