X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=5c38ec8f80937d5f2167fe196dbcd98b057f5332;hb=edea3eff95b328cf2e9e45e1ff56d13cf43bf010;hp=aec706a18c4a049623e80b54676c2d3f5cbb4d91;hpb=4b91acd603b69ca40e107133e7038446760cc036;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index aec706a1..5c38ec8f 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -45,7 +45,7 @@ symbol *entryLabel; /* function entry label */ /*-----------------------------------------------------------------*/ /* forward definition of some functions */ -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); @@ -120,7 +120,8 @@ iCodeTable codeTable[] = {ARRAYINIT, "arrayInit", picGenericOne, NULL}, {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL}, {CRITICAL, "critical_start", picCritical, NULL}, - {ENDCRITICAL, "critical_end", picEndCritical, NULL} + {ENDCRITICAL, "critical_end", picEndCritical, NULL}, + {SWAP, "swap", picGenericOne, NULL} }; /*-----------------------------------------------------------------*/ @@ -189,7 +190,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, #if 0 // temporary disabled, leaving the warning as a reminder if (warnings) { - SNPRINTF (message, sizeof(message), "for %s %s in %s", + SNPRINTF (message, sizeof(message), "for %s %s in %s", IS_UNSIGNED(ltype) ? "unsigned" : "signed", nounName(ltype), msg); werror (W_CONST_RANGE, message); @@ -203,7 +204,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, /*-----------------------------------------------------------------*/ /* operandName - returns the name of the operand */ /*-----------------------------------------------------------------*/ -int +int printOperand (operand * op, FILE * file) { sym_link *opetype; @@ -232,13 +233,14 @@ 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 nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ +//#if REGA /* { */ + if(REGA && !getenv("PRINT_SHORT_OPERANDS")) { + fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%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->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc, OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr ); @@ -275,21 +277,53 @@ printOperand (operand * op, FILE * file) fprintf (file, "]"); } } -#else - fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ? - OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); +//#else /* } else { */ + } else { + /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */ + fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); + + if(getenv("PRINT_SHORT_OPERANDS")[0] < '1') + { + fprintf (file, "[lr%d:%d so:%d]", + OP_LIVEFROM (op), OP_LIVETO (op), + OP_SYMBOL (op)->stack); + } + + if(getenv("PRINT_SHORT_OPERANDS")[0] < '2') + { + fprintf (file, "{"); + printTypeChain (operandType (op), file); + if (SPIL_LOC (op) && IS_ITEMP (op)) + fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); + fprintf (file, "}"); + } + /* if assigned to registers */ - if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt) + if (OP_SYMBOL (op)->nRegs) { - int i; - fprintf (file, "["); - for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) - fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ? - OP_SYMBOL (op)->regs[i]->name : - "err")); - fprintf (file, "]"); + if (OP_SYMBOL (op)->isspilt) + { + if (!OP_SYMBOL (op)->remat) + if (OP_SYMBOL (op)->usl.spillLoc) + fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + OP_SYMBOL (op)->usl.spillLoc->rname : + OP_SYMBOL (op)->usl.spillLoc->name)); + else + fprintf (file, "[err]"); + else + fprintf (file, "[remat]"); + } + else + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + fprintf (file, "]"); + } } -#endif +//#endif /* } */ + } break; case TYPE: @@ -398,6 +432,9 @@ PRINTFUNC (picGenericOne) if (ic->op == SEND || ic->op == RECEIVE) { fprintf(of,"{argreg = %d}",ic->argreg); } + if (ic->op == IPUSH) { + fprintf(of,"{parmPush = %d}",ic->parmPush); + } fprintf (of, "\n"); } @@ -513,7 +550,7 @@ piCode (void *item, FILE * of) of = stdout; icTab = getTableEntry (ic->op); - fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t", + fprintf (of, "%s(%d:%d:%d:%d:%d)\t", ic->filename, ic->lineno, ic->seq, ic->key, ic->depth, ic->supportRtn); icTab->iCodePrint (of, ic, icTab->printName); @@ -640,7 +677,7 @@ newiTemp (char *s) { SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++); } - + itmp = newSymbol (buffer, 1); strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX); itmp->isitmp = 1; @@ -656,13 +693,13 @@ newiTempLabel (char *s) { symbol *itmplbl; - /* check if this alredy exists */ + /* check if this already exists */ if (s && (itmplbl = findSym (LabelTab, NULL, s))) return itmplbl; if (s) { - itmplbl = newSymbol (s, 1); + itmplbl = newSymbol (s, 1); } else { @@ -699,7 +736,7 @@ newiTempPreheaderLabel () /*-----------------------------------------------------------------*/ /* initiCode - initialises some iCode related stuff */ /*-----------------------------------------------------------------*/ -void +void initiCode () { @@ -834,13 +871,13 @@ operandType (operand * op) /*-----------------------------------------------------------------*/ /* isParamterToCall - will return 1 if op is a parameter to args */ /*-----------------------------------------------------------------*/ -int +int isParameterToCall (value * args, operand * op) { value *tval = args; wassert (IS_SYMOP(op)); - + while (tval) { if (tval->sym && @@ -854,7 +891,7 @@ isParameterToCall (value * args, operand * op) /*-----------------------------------------------------------------*/ /* isOperandGlobal - return 1 if operand is a global variable */ /*-----------------------------------------------------------------*/ -int +int isOperandGlobal (operand * op) { if (!op) @@ -876,7 +913,7 @@ isOperandGlobal (operand * op) /*-----------------------------------------------------------------*/ /* isOperandVolatile - return 1 if the operand is volatile */ /*-----------------------------------------------------------------*/ -int +int isOperandVolatile (operand * op, bool chkTemp) { sym_link *optype; @@ -886,19 +923,19 @@ isOperandVolatile (operand * op, bool chkTemp) return 0; opetype = getSpec (optype = operandType (op)); - - if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype)) - return 1; - - if (IS_VOLATILE (opetype)) - return 1; - return 0; + + if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype)) + return 1; + + if (IS_VOLATILE (opetype)) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* isOperandLiteral - returns 1 if an operand contains a literal */ /*-----------------------------------------------------------------*/ -int +int isOperandLiteral (operand * op) { sym_link *opetype; @@ -917,7 +954,7 @@ isOperandLiteral (operand * op) /*-----------------------------------------------------------------*/ /* isOperandInFarSpace - will return true if operand is in farSpace */ /*-----------------------------------------------------------------*/ -bool +bool isOperandInFarSpace (operand * op) { sym_link *etype; @@ -945,7 +982,7 @@ isOperandInFarSpace (operand * op) /*------------------------------------------------------------------*/ /* isOperandInDirSpace - will return true if operand is in dirSpace */ /*------------------------------------------------------------------*/ -bool +bool isOperandInDirSpace (operand * op) { sym_link *etype; @@ -973,7 +1010,7 @@ isOperandInDirSpace (operand * op) /*--------------------------------------------------------------------*/ /* isOperandInCodeSpace - will return true if operand is in codeSpace */ /*--------------------------------------------------------------------*/ -bool +bool isOperandInCodeSpace (operand * op) { sym_link *etype; @@ -1003,7 +1040,7 @@ isOperandInCodeSpace (operand * op) /*-----------------------------------------------------------------*/ /* isOperandOnStack - will return true if operand is on stack */ /*-----------------------------------------------------------------*/ -bool +bool isOperandOnStack (operand * op) { sym_link *etype; @@ -1027,7 +1064,7 @@ isOperandOnStack (operand * op) /* isOclsExpensive - will return true if accesses to an output */ /* storage class are expensive */ /*-----------------------------------------------------------------*/ -bool +bool isOclsExpensive (struct memmap *oclass) { if (port->oclsExpense) @@ -1038,6 +1075,40 @@ isOclsExpensive (struct memmap *oclass) return IN_FARSPACE (oclass); } +/*-----------------------------------------------------------------*/ +/* isiCodeInFunctionCall - return TRUE if an iCode is between a */ +/* CALL/PCALL and the first IPUSH/SEND associated with the call */ +/*-----------------------------------------------------------------*/ +int +isiCodeInFunctionCall (iCode * ic) +{ + iCode * lic = ic; + + /* Find the next CALL/PCALL */ + while (lic) + { + if (lic->op == CALL || lic->op == PCALL) + break; + lic = lic->next; + } + + if (!lic) + return FALSE; + + /* A function call was found. Scan backwards and see if an */ + /* IPUSH or SEND is encountered */ + while (ic) + { + if (lic != ic && (ic->op == CALL || ic->op == PCALL)) + return FALSE; + if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush)) + return TRUE; + ic = ic->prev; + } + + return FALSE; +} + /*-----------------------------------------------------------------*/ /* operandLitValue - literal value of an operand */ /*-----------------------------------------------------------------*/ @@ -1357,8 +1428,10 @@ isOperandEqual (operand * left, operand * right) return isSymbolEqual (left->operand.symOperand, right->operand.symOperand); case VALUE: - return (floatFromVal (left->operand.valOperand) == - floatFromVal (right->operand.valOperand)); + return (compareType (left->operand.valOperand->type, + right->operand.valOperand->type) && + (floatFromVal (left->operand.valOperand) == + floatFromVal (right->operand.valOperand))); case TYPE: if (compareType (left->operand.typeOperand, right->operand.typeOperand) == 1) @@ -1371,7 +1444,7 @@ isOperandEqual (operand * left, operand * right) /*-------------------------------------------------------------------*/ /* isiCodeEqual - compares two iCodes are equal, returns true if yes */ /*-------------------------------------------------------------------*/ -int +int isiCodeEqual (iCode * left, iCode * right) { /* if the same pointer */ @@ -1404,7 +1477,7 @@ isiCodeEqual (iCode * left, iCode * right) if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) return 0; } - + return 1; } return 0; @@ -1453,7 +1526,7 @@ operandFromOperand (operand * op) nop->isLiteral = op->isLiteral; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; - + switch (nop->type) { case SYMBOL: @@ -1527,18 +1600,17 @@ 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 */ ) - { + { /* we will use it after all optimizations and before liveRange calculation */ @@ -1667,7 +1739,7 @@ operandFromAst (ast * tree,int lvl) default: assert (0); } - + /* Just to keep the compiler happy */ return (operand *) 0; } @@ -1675,7 +1747,7 @@ operandFromAst (ast * tree,int lvl) /*-----------------------------------------------------------------*/ /* setOperandType - sets the operand's type to the given type */ /*-----------------------------------------------------------------*/ -void +void setOperandType (operand * op, sym_link * type) { /* depending on the type of operand */ @@ -1716,7 +1788,7 @@ getArraySizePtr (operand * op) if(IS_PTR(ltype)) { int size = getSize(ltype); - return(IS_GENPTR(ltype)?(size-1):size); + return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size); } if(IS_ARRAY(ltype)) @@ -1734,7 +1806,10 @@ getArraySizePtr (operand * op) case FUNCTION: return (FPTRSIZE); case GPOINTER: - return (GPTRSIZE-1); + if (GPTRSIZE > FPTRSIZE) + return (GPTRSIZE-1); + else + return (FPTRSIZE); default: return (FPTRSIZE); @@ -1793,7 +1868,7 @@ usualBinaryConversions (operand ** op1, operand ** op2, *op1 = geniCodeCast (ctype, *op1, TRUE); *op2 = geniCodeCast (ctype, *op2, TRUE); - + return ctype; } @@ -1879,7 +1954,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) geniCodeArray2Ptr (op); op->isaddr = 0; } - + /* if the operand is already the desired type then do nothing */ if (compareType (type, optype) == 1) return op; @@ -1920,11 +1995,22 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } } } else { // from a pointer to a pointer - if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) { + if (IS_GENPTR(type) && IS_VOID(type->next)) + { // cast to void* is always allowed + } + else if (IS_GENPTR(optype) && IS_VOID(optype->next)) + { // cast from void* is always allowed + } + else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) { // if not a pointer to a function if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { if (implicit) { // if not to generic, they have to match - if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) { + if (!IS_GENPTR(type) && + !((DCL_TYPE(optype) == DCL_TYPE(type)) || + ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER)) + ) + ) + { werror(E_INCOMPAT_PTYPES); errors++; } @@ -1950,7 +2036,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } /* if they are the same size create an assignment */ - + /* This seems very dangerous to me, since there are several */ /* optimizations (for example, gcse) that don't notice the */ /* cast hidden in this assignement and may simplify an */ @@ -1984,9 +2070,10 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) restype = getSpec (operandType (IC_RESULT (ic))); if (!IS_LITERAL(opetype) && !IS_BIT(opetype)) + { SPEC_SCLS (restype) = SPEC_SCLS (opetype); - SPEC_OCLS (restype) = SPEC_OCLS (opetype); - + SPEC_OCLS (restype) = SPEC_OCLS (opetype); + } ADDTOCHAIN (ic); return IC_RESULT (ic); } @@ -2051,8 +2138,8 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) 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) + && strcmp (port->target, "pic16") != 0 /* don't shift for pic */ + && strcmp (port->target, "pic14") != 0) { if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))) { @@ -2170,7 +2257,7 @@ subtractExit: if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) { return result; } - + // should we really do this? is this ANSI? return geniCodeDivision (result, operandFromLit (getSize (ltype->next)), @@ -2301,7 +2388,7 @@ geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl) } /*-----------------------------------------------------------------*/ -/* aggrToPtr - changes an aggregate to pointer to an aggregate */ +/* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */ /*-----------------------------------------------------------------*/ sym_link * aggrToPtr (sym_link * type, bool force) @@ -2322,6 +2409,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 */ /*-----------------------------------------------------------------*/ @@ -2397,7 +2497,11 @@ geniCodeArray (operand * left, operand * right, int lvl) !IS_PTR (ltype->next)) ? ltype : ltype->next), 0); - IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next)); + if (!IS_AGGREGATE (ltype->next)) + { + IC_RESULT (ic)->isaddr = 1; + IC_RESULT (ic)->aggr2ptr = 1; + } ADDTOCHAIN (ic); return IC_RESULT (ic); @@ -2417,7 +2521,7 @@ geniCodeStruct (operand * left, operand * right, bool islval) right->operand.symOperand); wassert(IS_SYMOP(right)); - + /* add the offset */ ic = newiCode ('+', left, operandFromLit (element->offset)); @@ -2430,10 +2534,10 @@ geniCodeStruct (operand * left, operand * right, bool islval) SPEC_OCLS (retype) = SPEC_OCLS (etype); SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); SPEC_CONST (retype) |= SPEC_CONST (etype); - + if (IS_PTR (element->type)) setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE)); - + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type)); ADDTOCHAIN (ic); @@ -2469,9 +2573,11 @@ 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 (size == 0) + werror(W_SIZEOF_VOID); if (IS_FLOAT (rvtype)) ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0"))); else @@ -2480,7 +2586,7 @@ geniCodePostInc (operand * op) IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); ADDTOCHAIN (ic); - geniCodeAssign (op, result, 0); + geniCodeAssign (op, result, 0, 0); return rOp; @@ -2507,8 +2613,9 @@ geniCodePreInc (operand * op, bool lvalue) return op; } - size = (IS_PTR (roptype) ? getSize (roptype->next) : 1); + if (size == 0) + werror(W_SIZEOF_VOID); if (IS_FLOAT (roptype)) ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0"))); else @@ -2516,8 +2623,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; @@ -2552,9 +2659,11 @@ 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 (size == 0) + werror(W_SIZEOF_VOID); if (IS_FLOAT (rvtype)) ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0"))); else @@ -2563,7 +2672,7 @@ geniCodePostDec (operand * op) IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); ADDTOCHAIN (ic); - geniCodeAssign (op, result, 0); + geniCodeAssign (op, result, 0, 0); return rOp; @@ -2590,8 +2699,9 @@ geniCodePreDec (operand * op, bool lvalue) return op; } - size = (IS_PTR (roptype) ? getSize (roptype->next) : 1); + if (size == 0) + werror(W_SIZEOF_VOID); if (IS_FLOAT (roptype)) ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0"))); else @@ -2599,8 +2709,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; @@ -2643,7 +2753,7 @@ geniCodeAddressOf (operand * op) op->isaddr = 0; return op; } - + /* lvalue check already done in decorateType */ /* this must be a lvalue */ /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */ @@ -2676,7 +2786,7 @@ geniCodeAddressOf (operand * op) /*-----------------------------------------------------------------*/ /* setOClass - sets the output class depending on the pointer type */ /*-----------------------------------------------------------------*/ -void +void setOClass (sym_link * ptr, sym_link * spec) { switch (DCL_TYPE (ptr)) @@ -2750,7 +2860,7 @@ geniCodeDerefPtr (operand * op,int lvl) /* outputclass needs 2b updated */ setOClass (optype, retype); } - + op->isGptr = IS_GENPTR (optype); op->isaddr = (IS_PTR (rtype) || @@ -2819,7 +2929,7 @@ geniCodeRightShift (operand * left, operand * right) /*-----------------------------------------------------------------*/ /* geniCodeLogic- logic code */ /*-----------------------------------------------------------------*/ -operand * +static operand * geniCodeLogic (operand * left, operand * right, int op) { iCode *ic; @@ -2851,7 +2961,7 @@ geniCodeLogic (operand * left, operand * right, int op) ic = setNextItem (iCodeChain); } /* if casting literal to generic pointer, then cast to rtype instead */ - if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) + if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) { left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic)))); ltype = operandType(left); @@ -2871,7 +2981,7 @@ geniCodeLogic (operand * left, operand * right, int op) ic = setNextItem (iCodeChain); } /* if casting literal to generic pointer, then cast to rtype instead */ - if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) + if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) { right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic)))); rtype = operandType(right); @@ -2891,12 +3001,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 */ /*-----------------------------------------------------------------*/ @@ -2930,7 +3105,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); @@ -2939,7 +3114,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); @@ -2951,13 +3126,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; @@ -2967,7 +3142,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) check if the literal value is within bounds */ if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) { - checkConstantRange(ltype, + checkConstantRange(ltype, OP_VALUE(right), "= operation", 0); } @@ -3030,7 +3205,7 @@ geniCodeDummyRead (operand * op) if (!IS_VOLATILE(type)) return; - + ic = newiCode (DUMMY_READ_VOLATILE, NULL, op); ADDTOCHAIN (ic); @@ -3040,7 +3215,7 @@ geniCodeDummyRead (operand * op) /*-----------------------------------------------------------------*/ /* geniCodeSEParms - generate code for side effecting fcalls */ /*-----------------------------------------------------------------*/ -static void +static void geniCodeSEParms (ast * parms,int lvl) { if (!parms) @@ -3063,9 +3238,9 @@ geniCodeSEParms (ast * parms,int lvl) IS_ADDRESS_OF_OP (parms->right)) parms->right->left->lvalue = 1; - parms->opval.oprnd = + parms->opval.oprnd = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); - + parms->type = EX_OPERAND; AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) : SPEC_ARGREG(parms->ftype); @@ -3075,7 +3250,7 @@ geniCodeSEParms (ast * parms,int lvl) /* geniCodeParms - generates parameters */ /*-----------------------------------------------------------------*/ value * -geniCodeParms (ast * parms, value *argVals, int *stack, +geniCodeParms (ast * parms, value *argVals, int *stack, sym_link * ftype, int lvl) { iCode *ic; @@ -3106,12 +3281,12 @@ geniCodeParms (ast * parms, value *argVals, int *stack, /* hack don't like this but too lazy to think of something better */ if (IS_ADDRESS_OF_OP (parms)) - parms->left->lvalue = 1; + parms->left->lvalue = 1; if (IS_CAST_OP (parms) && - IS_PTR (parms->ftype) && - IS_ADDRESS_OF_OP (parms->right)) - parms->right->left->lvalue = 1; + IS_PTR (parms->ftype) && + IS_ADDRESS_OF_OP (parms->right)) + parms->right->left->lvalue = 1; pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); } @@ -3129,24 +3304,24 @@ geniCodeParms (ast * parms, value *argVals, int *stack, { /* now decide whether to push or assign */ if (!(options.stackAuto || IFFUNC_ISREENT (ftype))) - { + { - /* assign */ - 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); - } + /* assign */ + 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, 0); + } else - { - sym_link *p = operandType (pval); - /* push */ - ic = newiCode (IPUSH, pval, NULL); - ic->parmPush = 1; - /* update the stack adjustment */ - *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p); - ADDTOCHAIN (ic); - } + { + sym_link *p = operandType (pval); + /* push */ + ic = newiCode (IPUSH, pval, NULL); + ic->parmPush = 1; + /* update the stack adjustment */ + *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p); + ADDTOCHAIN (ic); + } } argVals=argVals->next; @@ -3165,7 +3340,7 @@ geniCodeCall (operand * left, ast * parms,int lvl) sym_link *ftype; int stack = 0; - if (!IS_FUNC(OP_SYMBOL(left)->type) && + if (!IS_FUNC(OP_SYMBOL(left)->type) && !IS_CODEPTR(OP_SYMBOL(left)->type)) { werror (E_FUNCTION_EXPECTED); return operandFromValue(valueFromLit(0)); @@ -3179,7 +3354,7 @@ geniCodeCall (operand * left, ast * parms,int lvl) ftype = operandType (left); if (IS_CODEPTR (ftype)) ftype = ftype->next; - + /* first the parameters */ geniCodeParms (parms, NULL, &stack, ftype, lvl); @@ -3206,9 +3381,11 @@ geniCodeCall (operand * left, ast * parms,int lvl) /*-----------------------------------------------------------------*/ /* geniCodeReceive - generate intermediate code for "receive" */ /*-----------------------------------------------------------------*/ -static void +static void geniCodeReceive (value * args) { + unsigned char paramByteCounter = 0; + /* for all arguments that are passed in registers */ while (args) { @@ -3242,13 +3419,24 @@ geniCodeReceive (value * args) } } - ic = newiCode (RECEIVE, NULL, NULL); + ic = newiCode (RECEIVE, NULL, NULL); ic->argreg = SPEC_ARGREG(args->etype); if (first) { currFunc->recvSize = getSize (sym->type); first = 0; } IC_RESULT (ic) = opr; + + /* misuse of parmBytes (normally used for functions) + * to save estimated stack position of this argument. + * Normally this should be zero for RECEIVE iCodes. + * No idea if this causes side effects on other ports. - dw + */ + ic->parmBytes = paramByteCounter; + + /* what stack position do we have? */ + paramByteCounter += getSize (sym->type); + ADDTOCHAIN (ic); } @@ -3259,7 +3447,7 @@ geniCodeReceive (value * args) /*-----------------------------------------------------------------*/ /* geniCodeFunctionBody - create the function body */ /*-----------------------------------------------------------------*/ -void +void geniCodeFunctionBody (ast * tree,int lvl) { iCode *ic; @@ -3285,6 +3473,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); @@ -3300,6 +3489,7 @@ geniCodeFunctionBody (ast * tree,int lvl) /* now generate the end proc */ ic = newiCode (ENDFUNCTION, func, NULL); + ic->tree = tree; ADDTOCHAIN (ic); return; } @@ -3307,7 +3497,7 @@ geniCodeFunctionBody (ast * tree,int lvl) /*-----------------------------------------------------------------*/ /* geniCodeReturn - gen icode for 'return' statement */ /*-----------------------------------------------------------------*/ -void +void geniCodeReturn (operand * op) { iCode *ic; @@ -3323,7 +3513,7 @@ geniCodeReturn (operand * op) /*-----------------------------------------------------------------*/ /* geniCodeIfx - generates code for extended if statement */ /*-----------------------------------------------------------------*/ -void +void geniCodeIfx (ast * tree,int lvl) { iCode *ic; @@ -3382,10 +3572,11 @@ exit: /*-----------------------------------------------------------------*/ /* geniCodeJumpTable - tries to create a jump table for switch */ /*-----------------------------------------------------------------*/ -int +int geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) { - int min = 0, max = 0, t, cnt = 0; + int min, max, cnt = 1; + int i, t; value *vch; iCode *ic; operand *boundary; @@ -3393,6 +3584,10 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) set *labels = NULL; int needRangeCheck = !optimize.noJTabBoundary || tree->values.switchVals.swDefault; + sym_link *cetype = getSpec (operandType (cond)); + int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost; + int sizeofMatchJump, sizeofJumpTable; + int sizeIndex; if (!tree || !caseVals) return 0; @@ -3400,50 +3595,115 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* the criteria for creating a jump table is */ /* all integer numbers between the maximum & minimum must */ /* be present , the maximum value should not exceed 255 */ - min = max = (int) floatFromVal (vch = caseVals); - SNPRINTF (buffer, sizeof(buffer), - "_case_%d_%d", - tree->values.switchVals.swNum, - min); - addSet (&labels, newiTempLabel (buffer)); - - /* if there is only one case value then no need */ - if (!(vch = vch->next)) - return 0; + /* If not all integer numbers are present the algorithm */ + /* inserts jumps to the default label for the missing numbers */ + /* and decides later whether it is worth it */ + min = (int) floatFromVal (vch = caseVals); - while (vch) + while (vch->next) { - if (((t = (int) floatFromVal (vch)) - max) != 1) - return 0; - SNPRINTF (buffer, sizeof(buffer), - "_case_%d_%d", - tree->values.switchVals.swNum, - t); - addSet (&labels, newiTempLabel (buffer)); - max = t; cnt++; vch = vch->next; } + max = (int) floatFromVal (vch); + + /* Exit if the range is too large to handle with a jump table. */ + if (1 + max - min > port->jumptableCost.maxCount) + return 0; + + switch (getSize (operandType (cond))) + { + case 1: sizeIndex = 0; break; + case 2: sizeIndex = 1; break; + case 4: sizeIndex = 2; break; + default: return 0; + } + + /* Compute the size cost of the range check and subtraction. */ + sizeofMinCost = 0; + sizeofZeroMinCost = 0; + sizeofMaxCost = 0; + if (needRangeCheck) + { + if (!(min==0 && IS_UNSIGNED (cetype))) + sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex]; + if (!IS_UNSIGNED (cetype)) + sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex]; + sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex]; + } + if (min) + sizeofMinCost += port->jumptableCost.sizeofSubtract; + + /* If the size cost of handling a non-zero minimum exceeds the */ + /* cost of extending the range down to zero, then it might be */ + /* better to extend the range to zero. */ + if (min > 0 && (sizeofMinCost-sizeofZeroMinCost) + >= (min * port->jumptableCost.sizeofElement)) + { + /* Only extend the jump table if it would still be manageable. */ + if (1 + max <= port->jumptableCost.maxCount) + { + min = 0; + if (IS_UNSIGNED (cetype)) + sizeofMinCost = 0; + else + sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex]; + } + } - /* if the number of case statements <= 2 then */ - /* it is not economical to create the jump table */ - /* since two compares are needed for boundary conditions */ - if ((needRangeCheck && cnt <= 2) || max > (255 / 3)) + /* Compute the total size cost of a jump table. */ + sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement + + port->jumptableCost.sizeofDispatch + + sizeofMinCost + sizeofMaxCost; + + /* Compute the total size cost of a match & jump sequence */ + sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex]; + + /* If the size cost of the jump table is uneconomical then exit */ + if (sizeofMatchJump < sizeofJumpTable) return 0; + /* The jump table is preferable. */ + + /* First, a label for the default or missing cases. */ if (tree->values.switchVals.swDefault) { - SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum); + SNPRINTF (buffer, sizeof(buffer), + "_default_%d", + tree->values.switchVals.swNum); } else { - SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum); + SNPRINTF (buffer, sizeof(buffer), + "_swBrk_%d", + tree->values.switchVals.swNum); } - - falseLabel = newiTempLabel (buffer); - /* so we can create a jumptable */ + /* Build the list of labels for the jump table. */ + vch = caseVals; + t = (int) floatFromVal (vch); + for (i=min; i<=max; i++) + { + if (vch && t==i) + { + /* Explicit case: make a new label for it. */ + SNPRINTF (buffer, sizeof(buffer), + "_case_%d_%d", + tree->values.switchVals.swNum, + i); + addSet (&labels, newiTempLabel (buffer)); + vch = vch->next; + if (vch) + t = (int) floatFromVal (vch); + } + else + { + /* Implicit case: use the default label. */ + addSet (&labels, falseLabel); + } + } + /* first we rule out the boundary conditions */ /* if only optimization says so */ if (needRangeCheck) @@ -3490,13 +3750,13 @@ geniCodeSwitch (ast * tree,int lvl) operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE); value *caseVals = tree->values.switchVals.swVals; symbol *trueLabel, *falseLabel; - + /* If the condition is a literal, then just jump to the */ /* appropriate case label. */ if (IS_LITERAL(getSpec(operandType(cond)))) { int switchVal, caseVal; - + switchVal = (int) floatFromVal (cond->operand.valOperand); while (caseVals) { @@ -3514,6 +3774,22 @@ geniCodeSwitch (ast * tree,int lvl) goto defaultOrBreak; } + /* If cond is volatile, it might change while we are trying to */ + /* find the matching case. To avoid this possibility, make a */ + /* non-volatile copy to use 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; + } + /* if we can make this a jump table */ if (geniCodeJumpTable (cond, caseVals, tree)) goto jumpTable; /* no need for the comparison */ @@ -3558,7 +3834,7 @@ jumpTable: /*-----------------------------------------------------------------*/ /* geniCodeInline - intermediate code for inline assembler */ /*-----------------------------------------------------------------*/ -static void +static void geniCodeInline (ast * tree) { iCode *ic; @@ -3588,30 +3864,42 @@ geniCodeArrayInit (ast * tree, operand *array) } ADDTOCHAIN (ic); } - + /*-----------------------------------------------------------------*/ /* geniCodeCritical - intermediate code for a critical statement */ /*-----------------------------------------------------------------*/ -static void +static void geniCodeCritical (ast *tree, int lvl) { iCode *ic; operand *op = NULL; + sym_link *type; + + if (!options.stackAuto) + { + type = newLink(SPECIFIER); + SPEC_VOLATILE(type) = 1; + SPEC_NOUN(type) = V_BIT; + SPEC_SCLS(type) = S_BIT; + SPEC_BLEN(type) = 1; + SPEC_BSTR(type) = 0; + op = newiTempOperand(type, 1); + } /* If op is NULL, the original interrupt state will saved on */ /* the stack. Otherwise, it will be saved in op. */ - - /* Generate a save of the current interrupt state & disabled */ + + /* Generate a save of the current interrupt state & disable */ ic = newiCode (CRITICAL, NULL, NULL); IC_RESULT (ic) = op; ADDTOCHAIN (ic); - + /* Generate the critical code sequence */ if (tree->left && tree->left->type == EX_VALUE) geniCodeDummyRead (ast2iCode (tree->left,lvl+1)); else ast2iCode (tree->left,lvl+1); - + /* Generate a restore of the original interrupt state */ ic = newiCode (ENDCRITICAL, NULL, op); ADDTOCHAIN (ic); @@ -3729,6 +4017,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 && @@ -3907,28 +4197,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); @@ -3946,7 +4237,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: @@ -3954,8 +4245,9 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeMultiply (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE), FALSE), - getResultTypeFromType (tree->ftype)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case DIV_ASSIGN: return @@ -3964,7 +4256,7 @@ ast2iCode (ast * tree,int lvl) FALSE), geniCodeRValue (right, FALSE), getResultTypeFromType (tree->ftype)), - 0); + 0, 1); case MOD_ASSIGN: return geniCodeAssign (left, @@ -3972,7 +4264,7 @@ ast2iCode (ast * tree,int lvl) FALSE), geniCodeRValue (right, FALSE), getResultTypeFromType (tree->ftype)), - 0); + 0, 1); case ADD_ASSIGN: { sym_link *rtype = operandType (right); @@ -3990,7 +4282,7 @@ ast2iCode (ast * tree,int lvl) right, getResultTypeFromType (tree->ftype), lvl), - 0); + 0, 1); } case SUB_ASSIGN: { @@ -4011,7 +4303,7 @@ ast2iCode (ast * tree,int lvl) FALSE), right, getResultTypeFromType (tree->ftype)), - 0); + 0, 1); } case LEFT_ASSIGN: return @@ -4020,13 +4312,13 @@ ast2iCode (ast * tree,int lvl) ,FALSE), geniCodeRValue (right, FALSE), getResultTypeFromType (tree->ftype)), - 0); + 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, @@ -4034,7 +4326,7 @@ ast2iCode (ast * tree,int lvl) FALSE), geniCodeRValue (right, FALSE), BITWISEAND, - operandType (left)), 0); + operandType (left)), 0, 1); case XOR_ASSIGN: return geniCodeAssign (left, @@ -4042,7 +4334,7 @@ ast2iCode (ast * tree,int lvl) FALSE), geniCodeRValue (right, FALSE), '^', - operandType (left)), 0); + operandType (left)), 0, 1); case OR_ASSIGN: return geniCodeAssign (left, @@ -4050,7 +4342,7 @@ ast2iCode (ast * tree,int lvl) ,FALSE), geniCodeRValue (right, FALSE), '|', - operandType (left)), 0); + operandType (left)), 0, 1); case ',': return geniCodeRValue (right, FALSE); @@ -4084,11 +4376,11 @@ ast2iCode (ast * tree,int lvl) case INLINEASM: geniCodeInline (tree); return NULL; - + case ARRAYINIT: geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); return NULL; - + case CRITICAL: geniCodeCritical (tree, lvl); } @@ -4137,25 +4429,25 @@ static const char *opTypeToStr(OPTYPE op) case VALUE: return "value"; case TYPE: return "type"; } - return "undefined type"; + return "undefined type"; } -operand *validateOpType(operand *op, +operand *validateOpType(operand *op, const char *macro, const char *args, OPTYPE type, - const char *file, + const char *file, unsigned line) -{ +{ if (op && op->type == type) { return op; } - fprintf(stderr, + fprintf(stderr, "Internal error: validateOpType failed in %s(%s) @ %s:%u:" " expected %s, got %s\n", - macro, args, file, line, + macro, args, file, line, opTypeToStr(type), op ? opTypeToStr(op->type) : "null op"); exit(-1); return op; // never reached, makes compiler happy.