whoops! disabled varargs parameter upcasting by mistake in last commit
[fw/sdcc] / src / SDCCicode.c
index 941cbb78b833907bbb76b49a5d64a8b233ad2aa1..9d82ef56774d4535b0054d1087ef8637509f87e8 100644 (file)
@@ -116,7 +116,7 @@ iCodeTable codeTable[] = {
 /*-----------------------------------------------------------------*/
 int printOperand (operand *op, FILE *file)
 {
-    link *opetype;
+    sym_link *opetype;
     int pnl = 0;
 
     if (!op)
@@ -602,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);
@@ -633,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) {
@@ -651,7 +651,7 @@ link *operandType (operand *op)
                " operand type not known ");
        assert (0) ; /* should never come here */
        /*  Just to keep the compiler happy */
-       return (link *)0;
+       return (sym_link *)0;
     }
 }
 
@@ -697,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;
@@ -718,7 +718,7 @@ int isOperandVolatile ( operand *op , bool chkTemp)
 /*-----------------------------------------------------------------*/
 int isOperandLiteral ( operand *op )
 {
-    link *opetype ;
+    sym_link *opetype ;
     
     if (!op)
        return 0;
@@ -735,7 +735,7 @@ int isOperandLiteral ( operand *op )
 /*-----------------------------------------------------------------*/
 bool isOperandInFarSpace (operand *op)
 {
-    link *etype;
+    sym_link *etype;
 
     if (!op)
        return FALSE;
@@ -756,6 +756,24 @@ bool isOperandInFarSpace (operand *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_STACK(etype)) ? TRUE : FALSE);
+}
+
 /*-----------------------------------------------------------------*/
 /* operandLitValue - literal value of an operand                   */
 /*-----------------------------------------------------------------*/
@@ -770,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;
         
@@ -1173,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 ;
     
@@ -1226,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) {
@@ -1254,6 +1272,143 @@ void setOperandType (operand *op, link *type)
     
 }
 
