}
}
+/*-----------------------------------------------------------------*/
+/* z80_emitDebuggerSymbol - associate the current code location */
+/* with a debugger symbol */
+/*-----------------------------------------------------------------*/
+void
+z80_emitDebuggerSymbol (char * debugSym)
+{
+ _G.lines.isDebug = 1;
+ emit2 ("%s !equ .", debugSym);
+ emit2 ("!global", debugSym);
+ _G.lines.isDebug = 0;
+}
+
/*-----------------------------------------------------------------*/
/* emit2 - writes the code into a file : for now it is simple */
/*-----------------------------------------------------------------*/
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
va_start (ap, fmt);
if (sym1 == sym2)
return 1;
- if (strcmp (sym1->rname, sym2->rname) == 0)
+ if (sym1->rname[0] && sym2->rname[0]
+ && strcmp (sym1->rname, sym2->rname) == 0)
return 2;
-
/* if left is a tmp & right is not */
if (IS_ITEMP (op1) &&
!IS_ITEMP (op2) &&
case AOP_SFR:
if( IS_GB )
- {
- // wassert (IS_GB);
- if (strcmp (s, "a"))
- emit2 ("ld a,%s", s);
- emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
- }
+ {
+ // wassert (IS_GB);
+ if (strcmp (s, "a"))
+ emit2 ("ld a,%s", s);
+ emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+ }
else
- { /*.p.t.20030716 handling for i/o port read access for Z80 */
- if( aop->paged )
- { /* banked mode */
- if( aop->bcInUse ) emit2( "push bc" );
-
- emit2( "ld bc,#%s", aop->aopu.aop_dir );
-
- if(( s[0] == '#' ) /* immediate number */
- ||( s[0] == '(' ) /* indirect register (ix or iy ??)*/
- ||( isdigit( s[0] )))/* indirect register with offset (ix or iy ??)*/
- {
- emit2( "ld a,%s", s );
- emit2( "out (c),a" );
- }
- else
- {
- emit2( "out (c),%s", s );
- }
+ { /*.p.t.20030716 handling for i/o port read access for Z80 */
+ if (aop->paged)
+ { /* banked mode */
+ if (aop->bcInUse)
+ emit2( "push bc" );
+
+ if (strlen(s) != 1
+ || (s[0] != 'a' && s[0] != 'd' && s[0] != 'e'
+ && s[0] != 'h' && s[0] != 'l'))
+ {
+ emit2( "ld a,%s", s );
+ s = "a";
+ }
+
+ emit2( "ld bc,#%s", aop->aopu.aop_dir );
+ emit2( "out (c),%s", s );
- if( aop->bcInUse )
- emit2( "pop bc" );
+ if( aop->bcInUse )
+ emit2( "pop bc" );
+ else
+ spillPair (PAIR_BC);
+ }
+ else if( z80_opts.port_mode == 180 )
+ { /* z180 in0/out0 mode */
+ emit2( "ld a,%s", s );
+ emit2( "out0 (%s),a", aop->aopu.aop_dir );
+ }
else
- spillPair (PAIR_BC);
- }
- else if( z80_opts.port_mode == 180 )
- { /* z180 in0/out0 mode */
- emit2( "ld a,%s", s );
- emit2( "out0 (%s),a", aop->aopu.aop_dir );
- }
- else
- { /* 8 bit mode */
- emit2( "ld a,%s", s );
- emit2( "out (%s),a", aop->aopu.aop_dir );
+ { /* 8 bit mode */
+ emit2( "ld a,%s", s );
+ emit2( "out (%s),a", aop->aopu.aop_dir );
+ }
}
- }
break;
case AOP_REG:
emitDebug("; genUminusFloat");
/* for this we just need to flip the
- first it then copy the rest in place */
+ first bit then copy the rest in place */
size = AOP_SIZE (op) - 1;
_moveA(aopGet (AOP (op), MSB32, FALSE));
}
spillCached ();
- /* Mark the regsiters as restored. */
+ /* Mark the registers as restored. */
_G.saves.saved = FALSE;
/* if we need assign a result value */
/* Create the function header */
emit2 ("!functionheader", sym->name);
- sprintf (buffer, "%s_start", sym->rname);
- emit2 ("!labeldef", buffer);
+ if (!IS_STATIC(sym->etype))
+ {
+ sprintf (buffer, "%s_start", sym->rname);
+ emit2 ("!labeldef", buffer);
+ }
emit2 ("!functionlabeldef", sym->rname);
if (options.profile)
ftype = operandType (IC_LEFT (ic));
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL (ftype))
- emit2 ("!di");
-
/* if this is an interrupt service routine then save all potentially used registers. */
if (IFFUNC_ISISR (sym->type))
{
- emit2 ("!pusha");
+ if (!FUNC_ISNAKED( sym->type ))
+ {
+ emit2 ("!pusha");
+ }
+ }
+ else
+ {
+ /* if critical function then turn interrupts off */
+ if (IFFUNC_ISCRITICAL (sym->type))
+ {
+ emit2 ("!di");
+ }
}
/* PENDING: callee-save etc */
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- if (IFFUNC_ISISR (sym->type))
+
+ /* PENDING: calleeSave */
+ if (IS_Z80 && _G.omitFramePtr)
{
- wassertl (0, "Tried to close an interrupt support function");
+ if (_G.stack.offset)
+ emit2 ("!ldaspsp", _G.stack.offset);
}
- else
+ else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX)
{
- if (IFFUNC_ISCRITICAL (sym->type))
- emit2 ("!ei");
-
- /* PENDING: calleeSave */
-
- if (IS_Z80 && _G.omitFramePtr)
- {
- if (_G.stack.offset)
- emit2 ("!ldaspsp", _G.stack.offset);
- }
- else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX)
- {
- emit2 ("!leavexl", _G.stack.offset);
- }
- else if (_G.stack.offset)
- {
- emit2 ("!leavex", _G.stack.offset);
- }
- else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
- {
- emit2 ("!leave");
- }
+ emit2 ("!leavexl", _G.stack.offset);
+ }
+ else if (_G.stack.offset)
+ {
+ emit2 ("!leavex", _G.stack.offset);
+ }
+ else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
+ {
+ emit2 ("!leave");
+ }
+
+ if (_G.calleeSaves.pushedDE)
+ {
+ emit2 ("pop de");
+ _G.calleeSaves.pushedDE = FALSE;
+ }
- if (_G.calleeSaves.pushedDE)
- {
- emit2 ("pop de");
- _G.calleeSaves.pushedDE = FALSE;
- }
+ if (_G.calleeSaves.pushedBC)
+ {
+ emit2 ("pop bc");
+ _G.calleeSaves.pushedBC = FALSE;
+ }
- if (_G.calleeSaves.pushedBC)
- {
- emit2 ("pop bc");
- _G.calleeSaves.pushedBC = FALSE;
- }
+ if (options.profile)
+ {
+ emit2 ("!profileexit");
+ }
- if (options.profile)
+ /* if this is an interrupt service routine then restore all potentially used registers. */
+ if (IFFUNC_ISISR (sym->type))
+ {
+ if (!FUNC_ISNAKED( sym->type ))
{
- emit2 ("!profileexit");
+ emit2 ("!popa");
}
+ }
+ else
+ {
+ /* if critical function then turn interrupts back on */
+ if (IFFUNC_ISCRITICAL (sym->type))
+ emit2 ("!ei");
+ }
-
- 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;
- }
+ if (options.debug && currFunc)
+ {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
+ if (IFFUNC_ISISR (sym->type))
+ {
+ /* "critical interrupt" is used to imply NMI handler */
+ if (IS_Z80 && IFFUNC_ISCRITICAL (sym->type))
+ emit2 ("retn");
+ else
+ emit2 ("reti");
+ }
+ else
+ {
/* Both banked and non-banked just ret */
emit2 ("ret");
-
+ }
+
+ if (!IS_STATIC(sym->etype))
+ {
sprintf (buffer, "%s_end", sym->rname);
emit2 ("!labeldef", buffer);
}
+
_G.flushStatics = 1;
_G.stack.pushed = 0;
_G.stack.offset = 0;
int count, i;
/* If true then the final operation should be a subtract */
bool active = FALSE;
+ bool byteResult;
/* Shouldn't occur - all done through function calls */
aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
aopOp (IC_RIGHT (ic), ic, FALSE, FALSE);
aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+
+ byteResult = (AOP_SIZE (IC_RESULT (ic)) == 1);
if (AOP_SIZE (IC_LEFT (ic)) > 2 ||
AOP_SIZE (IC_RIGHT (ic)) > 2 ||
if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
{
emit2 ("ld e,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE));
- emit2 ("ld a,e");
- emit2 ("rlc a");
- emit2 ("sbc a,a");
- emit2 ("ld d,a");
+ if (!byteResult)
+ {
+ emit2 ("ld a,e");
+ emit2 ("rlc a");
+ emit2 ("sbc a,a");
+ emit2 ("ld d,a");
+ }
}
else
{
if (active == FALSE)
{
emit2 ("ld l,e");
- emit2 ("ld h,d");
+ if (!byteResult)
+ emit2 ("ld h,d");
}
else
{
_G.stack.pushedDE = FALSE;
}
- commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
+ if (byteResult)
+ aopPut (AOP (IC_RESULT (ic)), _pairs[PAIR_HL].l, 0);
+ else
+ commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
freeAsmop (IC_LEFT (ic), NULL, ic);
freeAsmop (IC_RIGHT (ic), NULL, ic);
aopOp (left, ic, FALSE, FALSE);
aopOp (result, ic, FALSE, FALSE);
+ if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+ _push (PAIR_AF);
+
/* now move the left to the result if they are not the
same */
offset = 0;
tlbl1 = newiTempLabel (NULL);
+ if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+ _pop (PAIR_AF);
+
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
emitLabel (tlbl->key + 100);
l = aopGet (AOP (result), offset, FALSE);
aopOp (left, ic, FALSE, FALSE);
aopOp (result, ic, FALSE, FALSE);
+ if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+ _push (PAIR_AF);
+
/* now move the left to the result if they are not the
same */
if (!sameRegs (AOP (left), AOP (result)))
tlbl1 = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = size - 1;
+
+ if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+ _pop (PAIR_AF);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
emitLabel (tlbl->key + 100);
{
fetchPair (pairId, AOP (result));
}
- /* so hl know contains the address */
+ /* so hl now contains the address */
freeAsmop (result, NULL, ic);
/* if bit then unpack */
chunks.
*/
static void
-_rleAppend(RLECTX *self, int c)
+_rleAppend(RLECTX *self, unsigned c)
{
int i;
if (type && type->next)
{
- elementSize = getSize(type->next);
+ if (IS_SPEC(type->next) || IS_PTR(type->next))
+ {
+ elementSize = getSize(type->next);
+ }
+ else if (IS_ARRAY(type->next) && type->next->next)
+ {
+ elementSize = getSize(type->next->next);
+ }
+ else
+ {
+ printTypeChainRaw (type, NULL);
+ wassertl (0, "Can't determine element size in genArrayInit.");
+ }
}
else
{
wassertl (0, "Can't determine element size in genArrayInit.");
}
+ wassertl ((elementSize > 0) && (elementSize <= 4), "Illegal element size in genArrayInit.");
+
iLoop = IC_ARRAYILIST(ic);
lastVal = (unsigned)-1;
{
ix = iLoop->count;
- if (ix != 0)
+ for (i = 0; i < ix; i++)
{
- for (i = 0; i < ix; i++)
+ for (eIndex = 0; eIndex < elementSize; eIndex++)
{
- for (eIndex = 0; eIndex < elementSize; eIndex++)
- {
- val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
- _rleAppend(&rle, val);
- }
+ val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+ _rleAppend(&rle, val);
}
- }
+ }
iLoop = iLoop->next;
}
/* 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;
+ debugFile->writeFunction (currFunc, lic);
}
for (ic = lic; ic; ic = ic->next)
{
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;
+ debugFile->writeCLine (ic);
}
if (!options.noCcodeInAsm) {
emit2 (";%s:%d: %s", ic->filename, ic->lineno,