X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=4e93c888ce17805e5b38e4ade37243139f6c8165;hb=d46b4a50e1b8b1819d974533a9012b013090f8fd;hp=e9f6b3b1401227e4ed564186f2c05802c646694c;hpb=6e277036fcd90fdc1ceb64994e08bc59fbd215e6;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index e9f6b3b1..4e93c888 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -37,7 +37,6 @@ char *filename; int lineno; int block; int scopeLevel; -int lvaluereq; symbol *returnLabel; /* function return label */ symbol *entryLabel; /* function entry label */ @@ -45,13 +44,14 @@ symbol *entryLabel; /* function entry label */ /* forward definition of some functions */ operand *geniCodeDivision (operand *, operand *); operand *geniCodeAssign (operand *, operand *, int); -operand *geniCodeArray (operand *, operand *); +operand *geniCodeArray (operand *, operand *,int); operand *geniCodeArray2Ptr (operand *); operand *geniCodeRValue (operand *, bool); -operand *geniCodeDerefPtr (operand *); +operand *geniCodeDerefPtr (operand *,int); +int isLvaluereq(int lvl); #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) -/* forward definition of print functions */ +/* forward definition of ic print functions */ PRINTFUNC (picGetValueAtAddr); PRINTFUNC (picSetValueAtAddr); PRINTFUNC (picAddrOf); @@ -398,6 +398,10 @@ piCode (void *item, FILE * of) return 1; } +void PICC(iCode *ic) +{ + printiCChain(ic,stdout); +} /*-----------------------------------------------------------------*/ /* printiCChain - prints intermediate code for humans */ /*-----------------------------------------------------------------*/ @@ -535,7 +539,7 @@ newiTempLabel (char *s) itmplbl->isitmp = 1; itmplbl->islbl = 1; itmplbl->key = labelKey++; - addSym (LabelTab, itmplbl, itmplbl->name, 0, 0); + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0); return itmplbl; } @@ -553,7 +557,7 @@ newiTempPreheaderLabel () itmplbl->isitmp = 1; itmplbl->islbl = 1; itmplbl->key = labelKey++; - addSym (LabelTab, itmplbl, itmplbl->name, 0, 0); + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0); return itmplbl; } @@ -579,6 +583,7 @@ copyiCode (iCode * ic) nic->filename = ic->filename; nic->block = ic->block; nic->level = ic->level; + nic->parmBytes = ic->parmBytes; /* deal with the special cases first */ switch (ic->op) @@ -834,11 +839,15 @@ operand * operandOperation (operand * left, operand * right, int op, sym_link * type) { + sym_link *let , *ret=NULL; operand *retval = (operand *) 0; - + assert (isOperandLiteral (left)); - if (right) + let = getSpec(operandType(left)); + if (right) { assert (isOperandLiteral (right)); + ret = getSpec(operandType(left)); + } switch (op) { @@ -870,22 +879,34 @@ operandOperation (operand * left, operand * right, operandLitValue (right))); break; case '%': - if ((unsigned long) operandLitValue (right) == 0) - { + if ((unsigned long) operandLitValue (right) == 0) { werror (E_DIVIDE_BY_ZERO); retval = right; - } - else - retval = operandFromLit ((unsigned long) operandLitValue (left) % - (unsigned long) operandLitValue (right)); + } + else + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) % + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); + break; case LEFT_OP: - retval = operandFromLit ((unsigned long) operandLitValue (left) << - (unsigned long) operandLitValue (right)); + retval = operandFromLit (((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) << + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right)))); break; case RIGHT_OP: - retval = operandFromLit ((unsigned long) operandLitValue (left) >> - (unsigned long) operandLitValue (right)); + retval = operandFromLit (((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) >> + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right)))); break; case EQ_OP: retval = operandFromLit (operandLitValue (left) == @@ -933,7 +954,7 @@ operandOperation (operand * left, operand * right, break; case RRC: { - long i = operandLitValue (left); + long i = (long) operandLitValue (left); retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | (i << 1)); @@ -941,7 +962,7 @@ operandOperation (operand * left, operand * right, break; case RLC: { - long i = operandLitValue (left); + long i = (long) operandLitValue (left); retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | (i >> 1)); @@ -1000,7 +1021,7 @@ isOperandEqual (operand * left, operand * right) return (floatFromVal (left->operand.valOperand) == floatFromVal (right->operand.valOperand)); case TYPE: - if (checkType (left->operand.typeOperand, + if (compareType (left->operand.typeOperand, right->operand.typeOperand) == 1) return 1; } @@ -1071,7 +1092,6 @@ newiTempFromOp (operand * op) nop->noSpilLoc = op->noSpilLoc; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; - nop->parmBytes = op->parmBytes; return nop; } @@ -1095,7 +1115,6 @@ operandFromOperand (operand * op) nop->noSpilLoc = op->noSpilLoc; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; - nop->parmBytes = op->parmBytes; switch (nop->type) { @@ -1157,14 +1176,13 @@ operandFromSymbol (symbol * sym) op->key = sym->key; op->isvolatile = isOperandVolatile (op, TRUE); op->isGlobal = isOperandGlobal (op); - op->parmBytes = sym->argStack; return op; } /* under the following conditions create a register equivalent for a local symbol */ if (sym->level && sym->etype && SPEC_OCLS (sym->etype) && - (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) && + (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) && options.stackAuto == 0) ok = 0; @@ -1276,7 +1294,7 @@ operandFromLink (sym_link * type) /* operandFromLit - makes an operand from a literal value */ /*-----------------------------------------------------------------*/ operand * -operandFromLit (float i) +operandFromLit (double i) { return operandFromValue (valueFromLit (i)); } @@ -1285,7 +1303,7 @@ operandFromLit (float i) /* operandFromAst - creates an operand from an ast */ /*-----------------------------------------------------------------*/ operand * -operandFromAst (ast * tree) +operandFromAst (ast * tree,int lvl) { if (!tree) @@ -1295,7 +1313,7 @@ operandFromAst (ast * tree) switch (tree->type) { case EX_OP: - return ast2iCode (tree); + return ast2iCode (tree,lvl+1); break; case EX_VALUE: @@ -1343,6 +1361,43 @@ setOperandType (operand * op, sym_link * type) } } +/*-----------------------------------------------------------------*/ +/* Get size in byte of ptr need to access an array */ +/*-----------------------------------------------------------------*/ +int +getArraySizePtr (operand * op) +{ + sym_link *ltype = operandType(op); + + if(IS_PTR(ltype)) + { + int size = getSize(ltype); + return(IS_GENPTR(ltype)?(size-1):size); + } + + if(IS_ARRAY(ltype)) + { + sym_link *letype = getSpec(ltype); + switch (PTR_TYPE (SPEC_OCLS (letype))) + { + case IPOINTER: + case PPOINTER: + case POINTER: + return (PTRSIZE); + case EEPPOINTER: + case FPOINTER: + case CPOINTER: + case FUNCTION: + return (FPTRSIZE); + case GPOINTER: + return (GPTRSIZE-1); + + default: + return (FPTRSIZE); + } + } + return (FPTRSIZE); +} /*-----------------------------------------------------------------*/ /* perform "usual unary conversions" */ @@ -1352,7 +1407,7 @@ usualUnaryConversions (operand * op) { if (IS_INTEGRAL (operandType (op))) { - if (getSize (operandType (op)) < INTSIZE) + if (getSize (operandType (op)) < (unsigned int) INTSIZE) { /* Widen to int. */ return geniCodeCast (INTTYPE, op, TRUE); @@ -1367,122 +1422,17 @@ usualUnaryConversions (operand * op) 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)); + 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; } - /*-----------------------------------------------------------------*/ /* geniCodeValueAtAddress - generate intermeditate code for value */ /* at address */ @@ -1517,7 +1467,7 @@ geniCodeRValue (operand * op, bool force) if (IS_SPEC (type) && IS_TRUE_SYMOP (op) && - (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT)) + (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390)) { op = operandFromOperand (op); op->isaddr = 0; @@ -1563,7 +1513,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } /* if the operand is already the desired type then do nothing */ - if (checkType (type, optype) == 1) + if (compareType (type, optype) == 1) return op; /* if this is a literal then just change the type & return */ @@ -1579,7 +1529,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) !IS_GENPTR (type)) { werror (E_INCOMPAT_CAST); - werror (E_CONTINUE, "from type '"); + fprintf (stderr, "from type '"); printTypeChain (optype, stderr); fprintf (stderr, "' to type '"); printTypeChain (type, stderr); @@ -1647,11 +1597,10 @@ geniCodeGoto (symbol * label) /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ operand * -geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation) +geniCodeMultiply (operand * left, operand * right,int resultIsInt) { iCode *ic; int p2 = 0; - int saveOption; sym_link *resType; LRTYPE; @@ -1660,50 +1609,38 @@ geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation) return operandFromValue (valMult (left->operand.valOperand, right->operand.valOperand)); + if (IS_LITERAL(retype)) { + p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)); + } - //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size - if ((ptrSizeCalculation) && (1 == getSize (rtype)) && - (1 == getSize (ltype))) + resType = usualBinaryConversions (&left, &right); +#if 1 + rtype = operandType (right); + retype = getSpec (rtype); + ltype = operandType (left); + letype = getSpec (ltype); +#endif + if (resultIsInt) { - saveOption = options.ANSIint; - options.ANSIint = 0; - resType = usualBinaryConversions (&left, &right); - ltype = operandType (left); - rtype = operandType (right); - SPEC_SHORT (getSpec (resType)) = 0; - options.ANSIint = saveOption; - } - else { - resType = usualBinaryConversions (&left, &right); - if (IS_DS390_PORT) { - /* jwk char*char=int - Now be can use the 16bit result of "mul a,b" instead of explicit - casts and support function calls as with --ansiint - */ - if ((IS_CHAR(letype) || IS_SHORT(letype)) && - (IS_CHAR(retype) || IS_SHORT(retype))) { - SPEC_NOUN(getSpec(resType))=V_INT; - SPEC_SHORT(getSpec(resType))=0; - } + SPEC_NOUN(getSpec(resType))=V_INT; } - } /* if the right is a literal & power of 2 */ /* then make it a left shift */ - /*If we are computing ptr size then normal multiplication */ - /*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 as 1 byte muldiv */ - if (IS_LITERAL (retype) && !IS_FLOAT (letype) && - !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) && - (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)))) - { - if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype))) + /* 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 ((resultIsInt) && (getSize (resType) != getSize (ltype))) { /* LEFT_OP need same size for left and result, */ left = geniCodeCast (resType, left, TRUE); ltype = operandType (left); } - ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */ + ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */ } else { @@ -1740,8 +1677,9 @@ geniCodeDivision (operand * left, operand * right) if (IS_LITERAL (retype) && !IS_FLOAT (letype) && (p2 = powof2 ((unsigned long) - floatFromVal (right->operand.valOperand)))) - ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ + floatFromVal (right->operand.valOperand)))) { + ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ + } else { ic = newiCode ('/', left, right); /* normal division */ @@ -1838,7 +1776,7 @@ geniCodeSubtract (operand * left, operand * right) { isarray = left->isaddr; right = geniCodeMultiply (right, - operandFromLit (getSize (ltype->next)), TRUE); + operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype); } else @@ -1863,7 +1801,7 @@ geniCodeSubtract (operand * left, operand * right) /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ operand * -geniCodeAdd (operand * left, operand * right) +geniCodeAdd (operand * left, operand * right,int lvl) { iCode *ic; sym_link *resType; @@ -1873,7 +1811,7 @@ geniCodeAdd (operand * left, operand * right) /* if left is an array then array access */ if (IS_ARRAY (ltype)) - return geniCodeArray (left, right); + return geniCodeArray (left, right,lvl); /* if the right side is LITERAL zero */ /* return the left side */ @@ -1887,13 +1825,12 @@ geniCodeAdd (operand * left, operand * right) /* if left is an array or pointer then size */ if (IS_PTR (ltype)) { - isarray = left->isaddr; - size = - operandFromLit (getSize (ltype->next)); - - right = geniCodeMultiply (right, size, (getSize (ltype) != 1)); - + // there is no need to multiply with 1 + if (getSize(ltype->next)!=1) { + size = operandFromLit (getSize (ltype->next)); + right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + } resType = copyLinkChain (ltype); } else @@ -1986,7 +1923,7 @@ geniCodeArray2Ptr (operand * op) /* geniCodeArray - array access */ /*-----------------------------------------------------------------*/ operand * -geniCodeArray (operand * left, operand * right) +geniCodeArray (operand * left, operand * right,int lvl) { iCode *ic; sym_link *ltype = operandType (left); @@ -1997,12 +1934,11 @@ geniCodeArray (operand * left, operand * right) { left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, right)); + return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl); } - /* array access */ right = geniCodeMultiply (right, - operandFromLit (getSize (ltype->next)), TRUE); + operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); /* we can check for limits here */ if (isOperandLiteral (right) && @@ -2336,7 +2272,7 @@ setOClass (sym_link * ptr, sym_link * spec) /* geniCodeDerefPtr - dereference pointer with '*' */ /*-----------------------------------------------------------------*/ operand * -geniCodeDerefPtr (operand * op) +geniCodeDerefPtr (operand * op,int lvl) { sym_link *rtype, *retype; sym_link *optype = operandType (op); @@ -2354,7 +2290,7 @@ geniCodeDerefPtr (operand * op) } /* now get rid of the pointer part */ - if (lvaluereq && IS_ITEMP (op)) + if (isLvaluereq(lvl) && IS_ITEMP (op)) { retype = getSpec (rtype = copyLinkChain (optype)); } @@ -2380,7 +2316,7 @@ geniCodeDerefPtr (operand * op) IS_CHAR (rtype) || IS_FLOAT (rtype)); - if (!lvaluereq) + if (!isLvaluereq(lvl)) op = geniCodeRValue (op, TRUE); setOperandType (op, rtype); @@ -2414,16 +2350,6 @@ geniCodeLeftShift (operand * left, operand * right) { iCode *ic; - - /* Note that we don't use the usual binary conversions for the - * shift operations, in accordance with our ANSI friends. - */ - if (options.ANSIint) - { - right = usualUnaryConversions (right); - left = usualUnaryConversions (left); - } - ic = newiCode (LEFT_OP, left, right); IC_RESULT (ic) = newiTempOperand (operandType (left), 0); ADDTOCHAIN (ic); @@ -2438,16 +2364,6 @@ geniCodeRightShift (operand * left, operand * right) { iCode *ic; - - /* Note that we don't use the usual binary conversions for the - * shift operations, in accordance with our ANSI friends. - */ - if (options.ANSIint) - { - right = usualUnaryConversions (right); - left = usualUnaryConversions (left); - } - ic = newiCode (RIGHT_OP, left, right); IC_RESULT (ic) = newiTempOperand (operandType (left), 0); ADDTOCHAIN (ic); @@ -2476,9 +2392,9 @@ geniCodeLogic (operand * left, operand * right, int op) if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype)) { int nbits = bitsForType (ltype); - long v = operandLitValue (right); + long v = (long) operandLitValue (right); - if (v > ((LONG_LONG) 1 << nbits) && v > 0) + if (v >= ((LONG_LONG) 1 << nbits) && v > 0) werror (W_CONST_RANGE, " compare operation "); } @@ -2487,10 +2403,10 @@ geniCodeLogic (operand * left, operand * right, int op) ic = newiCode (op, left, right); IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); - /* if comparing anything greater than one byte + /* if comparing float and not a '==' || '!=' || '&&' || '||' (these will be inlined */ - if (getSize (ctype) > 1 && + if (IS_FLOAT(ctype) && op != EQ_OP && op != NE_OP && op != AND_OP && @@ -2518,19 +2434,19 @@ geniCodeUnary (operand * op, int oper) /* geniCodeConditional - geniCode for '?' ':' operation */ /*-----------------------------------------------------------------*/ operand * -geniCodeConditional (ast * tree) +geniCodeConditional (ast * tree,int lvl) { iCode *ic; symbol *falseLabel = newiTempLabel (NULL); symbol *exitLabel = newiTempLabel (NULL); - operand *cond = ast2iCode (tree->left); + operand *cond = ast2iCode (tree->left,lvl+1); operand *true, *false, *result; ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel); ADDTOCHAIN (ic); - true = ast2iCode (tree->right->left); + true = ast2iCode (tree->right->left,lvl+1); /* move the value to a new Operand */ result = newiTempOperand (operandType (true), 0); @@ -2542,7 +2458,7 @@ geniCodeConditional (ast * tree) /* now for the right side */ geniCodeLabel (falseLabel); - false = ast2iCode (tree->right->right); + false = ast2iCode (tree->right->right,lvl+1); geniCodeAssign (result, geniCodeRValue (false, FALSE), 0); /* create the exit label */ @@ -2572,9 +2488,9 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) { int nbits = bitsForType (ltype); - long v = operandLitValue (right); + long v = (long) operandLitValue (right); - if (v > ((LONG_LONG) 1 << nbits) && v > 0) + if (v >= ((LONG_LONG) 1 << nbits) && v > 0) werror (W_CONST_RANGE, " = operation"); } @@ -2585,12 +2501,12 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) /* first check the type for pointer assignement */ if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) && - checkType (ltype, rtype) < 0) + compareType (ltype, rtype) < 0) { - if (checkType (ltype->next, rtype) < 0) + if (compareType (ltype->next, rtype) < 0) right = geniCodeCast (ltype->next, right, TRUE); } - else if (checkType (ltype, rtype) < 0) + else if (compareType (ltype, rtype) < 0) right = geniCodeCast (ltype, right, TRUE); /* if left is a true symbol & ! volatile @@ -2629,15 +2545,15 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) /* geniCodeSEParms - generate code for side effecting fcalls */ /*-----------------------------------------------------------------*/ static void -geniCodeSEParms (ast * parms) +geniCodeSEParms (ast * parms,int lvl) { if (!parms) return; if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeSEParms (parms->left); - geniCodeSEParms (parms->right); + geniCodeSEParms (parms->left,lvl); + geniCodeSEParms (parms->right,lvl); return; } @@ -2652,7 +2568,7 @@ geniCodeSEParms (ast * parms) parms->right->left->lvalue = 1; parms->opval.oprnd = - geniCodeRValue (ast2iCode (parms), FALSE); + geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); parms->type = EX_OPERAND; } @@ -2661,7 +2577,7 @@ geniCodeSEParms (ast * parms) /* geniCodeParms - generates parameters */ /*-----------------------------------------------------------------*/ static void -geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) +geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl) { iCode *ic; operand *pval; @@ -2672,8 +2588,8 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) /* if this is a param node then do the left & right */ if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeParms (parms->left, stack, fetype, func); - geniCodeParms (parms->right, stack, fetype, func); + geniCodeParms (parms->left, stack, fetype, func,lvl); + geniCodeParms (parms->right, stack, fetype, func,lvl); return; } @@ -2693,7 +2609,7 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) IS_ADDRESS_OF_OP (parms->right)) parms->right->left->lvalue = 1; - pval = geniCodeRValue (ast2iCode (parms), FALSE); + pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); } /* if register parm then make it a send */ @@ -2731,7 +2647,7 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) /* geniCodeCall - generates temp code for calling */ /*-----------------------------------------------------------------*/ operand * -geniCodeCall (operand * left, ast * parms) +geniCodeCall (operand * left, ast * parms,int lvl) { iCode *ic; operand *result; @@ -2741,13 +2657,13 @@ geniCodeCall (operand * left, ast * parms) /* take care of parameters with side-effecting function calls in them, this is required to take care of overlaying function parameters */ - geniCodeSEParms (parms); + geniCodeSEParms (parms,lvl); /* first the parameters */ - geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left)); + geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl); /* now call : if symbol then pcall */ - if (IS_ITEMP (left)) + if (IS_OP_POINTER (left) || IS_ITEMP(left)) ic = newiCode (PCALL, left, NULL); else ic = newiCode (CALL, left, NULL); @@ -2761,7 +2677,7 @@ geniCodeCall (operand * left, ast * parms) ADDTOCHAIN (ic); /* stack adjustment after call */ - left->parmBytes = stack; + ic->parmBytes = stack; return result; } @@ -2790,7 +2706,7 @@ geniCodeReceive (value * args) if (IN_FARSPACE (SPEC_OCLS (sym->etype)) && options.stackAuto == 0 && - !IS_DS390_PORT) + !TARGET_IS_DS390) { } else @@ -2819,7 +2735,7 @@ geniCodeReceive (value * args) /* geniCodeFunctionBody - create the function body */ /*-----------------------------------------------------------------*/ void -geniCodeFunctionBody (ast * tree) +geniCodeFunctionBody (ast * tree,int lvl) { iCode *ic; operand *func; @@ -2832,7 +2748,7 @@ geniCodeFunctionBody (ast * tree) iTempLblNum = 0; operandKey = 0; iCodeKey = 0; - func = ast2iCode (tree->left); + func = ast2iCode (tree->left,lvl+1); fetype = getSpec (operandType (func)); savelineno = lineno; @@ -2855,7 +2771,7 @@ geniCodeFunctionBody (ast * tree) geniCodeReceive (tree->values.args); /* generate code for the body */ - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); /* create a label for return */ geniCodeLabel (returnLabel); @@ -2886,10 +2802,10 @@ geniCodeReturn (operand * op) /* geniCodeIfx - generates code for extended if statement */ /*-----------------------------------------------------------------*/ void -geniCodeIfx (ast * tree) +geniCodeIfx (ast * tree,int lvl) { iCode *ic; - operand *condition = ast2iCode (tree->left); + operand *condition = ast2iCode (tree->left,lvl+1); sym_link *cetype; /* if condition is null then exit */ @@ -2938,7 +2854,7 @@ geniCodeIfx (ast * tree) } exit: - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ @@ -3036,10 +2952,10 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* geniCodeSwitch - changes a switch to a if statement */ /*-----------------------------------------------------------------*/ void -geniCodeSwitch (ast * tree) +geniCodeSwitch (ast * tree,int lvl) { iCode *ic; - operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE); + operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE); value *caseVals = tree->values.switchVals.swVals; symbol *trueLabel, *falseLabel; @@ -3077,7 +2993,7 @@ geniCodeSwitch (ast * tree) geniCodeGoto (falseLabel); jumpTable: - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ @@ -3093,18 +3009,78 @@ geniCodeInline (ast * tree) ADDTOCHAIN (ic); } +/*-----------------------------------------------------------------*/ +/* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */ +/* particular case. Ie : assigning or dereferencing array or ptr */ +/*-----------------------------------------------------------------*/ +set * lvaluereqSet = NULL; +typedef struct lvalItem + { + int req; + int lvl; + } +lvalItem; + +/*-----------------------------------------------------------------*/ +/* addLvaluereq - add a flag for lvalreq for current ast level */ +/*-----------------------------------------------------------------*/ +void addLvaluereq(int lvl) +{ + lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem)); + lpItem->req=1; + lpItem->lvl=lvl; + addSetHead(&lvaluereqSet,lpItem); + +} +/*-----------------------------------------------------------------*/ +/* delLvaluereq - del a flag for lvalreq for current ast level */ +/*-----------------------------------------------------------------*/ +void delLvaluereq() +{ + lvalItem * lpItem; + lpItem = getSet(&lvaluereqSet); + if(lpItem) free(lpItem); +} +/*-----------------------------------------------------------------*/ +/* clearLvaluereq - clear lvalreq flag */ +/*-----------------------------------------------------------------*/ +void clearLvaluereq() +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) lpItem->req = 0; +} +/*-----------------------------------------------------------------*/ +/* getLvaluereq - get the last lvalreq level */ +/*-----------------------------------------------------------------*/ +int getLvaluereqLvl() +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) return lpItem->lvl; + return 0; +} +/*-----------------------------------------------------------------*/ +/* isLvaluereq - is lvalreq valid for this level ? */ +/*-----------------------------------------------------------------*/ +int isLvaluereq(int lvl) +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1))); + return 0; +} + /*-----------------------------------------------------------------*/ /* ast2iCode - creates an icodeList from an ast */ /*-----------------------------------------------------------------*/ operand * -ast2iCode (ast * tree) +ast2iCode (ast * tree,int lvl) { operand *left = NULL; operand *right = NULL; - if (!tree) return NULL; - /* set the global variables for filename & line number */ if (tree->filename) filename = tree->filename; @@ -3123,11 +3099,11 @@ ast2iCode (ast * tree) /* if we find a nullop */ if (tree->type == EX_OP && - (tree->opval.op == NULLOP || - tree->opval.op == BLOCK)) + (tree->opval.op == NULLOP || + tree->opval.op == BLOCK)) { - ast2iCode (tree->left); - ast2iCode (tree->right); + ast2iCode (tree->left,lvl+1); + ast2iCode (tree->right,lvl+1); return NULL; } @@ -3143,44 +3119,37 @@ ast2iCode (ast * tree) tree->opval.op != INLINEASM) { - if (IS_ASSIGN_OP (tree->opval.op) || - IS_DEREF_OP (tree) || - (tree->opval.op == '&' && !tree->right) || - tree->opval.op == PTR_OP) - { - lvaluereq++; - if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) || - (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left))) - { - int olvr = lvaluereq; - lvaluereq = 0; - left = operandFromAst (tree->left); - lvaluereq = olvr - 1; - } - else - { - left = operandFromAst (tree->left); - lvaluereq--; - } - if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) - left = geniCodeRValue (left, TRUE); - } - else - { - left = operandFromAst (tree->left); - } - if (tree->opval.op == INC_OP || - tree->opval.op == DEC_OP) - { - lvaluereq++; - right = operandFromAst (tree->right); - lvaluereq--; - } - else - { - right = operandFromAst (tree->right); - } - } + if (IS_ASSIGN_OP (tree->opval.op) || + IS_DEREF_OP (tree) || + (tree->opval.op == '&' && !tree->right) || + tree->opval.op == PTR_OP) + { + addLvaluereq(lvl); + if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) || + (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left))) + clearLvaluereq(); + + left = operandFromAst (tree->left,lvl); + delLvaluereq(); + if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) + left = geniCodeRValue (left, TRUE); + } + else + { + left = operandFromAst (tree->left,lvl); + } + if (tree->opval.op == INC_OP || + tree->opval.op == DEC_OP) + { + addLvaluereq(lvl); + right = operandFromAst (tree->right,lvl); + delLvaluereq(); + } + else + { + right = operandFromAst (tree->right,lvl); + } + } /* now depending on the type of operand */ /* this will be a biggy */ @@ -3194,7 +3163,7 @@ ast2iCode (ast * tree) right = geniCodeRValue (right, TRUE); } - return geniCodeArray (left, right); + return geniCodeArray (left, right,lvl); case '.': /* structure dereference */ if (IS_PTR (operandType (left))) @@ -3254,9 +3223,9 @@ ast2iCode (ast * tree) case '*': if (right) return geniCodeMultiply (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), FALSE); + geniCodeRValue (right, FALSE),IS_INT(tree->ftype)); else - return geniCodeDerefPtr (geniCodeRValue (left, FALSE)); + return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': if (right) @@ -3268,7 +3237,7 @@ ast2iCode (ast * tree) case '+': if (right) return geniCodeAdd (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE),lvl); else return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ @@ -3307,7 +3276,7 @@ ast2iCode (ast * tree) geniCodeRValue (right, FALSE), tree->opval.op); case '?': - return geniCodeConditional (tree); + return geniCodeConditional (tree,lvl); case SIZEOF: return operandFromLit (getSize (tree->right->ftype)); @@ -3317,7 +3286,7 @@ ast2iCode (ast * tree) sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && checkType (rtype->next, ltype) == 1) + && right->isaddr && compareType (rtype->next, ltype) == 1) right = geniCodeRValue (right, TRUE); else right = geniCodeRValue (right, FALSE); @@ -3330,7 +3299,7 @@ ast2iCode (ast * tree) geniCodeAssign (left, geniCodeMultiply (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE), FALSE), 0); + geniCodeRValue (right, FALSE),FALSE), 0); case DIV_ASSIGN: return @@ -3349,7 +3318,7 @@ ast2iCode (ast * tree) sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && checkType (rtype->next, ltype) == 1) + && right->isaddr && compareType (rtype->next, ltype) == 1) right = geniCodeRValue (right, TRUE); else right = geniCodeRValue (right, FALSE); @@ -3358,14 +3327,14 @@ ast2iCode (ast * tree) return geniCodeAssign (left, geniCodeAdd (geniCodeRValue (operandFromOperand (left), FALSE), - right), 0); + right,lvl), 0); } case SUB_ASSIGN: { sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && checkType (rtype->next, ltype) == 1) + && right->isaddr && compareType (rtype->next, ltype) == 1) { right = geniCodeRValue (right, TRUE); } @@ -3419,18 +3388,18 @@ ast2iCode (ast * tree) return geniCodeRValue (right, FALSE); case CALL: - return geniCodeCall (ast2iCode (tree->left), - tree->right); + return geniCodeCall (ast2iCode (tree->left,lvl+1), + tree->right,lvl); case LABEL: - geniCodeLabel (ast2iCode (tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand); + return ast2iCode (tree->right,lvl+1); case GOTO: - geniCodeGoto (ast2iCode (tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand); + return ast2iCode (tree->right,lvl+1); case FUNCTION: - geniCodeFunctionBody (tree); + geniCodeFunctionBody (tree,lvl); return NULL; case RETURN: @@ -3438,11 +3407,11 @@ ast2iCode (ast * tree) return NULL; case IFX: - geniCodeIfx (tree); + geniCodeIfx (tree,lvl); return NULL; case SWITCH: - geniCodeSwitch (tree); + geniCodeSwitch (tree,lvl); return NULL; case INLINEASM: @@ -3482,6 +3451,6 @@ iCodeFromAst (ast * tree) { returnLabel = newiTempLabel ("_return"); entryLabel = newiTempLabel ("_entry"); - ast2iCode (tree); + ast2iCode (tree,0); return reverseiCChain (); }