fixed the array bug
[fw/sdcc] / src / SDCCicode.c
index 90cfe1a8e27a25f30e767864ca35e7e89fbd2243..ec5a26c6f75c9e1b9ffda09459bdafb64cd640ef 100644 (file)
@@ -648,12 +648,13 @@ link *operandType (operand *op)
        
     case TYPE :
        return op->operand.typeOperand ;
+    default:
+       werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
+               " operand type not known ");
+       assert (0) ; /* should never come here */
+       /*  Just to keep the compiler happy */
+       return (link *)0;
     }
-    werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
-           " operand type not known ");
-    assert (0) ; /* should never come here */
-    /*  Just to keep the compiler happy */
-    return (link *)0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1059,7 +1060,7 @@ operand *operandFromSymbol (symbol *sym)
 {
     operand *op ;
     iCode *ic ;
-    
+    int ok =1 ;
     /* if the symbol's type is a literal */
     /* then it is an enumerator type     */
     if (IS_LITERAL(sym->etype) && SPEC_ENUM(sym->etype)) 
@@ -1083,6 +1084,11 @@ operand *operandFromSymbol (symbol *sym)
     
     /* 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))  &&
+       options.stackAuto == 0)
+       ok =0;
+
     if (!IS_AGGREGATE(sym->type) &&     /* not an aggregate */
        !IS_FUNC(sym->type)      &&     /* not a function   */
        !sym->_isparm            &&     /* not a parameter  */
@@ -1092,7 +1098,7 @@ operand *operandFromSymbol (symbol *sym)
        !IS_VOLATILE(sym->etype) &&     /* not declared as volatile */
        !IS_STATIC(sym->etype)   &&     /* and not declared static  */
        !sym->islbl              &&     /* not a label */
-       !IN_FARSPACE(SPEC_OCLS(sym->etype)) && /* not in far space */
+       ok                       &&     /* farspace check */
        !IS_BITVAR(sym->etype)          /* not a bit variable */
        ) {
        
@@ -1105,7 +1111,7 @@ operand *operandFromSymbol (symbol *sym)
        OP_SYMBOL(sym->reqv)->islocal = 1;
        SPIL_LOC(sym->reqv) = sym;
     }
-
+   
     if (!IS_AGGREGATE(sym->type)) {
        op = newOperand();
        op->type = SYMBOL;
@@ -1327,7 +1333,7 @@ operand *geniCodeCast (link *type, operand *op, bool implicit)
        return op;
     
     /* if this is a literal then just change the type & return */
-    if (IS_LITERAL(opetype) && !IS_PTR(type) && !IS_PTR(optype))
+    if (IS_LITERAL(opetype) && op->type == VALUE && !IS_PTR(type) && !IS_PTR(optype))
        return operandFromValue(valCastLiteral(type,
                                               operandLitValue(op)));
           
@@ -1539,7 +1545,8 @@ operand *geniCodeSubtract (operand *left, operand *right)
        return geniCodePtrPtrSubtract (left,right);
     
     /* if they are both literal then we know the result */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype)) 
+    if (IS_LITERAL(letype) && IS_LITERAL(retype)
+       && left->isLiteral && right->isLiteral) 
        return operandFromValue (valMinus(left->operand.valOperand,
                                          right->operand.valOperand));
     
@@ -1579,18 +1586,18 @@ operand *geniCodeAdd (operand *left, operand *right )
     operand *size ;
     int isarray = 0;
     LRTYPE ;
-    
+
     /* if left is an array then array access */
     if (IS_ARRAY(ltype)) 
        return geniCodeArray (left,right);           
     
     /* if the right side is LITERAL zero */
     /* return the left side              */
-    if (IS_LITERAL(retype) && !floatFromVal(valFromType(retype)))
+    if (IS_LITERAL(retype) && right->isLiteral && !floatFromVal(valFromType(retype)))
        return left;
     
     /* if left is literal zero return right */
-    if (IS_LITERAL(letype) && !floatFromVal(valFromType(letype)))
+    if (IS_LITERAL(letype) && left->isLiteral && !floatFromVal(valFromType(letype)))
        return right ;
     
     /* if left is an array or pointer then size */
@@ -1609,7 +1616,8 @@ operand *geniCodeAdd (operand *left, operand *right )
     }
     
     /* if they are both literals then we know */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype))
+    if (IS_LITERAL(letype) && IS_LITERAL(retype)
+       && left->isLiteral && right->isLiteral)
        return operandFromValue (valPlus(valFromType(letype),
                                         valFromType(retype)));
     
@@ -1647,7 +1655,7 @@ link *aggrToPtr ( link *type, bool force)
     ptype->next = type;
     /* if the output class is generic */
     if ((DCL_TYPE(ptype) = PTR_TYPE(SPEC_OCLS(etype))) == CPOINTER)
