MS VC6 Port
[fw/sdcc] / src / SDCCicode.c
index c405c1af6a51dd66fc18ed71a898146cf1dcd8e5..ecbb2b8da3f126b4b285b1472af7e1f5b58672de 100644 (file)
    You are forbidden to forbid anyone else to use, share and improve
    what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
-#include <stdio.h>
-#include "SDCCglobl.h"
-#include "SDCCast.h"
-#include "SDCCmem.h"
-#include "SDCCy.h"
-#include "SDCChasht.h"
-#include "SDCCicode.h"
-#include "SDCCerr.h"
-#include "SDCCralloc.h"
+
+#include "common.h"
 
 /*-----------------------------------------------------------------*/
 /* global variables       */
@@ -45,8 +38,6 @@ int block;
 int scopeLevel;
 int lvaluereq;
 
-extern int labelKey ;
-
 symbol *returnLabel ; /* function return label */
 symbol *entryLabel  ; /* function entry  label */
 /*-----------------------------------------------------------------*/
@@ -59,7 +50,6 @@ operand *geniCodeRValue (operand *, bool );
 operand *geniCodeDerefPtr (operand *);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
-
 /* forward definition of print functions */
 PRINTFUNC(picGetValueAtAddr);
 PRINTFUNC(picSetValueAtAddr);
@@ -67,8 +57,6 @@ PRINTFUNC(picAddrOf);
 PRINTFUNC(picGeneric);
 PRINTFUNC(picGenericOne);
 PRINTFUNC(picCast);
-PRINTFUNC(picIncrement);
-PRINTFUNC(picDecrement);
 PRINTFUNC(picAssign);
 PRINTFUNC(picLabel);
 PRINTFUNC(picGoto);
@@ -128,7 +116,7 @@ iCodeTable codeTable[] = {
 /*-----------------------------------------------------------------*/
 int printOperand (operand *op, FILE *file)
 {
-    link *opetype;
+    sym_link *opetype;
     int pnl = 0;
 
     if (!op)
@@ -159,12 +147,6 @@ int printOperand (operand *op, FILE *file)
                 OP_LIVEFROM(op),OP_LIVETO(op),
                 OP_SYMBOL(op)->stack,
                 op->isaddr, OP_SYMBOL(op)->isreqv,OP_SYMBOL(op)->remat
-/*              , */
-/*              OP_SYMBOL(op)->allocreq,OP_SYMBOL(op)->remat, */
-/*              OP_SYMBOL(op)->ruonly, */
-/*              OP_SYMBOL(op)->isptr,op->isaddr,OP_SYMBOL(op)->used, */
-/*              OP_SYMBOL(op)->isind, */
-/*              OP_SYMBOL(op)->accuse, op->key, OP_SYMBOL(op)->key */
                 );
        {
            fprintf(file,"{"); printTypeChain(operandType(op),file); 
@@ -191,9 +173,7 @@ int printOperand (operand *op, FILE *file)
                int i;
                fprintf(file,"[");
                for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
-                   fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ? 
-                                       OP_SYMBOL(op)->regs[i]->name :
-                                       "err"));
+                   fprintf(file,"%s ", port->getRegName(OP_SYMBOL(op)->regs[i]));
                fprintf(file,"]");
            }
        } 
@@ -560,6 +540,51 @@ void initiCode ()
 
 }
 
+/*-----------------------------------------------------------------*/
+/* copyiCode - make a copy of the iCode given                      */
+/*-----------------------------------------------------------------*/
+iCode *copyiCode (iCode *ic)
+{
+    iCode *nic = newiCode(ic->op,NULL,NULL);
+
+    nic->lineno = ic->lineno ;
+    nic->filename= ic->filename ;
+    nic->block = ic->block;
+    nic->level = ic->level;
+
+    /* deal with the special cases first */
+    switch (ic->op) {
+    case IFX:
+       IC_COND(nic) = operandFromOperand(IC_COND(ic));
+       IC_TRUE(nic) = IC_TRUE(ic);
+       IC_FALSE(nic)= IC_FALSE(ic);
+       break;
+
+    case JUMPTABLE:
+       IC_JTCOND(nic) = operandFromOperand(IC_JTCOND(ic));
+       IC_JTLABELS(nic) = IC_JTLABELS(ic);
+       break;
+
+    case CALL:
+    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:
+       IC_INLINE(nic) = IC_INLINE(ic);
+       break;
+       
+    default:
+       IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic));
+       IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic));
+       IC_RIGHT(nic)= operandFromOperand(IC_RIGHT(ic));
+    }
+
+    return nic;
+}
+
 /*-----------------------------------------------------------------*/
 /* getTableEntry - gets the table entry for the given operator     */
 /*-----------------------------------------------------------------*/
@@ -577,11 +602,11 @@ iCodeTable *getTableEntry (int oper )
 /*-----------------------------------------------------------------*/
 /* newiTempOperand - new intermediate temp operand                 */
 /*-----------------------------------------------------------------*/
