#include <string.h>
#include <ctype.h>
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
#endif
#include "z80.h"
int pushedBC;
int pushedDE;
} stack;
+
+ struct
+ {
+ int pushedBC;
+ int pushedDE;
+ } calleeSaves;
+
int frameId;
int receiveOffset;
bool flushStatics;
{
char buffer[256];
- tvsprintf (buffer, szFormat, ap);
+ tvsprintf (buffer, sizeof(buffer), szFormat, ap);
_tidyUp (buffer);
_G.lines.current = (_G.lines.current ?
if (!DISABLE_DEBUG)
{
va_list ap;
-
+
va_start (ap, szFormat);
-
+
_vemit2 (szFormat, ap);
-
+
va_end (ap);
}
}
static void
_emitMove(const char *to, const char *from)
{
- if (strcasecmp(to, from) != 0)
+ if (STRCASECMP(to, from) != 0)
{
emit2("ld %s,%s", to, from);
}
break;
default:
/* No information. */
+ break;
}
}
_pop (aop->aopu.aop_pairId);
}
+ if (getPairId (aop) == PAIR_HL)
+ {
+ spillPair (PAIR_HL);
+ }
+
dealloc:
/* all other cases just dealloc */
if (op)
char *
aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
{
- char *s = buffer;
-
/* depending on type */
switch (aop->type)
{
/* PENDING: for re-target */
if (with_hash)
{
- tsprintf (s, "!hashedstr + %d", aop->aopu.aop_immd, offset);
+ tsprintf (buffer, sizeof(buffer),
+ "!hashedstr + %d", aop->aopu.aop_immd, offset);
}
else if (offset == 0)
{
- tsprintf (s, "%s", aop->aopu.aop_immd);
+ tsprintf (buffer, sizeof(buffer),
+ "%s", aop->aopu.aop_immd);
}
else
{
- tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset);
+ tsprintf (buffer, sizeof(buffer),
+ "%s + %d", aop->aopu.aop_immd, offset);
}
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_LIT:
{
}
if (with_hash)
- tsprintf (buffer, "!immedword", v);
+ tsprintf (buffer, sizeof(buffer), "!immedword", v);
else
- tsprintf (buffer, "!constword", v);
+ tsprintf (buffer, sizeof(buffer), "!constword", v);
return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
}
/* it is type float */
fl.f = (float) floatFromVal (val);
-#ifdef _BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
i = fl.c[3-offset] | (fl.c[3-offset-1]<<8);
#else
i = fl.c[offset] | (fl.c[offset+1]<<8);
#endif
if (with_hash)
- tsprintf (buffer, "!immedword", i);
+ tsprintf (buffer, sizeof(buffer), "!immedword", i);
else
- tsprintf (buffer, "!constword", i);
+ tsprintf (buffer, sizeof(buffer), "!constword", i);
return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
}
static const char *
aopGet (asmop * aop, int offset, bool bit16)
{
- char *s = buffer;
+ // char *s = buffer;
/* offset is greater than size then zero */
/* PENDING: this seems a bit screwed in some pointer cases. */
if (offset > (aop->size - 1) &&
aop->type != AOP_LIT)
{
- tsprintf (s, "!zero");
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ tsprintf (buffer, sizeof(buffer), "!zero");
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
}
/* depending on type */
case AOP_IMMD:
/* PENDING: re-target */
if (bit16)
- tsprintf (s, "!immedwords", aop->aopu.aop_immd);
+ tsprintf (buffer, sizeof(buffer), "!immedwords", aop->aopu.aop_immd);
else
switch (offset)
{
case 2:
- tsprintf (s, "!bankimmeds", aop->aopu.aop_immd);
+ tsprintf (buffer, sizeof(buffer), "!bankimmeds", aop->aopu.aop_immd);
break;
case 1:
- tsprintf (s, "!msbimmeds", aop->aopu.aop_immd);
+ tsprintf (buffer, sizeof(buffer), "!msbimmeds", aop->aopu.aop_immd);
break;
case 0:
- tsprintf (s, "!lsbimmeds", aop->aopu.aop_immd);
+ tsprintf (buffer, sizeof(buffer), "!lsbimmeds", aop->aopu.aop_immd);
break;
default:
wassertl (0, "Fetching from beyond the limits of an immediate value.");
}
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_DIR:
wassert (IS_GB);
emit2 ("ld a,(%s+%d)", aop->aopu.aop_dir, offset);
- sprintf (s, "a");
+ SNPRINTF (buffer, sizeof(buffer), "a");
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_SFR:
wassert (IS_GB);
emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
- sprintf (s, "a");
+ SNPRINTF (buffer, sizeof(buffer), "a");
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_REG:
return aop->aopu.aop_reg[offset]->name;
case AOP_HL:
wassert (IS_GB);
setupPair (PAIR_HL, aop, offset);
- tsprintf (s, "!*hl");
+ tsprintf (buffer, sizeof(buffer), "!*hl");
- return traceAlloc(&_G.trace.aops, Safe_strdup (s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
case AOP_IY:
wassert (IS_Z80);
setupPair (PAIR_IY, aop, offset);
- tsprintf (s, "!*iyx", offset);
+ tsprintf (buffer, sizeof(buffer), "!*iyx", offset);
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_EXSTK:
wassert (IS_Z80);
setupPair (PAIR_IY, aop, offset);
- tsprintf (s, "!*iyx", offset, offset);
+ tsprintf (buffer, sizeof(buffer), "!*iyx", offset, offset);
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_STK:
if (IS_GB)
{
setupPair (PAIR_HL, aop, offset);
- tsprintf (s, "!*hl");
+ tsprintf (buffer, sizeof(buffer), "!*hl");
}
else
{
if (aop->aopu.aop_stk >= 0)
offset += _G.stack.param_offset;
- tsprintf (s, "!*ixx", aop->aopu.aop_stk + offset);
+ tsprintf (buffer, sizeof(buffer),
+ "!*ixx", aop->aopu.aop_stk + offset);
}
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_CRY:
wassertl (0, "Tried to fetch from a bit variable");
}
else
{
- tsprintf(s, "!zero");
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ tsprintf(buffer, sizeof(buffer), "!zero");
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
}
case AOP_HLREG:
unsigned long v = aop->aopu.aop_simplelit;
v >>= (offset * 8);
- tsprintf (s, "!immedbyte", (unsigned int) v & 0xff);
+ tsprintf (buffer, sizeof(buffer),
+ "!immedbyte", (unsigned int) v & 0xff);
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
}
case AOP_STR:
aop->coff = offset;
case AOP_PAIRPTR:
setupPair (aop->aopu.aop_pairId, aop, offset);
- sprintf (s, "(%s)", _pairs[aop->aopu.aop_pairId].name);
+ SNPRINTF (buffer, sizeof(buffer),
+ "(%s)", _pairs[aop->aopu.aop_pairId].name);
- return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
default:
break;
}
// PENDING
- tsprintf(buffer2, s);
+ tsprintf(buffer2, sizeof(buffer2), s);
s = buffer2;
/* will assign value to value */
emit2 ("ld a,%s", aopGet (AOP (left), LSB, FALSE));
emit2 ("ld h,%s", aopGet (AOP (left), MSB16, FALSE));
emit2 ("ld l,a");
+ spillPair (PAIR_HL);
}
else if ( getPairId ( AOP (result)) == PAIR_IY)
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
sym_link *ftype;
-#if CALLEE_SAVES
bool bcInUse = FALSE;
bool deInUse = FALSE;
-#endif
setArea (IFFUNC_NONBANKED (sym->type));
_G.stack.param_offset = 0;
-#if CALLEE_SAVES
+ if (z80_opts.calleeSavesBC)
+ {
+ bcInUse = TRUE;
+ }
+
/* Detect which registers are used. */
- if (sym->regsUsed)
+ if (IFFUNC_CALLEESAVES(sym->type) && sym->regsUsed)
{
int i;
for (i = 0; i < sym->regsUsed->size; i++)
_G.stack.param_offset += 2;
}
- _G.stack.pushedBC = bcInUse;
+ _G.calleeSaves.pushedBC = bcInUse;
if (deInUse)
{
_G.stack.param_offset += 2;
}
- _G.stack.pushedDE = deInUse;
-#endif
+ _G.calleeSaves.pushedDE = deInUse;
/* adjust the stack for the function */
_G.stack.last = sym->stack;
emit2 ("!leave");
}
-#if CALLEE_SAVES
- if (_G.stack.pushedDE)
+ if (_G.calleeSaves.pushedDE)
{
emit2 ("pop de");
- _G.stack.pushedDE = FALSE;
+ _G.calleeSaves.pushedDE = FALSE;
}
- if (_G.stack.pushedDE)
+ if (_G.calleeSaves.pushedBC)
{
emit2 ("pop bc");
- _G.stack.pushedDE = FALSE;
+ _G.calleeSaves.pushedBC = FALSE;
}
-#endif
if (options.profile)
{
movLeft2Result (left, offl + 1, result, offr + 1, 0);
}
- if (shCount == 1 && getPairId (AOP (result)) == PAIR_HL)
+ if (getPairId (AOP (result)) == PAIR_HL)
{
- emit2 ("add hl,hl");
+ while (shCount--)
+ {
+ emit2 ("add hl,hl");
+ }
}
else
{
tlbl = newiTempLabel (NULL);
tlbl1 = newiTempLabel (NULL);
- /* Left is already in result - so now do the shift */
- if (shCount > 1)
+ if (AOP (result)->type == AOP_REG)
{
- emit2 ("ld a,!immedbyte+1", shCount);
- emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ while (shCount--)
+ {
+ for (offset = 0; offset < size; offset++)
+ {
+ l = aopGet (AOP (result), offset, FALSE);
+
+ if (offset == 0)
+ {
+ emit2 ("sla %s", l);
+ }
+ else
+ {
+ emit2 ("rl %s", l);
+ }
+ }
+ }
}
-
- while (size--)
+ else
{
- l = aopGet (AOP (result), offset, FALSE);
-
- if (offset == 0)
- {
- emit2 ("sla %s", l);
- }
- else
- {
- emit2 ("rl %s", l);
- }
+ /* Left is already in result - so now do the shift */
+ if (shCount > 1)
+ {
+ emit2 ("ld a,!immedbyte+1", shCount);
+ emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+ emitLabel (tlbl->key + 100);
+ }
- offset++;
- }
- if (shCount > 1)
- {
- emitLabel (tlbl1->key + 100);
- emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ while (size--)
+ {
+ l = aopGet (AOP (result), offset, FALSE);
+
+ if (offset == 0)
+ {
+ emit2 ("sla %s", l);
+ }
+ else
+ {
+ emit2 ("rl %s", l);
+ }
+
+ offset++;
+ }
+ if (shCount > 1)
+ {
+ emitLabel (tlbl1->key + 100);
+ emit2 ("dec a");
+ emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ }
}
}
}
wassert (0);
}
- else if (shCount >= (size * 8))
+ else if (shCount >= (size * 8)) {
+ const char *s;
+ if (!SPEC_USIGN(getSpec(operandType(left)))) {
+ _moveA(aopGet (AOP (left), 0, FALSE));
+ emit2 ("rlc a");
+ emit2 ("sbc a,a");
+ s=ACC_NAME;
+ } else {
+ s="!zero";
+ }
while (size--)
- aopPut (AOP (result), "!zero", size);
+ aopPut (AOP (result), s, size);
+ }
else
{
switch (size)
return;
}
+ emit2 ("ld a,%s", aopGet (AOP (right), 0, FALSE));
+ emit2 ("inc a");
+ freeAsmop (right, NULL, ic);
+
aopOp (left, ic, FALSE, FALSE);
aopOp (result, ic, FALSE, FALSE);
/* now move the left to the result if they are not the
same */
- if (!sameRegs (AOP (left), AOP (result)) &&
- AOP_SIZE (result) > 1)
+ if (!sameRegs (AOP (left), AOP (result)))
{
size = AOP_SIZE (result);
}
}
- emit2 ("ld a,%s", aopGet (AOP (right), 0, FALSE));
- emit2 ("inc a");
- freeAsmop (right, NULL, ic);
-
tlbl = newiTempLabel (NULL);
tlbl1 = newiTempLabel (NULL);
size = AOP_SIZE (result);
/* Just do it */
if (isPtrPair (AOP (left)))
{
- tsprintf (buffer, "!*pair", getPairName (AOP (left)));
+ tsprintf (buffer, sizeof(buffer),
+ "!*pair", getPairName (AOP (left)));
aopPut (AOP (result), buffer, 0);
}
else
while (size--)
{
char at[20];
- tsprintf (at, "!*iyx", offset);
+ tsprintf (at, sizeof(at), "!*iyx", offset);
aopPut (AOP (result), at, offset);
offset++;
}
emit2 ("inc hl");
emit2 ("ld h,!*hl");
emit2 ("ld l,a");
+ spillPair (PAIR_HL);
}
else if (getPairId (AOP (left)) == PAIR_HL && !isLastUse (ic, left))
{
freeAsmop (IC_RESULT (ic), NULL, ic);
}
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+ emit2 ("; genDummyRead not implemented");
+
+ ic = ic;
+}
+
enum
{
/** Maximum number of bytes to emit per line. */
if (cln != ic->lineno)
{
- emit2 ("; %s %d", ic->filename, ic->lineno);
+ if (!options.noCcodeInAsm) {
+ emit2 (";%s:%d: %s", ic->filename, ic->lineno,
+ printCLine(ic->filename, ic->lineno));
+ }
cln = ic->lineno;
}
+ if (options.iCodeInAsm) {
+ emit2 (";ic:%d: %s", ic->key, printILine(ic));
+ }
/* if the result is marked as
spilt and rematerializable or code for
this has already been generated then
emitDebug ("; genArrayInit");
genArrayInit(ic);
break;
-
+
+ case DUMMY_READ_VOLATILE:
+ genDummyRead (ic);
+ break;
+
default:
ic = ic;
}
v = 0-v;
v &= 0xFFFF;
- tsprintf (buffer, "!immedword", v);
+ tsprintf (buffer, sizeof(buffer), "!immedword", v);
return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
}