- removed compiler command line option /WX: Treats all warnings as errors
[fw/sdcc] / src / SDCCicode.c
index f9076153b113853f5bf0aeb46dee52520272c195..e20c2d8227a9ef652b34cd6f636270387a76509d 100644 (file)
@@ -224,14 +224,14 @@ printOperand (operand * op, FILE * file)
     case SYMBOL:
 #define REGA 1
 #ifdef REGA
-      fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d}",             /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
+      fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%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,
               OP_LIVEFROM (op), OP_LIVETO (op),
               OP_SYMBOL (op)->stack,
               op->isaddr, OP_SYMBOL (op)->isreqv, 
               OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
-              OP_SYMBOL(op)->ruonly
+              OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
        );
       {
        fprintf (file, "{");
@@ -386,6 +386,9 @@ PRINTFUNC (picGenericOne)
   if (!IC_RESULT (ic) && !IC_LEFT (ic))
     fprintf (of, s);
 
+  if (ic->op == SEND || ic->op == RECEIVE) {
+      fprintf(of,"{argreg = %d}",ic->argreg);
+  }
   fprintf (of, "\n");
 }
 
@@ -918,12 +921,11 @@ isOperandInDirSpace (operand * op)
   return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
 
-/*-----------------------------------------------------------------*/
-/* isOperandOnStack - will return true if operand is on stack      */
-/*-----------------------------------------------------------------*/
-#if 0
+/*--------------------------------------------------------------------*/
+/* isOperandInCodeSpace - will return true if operand is in codeSpace */
+/*--------------------------------------------------------------------*/
 bool 
-isOperandOnStack (operand * op)
+isOperandInCodeSpace (operand * op)
 {
   sym_link *etype;
 
@@ -935,9 +937,23 @@ isOperandOnStack (operand * op)
 
   etype = getSpec (operandType (op));
 
-  return ((IN_STACK (etype)) ? TRUE : FALSE);
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+       etype = SPIL_LOC (op)->etype;
+      else
+       return FALSE;
+    }
+  else
+    {
+      etype = getSpec (operandType (op));
+    }
+  return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
-#else
+
+/*-----------------------------------------------------------------*/
+/* isOperandOnStack - will return true if operand is on stack      */
+/*-----------------------------------------------------------------*/
 bool 
 isOperandOnStack (operand * op)
 {
@@ -957,7 +973,6 @@ isOperandOnStack (operand * op)
 
   return FALSE;
 }
-#endif
 
 /*-----------------------------------------------------------------*/
 /* operandLitValue - literal value of an operand                   */
@@ -1063,14 +1078,27 @@ operandOperation (operand * left, operand * right,
                                  (unsigned long) operandLitValue (right) :
                                  (long) operandLitValue (right)));
       break;
-    case RIGHT_OP:
-      retval = operandFromLit ((SPEC_USIGN(let) ? 
-                                 (unsigned long) operandLitValue (left) :
-                                 (long) operandLitValue (left)) >>
-                                (SPEC_USIGN(ret) ? 
-                                 (unsigned long) operandLitValue (right) :
-                                 (long) operandLitValue (right)));
+    case RIGHT_OP: {
+      double lval = operandLitValue(left), rval = operandLitValue(right);
+      double res=0;
+      switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0)) 
+       {
+       case 0: // left=unsigned right=unsigned
+         res=(unsigned long)lval >> (unsigned long)rval;
+         break;
+       case 1: // left=unsigned right=signed
+         res=(unsigned long)lval >> (signed long)rval;
+         break;
+       case 2: // left=signed right=unsigned
+         res=(signed long)lval >> (unsigned long)rval;
+         break;
+       case 3: // left=signed right=signed
+         res=(signed long)lval >> (signed long)rval;
+         break;
+       }
+      retval = operandFromLit (res);
       break;
+    }
     case EQ_OP:
       retval = operandFromLit (operandLitValue (left) ==
                               operandLitValue (right));
