X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=72d5726683ebcc6742b85efb135b77742e0331a3;hb=47bb725c96ea3f78ac860012cf1feb35cf66bfb2;hp=03c1f662c97ba467b9a96fffa28fb503fa5b7578;hpb=f66772d1af3c01d4b56b2b73b3f11fa85e92da25;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index 03c1f662..72d57266 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -220,7 +220,9 @@ static struct bool flushStatics; bool in_home; const char *lastFunctionName; - + iCode *current_iCode; + bool preserveCarry; + set *sendSet; struct @@ -234,6 +236,7 @@ static struct lineNode *head; lineNode *current; int isInline; + int isDebug; allocTrace trace; } lines; @@ -261,7 +264,8 @@ static const char *aopNames[] = { "AOP_HLREG", "AOP_SIMPLELIT", "AOP_EXSTK", - "AOP_PAIRPT" + "AOP_PAIRPT", + "AOP_DUMMY" }; static bool @@ -407,6 +411,8 @@ _vemit2 (const char *szFormat, va_list ap) (_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 @@ -436,6 +442,19 @@ emitDebug (const char *szFormat,...) } } +/*-----------------------------------------------------------------*/ +/* 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 */ /*-----------------------------------------------------------------*/ @@ -444,7 +463,7 @@ _emit2 (const char *inst, const char *fmt,...) { va_list ap; char lb[INITIAL_INLINEASM]; - char *lbp = lb; + unsigned char *lbp = lb; va_start (ap, fmt); @@ -466,6 +485,7 @@ _emit2 (const char *inst, const char *fmt,...) (_G.lines.head = _newLineNode (lb))); } _G.lines.current->isInline = _G.lines.isInline; + _G.lines.current->ic = _G.current_iCode; va_end (ap); } @@ -783,18 +803,34 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a) 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 */ @@ -911,10 +947,10 @@ operandsEqu (operand * op1, operand * op2) 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) && @@ -987,6 +1023,11 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a) /* 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; } @@ -994,6 +1035,11 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a) 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; } @@ -1079,13 +1125,21 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a) 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; } @@ -1467,6 +1521,12 @@ setupPairFromSP (PAIR_ID id, int offset) { 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); @@ -1474,7 +1534,13 @@ setupPairFromSP (PAIR_ID id, int offset) } else { - emit2 ("!ldahlsp", offset); + emit2 ("!ldahlsp", offset); + } + + if (_G.preserveCarry) + { + _pop (PAIR_AF); + offset -= 2; } } @@ -1510,11 +1576,15 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset) 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; @@ -1581,6 +1651,10 @@ aopGet (asmop * aop, int offset, bool bit16) /* 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) @@ -1611,11 +1685,35 @@ aopGet (asmop * aop, int offset, bool bit16) 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; @@ -1767,6 +1865,10 @@ aopPut (asmop * aop, const char *s, int offset) /* 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); @@ -1776,10 +1878,47 @@ aopPut (asmop * aop, const char *s, int offset) 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" ); + + 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" ); + 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: @@ -1935,7 +2074,7 @@ aopPut (asmop * aop, const char *s, int offset) #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) @@ -2256,7 +2395,7 @@ genUminusFloat (operand * op, operand * result) 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)); @@ -2422,7 +2561,8 @@ _saveRegsForCall(iCode *ic, int sendSetSize) 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); @@ -2657,6 +2797,7 @@ _opUsesPair (operand * op, iCode * ic, PAIR_ID pairId) 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 */ @@ -2773,7 +2914,7 @@ emitCall (iCode * ic, bool ispcall) } spillCached (); - /* Mark the regsiters as restored. */ + /* Mark the registers as restored. */ _G.saves.saved = FALSE; /* if we need assign a result value */ @@ -2825,12 +2966,24 @@ emitCall (iCode * ic, bool ispcall) } 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"); @@ -2857,9 +3010,6 @@ emitCall (iCode * ic, bool ispcall) 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"); @@ -2950,8 +3100,11 @@ genFunction (iCode * ic) /* 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) @@ -2961,14 +3114,21 @@ genFunction (iCode * ic) 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 */ @@ -3052,8 +3212,9 @@ genFunction (iCode * ic) 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; } @@ -3065,59 +3226,83 @@ genEndFunction (iCode * ic) { 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 - { - 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"); + } - - /* Both baned and non-banked just ret */ + 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; @@ -3144,6 +3329,9 @@ genRet (iCode * ic) 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) @@ -3155,6 +3343,11 @@ genRet (iCode * ic) 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)))) @@ -3169,7 +3362,8 @@ genRet (iCode * 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++; } } } @@ -3424,7 +3618,10 @@ setupToPreserveCarry (asmop *result, asmop *left, asmop *right) } else if (couldDestroyCarry (right)) { - shiftIntoPair (0, right); + if (getPairId (result) == PAIR_HL) + _G.preserveCarry = TRUE; + else + shiftIntoPair (0, right); } else if (couldDestroyCarry (result)) { @@ -3458,7 +3655,7 @@ genPlus (iCode * ic) 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); @@ -3655,6 +3852,7 @@ genPlus (iCode * ic) } release: + _G.preserveCarry = FALSE; freeAsmop (IC_LEFT (ic), NULL, ic); freeAsmop (IC_RIGHT (ic), NULL, ic); freeAsmop (IC_RESULT (ic), NULL, ic); @@ -3858,6 +4056,7 @@ genMinus (iCode * ic) } release: + _G.preserveCarry = FALSE; freeAsmop (IC_LEFT (ic), NULL, ic); freeAsmop (IC_RIGHT (ic), NULL, ic); freeAsmop (IC_RESULT (ic), NULL, ic); @@ -3873,11 +4072,14 @@ genMult (iCode * 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 || @@ -3908,10 +4110,13 @@ genMult (iCode * ic) 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 { @@ -3933,7 +4138,8 @@ genMult (iCode * ic) if (active == FALSE) { emit2 ("ld l,e"); - emit2 ("ld h,d"); + if (!byteResult) + emit2 ("ld h,d"); } else { @@ -3952,7 +4158,10 @@ genMult (iCode * ic) _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); @@ -4822,7 +5031,7 @@ genAnd (iCode * ic, iCode * ifx) /* 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; @@ -5012,7 +5221,7 @@ genOr (iCode * ic, iCode * ifx) /* 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; @@ -5170,7 +5379,7 @@ genXor (iCode * ic, iCode * ifx) /* 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; @@ -5247,9 +5456,9 @@ genXor (iCode * ic, iCode * ifx) 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); } } @@ -5261,9 +5470,9 @@ genXor (iCode * ic, iCode * ifx) } 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); } } @@ -5299,9 +5508,9 @@ genXor (iCode * ic, iCode * ifx) } 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); } @@ -5832,6 +6041,9 @@ genLeftShift (iCode * 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 */ @@ -5853,6 +6065,9 @@ genLeftShift (iCode * ic) 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); @@ -6106,6 +6321,9 @@ genRightShift (iCode * 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 */ if (!sameRegs (AOP (left), AOP (result))) @@ -6125,6 +6343,9 @@ genRightShift (iCode * ic) 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); @@ -6633,7 +6854,7 @@ genGenPointerSet (operand * right, { fetchPair (pairId, AOP (result)); } - /* so hl know contains the address */ + /* so hl now contains the address */ freeAsmop (result, NULL, ic); /* if bit then unpack */ @@ -7019,7 +7240,7 @@ genCast (iCode * 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++); @@ -7076,9 +7297,44 @@ genReceive (iCode * ic) static void genDummyRead (iCode * ic) { - emit2 ("; genDummyRead not implemented"); + operand *op; + int size, offset; - ic = ic; + op = IC_RIGHT (ic); + if (op && IS_SYMOP (op)) + { + aopOp (op, ic, FALSE, FALSE); + + /* general case */ + size = AOP_SIZE (op); + offset = 0; + + 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; + + while (size--) + { + _moveA (aopGet (AOP (op), offset, FALSE)); + offset++; + } + + freeAsmop (op, NULL, ic); + } } enum @@ -7191,7 +7447,7 @@ _rleCommit(RLECTX *self) chunks. */ static void -_rleAppend(RLECTX *self, int c) +_rleAppend(RLECTX *self, unsigned c) { int i; @@ -7274,13 +7530,27 @@ genArrayInit (iCode * ic) 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; @@ -7293,17 +7563,14 @@ genArrayInit (iCode * ic) { 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; } @@ -7617,12 +7884,23 @@ genZ80Code (iCode * lic) } _G.lines.head = _G.lines.current = NULL; + + /* if debug information required */ + if (options.debug && currFunc) + { + debugFile->writeFunction (currFunc, lic); + } for (ic = lic; ic; ic = ic->next) { + _G.current_iCode = ic; - if (cln != ic->lineno) + if (ic->lineno && cln != ic->lineno) { + if (options.debug) + { + debugFile->writeCLine (ic); + } if (!options.noCcodeInAsm) { emit2 (";%s:%d: %s", ic->filename, ic->lineno, printCLine(ic->filename, ic->lineno)); @@ -7886,6 +8164,7 @@ genZ80Code (iCode * lic) break; case DUMMY_READ_VOLATILE: + emitDebug ("; genDummyRead"); genDummyRead (ic); break;