X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=fe437728ce97f42e0c4663a2e65b8a25a3f8b5df;hb=80972b2e54c9b88f11c27b878874fd2a6a681391;hp=c8ebf3be39270a7fed38fe0f6d2f2559c629ed1b;hpb=f5578880ac28fb1eead3fe585f3058973ccca10e;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index c8ebf3be..fe437728 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -25,6 +25,7 @@ #include "common.h" #include "newalloc.h" #include "math.h" +#include "dbuf_string.h" /*-----------------------------------------------------------------*/ /* global variables */ @@ -34,8 +35,8 @@ int iTempNum = 0; int iTempLblNum = 0; int operandKey = 0; int iCodeKey = 0; -char *filename; -int lineno; +char *filename; /* current file name */ +int lineno = 1; /* current line number */ int block; int scopeLevel; int seqPoint; @@ -54,7 +55,7 @@ int isLvaluereq(int lvl); void setOClass (sym_link * ptr, sym_link * spec); static operand *geniCodeCast (sym_link *, operand *, bool); -#define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) +#define PRINTFUNC(x) void x (struct dbuf_s *dbuf, iCode *ic, char *s) /* forward definition of ic print functions */ PRINTFUNC (picGetValueAtAddr); PRINTFUNC (picSetValueAtAddr); @@ -128,124 +129,58 @@ iCodeTable codeTable[] = }; /*-----------------------------------------------------------------*/ -/* checkConstantRange: check a constant against the type */ +/* operandName - returns the name of the operand */ /*-----------------------------------------------------------------*/ +int +printOperand (operand * op, FILE * file) +{ + struct dbuf_s dbuf; + int ret; + int pnl = 0; - -/* pedantic=0: allmost anything is allowed as long as the absolute - value is within the bit range of the type, and -1 is treated as - 0xf..f for unsigned types (e.g. in assign) - pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare) - pedantic>1: "char c=200" is not allowed (evaluates to -56) -*/ - -void checkConstantRange(sym_link *ltype, value *val, char *msg, - int pedantic) { - double max; - int warnings=0; - int negative=0; - long v; - - max = pow ((double)2.0, (double)bitsForType(ltype)); - - if (IS_LONG(val->type)) { - if (IS_UNSIGNED(val->type)) { - v=SPEC_CVAL(val->type).v_ulong; - } else { - v=SPEC_CVAL(val->type).v_long; - } - } else { - if (IS_UNSIGNED(val->type)) { - v=SPEC_CVAL(val->type).v_uint; - } else { - v=SPEC_CVAL(val->type).v_int; - } - } - - -#if 0 - // this could be a good idea - if (options.pedantic) - pedantic=2; -#endif - - if (IS_FLOAT(ltype)) { - // anything will do - return; - } - - if (IS_FIXED(ltype)) { - // anything will do - return; - } - - if (!IS_UNSIGNED(val->type) && v<0) { - negative=1; - if (IS_UNSIGNED(ltype) && (pedantic>1)) { - warnings++; + if (!file) + { + file = stdout; + pnl = 1; } - v=-v; - } - - // if very pedantic: "char c=200" is not allowed - if (pedantic>1 && !IS_UNSIGNED(ltype)) { - max = max/2 + negative; - } + dbuf_init (&dbuf, 1024); + ret = dbuf_printOperand(op, &dbuf); + dbuf_write_and_destroy (&dbuf, file); - if (v >= max) { - warnings++; - } - -#if 0 // temporary disabled, leaving the warning as a reminder - if (warnings) { - SNPRINTF (message, sizeof(message), "for %s %s in %s", - IS_UNSIGNED(ltype) ? "unsigned" : "signed", - nounName(ltype), msg); - werror (W_CONST_RANGE, message); + if (pnl) + putc ('\n', file); - if (pedantic>1) - fatalError++; - } -#endif + return ret; } -/*-----------------------------------------------------------------*/ -/* operandName - returns the name of the operand */ -/*-----------------------------------------------------------------*/ int -printOperand (operand * op, FILE * file) +dbuf_printOperand (operand * op, struct dbuf_s *dbuf) { sym_link *opetype; - int pnl = 0; if (!op) return 1; - if (!file) - { - file = stdout; - pnl = 1; - } switch (op->type) { case VALUE: opetype = getSpec (operandType (op)); if (IS_FLOAT (opetype)) - fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); + dbuf_printf (dbuf, "%g {", SPEC_CVAL (opetype).v_float); else if (IS_FIXED16X16 (opetype)) - fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16)); + dbuf_printf (dbuf, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16)); else - fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand)); - printTypeChain (operandType (op), file); - fprintf (file, "}"); + dbuf_printf (dbuf, "0x%x {", (unsigned int) ulFromVal (op->operand.valOperand)); + dbuf_printTypeChain (operandType (op), dbuf); + dbuf_append_char (dbuf, '}'); break; case SYMBOL: #define REGA 1 //#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}" , */ + dbuf_printf (dbuf, "%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), @@ -255,11 +190,11 @@ printOperand (operand * op, FILE * file) OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr ); { - fprintf (file, "{"); - printTypeChain (operandType (op), file); + dbuf_append_char (dbuf, '{'); + dbuf_printTypeChain (operandType (op), dbuf); if (SPIL_LOC (op) && IS_ITEMP (op)) - fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); - fprintf (file, "}"); + dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname); + dbuf_append_char (dbuf, '}'); } @@ -270,42 +205,42 @@ printOperand (operand * op, FILE * file) { if (!OP_SYMBOL (op)->remat) if (OP_SYMBOL (op)->usl.spillLoc) - fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? OP_SYMBOL (op)->usl.spillLoc->rname : OP_SYMBOL (op)->usl.spillLoc->name)); else - fprintf (file, "[err]"); + dbuf_append_str (dbuf, "[err]"); else - fprintf (file, "[remat]"); + dbuf_append_str (dbuf, "[remat]"); } else { int i; - fprintf (file, "["); + dbuf_append_char (dbuf, '['); for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) - fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); - fprintf (file, "]"); + dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + dbuf_append_char (dbuf, ']'); } } //#else /* } else { */ } else { /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */ - fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); + dbuf_printf (dbuf, "%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]", + dbuf_printf (dbuf, "[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); + dbuf_append_char (dbuf, '{'); + dbuf_printTypeChain (operandType (op), dbuf); if (SPIL_LOC (op) && IS_ITEMP (op)) - fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); - fprintf (file, "}"); + dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname); + dbuf_append_char (dbuf, '}'); } /* if assigned to registers */ @@ -315,21 +250,21 @@ printOperand (operand * op, FILE * file) { if (!OP_SYMBOL (op)->remat) if (OP_SYMBOL (op)->usl.spillLoc) - fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? OP_SYMBOL (op)->usl.spillLoc->rname : OP_SYMBOL (op)->usl.spillLoc->name)); else - fprintf (file, "[err]"); + dbuf_append_str (dbuf, "[err]"); else - fprintf (file, "[remat]"); + dbuf_append_str (dbuf, "[remat]"); } else { int i; - fprintf (file, "["); + dbuf_append_char (dbuf, '['); for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) - fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); - fprintf (file, "]"); + dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + dbuf_append_char (dbuf, ']'); } } //#endif /* } */ @@ -337,14 +272,12 @@ printOperand (operand * op, FILE * file) break; case TYPE: - fprintf (file, "("); - printTypeChain (op->operand.typeOperand, file); - fprintf (file, ")"); + dbuf_append_char (dbuf, '('); + dbuf_printTypeChain (op->operand.typeOperand, dbuf); + dbuf_append_char (dbuf, ')'); break; } - if (pnl) - fprintf (file, "\n"); return 0; } @@ -354,197 +287,196 @@ printOperand (operand * op, FILE * file) /*-----------------------------------------------------------------*/ PRINTFUNC (picGetValueAtAddr) { - fprintf (of, "\t"); - printOperand (IC_RESULT (ic), of); - fprintf (of, " = "); - fprintf (of, "@["); - printOperand (IC_LEFT (ic), of); - fprintf (of, "]"); - - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\t'); + dbuf_printOperand (IC_RESULT (ic), dbuf); + dbuf_append_str (dbuf, " = "); + dbuf_append_str (dbuf, "@["); + dbuf_printOperand (IC_LEFT (ic), dbuf); + dbuf_append_str (dbuf, "]\n"); } PRINTFUNC (picSetValueAtAddr) { - fprintf (of, "\t"); - fprintf (of, "*["); - printOperand (IC_LEFT (ic), of); - fprintf (of, "] = "); - printOperand (IC_RIGHT (ic), of); - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\t'); + dbuf_append_str (dbuf, "*["); + dbuf_printOperand (IC_LEFT (ic), dbuf); + dbuf_append_str (dbuf, "] = "); + dbuf_printOperand (IC_RIGHT (ic), dbuf); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picAddrOf) { - fprintf (of, "\t"); - printOperand (IC_RESULT (ic), of); + dbuf_append_char (dbuf, '\t'); + dbuf_printOperand (IC_RESULT (ic), dbuf); if (IS_ITEMP (IC_LEFT (ic))) - fprintf (of, " = "); + dbuf_append_str (dbuf, " = "); else - fprintf (of, " = &["); - printOperand (IC_LEFT (ic), of); + dbuf_append_str (dbuf, " = &["); + dbuf_printOperand (IC_LEFT (ic), dbuf); if (IC_RIGHT (ic)) { if (IS_ITEMP (IC_LEFT (ic))) - fprintf (of, " offsetAdd "); + dbuf_append_str (dbuf, " offsetAdd "); else - fprintf (of, " , "); - printOperand (IC_RIGHT (ic), of); + dbuf_append_str (dbuf, " , "); + dbuf_printOperand (IC_RIGHT (ic), dbuf); } if (IS_ITEMP (IC_LEFT (ic))) - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\n'); else - fprintf (of, "]\n"); + dbuf_append_str (dbuf, "]\n"); } PRINTFUNC (picJumpTable) { symbol *sym; - fprintf (of, "\t"); - fprintf (of, "%s\t", s); - printOperand (IC_JTCOND (ic), of); - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\t'); + dbuf_printf (dbuf, "%s\t", s); + dbuf_printOperand (IC_JTCOND (ic), dbuf); for (sym = setFirstItem (IC_JTLABELS (ic)); sym; sym = setNextItem (IC_JTLABELS (ic))) - fprintf (of, "\t\t\t%s\n", sym->name); + dbuf_printf (dbuf, "; %s", sym->name); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picGeneric) { - fprintf (of, "\t"); - printOperand (IC_RESULT (ic), of); - fprintf (of, " = "); - printOperand (IC_LEFT (ic), of); - fprintf (of, " %s ", s); - printOperand (IC_RIGHT (ic), of); - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\t'); + dbuf_printOperand (IC_RESULT (ic), dbuf); + dbuf_append_str (dbuf, " = "); + dbuf_printOperand (IC_LEFT (ic), dbuf); + dbuf_printf (dbuf, " %s ", s); + dbuf_printOperand (IC_RIGHT (ic), dbuf); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picGenericOne) { - fprintf (of, "\t"); + dbuf_append_char (dbuf, '\t'); if (IC_RESULT (ic)) { - printOperand (IC_RESULT (ic), of); - fprintf (of, " = "); + dbuf_printOperand (IC_RESULT (ic), dbuf); + dbuf_append_str (dbuf, " = "); } if (IC_LEFT (ic)) { - fprintf (of, "%s ", s); - printOperand (IC_LEFT (ic), of); + dbuf_printf (dbuf, "%s ", s); + dbuf_printOperand (IC_LEFT (ic), dbuf); } if (!IC_RESULT (ic) && !IC_LEFT (ic)) - fprintf (of, s); + dbuf_append_str (dbuf, s); if (ic->op == SEND || ic->op == RECEIVE) { - fprintf(of,"{argreg = %d}",ic->argreg); + dbuf_printf (dbuf,"{argreg = %d}",ic->argreg); } if (ic->op == IPUSH) { - fprintf(of,"{parmPush = %d}",ic->parmPush); + dbuf_printf (dbuf,"{parmPush = %d}",ic->parmPush); } - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picCast) { - fprintf (of, "\t"); - printOperand (IC_RESULT (ic), of); - fprintf (of, " = "); - printOperand (IC_LEFT (ic), of); - printOperand (IC_RIGHT (ic), of); - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\t'); + dbuf_printOperand (IC_RESULT (ic), dbuf); + dbuf_append_str (dbuf, " = "); + dbuf_printOperand (IC_LEFT (ic), dbuf); + dbuf_printOperand (IC_RIGHT (ic), dbuf); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picAssign) { - fprintf (of, "\t"); + dbuf_append_char (dbuf, '\t'); if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic))) - fprintf (of, "*("); + dbuf_append_str (dbuf, "*("); - printOperand (IC_RESULT (ic), of); + dbuf_printOperand (IC_RESULT (ic), dbuf); if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic))) - fprintf (of, ")"); + dbuf_append_char (dbuf, ')'); - fprintf (of, " %s ", s); - printOperand (IC_RIGHT (ic), of); + dbuf_printf (dbuf, " %s ", s); + dbuf_printOperand (IC_RIGHT (ic), dbuf); - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picLabel) { - fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); + dbuf_printf (dbuf, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); } PRINTFUNC (picGoto) { - fprintf (of, "\t"); - fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); + dbuf_append_char (dbuf, '\t'); + dbuf_printf (dbuf, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); } PRINTFUNC (picIfx) { - fprintf (of, "\t"); - fprintf (of, "if "); - printOperand (IC_COND (ic), of); + dbuf_append_char (dbuf, '\t'); + dbuf_append_str (dbuf, "if "); + dbuf_printOperand (IC_COND (ic), dbuf); if (!IC_TRUE (ic)) - fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key); + dbuf_printf (dbuf, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key); else { - fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key); + dbuf_printf (dbuf, " != 0 goto %s($%d)", IC_TRUE (ic)->name, IC_TRUE (ic)->key); if (IC_FALSE (ic)) - fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name); + dbuf_printf (dbuf, "; zzgoto %s\n", IC_FALSE (ic)->name); + dbuf_append_char (dbuf, '\n'); } } PRINTFUNC (picInline) { - fprintf (of, "%s", IC_INLINE (ic)); + dbuf_append_str (dbuf, IC_INLINE (ic)); } PRINTFUNC (picReceive) { - printOperand (IC_RESULT (ic), of); - fprintf (of, " = %s ", s); - printOperand (IC_LEFT (ic), of); - fprintf (of, "\n"); + dbuf_printOperand (IC_RESULT (ic), dbuf); + dbuf_printf (dbuf, " = %s ", s); + dbuf_printOperand (IC_LEFT (ic), dbuf); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picDummyRead) { - fprintf (of, "\t"); - fprintf (of, "%s ", s); - printOperand (IC_RIGHT (ic), of); - fprintf (of, "\n"); + dbuf_append_char (dbuf, '\t'); + dbuf_printf (dbuf, "%s ", s); + dbuf_printOperand (IC_RIGHT (ic), dbuf); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picCritical) { - fprintf (of, "\t"); + dbuf_append_char (dbuf, '\t'); if (IC_RESULT (ic)) - printOperand (IC_RESULT (ic), of); + dbuf_printOperand (IC_RESULT (ic), dbuf); else - fprintf (of, "(stack)"); - fprintf (of, " = %s ", s); - fprintf (of, "\n"); + dbuf_append_str (dbuf, "(stack)"); + dbuf_printf (dbuf, " = %s ", s); + dbuf_append_char (dbuf, '\n'); } PRINTFUNC (picEndCritical) { - fprintf (of, "\t"); - fprintf (of, "%s = ", s); + dbuf_append_char (dbuf, '\t'); + dbuf_printf (dbuf, "%s = ", s); if (IC_RIGHT (ic)) - printOperand (IC_RIGHT (ic), of); + dbuf_printOperand (IC_RIGHT (ic), dbuf); else - fprintf (of, "(stack)"); - fprintf (of, "\n"); + dbuf_append_str (dbuf, "(stack)"); + dbuf_append_char (dbuf, '\n'); } /*-----------------------------------------------------------------*/ @@ -555,6 +487,7 @@ piCode (void *item, FILE * of) { iCode *ic = item; iCodeTable *icTab; + struct dbuf_s dbuf; if (!of) of = stdout; @@ -563,7 +496,9 @@ piCode (void *item, FILE * of) 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); + dbuf_init (&dbuf, 1024); + icTab->iCodePrint (&dbuf, ic, icTab->printName); + dbuf_write_and_destroy (&dbuf, of); return 1; } @@ -579,6 +514,7 @@ printiCChain (iCode * icChain, FILE * of) { iCode *loop; iCodeTable *icTab; + struct dbuf_s dbuf; if (!of) of = stdout; @@ -590,7 +526,11 @@ printiCChain (iCode * icChain, FILE * of) loop->filename, loop->lineno, loop->seq, loop->key, loop->depth, loop->supportRtn); - icTab->iCodePrint (of, loop, icTab->printName); + dbuf_init(&dbuf, 1024); + icTab->iCodePrint (&dbuf, loop, icTab->printName); + dbuf_write_and_destroy (&dbuf, of); + //// + fflush(of); } } } @@ -621,8 +561,8 @@ newiCode (int op, operand * left, operand * right) ic = Safe_alloc ( sizeof (iCode)); ic->seqPoint = seqPoint; - ic->lineno = lineno; ic->filename = filename; + ic->lineno = lineno; ic->block = block; ic->level = scopeLevel; ic->op = op; @@ -725,14 +665,15 @@ newiTempLabel (char *s) } /*-----------------------------------------------------------------*/ -/* newiTempPreheaderLabel - creates a new preheader label */ +/* newiTempLoopHeaderLabel - creates a new loop header label */ /*-----------------------------------------------------------------*/ symbol * -newiTempPreheaderLabel () +newiTempLoopHeaderLabel (bool pre) { symbol *itmplbl; - SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++); + SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d", + iTempLblNum++); itmplbl = newSymbol (buffer, 1); itmplbl->isitmp = 1; @@ -760,8 +701,8 @@ copyiCode (iCode * ic) { iCode *nic = newiCode (ic->op, NULL, NULL); - nic->lineno = ic->lineno; nic->filename = ic->filename; + nic->lineno = ic->lineno; nic->block = ic->block; nic->level = ic->level; nic->parmBytes = ic->parmBytes; @@ -860,7 +801,6 @@ operandType (operand * op) /* depending on type of operand */ switch (op->type) { - case VALUE: return op->operand.valOperand->type; @@ -869,6 +809,7 @@ operandType (operand * op) case TYPE: return op->operand.typeOperand; + default: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, " operand type not known "); @@ -878,6 +819,24 @@ operandType (operand * op) } } +/*-----------------------------------------------------------------*/ +/* operandSize - returns size of an operand in bytes */ +/*-----------------------------------------------------------------*/ +unsigned int +operandSize (operand * op) +{ + sym_link *type; + + /* if nothing return 0 */ + if (!op) + return 0; + + type = operandType (op); + if (op->aggr2ptr == 2) + type = type->next; + return getSize (type); +} + /*-----------------------------------------------------------------*/ /* isParamterToCall - will return 1 if op is a parameter to args */ /*-----------------------------------------------------------------*/ @@ -1237,26 +1196,26 @@ operandOperation (operand * left, operand * right, /* signed and unsigned mul are the same, as long as the precision of the result isn't bigger than the precision of the operands. */ retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD) operandLitValue (left) * - (TYPE_UDWORD) operandLitValue (right))); + (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) * + (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)))); else if (IS_UNSIGNED (type)) /* unsigned int */ { /* unsigned int is handled here in order to detect overflow */ - TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) * - (TYPE_UWORD) operandLitValue (right); + TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) double2ul (operandLitValue (left)) * + (TYPE_TARGET_UINT) double2ul (operandLitValue (right)); - retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul)); - if (ul != (TYPE_UWORD) ul) + retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul)); + if (ul != (TYPE_TARGET_UINT) ul) werror (W_INT_OVL); } else /* signed int */ { /* signed int is handled here in order to detect overflow */ - TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) * - (TYPE_WORD) operandLitValue (right); + TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) * + (TYPE_TARGET_INT) operandLitValue (right); - retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l)); - if (l != (TYPE_WORD) l) + retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l)); + if (l != (TYPE_TARGET_INT) l) werror (W_INT_OVL); } } @@ -1267,32 +1226,33 @@ operandOperation (operand * left, operand * right, operandLitValue (right))); break; case '/': - if ((TYPE_UDWORD) operandLitValue (right) == 0) + if (IS_UNSIGNED (type)) { - werror (E_DIVIDE_BY_ZERO); - retval = right; - + if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0) + { + werror (E_DIVIDE_BY_ZERO); + retval = right; + } + SPEC_USIGN (let) = 1; + SPEC_USIGN (ret) = 1; + retval = operandFromValue (valCastLiteral (type, + (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) / + (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)))); } else { - if (IS_UNSIGNED (type)) + if (operandLitValue (right) == 0) { - SPEC_USIGN (let) = 1; - SPEC_USIGN (ret) = 1; - retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD) operandLitValue (left) / - (TYPE_UDWORD) operandLitValue (right))); - } - else - { - retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) / - operandLitValue (right))); + werror (E_DIVIDE_BY_ZERO); + retval = right; } + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) / + operandLitValue (right))); } break; case '%': - if ((TYPE_UDWORD) operandLitValue (right) == 0) + if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0) { werror (E_DIVIDE_BY_ZERO); retval = right; @@ -1300,31 +1260,31 @@ operandOperation (operand * left, operand * right, else { if (IS_UNSIGNED (type)) - retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) % - (TYPE_UDWORD) operandLitValue (right)); + retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) % + (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))); else - retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) % - (TYPE_DWORD) operandLitValue (right)); + retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) % + (TYPE_TARGET_LONG) operandLitValue (right)); } break; case LEFT_OP: /* The number of left shifts is always unsigned. Signed doesn't make sense here. Shifting by a negative number is impossible. */ retval = operandFromValue (valCastLiteral (type, - ((TYPE_UDWORD) operandLitValue (left) << - (TYPE_UDWORD) operandLitValue (right)))); + ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) << + (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))))); break; case RIGHT_OP: /* The number of right shifts is always unsigned. Signed doesn't make sense here. Shifting by a negative number is impossible. */ if (IS_UNSIGNED(let)) /* unsigned: logic shift right */ - retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >> - (TYPE_UDWORD) operandLitValue (right)); + retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) >> + (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))); else /* signed: arithmetic shift right */ - retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >> - (TYPE_UDWORD) operandLitValue (right)); + retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) >> + (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))); break; case EQ_OP: if (IS_FLOAT (let) || IS_FLOAT (ret)) @@ -1340,10 +1300,10 @@ operandOperation (operand * left, operand * right, else { /* this op doesn't care about signedness */ - TYPE_UDWORD l, r; + TYPE_TARGET_ULONG l, r; - l = (TYPE_UDWORD) operandLitValue (left); - r = (TYPE_UDWORD) operandLitValue (right); + l = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)); + r = (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)); /* In order to correctly compare 'signed int' and 'unsigned int' it's neccessary to strip them to 16 bit. Literals are reduced to their cheapest type, therefore left and @@ -1352,8 +1312,8 @@ operandOperation (operand * left, operand * right, if (!IS_LONG (let) && !IS_LONG (ret)) { - r = (TYPE_UWORD) r; - l = (TYPE_UWORD) l; + r = (TYPE_TARGET_UINT) r; + l = (TYPE_TARGET_UINT) l; } retval = operandFromLit (l == r); } @@ -1380,18 +1340,18 @@ operandOperation (operand * left, operand * right, break; case BITWISEAND: retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD)operandLitValue(left) & - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) & + (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)))); break; case '|': retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD)operandLitValue(left) | - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) | + (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)))); break; case '^': retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD)operandLitValue(left) ^ - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) ^ + (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)))); break; case AND_OP: retval = operandFromLit (operandLitValue (left) && @@ -1403,7 +1363,7 @@ operandOperation (operand * left, operand * right, break; case RRC: { - TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); + TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)); retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | (i << 1)); @@ -1411,27 +1371,27 @@ operandOperation (operand * left, operand * right, break; case RLC: { - TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); + TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)); retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | (i >> 1)); } break; case GETABIT: - retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >> - (TYPE_UDWORD)operandLitValue(right)) & 1); + retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >> + (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))) & 1); break; case GETBYTE: - retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >> - (TYPE_UDWORD)operandLitValue(right)) & 0xFF); + retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >> + (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFF)); break; case GETWORD: - retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >> - (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF); + retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >> + (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFFFF)); break; case GETHBIT: - retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >> + retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >> ((getSize (let) * 8) - 1)) & 1); break; @@ -1442,8 +1402,7 @@ operandOperation (operand * left, operand * right, case '~': retval = operandFromValue (valCastLiteral (type, - ~((TYPE_UDWORD) - operandLitValue (left)))); + ~((TYPE_TARGET_ULONG) double2ul (operandLitValue (left))))); break; case '!': @@ -1838,7 +1797,7 @@ setOperandType (operand * op, sym_link * type) /*-----------------------------------------------------------------*/ /* Get size in byte of ptr need to access an array */ /*-----------------------------------------------------------------*/ -static int +static unsigned int getArraySizePtr (operand * op) { sym_link *ltype = operandType(op); @@ -1988,6 +1947,37 @@ geniCodeRValue (operand * op, bool force) return IC_RESULT (ic); } +static DECLARATOR_TYPE +getPtrType(sym_link *type) +{ + //for Z80 anything goes + if (TARGET_Z80_LIKE) + return POINTER; + + //preserve original behaviour for PIC16 + if (TARGET_IS_PIC16) + return POINTER; + + //for HC08 only zeropage ptr is different + if (TARGET_IS_HC08) + { + if (IS_DATA_PTR (type)) + return POINTER; + else + return FPOINTER; + } + + if (IS_DATA_PTR (type) && TARGET_MCS51_LIKE) + return IPOINTER; + if (IS_PTR (type)) + return DCL_TYPE (type); + else if (IS_FUNC (type)) + return CPOINTER; + else if (IS_ARRAY (type)) + return PTR_TYPE (SPEC_OCLS (getSpec (type))); + return UPOINTER; +} + /*-----------------------------------------------------------------*/ /* geniCodeCast - changes the value from one type to another */ /*-----------------------------------------------------------------*/ @@ -2020,8 +2010,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /* if this is a literal then just change the type & return */ if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype)) { - return operandFromValue (valCastLiteral (type, - operandLitValue (op))); + return operandFromValue (valCastLiteral (type, operandLitValue (op))); } /* if casting to/from pointers, do some checking */ @@ -2097,7 +2086,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /* 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 */ + /* cast hidden in this assignment and may simplify an */ /* iCode to use the original (uncasted) operand. */ /* Unfortunately, other things break when this cast is */ /* made explicit. Need to fix this someday. */ @@ -2109,7 +2098,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) !IS_FIXED (type) && !IS_FIXED (optype) && ((IS_SPEC (type) && IS_SPEC (optype)) || - (!IS_SPEC (type) && !IS_SPEC (optype)))) + (IS_DECL (type) && IS_DECL (optype) && getPtrType (type) == getPtrType (optype)))) { ic = newiCode ('=', NULL, op); IC_RESULT (ic) = newiTempOperand (type, 0); @@ -2179,7 +2168,7 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) right->operand.valOperand)); if (IS_LITERAL(retype)) { - p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)); + p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand)); } resType = usualBinaryConversions (&left, &right, resultType, '*'); @@ -2211,11 +2200,19 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) } else { - ic = newiCode ('*', left, right); /* normal multiplication */ /* if the size left or right > 1 then support routine */ if (getSize (ltype) > 1 || getSize (rtype) > 1) - ic->supportRtn = 1; - + { + if (IS_LITERAL (retype)) + ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */ + else + ic = newiCode ('*', left, right); /* multiplication by support routine */ + ic->supportRtn = 1; + } + else + { + ic = newiCode ('*', left, right); /* normal multiplication */ + } } IC_RESULT (ic) = newiTempOperand (resType, 1); @@ -2246,8 +2243,7 @@ geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType) !IS_FLOAT (letype) && !IS_FIXED (letype) && IS_UNSIGNED(letype) && - ((p2 = powof2 ((TYPE_UDWORD) - floatFromVal (right->operand.valOperand))) > 0)) { + ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) { ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ } else @@ -2409,11 +2405,7 @@ geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl) size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, - size, - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR); + right = geniCodeMultiply (right, size, resultType); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ @@ -2512,6 +2504,14 @@ geniCodeArray (operand * left, operand * right, int lvl) operand *size; sym_link *ltype = operandType (left); bool indexUnsigned; + RESULT_TYPE resultType; + + resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR; + if (DCL_ELEM (ltype)) + { + if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255) + resultType = RESULT_TYPE_CHAR; + } if (IS_PTR (ltype)) { @@ -2520,22 +2520,13 @@ geniCodeArray (operand * left, operand * right, int lvl) left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, - right, - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR, - lvl), + return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl), lvl); } size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, - size, - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR); + right = geniCodeMultiply (right, size, resultType); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ if (indexUnsigned) @@ -2789,7 +2780,7 @@ geniCodePreDec (operand * op, bool lvalue) /*-----------------------------------------------------------------*/ -/* geniCodeBitwise - gen int code for bitWise operators */ +/* geniCodeBitwise - gen int code for bitWise operators */ /*-----------------------------------------------------------------*/ operand * geniCodeBitwise (operand * left, operand * right, @@ -2847,7 +2838,7 @@ geniCodeAddressOf (operand * op) return op; } - /* other wise make this of the type coming in */ + /* otherwise make this of the type coming in */ ic = newiCode (ADDRESS_OF, op, NULL); IC_RESULT (ic) = newiTempOperand (p, 1); IC_RESULT (ic)->isaddr = 0; @@ -3003,10 +2994,10 @@ geniCodeRightShift (operand * left, operand * right) /* geniCodeLogic- logic code */ /*-----------------------------------------------------------------*/ static operand * -geniCodeLogic (operand * left, operand * right, int op) +geniCodeLogic (operand * left, operand * right, int op, ast *tree) { iCode *ic; - sym_link *ctype; + sym_link *ctype, *ttype; sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); @@ -3014,8 +3005,17 @@ geniCodeLogic (operand * left, operand * right, int op) check if the literal value is within bounds */ if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype)) { - checkConstantRange(ltype, - OP_VALUE(right), "compare operation", 1); + CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE); + switch (ccr_result) + { + case CCR_ALWAYS_TRUE: + case CCR_ALWAYS_FALSE: + if (!options.lessPedantic) + werror (W_COMP_RANGE, "true resp. false"); + return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0); + default: + break; + } } /* if one operand is a pointer and the other is a literal generic void pointer, @@ -3061,10 +3061,12 @@ geniCodeLogic (operand * left, operand * right, int op) } } - ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0); + ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0); ic = newiCode (op, left, right); - IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); + /* store 0 or 1 in result */ + ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink(); + IC_RESULT (ic) = newiTempOperand (ttype, 1); /* if comparing float and not a '==' || '!=' || '&&' || '||' (these @@ -3135,7 +3137,7 @@ geniCodeLogicAndOr (ast *tree, int lvl) ADDTOCHAIN (ic); /* store 0 or 1 in result */ - type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink(); + type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink(); result = newiTempOperand (type, 1); geniCodeLabel (falseLabel); @@ -3186,18 +3188,19 @@ geniCodeConditional (ast * tree,int lvl) iCode *ic; symbol *falseLabel = newiTempLabel (NULL); symbol *exitLabel = newiTempLabel (NULL); - operand *cond = ast2iCode (tree->left,lvl+1); - operand *true, *false, *result; + ast *astTrue = tree->right->left; + ast *astFalse = tree->right->right; + operand *cond = ast2iCode (tree->left, lvl+1); + operand *result = newiTempOperand (tree->ftype, 0); + operand *opTrue, *opFalse; - ic = newiCodeCondition (geniCodeRValue (cond, FALSE), - NULL, falseLabel); + ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel); ADDTOCHAIN (ic); - true = ast2iCode (tree->right->left,lvl+1); + opTrue = ast2iCode (astTrue, lvl+1); - /* move the value to a new Operand */ - result = newiTempOperand (tree->right->ftype, 0); - geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0); + /* move the value to the new operand */ + geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0); /* generate an unconditional goto */ geniCodeGoto (exitLabel); @@ -3205,8 +3208,8 @@ geniCodeConditional (ast * tree,int lvl) /* now for the right side */ geniCodeLabel (falseLabel); - false = ast2iCode (tree->right->right,lvl+1); - geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0); + opFalse = ast2iCode (astFalse, lvl+1); + geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0); /* create the exit label */ geniCodeLabel (exitLabel); @@ -3232,10 +3235,11 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) /* left is integral type and right is literal then check if the literal value is within bounds */ - if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) + if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) && + checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL && + !options.lessPedantic) { - checkConstantRange(ltype, - OP_VALUE(right), "= operation", 0); + werror (W_LIT_OVERFLOW); } /* if the left & right type don't exactly match */ @@ -3247,7 +3251,9 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) && compareType (ltype, rtype) <= 0) { - if (compareType (ltype->next, rtype) < 0) + if (left->aggr2ptr) + right = geniCodeCast (ltype, right, TRUE); + else if (compareType (ltype->next, rtype) < 0) right = geniCodeCast (ltype->next, right, TRUE); } else if (compareType (ltype, rtype) < 0) @@ -3287,7 +3293,9 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) ic->supportRtn = 1; ic->nosupdate = nosupdate; - return left; + /* left could be a pointer assignment, + return the properly casted right instead */ + return right; } /*-----------------------------------------------------------------*/ @@ -3547,6 +3555,7 @@ geniCodeFunctionBody (ast * tree,int lvl) iCode *ic; operand *func; sym_link *fetype; + char *savefilename; int savelineno; /* reset the auto generation */ @@ -3558,15 +3567,19 @@ geniCodeFunctionBody (ast * tree,int lvl) func = ast2iCode (tree->left,lvl+1); fetype = getSpec (operandType (func)); + savefilename = filename; savelineno = lineno; + filename = OP_SYMBOL (func)->fileDef; lineno = OP_SYMBOL (func)->lineDef; /* create an entry label */ geniCodeLabel (entryLabel); + filename = savefilename; lineno = savelineno; /* create a proc icode */ ic = newiCode (FUNCTION, func, NULL); - lineno=ic->lineno = OP_SYMBOL (func)->lineDef; + filename = ic->filename = OP_SYMBOL (func)->fileDef; + lineno = ic->lineno = OP_SYMBOL (func)->lineDef; ic->tree = tree; ADDTOCHAIN (ic); @@ -3690,14 +3703,14 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* 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); + min = (int) ulFromVal (vch = caseVals); while (vch->next) { cnt++; vch = vch->next; } - max = (int) floatFromVal (vch); + max = (int) ulFromVal (vch); /* Exit if the range is too large to handle with a jump table. */ if (1 + max - min > port->jumptableCost.maxCount) @@ -3774,7 +3787,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* Build the list of labels for the jump table. */ vch = caseVals; - t = (int) floatFromVal (vch); + t = (int) ulFromVal (vch); for (i=min; i<=max; i++) { if (vch && t==i) @@ -3787,7 +3800,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) addSet (&labels, newiTempLabel (buffer)); vch = vch->next; if (vch) - t = (int) floatFromVal (vch); + t = (int) ulFromVal (vch); } else { @@ -3805,13 +3818,13 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) the condition is unsigned & minimum value is zero */ if (!(min == 0 && IS_UNSIGNED (cetype))) { - boundary = geniCodeLogic (cond, operandFromLit (min), '<'); + boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL); ic = newiCodeCondition (boundary, falseLabel, NULL); ADDTOCHAIN (ic); } /* now for upper bounds */ - boundary = geniCodeLogic (cond, operandFromLit (max), '>'); + boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL); ic = newiCodeCondition (boundary, falseLabel, NULL); ADDTOCHAIN (ic); } @@ -3849,10 +3862,10 @@ geniCodeSwitch (ast * tree,int lvl) { int switchVal, caseVal; - switchVal = (int) floatFromVal (cond->operand.valOperand); + switchVal = (int) ulFromVal (cond->operand.valOperand); while (caseVals) { - caseVal = (int) floatFromVal (caseVals); + caseVal = (int) ulFromVal (caseVals); if (caseVal == switchVal) { SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d", @@ -3892,11 +3905,11 @@ geniCodeSwitch (ast * tree,int lvl) operand *compare = geniCodeLogic (cond, operandFromValue (caseVals), - EQ_OP); + EQ_OP, NULL); SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d", tree->values.switchVals.swNum, - (int) floatFromVal (caseVals)); + (int) ulFromVal (caseVals)); trueLabel = newiTempLabel (buffer); ic = newiCodeCondition (compare, trueLabel, NULL); @@ -3967,7 +3980,7 @@ geniCodeCritical (ast *tree, int lvl) operand *op = NULL; sym_link *type; - if (!options.stackAuto) + if (!options.stackAuto && !TARGET_IS_HC08) { type = newLink(SPECIFIER); SPEC_VOLATILE(type) = 1; @@ -4286,17 +4299,33 @@ ast2iCode (ast * tree,int lvl) case GETHBIT: { operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); - setOperandType (op, UCHARTYPE); + if (!IS_BIT (operandType (op))) + setOperandType (op, UCHARTYPE); return op; } case GETABIT: + { + operand *op = geniCodeBinary (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op); + if (!IS_BIT (operandType (op))) + setOperandType (op, UCHARTYPE); + return op; + } case GETBYTE: + { + operand *op = geniCodeBinary (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op); + setOperandType (op, UCHARTYPE); + return op; + } case GETWORD: { operand *op = geniCodeBinary (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE), tree->opval.op); - setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE); + setOperandType (op, UINTTYPE); return op; } case AND_OP: @@ -4310,18 +4339,18 @@ ast2iCode (ast * tree,int lvl) case NE_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. + result on all machines we have to specify a clear sequence. return geniCodeLogic (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE), tree->opval.op); */ { - operand *leftOp, *rightOp; + operand *leftOp, *rightOp; leftOp = geniCodeRValue (left , FALSE); rightOp = geniCodeRValue (right, FALSE); - return geniCodeLogic (leftOp, rightOp, tree->opval.op); + return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree); } case '?': return geniCodeConditional (tree,lvl); @@ -4339,8 +4368,7 @@ ast2iCode (ast * tree,int lvl) else right = geniCodeRValue (right, FALSE); - geniCodeAssign (left, right, 0, 1); - return right; + return geniCodeAssign (left, right, 0, 1); } case MUL_ASSIGN: return @@ -4551,6 +4579,6 @@ operand *validateOpType(operand *op, " expected %s, got %s\n", macro, args, file, line, opTypeToStr(type), op ? opTypeToStr(op->type) : "null op"); - exit(-1); + exit(EXIT_FAILURE); return op; // never reached, makes compiler happy. }