fixed the foo[foo[5]+5]=10 bug
[fw/sdcc] / src / SDCCicode.c
index 56eae7f0d06c49b47f69d59e216fc3f188190aa5..748a9daf0b9827ae9356e766f104e938d9e262f8 100644 (file)
@@ -51,7 +51,7 @@ operand *geniCodeRValue (operand *, bool);
 operand *geniCodeDerefPtr (operand *);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
-/* forward definition of print functions */
+/* forward definition of ic print functions */
 PRINTFUNC (picGetValueAtAddr);
 PRINTFUNC (picSetValueAtAddr);
 PRINTFUNC (picAddrOf);
@@ -398,6 +398,10 @@ piCode (void *item, FILE * of)
   return 1;
 }
 
+void PICC(iCode *ic)
+{
+       printiCChain(ic,stdout);
+}
 /*-----------------------------------------------------------------*/
 /* printiCChain - prints intermediate code for humans              */
 /*-----------------------------------------------------------------*/
@@ -579,6 +583,7 @@ copyiCode (iCode * ic)
   nic->filename = ic->filename;
   nic->block = ic->block;
   nic->level = ic->level;
+  nic->parmBytes = ic->parmBytes;
 
   /* deal with the special cases first */
   switch (ic->op)
@@ -1071,7 +1076,6 @@ newiTempFromOp (operand * op)
   nop->noSpilLoc = op->noSpilLoc;
   nop->usesDefs = op->usesDefs;
   nop->isParm = op->isParm;
-  nop->parmBytes = op->parmBytes;
   return nop;
 }
 
@@ -1095,7 +1099,6 @@ operandFromOperand (operand * op)
   nop->noSpilLoc = op->noSpilLoc;
   nop->usesDefs = op->usesDefs;
   nop->isParm = op->isParm;
-  nop->parmBytes = op->parmBytes;
 
   switch (nop->type)
     {
@@ -1157,14 +1160,13 @@ operandFromSymbol (symbol * sym)
       op->key = sym->key;
       op->isvolatile = isOperandVolatile (op, TRUE);
       op->isGlobal = isOperandGlobal (op);
-      op->parmBytes = sym->argStack;
       return op;
     }
 
   /* under the following conditions create a
      register equivalent for a local symbol */
   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
-      (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) &&
+      (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
       options.stackAuto == 0)
     ok = 0;
 
@@ -1343,6 +1345,43 @@ setOperandType (operand * op, sym_link * type)
     }
 
 }
+/*-----------------------------------------------------------------*/
+/* Get size in byte of ptr need to access an array                 */
+/*-----------------------------------------------------------------*/
+int
+getArraySizePtr (operand * op)
+{
+  sym_link *ltype = operandType(op);
+
+  if(IS_PTR(ltype))
+    {
+      int size = getSize(ltype);
+      return(IS_GENPTR(ltype)?(size-1):size);
+    }
+
+  if(IS_ARRAY(ltype))
+    {
+      sym_link *letype = getSpec(ltype);
+      switch (PTR_TYPE (SPEC_OCLS (letype)))
+       {
+       case IPOINTER:
+       case PPOINTER:
+       case POINTER:
+         return (PTRSIZE);
+       case EEPPOINTER:
+       case FPOINTER:
+       case CPOINTER:
+       case FUNCTION:
+         return (FPTRSIZE);
+       case GPOINTER:
+         return (GPTRSIZE-1);
+
+       default:
+         return (FPTRSIZE);
+       }
+    }
+  return (FPTRSIZE);
+}
 
 /*-----------------------------------------------------------------*/
 /* perform "usual unary conversions"                               */