+/*-----------------------------------------------------------------*/
+/* perform "usual unary conversions"                               */
+/*-----------------------------------------------------------------*/
+operand *usualUnaryConversions(operand *op)
+{
+    if (IS_INTEGRAL(operandType(op)))
+    {
+        if (getSize(operandType(op)) < INTSIZE) 
+        {
+            /* Widen to int. */
+           return geniCodeCast(INTTYPE,op,TRUE);           
+        }    
+    }
+    return op;
+}
+
+/*-----------------------------------------------------------------*/
+/* perform "usual binary conversions"                              */
+/*-----------------------------------------------------------------*/
+sym_link * usualBinaryConversions(operand **op1, operand **op2)
+{
+    if (!options.ANSIint)
+    {
+       /* "Classic" SDCC behavior. */
+       sym_link *ctype; 
+       sym_link *rtype = operandType(*op2);
+       sym_link *ltype = operandType(*op1);
+         
+       ctype = computeType(ltype,rtype);                             
+       *op1 = geniCodeCast(ctype,*op1,TRUE);
+       *op2= geniCodeCast(ctype,*op2,TRUE);
+    
+       return ctype;
+    }
+    
+    *op1 = usualUnaryConversions(*op1);
+    *op2 = usualUnaryConversions(*op2);
+
+    /* Try to make the two operands of the same type, following
+     * the "usual binary conversions" promotion rules.
+     *
+     * NB: floating point types are not yet properly handled; we
+     * follow the "classic" behavior.
+     */    
+     
+    if (IS_FLOAT(operandType(*op1)) || IS_FLOAT(operandType(*op2)))
+    {
+       return newFloatLink();     
+    }
+     
+    if (!IS_INTEGRAL(operandType(*op1)) || !IS_INTEGRAL(operandType(*op2)))
+    {
+        /* if either is not an integer type, we're done. */
+        return copyLinkChain(operandType(*op1)); /* Punt! we should never get here. */
+    }
+    
+    /* If either is an unsigned long, make sure both are. */
+    if (SPEC_USIGN(operandType(*op1)) && IS_LONG(operandType(*op1)))
+    {
+        if (!SPEC_USIGN(operandType(*op2)) || !IS_LONG(operandType(*op2)))
+        {
+             *op2 = geniCodeCast(ULONGTYPE,*op2,TRUE);
+        }
+        return copyLinkChain(operandType(*op1));
+    }
+    
+    if (SPEC_USIGN(operandType(*op2)) && IS_LONG(operandType(*op2)))
+    {
+        if (!SPEC_USIGN(operandType(*op1)) || !IS_LONG(operandType(*op1)))
+        {
+             *op1 = geniCodeCast(ULONGTYPE,*op1,TRUE);
+        }
+        return copyLinkChain(operandType(*op2));
+    }    
+    
+    /* Next, if one is long and the other is int (signed or un), 
+     * cast both to long.
+     *
+     * Note that because in our environment a long can hold all 
+     * the values of an unsigned int, the "long/unsigned int" pair
+     * in the ANSI conversion table is unnecessary; this test
+     * handles that case implicitly.
+     */
+    if (IS_LONG(operandType(*op1)))
+    {
+        /* NB: because of the unary conversions, op2 cannot
+         * be smaller than int. Therefore, if it is not
+         * long, it is a regular int.
+         */
+        if (!IS_LONG(operandType(*op2)))
+        {
+             *op2 = geniCodeCast(LONGTYPE,*op2,TRUE);
+        }
+        return copyLinkChain(operandType(*op1));
+    }
+    
+    if (IS_LONG(operandType(*op2)))
+    {
+        /* NB: because of the unary conversions, op2 cannot
+         * be smaller than int. Therefore, if it is not
+         * long, it is a regular int.
+         */    
+        if (!IS_LONG(operandType(*op1)))
+        {
+             *op1 = geniCodeCast(LONGTYPE,*op1,TRUE);
+        }
+        return copyLinkChain(operandType(*op2));
+    }     
+         
+    /* All right, neither is long; they must both be integers.
+     *
+     * Only remaining issue is signed vs. unsigned; if one is unsigned
+     * and the other isn't, convert both to unsigned.
+     */
+    if (SPEC_USIGN(operandType(*op1)))
+    {
+        if (!SPEC_USIGN(operandType(*op2)))
+        {
+             *op2 = geniCodeCast(UINTTYPE,*op2,TRUE);
+        }
+        return copyLinkChain(operandType(*op1));
+    }
+    
+    if (SPEC_USIGN(operandType(*op2)))
+    {
+        if (!SPEC_USIGN(operandType(*op1)))
+        {
+             *op1 = geniCodeCast(UINTTYPE,*op1,TRUE);
+        }
+        return copyLinkChain(operandType(*op2));
+    }         
+    
+    /* Done! */
+    return copyLinkChain(operandType(*op1));
+}
+
+
 /*-----------------------------------------------------------------*/
 /* geniCodeValueAtAddress - generate intermeditate code for value  */
 /*                          at address                             */
@@ -1261,8 +1416,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   */
@@ -1277,7 +1432,7 @@ operand *geniCodeRValue (operand *op, bool force)
     
     /* if this is not a temp symbol then */
     if (!IS_ITEMP(op) && 
-       !force        && 
+       !force && 
        !IN_FARSPACE(SPEC_OCLS(etype))) {
        op = operandFromOperand(op);
        op->isaddr = 0;
@@ -1286,7 +1441,7 @@ operand *geniCodeRValue (operand *op, bool force)
     
     if (IS_SPEC(type) && 
        IS_TRUE_SYMOP(op) &&
-       !IN_FARSPACE(SPEC_OCLS(etype))) {
+       (!IN_FARSPACE(SPEC_OCLS(etype)) || IS_DS390_PORT)) {
        op = operandFromOperand(op);
        op->isaddr = 0;
        return op;
@@ -1315,12 +1470,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)) {
@@ -1408,7 +1563,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 */
@@ -1416,9 +1571,7 @@ operand *geniCodeMultiply (operand *left, operand *right)
        return operandFromValue (valMult(left->operand.valOperand,
                                         right->operand.valOperand));
         
-    resType = computeType (ltype,rtype) ;
-    left = geniCodeCast(resType,left,TRUE);
-    right= geniCodeCast(resType,right,TRUE);
+    resType = usualBinaryConversions(&left, &right);
     
     /* if the right is a literal & power of 2 */
     /* then make it a left shift              */
@@ -1445,15 +1598,13 @@ 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);
-    right= geniCodeCast(resType,right,TRUE);
+    resType = usualBinaryConversions(&left, &right);
     
     /* if the right is a literal & power of 2 */
     /* then make it a right shift             */
