short debugLine;
short nRegsSaved;
set *sendSet;
+ iCode *current_iCode;
}
_G;
(lineHead = newLineNode (lb)));
lineCurr->isInline = _G.inLine;
lineCurr->isDebug = _G.debugLine;
+ lineCurr->ic = _G.current_iCode;
+ lineCurr->isComment = (*lbp==';');
va_end (ap);
}
}
+
+/*-----------------------------------------------------------------*/
+/* leftRightUseAcc - returns size of accumulator use by operands */
+/*-----------------------------------------------------------------*/
+static int
+leftRightUseAcc(iCode *ic)
+{
+ operand *op;
+ int size;
+ int accuseSize = 0;
+ int accuse = 0;
+
+ if (!ic)
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "null iCode pointer");
+ return 0;
+ }
+
+ if (ic->op == IFX)
+ {
+ op = IC_COND (ic);
+ if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ {
+ accuse = 1;
+ size = getSize (OP_SYMBOL (op)->type);
+ if (size>accuseSize)
+ accuseSize = size;
+ }
+ }
+ else if (ic->op == JUMPTABLE)
+ {
+ op = IC_JTCOND (ic);
+ if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ {
+ accuse = 1;
+ size = getSize (OP_SYMBOL (op)->type);
+ if (size>accuseSize)
+ accuseSize = size;
+ }
+ }
+ else
+ {
+ op = IC_LEFT (ic);
+ if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ {
+ accuse = 1;
+ size = getSize (OP_SYMBOL (op)->type);
+ if (size>accuseSize)
+ accuseSize = size;
+ }
+ op = IC_RIGHT (ic);
+ if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+ {
+ accuse = 1;
+ size = getSize (OP_SYMBOL (op)->type);
+ if (size>accuseSize)
+ accuseSize = size;
+ }
+ }
+
+ if (accuseSize)
+ return accuseSize;
+ else
+ 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
/* if it is in direct space */
if (IN_DIRSPACE (space))
{
+ //printf("aopForSym, using AOP_DIR for %s (%x)\n", sym->name, sym);
+ //printTypeChainRaw(sym->type, NULL);
+ //printf("space = %s\n", space ? space->sname : "NULL");
sym->aop = aop = newAsmop (AOP_DIR);
aop->aopu.aop_dir = sym->rname;
aop->size = getSize (sym->type);
return;
}
- /* else spill location */
- if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
- /* force a new aop if sizes differ */
- sym->usl.spillLoc->aop = NULL;
- }
- sym->aop = op->aop = aop =
- aopForSym (ic, sym->usl.spillLoc, result);
+ if (sym->usl.spillLoc)
+ {
+ if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+ {
+ /* force a new aop if sizes differ */
+ sym->usl.spillLoc->aop = NULL;
+ }
+ sym->aop = op->aop = aop =
+ aopForSym (ic, sym->usl.spillLoc, result);
+ aop->size = getSize (sym->type);
+ return;
+ }
+
+ /* else must be a dummy iTemp */
+ sym->aop = op->aop = aop = newAsmop (AOP_DUMMY);
aop->size = getSize (sym->type);
return;
}
case AOP_STK:
{
int sz = aop->size;
- int stk = aop->aopu.aop_stk + aop->size;
+ int stk = aop->aopu.aop_stk + aop->size - 1;
bitVectUnSetBit (ic->rUsed, R0_IDX);
bitVectUnSetBit (ic->rUsed, R1_IDX);
}
op->aop = aop;
freeAsmop (op, NULL, ic, TRUE);
- if (_G.r0Pushed)
- {
- emitcode ("pop", "ar0");
- _G.r0Pushed--;
- }
-
if (_G.r1Pushed)
{
emitcode ("pop", "ar1");
_G.r1Pushed--;
}
+
+ if (_G.r0Pushed)
+ {
+ emitcode ("pop", "ar0");
+ _G.r0Pushed--;
+ }
}
}
if (strcmp (aop->aopu.aop_str[offset], "a") == 0)
return TRUE;
return FALSE;
+ case AOP_DUMMY:
+ return FALSE;
default:
/* Error case --- will have been caught already */
wassert(0);
}
}
-
/*-----------------------------------------------------------------*/
/* aopGet - for fetching value of the aop */
/*-----------------------------------------------------------------*/
/* depending on type */
switch (aop->type)
{
-
+ case AOP_DUMMY:
+ return zero;
+
case AOP_R0:
case AOP_R1:
/* if we need to increment it */
/* depending on where it is ofcourse */
switch (aop->type)
{
+ case AOP_DUMMY:
+ MOVA (s); /* read s in case it was volatile */
+ break;
+
case AOP_DIR:
if (offset)
sprintf (d, "(%s + %d)",
(x->aopu.aop_reg[0] == mcs51_regWithIdx(R0_IDX) || \
x->aopu.aop_reg[0] == mcs51_regWithIdx(R1_IDX) )))
-/*-----------------------------------------------------------------*/
-/* genNotFloat - generates not for float operations */
-/*-----------------------------------------------------------------*/
-static void
-genNotFloat (operand * op, operand * res)
-{
- int size, offset;
- char *l;
- symbol *tlbl;
-
- D(emitcode ("; genNotFloat",""));
-
- /* we will put 127 in the first byte of
- the result */
- aopPut (AOP (res), "#127", 0, isOperandVolatile (op, FALSE));
- size = AOP_SIZE (op) - 1;
- offset = 1;
-
- l = aopGet (op->aop, offset++, FALSE, FALSE);
- MOVA (l);
-
- while (size--)
- {
- emitcode ("orl", "a,%s",
- aopGet (op->aop,
- offset++, FALSE, FALSE));
- }
-
- tlbl = newiTempLabel (NULL);
- aopPut (res->aop, one, 1, isOperandVolatile (op, FALSE));
- emitcode ("jz", "%05d$", (tlbl->key + 100));
- aopPut (res->aop, zero, 1, isOperandVolatile (op, FALSE));
- emitcode ("", "%05d$:", (tlbl->key + 100));
-
- size = res->aop->size - 2;
- offset = 2;
- /* put zeros in the rest */
- while (size--)
- aopPut (res->aop, zero, offset++, isOperandVolatile (op, FALSE));
-}
/*-----------------------------------------------------------------*/
/* opIsGptr: returns non-zero if the passed operand is */
genNot (iCode * ic)
{
symbol *tlbl;
- sym_link *optype = operandType (IC_LEFT (ic));
D(emitcode ("; genNot",""));
goto release;
}
- /* if type float then do float */
- if (IS_FLOAT (optype))
- {
- genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
- goto release;
- }
-
toBoolean (IC_LEFT (ic));
tlbl = newiTempLabel (NULL);
aopOp (IC_RESULT (ic), ic, TRUE);
/* special case if in bit space */
- if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) {
- 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);
+ if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
+ {
+ 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);
+ goto release;
+ }
+
+ tlbl=newiTempLabel(NULL);
+ if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC ||
+ AOP_TYPE (IC_LEFT (ic)) == AOP_REG ||
+ IS_AOP_PREG (IC_LEFT (ic)))
+ {
+ emitcode ("cjne", "%s,#0x01,%05d$",
+ aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE),
+ tlbl->key + 100);
+ }
+ else
+ {
+ char *l = aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE);
+ MOVA (l);
+ emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
+ }
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ outBitC (IC_RESULT(ic));
goto release;
}
- tlbl=newiTempLabel(NULL);
- emitcode ("cjne", "%s,#0x01,%05d$",
- aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE), tlbl->key+100);
- emitcode ("", "%05d$:", tlbl->key+100);
- outBitC (IC_RESULT(ic));
- goto release;
- }
size = AOP_SIZE (IC_RESULT (ic));
while (size--)
(FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
!IFFUNC_ISISR (dtype))
{
- swapBanks = TRUE;
- }
-
+ swapBanks = TRUE;
+ }
+
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
saveRegisters (ic);
if (swapBanks)
{
- emitcode ("mov", "psw,#0x%02x",
+ emitcode ("mov", "psw,#0x%02x",
((FUNC_REGBANK(dtype)) << 3) & 0xff);
}
if (swapBanks)
{
- emitcode ("mov", "psw,#0x%02x",
+ emitcode ("mov", "psw,#0x%02x",
((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
}
/* if we need assign a result value */
if ((IS_ITEMP (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->accuse ||
+ OP_SYMBOL (IC_RESULT (ic))->accuse ||
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
return;
}
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL (ftype))
- emitcode ("clr", "ea");
-
/* here we need to generate the equates for the
register bank if required */
if (FUNC_REGBANK (ftype) != rbank)
emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff));
emitcode ("mov", "_spx,a");
}
-
+
+ /* if critical function then turn interrupts off */
+ if (IFFUNC_ISCRITICAL (ftype))
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+ emitcode ("setb", "c");
+ emitcode ("jbc", "ea,%05d$", (tlbl->key + 100)); /* atomic test & clear */
+ emitcode ("clr", "c");
+ emitcode ("", "%05d$:", (tlbl->key + 100));
+ emitcode ("push", "psw"); /* save old ea via c in psw */
+ }
}
/*-----------------------------------------------------------------*/
emitcode(";", "naked function: no epilogue.");
return;
}
+
+ if (IFFUNC_ISCRITICAL (sym->type))
+ {
+ emitcode ("pop", "psw"); /* restore ea via c in psw */
+ emitcode ("mov", "ea,c");
+ }
if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
{
if (!inExcludeList ("acc"))
emitcode ("pop", "acc");
- if (IFFUNC_ISCRITICAL (sym->type))
- emitcode ("setb", "ea");
-
/* if debug then send end of function */
if (options.debug && currFunc)
{
}
else
{
- if (IFFUNC_ISCRITICAL (sym->type))
- emitcode ("setb", "ea");
-
if (IFFUNC_CALLEESAVES(sym->type))
{
int i;
if (SPEC_USIGN(opetype)
// ignore the sign of left and right, what else can we do?
- || (SPEC_USIGN(operandType(left)) &&
+ || (SPEC_USIGN(operandType(left)) &&
SPEC_USIGN(operandType(right)))) {
// just an unsigned 8*8=8/16 multiply
//emitcode (";","unsigned");
/* if literal */
if (AOP_TYPE(right)==AOP_LIT) {
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
/* AND literal negative */
if (val < 0) {
emitcode ("cpl", "F0"); // complement sign flag
emitcode ("", "%05d$:", lbl->key+100);
}
emitcode ("mul", "ab");
-
+
lbl=newiTempLabel(NULL);
emitcode ("jnb", "F0,%05d$", lbl->key+100);
// only ONE op was negative, we have to do a 8/16-bit two's complement
#if 0 // one of them can be a sloc shared with the result
if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1)
#else
- if (getSize(operandType(left)) == 1 &&
+ if (getSize(operandType(left)) == 1 &&
getSize(operandType(right)) == 1)
#endif
{
assert (0);
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
}
/*-----------------------------------------------------------------*/
/* should have been converted to function call */
assert (0);
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
assert (0);
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
}
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
{
outBitC (result);
if the right is in a pointer register and left
is not */
if ((AOP_TYPE (left) == AOP_LIT) ||
+ (AOP_TYPE (left) == AOP_IMMD) ||
(IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
{
operand *t = right;
right = left;
left = t;
}
+
if (AOP_TYPE (right) == AOP_LIT)
lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
else if (AOP_TYPE (right) == AOP_REG ||
AOP_TYPE (right) == AOP_DIR ||
AOP_TYPE (right) == AOP_LIT ||
+ AOP_TYPE (right) == AOP_IMMD ||
(AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) ||
(IS_AOP_PREG (left) && !IS_AOP_PREG (right)))
{
}
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
outBitAcc (result);
}
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
outBitAcc (result);
}
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
}
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
}
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
}
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
genlshFour (result, left, shCount);
break;
default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"*** ack! mystery literal shift!\n");
break;
}
}
/*-----------------------------------------------------------------*/
-/* genUnpackBits - generates code for unpacking bits */
+/* emitPtrByteGet - emits code to get a byte into A through a */
+/* pointer register (R0, R1, or DPTR). The */
+/* original value of A can be preserved in B. */
/*-----------------------------------------------------------------*/
static void
-genUnpackBits (operand * result, char *rname, int ptype)
+emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
{
- int shCnt;
- int rlen = 0;
- sym_link *etype;
- int offset = 0;
- int rsize;
-
- D(emitcode ("; genUnpackBits",""));
-
- etype = getSpec (operandType (result));
- rsize = getSize (operandType (result));
- /* read the first byte */
- switch (ptype)
+ switch (p_type)
{
-
- case POINTER:
case IPOINTER:
+ case POINTER:
+ if (preserveAinB)
+ emitcode ("mov", "b,a");
emitcode ("mov", "a,@%s", rname);
break;
case PPOINTER:
+ if (preserveAinB)
+ emitcode ("mov", "b,a");
emitcode ("movx", "a,@%s", rname);
break;
-
+
case FPOINTER:
+ if (preserveAinB)
+ emitcode ("mov", "b,a");
emitcode ("movx", "a,@dptr");
break;
case CPOINTER:
+ if (preserveAinB)
+ emitcode ("mov", "b,a");
emitcode ("clr", "a");
emitcode ("movc", "a,@a+dptr");
break;
case GPOINTER:
+ if (preserveAinB)
+ {
+ emitcode ("push", "b");
+ emitcode ("push", "acc");
+ }
emitcode ("lcall", "__gptrget");
+ if (preserveAinB)
+ emitcode ("pop", "b");
break;
}
+}
- rlen = SPEC_BLEN (etype);
-
- /* if we have bitdisplacement then it fits */
- /* into this byte completely or if length is */
- /* less than a byte */
- if ((shCnt = SPEC_BSTR (etype)) ||
- (SPEC_BLEN (etype) <= 8))
+/*-----------------------------------------------------------------*/
+/* emitPtrByteSet - emits code to set a byte from src through a */
+/* pointer register (R0, R1, or DPTR). */
+/*-----------------------------------------------------------------*/
+static void
+emitPtrByteSet (char *rname, int p_type, char *src)
+{
+ switch (p_type)
{
+ case IPOINTER:
+ case POINTER:
+ if (*src=='@')
+ {
+ MOVA (src);
+ emitcode ("mov", "@%s,a", rname);
+ }
+ else
+ emitcode ("mov", "@%s,%s", rname, src);
+ break;
- /* shift right acc */
- AccRsh (shCnt);
+ case PPOINTER:
+ MOVA (src);
+ emitcode ("movx", "@%s,a", rname);
+ break;
+
+ case FPOINTER:
+ MOVA (src);
+ emitcode ("movx", "@dptr,a");
+ break;
- emitcode ("anl", "a,#0x%02x",
- ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
- aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
- goto finish;
+ case GPOINTER:
+ MOVA (src);
+ emitcode ("lcall", "__gptrput");
+ break;
}
+}
- /* bit field did not fit in a byte */
- aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
-
- while (1)
- {
-
- switch (ptype)
- {
- case POINTER:
- case IPOINTER:
- emitcode ("inc", "%s", rname);
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case PPOINTER:
- emitcode ("inc", "%s", rname);
- emitcode ("movx", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("inc", "dptr");
- emitcode ("movx", "a,@dptr");
- break;
-
- case CPOINTER:
- emitcode ("clr", "a");
- emitcode ("inc", "dptr");
- emitcode ("movc", "a,@a+dptr");
- break;
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits */
+/*-----------------------------------------------------------------*/
+static void
+genUnpackBits (operand * result, char *rname, int ptype)
+{
+ int offset = 0; /* result byte offset */
+ int rsize; /* result size */
+ int rlen = 0; /* remaining bitfield length */
+ sym_link *etype; /* bitfield type information */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
- case GPOINTER:
- emitcode ("inc", "dptr");
- emitcode ("lcall", "__gptrget");
- break;
- }
+ D(emitcode ("; genUnpackBits",""));
- rlen -= 8;
- /* if we are done */
- if (rlen < 8)
- break;
+ etype = getSpec (operandType (result));
+ rsize = getSize (operandType (result));
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ emitPtrByteGet (rname, ptype, FALSE);
+ AccRsh (bstr);
+ emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (8 - blen));
aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
+ goto finish;
+ }
+ /* Bit field did not fit in a byte. Copy all
+ but the partial byte at the end. */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ emitPtrByteGet (rname, ptype, FALSE);
+ aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
+ if (rlen>8)
+ emitcode ("inc", "%s", rname);
}
+ /* Handle the partial byte at the end */
if (rlen)
{
- // emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(rlen));
- AccLsh (8 - rlen);
+ emitPtrByteGet (rname, ptype, FALSE);
+ emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (8-rlen));
aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
}
while (rsize--)
aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE));
}
- return;
}
return;
}
- /* if the value is already in a pointer register
+ /* if the value is already in a pointer register
then don't need anything more */
if (!AOP_INPREG (AOP (left)))
{
- /* otherwise get a free pointer register */
- aop = newAsmop (0);
- preg = getFreePtr (ic, &aop, FALSE);
- emitcode ("mov", "%s,%s",
- preg->name,
- aopGet (AOP (left), 0, FALSE, TRUE));
- rname = preg->name;
+ if (IS_AOP_PREG (left))
+ {
+ // Aha, it is a pointer, just in disguise.
+ rname = aopGet (AOP (left), 0, FALSE, FALSE);
+ if (*rname != '@')
+ {
+ fprintf(stderr, "probable internal error: unexpected rname @ %s:%d\n",
+ __FILE__, __LINE__);
+ }
+ else
+ {
+ // Expected case.
+ emitcode ("mov", "a%s,%s", rname + 1, rname);
+ rname++; // skip the '@'.
+ }
+ }
+ else
+ {
+ /* otherwise get a free pointer register */
+ aop = newAsmop (0);
+ preg = getFreePtr (ic, &aop, FALSE);
+ emitcode ("mov", "%s,%s",
+ preg->name,
+ aopGet (AOP (left), 0, FALSE, TRUE));
+ rname = preg->name;
+ }
}
else
rname = aopGet (AOP (left), 0, FALSE, FALSE);
-
+
//aopOp (result, ic, FALSE);
aopOp (result, ic, result?TRUE:FALSE);
if (pi) { /* post increment present */
aopPut(AOP ( left ),rname,0, isOperandVolatile (left, FALSE));
}
- freeAsmop (NULL, aop, ic, TRUE);
+ freeAsmop (NULL, aop, ic, RESULTONSTACK (ic) ? FALSE : TRUE);
}
else
{
}
/* done */
+ freeAsmop (result, NULL, ic, RESULTONSTACK (ic) ? FALSE : TRUE);
freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
if (pi) pi->generated = 1;
}
}
+/*--------------------------------------------------------------------*/
+/* loadDptrFromOperand - load dptr (and optionally B) from operand op */
+/*--------------------------------------------------------------------*/
+static void
+loadDptrFromOperand (operand *op, bool loadBToo)
+{
+ if (AOP_TYPE (op) != AOP_STR)
+ {
+ /* if this is remateriazable */
+ if (AOP_TYPE (op) == AOP_IMMD)
+ {
+ emitcode ("mov", "dptr,%s", aopGet (AOP (op), 0, TRUE, FALSE));
+ if (loadBToo)
+ {
+ if (AOP(op)->aopu.aop_immd.from_cast_remat)
+ emitcode ("mov", "b,%s",aopGet(AOP (op), AOP_SIZE(op)-1, FALSE, FALSE));
+ else
+ {
+ wassertl(FALSE, "need pointerCode");
+ emitcode ("", "; mov b,???");
+ /* genPointerGet and genPointerSet originally did different
+ ** things for this case. Both seem wrong.
+ ** from genPointerGet:
+ ** emitcode ("mov", "b,#%d", pointerCode (retype));
+ ** from genPointerSet:
+ ** emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
+ */
+ }
+ }
+ }
+ else if (AOP_TYPE (op) == AOP_DPTR)
+ {
+ if (loadBToo)
+ {
+ MOVA (aopGet (AOP (op), 0, FALSE, FALSE));
+ emitcode ("push", "acc");
+ MOVA (aopGet (AOP (op), 1, FALSE, FALSE));
+ emitcode ("push", "acc");
+ emitcode ("mov", "b,%s", aopGet (AOP (op), 2, FALSE, FALSE));
+ emitcode ("pop", "dph");
+ emitcode ("pop", "dpl");
+ }
+ else
+ {
+ MOVA (aopGet (AOP (op), 0, FALSE, FALSE));
+ emitcode ("push", "acc");
+ emitcode ("mov", "dph,%s", aopGet (AOP (op), 1, FALSE, FALSE));
+ emitcode ("pop", "dpl");
+ }
+ }
+ else
+ { /* we need to get it byte by byte */
+ emitcode ("mov", "dpl,%s", aopGet (AOP (op), 0, FALSE, FALSE));
+ emitcode ("mov", "dph,%s", aopGet (AOP (op), 1, FALSE, FALSE));
+ if (loadBToo)
+ emitcode ("mov", "b,%s", aopGet (AOP (op), 2, FALSE, FALSE));
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* genFarPointerGet - gget value from far space */
/*-----------------------------------------------------------------*/
D(emitcode ("; genFarPointerGet",""));
aopOp (left, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE (left) != AOP_STR)
- {
- /* if this is remateriazable */
- if (AOP_TYPE (left) == AOP_IMMD)
- emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
- else
- { /* we need to get it byte by byte */
- emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
- emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
- }
- }
- /* so dptr know contains the address */
+ loadDptrFromOperand (left, FALSE);
+
+ /* so dptr now contains the address */
aopOp (result, ic, FALSE);
/* if bit then unpack */
D(emitcode ("; genCodePointerGet",""));
aopOp (left, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE (left) != AOP_STR)
- {
- /* if this is remateriazable */
- if (AOP_TYPE (left) == AOP_IMMD)
- emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
- else
- { /* we need to get it byte by byte */
- emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
- emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
- }
- }
- /* so dptr know contains the address */
+ loadDptrFromOperand (left, FALSE);
+
+ /* so dptr now contains the address */
aopOp (result, ic, FALSE);
/* if bit then unpack */
D(emitcode ("; genGenPointerGet",""));
aopOp (left, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE (left) != AOP_STR)
- {
- /* if this is remateriazable */
- if (AOP_TYPE (left) == AOP_IMMD)
- {
- emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
- if (AOP(left)->aopu.aop_immd.from_cast_remat)
- emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE));
- else
- emitcode ("mov", "b,#%d", pointerCode (retype));
- }
- else
- { /* we need to get it byte by byte */
- emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
- emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
- emitcode ("mov", "b,%s", aopGet (AOP (left), 2, FALSE, FALSE));
- }
- }
+ loadDptrFromOperand (left, TRUE);
+
/* so dptr know contains the address */
aopOp (result, ic, FALSE);
}
+
+
/*-----------------------------------------------------------------*/
/* genPackBits - generates code for packed bit storage */
/*-----------------------------------------------------------------*/
operand * right,
char *rname, int p_type)
{
- int shCount = 0;
- int offset = 0;
- int rLen = 0;
- int blen, bstr;
- char *l;
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ int litval; /* source literal value (if AOP_LIT) */
+ unsigned char mask; /* bitmask within current byte */
D(emitcode ("; genPackBits",""));
blen = SPEC_BLEN (etype);
bstr = SPEC_BSTR (etype);
- l = aopGet (AOP (right), offset++, FALSE, FALSE);
- MOVA (l);
-
- /* if the bit lenth is less than or */
- /* it exactly fits a byte then */
- if (SPEC_BLEN (etype) <= 8)
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
{
- shCount = SPEC_BSTR (etype);
-
- /* shift left acc */
- AccLsh (shCount);
+ mask = ((unsigned char) (0xFF << (blen + bstr)) |
+ (unsigned char) (0xFF >> (8 - bstr)));
- if (SPEC_BLEN (etype) < 8)
- { /* if smaller than a byte */
-
-
- switch (p_type)
- {
- case POINTER:
- emitcode ("mov", "b,a");
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("mov", "b,a");
- emitcode ("movx", "a,@dptr");
- break;
-
- case GPOINTER:
- emitcode ("push", "b");
- emitcode ("push", "acc");
- emitcode ("lcall", "__gptrget");
- emitcode ("pop", "b");
- break;
- }
-
- emitcode ("anl", "a,#0x%02x", (unsigned char)
- ((unsigned char) (0xFF << (blen + bstr)) |
- (unsigned char) (0xFF >> (8 - bstr))));
- emitcode ("orl", "a,b");
- if (p_type == GPOINTER)
- emitcode ("pop", "b");
- }
- }
-
- switch (p_type)
- {
- case POINTER:
- emitcode ("mov", "@%s,a", rname);
- break;
-
- case FPOINTER:
- emitcode ("movx", "@dptr,a");
- break;
-
- case GPOINTER:
- emitcode ("lcall", "__gptrput");
- break;
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with a bitfield length <8 and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval <<= bstr;
+ litval &= (~mask) & 0xff;
+ emitPtrByteGet (rname, p_type, FALSE);
+ if ((mask|litval)!=0xff)
+ emitcode ("anl","a,#0x%02x", mask);
+ if (litval)
+ emitcode ("orl","a,#0x%02x", litval);
+ }
+ else
+ {
+ if ((blen==1) && (p_type!=GPOINTER))
+ {
+ /* Case with a bitfield length == 1 and no generic pointer
+ */
+ if (AOP_TYPE (right) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
+ else
+ {
+ MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+ emitcode ("rrc","a");
+ }
+ emitPtrByteGet (rname, p_type, FALSE);
+ emitcode ("mov","acc.%d,c",bstr);
+ }
+ else
+ {
+ /* Case with a bitfield length < 8 and arbitrary source
+ */
+ MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+ /* shift and mask source value */
+ AccLsh (bstr);
+ emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
+
+ /* transfer A to B and get next byte */
+ emitPtrByteGet (rname, p_type, TRUE);
+
+ emitcode ("anl", "a,#0x%02x", mask);
+ emitcode ("orl", "a,b");
+ if (p_type == GPOINTER)
+ emitcode ("pop", "b");
+ }
+ }
+
+ emitPtrByteSet (rname, p_type, "a");
+ return;
}
- /* if we r done */
- if (SPEC_BLEN (etype) <= 8)
- return;
-
- emitcode ("inc", "%s", rname);
- rLen = SPEC_BLEN (etype);
-
- /* now generate for lengths greater than one byte */
- while (1)
+ /* Bit length is greater than 7 bits. In this case, copy */
+ /* all except the partial byte at the end */
+ for (rlen=blen;rlen>=8;rlen-=8)
{
-
- l = aopGet (AOP (right), offset++, FALSE, TRUE);
-
- rLen -= 8;
- if (rLen < 8)
- break;
-
- switch (p_type)
- {
- case POINTER:
- if (*l == '@')
- {
- MOVA (l);
- emitcode ("mov", "@%s,a", rname);
- }
- else
- emitcode ("mov", "@%s,%s", rname, l);
- break;
-
- case FPOINTER:
- MOVA (l);
- emitcode ("movx", "@dptr,a");
- break;
-
- case GPOINTER:
- MOVA (l);
- emitcode ("lcall", "__gptrput");
- break;
- }
- emitcode ("inc", "%s", rname);
+ emitPtrByteSet (rname, p_type,
+ aopGet (AOP (right), offset++, FALSE, TRUE) );
+ if (rlen>8)
+ emitcode ("inc", "%s", rname);
}
- MOVA (l);
-
- /* last last was not complete */
- if (rLen)
+ /* If there was a partial byte at the end */
+ if (rlen)
{
- /* save the byte & read byte */
- switch (p_type)
- {
- case POINTER:
- emitcode ("mov", "b,a");
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("mov", "b,a");
- emitcode ("movx", "a,@dptr");
- break;
+ mask = (((unsigned char) -1 << rlen) & 0xff);
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with partial byte and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval >>= (blen-rlen);
+ litval &= (~mask) & 0xff;
+ emitPtrByteGet (rname, p_type, FALSE);
+ if ((mask|litval)!=0xff)
+ emitcode ("anl","a,#0x%02x", mask);
+ if (litval)
+ emitcode ("orl","a,#0x%02x", litval);
+ }
+ else
+ {
+ /* Case with partial byte and arbitrary source
+ */
+ MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
+ emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
- case GPOINTER:
- emitcode ("push", "b");
- emitcode ("push", "acc");
- emitcode ("lcall", "__gptrget");
- emitcode ("pop", "b");
- break;
- }
+ /* transfer A to B and get next byte */
+ emitPtrByteGet (rname, p_type, TRUE);
- emitcode ("anl", "a,#0x%02x", (((unsigned char) -1 << rLen) & 0xff));
- emitcode ("orl", "a,b");
+ emitcode ("anl", "a,#0x%02x", mask);
+ emitcode ("orl", "a,b");
+ if (p_type == GPOINTER)
+ emitcode ("pop", "b");
+ }
+ emitPtrByteSet (rname, p_type, "a");
}
- if (p_type == GPOINTER)
- emitcode ("pop", "b");
-
- switch (p_type)
- {
-
- case POINTER:
- emitcode ("mov", "@%s,a", rname);
- break;
+}
- case FPOINTER:
- emitcode ("movx", "@dptr,a");
- break;
- case GPOINTER:
- emitcode ("lcall", "__gptrput");
- break;
- }
-}
/*-----------------------------------------------------------------*/
/* genDataPointerSet - remat pointer to data space */
/*-----------------------------------------------------------------*/
genDataPointerSet (right, result, ic);
return;
}
-
+
/* if the value is already in a pointer register
then don't need anything more */
if (!AOP_INPREG (AOP (result)))
else
{
// Expected case.
+ emitcode ("mov", "a%s,%s", rname + 1, rname);
rname++; // skip the '@'.
}
}
}
aopOp (right, ic, FALSE);
-
+
/* if bitfield then unpack the bits */
if (IS_BITVAR (retype) || IS_BITVAR (letype))
genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER);
D(emitcode ("; genFarPointerSet",""));
aopOp (result, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE (result) != AOP_STR)
- {
- /* if this is remateriazable */
- if (AOP_TYPE (result) == AOP_IMMD)
- emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
- else
- { /* we need to get it byte by byte */
- emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
- emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
- }
- }
+ loadDptrFromOperand (result, FALSE);
+
/* so dptr know contains the address */
aopOp (right, ic, FALSE);
D(emitcode ("; genGenPointerSet",""));
aopOp (result, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE (result) != AOP_STR)
- {
- /* if this is remateriazable */
- if (AOP_TYPE (result) == AOP_IMMD)
- {
- emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
- if (AOP(result)->aopu.aop_immd.from_cast_remat)
- emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE));
- else
- emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
- }
- else
- { /* we need to get it byte by byte */
- emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
- emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
- emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE));
- }
- }
+ loadDptrFromOperand (result, TRUE);
+
/* so dptr know contains the address */
aopOp (right, ic, FALSE);
aopOp (right, ic, FALSE);
aopOp (result, ic, FALSE);
- /* if the result is a bit */
- if (IS_BITVAR(OP_SYMBOL(result)->type))
+ /* if the result is a bit (and not a bitfield) */
+ // if (AOP_TYPE (result) == AOP_CRY)
+ if (IS_BITVAR (OP_SYMBOL (result)->type)
+ && !IS_BITFIELD (OP_SYMBOL (result)->type) )
{
/* if the right size is a literal then
we know what the value is */
goto release;
}
+
/* if they are the same size : or less */
if (AOP_SIZE (result) <= AOP_SIZE (right))
{
offset = 0;
while (size--)
{
- emitcode ("mov", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
offset++;
}
freeAsmop (right, NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* genCritical - generate code for start of a critical sequence */
+/*-----------------------------------------------------------------*/
+static void
+genCritical (iCode *ic)
+{
+ symbol *tlbl = newiTempLabel (NULL);
+
+ D(emitcode("; genCritical",""));
+
+ if (IC_RESULT (ic))
+ aopOp (IC_RESULT (ic), ic, TRUE);
+
+ emitcode ("setb", "c");
+ emitcode ("jbc", "ea,%05d$", (tlbl->key + 100)); /* atomic test & clear */
+ emitcode ("clr", "c");
+ emitcode ("", "%05d$:", (tlbl->key + 100));
+
+ if (IC_RESULT (ic))
+ outBitC (IC_RESULT (ic)); /* save old ea in an operand */
+ else
+ emitcode ("push", "psw"); /* save old ea via c in psw on top of stack*/
+
+ if (IC_RESULT (ic))
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndCritical - generate code for end of a critical sequence */
+/*-----------------------------------------------------------------*/
+static void
+genEndCritical (iCode *ic)
+{
+ D(emitcode("; genEndCritical",""));
+
+ if (IC_RIGHT (ic))
+ {
+ aopOp (IC_RIGHT (ic), ic, FALSE);
+ if (AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
+ {
+ emitcode ("mov", "c,%s", IC_RIGHT (ic)->aop->aopu.aop_dir);
+ emitcode ("mov", "ea,c");
+ }
+ else
+ {
+ MOVA (aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
+ emitcode ("rrc", "a");
+ emitcode ("mov", "ea,c");
+ }
+ freeAsmop (IC_RIGHT (ic), NULL, ic, TRUE);
+ }
+ else
+ {
+ emitcode ("pop", "psw"); /* restore ea via c in psw on top of stack */
+ emitcode ("mov", "ea,c");
+ }
+}
+
+
/*-----------------------------------------------------------------*/
/* gen51Code - generate code for 8051 based controllers */
/*-----------------------------------------------------------------*/
for (ic = lic; ic; ic = ic->next)
{
-
+ _G.current_iCode = ic;
+
if (ic->lineno && cln != ic->lineno)
{
if (options.debug)
genDummyRead (ic);
break;
+ case CRITICAL:
+ genCritical (ic);
+ break;
+
+ case ENDCRITICAL:
+ genEndCritical (ic);
+ break;
+
default:
ic = ic;
}
}
+ _G.current_iCode = NULL;
/* now we are ready to call the
peep hole optimizer */