doc/sdccman.lyx: minor changes, mentioned beta vendor support for ds80c400
[fw/sdcc] / src / SDCCicode.c
index ae54a48a2afbcdf0dd811513de1fd0c231f349ff..9b841e5219bc278fc546397106634b626160a5ad 100644 (file)
@@ -45,7 +45,7 @@ symbol *entryLabel;           /* function entry  label */
 
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
-operand *geniCodeAssign (operand *, operand *, int);
+operand *geniCodeAssign (operand *, operand *, int, int);
 static operand *geniCodeArray (operand *, operand *,int);
 static operand *geniCodeArray2Ptr (operand *);
 operand *geniCodeRValue (operand *, bool);
@@ -1527,16 +1527,15 @@ operandFromSymbol (symbol * sym)
     ok = 0;
 
   if (!IS_AGGREGATE (sym->type) &&     /* not an aggregate */
-      !IS_FUNC (sym->type) &&  /* not a function   */
-      !sym->_isparm &&         /* not a parameter  */
-      sym->level &&            /* is a local variable */
-      !sym->addrtaken &&       /* whose address has not been taken */
-      !sym->reqv &&            /* does not already have a reg equivalence */
+      !IS_FUNC (sym->type) &&          /* not a function   */
+      !sym->_isparm &&                 /* not a parameter  */
+      IS_AUTO (sym) &&                 /* is a local auto variable */
+      !sym->addrtaken &&               /* whose address has not been taken */
+      !sym->reqv &&                    /* does not already have a reg equivalence */
       !IS_VOLATILE (sym->etype) &&     /* not declared as volatile */
-      !IS_STATIC (sym->etype) &&       /* and not declared static  */
-      !sym->islbl &&           /* not a label */
-      ok &&                    /* farspace check */
-      !IS_BITVAR (sym->etype)  /* not a bit variable */
+      !sym->islbl &&                   /* not a label */
+      ok &&                            /* farspace check */
+      !IS_BITVAR (sym->etype)          /* not a bit variable */
     )
     {                                   
 
@@ -2322,6 +2321,19 @@ aggrToPtr (sym_link * type, bool force)
   return ptype;
 }
 
+/*------------------------------------------------------------------*/
+/* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
+/*------------------------------------------------------------------*/
+int
+aggrToPtrDclType (sym_link * type, bool force)
+{
+  if (IS_PTR (type) && !force)
+    return DCL_TYPE (type);
+
+  /* return the pointer depending on the storage class */
+  return PTR_TYPE (SPEC_OCLS (getSpec (type)));
+}
+
 /*-----------------------------------------------------------------*/
 /* geniCodeArray2Ptr - array to pointer                            */
 /*-----------------------------------------------------------------*/
@@ -2469,7 +2481,7 @@ geniCodePostInc (operand * op)
   if (IS_ITEMP (rv))
     OP_SYMBOL(rv)->noSpilLoc = 1;
 
-  geniCodeAssign (rOp, rv, 0);
+  geniCodeAssign (rOp, rv, 0, 0);
 
   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
   if (IS_FLOAT (rvtype))
@@ -2480,7 +2492,7 @@ geniCodePostInc (operand * op)
   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
   ADDTOCHAIN (ic);
 
-  geniCodeAssign (op, result, 0);
+  geniCodeAssign (op, result, 0, 0);
 
   return rOp;
 
@@ -2516,8 +2528,8 @@ geniCodePreInc (operand * op, bool lvalue)
   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
   ADDTOCHAIN (ic);
 
-  (void) geniCodeAssign (op, result, 0);
-  if (lvalue || IS_TRUE_SYMOP (op))
+  (void) geniCodeAssign (op, result, 0, 0);
+  if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
     return op;
   else
     return result;
@@ -2552,7 +2564,7 @@ geniCodePostDec (operand * op)
   if (IS_ITEMP (rv))
     OP_SYMBOL(rv)->noSpilLoc = 1;
 
-  geniCodeAssign (rOp, rv, 0);
+  geniCodeAssign (rOp, rv, 0, 0);
 
   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
   if (IS_FLOAT (rvtype))
@@ -2563,7 +2575,7 @@ geniCodePostDec (operand * op)
   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
   ADDTOCHAIN (ic);
 
-  geniCodeAssign (op, result, 0);
+  geniCodeAssign (op, result, 0, 0);
 
   return rOp;
 
@@ -2599,8 +2611,8 @@ geniCodePreDec (operand * op, bool lvalue)
   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
   ADDTOCHAIN (ic);
 
-  (void) geniCodeAssign (op, result, 0);
-  if (lvalue || IS_TRUE_SYMOP (op))
+  (void) geniCodeAssign (op, result, 0, 0);
+  if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
     return op;
   else
     return result;
@@ -2950,12 +2962,12 @@ geniCodeLogicAndOr (ast *tree, int lvl)
   result = newiTempOperand (newCharLink(), 1);
   
   geniCodeLabel (falseLabel);
-  geniCodeAssign (result, operandFromLit (0), 0);
+  geniCodeAssign (result, operandFromLit (0), 0, 0);
   /* generate an unconditional goto */
   geniCodeGoto (exitLabel);
 
   geniCodeLabel (trueLabel);
-  geniCodeAssign (result, operandFromLit (1), 0);
+  geniCodeAssign (result, operandFromLit (1), 0, 0);
 
   geniCodeLabel (exitLabel);
 
