From: kvigor Date: Thu, 25 Jan 2001 20:53:13 +0000 (+0000) Subject: Add support for ANSI integer promotion rules X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=a84ad3e5f5807115a4594697d15777aae821c6e8;p=fw%2Fsdcc Add support for ANSI integer promotion rules git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@535 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index 6e2b6213..1c05ec56 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -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 @@ -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 */ diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 00f1ee2f..2a8b24d0 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -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); diff --git a/src/SDCCmain.c b/src/SDCCmain.c index c9618aef..ea961cbb 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -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)) { diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 9cad165d..55d95ec8 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -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 * );