{
short r0Pushed;
short r1Pushed;
+ short r0InB;
+ short r1InB;
short accInUse;
short inLine;
short debugLine;
va_end (ap);
}
+/*-----------------------------------------------------------------*/
+/* mcs51_emitDebuggerSymbol - associate the current code location */
+/* with a debugger symbol */
+/*-----------------------------------------------------------------*/
+void
+mcs51_emitDebuggerSymbol (char * debugSym)
+{
+ _G.debugLine = 1;
+ emitcode ("", "%s ==.", debugSym);
+ _G.debugLine = 0;
+}
+
/*-----------------------------------------------------------------*/
/* mova - moves specified value into accumulator */
/*-----------------------------------------------------------------*/
if (!r0iu)
{
/* push it if not already pushed */
- if (!_G.r0Pushed)
+ if (ic->op == IPUSH)
+ {
+ emitcode ("mov", "b,%s",
+ mcs51_regWithIdx (R0_IDX)->dname);
+ _G.r0InB++;
+ }
+ else if (!_G.r0Pushed)
{
emitcode ("push", "%s",
mcs51_regWithIdx (R0_IDX)->dname);
if (!r1iu)
{
/* push it if not already pushed */
- if (!_G.r1Pushed)
+ if (ic->op == IPUSH)
+ {
+ emitcode ("mov", "b,%s",
+ mcs51_regWithIdx (R1_IDX)->dname);
+ _G.r1InB++;
+ }
+ else if (!_G.r1Pushed)
{
emitcode ("push", "%s",
mcs51_regWithIdx (R1_IDX)->dname);
if (sym1 == sym2)
return TRUE;
- if (strcmp (sym1->rname, sym2->rname) == 0)
+ if (sym1->rname[0] && sym2->rname[0]
+ && strcmp (sym1->rname, sym2->rname) == 0)
return TRUE;
-
/* if left is a tmp & right is not */
if (IS_ITEMP (op1) &&
!IS_ITEMP (op2) &&
switch (aop->type)
{
case AOP_R0:
- if (_G.r0Pushed)
+ if (_G.r0InB)
+ {
+ emitcode ("mov", "r0,b");
+ _G.r0InB--;
+ }
+ else if (_G.r0Pushed)
{
if (pop)
{
break;
case AOP_R1:
+ if (_G.r1InB)
+ {
+ emitcode ("mov", "r1,b");
+ _G.r1InB--;
+ }
if (_G.r1Pushed)
{
if (pop)
}
}
+/*------------------------------------------------------------------*/
+/* freeForBranchAsmop - partial free up of Asmop for a branch; just */
+/* pop r0 or r1 off stack if pushed */
+/*------------------------------------------------------------------*/
+static void
+freeForBranchAsmop (operand * op)
+{
+ asmop *aop;
+
+ if (!op)
+ return;
+
+ aop = op->aop;
+
+ if (!aop)
+ return;
+
+ if (aop->freed)
+ return;
+
+ switch (aop->type)
+ {
+ case AOP_R0:
+ if (_G.r0InB)
+ {
+ emitcode ("mov", "r0,b");
+ }
+ else if (_G.r0Pushed)
+ {
+ emitcode ("pop", "ar0");
+ }
+ break;
+
+ case AOP_R1:
+ if (_G.r1InB)
+ {
+ emitcode ("mov", "r1,b");
+ }
+ else if (_G.r1Pushed)
+ {
+ emitcode ("pop", "ar1");
+ }
+ break;
+
+ case AOP_STK:
+ {
+ int sz = aop->size;
+ int stk = aop->aopu.aop_stk + aop->size - 1;
+
+ emitcode ("mov", "b,r0");
+ if (stk)
+ {
+ emitcode ("mov", "a,_bp");
+ emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff);
+ emitcode ("mov", "r0,a");
+ }
+ else
+ {
+ emitcode ("mov", "r0,_bp");
+ }
+
+ while (sz--)
+ {
+ emitcode ("pop", "acc");
+ emitcode ("mov", "@r0,a");
+ if (!sz)
+ break;
+ emitcode ("dec", "r0");
+ }
+ emitcode ("mov", "r0,b");
+ }
+ }
+
+}
+
/*-----------------------------------------------------------------*/
/* aopGetUsesAcc - indicates ahead of time whether aopGet() will */
/* clobber the accumulator */
{
if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
{
- emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
- emitcode ("cpl", "c");
- emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
+ /* promotion rules are responsible for this strange result: */
+ emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir);
goto release;
}
if (IFFUNC_ISNAKED(sym->type))
{
emitcode(";", "naked function: no epilogue.");
+ if (options.debug && currFunc)
+ debugFile->writeEndFunction (currFunc, ic, 0);
return;
}
/* if debug then send end of function */
if (options.debug && currFunc)
{
- _G.debugLine = 1;
- emitcode ("", "C$%s$%d$%d$%d ==.",
- FileBaseName (ic->filename), currFunc->lastLine,
- ic->level, ic->block);
- if (IS_STATIC (currFunc->etype))
- emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
- else
- emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
- _G.debugLine = 0;
+ debugFile->writeEndFunction (currFunc, ic, 1);
}
emitcode ("reti", "");
/* if debug then send end of function */
if (options.debug && currFunc)
{
- _G.debugLine = 1;
- emitcode ("", "C$%s$%d$%d$%d ==.",
- FileBaseName (ic->filename), currFunc->lastLine,
- ic->level, ic->block);
- if (IS_STATIC (currFunc->etype))
- emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
- else
- emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
- _G.debugLine = 0;
+ debugFile->writeEndFunction (currFunc, ic, 1);
}
emitcode ("ret", "");
}
- if (!port->peep.getRegsRead || !port->peep.getRegsWritten)
+ if (!port->peep.getRegsRead || !port->peep.getRegsWritten || options.nopeep)
return;
/* If this was an interrupt handler using bank 0 that called another */
&& !bitVectBitValue (regsUsed, CND_IDX))
{
regsUsed = bitVectUnion (regsUsed, regsUsedPrologue);
- if (IFFUNC_ISISR (sym->type) && !FUNC_REGBANK(sym->type)
- && !sym->stack)
+ if (IFFUNC_ISISR (sym->type) && !FUNC_REGBANK (sym->type)
+ && !sym->stack && !FUNC_ISCRITICAL (sym->type))
bitVectUnSetBit (regsUsed, CND_IDX);
}
else
/* genIfxJump :- will create a jump depending on the ifx */
/*-----------------------------------------------------------------*/
static void
-genIfxJump (iCode * ic, char *jval)
+genIfxJump (iCode * ic, char *jval, operand *left, operand *right, operand *result)
{
symbol *jlbl;
symbol *tlbl = newiTempLabel (NULL);
emitcode (inst, "%s,%05d$", jval, (tlbl->key + 100));
else
emitcode (inst, "%05d$", tlbl->key + 100);
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", jlbl->key + 100);
emitcode ("", "%05d$:", tlbl->key + 100);
MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE));
if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
{
- genIfxJump (ifx, "acc.7");
+ genIfxJump (ifx, "acc.7", left, right, result);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (left, NULL, ic, TRUE);
+
return;
}
else
ifx conditional branch then generate
code a little differently */
if (ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", NULL, NULL, result);
else
outBitC (result);
/* leave the result in acc */
if (IC_TRUE (ifx))
{
emitcode ("jnc", "%05d$", tlbl->key + 100);
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
}
else
{
emitcode ("jc", "%05d$", tlbl->key + 100);
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
}
emitcode ("", "%05d$:", tlbl->key + 100);
gencjneshort (left, right, tlbl);
if (IC_TRUE (ifx))
{
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
emitcode ("", "%05d$:", tlbl->key + 100);
}
symbol *lbl = newiTempLabel (NULL);
emitcode ("sjmp", "%05d$", lbl->key + 100);
emitcode ("", "%05d$:", tlbl->key + 100);
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
emitcode ("", "%05d$:", lbl->key + 100);
}
}
if (ifx)
{
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", left, right, result);
goto release;
}
/* if the result is used in an arithmetic operation
}
if (ifx)
{
- genIfxJump (ifx, "a");
+ genIfxJump (ifx, "a", left, right, result);
goto release;
}
/* if the result is used in an arithmetic operation
/* jmpTrueOrFalse - */
/*-----------------------------------------------------------------*/
static void
-jmpTrueOrFalse (iCode * ic, symbol * tlbl)
+jmpTrueOrFalse (iCode * ic, symbol * tlbl, operand *left, operand *right, operand *result)
{
// ugly but optimized by peephole
if (IC_TRUE (ic))
symbol *nlbl = newiTempLabel (NULL);
emitcode ("sjmp", "%05d$", nlbl->key + 100);
emitcode ("", "%05d$:", tlbl->key + 100);
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
emitcode ("", "%05d$:", nlbl->key + 100);
}
else
{
+ freeForBranchAsmop (result);
+ freeForBranchAsmop (right);
+ freeForBranchAsmop (left);
emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
emitcode ("", "%05d$:", tlbl->key + 100);
}
outBitC (result);
// if(bit & ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", left, right, result);
goto release;
}
if (ifx)
{
sprintf (buffer, "acc.%d", posbit & 0x07);
- genIfxJump (ifx, buffer);
+ genIfxJump (ifx, buffer, left, right, result);
}
goto release;
}
else
{
if (ifx)
- jmpTrueOrFalse (ifx, tlbl);
+ jmpTrueOrFalse (ifx, tlbl, left, right, result);
else
emitcode ("", "%05d$:", tlbl->key + 100);
goto release;
outBitC (result);
}
else if (ifx)
- jmpTrueOrFalse (ifx, tlbl);
+ jmpTrueOrFalse (ifx, tlbl, left, right, result);
else
emitcode ("", "%05d$:", tlbl->key + 100);
}
emitcode ("jnz", "%05d$", tlbl->key + 100);
if ((AOP_TYPE (result) == AOP_CRY) && ifx)
{
- jmpTrueOrFalse (ifx, tlbl);
+ jmpTrueOrFalse (ifx, tlbl, left, right, result);
goto release;
}
else
outBitC (result);
// if(bit | ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", left, right, result);
goto release;
}
}
else
{
- genIfxJump (ifx, "a");
+ genIfxJump (ifx, "a", left, right, result);
goto release;
}
}
outBitC (result);
}
else if (ifx)
- jmpTrueOrFalse (ifx, tlbl);
+ jmpTrueOrFalse (ifx, tlbl, left, right, result);
else
emitcode ("", "%05d$:", tlbl->key + 100);
}
outBitC (result);
// if(bit | ...)
else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
- genIfxJump (ifx, "c");
+ genIfxJump (ifx, "c", left, right, result);
goto release;
}
outBitC (result);
}
else if (ifx)
- jmpTrueOrFalse (ifx, tlbl);
+ jmpTrueOrFalse (ifx, tlbl, left, right, result);
}
else
for (; (size--); offset++)
/* if the condition is a bit variable */
if (isbit && IS_ITEMP (cond) &&
SPIL_LOC (cond))
- genIfxJump (ic, SPIL_LOC (cond)->rname);
+ genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL);
else if (isbit && !IS_ITEMP (cond))
- genIfxJump (ic, OP_SYMBOL (cond)->rname);
+ genIfxJump (ic, OP_SYMBOL (cond)->rname, NULL, NULL, NULL);
else
- genIfxJump (ic, "a");
+ genIfxJump (ic, "a", NULL, NULL, NULL);
ic->generated = 1;
}
/* if debug information required */
if (options.debug && currFunc)
{
- debugFile->writeFunction(currFunc);
- _G.debugLine = 1;
- if (IS_STATIC (currFunc->etype))
- emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
- else
- emitcode ("", "G$%s$0$0 ==.", currFunc->name);
- _G.debugLine = 0;
+ debugFile->writeFunction (currFunc, lic);
}
/* stack pointer name */
if (options.useXstack)
{
if (options.debug)
{
- _G.debugLine = 1;
- emitcode ("", "C$%s$%d$%d$%d ==.",
- FileBaseName (ic->filename), ic->lineno,
- ic->level, ic->block);
- _G.debugLine = 0;
+ debugFile->writeCLine(ic);
}
if (!options.noCcodeInAsm) {
emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,