X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=1b43a42850a335c01fc35c78d708e5cddef2da30;hb=5a1d5e778e85664f4e6657019348b4756b16eacb;hp=dc92aceda7b7c5577d1bbd55b42620927cb42b5a;hpb=11adc0eac02dc5f3ade646b5de6b15ae5cbf142b;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index dc92aced..1b43a428 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -1038,6 +1038,25 @@ algebraicOpts (iCode * ic, eBBlock * ebp) } if (rightValue == -1.0) { + /* '*' can have two unsigned chars as operands */ + /* and an unsigned int as result. */ + if (IS_INTEGRAL (operandType (IC_LEFT (ic)))) + { + if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) && + (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic))))) + { + operand * op; + iCode * newic; + /* Widen to int. */ + op = operandFromOperand (IC_RESULT (ic)); + op->type = TYPE; + setOperandType (op, INTTYPE); + newic = newiCode (CAST, op, IC_LEFT (ic)); + IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE); + addiCodeToeBBlock (ebp, newic, ic); + IC_LEFT (ic) = IC_RESULT (newic); + } + } /* convert x * -1 to -x */ ic->op = UNARYMINUS; IC_RIGHT (ic) = NULL; @@ -1054,20 +1073,59 @@ algebraicOpts (iCode * ic, eBBlock * ebp) IC_LEFT (ic) = NULL; IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); IC_RESULT (ic)->isaddr = 0; - break; + return; } - /* if this is a division then check if right */ - /* is one then change it to an assignment */ - if (IS_OP_LITERAL (IC_RIGHT (ic)) && - operandLitValue (IC_RIGHT (ic)) == 1.0) + /* if this is a division then check if left is zero */ + /* and right is not then change it to an assignment */ + if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) && + (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0)) { - ic->op = '='; IC_RIGHT (ic) = IC_LEFT (ic); IC_LEFT (ic) = NULL; SET_RESULT_RIGHT (ic); return; } + /* if this is a division then check if right */ + /* is one then change it to an assignment */ + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + double rightValue = operandLitValue (IC_RIGHT (ic)); + if (rightValue == 1.0) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + if (rightValue == -1.0) + { + /* '/' can have two unsigned chars as operands */ + /* and an unsigned int as result. */ + if (IS_INTEGRAL (operandType (IC_LEFT (ic)))) + { + if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) && + (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic))))) + { + operand * op; + iCode * newic; + /* Widen to int. */ + op = operandFromOperand (IC_RESULT (ic)); + op->type = TYPE; + setOperandType (op, INTTYPE); + newic = newiCode (CAST, op, IC_LEFT (ic)); + IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE); + addiCodeToeBBlock (ebp, newic, ic); + IC_LEFT (ic) = IC_RESULT (newic); + } + } + /* convert x / -1 to -x */ + ic->op = UNARYMINUS; + IC_RIGHT (ic) = NULL; + return; + } + } break; /* if both are the same for an comparison operators */ case EQ_OP: @@ -2187,7 +2245,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, mine and type is a pointer then delete pointerGets to take care of aliasing */ if (ASSIGNMENT (ic) && - IS_SYMOP (IC_RESULT (ic)) && + IS_SYMOP (IC_RESULT (ic)) && OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) && IS_PTR (operandType (IC_RESULT (ic)))) {