IC_RESULT (newic) = IC_RESULT (ic);
newic->lineno = lineno;
newic->parmBytes+=bytesPushed;
-
+ ebp->hasFcall = 1;
+ if (currFunc)
+ FUNC_HASFCALL (currFunc->type) = 1;
+
if(TARGET_IS_PIC16) {
/* normally these functions aren't marked external, so we can use their
* _extern field to marked as already added to symbol table */
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
newic->parmBytes+=bytesPushed;
+ ebp->hasFcall = 1;
+ if (currFunc)
+ FUNC_HASFCALL (currFunc->type) = 1;
if(TARGET_IS_PIC16) {
/* normally these functions aren't marked external, so we can use their
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
newic->parmBytes+=bytesPushed;
+ ebp->hasFcall = 1;
+ if (currFunc)
+ FUNC_HASFCALL (currFunc->type) = 1;
if(TARGET_IS_PIC16) {
/* normally these functions aren't marked external, so we can use their
int su;
int bytesPushed=0;
- // Easy special case which avoids function call: modulo by a literal power
- // of two can be replaced by a bitwise AND.
- if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
- {
- unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
-
- // See if literal value is a power of 2.
- while (litVal && !(litVal & 1))
- {
- litVal >>= 1;
- }
- if (litVal)
- {
- // discard first high bit set.
- litVal >>= 1;
- }
-
- if (!litVal)
- {
- ic->op = BITWISEAND;
- IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
- return;
- }
- }
-
remiCodeFromeBBlock (ebp, ic);
-
/* depending on the type */
for (bwd = 0; bwd < 3; bwd++)
{
IC_RESULT (newic) = IC_RESULT (ic);
newic->lineno = lineno;
newic->parmBytes+=bytesPushed; // to clear the stack after the call
+ ebp->hasFcall = 1;
+ if (currFunc)
+ FUNC_HASFCALL (currFunc->type) = 1;
if(TARGET_IS_PIC16) {
/* normally these functions aren't marked external, so we can use their
cnvToFloatCast (ic, ebbs[i]);
}
+ // Easy special case which avoids function call: modulo by a literal power
+ // of two can be replaced by a bitwise AND.
+ if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
+ IS_UNSIGNED(operandType(IC_LEFT(ic))))
+ {
+ unsigned litVal = abs(operandLitValue(IC_RIGHT(ic)));
+
+ // See if literal value is a power of 2.
+ while (litVal && !(litVal & 1))
+ {
+ litVal >>= 1;
+ }
+ if (litVal)
+ {
+ // discard lowest set bit.
+ litVal >>= 1;
+ }
+
+ if (!litVal)
+ {
+ ic->op = BITWISEAND;
+ IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
+ continue;
+ }
+ }
+
/* if long / int mult or divide or mod */
if (ic->op == '*' || ic->op == '/' || ic->op == '%')
{
static int
isLocalWithoutDef (symbol * sym)
{
- if (!sym->level)
- return 0;
-
- if (IS_STATIC (sym->etype))
+ if (!IS_AUTO (sym))
return 0;
if (IS_VOLATILE (sym->type))
if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
continue;
+ /* We also cannot remove the iCode, when an operand is volatile. */
+ /* Even read access can cause side effects on some hardware registers! */
+
+ /* if the left operand is volatile then continue */
+ if (IC_LEFT(ic) && isOperandVolatile (IC_LEFT (ic), TRUE))
+ continue;
+
+
/* if the result is a temp & isaddr then skip */
if (IC_RESULT (ic) && POINTER_SET (ic))
continue;
- if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
+ if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
+ && !SPIL_LOC (IC_RESULT (ic)))
continue;
/* if the result is used in the remainder of the */
volRight = FALSE;
}
+ if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
+ {
+ if (SPIL_LOC (IC_RESULT (ic)))
+ {
+ IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
+ SPIL_LOC (IC_RESULT (ic)) = NULL;
+ }
+ continue;
+ }
+
change = 1;
gchange++;