X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=72d5726683ebcc6742b85efb135b77742e0331a3;hb=195ee3f3ee25ce2c5f2a59fbd2779c4cb80527c3;hp=cd669c7c359f3741344515ea5947182b254badd1;hpb=f983558a0e07566cf65dca67cddd3f4bf81328e0;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index cd669c7c..72d57266 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -442,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 */ /*-----------------------------------------------------------------*/ @@ -450,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); @@ -934,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) && @@ -1866,48 +1879,46 @@ aopPut (asmop * aop, const char *s, int offset) 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: @@ -2384,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)); @@ -2903,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 */ @@ -3089,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) @@ -3100,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 */ @@ -3205,74 +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 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; @@ -4042,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 || @@ -4077,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 { @@ -4102,7 +4138,8 @@ genMult (iCode * ic) if (active == FALSE) { emit2 ("ld l,e"); - emit2 ("ld h,d"); + if (!byteResult) + emit2 ("ld h,d"); } else { @@ -4121,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); @@ -6001,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 */ @@ -6022,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); @@ -6275,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))) @@ -6294,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); @@ -6802,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 */ @@ -7395,7 +7447,7 @@ _rleCommit(RLECTX *self) chunks. */ static void -_rleAppend(RLECTX *self, int c) +_rleAppend(RLECTX *self, unsigned c) { int i; @@ -7478,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; @@ -7497,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; } @@ -7825,14 +7888,7 @@ genZ80Code (iCode * lic) /* 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) @@ -7843,13 +7899,7 @@ genZ80Code (iCode * lic) { 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,