-       DCL_PTR_CONST(ptype) = 1;
+       DCL_PTR_CONST(ptype) = port->mem.code_ro;
 
     /* if the variable was declared a constant */
     /* then the pointer points to a constant */
@@ -1670,7 +1678,7 @@ operand *geniCodeArray2Ptr (operand *op)
 
     /* set the pointer depending on the storage class */    
     if ((DCL_TYPE(optype) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
-       DCL_PTR_CONST(optype) = 1;
+       DCL_PTR_CONST(optype) = port->mem.code_ro;
 
     
     /* if the variable was declared a constant */
@@ -1925,18 +1933,19 @@ operand *geniCodeAddressOf (operand *op)
     link *optype = operandType(op);
     link *opetype= getSpec(optype);
     
+    /* lvalue check already done in decorateType */
     /* this must be a lvalue */
-    if (!op->isaddr && !IS_AGGREGATE(optype)) {
-       werror (E_LVALUE_REQUIRED,"&");
-       return op;
-    }
+/*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
+/*     werror (E_LVALUE_REQUIRED,"&"); */
+/*     return op; */
+/*     } */
     
     p = newLink();
     p->class = DECLARATOR ;
     
     /* set the pointer depending on the storage class */
     if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
-       DCL_PTR_CONST(p) = 1;
+       DCL_PTR_CONST(p) = port->mem.code_ro;
 
     /* make sure we preserve the const & volatile */
     if (IS_CONSTANT(opetype)) 
@@ -1990,6 +1999,14 @@ void setOClass (link *ptr, link *spec)
     case PPOINTER:
        SPEC_OCLS(spec) = xstack;
        break;
+
+    case EEPPOINTER:
+       SPEC_OCLS(spec) = eeprom;
+       break;
+
+    default:
+       break;
+
     }
 }
 
@@ -2202,7 +2219,7 @@ operand *geniCodeAssign (operand *left, operand *right, int nosupdate)
        
     /* left is integral type and right is literal then
        check if the literal value is within bounds */
-    if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) {
+    if (IS_INTEGRAL(ltype) && right->type == VALUE && IS_LITERAL(rtype)) {
        int nbits = bitsForType(ltype);
        long v = operandLitValue(right);
 
@@ -2401,16 +2418,19 @@ static void geniCodeReceive (value *args)
 
            /* we will use it after all optimizations
               and before liveRange calculation */          
-           if (!sym->addrtaken && 
-               !IS_VOLATILE(sym->etype) &&
-               !IN_FARSPACE(SPEC_OCLS(sym->etype))) {
-               opl = newiTempOperand(args->type,0);
-               sym->reqv = opl ;           
-               sym->reqv->key = sym->key ;
-               OP_SYMBOL(sym->reqv)->key = sym->key;
-               OP_SYMBOL(sym->reqv)->isreqv = 1;
-               OP_SYMBOL(sym->reqv)->islocal= 0;
-               SPIL_LOC(sym->reqv) =  sym;
+           if (!sym->addrtaken && !IS_VOLATILE(sym->etype)) {
+
+               if(IN_FARSPACE(SPEC_OCLS(sym->etype)) &&
+                  options.stackAuto == 0) {
+               } else {
+                   opl = newiTempOperand(args->type,0);
+                   sym->reqv = opl ;       
+                   sym->reqv->key = sym->key ;
+                   OP_SYMBOL(sym->reqv)->key = sym->key;
+                   OP_SYMBOL(sym->reqv)->isreqv = 1;
+                   OP_SYMBOL(sym->reqv)->islocal= 0;
+                   SPIL_LOC(sym->reqv) =  sym;
+               }
            }
 
            ic = newiCode(RECEIVE,NULL,NULL);
@@ -2736,8 +2756,13 @@ operand *ast2iCode (ast *tree)
            (tree->opval.op == '&' && !tree->right) ||
            tree->opval.op == PTR_OP) {
            lvaluereq++;
-           left = operandFromAst(tree->left);
-           lvaluereq--;
+           if (IS_ARRAY_OP(tree->left) && IS_ARRAY_OP(tree->left->left)) {
+               lvaluereq--;
+               left = operandFromAst(tree->left);
+           } else {
+               left = operandFromAst(tree->left);
+               lvaluereq--;
+           }
        } else {
            left =  operandFromAst(tree->left);
        }
@@ -2756,8 +2781,11 @@ operand *ast2iCode (ast *tree)
     switch (tree->opval.op) {
        
     case '[' :    /* array operation */
-       left= geniCodeRValue (left,TRUE);
-       right=geniCodeRValue (right,TRUE);                 
+       {
+           link *ltype = operandType(left);
+           left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE);
+           right=geniCodeRValue (right,TRUE);             
+       }
        
        return geniCodeArray (left,right);