extern int mcs51_ptrRegReq;
extern int mcs51_nRegs;
extern FILE *codeOutFile;
-static void saverbank (int, iCode *, bool);
+static void saveRBank (int, iCode *, bool);
#define RESULTONSTACK(x) \
(IC_RESULT(x) && IC_RESULT(x)->aop && \
IC_RESULT(x)->aop->type == AOP_STK )
return aop;
}
-static void
-genSetDPTR (int n)
-{
- if (!n)
- {
- emitcode (";", "Select standard DPTR");
- emitcode ("mov", "dps, #0x00");
- }
- else
- {
- emitcode (";", "Select alternate DPTR");
- emitcode ("mov", "dps, #0x01");
- }
-}
-
/*-----------------------------------------------------------------*/
/* pointerCode - returns the code for a pointer type */
/*-----------------------------------------------------------------*/
return rs;
case AOP_DPTR:
- case AOP_DPTR2:
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR (1);
- }
-
while (offset > aop->coff)
{
emitcode ("inc", "dptr");
{
emitcode ("movx", "a,@dptr");
}
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR (0);
- }
-
return (dname ? "acc" : "a");
break;
case AOP_DPTR:
- case AOP_DPTR2:
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR (1);
- }
-
if (aop->code)
{
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
MOVA (s);
emitcode ("movx", "@dptr,a");
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR (0);
- }
break;
case AOP_R0:
static void
reAdjustPreg (asmop * aop)
{
- aop->coff = 0;
if ((aop->coff==0) || aop->size <= 1)
return;
emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
break;
case AOP_DPTR:
- case AOP_DPTR2:
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR (1);
- }
while (aop->coff--)
{
emitcode ("lcall", "__decdptr");
}
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR (0);
- }
break;
-
}
-
+ aop->coff = 0;
}
#define AOP(op) op->aop
AOP_TYPE(x) == AOP_R0))
#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
- AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
- AOP(x)->paged))
+ AOP_TYPE(x) == AOP_DPTR || AOP(x)->paged))
#define AOP_INPREG(x) (x && (x->type == AOP_REG && \
(x->aopu.aop_reg[0] == mcs51_regWithIdx(R0_IDX) || \
}
detype = getSpec (operandType (IC_LEFT (ic)));
+
+#if 0 // why should we do this here??? jwk20011105
if (detype &&
(SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
IS_ISR (currFunc->etype) &&
!ic->bankSaved)
-
- saverbank (SPEC_BANK (detype), ic, TRUE);
+ saveRBank (SPEC_BANK (detype), ic, TRUE);
+#endif
}
/*-----------------------------------------------------------------*/
}
/*-----------------------------------------------------------------*/
-/* unsaverbank - restores the resgister bank from stack */
+/* unsaveRBank - restores the resgister bank from stack */
/*-----------------------------------------------------------------*/
static void
-unsaverbank (int bank, iCode * ic, bool popPsw)
+unsaveRBank (int bank, iCode * ic, bool popPsw)
{
int i;
asmop *aop;
}
/*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack */
+/* saveRBank - saves an entire register bank on the stack */
/*-----------------------------------------------------------------*/
static void
-saverbank (int bank, iCode * ic, bool pushPsw)
+saveRBank (int bank, iCode * ic, bool pushPsw)
{
int i;
asmop *aop;
{
sym_link *detype;
- /* if caller saves & we have not saved then */
- if (!ic->regsSaved)
- saveRegisters (ic);
-
- /* if we are calling a function that is not using
- the same register bank then we need to save the
- destination registers on the stack */
- detype = getSpec (operandType (IC_LEFT (ic)));
- if (detype &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
- IS_ISR (currFunc->etype) &&
- !ic->bankSaved)
-
- saverbank (SPEC_BANK (detype), ic, TRUE);
-
/* if send set is not empty the assign */
if (_G.sendSet)
{
}
_G.sendSet = NULL;
}
+
+ /* if we are calling a function that is not using
+ the same register bank then we need to save the
+ destination registers on the stack */
+ detype = getSpec (operandType (IC_LEFT (ic)));
+ if (detype &&
+ (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
+ IS_ISR (currFunc->etype) &&
+ !ic->bankSaved) {
+ saveRBank (SPEC_BANK (detype), ic, TRUE);
+ } else /* no need to save if we just saved the whole bank */ {
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters (ic);
+ }
+
/* make the call */
emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
OP_SYMBOL (IC_LEFT (ic))->rname :
/* if register bank was saved then pop them */
if (ic->bankSaved)
- unsaverbank (SPEC_BANK (detype), ic, TRUE);
+ unsaveRBank (SPEC_BANK (detype), ic, TRUE);
/* if we hade saved some registers then unsave them */
if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
if (detype &&
IS_ISR (currFunc->etype) &&
(SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
- saverbank (SPEC_BANK (detype), ic, TRUE);
+ saveRBank (SPEC_BANK (detype), ic, TRUE);
/* push the return address on to the stack */
if (detype &&
(SPEC_BANK (currFunc->etype) !=
SPEC_BANK (detype)))
- unsaverbank (SPEC_BANK (detype), ic, TRUE);
+ unsaveRBank (SPEC_BANK (detype), ic, TRUE);
/* if we hade saved some registers then
unsave them */
else
{
/* this function has a function call cannot
- determines register usage so we will have the
+ determines register usage so we will have to push the
entire bank */
- saverbank (0, ic, FALSE);
+ saveRBank (0, ic, FALSE);
}
}
}
else
{
/* this function has a function call cannot
- determines register usage so we will have the
+ determines register usage so we will have to pop the
entire bank */
- unsaverbank (0, ic, FALSE);
+ unsaveRBank (0, ic, FALSE);
}
}
if (size<1 || size>2) {
// this should never happen
fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
- AOP_SIZE(result), __FUNCTION__, lineno);
+ AOP_SIZE(result), __FILE__, lineno);
exit (1);
}
aopOp (right, ic, FALSE);
/* special case both in far space */
- if ((AOP_TYPE (right) == AOP_DPTR ||
- AOP_TYPE (right) == AOP_DPTR2) &&
+ if (AOP_TYPE (right) == AOP_DPTR &&
IS_TRUE_SYMOP (result) &&
isOperandInFarSpace (result))
{
aopOp (IC_RESULT (ic), ic, FALSE);
- if (IS_AOP_PREG (IC_RESULT (ic)))
+ if (AOP_NEEDSACC(IC_RESULT(ic)))
+ {
+ /* If the result is accessed indirectly via
+ * the accumulator, we must explicitly write
+ * it back after the decrement.
+ */
+ char *rByte = aopGet(AOP(IC_RESULT(ic)), 0, FALSE, FALSE);
+
+ if (strcmp(rByte, "a"))
+ {
+ /* Something is hopelessly wrong */
+ fprintf(stderr, "*** warning: internal error at %s:%d\n",
+ __FILE__, __LINE__);
+ /* We can just give up; the generated code will be inefficient,
+ * but what the hey.
+ */
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ return 0;
+ }
+ emitcode ("dec", "%s", rByte);
+ aopPut(AOP(IC_RESULT(ic)), rByte, 0);
+ emitcode ("jnz", "%05d$", lbl->key + 100);
+ }
+ else if (IS_AOP_PREG (IC_RESULT (ic)))
{
emitcode ("dec", "%s",
aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));