-operand *newiTempOperand (link *type, char throwType)
+operand *newiTempOperand (sym_link *type, char throwType)
 {
     symbol *itmp;
     operand *op = newOperand();
-    link *etype;
+    sym_link *etype;
 
     op->type = SYMBOL ;
     itmp = newiTemp(NULL);
@@ -608,7 +633,7 @@ operand *newiTempOperand (link *type, char throwType)
 /*-----------------------------------------------------------------*/
 /* operandType - returns the type chain for an operand             */
 /*-----------------------------------------------------------------*/
-link *operandType (operand *op) 
+sym_link *operandType (operand *op) 
 {
     /* depending on type of operand */
     switch (op->type) {
@@ -621,13 +646,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 (sym_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;
 }
 
 /*-----------------------------------------------------------------*/
@@ -672,8 +697,8 @@ int isOperandGlobal ( operand *op )
 /*-----------------------------------------------------------------*/
 int isOperandVolatile ( operand *op , bool chkTemp)
 {
-    link *optype ;
-    link *opetype ;
+    sym_link *optype ;
+    sym_link *opetype ;
 
     if (IS_ITEMP(op) && !chkTemp)
        return 0;
@@ -693,7 +718,7 @@ int isOperandVolatile ( operand *op , bool chkTemp)
 /*-----------------------------------------------------------------*/
 int isOperandLiteral ( operand *op )
 {
-    link *opetype ;
+    sym_link *opetype ;
     
     if (!op)
        return 0;
@@ -710,7 +735,7 @@ int isOperandLiteral ( operand *op )
 /*-----------------------------------------------------------------*/
 bool isOperandInFarSpace (operand *op)
 {
-    link *etype;
+    sym_link *etype;
 
     if (!op)
        return FALSE;
@@ -724,9 +749,29 @@ bool isOperandInFarSpace (operand *op)
        else            
            return FALSE;
     }
+    else
+    {
+       etype = getSpec(operandType(op));
+    }
+    return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
+}
+
+/*-----------------------------------------------------------------*/
+/* isOperandOnStack - will return true if operand is on stack      */
+/*-----------------------------------------------------------------*/
+bool isOperandOnStack(operand *op)
+{
+    sym_link *etype;
+
+    if (!op)
+       return FALSE;
+
+    if (!IS_SYMOP(op))
+       return FALSE ;
 
     etype = getSpec(operandType(op));
-    return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
+
+    return ((IN_STACK(etype)) ? TRUE : FALSE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -743,7 +788,7 @@ double operandLitValue ( operand *op )
 /* operandOperation - perforoms operations on operands             */
 /*-----------------------------------------------------------------*/
 operand *operandOperation (operand *left,operand *right,
-                          int op, link *type)
+                          int op, sym_link *type)
 {
     operand *retval = (operand *)0;
         
@@ -950,13 +995,41 @@ int isiCodeEqual (iCode *left, iCode *right)
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* newiTempFromOp - create a temp Operand with same attributes     */
+/*-----------------------------------------------------------------*/
+operand *newiTempFromOp (operand *op)
+{
+    operand *nop;
+
+    if (!op)
+       return NULL;
+    
+    if (!IS_ITEMP(op))
+       return op;
+
+    nop = newiTempOperand(operandType(op),TRUE);
+    nop->isaddr = op->isaddr ;
+    nop->isvolatile = op->isvolatile ;
+    nop->isGlobal = op->isGlobal ;
+    nop->isLiteral= op->isLiteral ;
+    nop->noSpilLoc= op->noSpilLoc;
+    nop->usesDefs = op->usesDefs;
+    nop->isParm = op->isParm;
+    nop->parmBytes = op->parmBytes;
+    return nop;
+}
+
 /*-----------------------------------------------------------------*/
 /* operand from operand - creates an operand holder for the type   */
 /*-----------------------------------------------------------------*/
 operand *operandFromOperand (operand *op)
 {
-    operand *nop = newOperand();
+    operand *nop ;
     
+    if (!op)
+       return NULL;
+    nop = newOperand();
     nop->type = op->type;
     nop->isaddr = op->isaddr ;
     nop->key = op->key ;
@@ -1005,7 +1078,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)) 
@@ -1023,11 +1096,17 @@ operand *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)) &&
+       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  */
@@ -1036,8 +1115,10 @@ operand *operandFromSymbol (symbol *sym)
        !sym->reqv               &&     /* does not already have a register euivalence */
        !IS_VOLATILE(sym->etype) &&     /* not declared as volatile */
        !IS_STATIC(sym->etype)   &&     /* and not declared static  */
-       !sym->islbl              &&
-       !IN_FARSPACE(SPEC_OCLS(sym->etype))) {     /* not a label */
+       !sym->islbl              &&     /* not a label */
+       ok                       &&     /* farspace check */
+       !IS_BITVAR(sym->etype)          /* not a bit variable */
+       ) {
        
        /* we will use it after all optimizations
           and before liveRange calculation */
@@ -1048,7 +1129,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;
@@ -1110,11 +1191,11 @@ operand *operandFromValue (value *val)
 /*-----------------------------------------------------------------*/
 /* operandFromLink - operand from typeChain                        */
 /*-----------------------------------------------------------------*/
-operand *operandFromLink (link *type)
+operand *operandFromLink (sym_link *type)
 {
     operand *op ;
     
-    /* operand from link */
+    /* operand from sym_link */
     if ( ! type )
        return NULL ;
     
@@ -1163,7 +1244,7 @@ operand *operandFromAst ( ast *tree )
 /*-----------------------------------------------------------------*/
 /* setOperandType - sets the operand's type to the given type      */
 /*-----------------------------------------------------------------*/
-void setOperandType (operand *op, link *type)
+void setOperandType (operand *op, sym_link *type)
 {
     /* depending on the type of operand */
     switch (op->type) {
@@ -1198,8 +1279,8 @@ void setOperandType (operand *op, link *type)
 operand *geniCodeRValue (operand *op, bool force)
 {
     iCode *ic ;
-    link *type = operandType(op);
-    link *etype= getSpec(type);
+    sym_link *type = operandType(op);
+    sym_link *etype= getSpec(type);
     
     /* if this is an array & already */
     /* an address then return this   */
@@ -1252,12 +1333,12 @@ operand *geniCodeRValue (operand *op, bool force)
 /*-----------------------------------------------------------------*/
 /* geniCodeCast - changes the value from one type to another       */
 /*-----------------------------------------------------------------*/
-operand *geniCodeCast (link *type, operand *op, bool implicit) 
+operand *geniCodeCast (sym_link *type, operand *op, bool implicit) 
 {
     iCode *ic ;
-    link *optype ;
-    link *opetype = getSpec(optype = operandType(op));
-    link *restype ;
+    sym_link *optype ;
+    sym_link *opetype = getSpec(optype = operandType(op));
+    sym_link *restype ;
     
     /* one of them has size zero then error */
     if (IS_VOID(optype)) {
@@ -1270,7 +1351,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)));
           
@@ -1345,7 +1426,7 @@ operand *geniCodeMultiply (operand *left, operand *right)
 { 
     iCode *ic ;
     int p2 = 0;
-    link *resType ;
+    sym_link *resType ;
     LRTYPE ;
     
     /* if they are both literal then we know the result */
@@ -1382,11 +1463,11 @@ operand *geniCodeDivision (operand *left, operand *right)
 { 
     iCode *ic ;
     int p2 = 0;
-    link *resType;
-    link *rtype = operandType(right);
-    link *retype= getSpec(rtype);
-    link *ltype = operandType(left);
-    link *letype= getSpec(ltype);
+    sym_link *resType;
+    sym_link *rtype = operandType(right);
+    sym_link *retype= getSpec(rtype);
+    sym_link *ltype = operandType(left);
+    sym_link *letype= getSpec(ltype);
     
     resType = computeType (ltype,rtype) ;
     left = geniCodeCast(resType,left,TRUE);
@@ -1416,7 +1497,7 @@ operand *geniCodeDivision (operand *left, operand *right)
 operand *geniCodeModulus (operand *left, operand *right)
 { 
     iCode *ic ;
-    link *resType;
+    sym_link *resType;
     LRTYPE ;
     
     /* if they are both literal then we know the result */
@@ -1473,7 +1554,7 @@ operand *geniCodeSubtract (operand *left, operand *right)
 {
     iCode *ic ;
     int isarray= 0;
-    link *resType;
+    sym_link *resType;
     LRTYPE ;
     
     /* if they both pointers then */
@@ -1482,7 +1563,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));
     
@@ -1518,22 +1600,22 @@ operand *geniCodeSubtract (operand *left, operand *right)
 operand *geniCodeAdd (operand *left, operand *right )
 {
     iCode *ic ;
-    link *resType ;
+    sym_link *resType ;
     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 */
@@ -1542,7 +1624,12 @@ operand *geniCodeAdd (operand *left, operand *right )
        isarray = left->isaddr;
        size = 
            operandFromLit(getSize(ltype->next));
+       if (getSize(ltype) > 1 && (getSize(rtype) < INTSIZE)) 
+       {
+           right = geniCodeCast(INTTYPE,right,TRUE);       
+       }
        right = geniCodeMultiply (right ,size);
+
        resType = copyLinkChain(ltype);
     }
     else { /* make them the same size */
@@ -1552,7 +1639,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)));
     
@@ -1575,10 +1663,10 @@ operand *geniCodeAdd (operand *left, operand *right )
 /*-----------------------------------------------------------------*/
 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
 /*-----------------------------------------------------------------*/
-link *aggrToPtr ( link *type, bool force)
+sym_link *aggrToPtr ( sym_link *type, bool force)
 {
-    link *etype ;
-    link *ptype ;
+    sym_link *etype ;
+    sym_link *ptype ;
 
     
     if (IS_PTR(type) && !force)
@@ -1589,25 +1677,9 @@ link *aggrToPtr ( link *type, bool force)
 
     ptype->next = type;
     /* if the output class is generic */
-    if (SPEC_OCLS(etype) == generic)
-       DCL_TYPE(ptype) = GPOINTER;
-    else
-       if (SPEC_OCLS(etype)->codesp ) {
-           DCL_TYPE(ptype) = CPOINTER ;
-           DCL_PTR_CONST(ptype) = 1;
-       }
-       else
-           if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
-               DCL_TYPE(ptype) = FPOINTER ;
-           else
-               if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
-                   DCL_TYPE(ptype) = PPOINTER ;
-               else
-                   if (SPEC_OCLS(etype) == idata)
-                       DCL_TYPE(ptype) = IPOINTER;
-                   else
-                       DCL_TYPE(ptype) = POINTER ;
-    
+    if ((DCL_TYPE(ptype) = PTR_TYPE(SPEC_OCLS(etype))) == CPOINTER)
+       DCL_PTR_CONST(ptype) = port->mem.code_ro;
+
     /* if the variable was declared a constant */
     /* then the pointer points to a constant */
     if (IS_CONSTANT(etype) )
@@ -1624,25 +1696,13 @@ link *aggrToPtr ( link *type, bool force)
 /*-----------------------------------------------------------------*/
 operand *geniCodeArray2Ptr (operand *op)
 {
-    link *optype = operandType(op);
-    link *opetype = getSpec(optype);
-    
-    /* set the pointer depending on the storage class */
-    if (SPEC_OCLS(opetype)->codesp ) {
-       DCL_TYPE(optype) = CPOINTER ;
-       DCL_PTR_CONST(optype) = 1;
-    }
-    else
-       if (SPEC_OCLS(opetype)->fmap && !SPEC_OCLS(opetype)->paged)
-           DCL_TYPE(optype) = FPOINTER ;
-       else
-           if (SPEC_OCLS(opetype)->fmap && SPEC_OCLS(opetype)->paged)
-               DCL_TYPE(optype) = PPOINTER ;
-           else
-               if (SPEC_OCLS(opetype) == idata)
-                   DCL_TYPE(optype) = IPOINTER;
-               else
-                   DCL_TYPE(optype) = POINTER ;
+    sym_link *optype = operandType(op);
+    sym_link *opetype = getSpec(optype);
+
+    /* set the pointer depending on the storage class */    
+    if ((DCL_TYPE(optype) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
+       DCL_PTR_CONST(optype) = port->mem.code_ro;
+
     
     /* if the variable was declared a constant */
     /* then the pointer points to a constant */
@@ -1662,18 +1722,22 @@ operand *geniCodeArray2Ptr (operand *op)
 operand *geniCodeArray (operand *left,operand *right)
 {
     iCode *ic;
-    link *ltype = operandType(left);
+    sym_link *ltype = operandType(left);
     
     if (IS_PTR(ltype)) {
-       operand *r ;
-       int olval = lvaluereq ;
-       lvaluereq = IS_PTR(ltype->next);
-       r= geniCodeDerefPtr(geniCodeAdd(left,right));
-       lvaluereq = olval;
-       return r;
+       if (IS_PTR(ltype->next) && left->isaddr)
+       {
+           left = geniCodeRValue(left,FALSE);
+       }
+       return geniCodeDerefPtr(geniCodeAdd(left,right));
     }
 
-   /* array access */
+    /* array access */
+    if (getSize(operandType(right)) < INTSIZE) 
+    {
+        /* Widen the index type to int first. */
+       right = geniCodeCast(INTTYPE,right,TRUE);           
+    }
     right = geniCodeMultiply(right,
                             operandFromLit(getSize(ltype->next)));
 
@@ -1692,7 +1756,7 @@ operand *geniCodeArray (operand *left,operand *right)
                                      !IS_AGGREGATE(ltype->next) &&
                                      !IS_PTR(ltype->next))
                                     ? ltype : ltype->next),0);
-/*     IC_RESULT(ic) = newiTempOperand(ltype->next,0); */
+
     IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next));
     ADDTOCHAIN(ic);
     return IC_RESULT(ic) ;
@@ -1704,9 +1768,9 @@ operand *geniCodeArray (operand *left,operand *right)
 operand *geniCodeStruct (operand *left, operand *right, bool islval)
 {
     iCode *ic ;
-    link *type = operandType(left);
-    link *etype = getSpec(type);
-    link *retype ;
+    sym_link *type = operandType(left);
+    sym_link *etype = getSpec(type);
+    sym_link *retype ;
     symbol *element = getStructElement(SPEC_STRUCT(etype), 
                                       right->operand.symOperand);
     
@@ -1739,13 +1803,12 @@ operand *geniCodePostInc (operand *op)
 {
     iCode *ic ;
     operand *rOp ;
-    link *optype = operandType(op);
+    sym_link *optype = operandType(op);
     operand *result ;
     operand *rv = (IS_ITEMP(op) ? 
                   geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
                   op);            
-    link *rvtype = operandType(rv);    
-    int diff = (IS_PTR(rvtype) && DCL_TYPE(optype) != DCL_TYPE(rvtype));
+    sym_link *rvtype = operandType(rv);    
     int size = 0;
     
     /* if this is not an address we have trouble */
@@ -1754,7 +1817,7 @@ operand *geniCodePostInc (operand *op)
        return op ;
     }
     
-    rOp = newiTempOperand((diff ? rvtype : optype),0);
+    rOp = newiTempOperand(rvtype,0);
     rOp->noSpilLoc = 1;
 
     if (IS_ITEMP(rv))
@@ -1764,7 +1827,7 @@ operand *geniCodePostInc (operand *op)
    
     size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
     ic = newiCode('+',rv,operandFromLit(size));          
-    IC_RESULT(ic) = result =newiTempOperand((diff ? rvtype : optype),0);
+    IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
     ADDTOCHAIN(ic);
 
     geniCodeAssign(op,result,0);
@@ -1779,12 +1842,11 @@ operand *geniCodePostInc (operand *op)
 operand *geniCodePreInc (operand *op)
 {
     iCode *ic ;
-    link *optype = operandType(op);    
+    sym_link *optype = operandType(op);    
     operand *rop = (IS_ITEMP(op) ? 
                    geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
                    op);
-    link *roptype = operandType(rop);
-    int diff = (IS_PTR(roptype) && (DCL_TYPE(roptype) != DCL_TYPE(optype)));
+    sym_link *roptype = operandType(rop);
     operand *result;
     int size = 0;
     
@@ -1796,7 +1858,7 @@ operand *geniCodePreInc (operand *op)
 
     size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
     ic = newiCode('+',rop,operandFromLit(size));
-    IC_RESULT(ic) = result = newiTempOperand((diff ? roptype : optype),0) ;
+    IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
     ADDTOCHAIN(ic);
 
     
@@ -1810,13 +1872,12 @@ operand *geniCodePostDec (operand *op)
 {
     iCode *ic ;
     operand *rOp ;
-    link *optype = operandType(op);
+    sym_link *optype = operandType(op);
     operand *result ;
     operand *rv = (IS_ITEMP(op) ? 
                   geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
                   op);            
-    link *rvtype = operandType(rv);    
-    int diff = (IS_PTR(rvtype) && DCL_TYPE(optype) != DCL_TYPE(rvtype));
+    sym_link *rvtype = operandType(rv);    
     int size = 0;
     
     /* if this is not an address we have trouble */
@@ -1825,7 +1886,7 @@ operand *geniCodePostDec (operand *op)
        return op ;
     }
     
-    rOp = newiTempOperand((diff ? rvtype : optype),0);
+    rOp = newiTempOperand(rvtype,0);
     rOp->noSpilLoc = 1;
 
     if (IS_ITEMP(rv))
@@ -1835,7 +1896,7 @@ operand *geniCodePostDec (operand *op)
    
     size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
     ic = newiCode('-',rv,operandFromLit(size));          
-    IC_RESULT(ic) = result =newiTempOperand((diff ? rvtype : optype),0);
+    IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
     ADDTOCHAIN(ic);
 
     geniCodeAssign(op,result,0);
@@ -1850,12 +1911,11 @@ operand *geniCodePostDec (operand *op)
 operand *geniCodePreDec (operand *op)
 {  
     iCode *ic ;
-    link *optype = operandType(op);    
+    sym_link *optype = operandType(op);    
     operand *rop = (IS_ITEMP(op) ? 
                    geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
                    op);
-    link *roptype = operandType(rop);
-    int diff = (IS_PTR(roptype) && (DCL_TYPE(roptype) != DCL_TYPE(optype)));
+    sym_link *roptype = operandType(rop);
     operand *result;
     int size = 0;
     
@@ -1867,7 +1927,7 @@ operand *geniCodePreDec (operand *op)
 
     size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
     ic = newiCode('-',rop,operandFromLit(size));
-    IC_RESULT(ic) = result = newiTempOperand((diff ? roptype : optype),0) ;
+    IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
     ADDTOCHAIN(ic);
 
     
@@ -1879,7 +1939,7 @@ operand *geniCodePreDec (operand *op)
 /* geniCodeBitwise - gen int code for bitWise  operators           */
 /*-----------------------------------------------------------------*/
 operand *geniCodeBitwise (operand *left, operand *right, 
-                         int oper, link *resType)
+                         int oper, sym_link *resType)
 {
     iCode *ic;   
     
@@ -1899,39 +1959,24 @@ operand *geniCodeBitwise (operand *left, operand *right,
 operand *geniCodeAddressOf (operand *op) 
 {
     iCode *ic;
-    link *p ;
-    link *optype = operandType(op);
-    link *opetype= getSpec(optype);
+    sym_link *p ;
+    sym_link *optype = operandType(op);
+    sym_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 (SPEC_OCLS(opetype)->codesp ) {
-       DCL_TYPE(p) = CPOINTER ;
-       DCL_PTR_CONST(p) = 1;
-    }
-    else
-       if (SPEC_OCLS(opetype)->fmap && !SPEC_OCLS(opetype)->paged)
-           DCL_TYPE(p) = FPOINTER ;
-       else
-           if (SPEC_OCLS(opetype)->fmap && SPEC_OCLS(opetype)->paged)
-               DCL_TYPE(p) = PPOINTER ;
-           else
-               if (SPEC_OCLS(opetype) == idata)
-                   DCL_TYPE(p) = IPOINTER;
-               else
-                   if (SPEC_OCLS(opetype) == data ||
-                       SPEC_OCLS(opetype) == overlay)
-                       DCL_TYPE(p) = POINTER ;
-                   else
-                       DCL_TYPE(p) = GPOINTER;
     
+    /* set the pointer depending on the storage class */
+    if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
+       DCL_PTR_CONST(p) = port->mem.code_ro;
+
     /* make sure we preserve the const & volatile */
     if (IS_CONSTANT(opetype)) 
        DCL_PTR_CONST(p) = 1;
@@ -1958,7 +2003,7 @@ operand *geniCodeAddressOf (operand *op)
 /*-----------------------------------------------------------------*/
 /* setOClass - sets the output class depending on the pointer type */
 /*-----------------------------------------------------------------*/
-void setOClass (link *ptr, link *spec)
+void setOClass (sym_link *ptr, sym_link *spec)
 {
     switch (DCL_TYPE(ptr)) {
     case POINTER:
@@ -1984,7 +2029,14 @@ void setOClass (link *ptr, link *spec)
     case PPOINTER:
        SPEC_OCLS(spec) = xstack;
        break;
-       
+
+    case EEPPOINTER:
+       SPEC_OCLS(spec) = eeprom;
+       break;
+
+    default:
+       break;
+
     }
 }
 
@@ -1993,8 +2045,8 @@ void setOClass (link *ptr, link *spec)
 /*-----------------------------------------------------------------*/
 operand *geniCodeDerefPtr (operand *op)
 {    
-    link *rtype , *retype ;
-    link *optype = operandType(op);  
+    sym_link *rtype , *retype ;
+    sym_link *optype = operandType(op);  
 
     /* if this is a pointer then generate the rvalue */
     if (IS_PTR(optype)) {
@@ -2007,16 +2059,19 @@ operand *geniCodeDerefPtr (operand *op)
     }
     
     /* now get rid of the pointer part */
-    if (lvaluereq && IS_ITEMP(op))
+    if (lvaluereq && IS_ITEMP(op) )
+    {
        retype = getSpec(rtype = copyLinkChain(optype)) ;
+    }
     else
+    {
        retype = getSpec(rtype = copyLinkChain(optype->next)) ;
+    }
     
     /* if this is a pointer then outputclass needs 2b updated */
     if (IS_PTR(optype)) 
        setOClass(optype,retype);    
         
-    op = geniCodeRValue(op,TRUE);
     op->isGptr = IS_GENPTR(optype);
 
     /* if the pointer was declared as a constant */
@@ -2024,13 +2079,16 @@ operand *geniCodeDerefPtr (operand *op)
     if (IS_PTR_CONST(optype))
        SPEC_CONST(retype) = 1;
     
-
-    setOperandType(op,rtype);
     op->isaddr = (IS_PTR(rtype)    ||
                  IS_STRUCT(rtype) || 
                  IS_INT(rtype)    ||
                  IS_CHAR(rtype)   ||
                  IS_FLOAT(rtype) );
+
+    if (!lvaluereq)
+       op = geniCodeRValue(op,TRUE);
+
+    setOperandType(op,rtype);
     
     return op;    
 }
@@ -2041,7 +2099,7 @@ operand *geniCodeDerefPtr (operand *op)
 operand *geniCodeUnaryMinus (operand *op)
 {
     iCode *ic ;
-    link *optype = operandType(op);
+    sym_link *optype = operandType(op);
     
     if (IS_LITERAL(optype))
        return operandFromLit(- floatFromVal(op->operand.valOperand));
@@ -2058,7 +2116,7 @@ operand *geniCodeUnaryMinus (operand *op)
 operand *geniCodeLeftShift (operand *left, operand *right)
 { 
     iCode *ic;
-    link *ltype = operandType(left);
+    sym_link *ltype = operandType(left);
     
     ic = newiCode(LEFT_OP,left,right);
     IC_RESULT(ic) = newiTempOperand(ltype,0);
@@ -2072,7 +2130,7 @@ operand *geniCodeLeftShift (operand *left, operand *right)
 operand *geniCodeRightShift (operand *left, operand *right)
 { 
     iCode *ic;
-    link *ltype = operandType(left);
+    sym_link *ltype = operandType(left);
     
     ic = newiCode(RIGHT_OP,left,right);
     IC_RESULT(ic) = newiTempOperand(ltype,0);
@@ -2080,15 +2138,21 @@ operand *geniCodeRightShift (operand *left, operand *right)
     return IC_RESULT(ic) ;  
 }
 
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define LONG_LONG __int64
+#else
+#define LONG_LONG long long
+#endif
+
 /*-----------------------------------------------------------------*/
 /* geniCodeLogic- logic code                                       */
 /*-----------------------------------------------------------------*/
 operand *geniCodeLogic (operand *left, operand *right, int op )
 {
     iCode *ic ;
-    link *ctype; 
-    link *rtype = operandType(right);
-    link *ltype = operandType(left);
+    sym_link *ctype; 
+    sym_link *rtype = operandType(right);
+    sym_link *ltype = operandType(left);
     
     /* left is integral type and right is literal then
        check if the literal value is within bounds */
@@ -2096,7 +2160,7 @@ operand *geniCodeLogic (operand *left, operand *right, int op )
        int nbits = bitsForType(ltype);
        long v = operandLitValue(right);
 
-       if (v > ((long long) 1 << nbits) && v > 0)
+       if (v > ((LONG_LONG) 1 << nbits) && v > 0)
            werror(W_CONST_RANGE," compare operation ");
     }
 
@@ -2175,8 +2239,8 @@ operand *geniCodeConditional (ast *tree)
 operand *geniCodeAssign (operand *left, operand *right, int nosupdate)
 {
     iCode *ic ;
-    link *ltype = operandType(left);
-    link *rtype = operandType(right);
+    sym_link *ltype = operandType(left);
+    sym_link *rtype = operandType(right);
     
     if (!left->isaddr && !IS_ITEMP(left)) {
        werror(E_LVALUE_REQUIRED,"assignment");
@@ -2185,13 +2249,14 @@ 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);
 
-       if (v > ((long long)1 << nbits) && v > 0)
+       if (v > ((LONG_LONG)1 << nbits) && v > 0)
            werror(W_CONST_RANGE," = operation");
     }
+
     /* if the left & right type don't exactly match */
     /* if pointer set then make sure the check is
        done with the type & not the pointer */
@@ -2262,7 +2327,7 @@ static void geniCodeSEParms (ast *parms)
        parms->right->left->lvalue = 1;
 
     parms->opval.oprnd = 
-       geniCodeRValue(ast2iCode (parms),TRUE);   
+       geniCodeRValue(ast2iCode (parms),FALSE);
    
     parms->type = EX_OPERAND ;
 }
@@ -2270,7 +2335,7 @@ static void geniCodeSEParms (ast *parms)
 /*-----------------------------------------------------------------*/
 /* geniCodeParms - generates parameters                            */
 /*-----------------------------------------------------------------*/
-static void geniCodeParms ( ast *parms , int *stack, link *fetype)
+static void geniCodeParms ( ast *parms , int *stack, sym_link *fetype, symbol *func)
 {
     iCode *ic ;
     operand *pval ; 
@@ -2280,8 +2345,8 @@ static void geniCodeParms ( ast *parms , int *stack, link *fetype)
     
     /* if this is a param node then do the left & right */
     if (parms->type == EX_OP && parms->opval.op == PARAM) {
-       geniCodeParms (parms->left, stack,fetype) ;
-       geniCodeParms (parms->right, stack,fetype);
+       geniCodeParms (parms->left, stack,fetype,func) ;
+       geniCodeParms (parms->right, stack,fetype,func);
        return ;
     }
     
@@ -2304,8 +2369,8 @@ static void geniCodeParms ( ast *parms , int *stack, link *fetype)
     }
 
     /* if register parm then make it a send */
-    if ((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
-       IS_REGPARM(parms->etype)) {
+    if (((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
+       IS_REGPARM(parms->etype)) && !func->hasVargs ) {
        ic = newiCode(SEND,pval,NULL);
        ADDTOCHAIN(ic);
     } else {
@@ -2317,12 +2382,12 @@ static void geniCodeParms ( ast *parms , int *stack, link *fetype)
            geniCodeAssign(top,pval,1);
        }
        else { 
-
+           sym_link *p = operandType(pval);
            /* push */
            ic = newiCode(IPUSH,pval,NULL);
            ic->parmPush = 1;
            /* update the stack adjustment */
-           *stack += getSize(operandType(pval));
+           *stack += getSize(IS_AGGREGATE(p)? aggrToPtr(p,FALSE):p);
            ADDTOCHAIN(ic);
        }
     }
@@ -2336,7 +2401,7 @@ operand *geniCodeCall (operand *left, ast *parms)
 { 
     iCode *ic ;
     operand *result ;
-    link *type, *etype;
+    sym_link *type, *etype;
     int stack = 0 ;
     
     /* take care of parameters with side-effecting
@@ -2345,7 +2410,7 @@ operand *geniCodeCall (operand *left, ast *parms)
     geniCodeSEParms ( parms );
 
     /* first the parameters */
-    geniCodeParms ( parms , &stack , getSpec(operandType(left)));
+    geniCodeParms ( parms , &stack , getSpec(operandType(left)), OP_SYMBOL(left));
     
     /* now call : if symbol then pcall */
     if (IS_ITEMP(left)) 
@@ -2383,16 +2448,20 @@ 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 &&
+                  !IS_DS390_PORT) {
+               } 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);
@@ -2412,7 +2481,7 @@ void geniCodeFunctionBody (ast *tree)
 {
     iCode *ic ;
     operand *func ;
-    link *fetype  ;
+    sym_link *fetype  ;
     int savelineno ;
     
     /* reset the auto generation */
@@ -2477,8 +2546,7 @@ void geniCodeIfx (ast *tree)
 {
     iCode *ic;
     operand *condition = ast2iCode(tree->left);
-/*     link *ctype = operandType(condition);     */
-    link *cetype; 
+    sym_link *cetype; 
     
     /* if condition is null then exit */
     if (!condition)
@@ -2581,7 +2649,7 @@ int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree)
     /* first we rule out the boundary conditions */
     /* if only optimization says so */
     if ( ! optimize.noJTabBoundary ) {
-       link *cetype = getSpec(operandType(cond));
+       sym_link *cetype = getSpec(operandType(cond));
        /* no need to check the lower bound if
           the condition is unsigned & minimum value is zero */
        if (!( min == 0  && SPEC_USIGN(cetype))) {
@@ -2599,7 +2667,7 @@ int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree)
     /* if the min is not zero then we no make it zero */
     if (min) {
        cond = geniCodeSubtract(cond,operandFromLit(min));
-       setOperandType(cond,ucharType);
+       setOperandType(cond, UCHARTYPE);
     }
 
     /* now create the jumptable */
@@ -2714,14 +2782,36 @@ operand *ast2iCode (ast *tree)
         tree->opval.op != SWITCH &&
         tree->opval.op != FUNCTION &&
         tree->opval.op != INLINEASM ) {
-       if (IS_ASSIGN_OP(tree->opval.op) || IS_DEREF_OP(tree)) {
+
+       if (IS_ASSIGN_OP(tree->opval.op) || 
+           IS_DEREF_OP(tree)            || 
+           (tree->opval.op == '&' && !tree->right) ||
+           tree->opval.op == PTR_OP) {
+           lvaluereq++;
+           if ((IS_ARRAY_OP(tree->left) && IS_ARRAY_OP(tree->left->left)) ||
+               (IS_DEREF_OP(tree) && IS_ARRAY_OP(tree->left)))
+           {
+               int olvr = lvaluereq ;
+               lvaluereq = 0;
+               left = operandFromAst(tree->left);
+               lvaluereq = olvr - 1;
+           } else {
+               left = operandFromAst(tree->left);
+               lvaluereq--;
+           }
+           if (IS_DEREF_OP(tree) && IS_DEREF_OP(tree->left))
+                   left = geniCodeRValue(left,TRUE);
+       } else {
+           left =  operandFromAst(tree->left);
+       }
+       if (tree->opval.op == INC_OP || 
+           tree->opval.op == DEC_OP) {
            lvaluereq++;
-           left = operandFromAst(tree->left);
+           right= operandFromAst(tree->right);
            lvaluereq--;
        } else {
-           left =  operandFromAst(tree->left);
+           right= operandFromAst(tree->right);
        }
-       right= operandFromAst(tree->right);
     }
     
     /* now depending on the type of operand */
@@ -2729,8 +2819,11 @@ operand *ast2iCode (ast *tree)
     switch (tree->opval.op) {
        
     case '[' :    /* array operation */
-       left= geniCodeRValue (left,FALSE);
-       right=geniCodeRValue (right,TRUE);                 
+       {
+           sym_link *ltype = operandType(left);
+           left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE);
+           right=geniCodeRValue (right,TRUE);             
+       }
        
        return geniCodeArray (left,right);
        
@@ -2744,7 +2837,7 @@ operand *ast2iCode (ast *tree)
        
     case PTR_OP: /* structure pointer dereference */
        {
-           link *pType;
+           sym_link *pType;
            pType = operandType(left);
            left = geniCodeRValue(left,TRUE);
            
@@ -2828,7 +2921,7 @@ operand *ast2iCode (ast *tree)
     case GETHBIT:
        {
            operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
-           setOperandType(op,ucharType);
+           setOperandType(op, UCHARTYPE);
            return op;
        }
     case '>' :
@@ -2850,8 +2943,8 @@ operand *ast2iCode (ast *tree)
        
     case '='        :
        {
-           link *rtype = operandType(right);
-           link *ltype = operandType(left);
+           sym_link *rtype = operandType(right);
+           sym_link *ltype = operandType(left);
            if (IS_PTR(rtype) && IS_ITEMP(right) 
                && right->isaddr && checkType(rtype->next,ltype)==1)
                right =  geniCodeRValue(right,TRUE);
@@ -2882,8 +2975,8 @@ operand *ast2iCode (ast *tree)
                                           geniCodeRValue(right,FALSE)),0);
     case ADD_ASSIGN: 
        {
-           link *rtype = operandType(right);
-           link *ltype = operandType(left);
+           sym_link *rtype = operandType(right);
+           sym_link *ltype = operandType(left);
            if (IS_PTR(rtype) && IS_ITEMP(right) 
                && right->isaddr && checkType(rtype->next,ltype)==1)
                right =  geniCodeRValue(right,TRUE);
@@ -2898,8 +2991,8 @@ operand *ast2iCode (ast *tree)
        }
     case SUB_ASSIGN:
        {
-           link *rtype = operandType(right);
-           link *ltype = operandType(left);
+           sym_link *rtype = operandType(right);
+           sym_link *ltype = operandType(left);
            if (IS_PTR(rtype) && IS_ITEMP(right) 
                && right->isaddr && checkType(rtype->next,ltype)==1) {
                right =  geniCodeRValue(right,TRUE);