@@ -1517,7 +1556,7 @@ geniCodeRValue (operand * op, bool force)
 
   if (IS_SPEC (type) &&
       IS_TRUE_SYMOP (op) &&
-      (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT))
+      (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
     {
       op = operandFromOperand (op);
       op->isaddr = 0;
@@ -1647,12 +1686,11 @@ geniCodeGoto (symbol * label)
 /* geniCodeMultiply - gen intermediate code for multiplication     */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation,
-                 int resultIsInt)
+geniCodeMultiply (operand * left, operand * right,int resultIsInt)
 {
   iCode *ic;
   int p2 = 0;
-  int saveOption;
+  int saveOption=0;
   sym_link *resType;
   LRTYPE;
 
@@ -1661,51 +1699,45 @@ geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation,
     return operandFromValue (valMult (left->operand.valOperand,
                                      right->operand.valOperand));
 
+  if (IS_LITERAL(retype)) {
+    p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
+  }
 
-  //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
-  if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
-      (1 == getSize (ltype)))
+  if (resultIsInt)
     {
       saveOption = options.ANSIint;
       options.ANSIint = 0;
-      resType = usualBinaryConversions (&left, &right);
-      ltype = operandType (left);
-      rtype = operandType (right);
-      SPEC_SHORT (getSpec (resType)) = 0;
+    }
+  resType = usualBinaryConversions (&left, &right);
+#if 1
+  rtype = operandType (right);
+  retype = getSpec (rtype);
+  ltype = operandType (left);
+  letype = getSpec (ltype);
+#endif
+  if (resultIsInt)
+    {
       options.ANSIint = saveOption;
+      SPEC_NOUN(getSpec(resType))=V_INT;
+      SPEC_SHORT(getSpec(resType))=0;
     }
-  else {
-         resType = usualBinaryConversions (&left, &right);
-         /*     if (IS_DS390_PORT) { */
-         /* jwk char*char=int
-            Now be can use the 16bit result of "mul a,b" instead of explicit
-            casts and support function calls as with --ansiint
-         */
-         /*       if ((IS_CHAR(letype) || IS_SHORT(letype)) &&  */
-         /*       (IS_CHAR(retype) || IS_SHORT(retype))) { */
-         if (resultIsInt) {
-                 SPEC_NOUN(getSpec(resType))=V_INT;
-                 SPEC_SHORT(getSpec(resType))=0;
-         }
-  }
-/*   } */
 
   /* if the right is a literal & power of 2 */
   /* then make it a left shift              */
-  /*If we are computing  ptr size then normal multiplication */
-  /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
-  /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
-  if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
-      !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
-   (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
-    {
-      if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
+  /* code generated for 1 byte * 1 byte literal = 2 bytes result is more 
+     efficient in most cases than 2 bytes result = 2 bytes << literal 
+     if port has 1 byte muldiv */
+  if (p2 && !IS_FLOAT (letype) &&
+      !((resultIsInt) && (getSize (resType) != getSize (ltype)) && 
+       (port->muldiv.native_below == 1)))
+    {
+      if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
        {
          /* LEFT_OP need same size for left and result, */
          left = geniCodeCast (resType, left, TRUE);
          ltype = operandType (left);
        }
-      ic = newiCode (LEFT_OP, left, operandFromLit (p2));      /* left shift */
+      ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
     }
   else
     {
@@ -1840,7 +1872,7 @@ geniCodeSubtract (operand * left, operand * right)
     {
       isarray = left->isaddr;
       right = geniCodeMultiply (right,
-                             operandFromLit (getSize (ltype->next)), TRUE, FALSE);
+                               operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
     }
   else
@@ -1889,13 +1921,12 @@ geniCodeAdd (operand * left, operand * right)
   /* if left is an array or pointer then size */
   if (IS_PTR (ltype))
     {
-
       isarray = left->isaddr;
-      size =
-       operandFromLit (getSize (ltype->next));
-
-      right = geniCodeMultiply (right, size, (getSize (ltype) != 1),FALSE);
-
+      // there is no need to multiply with 1
+      if (getSize(ltype->next)!=1) {
+       size  = operandFromLit (getSize (ltype->next));
+       right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
+      }
       resType = copyLinkChain (ltype);
     }
   else
@@ -2002,9 +2033,8 @@ geniCodeArray (operand * left, operand * right)
       return geniCodeDerefPtr (geniCodeAdd (left, right));
     }
 
-  /* array access */
   right = geniCodeMultiply (right,
-                           operandFromLit (getSize (ltype->next)), TRUE,FALSE);
+                           operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
 
   /* we can check for limits here */
   if (isOperandLiteral (right) &&
@@ -2489,10 +2519,10 @@ geniCodeLogic (operand * left, operand * right, int op)
   ic = newiCode (op, left, right);
   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
 
-  /* if comparing anything greater than one byte
+  /* if comparing float
      and not a '==' || '!=' || '&&' || '||' (these
      will be inlined */
-  if (getSize (ctype) > 1 &&
+  if (IS_FLOAT(ctype) &&
       op != EQ_OP &&
       op != NE_OP &&
       op != AND_OP &&
@@ -2749,7 +2779,7 @@ geniCodeCall (operand * left, ast * parms)
   geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
 
   /* now call : if symbol then pcall */
-  if (IS_ITEMP (left))
+  if (IS_OP_POINTER (left) || IS_ITEMP(left))
     ic = newiCode (PCALL, left, NULL);
   else
     ic = newiCode (CALL, left, NULL);
@@ -2763,7 +2793,7 @@ geniCodeCall (operand * left, ast * parms)
   ADDTOCHAIN (ic);
 
   /* stack adjustment after call */
-  left->parmBytes = stack;
+  ic->parmBytes = stack;
 
   return result;
 }
@@ -2792,7 +2822,7 @@ geniCodeReceive (value * args)
 
              if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
                  options.stackAuto == 0 &&
-                 !IS_DS390_PORT)
+                 !TARGET_IS_DS390)
                {
                }
              else
@@ -3256,7 +3286,7 @@ ast2iCode (ast * tree)
     case '*':
       if (right)
        return geniCodeMultiply (geniCodeRValue (left, FALSE),
-                                geniCodeRValue (right, FALSE), FALSE,IS_INT(tree->ftype));
+                                geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
       else
        return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
 
@@ -3332,7 +3362,7 @@ ast2iCode (ast * tree)
        geniCodeAssign (left,
                geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 geniCodeRValue (right, FALSE), FALSE,FALSE), 0);
+                                 geniCodeRValue (right, FALSE),FALSE), 0);
 
     case DIV_ASSIGN:
       return