@@ -2995,7 +3007,7 @@ geniCodeConditional (ast * tree,int lvl)
 
   /* move the value to a new Operand */
   result = newiTempOperand (tree->right->ftype, 0);
-  geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
+  geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
 
   /* generate an unconditional goto */
   geniCodeGoto (exitLabel);
@@ -3004,7 +3016,7 @@ geniCodeConditional (ast * tree,int lvl)
   geniCodeLabel (falseLabel);
 
   false = ast2iCode (tree->right->right,lvl+1);
-  geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
+  geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
 
   /* create the exit label */
   geniCodeLabel (exitLabel);
@@ -3016,13 +3028,13 @@ geniCodeConditional (ast * tree,int lvl)
 /* geniCodeAssign - generate code for assignment                   */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeAssign (operand * left, operand * right, int nosupdate)
+geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
 {
   iCode *ic;
   sym_link *ltype = operandType (left);
   sym_link *rtype = operandType (right);
 
-  if (!left->isaddr && !IS_ITEMP (left))
+  if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
     {
       werror (E_LVALUE_REQUIRED, "assignment");
       return left;
@@ -3200,7 +3212,7 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
          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);
+         geniCodeAssign (top, pval, 1, 0);
        }
       else
        {
@@ -3350,6 +3362,7 @@ geniCodeFunctionBody (ast * tree,int lvl)
   /* create a proc icode */
   ic = newiCode (FUNCTION, func, NULL);
   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
+  ic->tree = tree;
 
   ADDTOCHAIN (ic);
 
@@ -3365,6 +3378,7 @@ geniCodeFunctionBody (ast * tree,int lvl)
 
   /* now generate the end proc */
   ic = newiCode (ENDFUNCTION, func, NULL);
+  ic->tree = tree;
   ADDTOCHAIN (ic);
   return;
 }
@@ -4014,7 +4028,7 @@ ast2iCode (ast * tree,int lvl)
        else
          right = geniCodeRValue (right, FALSE);
 
-       geniCodeAssign (left, right, 0);
+       geniCodeAssign (left, right, 0, 1);
        return right;
       }
     case MUL_ASSIGN:
@@ -4022,8 +4036,9 @@ ast2iCode (ast * tree,int lvl)
        geniCodeAssign (left,
                geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 geniCodeRValue (right, FALSE), FALSE),
-                                 getResultTypeFromType (tree->ftype));
+                                 geniCodeRValue (right, FALSE), 
+                                 getResultTypeFromType (tree->ftype)),
+                       0, 1);
 
     case DIV_ASSIGN:
       return
@@ -4032,7 +4047,7 @@ ast2iCode (ast * tree,int lvl)
                                                  FALSE),
                                  geniCodeRValue (right, FALSE),
                                  getResultTypeFromType (tree->ftype)),
-                       0);
+                       0, 1);
     case MOD_ASSIGN:
       return
        geniCodeAssign (left,
@@ -4040,7 +4055,7 @@ ast2iCode (ast * tree,int lvl)
                                                  FALSE),
                                  geniCodeRValue (right, FALSE),
                                  getResultTypeFromType (tree->ftype)),
-                       0);
+                       0, 1);
     case ADD_ASSIGN:
       {
        sym_link *rtype = operandType (right);
@@ -4058,7 +4073,7 @@ ast2iCode (ast * tree,int lvl)
                                  right,
                                  getResultTypeFromType (tree->ftype),
                                  lvl),
-                              0);
+                              0, 1);
       }
     case SUB_ASSIGN:
       {
@@ -4079,7 +4094,7 @@ ast2iCode (ast * tree,int lvl)
                                                  FALSE),
                                  right,
                                  getResultTypeFromType (tree->ftype)),
-                         0);
+                         0, 1);
       }
     case LEFT_ASSIGN:
       return
@@ -4088,13 +4103,13 @@ ast2iCode (ast * tree,int lvl)
                                                   ,FALSE),
                                   geniCodeRValue (right, FALSE),
                                   getResultTypeFromType (tree->ftype)),
-                       0);
+                       0, 1);
     case RIGHT_ASSIGN:
       return
        geniCodeAssign (left,
               geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
                                                   ,FALSE),
-                                  geniCodeRValue (right, FALSE)), 0);
+                                  geniCodeRValue (right, FALSE)), 0, 1);
     case AND_ASSIGN:
       return
        geniCodeAssign (left,
@@ -4102,7 +4117,7 @@ ast2iCode (ast * tree,int lvl)
                                                  FALSE),
                                  geniCodeRValue (right, FALSE),
                                  BITWISEAND,
-                                 operandType (left)), 0);
+                                 operandType (left)), 0, 1);
     case XOR_ASSIGN:
       return
        geniCodeAssign (left,
@@ -4110,7 +4125,7 @@ ast2iCode (ast * tree,int lvl)
                                                  FALSE),
                                  geniCodeRValue (right, FALSE),
                                  '^',
-                                 operandType (left)), 0);
+                                 operandType (left)), 0, 1);
     case OR_ASSIGN:
       return
        geniCodeAssign (left,
@@ -4118,7 +4133,7 @@ ast2iCode (ast * tree,int lvl)
                                                   ,FALSE),
                                   geniCodeRValue (right, FALSE),
                                   '|',
-                                  operandType (left)), 0);
+                                  operandType (left)), 0, 1);
     case ',':
       return geniCodeRValue (right, FALSE);