* Added.
[fw/sdcc] / src / SDCCicode.c
index 7dca929a28cb09708a605048325f32af70359385..4b44dd2540c427dc1b0b439d6e47f91e2592a997 100644 (file)
@@ -126,9 +126,9 @@ iCodeTable codeTable[] =
      pedantic>1: "char c=200" is not allowed (evaluates to -56)
 */
 
-void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
+void checkConstantRange(sym_link *ltype, value *val, char *msg, 
+                       int pedantic) {
   double max;
-  char message[132]="";
   int warnings=0;
   int negative=0;
   long v;
@@ -178,6 +178,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
     warnings++;
   }
 
+#if 0 // temporary disabled, leaving the warning as a reminder
   if (warnings) {
     sprintf (message, "for %s %s in %s", 
             SPEC_USIGN(ltype) ? "unsigned" : "signed",
@@ -187,6 +188,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
     if (pedantic>1)
       fatalError++;
   }
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -222,12 +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}",          /*{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->isaddr, OP_SYMBOL (op)->isreqv, 
+              OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
+              OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
        );
       {
        fprintf (file, "{");
@@ -382,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");
 }
 
@@ -683,7 +690,6 @@ copyiCode (iCode * ic)
     case PCALL:
       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
-      IC_ARGS (nic) = IC_ARGS (ic);
       break;
 
     case INLINEASM:
@@ -858,6 +864,7 @@ isOperandLiteral (operand * op)
 
   return 0;
 }
+
 /*-----------------------------------------------------------------*/
 /* isOperandInFarSpace - will return true if operand is in farSpace */
 /*-----------------------------------------------------------------*/
@@ -886,6 +893,64 @@ isOperandInFarSpace (operand * op)
   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
 
+/*------------------------------------------------------------------*/
+/* isOperandInDirSpace - will return true if operand is in dirSpace */
+/*------------------------------------------------------------------*/
+bool 
+isOperandInDirSpace (operand * op)
+{
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
+
+  if (!IS_SYMOP (op))
+    return 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_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
+/*--------------------------------------------------------------------*/
+/* isOperandInCodeSpace - will return true if operand is in codeSpace */
+/*--------------------------------------------------------------------*/
+bool 
+isOperandInCodeSpace (operand * op)
+{
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
+
+  if (!IS_SYMOP (op))
+    return FALSE;
+
+  etype = getSpec (operandType (op));
+
+  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);
+}
+
 /*-----------------------------------------------------------------*/
 /* isOperandOnStack - will return true if operand is on stack      */
 /*-----------------------------------------------------------------*/
@@ -901,8 +966,12 @@ isOperandOnStack (operand * op)
     return FALSE;
 
   etype = getSpec (operandType (op));
+  if (IN_STACK (etype) ||
+      OP_SYMBOL(op)->onStack ||
+      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
+    return TRUE;
 
-  return ((IN_STACK (etype)) ? TRUE : FALSE);
+  return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
@@ -916,6 +985,31 @@ operandLitValue (operand * op)
   return floatFromVal (op->operand.valOperand);
 }
 
+/*-----------------------------------------------------------------*/
+/* getBuiltInParms - returns parameters to a builtin functions     */
+/*-----------------------------------------------------------------*/
+iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
+{
+    sym_link *ftype;
+
+    *pcount = 0;
+    /* builtin functions uses only SEND for parameters */
+    while (ic->op != CALL) {
+       assert(ic->op == SEND && ic->builtinSEND);
+       ic->generated = 1;    /* mark the icode as generated */
+       parms[*pcount] = IC_LEFT(ic);
+       ic = ic->next;
+       (*pcount)++;
+    }
+    
+    ic->generated = 1;
+    /* make sure this is a builtin function call */
+    assert(IS_SYMOP(IC_LEFT(ic)));
+    ftype = operandType(IC_LEFT(ic));
+    assert(IFFUNC_ISBUILTIN(ftype));
+    return ic;
+}
+
 /*-----------------------------------------------------------------*/
 /* operandOperation - perforoms operations on operands             */
 /*-----------------------------------------------------------------*/
