X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=b5885e01aff796a178133418581f622b462179e2;hb=c4b55ee40ddb79b816c42b1567dc9b5858153b66;hp=84c6123f18fc43e1c0fb103b1c3479253b47ce11;hpb=ea34442f1a2452c591734d551d76e46718665404;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 84c6123f..b5885e01 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,10 +44,11 @@ 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 ic print functions */ @@ -109,7 +109,8 @@ iCodeTable codeTable[] = {IFX, "if", picIfx, NULL}, {INLINEASM, "", picInline, NULL}, {RECEIVE, "recv", picReceive, NULL}, - {SEND, "send", picGenericOne, NULL} + {SEND, "send", picGenericOne, NULL}, + {ARRAYINIT, "arrayInit", picGenericOne, NULL}, }; @@ -146,12 +147,12 @@ printOperand (operand * op, FILE * file) case SYMBOL: #define REGA 1 #ifdef REGA - fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ + fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), op->key, OP_LIVEFROM (op), OP_LIVETO (op), OP_SYMBOL (op)->stack, - op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat + op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc ); { fprintf (file, "{"); @@ -539,7 +540,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; } @@ -557,7 +558,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; } @@ -610,6 +611,10 @@ copyiCode (iCode * ic) IC_INLINE (nic) = IC_INLINE (ic); break; + case ARRAYINIT: + IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic); + break; + default: IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); @@ -839,11 +844,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) { @@ -875,22 +884,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) == @@ -938,7 +959,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)); @@ -946,7 +967,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)); @@ -1005,7 +1026,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; } @@ -1073,7 +1094,6 @@ newiTempFromOp (operand * op) nop->isvolatile = op->isvolatile; nop->isGlobal = op->isGlobal; nop->isLiteral = op->isLiteral; - nop->noSpilLoc = op->noSpilLoc; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; return nop; @@ -1096,7 +1116,6 @@ operandFromOperand (operand * op) nop->isvolatile = op->isvolatile; nop->isGlobal = op->isGlobal; nop->isLiteral = op->isLiteral; - nop->noSpilLoc = op->noSpilLoc; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; @@ -1278,7 +1297,7 @@ operandFromLink (sym_link * type) /* operandFromLit - makes an operand from a literal value */ /*-----------------------------------------------------------------*/ operand * -operandFromLit (float i) +operandFromLit (double i) { return operandFromValue (valueFromLit (i)); } @@ -1287,7 +1306,7 @@ operandFromLit (float i) /* operandFromAst - creates an operand from an ast */ /*-----------------------------------------------------------------*/ operand * -operandFromAst (ast * tree) +operandFromAst (ast * tree,int lvl) { if (!tree) @@ -1297,7 +1316,7 @@ operandFromAst (ast * tree) switch (tree->type) { case EX_OP: - return ast2iCode (tree); + return ast2iCode (tree,lvl+1); break; case EX_VALUE: @@ -1391,7 +1410,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); @@ -1406,122 +1425,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 */ @@ -1602,7 +1516,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 */ @@ -1618,7 +1532,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); @@ -1690,7 +1604,6 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) { iCode *ic; int p2 = 0; - int saveOption=0; sym_link *resType; LRTYPE; @@ -1699,26 +1612,30 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) return operandFromValue (valMult (left->operand.valOperand, right->operand.valOperand)); - if (resultIsInt) - { - saveOption = options.ANSIint; - options.ANSIint = 0; - } + if (IS_LITERAL(retype)) { + p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)); + } + resType = usualBinaryConversions (&left, &right); +#if 1 + rtype = operandType (right); + retype = getSpec (rtype); + ltype = operandType (left); + letype = getSpec (ltype); +#endif if (resultIsInt) { - options.ANSIint = saveOption; SPEC_NOUN(getSpec(resType))=V_INT; - SPEC_SHORT(getSpec(resType))=0; } /* if the right is a literal & power of 2 */ /* then make it a left shift */ - /*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) && - !((resultIsInt) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) && - (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)))) + /* 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))) { @@ -1726,7 +1643,7 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) 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 { @@ -1763,8 +1680,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 */ @@ -1886,7 +1804,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; @@ -1896,7 +1814,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 */ @@ -1911,8 +1829,11 @@ geniCodeAdd (operand * left, operand * right) if (IS_PTR (ltype)) { isarray = left->isaddr; - size = operandFromLit (getSize (ltype->next)); - right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + // 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 @@ -2005,7 +1926,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); @@ -2016,7 +1937,7 @@ geniCodeArray (operand * left, operand * right) { left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, right)); + return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl); } right = geniCodeMultiply (right, @@ -2103,10 +2024,10 @@ geniCodePostInc (operand * op) } rOp = newiTempOperand (rvtype, 0); - rOp->noSpilLoc = 1; + OP_SYMBOL(rOp)->noSpilLoc = 1; if (IS_ITEMP (rv)) - rv->noSpilLoc = 1; + OP_SYMBOL(rv)->noSpilLoc = 1; geniCodeAssign (rOp, rv, 0); @@ -2183,10 +2104,10 @@ geniCodePostDec (operand * op) } rOp = newiTempOperand (rvtype, 0); - rOp->noSpilLoc = 1; + OP_SYMBOL(rOp)->noSpilLoc = 1; if (IS_ITEMP (rv)) - rv->noSpilLoc = 1; + OP_SYMBOL(rv)->noSpilLoc = 1; geniCodeAssign (rOp, rv, 0); @@ -2354,7 +2275,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); @@ -2372,7 +2293,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)); } @@ -2398,7 +2319,7 @@ geniCodeDerefPtr (operand * op) IS_CHAR (rtype) || IS_FLOAT (rtype)); - if (!lvaluereq) + if (!isLvaluereq(lvl)) op = geniCodeRValue (op, TRUE); setOperandType (op, rtype); @@ -2432,16 +2353,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); @@ -2456,16 +2367,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); @@ -2494,9 +2395,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 "); } @@ -2505,10 +2406,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 && @@ -2536,19 +2437,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); @@ -2560,7 +2461,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 */ @@ -2590,9 +2491,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"); } @@ -2603,12 +2504,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 @@ -2647,15 +2548,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; } @@ -2670,7 +2571,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; } @@ -2679,7 +2580,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; @@ -2690,8 +2591,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; } @@ -2711,7 +2612,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 */ @@ -2749,7 +2650,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; @@ -2759,10 +2660,10 @@ 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_OP_POINTER (left) || IS_ITEMP(left)) @@ -2837,7 +2738,7 @@ geniCodeReceive (value * args) /* geniCodeFunctionBody - create the function body */ /*-----------------------------------------------------------------*/ void -geniCodeFunctionBody (ast * tree) +geniCodeFunctionBody (ast * tree,int lvl) { iCode *ic; operand *func; @@ -2850,7 +2751,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; @@ -2873,7 +2774,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); @@ -2904,10 +2805,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 */ @@ -2956,7 +2857,7 @@ geniCodeIfx (ast * tree) } exit: - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ @@ -3054,10 +2955,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; @@ -3095,7 +2996,7 @@ geniCodeSwitch (ast * tree) geniCodeGoto (falseLabel); jumpTable: - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ @@ -3111,18 +3012,91 @@ geniCodeInline (ast * tree) ADDTOCHAIN (ic); } +/*-----------------------------------------------------------------*/ +/* geniCodeArrayInit - intermediate code for array initializer */ +/*-----------------------------------------------------------------*/ +static void +geniCodeArrayInit (ast * tree, operand *array) +{ + iCode *ic; + + ic = newiCode (ARRAYINIT, array, NULL); + IC_ARRAYILIST (ic) = tree->values.constlist; + 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; @@ -3141,11 +3115,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; } @@ -3161,44 +3135,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 */ @@ -3212,7 +3179,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))) @@ -3274,7 +3241,7 @@ ast2iCode (ast * tree) return geniCodeMultiply (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE),IS_INT(tree->ftype)); else - return geniCodeDerefPtr (geniCodeRValue (left, FALSE)); + return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': if (right) @@ -3286,7 +3253,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 */ @@ -3325,7 +3292,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)); @@ -3335,7 +3302,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); @@ -3367,7 +3334,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); @@ -3376,14 +3343,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); } @@ -3437,18 +3404,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: @@ -3456,16 +3423,20 @@ 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: geniCodeInline (tree); return NULL; + + case ARRAYINIT: + geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); + return NULL; } return NULL; @@ -3500,6 +3471,6 @@ iCodeFromAst (ast * tree) { returnLabel = newiTempLabel ("_return"); entryLabel = newiTempLabel ("_entry"); - ast2iCode (tree); + ast2iCode (tree,0); return reverseiCChain (); }