@@ -1479,7 +1630,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 */
@@ -1487,9 +1638,7 @@ operand *geniCodeModulus (operand *left, operand *right)
        return operandFromValue (valMod(left->operand.valOperand,
                                        right->operand.valOperand));
     
-    resType = computeType (ltype,rtype) ;
-    left = geniCodeCast(resType,left,TRUE);
-    right= geniCodeCast(resType,right,TRUE);
+    resType = usualBinaryConversions(&left, &right);
     
     /* now they are the same size */
     ic = newiCode('%',left,right);
@@ -1536,7 +1685,7 @@ operand *geniCodeSubtract (operand *left, operand *right)
 {
     iCode *ic ;
     int isarray= 0;
-    link *resType;
+    sym_link *resType;
     LRTYPE ;
     
     /* if they both pointers then */
@@ -1558,9 +1707,7 @@ operand *geniCodeSubtract (operand *left, operand *right)
        resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype);
     }
     else { /* make them the same size */
-       resType = computeType (ltype,rtype) ;
-       left = geniCodeCast(resType,left,TRUE);
-       right= geniCodeCast(resType,right,TRUE);    
+        resType = usualBinaryConversions(&left, &right);
     }
     
     ic = newiCode('-',left,right);
@@ -1582,7 +1729,7 @@ 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 ;
@@ -1606,15 +1753,16 @@ 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);
-       if (getSize(ltype) > 1) 
-               right = geniCodeCast(INTTYPE,right,TRUE);
+
        resType = copyLinkChain(ltype);
     }
     else { /* make them the same size */
-       resType = computeType (ltype,rtype) ;
-       left = geniCodeCast(resType,left,TRUE);
-       right= geniCodeCast(resType,right,TRUE);
+        resType = usualBinaryConversions(&left, &right);
     }
     
     /* if they are both literals then we know */
@@ -1642,10 +1790,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)
@@ -1675,8 +1823,8 @@ link *aggrToPtr ( link *type, bool force)
 /*-----------------------------------------------------------------*/
 operand *geniCodeArray2Ptr (operand *op)
 {
-    link *optype = operandType(op);
-    link *opetype = getSpec(optype);
+    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)
@@ -1695,21 +1843,25 @@ operand *geniCodeArray2Ptr (operand *op)
     return op;
 }
 
+
 /*-----------------------------------------------------------------*/
 /* geniCodeArray - array access                                    */
 /*-----------------------------------------------------------------*/
 operand *geniCodeArray (operand *left,operand *right)
 {
     iCode *ic;
-    link *ltype = operandType(left);
+    sym_link *ltype = operandType(left);
     
     if (IS_PTR(ltype)) {
        if (IS_PTR(ltype->next) && left->isaddr)
+       {
            left = geniCodeRValue(left,FALSE);
+       }
        return geniCodeDerefPtr(geniCodeAdd(left,right));
     }
 
     /* array access */
+    right = usualUnaryConversions(right);
     right = geniCodeMultiply(right,
                             operandFromLit(getSize(ltype->next)));
 
@@ -1740,9 +1892,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);
     
@@ -1775,12 +1927,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);    
+    sym_link *rvtype = operandType(rv);    
     int size = 0;
     
     /* if this is not an address we have trouble */
@@ -1814,11 +1966,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);
+    sym_link *roptype = operandType(rop);
     operand *result;
     int size = 0;
     
@@ -1844,12 +1996,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);    
+    sym_link *rvtype = operandType(rv);    
     int size = 0;
     
     /* if this is not an address we have trouble */
@@ -1883,11 +2035,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);
+    sym_link *roptype = operandType(rop);
     operand *result;
     int size = 0;
     
@@ -1911,7 +2063,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;   
     
@@ -1931,9 +2083,9 @@ 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 */
@@ -1975,7 +2127,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:
@@ -2017,8 +2169,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)) {
@@ -2071,7 +2223,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));
@@ -2088,10 +2240,18 @@ operand *geniCodeUnaryMinus (operand *op)
 operand *geniCodeLeftShift (operand *left, operand *right)
 { 
     iCode *ic;
-    link *ltype = operandType(left);
-    
+
+    /* Note that we don't use the usual binary conversions for the 
+     * shift operations, in accordance with our ANSI friends.
+     */
+    if (options.ANSIint)
+    { 
+       right = usualUnaryConversions(right);
+       left = usualUnaryConversions(left);
+    }
+
     ic = newiCode(LEFT_OP,left,right);
-    IC_RESULT(ic) = newiTempOperand(ltype,0);
+    IC_RESULT(ic) = newiTempOperand(operandType(left),0);
     ADDTOCHAIN(ic);
     return IC_RESULT(ic) ;  
 }
