X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=4eeeab56a121f9dc2b255107bb942a74300313e4;hb=90bdb43b342189fcb94a398855d43f3f47f96738;hp=ee4783cd8978a02ffd7092349b093201d450e4f6;hpb=116a1bfc169e441ed10267f1b0fe8a2336b6dc78;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index ee4783cd..4eeeab56 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -80,6 +80,9 @@ iCodeTable codeTable[] = {RRC, "rrc", picGenericOne, NULL}, {RLC, "rlc", picGenericOne, NULL}, {GETHBIT, "ghbit", picGenericOne, NULL}, + {GETABIT, "gabit", picGenericOne, NULL}, + {GETBYTE, "gbyte", picGenericOne, NULL}, + {GETWORD, "gword", picGenericOne, NULL}, {UNARYMINUS, "-", picGenericOne, NULL}, {IPUSH, "push", picGenericOne, NULL}, {IPOP, "pop", picGenericOne, NULL}, @@ -124,88 +127,6 @@ iCodeTable codeTable[] = {SWAP, "swap", picGenericOne, NULL} }; -/*-----------------------------------------------------------------*/ -/* checkConstantRange: check a constant against the type */ -/*-----------------------------------------------------------------*/ - - -/* 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++; - } - v=-v; - } - - // if very pedantic: "char c=200" is not allowed - if (pedantic>1 && !IS_UNSIGNED(ltype)) { - max = max/2 + negative; - } - - 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 (pedantic>1) - fatalError++; - } -#endif -} - /*-----------------------------------------------------------------*/ /* operandName - returns the name of the operand */ /*-----------------------------------------------------------------*/ @@ -230,7 +151,7 @@ printOperand (operand * op, FILE * file) opetype = getSpec (operandType (op)); if (IS_FLOAT (opetype)) fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); - if (IS_FIXED16X16 (opetype)) + else if (IS_FIXED16X16 (opetype)) fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16)); else fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand)); @@ -722,14 +643,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; @@ -986,6 +908,34 @@ isOperandInFarSpace (operand * op) return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); } +/*-----------------------------------------------------------------*/ +/* isOperandInPagedSpace - return true if operand is in pagedSpace */ +/*-----------------------------------------------------------------*/ +bool +isOperandInPagedSpace (operand * op) +{ + sym_link *etype; + + if (!op) + return FALSE; + + if (!IS_SYMOP (op)) + return FALSE; + + if (!IS_TRUE_SYMOP (op)) + { + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; + } + else + { + etype = getSpec (operandType (op)); + } + return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); +} + /*------------------------------------------------------------------*/ /* isOperandInDirSpace - will return true if operand is in dirSpace */ /*------------------------------------------------------------------*/ @@ -1206,26 +1156,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) operandLitValue (left) * + (TYPE_TARGET_ULONG) 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) operandLitValue (left) * + (TYPE_TARGET_UINT) 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); } } @@ -1236,7 +1186,7 @@ operandOperation (operand * left, operand * right, operandLitValue (right))); break; case '/': - if ((TYPE_UDWORD) operandLitValue (right) == 0) + if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0) { werror (E_DIVIDE_BY_ZERO); retval = right; @@ -1249,8 +1199,8 @@ operandOperation (operand * left, operand * right, SPEC_USIGN (let) = 1; SPEC_USIGN (ret) = 1; retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD) operandLitValue (left) / - (TYPE_UDWORD) operandLitValue (right))); + (TYPE_TARGET_ULONG) operandLitValue (left) / + (TYPE_TARGET_ULONG) operandLitValue (right))); } else { @@ -1261,7 +1211,7 @@ operandOperation (operand * left, operand * right, } break; case '%': - if ((TYPE_UDWORD) operandLitValue (right) == 0) + if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0) { werror (E_DIVIDE_BY_ZERO); retval = right; @@ -1269,42 +1219,39 @@ 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) operandLitValue (left) % + (TYPE_TARGET_ULONG) 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) operandLitValue (left) << + (TYPE_TARGET_ULONG) 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) operandLitValue (left) >> + (TYPE_TARGET_ULONG) 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) operandLitValue (right)); break; case EQ_OP: - if (IS_FLOAT (let) || - IS_FLOAT (ret)) + if (IS_FLOAT (let) || IS_FLOAT (ret)) { retval = operandFromLit (operandLitValue (left) == operandLitValue (right)); } - else - if (IS_FIXED16X16 (let) || - IS_FIXED16X16 (ret)) + else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret)) { retval = operandFromLit (operandLitValue (left) == operandLitValue (right)); @@ -1312,10 +1259,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) operandLitValue (left); + r = (TYPE_TARGET_ULONG) 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 @@ -1324,8 +1271,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); } @@ -1352,18 +1299,18 @@ operandOperation (operand * left, operand * right, break; case BITWISEAND: retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD)operandLitValue(left) & - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_TARGET_ULONG)operandLitValue(left) & + (TYPE_TARGET_ULONG)operandLitValue(right))); break; case '|': retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD)operandLitValue(left) | - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_TARGET_ULONG)operandLitValue(left) | + (TYPE_TARGET_ULONG)operandLitValue(right))); break; case '^': retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD)operandLitValue(left) ^ - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_TARGET_ULONG)operandLitValue(left) ^ + (TYPE_TARGET_ULONG)operandLitValue(right))); break; case AND_OP: retval = operandFromLit (operandLitValue (left) && @@ -1375,7 +1322,7 @@ operandOperation (operand * left, operand * right, break; case RRC: { - TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); + TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left); retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | (i << 1)); @@ -1383,12 +1330,29 @@ operandOperation (operand * left, operand * right, break; case RLC: { - TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); + TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left); retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | (i >> 1)); } break; + case GETABIT: + retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >> + (TYPE_TARGET_ULONG)operandLitValue(right)) & 1); + break; + case GETBYTE: + retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >> + (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF); + break; + case GETWORD: + retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >> + (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF); + break; + + case GETHBIT: + retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >> + ((getSize (let) * 8) - 1)) & 1); + break; case UNARYMINUS: retval = operandFromValue (valCastLiteral (type, @@ -1397,7 +1361,7 @@ operandOperation (operand * left, operand * right, case '~': retval = operandFromValue (valCastLiteral (type, - ~((TYPE_UDWORD) + ~((TYPE_TARGET_ULONG) operandLitValue (left)))); break; @@ -1793,7 +1757,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); @@ -2134,7 +2098,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) floatFromVal (right->operand.valOperand)); } resType = usualBinaryConversions (&left, &right, resultType, '*'); @@ -2150,7 +2114,7 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) /* 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) && !IS_FIXED (letype) + if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype) && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)) && (port->support.muldiv == 1)) && strcmp (port->target, "pic16") != 0 /* don't shift for pic */ @@ -2201,8 +2165,8 @@ 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)))) { + ((p2 = powof2 ((TYPE_TARGET_ULONG) + floatFromVal (right->operand.valOperand))) > 0)) { ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ } else @@ -2364,11 +2328,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: */ @@ -2467,6 +2427,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)) { @@ -2475,22 +2443,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) @@ -2598,8 +2557,7 @@ geniCodePostInc (operand * op) werror(W_SIZEOF_VOID); if (IS_FLOAT (rvtype)) ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0"))); - else - if (IS_FIXED16X16 (rvtype)) + else if (IS_FIXED16X16 (rvtype)) ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0"))); else ic = newiCode ('+', rv, operandFromLit (size)); @@ -2639,8 +2597,7 @@ geniCodePreInc (operand * op, bool lvalue) werror(W_SIZEOF_VOID); if (IS_FLOAT (roptype)) ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0"))); - else - if (IS_FIXED16X16 (roptype)) + else if (IS_FIXED16X16 (roptype)) ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0"))); else ic = newiCode ('+', rop, operandFromLit (size)); @@ -2690,8 +2647,7 @@ geniCodePostDec (operand * op) werror(W_SIZEOF_VOID); if (IS_FLOAT (rvtype)) ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0"))); - else - if (IS_FIXED16X16 (rvtype)) + else if (IS_FIXED16X16 (rvtype)) ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0"))); else ic = newiCode ('-', rv, operandFromLit (size)); @@ -2731,8 +2687,7 @@ geniCodePreDec (operand * op, bool lvalue) werror(W_SIZEOF_VOID); if (IS_FLOAT (roptype)) ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0"))); - else - if (IS_FIXED16X16 (roptype)) + else if (IS_FIXED16X16 (roptype)) ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0"))); else ic = newiCode ('-', rop, operandFromLit (size)); @@ -2806,13 +2761,14 @@ 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; ADDTOCHAIN (ic); return IC_RESULT (ic); } + /*-----------------------------------------------------------------*/ /* setOClass - sets the output class depending on the pointer type */ /*-----------------------------------------------------------------*/ @@ -2972,8 +2928,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, @@ -3019,7 +2984,7 @@ 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); @@ -3122,6 +3087,19 @@ geniCodeUnary (operand * op, int oper) return IC_RESULT (ic); } +/*-----------------------------------------------------------------*/ +/* geniCodeBinary - for a generic binary operation */ +/*-----------------------------------------------------------------*/ +operand * +geniCodeBinary (operand * left, operand * right, int oper) +{ + iCode *ic = newiCode (oper, left, right); + + IC_RESULT (ic) = newiTempOperand (operandType (left), 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); +} + /*-----------------------------------------------------------------*/ /* geniCodeConditional - geniCode for '?' ':' operation */ /*-----------------------------------------------------------------*/ @@ -3177,10 +3155,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 */ @@ -3209,12 +3188,16 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) isOperandGlobal (left)) { symbol *sym = NULL; + operand *newRight; if (IS_TRUE_SYMOP (right)) sym = OP_SYMBOL (right); ic = newiCode ('=', NULL, right); - IC_RESULT (ic) = right = newiTempOperand (ltype, 0); - SPIL_LOC (right) = sym; + IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0); + /* avoid double fetch from volatile right, see bug 1369874 */ + if (!isOperandVolatile (right, FALSE)) + SPIL_LOC (newRight) = sym; + right = newRight; ADDTOCHAIN (ic); } @@ -3576,8 +3559,6 @@ geniCodeIfx (ast * tree,int lvl) { if (tree->falseLabel) geniCodeGoto (tree->falseLabel); - else - assert (0); } goto exit; } @@ -4220,15 +4201,6 @@ ast2iCode (ast * tree,int lvl) #endif case '~': - { - sym_link *ltype = operandType (left); - operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); - if ((SPEC_NOUN(ltype) == V_CHAR) && IS_UNSIGNED(ltype)) - { - setOperandType (op, INTTYPE); - } - return op; - } case RRC: case RLC: case SWAP: @@ -4241,6 +4213,16 @@ ast2iCode (ast * tree,int lvl) setOperandType (op, UCHARTYPE); return op; } + case GETABIT: + case GETBYTE: + case GETWORD: + { + operand *op = geniCodeBinary (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op); + setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE); + return op; + } case AND_OP: case OR_OP: return geniCodeLogicAndOr (tree, lvl); @@ -4493,6 +4475,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. }