+2003-10-03 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ * src/z80/gen.h,
+ * src/z80/gen.c (aopOp, aopGet, aopPut, genDummyRead),
+ * src/mcs51/gen.h
+ * src/mcs51/gen.c (aopOp, aopGet, aopPut, genDummyRead),
+ * src/ds390/gen.h
+ * src/ds390/gen.c (aopOp, aopGet, aopPut, genDummyRead),
+ * src/SDCCicode.c (ast2iCode, geniCodeDummyRead): Fixed bug #663539
+ * src/SDCCopt.c (killDeadCode): Fixed bugs #663539 & #816705
+
2003-10-02 Erik Petrich <epetrich@ivorytower.norman.ok.us>
* src/z80/gen.c (genRet): fixed bug #524753
* src/z80/gen.c (genZ80code, _vemit2, _emit2): added support
for tracking iCodes in the peephole optimizer for z80
-
2003-10-01 Erik Petrich <epetrich@ivorytower.norman.ok.us>
* src/SDCCicode.c (geniCodeJumpTable, geniCodeSwitch): fixed
return left;
}
+/*-----------------------------------------------------------------*/
+/* geniCodeDummyRead - generate code for dummy read */
+/*-----------------------------------------------------------------*/
+static void
+geniCodeDummyRead (operand * op)
+{
+ iCode *ic;
+ sym_link *type = operandType (op);
+
+ if (!IS_VOLATILE(type))
+ return;
+
+ ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
+ ADDTOCHAIN (ic);
+
+ ic->nosupdate = 1;
+}
+
/*-----------------------------------------------------------------*/
/* geniCodeSEParms - generate code for side effecting fcalls */
/*-----------------------------------------------------------------*/
(tree->opval.op == NULLOP ||
tree->opval.op == BLOCK))
{
- ast2iCode (tree->left,lvl+1);
- ast2iCode (tree->right,lvl+1);
+ if (tree->left && tree->left->type == EX_VALUE)
+ geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
+ else
+ ast2iCode (tree->left,lvl+1);
+ if (tree->right && tree->right->type == EX_VALUE)
+ geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
+ else
+ ast2iCode (tree->right,lvl+1);
return NULL;
}
if (SKIP_IC (ic) ||
ic->op == IFX ||
- ic->op == RETURN)
+ ic->op == RETURN ||
+ ic->op == DUMMY_READ_VOLATILE)
continue;
/* if the result is volatile then continue */
/* if the result is a temp & isaddr then skip */
if (IC_RESULT (ic) && POINTER_SET (ic))
continue;
+
+ if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
+ continue;
/* if the result is used in the remainder of the */
/* block then skip */
continue;
kill = 1;
- }
+ }
kill:
/* kill this one if required */
aop->aopu.dptr = sym->dptr;
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, useDP2);
+
+ 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, useDP2);
+ 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;
}
/* depending on type */
switch (aop->type)
{
+ case AOP_DUMMY:
+ return zero;
case AOP_R0:
case AOP_R1:
/* 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)
{
offset = 0;
while (size--)
{
- emitcode ("mov", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
offset++;
}
AOP_REG, AOP_DIR,
AOP_DPTR, AOP_DPTR2, AOP_R0, AOP_R1,
AOP_STK, AOP_IMMD, AOP_STR,
- AOP_CRY, AOP_ACC, AOP_DPTRn
+ AOP_CRY, AOP_ACC, AOP_DPTRn, AOP_DUMMY
};
/* type asmop : a homogenised type for
AOP_STR - array of strings
AOP_ACC - result is in the acc:b pair
AOP_DPTRn - is in dptr(n)
+ AOP_DUMMY - read as 0, discard writes
*/
short coff; /* current offset */
short size; /* total size */
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;
}
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);
/* 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)",
offset = 0;
while (size--)
{
- emitcode ("mov", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
offset++;
}
AOP_REG, AOP_DIR,
AOP_DPTR, AOP_R0, AOP_R1,
AOP_STK, AOP_IMMD, AOP_STR,
- AOP_CRY, AOP_ACC
+ AOP_CRY, AOP_ACC, AOP_DUMMY
};
/* type asmop : a homogenised type for
AOP_CRY - carry contains the value of this
AOP_STR - array of strings
AOP_ACC - result is in the acc:b pair
+ AOP_DUMMY - read as 0, discard writes
*/
short coff; /* current offset */
short size; /* total size */
"AOP_HLREG",
"AOP_SIMPLELIT",
"AOP_EXSTK",
- "AOP_PAIRPT"
+ "AOP_PAIRPT",
+ "AOP_DUMMY"
};
static bool
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, requires_a);
+ 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, requires_a);
+ 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;
}
/* depending on type */
switch (aop->type)
{
+ case AOP_DUMMY:
+ tsprintf (buffer, sizeof(buffer), "!zero");
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+
case AOP_IMMD:
/* PENDING: re-target */
if (bit16)
/* depending on where it is ofcourse */
switch (aop->type)
{
+ case AOP_DUMMY:
+ _moveA (s); /* in case s is volatile */
+ break;
+
case AOP_DIR:
/* Direct. Hmmm. */
wassert (IS_GB);
static void
genDummyRead (iCode * ic)
{
- emit2 ("; genDummyRead not implemented");
+ operand *right;
+ int size, offset;
- ic = ic;
+ right = IC_RIGHT (ic);
+ aopOp (right, ic, FALSE, FALSE);
+
+ /* general case */
+ size = AOP_SIZE (right);
+ offset = 0;
+
+ while (size--)
+ {
+ _moveA (aopGet (AOP (right), offset, FALSE));
+ offset++;
+ }
+
+release:
+ freeAsmop (right, NULL, ic);
}
enum
break;
case DUMMY_READ_VOLATILE:
+ emitDebug ("; genDummyRead");
genDummyRead (ic);
break;
/* Is in the extended stack pointer (IY on the Z80) */
AOP_EXSTK,
/* Is referenced by a pointer in a register pair. */
- AOP_PAIRPTR
+ AOP_PAIRPTR,
+ /* Read as 0, discard writes */
+ AOP_DUMMY
}
AOP_TYPE;