X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=f4e50eba162c9333a736ee99c9196b129101bc24;hb=67613b6eceb41c8a242c2556a0f59311adb0b388;hp=e65e7d5de73728ddbaf8bc75bd73b3a0d221f496;hpb=2b768f4d1d91642a8e7ffdddafd545d286ae1fbc;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index e65e7d5d..f4e50eba 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -45,7 +45,6 @@ symbol *entryLabel; /* function entry label */ /*-----------------------------------------------------------------*/ /* forward definition of some functions */ -operand *geniCodeDivision (operand *, operand *, bool); operand *geniCodeAssign (operand *, operand *, int); static operand *geniCodeArray (operand *, operand *,int); static operand *geniCodeArray2Ptr (operand *); @@ -1219,22 +1218,32 @@ operandOperation (operand * left, operand * right, (TYPE_UDWORD) operandLitValue (right)); break; case EQ_OP: - /* this op doesn't care about signedness */ - { - TYPE_UDWORD l, r; - - l = (TYPE_UDWORD) operandLitValue (left); - if (IS_CHAR(OP_VALUE(left)->type)) - l &= 0xff; - else if (!IS_LONG (OP_VALUE(left)->type)) - l &= 0xffff; - r = (TYPE_UDWORD) operandLitValue (right); - if (IS_CHAR(OP_VALUE(right)->type)) - r &= 0xff; - else if (!IS_LONG (OP_VALUE(right)->type)) - r &= 0xffff; - retval = operandFromLit (l == r); - } + if (IS_FLOAT (let) || + IS_FLOAT (ret)) + { + retval = operandFromLit (operandLitValue (left) == + operandLitValue (right)); + } + else + { + /* this op doesn't care about signedness */ + TYPE_UDWORD l, r; + + l = (TYPE_UDWORD) operandLitValue (left); + r = (TYPE_UDWORD) operandLitValue (right); + /* In order to correctly compare 'signed int' and 'unsigned int' it's + neccessary to strip them to 16 bit. + Literals are reduced to their cheapest type, therefore left and + right might have different types. It's neccessary to find a + common type: int (used for char too) or long */ + if (!IS_LONG (let) && + !IS_LONG (ret)) + { + r = (TYPE_UWORD) r; + l = (TYPE_UWORD) l; + } + retval = operandFromLit (l == r); + } break; case '<': retval = operandFromLit (operandLitValue (left) < @@ -1693,10 +1702,11 @@ setOperandType (operand * op, sym_link * type) } } + /*-----------------------------------------------------------------*/ /* Get size in byte of ptr need to access an array */ /*-----------------------------------------------------------------*/ -int +static int getArraySizePtr (operand * op) { sym_link *ltype = operandType(op); @@ -1756,7 +1766,7 @@ usualUnaryConversions (operand * op) static sym_link * usualBinaryConversions (operand ** op1, operand ** op2, - bool resultIsInt, char op) + RESULT_TYPE resultType, char op) { sym_link *ctype; sym_link *rtype = operandType (*op2); @@ -1768,8 +1778,7 @@ usualBinaryConversions (operand ** op1, operand ** op2, bool oldOneByteOps = FALSE; static bool saidHello = FALSE; - if ( strcmp (port->target, "pic14") == 0 - || strcmp (port->target, "pic16") == 0) + if (strcmp (port->target, "pic14") == 0) oldOneByteOps = TRUE; if (getenv ("SDCC_NEWONEBYTEOPS")) { @@ -1795,10 +1804,10 @@ usualBinaryConversions (operand ** op1, operand ** op2, && ( (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype))) || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype))))) /* one or two signed char operands: promote to int */ - resultIsInt = TRUE; + resultType = RESULT_TYPE_INT; #endif - ctype = computeType (ltype, rtype, resultIsInt); + ctype = computeType (ltype, rtype, resultType, op); #ifdef OLDONEBYTEOPS @@ -2060,8 +2069,8 @@ geniCodeGoto (symbol * label) /*-----------------------------------------------------------------*/ /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ -operand * -geniCodeMultiply (operand * left, operand * right, bool resultIsInt) +static operand * +geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int p2 = 0; @@ -2077,7 +2086,7 @@ geniCodeMultiply (operand * left, operand * right, bool resultIsInt) p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)); } - resType = usualBinaryConversions (&left, &right, resultIsInt, '*'); + resType = usualBinaryConversions (&left, &right, resultType, '*'); #if 1 rtype = operandType (right); retype = getSpec (rtype); @@ -2090,11 +2099,13 @@ geniCodeMultiply (operand * left, operand * right, bool resultIsInt) /* code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases than 2 bytes result = 2 bytes << literal if port has 1 byte muldiv */ - if (p2 && !IS_FLOAT (letype) && - !((resultIsInt) && (getSize (resType) != getSize (ltype)) && - (port->support.muldiv == 1))) + if (p2 && !IS_FLOAT (letype) + && !((resultType != RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)) + && (port->support.muldiv == 1)) + && strcmp (port->target, "pic14") != 0 /* don't shift for pic */ + && strcmp (port->target, "pic16") != 0) { - if ((resultIsInt) && (getSize (resType) != getSize (ltype))) + if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))) { /* LEFT_OP need same size for left and result, */ left = geniCodeCast (resType, left, TRUE); @@ -2119,8 +2130,8 @@ geniCodeMultiply (operand * left, operand * right, bool resultIsInt) /*-----------------------------------------------------------------*/ /* geniCodeDivision - gen intermediate code for division */ /*-----------------------------------------------------------------*/ -operand * -geniCodeDivision (operand * left, operand * right, bool resultIsInt) +static operand * +geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int p2 = 0; @@ -2130,7 +2141,7 @@ geniCodeDivision (operand * left, operand * right, bool resultIsInt) sym_link *ltype = operandType (left); sym_link *letype = getSpec (ltype); - resType = usualBinaryConversions (&left, &right, resultIsInt, '/'); + resType = usualBinaryConversions (&left, &right, resultType, '/'); /* if the right is a literal & power of 2 and left is unsigned then make it a @@ -2157,8 +2168,8 @@ geniCodeDivision (operand * left, operand * right, bool resultIsInt) /*-----------------------------------------------------------------*/ /* geniCodeModulus - gen intermediate code for modulus */ /*-----------------------------------------------------------------*/ -operand * -geniCodeModulus (operand * left, operand * right, bool resultIsInt) +static operand * +geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; sym_link *resType; @@ -2169,7 +2180,7 @@ geniCodeModulus (operand * left, operand * right, bool resultIsInt) return operandFromValue (valMod (left->operand.valOperand, right->operand.valOperand)); - resType = usualBinaryConversions (&left, &right, resultIsInt, '%'); + resType = usualBinaryConversions (&left, &right, resultType, '%'); /* now they are the same size */ ic = newiCode ('%', left, right); @@ -2220,8 +2231,8 @@ subtractExit: /*-----------------------------------------------------------------*/ /* geniCodeSubtract - generates code for subtraction */ /*-----------------------------------------------------------------*/ -operand * -geniCodeSubtract (operand * left, operand * right) +static operand * +geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int isarray = 0; @@ -2244,12 +2255,15 @@ geniCodeSubtract (operand * left, operand * right) { isarray = left->isaddr; right = geniCodeMultiply (right, - operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); + operandFromLit (getSize (ltype->next)), + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype); } else { /* make them the same size */ - resType = usualBinaryConversions (&left, &right, FALSE, '-'); + resType = usualBinaryConversions (&left, &right, resultType, '-'); } ic = newiCode ('-', left, right); @@ -2268,8 +2282,8 @@ geniCodeSubtract (operand * left, operand * right) /*-----------------------------------------------------------------*/ /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ -operand * -geniCodeAdd (operand * left, operand * right, int lvl) +static operand * +geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl) { iCode *ic; sym_link *resType; @@ -2297,7 +2311,11 @@ geniCodeAdd (operand * left, operand * right, int lvl) size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + right = geniCodeMultiply (right, + size, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ @@ -2308,7 +2326,7 @@ geniCodeAdd (operand * left, operand * right, int lvl) } else { // make them the same size - resType = usualBinaryConversions (&left, &right, FALSE, '+'); + resType = usualBinaryConversions (&left, &right, resultType, '+'); } /* if they are both literals then we know */ @@ -2390,12 +2408,22 @@ geniCodeArray (operand * left, operand * right, int lvl) left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl); + return geniCodeDerefPtr (geniCodeAdd (left, + right, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR, + lvl), + lvl); } size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + right = geniCodeMultiply (right, + size, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ if (indexUnsigned) @@ -2898,7 +2926,7 @@ geniCodeLogic (operand * left, operand * right, int op) } } - ctype = usualBinaryConversions (&left, &right, FALSE, ' '); + ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, ' '); ic = newiCode (op, left, right); IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); @@ -3487,7 +3515,7 @@ 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)); + cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR); if (!IS_LITERAL(getSpec(operandType(cond)))) setOperandType (cond, UCHARTYPE); } @@ -3855,31 +3883,34 @@ ast2iCode (ast * tree,int lvl) case '/': return geniCodeDivision (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE), - IS_INT (tree->ftype)); + getResultTypeFromType (tree->ftype)); case '%': return geniCodeModulus (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE), - IS_INT (tree->ftype)); + getResultTypeFromType (tree->ftype)); case '*': if (right) return geniCodeMultiply (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE), - IS_INT (tree->ftype)); + getResultTypeFromType (tree->ftype)); else return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': if (right) return geniCodeSubtract (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); else return geniCodeUnaryMinus (geniCodeRValue (left, FALSE)); case '+': if (right) return geniCodeAdd (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE),lvl); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype), + lvl); else return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ @@ -3970,7 +4001,8 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeMultiply (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE),FALSE), 0); + geniCodeRValue (right, FALSE), FALSE), + getResultTypeFromType (tree->ftype)); case DIV_ASSIGN: return @@ -3978,7 +4010,7 @@ ast2iCode (ast * tree,int lvl) geniCodeDivision (geniCodeRValue (operandFromOperand (left), FALSE), geniCodeRValue (right, FALSE), - IS_INT (tree->ftype)), + getResultTypeFromType (tree->ftype)), 0); case MOD_ASSIGN: return @@ -3986,7 +4018,7 @@ ast2iCode (ast * tree,int lvl) geniCodeModulus (geniCodeRValue (operandFromOperand (left), FALSE), geniCodeRValue (right, FALSE), - IS_INT (tree->ftype)), + getResultTypeFromType (tree->ftype)), 0); case ADD_ASSIGN: { @@ -4002,7 +4034,10 @@ ast2iCode (ast * tree,int lvl) return geniCodeAssign (left, geniCodeAdd (geniCodeRValue (operandFromOperand (left), FALSE), - right,lvl), 0); + right, + getResultTypeFromType (tree->ftype), + lvl), + 0); } case SUB_ASSIGN: { @@ -4021,7 +4056,9 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeSubtract (geniCodeRValue (operandFromOperand (left), FALSE), - right), 0); + right, + getResultTypeFromType (tree->ftype)), + 0); } case LEFT_ASSIGN: return