+2003-08-20 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ Fixed bug #741761
+
+ * src/mcs51/gen.c (aopForSym, leftRightUseAcc),
+ * src/ds390/gen.c (aopForSym, leftRightUseAcc): preserve A and B
+ if the left or right operand symbols have the accuse flag set.
+
2003-08-20 Erik Petrich <epetrich@ivorytower.norman.ok.us>
Changed the type of the result of the ! (NOT) operator to char;
}
+/*-----------------------------------------------------------------*/
+/* leftRightUseAcc - returns size of accumulator use by operands */
+/*-----------------------------------------------------------------*/
+static int
+leftRightUseAcc(iCode *ic)
+{
+ int accuse = 0;
+
+ if (ic && IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))
+ && OP_SYMBOL (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->accuse)
+ accuse = (accuse < OP_SYMBOL (IC_LEFT (ic))->nRegs)
+ ? OP_SYMBOL (IC_LEFT (ic))->nRegs : accuse;
+
+ if (ic && IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
+ && OP_SYMBOL (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->accuse)
+ accuse = (accuse < OP_SYMBOL (IC_RIGHT (ic))->nRegs)
+ ? OP_SYMBOL (IC_RIGHT (ic))->nRegs : accuse;
+
+ return accuse;
+}
+
/*-----------------------------------------------------------------*/
/* aopForSym - for a true symbol */
/*-----------------------------------------------------------------*/
{
asmop *aop;
memmap *space = SPEC_OCLS (sym->etype);
+ int accuse = leftRightUseAcc (ic);
/* if already has one */
if (sym->aop)
if (sym->onStack)
{
- if (_G.accInUse)
+ if (_G.accInUse || accuse)
emitcode ("push", "acc");
- if (_G.bInUse)
+ if (_G.bInUse || (accuse>1))
emitcode ("push", "b");
emitcode ("mov", "a,_bp");
emitcode ("mov", "%s,a",
aop->aopu.aop_ptr->name);
- if (_G.bInUse)
+ if (_G.bInUse || (accuse>1))
emitcode ("pop", "b");
- if (_G.accInUse)
+ if (_G.accInUse || accuse)
emitcode ("pop", "acc");
}
else
emitcode("mov","dps,#0");
}
} else {
- if (_G.accInUse)
+ if (_G.accInUse || accuse)
emitcode ("push", "acc");
- if (_G.bInUse)
+ if (_G.bInUse || (accuse>1))
emitcode ("push", "b");
emitcode ("mov", "a,_bpx");
emitcode ("mov", "dpl,b");
}
- if (_G.bInUse)
+ if (_G.bInUse || (accuse>1))
emitcode ("pop", "b");
- if (_G.accInUse)
+ if (_G.accInUse || accuse)
emitcode ("pop", "acc");
}
sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
}
+
+/*-----------------------------------------------------------------*/
+/* leftRightUseAcc - returns size of accumulator use by operands */
+/*-----------------------------------------------------------------*/
+static int
+leftRightUseAcc(iCode *ic)
+{
+ int accuse = 0;
+
+ if (ic && IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))
+ && OP_SYMBOL (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->accuse)
+ accuse = (accuse < OP_SYMBOL (IC_LEFT (ic))->nRegs)
+ ? OP_SYMBOL (IC_LEFT (ic))->nRegs : accuse;
+
+ if (ic && IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
+ && OP_SYMBOL (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->accuse)
+ accuse = (accuse < OP_SYMBOL (IC_RIGHT (ic))->nRegs)
+ ? OP_SYMBOL (IC_RIGHT (ic))->nRegs : accuse;
+
+ return accuse;
+}
+
+
/*-----------------------------------------------------------------*/
/* aopForSym - for a true symbol */
/*-----------------------------------------------------------------*/
if (sym->onStack)
{
- if (_G.accInUse)
+ if (_G.accInUse || leftRightUseAcc (ic))
emitcode ("push", "acc");
emitcode ("mov", "a,_bp");
emitcode ("mov", "%s,a",
aop->aopu.aop_ptr->name);
- if (_G.accInUse)
+ if (_G.accInUse || leftRightUseAcc (ic))
emitcode ("pop", "acc");
}
else