@@ -1551,7 +1645,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);
@@ -1607,7 +1700,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   if (IS_PTR(type)) { // to a pointer
     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
       if (IS_INTEGRAL(optype)) { 
-       // maybe this is NULL, than it's ok.
+       // maybe this is NULL, than it's ok. 
        if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
          if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
            // no way to set the storage
@@ -1687,7 +1780,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);
@@ -1926,7 +2020,7 @@ geniCodeSubtract (operand * left, operand * right)
 /* geniCodeAdd - generates iCode for addition                      */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeAdd (operand * left, operand * right,int lvl)
+geniCodeAdd (operand * left, operand * right, int lvl)
 {
   iCode *ic;
   sym_link *resType;
@@ -1947,7 +2041,7 @@ geniCodeAdd (operand * left, operand * right,int lvl)
   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
     return right;
 
-  /* if left is an array or pointer then size */
+  /* if left is a pointer then size */
   if (IS_PTR (ltype))
     {
       isarray = left->isaddr;
@@ -1959,7 +2053,7 @@ geniCodeAdd (operand * left, operand * right,int lvl)
       resType = copyLinkChain (ltype);
     }
   else
-    {                          /* make them the same size */
+    { // make them the same size
       resType = usualBinaryConversions (&left, &right);
     }
 
@@ -2059,7 +2153,7 @@ geniCodeArray (operand * left, operand * right,int lvl)
        {
          left = geniCodeRValue (left, FALSE);
        }
-      return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
+      return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
     }
 
   right = geniCodeMultiply (right,
@@ -2565,7 +2659,7 @@ geniCodeConditional (ast * tree,int lvl)
   true = ast2iCode (tree->right->left,lvl+1);
 
   /* move the value to a new Operand */
-  result = newiTempOperand (operandType (true), 0);
+  result = newiTempOperand (tree->right->ftype, 0);
   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
 
   /* generate an unconditional goto */
@@ -2680,10 +2774,11 @@ 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) = SPEC_ARGREG(parms->etype);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2732,9 +2827,12 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
     }
 
   /* if register parm then make it a send */
-  if (IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type))
+  if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
+      IFFUNC_ISBUILTIN(func->type))
     {
       ic = newiCode (SEND, pval, NULL);
+      ic->argreg = SPEC_ARGREG(parms->etype);
+      ic->builtinSEND = FUNC_ISBUILTIN(func->type);
       ADDTOCHAIN (ic);
     }
   else
@@ -2745,6 +2843,8 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
 
          /* 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);
        }
       else
@@ -2789,12 +2889,12 @@ geniCodeCall (operand * left, ast * parms,int lvl)
   geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
 
   /* now call : if symbol then pcall */
-  if (IS_OP_POINTER (left) || IS_ITEMP(left))
+  if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
     ic = newiCode (PCALL, left, NULL);
-  else
+  } else {
     ic = newiCode (CALL, left, NULL);
+  }
 
-  IC_ARGS (ic) = FUNC_ARGS(left->operand.symOperand->type);
   type = copyLinkChain (operandType (left)->next);
   etype = getSpec (type);
   SPEC_EXTR (etype) = 0;
@@ -2817,7 +2917,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);
@@ -2832,7 +2932,6 @@ geniCodeReceive (value * args)
 
              if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
                  options.stackAuto == 0 &&
-                 /* !TARGET_IS_DS390) */
                  (!(options.model == MODEL_FLAT24)) )
                {
                }
@@ -2848,8 +2947,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);
        }
@@ -2886,10 +2989,7 @@ geniCodeFunctionBody (ast * tree,int lvl)
 
   /* create a proc icode */
   ic = newiCode (FUNCTION, func, NULL);
-  /* if the function has parmas   then */
-  /* save the parameters information    */
-  ic->argLabel.args = tree->values.args;
-  ic->lineno = OP_SYMBOL (func)->lineDef;
+  lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
 
   ADDTOCHAIN (ic);
 
@@ -3229,6 +3329,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;