@@ -2102,15 +2262,23 @@ operand *geniCodeLeftShift (operand *left, operand *right)
 operand *geniCodeRightShift (operand *left, operand *right)
 { 
     iCode *ic;
-    link *ltype = operandType(left);
+
+    /* Note that we don't use the usual binary conversions for the 
+     * shift operations, in accordance with our ANSI friends.
+     */
+    if (options.ANSIint)
+    { 
+       right = usualUnaryConversions(right);
+       left = usualUnaryConversions(left);
+    }
     
     ic = newiCode(RIGHT_OP,left,right);
-    IC_RESULT(ic) = newiTempOperand(ltype,0);
+    IC_RESULT(ic) = newiTempOperand(operandType(left),0);
     ADDTOCHAIN(ic);
     return IC_RESULT(ic) ;  
 }
 
-#ifdef __BORLANDC__
+#if defined(__BORLANDC__) || defined(_MSC_VER)
 #define LONG_LONG __int64
 #else
 #define LONG_LONG long long
@@ -2122,9 +2290,9 @@ operand *geniCodeRightShift (operand *left, operand *right)
 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 */
@@ -2136,9 +2304,7 @@ operand *geniCodeLogic (operand *left, operand *right, int op )
            werror(W_CONST_RANGE," compare operation ");
     }
 
-    ctype = computeType(ltype,rtype);                        
-    left = geniCodeCast(ctype,left,TRUE);
-    right= geniCodeCast(ctype,right,TRUE);
+    ctype = usualBinaryConversions(&left, &right);
 
     ic = newiCode(op,left,right);
     IC_RESULT(ic) = newiTempOperand (newCharLink(),1);
@@ -2211,8 +2377,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");
@@ -2307,7 +2473,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 ; 
@@ -2317,8 +2483,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 ;
     }
     
@@ -2342,8 +2508,7 @@ 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)) && 
-       !IS_RENT(fetype)) {
+       IS_REGPARM(parms->etype)) && !func->hasVargs ) {
        ic = newiCode(SEND,pval,NULL);
        ADDTOCHAIN(ic);
     } else {
@@ -2355,7 +2520,7 @@ static void geniCodeParms ( ast *parms , int *stack, link *fetype)
            geniCodeAssign(top,pval,1);
        }
        else { 
-           link *p = operandType(pval);
+           sym_link *p = operandType(pval);
            /* push */
            ic = newiCode(IPUSH,pval,NULL);
            ic->parmPush = 1;
@@ -2374,7 +2539,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
@@ -2383,7 +2548,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)) 
@@ -2454,7 +2619,7 @@ void geniCodeFunctionBody (ast *tree)
 {
     iCode *ic ;
     operand *func ;
-    link *fetype  ;
+    sym_link *fetype  ;
     int savelineno ;
     
     /* reset the auto generation */
@@ -2519,7 +2684,7 @@ void geniCodeIfx (ast *tree)
 {
     iCode *ic;
     operand *condition = ast2iCode(tree->left);
-    link *cetype; 
+    sym_link *cetype; 
     
     /* if condition is null then exit */
     if (!condition)
@@ -2622,7 +2787,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))) {
@@ -2793,7 +2958,7 @@ operand *ast2iCode (ast *tree)
        
     case '[' :    /* array operation */
        {
-           link *ltype = operandType(left);
+           sym_link *ltype = operandType(left);
            left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE);
            right=geniCodeRValue (right,TRUE);             
        }
@@ -2810,7 +2975,7 @@ operand *ast2iCode (ast *tree)
        
     case PTR_OP: /* structure pointer dereference */
        {
-           link *pType;
+           sym_link *pType;
            pType = operandType(left);
            left = geniCodeRValue(left,TRUE);
            
@@ -2916,8 +3081,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);
@@ -2948,8 +3113,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);
@@ -2964,8 +3129,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);