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;
(_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;
}
return aop;
}
- if (IS_GB)
+ if( IN_REGSP( space ))
+ { /*.p.t.20030716 minor restructure to add SFR support to the Z80 */
+ if (IS_GB)
{
/* if it is in direct space */
- if (IN_REGSP (space) && !requires_a)
- {
- sym->aop = aop = newAsmop (AOP_SFR);
- aop->aopu.aop_dir = sym->rname;
- aop->size = getSize (sym->type);
+ if( !requires_a )
+ {
+ sym->aop = aop = newAsmop (AOP_SFR);
+ aop->aopu.aop_dir = sym->rname;
+ aop->size = getSize (sym->type);
emitDebug ("; AOP_SFR for %s", sym->rname);
- return aop;
- }
+ return aop;
+ }
}
+ else
+ { /*.p.t.20030716 adding SFR support to the Z80 port */
+ aop = newAsmop (AOP_SFR);
+ sym->aop = aop;
+ aop->aopu.aop_dir = sym->rname;
+ aop->size = getSize( sym->type );
+ aop->paged = FUNC_REGBANK(sym->type);
+ aop->bcInUse = isPairInUse( PAIR_BC, ic );
+ aop->deInUse = isPairInUse( PAIR_DE, ic );
+ emitDebug( ";Z80 AOP_SFR for %s banked:%d bc:%d de:%d", sym->rname, FUNC_REGBANK(sym->type), aop->bcInUse, aop->deInUse );
+
+ return( aop );
+ }
+ }
/* only remaining is far space */
/* in which case DPTR gets the address */
/* if already has a asmop then continue */
if (op->aop)
{
+ if (op->aop->type == AOP_SFR)
+ {
+ op->aop->bcInUse = isPairInUse( PAIR_BC, ic );
+ op->aop->deInUse = isPairInUse( PAIR_DE, ic );
+ }
return;
}
if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
{
op->aop = OP_SYMBOL (op)->aop;
+ if (op->aop->type == AOP_SFR)
+ {
+ op->aop->bcInUse = isPairInUse( PAIR_BC, ic );
+ op->aop->deInUse = isPairInUse( PAIR_DE, ic );
+ }
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;
return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
case AOP_SFR:
- wassert (IS_GB);
- emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
- SNPRINTF (buffer, sizeof(buffer), "a");
+ if( IS_GB )
+ {
+ // wassert (IS_GB);
+ emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
+ SNPRINTF (buffer, sizeof(buffer), "a");
- return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+ }
+ else
+ { /*.p.t.20030716 handling for i/o port read access for Z80 */
+ if( aop->paged )
+ { /* banked mode */
+ /* reg A goes to address bits 15-8 during "in a,(x)" instruction */
+ emit2( "ld a,!msbimmeds", aop->aopu.aop_dir);
+ emit2( "in a,(!lsbimmeds)", aop->aopu.aop_dir);
+ }
+ else if( z80_opts.port_mode == 180 )
+ { /* z180 in0/out0 mode */
+ emit2( "in0 a,(%s)", aop->aopu.aop_dir );
+ }
+ else
+ { /* 8 bit mode */
+ emit2( "in a,(%s)", aop->aopu.aop_dir );
+ }
+
+ SNPRINTF (buffer, sizeof(buffer), "a");
+
+ return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+ }
case AOP_REG:
return aop->aopu.aop_reg[offset]->name;
break;
case AOP_SFR:
- wassert (IS_GB);
- if (strcmp (s, "a"))
- emit2 ("ld a,%s", s);
- emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+ 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);
+ }
+ 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 );
+ }
+
+ 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
+ { /* 8 bit mode */
+ emit2( "ld a,%s", s );
+ emit2( "out (%s),a", aop->aopu.aop_dir );
+ }
+ }
break;
case AOP_REG:
#define AOP(op) op->aop
#define AOP_TYPE(op) AOP(op)->type
#define AOP_SIZE(op) AOP(op)->size
-#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY))
+#define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
static void
commitPair (asmop * aop, PAIR_ID id)
emit2 ("!enterxl", sym->stack);
else if (sym->stack)
emit2 ("!enterx", sym->stack);
- else
+ else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
emit2 ("!enter");
+
_G.stack.offset = sym->stack;
}
{
emit2 ("!leavex", _G.stack.offset);
}
- else
+ else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
{
emit2 ("!leave");
}
}
- /* 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);
}
else if (couldDestroyCarry (right))
{
- shiftIntoPair (0, right);
+ if (getPairId (result) == PAIR_HL)
+ _G.preserveCarry = TRUE;
+ else
+ shiftIntoPair (0, right);
}
else if (couldDestroyCarry (result))
{
in ACC */
if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
- (AOP_NEEDSACC (IC_LEFT (ic))) ||
+ (AOP_NEEDSACC (IC_RIGHT (ic))) ||
AOP_TYPE (IC_RIGHT (ic)) == AOP_ACC)
{
operand *t = IC_RIGHT (ic);
}
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);
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);
/* if left is a literal & right is not then exchange them */
if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
- AOP_NEEDSACC (left))
+ (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
{
operand *tmp = right;
right = left;
/* if left is a literal & right is not then exchange them */
if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
- AOP_NEEDSACC (left))
+ (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
{
operand *tmp = right;
right = left;
/* if left is a literal & right is not then exchange them */
if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
- AOP_NEEDSACC (left))
+ (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
{
operand *tmp = right;
right = left;
continue;
else
{
- _moveA (aopGet (AOP (right), offset, FALSE));
+ _moveA (aopGet (AOP (left), offset, FALSE));
emit2 ("xor a,%s",
- aopGet (AOP (left), offset, FALSE));
+ aopGet (AOP (right), offset, FALSE));
aopPut (AOP (result), "a", offset);
}
}
}
else
{
- _moveA (aopGet (AOP (right), offset, FALSE));
+ _moveA (aopGet (AOP (left), offset, FALSE));
emit2 ("xor a,%s",
- aopGet (AOP (left), offset, FALSE));
+ aopGet (AOP (right), offset, FALSE));
aopPut (AOP (result), "a", offset);
}
}
}
else
{
- _moveA (aopGet (AOP (right), offset, FALSE));
+ _moveA (aopGet (AOP (left), offset, FALSE));
emit2 ("xor a,%s",
- aopGet (AOP (left), offset, FALSE));
+ aopGet (AOP (right), offset, FALSE));
}
aopPut (AOP (result), "a", offset);
}
static void
genDummyRead (iCode * ic)
{
- operand *right;
+ operand *op;
int size, offset;
- right = IC_RIGHT (ic);
- aopOp (right, ic, FALSE, FALSE);
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE, FALSE);
- /* general case */
- size = AOP_SIZE (right);
- offset = 0;
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
- while (size--)
- {
- _moveA (aopGet (AOP (right), offset, FALSE));
- offset++;
+ while (size--)
+ {
+ _moveA (aopGet (AOP (op), offset, FALSE));
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic);
}
+
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE, FALSE);
+
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
-release:
- freeAsmop (right, NULL, ic);
+ while (size--)
+ {
+ _moveA (aopGet (AOP (op), offset, FALSE));
+ offset++;
+ }
+
+ freeAsmop (op, 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));