X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=cc530311e7077b22d4cd0bb37156f421fb4a083d;hb=02e5ffe7558a69ea0293fda3e1cf9747ac0ff29e;hp=e0191b114faca281d64da9fcf59859341a0afab2;hpb=9ce6d44e135c70f91434bbd2850c80359f62d535;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index e0191b11..cc530311 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -45,8 +45,7 @@ symbol *entryLabel; /* function entry label */ /*-----------------------------------------------------------------*/ /* forward definition of some functions */ -operand *geniCodeDivision (operand *, operand *); -operand *geniCodeAssign (operand *, operand *, int); +operand *geniCodeAssign (operand *, operand *, int, int); static operand *geniCodeArray (operand *, operand *,int); static operand *geniCodeArray2Ptr (operand *); operand *geniCodeRValue (operand *, bool); @@ -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) < @@ -1302,7 +1311,9 @@ operandOperation (operand * left, operand * right, break; case '~': - retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left))); + retval = operandFromValue (valCastLiteral (type, + ~((TYPE_UDWORD) + operandLitValue (left)))); break; case '!': @@ -1516,16 +1527,15 @@ operandFromSymbol (symbol * sym) ok = 0; if (!IS_AGGREGATE (sym->type) && /* not an aggregate */ - !IS_FUNC (sym->type) && /* not a function */ - !sym->_isparm && /* not a parameter */ - sym->level && /* is a local variable */ - !sym->addrtaken && /* whose address has not been taken */ - !sym->reqv && /* does not already have a reg equivalence */ + !IS_FUNC (sym->type) && /* not a function */ + !sym->_isparm && /* not a parameter */ + IS_AUTO (sym) && /* is a local auto variable */ + !sym->addrtaken && /* whose address has not been taken */ + !sym->reqv && /* does not already have a reg equivalence */ !IS_VOLATILE (sym->etype) && /* not declared as volatile */ - !IS_STATIC (sym->etype) && /* and not declared static */ - !sym->islbl && /* not a label */ - ok && /* farspace check */ - !IS_BITVAR (sym->etype) /* not a bit variable */ + !sym->islbl && /* not a label */ + ok && /* farspace check */ + !IS_BITVAR (sym->etype) /* not a bit variable */ ) { @@ -1533,6 +1543,7 @@ operandFromSymbol (symbol * sym) and before liveRange calculation */ sym->reqv = newiTempOperand (sym->type, 0); sym->reqv->key = sym->key; + OP_SYMBOL (sym->reqv)->prereqv = sym; OP_SYMBOL (sym->reqv)->key = sym->key; OP_SYMBOL (sym->reqv)->isreqv = 1; OP_SYMBOL (sym->reqv)->islocal = 1; @@ -1692,10 +1703,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); @@ -1752,36 +1764,35 @@ usualUnaryConversions (operand * op) /*-----------------------------------------------------------------*/ /* perform "usual binary conversions" */ /*-----------------------------------------------------------------*/ + static sym_link * usualBinaryConversions (operand ** op1, operand ** op2, - bool promoteCharToInt, bool isMul) + RESULT_TYPE resultType, int op) { sym_link *ctype; sym_link *rtype = operandType (*op2); sym_link *ltype = operandType (*op1); - ctype = computeType (ltype, rtype, promoteCharToInt); + ctype = computeType (ltype, rtype, resultType, op); - /* special for multiplication: - This if for 'mul a,b', which takes two chars and returns an int */ - if ( isMul - /* && promoteCharToInt superfluous, already handled by computeType() */ - && IS_INT (getSpec (ctype))) + switch (op) { - sym_link *retype = getSpec (rtype); - sym_link *letype = getSpec (ltype); - - if ( IS_CHAR (letype) - && IS_CHAR (retype) - && IS_UNSIGNED (letype) - && IS_UNSIGNED (retype)) - { - return ctype; - } + case '*': + case '/': + case '%': + if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype))) + { + /* one byte operations: keep signedness for code generator */ + return ctype; + } + break; + default: + break; } + *op1 = geniCodeCast (ctype, *op1, TRUE); *op2 = geniCodeCast (ctype, *op2, TRUE); - + return ctype; } @@ -1862,6 +1873,12 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) return op; } + if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type)) + { + geniCodeArray2Ptr (op); + op->isaddr = 0; + } + /* if the operand is already the desired type then do nothing */ if (compareType (type, optype) == 1) return op; @@ -1964,7 +1981,8 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /* preserve the storage class & output class */ /* of the original variable */ restype = getSpec (operandType (IC_RESULT (ic))); - if (!IS_LITERAL(opetype)) + if (!IS_LITERAL(opetype) && + !IS_BIT(opetype)) SPEC_SCLS (restype) = SPEC_SCLS (opetype); SPEC_OCLS (restype) = SPEC_OCLS (opetype); @@ -1999,8 +2017,8 @@ geniCodeGoto (symbol * label) /*-----------------------------------------------------------------*/ /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ -operand * -geniCodeMultiply (operand * left, operand * right, int resultIsInt) +static operand * +geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int p2 = 0; @@ -2016,7 +2034,7 @@ geniCodeMultiply (operand * left, operand * right, int resultIsInt) p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)); } - resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE); + resType = usualBinaryConversions (&left, &right, resultType, '*'); #if 1 rtype = operandType (right); retype = getSpec (rtype); @@ -2029,11 +2047,13 @@ geniCodeMultiply (operand * left, operand * right, int 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); @@ -2058,8 +2078,8 @@ geniCodeMultiply (operand * left, operand * right, int resultIsInt) /*-----------------------------------------------------------------*/ /* geniCodeDivision - gen intermediate code for division */ /*-----------------------------------------------------------------*/ -operand * -geniCodeDivision (operand * left, operand * right) +static operand * +geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int p2 = 0; @@ -2069,9 +2089,7 @@ geniCodeDivision (operand * left, operand * right) sym_link *ltype = operandType (left); sym_link *letype = getSpec (ltype); - resType = usualBinaryConversions (&left, &right, - (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE, - FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '/'); /* if the right is a literal & power of 2 and left is unsigned then make it a @@ -2098,8 +2116,8 @@ geniCodeDivision (operand * left, operand * right) /*-----------------------------------------------------------------*/ /* geniCodeModulus - gen intermediate code for modulus */ /*-----------------------------------------------------------------*/ -operand * -geniCodeModulus (operand * left, operand * right) +static operand * +geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; sym_link *resType; @@ -2110,9 +2128,7 @@ geniCodeModulus (operand * left, operand * right) return operandFromValue (valMod (left->operand.valOperand, right->operand.valOperand)); - resType = usualBinaryConversions (&left, &right, - (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE, - FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '%'); /* now they are the same size */ ic = newiCode ('%', left, right); @@ -2156,14 +2172,15 @@ subtractExit: // should we really do this? is this ANSI? return geniCodeDivision (result, - operandFromLit (getSize (ltype->next))); + operandFromLit (getSize (ltype->next)), + FALSE); } /*-----------------------------------------------------------------*/ /* 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; @@ -2186,12 +2203,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, FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '-'); } ic = newiCode ('-', left, right); @@ -2210,8 +2230,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; @@ -2239,7 +2259,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: */ @@ -2250,7 +2274,7 @@ geniCodeAdd (operand * left, operand * right, int lvl) } else { // make them the same size - resType = usualBinaryConversions (&left, &right, FALSE, FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '+'); } /* if they are both literals then we know */ @@ -2297,6 +2321,19 @@ aggrToPtr (sym_link * type, bool force) return ptype; } +/*------------------------------------------------------------------*/ +/* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */ +/*------------------------------------------------------------------*/ +int +aggrToPtrDclType (sym_link * type, bool force) +{ + if (IS_PTR (type) && !force) + return DCL_TYPE (type); + + /* return the pointer depending on the storage class */ + return PTR_TYPE (SPEC_OCLS (getSpec (type))); +} + /*-----------------------------------------------------------------*/ /* geniCodeArray2Ptr - array to pointer */ /*-----------------------------------------------------------------*/ @@ -2332,12 +2369,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) @@ -2434,7 +2481,7 @@ geniCodePostInc (operand * op) if (IS_ITEMP (rv)) OP_SYMBOL(rv)->noSpilLoc = 1; - geniCodeAssign (rOp, rv, 0); + geniCodeAssign (rOp, rv, 0, 0); size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1); if (IS_FLOAT (rvtype)) @@ -2445,7 +2492,7 @@ geniCodePostInc (operand * op) IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); ADDTOCHAIN (ic); - geniCodeAssign (op, result, 0); + geniCodeAssign (op, result, 0, 0); return rOp; @@ -2481,8 +2528,8 @@ geniCodePreInc (operand * op, bool lvalue) IC_RESULT (ic) = result = newiTempOperand (roptype, 0); ADDTOCHAIN (ic); - (void) geniCodeAssign (op, result, 0); - if (lvalue || IS_TRUE_SYMOP (op)) + (void) geniCodeAssign (op, result, 0, 0); + if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype)) return op; else return result; @@ -2517,7 +2564,7 @@ geniCodePostDec (operand * op) if (IS_ITEMP (rv)) OP_SYMBOL(rv)->noSpilLoc = 1; - geniCodeAssign (rOp, rv, 0); + geniCodeAssign (rOp, rv, 0, 0); size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1); if (IS_FLOAT (rvtype)) @@ -2528,7 +2575,7 @@ geniCodePostDec (operand * op) IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); ADDTOCHAIN (ic); - geniCodeAssign (op, result, 0); + geniCodeAssign (op, result, 0, 0); return rOp; @@ -2564,8 +2611,8 @@ geniCodePreDec (operand * op, bool lvalue) IC_RESULT (ic) = result = newiTempOperand (roptype, 0); ADDTOCHAIN (ic); - (void) geniCodeAssign (op, result, 0); - if (lvalue || IS_TRUE_SYMOP (op)) + (void) geniCodeAssign (op, result, 0, 0); + if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype)) return op; else return result; @@ -2754,12 +2801,15 @@ geniCodeUnaryMinus (operand * op) /* geniCodeLeftShift - gen i code for left shift */ /*-----------------------------------------------------------------*/ operand * -geniCodeLeftShift (operand * left, operand * right) +geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; + sym_link *resType; ic = newiCode (LEFT_OP, left, right); - IC_RESULT (ic) = newiTempOperand (operandType (left), 0); + + resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP); + IC_RESULT (ic) = newiTempOperand (resType, 0); ADDTOCHAIN (ic); return IC_RESULT (ic); } @@ -2781,7 +2831,7 @@ geniCodeRightShift (operand * left, operand * right) /*-----------------------------------------------------------------*/ /* geniCodeLogic- logic code */ /*-----------------------------------------------------------------*/ -operand * +static operand * geniCodeLogic (operand * left, operand * right, int op) { iCode *ic; @@ -2840,7 +2890,7 @@ geniCodeLogic (operand * left, operand * right, int op) } } - ctype = usualBinaryConversions (&left, &right, FALSE, FALSE); + ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0); ic = newiCode (op, left, right); IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); @@ -2853,12 +2903,77 @@ geniCodeLogic (operand * left, operand * right, int op) op != NE_OP && op != AND_OP && op != OR_OP) - ic->supportRtn = 1; + ic->supportRtn = 1; ADDTOCHAIN (ic); return IC_RESULT (ic); } +/*-----------------------------------------------------------------*/ +/* geniCodeLogicAndOr - && || operations */ +/*-----------------------------------------------------------------*/ +static operand * +geniCodeLogicAndOr (ast *tree, int lvl) +{ + iCode *ic; + symbol *falseLabel = newiTempLabel (NULL); + symbol *trueLabel = newiTempLabel (NULL); + symbol *exitLabel = newiTempLabel (NULL); + operand *op, *result, *condition; + + /* AND_OP and OR_OP are no longer generated because of bug-905492. + They can be reenabled by executing the following block. If you find + a decent optimization you could start right here: + */ +#if 0 + if (0) + { + operand *leftOp, *rightOp; + + leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE); + rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE); + + return geniCodeLogic (leftOp, rightOp, tree->opval.op); + } +#endif + + /* generate two IFX for the '&&' or '||' op */ + + /* evaluate left operand */ + condition = ast2iCode (tree->left, lvl + 1); + op = geniCodeRValue (condition, FALSE); + + /* test left operand */ + if (tree->opval.op == AND_OP) + ic = newiCodeCondition (op, NULL, falseLabel); + else /* OR_OP */ + ic = newiCodeCondition (op, trueLabel, NULL); + ADDTOCHAIN (ic); + + /* evaluate right operand */ + condition = ast2iCode (tree->right, lvl + 1); + op = geniCodeRValue (condition, FALSE); + + /* test right operand */ + ic = newiCodeCondition (op, trueLabel, NULL); + ADDTOCHAIN (ic); + + /* store 0 or 1 in result */ + result = newiTempOperand (newCharLink(), 1); + + geniCodeLabel (falseLabel); + geniCodeAssign (result, operandFromLit (0), 0, 0); + /* generate an unconditional goto */ + geniCodeGoto (exitLabel); + + geniCodeLabel (trueLabel); + geniCodeAssign (result, operandFromLit (1), 0, 0); + + geniCodeLabel (exitLabel); + + return result; +} + /*-----------------------------------------------------------------*/ /* geniCodeUnary - for a a generic unary operation */ /*-----------------------------------------------------------------*/ @@ -2892,7 +3007,7 @@ geniCodeConditional (ast * tree,int lvl) /* move the value to a new Operand */ result = newiTempOperand (tree->right->ftype, 0); - geniCodeAssign (result, geniCodeRValue (true, FALSE), 0); + geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0); /* generate an unconditional goto */ geniCodeGoto (exitLabel); @@ -2901,7 +3016,7 @@ geniCodeConditional (ast * tree,int lvl) geniCodeLabel (falseLabel); false = ast2iCode (tree->right->right,lvl+1); - geniCodeAssign (result, geniCodeRValue (false, FALSE), 0); + geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0); /* create the exit label */ geniCodeLabel (exitLabel); @@ -2913,13 +3028,13 @@ geniCodeConditional (ast * tree,int lvl) /* geniCodeAssign - generate code for assignment */ /*-----------------------------------------------------------------*/ operand * -geniCodeAssign (operand * left, operand * right, int nosupdate) +geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) { iCode *ic; sym_link *ltype = operandType (left); sym_link *rtype = operandType (right); - if (!left->isaddr && !IS_ITEMP (left)) + if (!left->isaddr && (!IS_ITEMP (left) || strictLval)) { werror (E_LVALUE_REQUIRED, "assignment"); return left; @@ -3097,7 +3212,7 @@ geniCodeParms (ast * parms, value *argVals, int *stack, operand *top = operandFromSymbol (argVals->sym); /* clear useDef and other bitVectors */ OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL; - geniCodeAssign (top, pval, 1); + geniCodeAssign (top, pval, 1, 0); } else { @@ -3247,6 +3362,7 @@ geniCodeFunctionBody (ast * tree,int lvl) /* create a proc icode */ ic = newiCode (FUNCTION, func, NULL); lineno=ic->lineno = OP_SYMBOL (func)->lineDef; + ic->tree = tree; ADDTOCHAIN (ic); @@ -3262,6 +3378,7 @@ geniCodeFunctionBody (ast * tree,int lvl) /* now generate the end proc */ ic = newiCode (ENDFUNCTION, func, NULL); + ic->tree = tree; ADDTOCHAIN (ic); return; } @@ -3405,6 +3522,23 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) falseLabel = newiTempLabel (buffer); + /* If cond is volatile, it might change after the boundary */ + /* conditions are tested to an out of bounds value, causing */ + /* a jump to a location outside of the jump table. To avoid */ + /* this possibility, use a non-volatile copy of it instead. */ + if (IS_OP_VOLATILE (cond)) + { + operand * newcond; + iCode * ic; + + newcond = newiTempOperand (operandType (cond), TRUE); + newcond->isvolatile = 0; + ic = newiCode ('=', NULL, cond); + IC_RESULT (ic) = newcond; + ADDTOCHAIN (ic); + cond = newcond; + } + /* so we can create a jumptable */ /* first we rule out the boundary conditions */ /* if only optimization says so */ @@ -3429,7 +3563,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); } @@ -3691,6 +3825,8 @@ ast2iCode (ast * tree,int lvl) tree->opval.op != '?' && tree->opval.op != CALL && tree->opval.op != IFX && + tree->opval.op != AND_OP && + tree->opval.op != OR_OP && tree->opval.op != LABEL && tree->opval.op != GOTO && tree->opval.op != SWITCH && @@ -3796,35 +3932,42 @@ ast2iCode (ast * tree,int lvl) case '/': return geniCodeDivision (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case '%': return geniCodeModulus (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case '*': if (right) return geniCodeMultiply (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE),IS_INT(tree->ftype)); + geniCodeRValue (right, FALSE), + 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 */ case LEFT_OP: return geniCodeLeftShift (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case RIGHT_OP: return geniCodeRightShift (geniCodeRValue (left, FALSE), @@ -3862,28 +4005,29 @@ ast2iCode (ast * tree,int lvl) setOperandType (op, UCHARTYPE); return op; } + case AND_OP: + case OR_OP: + return geniCodeLogicAndOr (tree, lvl); case '>': case '<': case LE_OP: case GE_OP: case EQ_OP: case NE_OP: - case AND_OP: - case OR_OP: /* different compilers (even different gccs) evaluate - the two calls in a different order. to get the same - result on all machines we've to specify a clear sequence. + the two calls in a different order. to get the same + result on all machines we've to specify a clear sequence. return geniCodeLogic (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE), tree->opval.op); */ { - operand *leftOp, *rightOp; + operand *leftOp, *rightOp; - rightOp = geniCodeRValue (right, FALSE); - leftOp = geniCodeRValue (left , FALSE); + leftOp = geniCodeRValue (left , FALSE); + rightOp = geniCodeRValue (right, FALSE); - return geniCodeLogic (leftOp, rightOp, tree->opval.op); + return geniCodeLogic (leftOp, rightOp, tree->opval.op); } case '?': return geniCodeConditional (tree,lvl); @@ -3901,7 +4045,7 @@ ast2iCode (ast * tree,int lvl) else right = geniCodeRValue (right, FALSE); - geniCodeAssign (left, right, 0); + geniCodeAssign (left, right, 0, 1); return right; } case MUL_ASSIGN: @@ -3909,20 +4053,26 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeMultiply (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE),FALSE), 0); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case DIV_ASSIGN: return geniCodeAssign (left, geniCodeDivision (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE)), 0); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case MOD_ASSIGN: return geniCodeAssign (left, geniCodeModulus (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE)), 0); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case ADD_ASSIGN: { sym_link *rtype = operandType (right); @@ -3937,7 +4087,10 @@ ast2iCode (ast * tree,int lvl) return geniCodeAssign (left, geniCodeAdd (geniCodeRValue (operandFromOperand (left), FALSE), - right,lvl), 0); + right, + getResultTypeFromType (tree->ftype), + lvl), + 0, 1); } case SUB_ASSIGN: { @@ -3956,20 +4109,24 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeSubtract (geniCodeRValue (operandFromOperand (left), FALSE), - right), 0); + right, + getResultTypeFromType (tree->ftype)), + 0, 1); } case LEFT_ASSIGN: return geniCodeAssign (left, geniCodeLeftShift (geniCodeRValue (operandFromOperand (left) ,FALSE), - geniCodeRValue (right, FALSE)), 0); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case RIGHT_ASSIGN: return geniCodeAssign (left, geniCodeRightShift (geniCodeRValue (operandFromOperand (left) ,FALSE), - geniCodeRValue (right, FALSE)), 0); + geniCodeRValue (right, FALSE)), 0, 1); case AND_ASSIGN: return geniCodeAssign (left, @@ -3977,7 +4134,7 @@ ast2iCode (ast * tree,int lvl) FALSE), geniCodeRValue (right, FALSE), BITWISEAND, - operandType (left)), 0); + operandType (left)), 0, 1); case XOR_ASSIGN: return geniCodeAssign (left, @@ -3985,7 +4142,7 @@ ast2iCode (ast * tree,int lvl) FALSE), geniCodeRValue (right, FALSE), '^', - operandType (left)), 0); + operandType (left)), 0, 1); case OR_ASSIGN: return geniCodeAssign (left, @@ -3993,7 +4150,7 @@ ast2iCode (ast * tree,int lvl) ,FALSE), geniCodeRValue (right, FALSE), '|', - operandType (left)), 0); + operandType (left)), 0, 1); case ',': return geniCodeRValue (right, FALSE);