Add support for ANSI integer promotion rules
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 25 Jan 2001 20:53:13 +0000 (20:53 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 25 Jan 2001 20:53:13 +0000 (20:53 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@535 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCglobl.h
src/SDCCicode.c
src/SDCCmain.c
src/SDCCsymt.h

index 6e2b62133d5989dbc60847c0cf1330085a4f0f3b..1c05ec56807083ecc6bf3fd129764da9dcc7a73f 100644 (file)
@@ -1,4 +1,4 @@
-/* SDCCglobl.h - global macros etc required by all files */
+;/* SDCCglobl.h - global macros etc required by all files */
 #ifndef SDCCGLOBL_H
 #define SDCCGLOBL_H
 #include <memory.h>
@@ -206,6 +206,7 @@ struct options {
     int nostdlib  : 1  ; /* Don't use standard lib files */
     int nostdinc  : 1  ; /* Don't use standard include files */
     int verbose   : 1  ; /* Show what the compiler is doing */
+    int ANSIint   : 1  ;  /* Use ANSI integer promotion rules in expressions. */
 
     char *calleeSaves[128]; /* list of functions using callee save */
     char *excludeRegs[32] ; /* registers excluded from saving */
index 00f1ee2fe81369066510ccb69646c71f921a6d75..2a8b24d0b9f1e7c7bdac9bb30ccd1f23ddfd12e1 100644 (file)
@@ -1272,6 +1272,143 @@ void setOperandType (operand *op, sym_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                             */
@@ -1434,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              */
@@ -1469,9 +1604,7 @@ operand *geniCodeDivision (operand *left, operand *right)
     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             */
@@ -1505,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);
@@ -1576,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);
@@ -1633,9 +1762,7 @@ operand *geniCodeAdd (operand *left, operand *right )
        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 */
@@ -1716,6 +1843,7 @@ operand *geniCodeArray2Ptr (operand *op)
     return op;
 }
 
+
 /*-----------------------------------------------------------------*/
 /* geniCodeArray - array access                                    */
 /*-----------------------------------------------------------------*/
@@ -1733,11 +1861,7 @@ operand *geniCodeArray (operand *left,operand *right)
     }
 
     /* array access */
-    if (getSize(operandType(right)) < INTSIZE) 
-    {
-        /* Widen the index type to int first. */
-       right = geniCodeCast(INTTYPE,right,TRUE);           
-    }
+    right = usualUnaryConversions(right);
     right = geniCodeMultiply(right,
                             operandFromLit(getSize(ltype->next)));
 
@@ -2117,17 +2241,12 @@ operand *geniCodeLeftShift (operand *left, operand *right)
 { 
     iCode *ic;
 
-    /* Operands must be promoted to int, according to ISO. */    
-    if (getSize(operandType(right)) < INTSIZE) 
-    {
-       right = geniCodeCast(INTTYPE,right,TRUE);           
-    }    
+    /* Note that we don't use the usual binary conversions for the 
+     * shift operations, in accordance with our ANSI friends.
+     */
+    right = usualUnaryConversions(right);
+    left = usualUnaryConversions(left);
 
-    if (getSize(operandType(left)) < INTSIZE) 
-    {
-       left = geniCodeCast(INTTYPE,left,TRUE);     
-    }
-    
     ic = newiCode(LEFT_OP,left,right);
     IC_RESULT(ic) = newiTempOperand(operandType(left),0);
     ADDTOCHAIN(ic);
@@ -2141,16 +2260,11 @@ operand *geniCodeRightShift (operand *left, operand *right)
 { 
     iCode *ic;
 
-    /* Operands must be promoted to int, according to ISO. */    
-    if (getSize(operandType(right)) < INTSIZE) 
-    {
-       right = geniCodeCast(INTTYPE,right,TRUE);           
-    }    
-
-    if (getSize(operandType(left)) < INTSIZE) 
-    {
-       left = geniCodeCast(INTTYPE,left,TRUE);     
-    }
+    /* Note that we don't use the usual binary conversions for the 
+     * shift operations, in accordance with our ANSI friends.
+     */
+    right = usualUnaryConversions(right);
+    left = usualUnaryConversions(left);
     
     ic = newiCode(RIGHT_OP,left,right);
     IC_RESULT(ic) = newiTempOperand(operandType(left),0);
@@ -2184,9 +2298,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);
index c9618aefbae7cd96321b40f46c67f70d4e2967c7..ea961cbbab4f30819a409a6756dc8d14d3bc005e 100644 (file)
@@ -123,6 +123,7 @@ char    *preOutName;
 #define OPTION_NOSTDLIB     "-nostdlib"
 #define OPTION_NOSTDINC     "-nostdinc"
 #define OPTION_VERBOSE      "-verbose"
+#define OPTION_ANSIINT     "-ansiint"
 static const char *_preCmd[] = {
     "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1", 
     "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
@@ -815,6 +816,11 @@ int   parseCmdLine ( int argc, char **argv )
                options.verbose=1;
                continue;
            }
+           
+           if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
+               options.ANSIint=1;
+               continue;
+           }       
 
            if (!port->parseOption(&argc, argv, &i))
            {
index 9cad165d2712acb68e34f56f0fc8f79b6df8c996..55d95ec8ffaf84c816619bc9fbddd62924a72fff 100644 (file)
@@ -357,8 +357,12 @@ extern sym_link *__multypes[3][2];
 extern symbol *__conv[2][3][2];
 
 #define CHARTYPE       __multypes[0][0]
-#define INTTYPE                __multypes[1][0]
 #define UCHARTYPE      __multypes[0][1]
+#define INTTYPE                __multypes[1][0]
+#define UINTTYPE       __multypes[1][1]
+#define LONGTYPE       __multypes[2][0]
+#define ULONGTYPE      __multypes[2][1]
+
 
 extern sym_link *floatType;
 
@@ -368,6 +372,7 @@ extern sym_link *floatType;
 void       initSymt           (                                );
 symbol      *newSymbol        ( char      *, int               );
 sym_link    *newLink          (                                );
+sym_link    *newFloatLink     (                                       );
 structdef   *newStruct        ( char      *                    );
 void         addDecl          ( symbol   *, int   , sym_link * );
 sym_link    *mergeSpec        ( sym_link      *, sym_link *    );