bool flushStatics;
bool in_home;
const char *lastFunctionName;
-
+ iCode *current_iCode;
+ bool preserveCarry;
+
set *sendSet;
struct
lineNode *head;
lineNode *current;
int isInline;
+ int isDebug;
allocTrace trace;
} lines;
"AOP_HLREG",
"AOP_SIMPLELIT",
"AOP_EXSTK",
- "AOP_PAIRPT"
+ "AOP_PAIRPT",
+ "AOP_DUMMY"
};
static bool
(_G.lines.head = _newLineNode (buffer)));
_G.lines.current->isInline = _G.lines.isInline;
+ _G.lines.current->isDebug = _G.lines.isDebug;
+ _G.lines.current->ic = _G.current_iCode;
}
static void
(_G.lines.head = _newLineNode (lb)));
}
_G.lines.current->isInline = _G.lines.isInline;
+ _G.lines.current->ic = _G.current_iCode;
va_end (ap);
}
void
aopDump(const char *plabel, asmop *aop)
{
+ int i;
+ char regbuf[9];
+ char *rbp = regbuf;
+
emitDebug("; Dump of %s: type %s size %u", plabel, aopNames[aop->type], aop->size);
switch (aop->type)
{
+ case AOP_EXSTK:
case AOP_STK:
emitDebug("; aop_stk %d", aop->aopu.aop_stk);
break;
+ case AOP_REG:
+ for (i=aop->size-1;i>=0;i--)
+ *rbp++ = *(aop->aopu.aop_reg[i]->name);
+ *rbp = '\0';
+ emitDebug("; reg = %s", regbuf);
+ break;
+ case AOP_PAIRPTR:
+ emitDebug("; pairptr = (%s)", _pairs[aop->aopu.aop_pairId].name);
+
default:
/* No information. */
break;
spillPair (pairId);
}
+void
+genMovePairPair (PAIR_ID srcPair, PAIR_ID dstPair)
+{
+ switch (dstPair)
+ {
+ case PAIR_IX:
+ case PAIR_IY:
+ case PAIR_AF:
+ _push(srcPair);
+ _pop(dstPair);
+ break;
+ case PAIR_BC:
+ case PAIR_DE:
+ case PAIR_HL:
+ if (srcPair == PAIR_IX || srcPair == PAIR_IY)
+ {
+ _push(srcPair);
+ _pop(dstPair);
+ }
+ else
+ {
+ emit2("ld %s,%s",_pairs[dstPair].l,_pairs[srcPair].l);
+ emit2("ld %s,%s",_pairs[dstPair].h,_pairs[srcPair].h);
+ }
+ default:
+ wassertl (0, "Tried to move a nonphysical pair");
+ }
+ _G.pairs[dstPair].last_type = _G.pairs[srcPair].last_type;
+ _G.pairs[dstPair].base = _G.pairs[srcPair].base;
+ _G.pairs[dstPair].offset = _G.pairs[srcPair].offset;
+}
+
+
/*-----------------------------------------------------------------*/
/* newAsmop - creates a new asmOp */
/*-----------------------------------------------------------------*/
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;
}
{
wassertl (id == PAIR_HL, "Setup relative to SP only implemented for HL");
+ if (_G.preserveCarry)
+ {
+ _push (PAIR_AF);
+ offset += 2;
+ }
+
if (offset < INT8MIN || offset > INT8MAX)
{
emit2 ("ld hl,!immedword", offset);
}
else
{
- emit2 ("!ldahlsp", offset);
+ emit2 ("!ldahlsp", offset);
+ }
+
+ if (_G.preserveCarry)
+ {
+ _pop (PAIR_AF);
+ offset -= 2;
}
}
else
{
/* PENDING: Do this better. */
+ if (_G.preserveCarry)
+ _push (PAIR_AF);
sprintf (buffer, "%d", offset + _G.stack.pushed);
emit2 ("ld %s,!hashedstr", _pairs[pairId].name, buffer);
emit2 ("add %s,sp", _pairs[pairId].name);
_G.pairs[pairId].last_type = aop->type;
_G.pairs[pairId].offset = offset;
+ if (_G.preserveCarry)
+ _pop (PAIR_AF);
}
}
break;
}
case AOP_PAIRPTR:
+ if (pairId != aop->aopu.aop_pairId)
+ genMovePairPair(aop->aopu.aop_pairId, pairId);
adjustPair (_pairs[pairId].name, &_G.pairs[pairId].offset, offset);
break;
/* 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)
case AOP_PAIRPTR:
setupPair (aop->aopu.aop_pairId, aop, offset);
- SNPRINTF (buffer, sizeof(buffer),
- "(%s)", _pairs[aop->aopu.aop_pairId].name);
+ if (aop->aopu.aop_pairId==PAIR_IX)
+ SNPRINTF (buffer, sizeof(buffer),
+ "!*ixx", 0);
+ else if (aop->aopu.aop_pairId==PAIR_IY)
+ SNPRINTF (buffer, sizeof(buffer),
+ "!*iyx", 0);
+ else
+ SNPRINTF (buffer, sizeof(buffer),
+ "(%s)", _pairs[aop->aopu.aop_pairId].name);
return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
/* 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);
case AOP_PAIRPTR:
setupPair (aop->aopu.aop_pairId, aop, offset);
- emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s);
+ if (aop->aopu.aop_pairId==PAIR_IX)
+ emit2 ("ld !*ixx,%s", 0, s);
+ else if (aop->aopu.aop_pairId==PAIR_IY)
+ emit2 ("ld !*ixy,%s", 0, s);
+ else
+ emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s);
break;
default:
bool bcInRet = FALSE, deInRet = FALSE;
bitVect *rInUse;
- rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), ic->rUsed);
+ rInUse = bitVectCplAnd (bitVectCopy (ic->rMask),
+ z80_rUmaskForOp (IC_RESULT(ic)));
deInUse = bitVectBitValue (rInUse, D_IDX) || bitVectBitValue(rInUse, E_IDX);
bcInUse = bitVectBitValue (rInUse, B_IDX) || bitVectBitValue(rInUse, C_IDX);
static void
emitCall (iCode * ic, bool ispcall)
{
+ bool bInRet, cInRet, dInRet, eInRet;
sym_link *dtype = operandType (IC_LEFT (ic));
/* if caller saves & we have not saved then */
}
spillCached ();
+ if (IC_RESULT (ic))
+ {
+ bitVect *result = z80_rUmaskForOp (IC_RESULT (ic));
+ bInRet = bitVectBitValue(result, B_IDX);
+ cInRet = bitVectBitValue(result, C_IDX);
+ dInRet = bitVectBitValue(result, D_IDX);
+ eInRet = bitVectBitValue(result, E_IDX);
+ }
+ else
+ {
+ bInRet = FALSE;
+ cInRet = FALSE;
+ dInRet = FALSE;
+ eInRet = FALSE;
+ }
if (_G.stack.pushedDE)
{
- bool dInRet = bitVectBitValue(ic->rUsed, D_IDX);
- bool eInRet = bitVectBitValue(ic->rUsed, E_IDX);
-
if (dInRet && eInRet)
{
wassertl (0, "Shouldn't push DE if it's wiped out by the return");
if (_G.stack.pushedBC)
{
- bool bInRet = bitVectBitValue(ic->rUsed, B_IDX);
- bool cInRet = bitVectBitValue(ic->rUsed, C_IDX);
-
if (bInRet && cInRet)
{
wassertl (0, "Shouldn't push BC if it's wiped out by the return");
}
- /* Both baned and non-banked just ret */
+ if (options.debug && currFunc)
+ {
+ _G.lines.isDebug = 1;
+ sprintf (buffer, "C$%s$%d$%d$%d",
+ FileBaseName (ic->filename), currFunc->lastLine,
+ ic->level, ic->block);
+ emit2 ("!labeldef", buffer);
+ if (IS_STATIC (currFunc->etype))
+ sprintf (buffer, "XF%s$%s$0$0", moduleName, currFunc->name);
+ else
+ sprintf (buffer, "XG$%s$0$0", currFunc->name);
+ emit2 ("!labeldef", buffer);
+ _G.lines.isDebug = 0;
+ }
+
+ /* Both banked and non-banked just ret */
emit2 ("ret");
sprintf (buffer, "%s_end", sym->rname);
aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
size = AOP_SIZE (IC_LEFT (ic));
+ aopDump("IC_LEFT", AOP(IC_LEFT(ic)));
+
+ #if 0
if ((size == 2) && ((l = aopGetWord (AOP (IC_LEFT (ic)), 0))))
{
if (IS_GB)
emit2 ("ld hl,%s", l);
}
}
+ #endif
+ if (size==2)
+ {
+ fetchPair(IS_GB ? PAIR_DE : PAIR_HL, AOP (IC_LEFT (ic)));
+ }
else
{
if (IS_GB && size == 4 && requiresHL (AOP (IC_LEFT (ic))))
l = aopGet (AOP (IC_LEFT (ic)), offset,
FALSE);
if (strcmp (_fReturn[offset], l))
- emit2 ("ld %s,%s", _fReturn[offset++], l);
+ emit2 ("ld %s,%s", _fReturn[offset], l);
+ offset++;
}
}
}
if (couldDestroyCarry (right) && couldDestroyCarry (result))
{
shiftIntoPair (0, right);
- shiftIntoPair (1, result);
+ /* check result again, in case right == result */
+ if (couldDestroyCarry (result))
+ shiftIntoPair (1, result);
}
else if (couldDestroyCarry (right))
{
- shiftIntoPair (0, right);
+ if (getPairId (result) == PAIR_HL)
+ _G.preserveCarry = TRUE;
+ else
+ shiftIntoPair (0, right);
}
else if (couldDestroyCarry (result))
{
goto release;
}
}
-
+
setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
while (size--)
}
release:
+ _G.preserveCarry = FALSE;
freeAsmop (IC_LEFT (ic), NULL, ic);
freeAsmop (IC_RIGHT (ic), NULL, ic);
freeAsmop (IC_RESULT (ic), NULL, ic);
}
release:
+ _G.preserveCarry = FALSE;
freeAsmop (IC_LEFT (ic), NULL, ic);
freeAsmop (IC_RIGHT (ic), NULL, ic);
freeAsmop (IC_RESULT (ic), NULL, ic);
/* now depending on the sign of the destination */
size = AOP_SIZE (result) - AOP_SIZE (right);
/* Unsigned or not an integral type - right fill with zeros */
- if (SPEC_USIGN (rtype) || !IS_SPEC (rtype) || AOP_TYPE(right)==AOP_CRY)
+ if (!IS_SPEC (rtype) || SPEC_USIGN (rtype) || AOP_TYPE(right)==AOP_CRY)
{
while (size--)
aopPut (AOP (result), "!zero", offset++);
static void
genDummyRead (iCode * ic)
{
- emit2 ("; genDummyRead not implemented");
+ operand *right;
+ int size, offset;
+
+ 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++;
+ }
- ic = ic;
+ freeAsmop (right, NULL, ic);
}
enum
}
_G.lines.head = _G.lines.current = NULL;
+
+ /* if debug information required */
+ if (options.debug && currFunc)
+ {
+ debugFile->writeFunction(currFunc);
+ _G.lines.isDebug = 1;
+ if (IS_STATIC (currFunc->etype))
+ sprintf (buffer, "F%s$%s$0$0", moduleName, currFunc->name);
+ else
+ sprintf (buffer, "G$%s$0$0", currFunc->name);
+ emit2 ("!labeldef", buffer);
+ _G.lines.isDebug = 0;
+ }
for (ic = lic; ic; ic = ic->next)
{
+ _G.current_iCode = ic;
- if (cln != ic->lineno)
+ if (ic->lineno && cln != ic->lineno)
{
+ if (options.debug)
+ {
+ _G.lines.isDebug = 1;
+ sprintf (buffer, "C$%s$%d$%d$%d",
+ FileBaseName (ic->filename), ic->lineno,
+ ic->level, ic->block);
+ emit2 ("%s !equ .", buffer);
+ emit2 ("!global", buffer);
+ _G.lines.isDebug = 0;
+ }
if (!options.noCcodeInAsm) {
emit2 (";%s:%d: %s", ic->filename, ic->lineno,
printCLine(ic->filename, ic->lineno));
break;
case DUMMY_READ_VOLATILE:
+ emitDebug ("; genDummyRead");
genDummyRead (ic);
break;