@@ -1630,7 +1658,6 @@ geniCodeRValue (operand * op, bool force)
   if (IS_SPEC (type) &&
       IS_TRUE_SYMOP (op) &&
       (!IN_FARSPACE (SPEC_OCLS (etype)) ||
-      /* TARGET_IS_DS390)) */
       (options.model == MODEL_FLAT24) ))
     {
       op = operandFromOperand (op);
@@ -1766,7 +1793,8 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   /* preserve the storage class & output class */
   /* of the original variable                  */
   restype = getSpec (operandType (IC_RESULT (ic)));
-  SPEC_SCLS (restype) = SPEC_SCLS (opetype);
+  if (!IS_LITERAL(opetype))
+      SPEC_SCLS (restype) = SPEC_SCLS (opetype);
   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
 
   ADDTOCHAIN (ic);
@@ -1876,10 +1904,12 @@ geniCodeDivision (operand * left, operand * right)
 
   resType = usualBinaryConversions (&left, &right);
 
-  /* if the right is a literal & power of 2 */
-  /* then make it a right shift             */
+  /* if the right is a literal & power of 2 
+     and left is unsigned then make it a    
+     right shift */
   if (IS_LITERAL (retype) &&
       !IS_FLOAT (letype) &&
+      SPEC_USIGN(letype) &&
       (p2 = powof2 ((unsigned long)
                    floatFromVal (right->operand.valOperand)))) {
     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
@@ -1949,6 +1979,11 @@ geniCodePtrPtrSubtract (operand * left, operand * right)
   ADDTOCHAIN (ic);
 
 subtractExit:
+  if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
+    return result;
+  }
+
+  // should we really do this? is this ANSI?
   return geniCodeDivision (result,
                           operandFromLit (getSize (ltype->next)));
 }
@@ -2759,10 +2794,12 @@ geniCodeSEParms (ast * parms,int lvl)
       IS_ADDRESS_OF_OP (parms->right))
     parms->right->left->lvalue = 1;
 
-  parms->opval.oprnd =
+  parms->opval.oprnd = 
     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
-
+               
   parms->type = EX_OPERAND;
+  AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
+               SPEC_ARGREG(parms->ftype);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2815,6 +2852,7 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
       IFFUNC_ISBUILTIN(func->type))
     {
       ic = newiCode (SEND, pval, NULL);
+      ic->argreg = SPEC_ARGREG(parms->etype);
       ic->builtinSEND = FUNC_ISBUILTIN(func->type);
       ADDTOCHAIN (ic);
     }
@@ -2900,7 +2938,7 @@ geniCodeReceive (value * args)
   /* for all arguments that are passed in registers */
   while (args)
     {
-
+      int first = 1;
       if (IS_REGPARM (args->etype))
        {
          operand *opr = operandFromValue (args);
@@ -2915,7 +2953,6 @@ geniCodeReceive (value * args)
 
              if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
                  options.stackAuto == 0 &&
-                 /* !TARGET_IS_DS390) */
                  (!(options.model == MODEL_FLAT24)) )
                {
                }
@@ -2931,8 +2968,12 @@ geniCodeReceive (value * args)
                }
            }
 
-         ic = newiCode (RECEIVE, NULL, NULL);
-         currFunc->recvSize = getSize (sym->etype);
+         ic = newiCode (RECEIVE, NULL, NULL);    
+         ic->argreg = SPEC_ARGREG(args->etype);
+         if (first) {
+             currFunc->recvSize = getSize (sym->type);
+             first = 0;
+         }
          IC_RESULT (ic) = opr;
          ADDTOCHAIN (ic);
        }
@@ -2969,7 +3010,7 @@ geniCodeFunctionBody (ast * tree,int lvl)
 
   /* create a proc icode */
   ic = newiCode (FUNCTION, func, NULL);
-  ic->lineno = OP_SYMBOL (func)->lineDef;
+  lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
 
   ADDTOCHAIN (ic);
 
@@ -3309,6 +3350,7 @@ ast2iCode (ast * tree,int lvl)
   operand *right = NULL;
   if (!tree)
     return NULL;
+
   /* set the global variables for filename & line number */
   if (tree->filename)
     filename = tree->filename;