short debugLine;
short nRegsSaved;
set *sendSet;
+ iCode *current_iCode;
}
_G;
while (isspace (*lbp))
lbp++;
-// printf ("%s\n", lb); // EEP - debugging
-
+
if (lbp && *lbp)
lineCurr = (lineCurr ?
connectLine (lineCurr, newLineNode (lb)) :
(lineHead = newLineNode (lb)));
lineCurr->isInline = _G.inLine;
lineCurr->isDebug = _G.debugLine;
+ lineCurr->ic = _G.current_iCode;
+ lineCurr->isComment = (*lbp==';');
va_end (ap);
}
static int
leftRightUseAcc(iCode *ic)
{
+ operand *op;
+ int size;
+ int accuseSize = 0;
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;
+ if (!ic)
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "null iCode pointer");
+ return 0;
+ }
- return accuse;
+ 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;
}
/* 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)",
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;
genPlus (iCode * ic)
{
int size, offset = 0;
- char *add;
+ int skip_bytes = 0;
+ char *add = "add";
asmop *leftOp, *rightOp;
+ operand * op;
/* special cases :- */
goto release;
size = getDataSize (IC_RESULT (ic));
-
leftOp = AOP(IC_LEFT(ic));
rightOp = AOP(IC_RIGHT(ic));
- add = "add";
+ op=IC_LEFT(ic);
+
+ /* if this is an add for an array access
+ at a 256 byte boundary */
+ if ( 2 == size
+ && AOP_TYPE (op) == AOP_IMMD
+ && IS_SYMOP (op)
+ && IS_SPEC (OP_SYM_ETYPE (op))
+ && SPEC_ABSA (OP_SYM_ETYPE (op))
+ && (SPEC_ADDR (OP_SYM_ETYPE (op)) & 0xff) == 0
+ )
+ {
+ D(emitcode ("; genPlus aligned array",""));
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (rightOp, 0, FALSE, FALSE),
+ 0,
+ isOperandVolatile (IC_RESULT (ic), FALSE));
- while (size--)
- {
- if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset))
+ if( 1 == getDataSize (IC_RIGHT (ic)) )
{
- emitcode("mov", "b,a");
- MOVA (aopGet (leftOp, offset, FALSE, TRUE));
- emitcode("xch", "a,b");
- MOVA (aopGet (rightOp, offset, FALSE, TRUE));
- emitcode (add, "a,b");
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (leftOp, 1, FALSE, FALSE),
+ 1,
+ isOperandVolatile (IC_RESULT (ic), FALSE));
}
- else if (aopGetUsesAcc (leftOp, offset))
- {
- MOVA (aopGet (leftOp, offset, FALSE, TRUE));
- emitcode (add, "a,%s", aopGet (rightOp, offset, FALSE, TRUE));
+ else
+ {
+ MOVA (aopGet (AOP (IC_LEFT (ic)), 1, FALSE, FALSE));
+ emitcode ("add", "a,%s", aopGet (rightOp, 1, FALSE, FALSE));
+ aopPut (AOP (IC_RESULT (ic)), "a", 1, isOperandVolatile (IC_RESULT (ic), FALSE));
}
+ goto release;
+ }
+
+ /* if the lower bytes of a literal are zero skip the addition */
+ if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT )
+ {
+ while ((0 == ((unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) & (0xff << skip_bytes*8))) &&
+ (skip_bytes+1 < size))
+ {
+ skip_bytes++;
+ }
+ if (skip_bytes)
+ D(emitcode ("; genPlus shortcut",""));
+ }
+
+ while (size--)
+ {
+ if( offset >= skip_bytes )
+ {
+ if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset))
+ {
+ emitcode("mov", "b,a");
+ MOVA (aopGet (leftOp, offset, FALSE, TRUE));
+ emitcode("xch", "a,b");
+ MOVA (aopGet (rightOp, offset, FALSE, TRUE));
+ emitcode (add, "a,b");
+ }
+ else if (aopGetUsesAcc (leftOp, offset))
+ {
+ MOVA (aopGet (leftOp, offset, FALSE, TRUE));
+ emitcode (add, "a,%s", aopGet (rightOp, offset, FALSE, TRUE));
+ }
+ else
+ {
+ MOVA (aopGet (rightOp, offset, FALSE, TRUE));
+ emitcode (add, "a,%s", aopGet (leftOp, offset, FALSE, TRUE));
+ }
+ aopPut (AOP (IC_RESULT (ic)), "a", offset, isOperandVolatile (IC_RESULT (ic), FALSE));
+ add = "addc"; /* further adds must propagate carry */
+ }
else
- {
- MOVA (aopGet (rightOp, offset, FALSE, TRUE));
- emitcode (add, "a,%s", aopGet (leftOp, offset, FALSE, TRUE));
+ {
+ if( !sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) ||
+ isOperandVolatile (IC_RESULT (ic), FALSE))
+ {
+ /* just move */
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (leftOp, offset, FALSE, FALSE),
+ offset,
+ isOperandVolatile (IC_RESULT (ic), FALSE));
+ }
}
- aopPut (AOP (IC_RESULT (ic)), "a", offset++, isOperandVolatile (IC_RESULT (ic), FALSE));
- add = "addc"; /* further adds must propagate carry */
+ offset++;
}
adjustArithmeticResult (ic);
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");
// TODO: check for accumulator clash between left & right aops?
- emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
- MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+
+ if( AOP_TYPE(right)==AOP_LIT ){
+ // moving to accumulator first helps peepholes
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
+ } else {
+ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+ }
+
emitcode ("mul", "ab");
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
if (size==2) {
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);
}
{
if (ifx)
jmpTrueOrFalse (ifx, tlbl);
+ else
+ emitcode ("", "%05d$:", tlbl->key + 100);
goto release;
}
}
}
else if (ifx)
jmpTrueOrFalse (ifx, tlbl);
+ else
+ emitcode ("", "%05d$:", tlbl->key + 100);
}
else
{
}
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);
}
}
else if (ifx)
jmpTrueOrFalse (ifx, tlbl);
+ else
+ emitcode ("", "%05d$:", tlbl->key + 100);
}
else
for (; (size--); offset++)
}
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);
}
freeAsmop (result, NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* genSwap - generates code to swap nibbles or bytes */
+/*-----------------------------------------------------------------*/
+static void
+genSwap (iCode * ic)
+{
+ operand *left, *result;
+
+ D(emitcode ("; genSwap",""));
+
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ switch (AOP_SIZE (left))
+ {
+ case 1: /* swap nibbles in byte */
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+ emitcode ("swap", "a");
+ aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
+ break;
+ case 2: /* swap bytes in word */
+ if (AOP_TYPE(left) == AOP_REG && sameRegs(AOP(left), AOP(result)))
+ {
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+ aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE),
+ 0, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), "a", 1, isOperandVolatile (result, FALSE));
+ }
+ else if (operandsEqu (left, result))
+ {
+ char * reg = "a";
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+ if (aopGetUsesAcc(AOP (left), 1) || aopGetUsesAcc(AOP (result), 0))
+ {
+ emitcode ("mov", "b,a");
+ reg = "b";
+ }
+ aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE),
+ 0, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), reg, 1, isOperandVolatile (result, FALSE));
+ }
+ else
+ {
+ aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE),
+ 0, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), aopGet (AOP (left), 0, FALSE, FALSE),
+ 1, isOperandVolatile (result, FALSE));
+ }
+ break;
+ default:
+ wassertl(FALSE, "unsupported SWAP operand size");
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
+}
+
+
/*-----------------------------------------------------------------*/
/* AccRol - rotate left accumulator by known count */
/*-----------------------------------------------------------------*/
genlshFour (result, left, shCount);
break;
default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"*** ack! mystery literal shift!\n");
break;
}
genRightShift (iCode * ic)
{
operand *right, *left, *result;
- sym_link *retype;
+ sym_link *letype;
int size, offset;
char *l;
symbol *tlbl, *tlbl1;
/* if signed then we do it the hard way preserve the
sign bit moving it inwards */
- retype = getSpec (operandType (IC_RESULT (ic)));
+ letype = getSpec (operandType (IC_LEFT (ic)));
- if (!SPEC_USIGN (retype))
+ if (!SPEC_USIGN (letype))
{
genSignedRightShift (ic);
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);
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);
static void
genDummyRead (iCode * ic)
{
- operand *right;
+ operand *op;
int size, offset;
D(emitcode("; genDummyRead",""));
- right = IC_RIGHT (ic);
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE);
- aopOp (right, ic, FALSE);
+ /* if the result is a bit */
+ if (AOP_TYPE (op) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+ else
+ {
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
+ while (size--)
+ {
+ MOVA (aopGet (AOP (op), offset, FALSE, FALSE));
+ offset++;
+ }
+ }
- /* if the result is a bit */
- if (AOP_TYPE (right) == AOP_CRY)
- {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- goto release;
+ freeAsmop (op, NULL, ic, TRUE);
}
- /* bit variables done */
- /* general case */
- size = AOP_SIZE (right);
- offset = 0;
- while (size--)
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
{
- emitcode ("mov", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
- offset++;
+ aopOp (op, ic, FALSE);
+
+ /* if the result is a bit */
+ if (AOP_TYPE (op) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+ else
+ {
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
+ while (size--)
+ {
+ MOVA (aopGet (AOP (op), offset, FALSE, FALSE));
+ offset++;
+ }
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
}
+}
-release:
- 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;
+
+ case SWAP:
+ genSwap (ic);
+ break;
+
default:
ic = ic;
}
}
+ _G.current_iCode = NULL;
/* now we are ready to call the
peep hole optimizer */