X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=e159073147471e29ba0ddeb42a3fbd849b89d443;hb=341294d1d8f1bcd8e7ee542194bfa29b9cc1986e;hp=f822996156bc4d626f0533bcbe15ec5f6dccb4cb;hpb=09f8f154e4e1b559fbd075da8dd3b7efcd69161a;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index f8229961..e1590731 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -220,7 +220,8 @@ static struct bool flushStatics; bool in_home; const char *lastFunctionName; - + iCode *current_iCode; + set *sendSet; struct @@ -234,6 +235,7 @@ static struct lineNode *head; lineNode *current; int isInline; + int isDebug; allocTrace trace; } lines; @@ -261,7 +263,8 @@ static const char *aopNames[] = { "AOP_HLREG", "AOP_SIMPLELIT", "AOP_EXSTK", - "AOP_PAIRPT" + "AOP_PAIRPT", + "AOP_DUMMY" }; static bool @@ -397,7 +400,7 @@ _newLineNode (char *line) static void _vemit2 (const char *szFormat, va_list ap) { - char buffer[256]; + char buffer[INITIAL_INLINEASM]; tvsprintf (buffer, sizeof(buffer), szFormat, ap); @@ -407,6 +410,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 @@ -466,6 +471,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); } @@ -486,12 +492,26 @@ _emitMove(const char *to, const char *from) void aopDump(const char *plabel, asmop *aop) { + int i; + char regbuf[9]; + char *rbp = regbuf; + emitDebug("; Dump of %s: type %s size %u", plabel, aopNames[aop->type], aop->size); switch (aop->type) { + case AOP_EXSTK: case AOP_STK: emitDebug("; aop_stk %d", aop->aopu.aop_stk); break; + case AOP_REG: + for (i=aop->size-1;i>=0;i--) + *rbp++ = *(aop->aopu.aop_reg[i]->name); + *rbp = '\0'; + emitDebug("; reg = %s", regbuf); + break; + case AOP_PAIRPTR: + emitDebug("; pairptr = (%s)", _pairs[aop->aopu.aop_pairId].name); + default: /* No information. */ break; @@ -670,6 +690,39 @@ _pop (PAIR_ID pairId) spillPair (pairId); } +void +genMovePairPair (PAIR_ID srcPair, PAIR_ID dstPair) +{ + switch (dstPair) + { + case PAIR_IX: + case PAIR_IY: + case PAIR_AF: + _push(srcPair); + _pop(dstPair); + break; + case PAIR_BC: + case PAIR_DE: + case PAIR_HL: + if (srcPair == PAIR_IX || srcPair == PAIR_IY) + { + _push(srcPair); + _pop(dstPair); + } + else + { + emit2("ld %s,%s",_pairs[dstPair].l,_pairs[srcPair].l); + emit2("ld %s,%s",_pairs[dstPair].h,_pairs[srcPair].h); + } + default: + wassertl (0, "Tried to move a nonphysical pair"); + } + _G.pairs[dstPair].last_type = _G.pairs[srcPair].last_type; + _G.pairs[dstPair].base = _G.pairs[srcPair].base; + _G.pairs[dstPair].offset = _G.pairs[srcPair].offset; +} + + /*-----------------------------------------------------------------*/ /* newAsmop - creates a new asmOp */ /*-----------------------------------------------------------------*/ @@ -1032,13 +1085,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; } @@ -1496,6 +1557,8 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset) } case AOP_PAIRPTR: + if (pairId != aop->aopu.aop_pairId) + genMovePairPair(aop->aopu.aop_pairId, pairId); adjustPair (_pairs[pairId].name, &_G.pairs[pairId].offset, offset); break; @@ -1532,6 +1595,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) @@ -1645,8 +1712,15 @@ aopGet (asmop * aop, int offset, bool bit16) case AOP_PAIRPTR: setupPair (aop->aopu.aop_pairId, aop, offset); - SNPRINTF (buffer, sizeof(buffer), - "(%s)", _pairs[aop->aopu.aop_pairId].name); + if (aop->aopu.aop_pairId==PAIR_IX) + SNPRINTF (buffer, sizeof(buffer), + "!*ixx", 0); + else if (aop->aopu.aop_pairId==PAIR_IY) + SNPRINTF (buffer, sizeof(buffer), + "!*iyx", 0); + else + SNPRINTF (buffer, sizeof(buffer), + "(%s)", _pairs[aop->aopu.aop_pairId].name); return traceAlloc(&_G.trace.aops, Safe_strdup(buffer)); @@ -1711,6 +1785,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); @@ -1861,7 +1939,12 @@ aopPut (asmop * aop, const char *s, int offset) case AOP_PAIRPTR: setupPair (aop->aopu.aop_pairId, aop, offset); - emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s); + if (aop->aopu.aop_pairId==PAIR_IX) + emit2 ("ld !*ixx,%s", 0, s); + else if (aop->aopu.aop_pairId==PAIR_IY) + emit2 ("ld !*ixy,%s", 0, s); + else + emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s); break; default: @@ -2361,7 +2444,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); @@ -2596,6 +2680,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 */ @@ -2764,12 +2849,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"); @@ -2796,9 +2893,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"); @@ -3051,7 +3145,22 @@ genEndFunction (iCode * ic) } - /* 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); @@ -3083,6 +3192,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) @@ -3094,6 +3206,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)))) @@ -3108,7 +3225,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++; } } } @@ -3357,7 +3475,9 @@ setupToPreserveCarry (asmop *result, asmop *left, asmop *right) if (couldDestroyCarry (right) && couldDestroyCarry (result)) { shiftIntoPair (0, right); - shiftIntoPair (1, result); + /* check result again, in case right == result */ + if (couldDestroyCarry (result)) + shiftIntoPair (1, result); } else if (couldDestroyCarry (right)) { @@ -3563,7 +3683,7 @@ genPlus (iCode * ic) goto release; } } - + setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic))); while (size--) @@ -6956,7 +7076,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++); @@ -7013,9 +7133,23 @@ genReceive (iCode * ic) static void genDummyRead (iCode * ic) { - emit2 ("; genDummyRead not implemented"); + operand *right; + int size, offset; - ic = ic; + right = IC_RIGHT (ic); + aopOp (right, ic, FALSE, FALSE); + + /* general case */ + size = AOP_SIZE (right); + offset = 0; + + while (size--) + { + _moveA (aopGet (AOP (right), offset, FALSE)); + offset++; + } + + freeAsmop (right, NULL, ic); } enum @@ -7554,12 +7688,36 @@ genZ80Code (iCode * lic) } _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)); @@ -7823,6 +7981,7 @@ genZ80Code (iCode * lic) break; case DUMMY_READ_VOLATILE: + emitDebug ("; genDummyRead"); genDummyRead (ic); break;