// PENDING
#define ACC_NAME _pairs[PAIR_AF].h
-#define RESULTONSTACK(x) \
- (IC_RESULT(x) && IC_RESULT(x)->aop && \
- IC_RESULT(x)->aop->type == AOP_STK )
-
enum
{
LSB,
lineNode *head;
lineNode *current;
int isInline;
+ allocTrace trace;
} lines;
+ struct
+ {
+ allocTrace aops;
+ } trace;
} _G;
static const char *aopGet (asmop * aop, int offset, bool bit16);
}
}
+static lineNode *
+_newLineNode (char *line)
+{
+ lineNode *pl;
+
+ pl = traceAlloc(&_G.lines.trace, Safe_alloc ( sizeof (lineNode)));
+ pl->line = traceAlloc(&_G.lines.trace, Safe_strdup (line));
+
+ return pl;
+}
+
static void
_vemit2 (const char *szFormat, va_list ap)
{
_tidyUp (buffer);
_G.lines.current = (_G.lines.current ?
- connectLine (_G.lines.current, newLineNode (buffer)) :
- (_G.lines.head = newLineNode (buffer)));
+ connectLine (_G.lines.current, _newLineNode (buffer)) :
+ (_G.lines.head = _newLineNode (buffer)));
_G.lines.current->isInline = _G.lines.isInline;
}
if (lbp && *lbp)
{
_G.lines.current = (_G.lines.current ?
- connectLine (_G.lines.current, newLineNode (lb)) :
- (_G.lines.head = newLineNode (lb)));
+ connectLine (_G.lines.current, _newLineNode (lb)) :
+ (_G.lines.head = _newLineNode (lb)));
}
_G.lines.current->isInline = _G.lines.isInline;
va_end (ap);
{
asmop *aop;
- aop = Safe_calloc (1, sizeof (asmop));
+ aop = traceAlloc(&_G.trace.aops, Safe_alloc (sizeof (asmop)));
aop->type = type;
return aop;
}
/* Assign depending on the storage class */
if (sym->onStack || sym->iaccess)
{
- emitDebug ("; AOP_STK for %s", sym->rname);
- sym->aop = aop = newAsmop (AOP_STK);
+ /* The pointer that is used depends on how big the offset is.
+ Normally everything is AOP_STK, but for offsets of < -127 or
+ > 128 on the Z80 an extended stack pointer is used.
+ */
+ if (IS_Z80 && (sym->stack < -127 || sym->stack > (int)(128-getSize (sym->type))))
+ {
+ emitDebug ("; AOP_EXSTK for %s", sym->rname);
+ sym->aop = aop = newAsmop (AOP_EXSTK);
+ }
+ else
+ {
+ emitDebug ("; AOP_STK for %s", sym->rname);
+ sym->aop = aop = newAsmop (AOP_STK);
+ }
+
aop->size = getSize (sym->type);
aop->aopu.aop_stk = sym->stack;
return aop;
if (IS_FUNC (sym->type))
{
sym->aop = aop = newAsmop (AOP_IMMD);
- aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
- strcpy (aop->aopu.aop_immd, sym->rname);
+ aop->aopu.aop_immd = traceAlloc(&_G.trace.aops, Safe_strdup (sym->rname));
aop->size = 2;
return aop;
}
break;
}
- aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
- strcpy (aop->aopu.aop_immd, buffer);
+ aop->aopu.aop_immd = traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
return aop;
}
{
tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset);
}
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
case AOP_LIT:
{
else
tsprintf (buffer, "!constword", v);
- return gc_strdup(buffer);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
}
else
{
case AOP_IY:
case AOP_HL:
case AOP_STK:
+ case AOP_EXSTK:
return TRUE;
default:
return FALSE;
}
}
_G.pairs[pairId].last_type = left->type;
- _G.pairs[pairId].base = gc_strdup (base);
+ _G.pairs[pairId].base = traceAlloc(&_G.trace.aops, Safe_strdup (base));
_G.pairs[pairId].offset = offset;
}
/* Both a lit on the right and a true symbol on the left */
switch (aop->type)
{
case AOP_IY:
+ wassertl (pairId == PAIR_IY, "AOP_IY must be in IY");
fetchLitPair (pairId, aop, 0);
break;
+
case AOP_HL:
fetchLitPair (pairId, aop, offset);
_G.pairs[pairId].offset = offset;
break;
+
+ case AOP_EXSTK:
+ wassertl (IS_Z80, "Only the Z80 has an extended stack");
+ wassertl (pairId == PAIR_IY, "The Z80 extended stack must be in IY");
+
+ {
+ int offset = aop->aopu.aop_stk + _G.stack.offset;
+
+ if (_G.pairs[pairId].last_type == aop->type &&
+ _G.pairs[pairId].offset == offset)
+ {
+ /* Already setup */
+ }
+ else
+ {
+ /* PENDING: Do this better. */
+ sprintf (buffer, "%d", offset + _G.stack.pushed);
+ emit2 ("ld iy,!hashedstr", buffer);
+ emit2 ("add iy,sp");
+ _G.pairs[pairId].last_type = aop->type;
+ _G.pairs[pairId].offset = offset;
+ }
+ }
+ break;
+
case AOP_STK:
{
/* Doesnt include _G.stack.pushed */
aop->type != AOP_LIT)
{
tsprintf (s, "!zero");
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
}
/* depending on type */
wassertl (0, "Fetching from beyond the limits of an immediate value.");
}
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
case AOP_DIR:
wassert (IS_GB);
emit2 ("ld a,(%s+%d)", aop->aopu.aop_dir, offset);
sprintf (s, "a");
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
case AOP_SFR:
wassert (IS_GB);
emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
sprintf (s, "a");
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
case AOP_REG:
return aop->aopu.aop_reg[offset]->name;
setupPair (PAIR_HL, aop, offset);
tsprintf (s, "!*hl");
- return gc_strdup (s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup (s));
case AOP_IY:
wassert (IS_Z80);
setupPair (PAIR_IY, aop, offset);
tsprintf (s, "!*iyx", offset);
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+
+ case AOP_EXSTK:
+ wassert (IS_Z80);
+ setupPair (PAIR_IY, aop, offset);
+ tsprintf (s, "!*iyx", offset, offset);
+
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
case AOP_STK:
if (IS_GB)
tsprintf (s, "!*ixx", aop->aopu.aop_stk + offset);
}
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
case AOP_CRY:
wassertl (0, "Tried to fetch from a bit variable");
else
{
tsprintf(s, "!zero");
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
}
case AOP_HLREG:
v >>= (offset * 8);
tsprintf (s, "!immedbyte", (unsigned int) v & 0xff);
- return gc_strdup(s);
+ return traceAlloc(&_G.trace.aops, Safe_strdup(s));
}
case AOP_STR:
aop->coff = offset;
case AOP_IY:
wassert (!IS_GB);
- setupPair (PAIR_IY, aop, offset);
if (!canAssignToPtr (s))
{
emit2 ("ld a,%s", s);
+ setupPair (PAIR_IY, aop, offset);
emit2 ("ld !*iyx,a", offset);
}
else
- emit2 ("ld !*iyx,%s", offset, s);
+ {
+ setupPair (PAIR_IY, aop, offset);
+ emit2 ("ld !*iyx,%s", offset, s);
+ }
break;
case AOP_HL:
emit2 ("ld !*hl,%s", s);
break;
+ case AOP_EXSTK:
+ wassert (!IS_GB);
+ if (!canAssignToPtr (s))
+ {
+ emit2 ("ld a,%s", s);
+ setupPair (PAIR_IY, aop, offset);
+ emit2 ("ld !*iyx,a", offset);
+ }
+ else
+ {
+ setupPair (PAIR_IY, aop, offset);
+ emit2 ("ld !*iyx,%s", offset, s);
+ }
+ break;
+
case AOP_STK:
if (IS_GB)
{
else
{
/* Subtract through, propagating the carry */
- emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", aopGet (AOP (right), offset++, FALSE));
+ emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", aopGet (AOP (right), offset, FALSE));
+ offset++;
}
}
}
iCode *ic;
int cln = 0;
- /* HACK */
+ /* Hack */
if (IS_GB)
{
_fReturn = _gbz80_return;
}
codeOutFile = fp;
}
+
+ freeTrace(&_G.lines.trace);
+ freeTrace(&_G.trace.aops);
}
/*
v &= 0xFFFF;
tsprintf (buffer, "!immedword", v);
- return gc_strdup (buffer);
+ return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
}