X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=c73d1ae22a70175bff287e0ab4deeba2cbdbc190;hb=e5c0243133d2ce207020e4817b1ea86b3c1057d8;hp=0782a420cd41d6de258f8052d67edee9279175fa;hpb=d5fff77ffc8d8bf19e26c1f1689d08325e9521e4;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index 0782a420..c73d1ae2 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -16,6 +16,7 @@ Slightly better genCmp(signed) 20597 159 195B Better reg packing, first peephole 20038 163 1873 With assign packing 19281 165 1849 + 5/3/00 17741 185 17B6 Michael Hope 2000 Based on the mcs51 generator - Sandeep Dutta . sandeep.dutta@usa.net (1998) @@ -30,6 +31,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software @@ -59,14 +61,15 @@ stuff. This is what it is all about CODE GENERATION for a specific MCU. Some of the routines may be reusable, will have to see */ -static char *zero = "#0x00"; -static char *one = "#0x01"; static char *spname ; static char *_z80_return[] = {"l", "h", "e", "d" }; static char *_gbz80_return[] = { "e", "d", "l", "h" }; static char **_fReturn; static char **_fTmp; +/* PENDING: messy */ +static char zero[20]; + static char *accUse[] = {"a" }; short rbank = -1; short accInUse = 0 ; @@ -77,6 +80,30 @@ extern int ptrRegReq ; extern int nRegs; extern FILE *codeOutFile; set *sendSet = NULL; + +typedef enum { + PAIR_INVALID, + PAIR_BC, + PAIR_DE, + PAIR_HL, + PAIR_IY, + PAIR_IX, + NUM_PAIRS +} PAIR_ID; + +static struct { + const char *name; + const char *l; + const char *h; +} _pairs[NUM_PAIRS] = { + { "??", "?", "?" }, + { "bc", "c", "b" }, + { "de", "e", "d" }, + { "hl", "l", "h" }, + { "iy", "iy.l?", "iy.h?" }, + { "ix", "ix.l?", "ix.h?" } +}; + #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ IC_RESULT(x)->aop->type == AOP_STK ) @@ -84,19 +111,13 @@ set *sendSet = NULL; #define MOVA(x) if (strcmp(x,"a")) emitcode("ld","a,%s",x); #define CLRC emitcode("xor","a,a"); -#define LABEL_STR "%05d$" - lineNode *lineHead = NULL; lineNode *lineCurr = NULL; -unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0, -0xE0, 0xC0, 0x80, 0x00}; -unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, -0x07, 0x03, 0x01, 0x00}; - -static int _lastStack = 0; -static int _pushed = 0; -static int _spoffset; +static const unsigned char SLMask[] = +{0xFF ,0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00}; +static const unsigned char SRMask[] = +{0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00}; #define LSB 0 #define MSB16 1 @@ -104,13 +125,65 @@ static int _spoffset; #define MSB32 3 /* Stack frame: - IX+4 param0 LH IX+2 ret LH IX+0 ix LH IX-2 temp0 LH */ +static struct { + struct { + AOP_TYPE last_type; + const char *lit; + int offset; + } pairs[NUM_PAIRS]; + struct { + int last; + int pushed; + int offset; + } stack; + int frameId; +} _G; + +static char *aopGet(asmop *aop, int offset, bool bit16); + +static void _tidyUp(char *buf) +{ + /* Clean up the line so that it is 'prettier' */ + if (strchr(buf, ':')) { + /* Is a label - cant do anything */ + return; + } + /* Change the first (and probably only) ' ' to a tab so + everything lines up. + */ + while (*buf) { + if (*buf == ' ') { + *buf = '\t'; + return; + } + buf++; + } +} + +static void emit2(const char *szFormat, ...) +{ + char buffer[256]; + va_list ap; + + va_start(ap, szFormat); + + tvsprintf(buffer, szFormat, ap); + + _tidyUp(buffer); + lineCurr = (lineCurr ? + connectLine(lineCurr,newLineNode(buffer)) : + (lineHead = newLineNode(buffer))); + + lineCurr->isInline = inLine; + lineCurr->isDebug = debugLine; +} + /*-----------------------------------------------------------------*/ /* emitcode - writes the code into a file : for now it is simple */ /*-----------------------------------------------------------------*/ @@ -139,6 +212,26 @@ void emitcode (const char *inst, const char *fmt, ...) va_end(ap); } +/* Z80: + { "adjustsp", + "\tld hl,#-%d\n" + "\tadd hl,sp\n" + "\tld sp,hl" + } + { "prelude", + "push bc" + "push de" + "push ix" + "ld ix,#0" + "add ix,sp" + { "leave" + emitcode("ld", "sp,ix"); + emitcode("pop", "ix"); + emitcode("pop", "de"); + } +} +*/ + const char *getPairName(asmop *aop) { if (aop->type == AOP_REG) { @@ -167,46 +260,64 @@ const char *getPairName(asmop *aop) break; } } - assert(0); + wassert(0); return NULL; } -/** Returns TRUE if the registers used in aop form a pair (BC, DE, HL) */ -bool isPair(asmop *aop) +static PAIR_ID getPairId(asmop *aop) { if (aop->size == 2) { if (aop->type == AOP_REG) { if ((aop->aopu.aop_reg[0]->rIdx == C_IDX)&&(aop->aopu.aop_reg[1]->rIdx == B_IDX)) { - return TRUE; + return PAIR_BC; } if ((aop->aopu.aop_reg[0]->rIdx == E_IDX)&&(aop->aopu.aop_reg[1]->rIdx == D_IDX)) { - return TRUE; + return PAIR_DE; } if ((aop->aopu.aop_reg[0]->rIdx == L_IDX)&&(aop->aopu.aop_reg[1]->rIdx == H_IDX)) { - return TRUE; + return PAIR_HL; } } if (aop->type == AOP_STR) { if (!strcmp(aop->aopu.aop_str[0], "c")&&!strcmp(aop->aopu.aop_str[1], "b")) { - return TRUE; + return PAIR_BC; } if (!strcmp(aop->aopu.aop_str[0], "e")&&!strcmp(aop->aopu.aop_str[1], "d")) { - return TRUE; + return PAIR_DE; } if (!strcmp(aop->aopu.aop_str[0], "l")&&!strcmp(aop->aopu.aop_str[1], "h")) { - return TRUE; + return PAIR_HL; } } } - return FALSE; + return PAIR_INVALID; } +/** Returns TRUE if the registers used in aop form a pair (BC, DE, HL) */ +bool isPair(asmop *aop) +{ + return (getPairId(aop) != PAIR_INVALID); +} + +bool isPtrPair(asmop *aop) +{ + PAIR_ID pairId = getPairId(aop); + switch (pairId) { + case PAIR_HL: + case PAIR_IY: + case PAIR_IX: + return TRUE; + default: + return FALSE; + } +} /** Push a register pair onto the stack */ void genPairPush(asmop *aop) { emitcode("push", "%s", getPairName(aop)); } + /*-----------------------------------------------------------------*/ /* newAsmop - creates a new asmOp */ /*-----------------------------------------------------------------*/ @@ -222,7 +333,7 @@ static asmop *newAsmop (short type) /*-----------------------------------------------------------------*/ /* aopForSym - for a true symbol */ /*-----------------------------------------------------------------*/ -static asmop *aopForSym (iCode *ic,symbol *sym,bool result) +static asmop *aopForSym (iCode *ic,symbol *sym,bool result, bool requires_a) { asmop *aop; memmap *space= SPEC_OCLS(sym->etype); @@ -233,9 +344,9 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) /* Assign depending on the storage class */ if (sym->onStack || sym->iaccess) { + emitcode("", "; AOP_STK for %s", sym->rname); sym->aop = aop = newAsmop(AOP_STK); aop->size = getSize(sym->type); - aop->aopu.aop_stk = sym->stack; return aop; } @@ -251,20 +362,24 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) if (IS_GB) { /* if it is in direct space */ - if (IN_DIRSPACE(space)) { - sym->aop = aop = newAsmop (AOP_DIR); + if (IN_REGSP(space) && !requires_a) { + sym->aop = aop = newAsmop (AOP_SFR); aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); - emitcode("", "; AOP_DIR for %s", sym->rname); + emitcode("", "; AOP_SFR for %s", sym->rname); return aop; } } /* only remaining is far space */ /* in which case DPTR gets the address */ - sym->aop = aop = newAsmop(AOP_IY); - if (!IS_GB) - emitcode ("ld","iy,#%s ; a", sym->rname); + if (IS_GB) { + emitcode("", "; AOP_HL for %s", sym->rname); + sym->aop = aop = newAsmop(AOP_HL); + } + else { + sym->aop = aop = newAsmop(AOP_IY); + } aop->size = getSize(sym->type); aop->aopu.aop_dir = sym->rname; @@ -287,6 +402,7 @@ static asmop *aopForRemat (symbol *sym) while (1) { /* if plus or minus print the right hand side */ if (ic->op == '+' || ic->op == '-') { + /* PENDING: for re-target */ sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)), ic->op ); s += strlen(s); @@ -390,12 +506,16 @@ bool sameRegs (asmop *aop1, asmop *aop2 ) { int i; - if (aop1 == aop2) - return TRUE ; + if (aop1->type == AOP_SFR || + aop2->type == AOP_SFR) + return FALSE; + + if (aop1 == aop2) + return TRUE; if (aop1->type != AOP_REG || aop2->type != AOP_REG ) - return FALSE ; + return FALSE; if (aop1->size != aop2->size) return FALSE ; @@ -411,7 +531,7 @@ bool sameRegs (asmop *aop1, asmop *aop2 ) /*-----------------------------------------------------------------*/ /* aopOp - allocates an asmop for an operand : */ /*-----------------------------------------------------------------*/ -static void aopOp (operand *op, iCode *ic, bool result) +static void aopOp (operand *op, iCode *ic, bool result, bool requires_a) { asmop *aop; symbol *sym; @@ -440,7 +560,7 @@ static void aopOp (operand *op, iCode *ic, bool result) /* if this is a true symbol */ if (IS_TRUE_SYMOP(op)) { - op->aop = aopForSym(ic,OP_SYMBOL(op),result); + op->aop = aopForSym(ic,OP_SYMBOL(op),result, requires_a); return ; } @@ -493,7 +613,7 @@ static void aopOp (operand *op, iCode *ic, bool result) /* else spill location */ sym->aop = op->aop = aop = - aopForSym(ic,sym->usl.spillLoc,result); + aopForSym(ic,sym->usl.spillLoc,result, requires_a); aop->size = getSize(sym->type); return; } @@ -525,11 +645,6 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic) aop->freed = 1; - switch (aop->type) { - case AOP_STK : - break; - } - dealloc: /* all other cases just dealloc */ if (op ) { @@ -543,55 +658,234 @@ dealloc: } } -char *aopGetWordLong(asmop *aop, int offset, bool with_hash) +bool isLitWord(asmop *aop) +{ + /* if (aop->size != 2) + return FALSE;*/ + switch (aop->type) { + case AOP_IMMD: + case AOP_LIT: + return TRUE; + default: + return FALSE; + } +} + +char *aopGetLitWordLong(asmop *aop, int offset, bool with_hash) { char *s = buffer ; char *rs; - if (aop->size != 2) +#if 0 + if (aop->size != 2 && aop->type != AOP_HL) return NULL; - assert(offset == 0); +#endif + wassert(offset == 0); /* depending on type */ switch (aop->type) { + case AOP_HL: + case AOP_IY: case AOP_IMMD: - sprintf (s,"%s%s",with_hash ? "#" : "", aop->aopu.aop_immd); + /* PENDING: for re-target */ + if (with_hash) + tsprintf(s, "!hashedstr", aop->aopu.aop_immd); + else + strcpy(s, aop->aopu.aop_immd); ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); return rs; - case AOP_LIT: { value * val = aop->aopu.aop_lit; /* if it is a float then it gets tricky */ /* otherwise it is fairly simple */ if (!IS_FLOAT(val->type)) { unsigned long v = floatFromVal(val); - - sprintf(buffer,"%s0x%04lx", with_hash ? "#" : "", v); + if (with_hash) + tsprintf(buffer, "!immedword", v); + else + tsprintf(buffer, "!constword", v); ALLOC_ATOMIC(rs,strlen(buffer)+1); return strcpy (rs,buffer); } - assert(0); + wassert(0); return NULL; } + default: + return NULL; } - return NULL; } char *aopGetWord(asmop *aop, int offset) { - return aopGetWordLong(aop, offset, TRUE); + return aopGetLitWordLong(aop, offset, TRUE); +} + +bool isPtr(const char *s) +{ + if (!strcmp(s, "hl")) + return TRUE; + if (!strcmp(s, "ix")) + return TRUE; + if (!strcmp(s, "iy")) + return TRUE; + return FALSE; +} + +static void adjustPair(const char *pair, int *pold, int new) +{ + wassert(pair); + + while (*pold < new) { + emitcode("inc", "%s", pair); + (*pold)++; + } + while (*pold > new) { + emitcode("dec", "%s", pair); + (*pold)--; + } +} + +static void spillPair(PAIR_ID pairId) +{ + _G.pairs[pairId].last_type = AOP_INVALID; + _G.pairs[pairId].lit = NULL; +} + +static void spillCached(void) +{ + spillPair(PAIR_HL); + spillPair(PAIR_IY); +} + +static bool requiresHL(asmop *aop) +{ + switch (aop->type) { + case AOP_HL: + case AOP_STK: + return TRUE; + default: + return FALSE; + } +} + +static void fetchLitPair(PAIR_ID pairId, asmop *left, int offset) +{ + const char *l; + const char *pair = _pairs[pairId].name; + l = aopGetLitWordLong(left, 0, FALSE); + wassert(l && pair); + + if (isPtr(pair)) { + if (pairId == PAIR_HL || pairId == PAIR_IY) { + if (_G.pairs[pairId].last_type == left->type) { + if (_G.pairs[pairId].lit && !strcmp(_G.pairs[pairId].lit, l)) { + if (pairId == PAIR_HL && abs(_G.pairs[pairId].offset - offset) < 3) { + adjustPair(pair, &_G.pairs[pairId].offset, offset); + return; + } + if (pairId == PAIR_IY && abs(offset)<127) { + return; + } + } + } + } + _G.pairs[pairId].last_type = left->type; + _G.pairs[pairId].lit = gc_strdup(l); + _G.pairs[pairId].offset = offset; + } + /* Both a lit on the right and a true symbol on the left */ + /* PENDING: for re-target */ + if (offset) + emit2("ld %s,!hashedstr + %d", pair, l, offset); + else + emit2("ld %s,!hashedstr", pair, l); +} + +static void fetchPairLong(PAIR_ID pairId, asmop *aop, int offset) +{ + /* if this is remateriazable */ + if (isLitWord(aop)) { + fetchLitPair(pairId, aop, offset); + } + else { /* we need to get it byte by byte */ + if (pairId == PAIR_HL && IS_GB && requiresHL(aop)) { + aopGet(aop, offset, FALSE); + emit2("!ldahli"); + emit2("ld h,!*hl"); + emit2("ld l,a"); + } + else { + emitcode("ld", "%s,%s", _pairs[pairId].l, aopGet(aop, offset, FALSE)); + emitcode("ld", "%s,%s", _pairs[pairId].h, aopGet(aop, offset+1, FALSE)); + } + /* PENDING: check? */ + if (pairId == PAIR_HL) + spillPair(PAIR_HL); + } +} + +static void fetchPair(PAIR_ID pairId, asmop *aop) +{ + fetchPairLong(pairId, aop, 0); +} + +static void fetchHL(asmop *aop) +{ + fetchPair(PAIR_HL, aop); +} + +static void setupPair(PAIR_ID pairId, asmop *aop, int offset) +{ + assert(pairId == PAIR_HL || pairId == PAIR_IY); + + switch (aop->type) { + case AOP_IY: + case AOP_HL: + fetchLitPair(pairId, aop, offset); + _G.pairs[pairId].offset = offset; + break; + case AOP_STK: { + /* Doesnt include _G.stack.pushed */ + int abso = aop->aopu.aop_stk + offset + _G.stack.offset; + assert(pairId == PAIR_HL); + /* In some cases we can still inc or dec hl */ + if (_G.pairs[pairId].last_type == AOP_STK && abs(_G.pairs[pairId].offset - abso) < 3) { + adjustPair(_pairs[pairId].name, &_G.pairs[pairId].offset, abso); + } + else { + emit2("!ldahlsp", aop->aopu.aop_stk+offset + _G.stack.pushed + _G.stack.offset); + } + _G.pairs[pairId].offset = abso; + break; + } + default: + wassert(0); + } + _G.pairs[pairId].last_type = aop->type; +} + +static void emitIntLabel(int key) +{ + emit2("!tlabeldef", key); +} + +static void emitLabel(int key) +{ + emit2("!tlabeldef", key); + spillCached(); } /*-----------------------------------------------------------------*/ /* aopGet - for fetching value of the aop */ /*-----------------------------------------------------------------*/ -static char *aopGet (asmop *aop, int offset, bool bit16) +static char *aopGet(asmop *aop, int offset, bool bit16) { char *s = buffer ; char *rs; /* offset is greater than size then zero */ + /* PENDING: this seems a bit screwed in some pointer cases. */ if (offset > (aop->size - 1) && aop->type != AOP_LIT) return zero; @@ -599,61 +893,73 @@ static char *aopGet (asmop *aop, int offset, bool bit16) /* depending on type */ switch (aop->type) { case AOP_IMMD: + /* PENDING: re-target */ if (bit16) - sprintf (s,"#%s",aop->aopu.aop_immd); + tsprintf (s,"!immedwords", aop->aopu.aop_immd); else if (offset) { - assert(offset == 1); - sprintf(s,"#>%s", - aop->aopu.aop_immd); + wassert(offset == 1); + tsprintf(s, "!lsbimmeds", aop->aopu.aop_immd); } else - sprintf(s,"#<%s", - aop->aopu.aop_immd); + tsprintf(s, "!msbimmeds", aop->aopu.aop_immd); ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); return rs; case AOP_DIR: - assert(IS_GB); + wassert(IS_GB); emitcode("ld", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset); sprintf(s, "a"); ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); return rs; + case AOP_SFR: + wassert(IS_GB); + emitcode("ldh", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset); + sprintf(s, "a"); + ALLOC_ATOMIC(rs,strlen(s)+1); + strcpy(rs,s); + return rs; + case AOP_REG: return aop->aopu.aop_reg[offset]->name; + case AOP_HL: + wassert(IS_GB); + setupPair(PAIR_HL, aop, offset); + tsprintf(s, "!*hl"); + return gc_strdup(s); + case AOP_IY: - sprintf(s,"%d(iy)", offset); + wassert(IS_Z80); + setupPair(PAIR_IY, aop, offset); + tsprintf(s,"!*iyx", offset); ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); return rs; case AOP_STK: if (IS_GB) { - /* We cant really optimise this as we cant afford to - change the flags. - */ - emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); - sprintf(s, "(hl)"); + setupPair(PAIR_HL, aop, offset); + tsprintf(s, "!*hl"); } else { - sprintf(s,"%d(ix) ; %u", aop->aopu.aop_stk+offset, offset); + tsprintf(s,"!*ixx", aop->aopu.aop_stk+offset); } ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); return rs; case AOP_CRY: - assert(0); + wassert(0); case AOP_ACC: if (!offset) { return "a"; } - return "#0x00"; + return "!zero"; case AOP_LIT: return aopLiteral (aop->aopu.aop_lit,offset); @@ -661,12 +967,10 @@ static char *aopGet (asmop *aop, int offset, bool bit16) case AOP_STR: aop->coff = offset; return aop->aopu.aop_str[offset]; + default: + break; } - - fprintf(stderr, "Type %u\n", aop->type); - - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "aopget got unsupported aop->type"); + wassertl(0, "aopget got unsupported aop->type"); exit(0); } @@ -683,9 +987,10 @@ bool isRegString(char *s) return FALSE; } -bool isConstant(char *s) +bool isConstant(const char *s) { - return (*s == '#'); + /* This is a bit of a hack... */ + return (*s == '#' || *s == '$'); } bool canAssignToPtr(char *s) @@ -713,61 +1018,80 @@ static void aopPut (asmop *aop, char *s, int offset) switch (aop->type) { case AOP_DIR: /* Direct. Hmmm. */ - assert(IS_GB); - emitcode("ld", "a,%s", s); + wassert(IS_GB); + if (strcmp(s, "a")) + emitcode("ld", "a,%s", s); emitcode("ld", "(%s+%d),a", aop->aopu.aop_dir, offset); break; + case AOP_SFR: + wassert(IS_GB); + if (strcmp(s, "a")) + emitcode("ld", "a,%s", s); + emitcode("ldh", "(%s+%d),a", aop->aopu.aop_dir, offset); + break; + case AOP_REG: - /* Dont bother if it's a ld x,x */ - if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { - emitcode("ld","%s,%s", - aop->aopu.aop_reg[offset]->name,s); - } + emitcode("ld","%s,%s", + aop->aopu.aop_reg[offset]->name,s); break; case AOP_IY: - assert(!IS_GB); + wassert(!IS_GB); + setupPair(PAIR_IY, aop, offset); if (!canAssignToPtr(s)) { - emitcode("ld", "a,%s", s); - emitcode("ld", "%d(iy),a", offset); + emit2("ld a,%s", s); + emit2("ld !*iyx,a", offset); } else - emitcode("ld", "%d(iy),%s", offset, s); + emit2("ld !*iyx,%s", offset, s); break; + + case AOP_HL: + wassert(IS_GB); + /* PENDING: for re-target */ + if (!strcmp(s, "!*hl") || !strcmp(s, "(hl)") || !strcmp(s, "[hl]")) { + emit2("ld a,!*hl"); + s = "a"; + } + setupPair(PAIR_HL, aop, offset); + emit2("ld !*hl,%s", s); + break; + case AOP_STK: if (IS_GB) { - if (!strcmp("(hl)", s)) { - emitcode("ld", "a,(hl)"); + /* PENDING: re-target */ + if (!strcmp(s, "!*hl") || !strcmp(s, "(hl)") || !strcmp(s, "[hl]")) { + emit2("ld a,!*hl"); s = "a"; } - emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); + setupPair(PAIR_HL, aop, offset); if (!canAssignToPtr(s)) { - emitcode("ld", "a,%s", s); - emitcode("ld", "(hl),a"); + emit2("ld a,%s", s); + emit2("ld !*hl,a"); } else - emitcode("ld", "(hl),%s", s); + emit2("ld !*hl,%s ; 3", s); } else { if (!canAssignToPtr(s)) { - emitcode("ld", "a,%s", s); - emitcode("ld", "%d(ix),a", aop->aopu.aop_stk+offset); + emit2("ld a,%s", s); + emit2("ld !*ixx,a", aop->aopu.aop_stk+offset); } else - emitcode("ld", "%d(ix),%s", aop->aopu.aop_stk+offset, s); + emit2("ld !*ixx,%s", aop->aopu.aop_stk+offset, s); } break; case AOP_CRY: /* if bit variable */ if (!aop->aopu.aop_dir) { - emitcode("ld", "a,#0"); - emitcode("rla", ""); + emit2("ld a,#0"); + emit2("rla"); } else { /* In bit space but not in C - cant happen */ - assert(0); + wassert(0); } break; @@ -813,7 +1137,7 @@ int getDataSize(operand *op) size = AOP_SIZE(op); if(size == 3) { /* pointer */ - assert(0); + wassert(0); } return size; } @@ -832,7 +1156,7 @@ static void movLeft2Result (operand *left, int offl, aopPut(AOP(result),l,offr); } else { - assert(0); + wassert(0); } } } @@ -850,7 +1174,7 @@ void outAcc(operand *result) offset = 1; /* unsigned or positive */ while (size--){ - aopPut(AOP(result),zero,offset++); + aopPut(AOP(result), zero, offset++); } } } @@ -865,8 +1189,8 @@ void outBitC(operand *result) aopPut(AOP(result),"blah",0); } else { - emitcode("ld", "a,#0"); - emitcode("rla", ""); + emit2("ld a,!zero"); + emit2("rla"); outAcc(result); } } @@ -900,17 +1224,17 @@ static void genNot (iCode *ic) link *optype = operandType(IC_LEFT(ic)); /* assign asmOps to operand & result */ - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); + aopOp (IC_LEFT(ic),ic,FALSE, TRUE); + aopOp (IC_RESULT(ic),ic,TRUE, FALSE); /* if in bit space then a special case */ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) { - assert(0); + wassert(0); } /* if type float then do float */ if (IS_FLOAT(optype)) { - assert(0); + wassert(0); } toBoolean(IC_LEFT(ic)); @@ -919,7 +1243,7 @@ static void genNot (iCode *ic) If A == 0, !A = 1 else A = 0 So if A = 0, A-1 = 0xFF and C is set, rotate C into reg. */ - emitcode("sub", "a,#0x01"); + emit2("sub a,!one"); outBitC(IC_RESULT(ic)); /* release the aops */ @@ -937,14 +1261,14 @@ static void genCpl (iCode *ic) /* assign asmOps to operand & result */ - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); + aopOp (IC_LEFT(ic),ic,FALSE, FALSE); + aopOp (IC_RESULT(ic),ic,TRUE, FALSE); /* if both are in bit space then a special case */ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - assert(0); + wassert(0); } size = AOP_SIZE(IC_RESULT(ic)); @@ -969,14 +1293,14 @@ static void genUminus (iCode *ic) link *optype, *rtype; /* assign asmops */ - aopOp(IC_LEFT(ic),ic,FALSE); - aopOp(IC_RESULT(ic),ic,TRUE); + aopOp(IC_LEFT(ic),ic,FALSE, FALSE); + aopOp(IC_RESULT(ic),ic,TRUE, FALSE); /* if both in bit space then special case */ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - assert(0); + wassert(0); goto release; } @@ -985,7 +1309,7 @@ static void genUminus (iCode *ic) /* if float then do float stuff */ if (IS_FLOAT(optype)) { - assert(0); + wassert(0); goto release; } @@ -995,16 +1319,16 @@ static void genUminus (iCode *ic) CLRC ; while(size--) { char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE); - emitcode("ld", "a,#0"); - emitcode("sbc","a,%s",l); + emit2("ld a,!zero"); + emit2("sbc a,%s",l); aopPut(AOP(IC_RESULT(ic)),"a",offset++); } /* if any remaining bytes in the result */ /* we just need to propagate the sign */ if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) { - emitcode("rlc","a"); - emitcode("sbc","a,a"); + emit2("rlc a"); + emit2("sbc a,a"); while (size--) aopPut(AOP(IC_RESULT(ic)),"a",offset++); } @@ -1015,42 +1339,34 @@ release: freeAsmop(IC_RESULT(ic),NULL,ic); } -static bool requiresHL(asmop *aop) -{ - switch (aop->type) { - case AOP_STK: - return TRUE; - default: - return FALSE; - } -} - /*-----------------------------------------------------------------*/ /* assignResultValue - */ /*-----------------------------------------------------------------*/ void assignResultValue(operand * oper) { - int offset = 0; int size = AOP_SIZE(oper); + bool topInA = 0; - assert(size <= 2); + wassert(size <= 4); + topInA = requiresHL(AOP(oper)); - while (size--) { - aopPut(AOP(oper),_fReturn[offset],offset); - offset++; - } -} - -static void fetchHL(asmop *aop) -{ - if (IS_GB && requiresHL(aop)) { - emitcode("ld", "a,%s", aopGet(aop, 0, FALSE)); - emitcode("ld", "h,%s", aopGet(aop, 1, FALSE)); - emitcode("ld", "l,a"); + if (!IS_GB) + wassert(size <= 2); + if (IS_GB && size == 4 && requiresHL(AOP(oper))) { + /* We do it the hard way here. */ + emitcode("push", "hl"); + _G.stack.pushed += 2; + aopPut(AOP(oper), _fReturn[0], 0); + aopPut(AOP(oper), _fReturn[1], 1); + emitcode("pop", "de"); + _G.stack.pushed -= 2; + aopPut(AOP(oper), _fReturn[0], 2); + aopPut(AOP(oper), _fReturn[1], 3); } else { - emitcode("ld", "l,%s", aopGet(aop, 0, FALSE)); - emitcode("ld", "h,%s", aopGet(aop, 1, FALSE)); + while (size--) { + aopPut(AOP(oper), _fReturn[size], size); + } } } @@ -1070,12 +1386,12 @@ static void genIpush (iCode *ic) if (OP_SYMBOL(IC_LEFT(ic))->isspilt) return ; - aopOp(IC_LEFT(ic),ic,FALSE); + aopOp(IC_LEFT(ic),ic,FALSE, FALSE); size = AOP_SIZE(IC_LEFT(ic)); /* push it on the stack */ if (isPair(AOP(IC_LEFT(ic)))) { emitcode("push", getPairName(AOP(IC_LEFT(ic)))); - _pushed += 2; + _G.stack.pushed += 2; } else { offset = size; @@ -1085,7 +1401,7 @@ static void genIpush (iCode *ic) emitcode("ld", "a,%s", l); emitcode("push", "af"); emitcode("inc", "sp"); - _pushed++; + _G.stack.pushed++; } } return ; @@ -1095,28 +1411,20 @@ static void genIpush (iCode *ic) at this point? */ /* then do the push */ - aopOp(IC_LEFT(ic),ic,FALSE); + aopOp(IC_LEFT(ic),ic,FALSE, FALSE); size = AOP_SIZE(IC_LEFT(ic)); if (isPair(AOP(IC_LEFT(ic)))) { - _pushed+=2; + _G.stack.pushed+=2; emitcode("push", "%s", getPairName(AOP(IC_LEFT(ic)))); } else { if (size == 2) { - char *s = aopGetWord(AOP(IC_LEFT(ic)), 0); - if (s) { - emitcode("ld", "hl,%s", s); - emitcode("push", "hl"); - _pushed+=2; - } - else { - /* Optimise here - load into HL then push HL */ - fetchHL(AOP(IC_LEFT(ic))); - emitcode("push", "hl"); - _pushed += 2; - } + fetchHL(AOP(IC_LEFT(ic))); + emitcode("push", "hl"); + spillPair(PAIR_HL); + _G.stack.pushed += 2; goto release; } offset = size; @@ -1125,7 +1433,7 @@ static void genIpush (iCode *ic) emitcode("ld", "a,%s", l); emitcode("push", "af"); emitcode("inc", "sp"); - _pushed++; + _G.stack.pushed++; } } release: @@ -1144,7 +1452,7 @@ static void genIpop (iCode *ic) if (OP_SYMBOL(IC_LEFT(ic))->isspilt) return ; - aopOp(IC_LEFT(ic),ic,FALSE); + aopOp(IC_LEFT(ic),ic,FALSE, FALSE); size = AOP_SIZE(IC_LEFT(ic)); offset = (size-1); if (isPair(AOP(IC_LEFT(ic)))) { @@ -1154,6 +1462,7 @@ static void genIpop (iCode *ic) while (size--) { emitcode("dec", "sp"); emitcode("pop", "hl"); + spillPair(PAIR_HL); aopPut(AOP(IC_LEFT(ic)), "l", offset--); } } @@ -1165,8 +1474,6 @@ static void genIpop (iCode *ic) */ static void emitCall (iCode *ic, bool ispcall) { - int isPrintf = 0; - /* if caller saves & we have not saved then */ if (!ic->regsSaved) { /* PENDING */ @@ -1178,7 +1485,7 @@ static void emitCall (iCode *ic, bool ispcall) for (sic = setFirstItem(sendSet) ; sic ; sic = setNextItem(sendSet)) { int size, offset = 0; - aopOp(IC_LEFT(sic),sic,FALSE); + aopOp(IC_LEFT(sic),sic,FALSE, FALSE); size = AOP_SIZE(IC_LEFT(sic)); while (size--) { char *l = aopGet(AOP(IC_LEFT(sic)),offset, @@ -1195,18 +1502,25 @@ static void emitCall (iCode *ic, bool ispcall) } if (ispcall) { - symbol *rlbl = newiTempLabel(NULL); - - emitcode("ld", "hl,#" LABEL_STR, (rlbl->key+100)); - emitcode("push", "hl"); + aopOp(IC_LEFT(ic),ic,FALSE, FALSE); - aopOp(IC_LEFT(ic),ic,FALSE); - emitcode("ld", "l,%s", aopGet(AOP(IC_LEFT(ic)), 0,FALSE)); - emitcode("ld", "h,%s", aopGet(AOP(IC_LEFT(ic)), 1,FALSE)); + if (isLitWord(AOP(IC_LEFT(ic)))) { + emitcode("", "; Special case where the pCall is to a constant"); + emitcode("call", aopGetLitWordLong(AOP(IC_LEFT(ic)), 0, FALSE)); + } + else { + symbol *rlbl = newiTempLabel(NULL); + spillPair(PAIR_HL); + emit2("ld hl,#!tlabel", (rlbl->key+100)); + emitcode("push", "hl"); + _G.stack.pushed += 2; + + fetchHL(AOP(IC_LEFT(ic))); + emit2("jp !*hl"); + emit2("!tlabeldef", (rlbl->key+100)); + _G.stack.pushed -= 2; + } freeAsmop(IC_LEFT(ic),NULL,ic); - - emitcode("jp", "(hl)"); - emitcode("","%05d$:",(rlbl->key+100)); } else { /* make the call */ @@ -1214,10 +1528,8 @@ static void emitCall (iCode *ic, bool ispcall) OP_SYMBOL(IC_LEFT(ic))->rname : OP_SYMBOL(IC_LEFT(ic))->name; emitcode("call", "%s", name); - if (!strcmp(name, "__printf")) - isPrintf = 1; - } + spillCached(); /* if we need assign a result value */ if ((IS_ITEMP(IC_RESULT(ic)) && @@ -1226,7 +1538,7 @@ static void emitCall (iCode *ic, bool ispcall) IS_TRUE_SYMOP(IC_RESULT(ic)) ) { accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); + aopOp(IC_RESULT(ic),ic,FALSE, FALSE); accInUse--; assignResultValue(IC_RESULT(ic)); @@ -1237,22 +1549,26 @@ static void emitCall (iCode *ic, bool ispcall) /* adjust the stack for parameters if required */ if (IC_LEFT(ic)->parmBytes) { int i = IC_LEFT(ic)->parmBytes; - emitcode("", ";parmBytes = %u\n", i); - if (isPrintf) - i+=2; - _pushed -= i; - if (i>6) { - emitcode("ld", "hl,#%d", i); - emitcode("add", "hl,sp"); - emitcode("ld", "sp,hl"); + _G.stack.pushed -= i; + if (IS_GB) { + emit2("!ldaspsp", i); } else { - while (i>1) { - emitcode("pop", "hl"); - i-=2; + spillCached(); + if (i>6) { + emitcode("ld", "hl,#%d", i); + emitcode("add", "hl,sp"); + emitcode("ld", "sp,hl"); } - if (i) - emitcode("inc", "sp"); + else { + while (i>1) { + emitcode("pop", "hl"); + i-=2; + } + if (i) + emitcode("inc", "sp"); + } + spillCached(); } } @@ -1296,49 +1612,37 @@ static int resultRemat (iCode *ic) /*-----------------------------------------------------------------*/ static void genFunction (iCode *ic) { - symbol *sym; + symbol *sym = OP_SYMBOL(IC_LEFT(ic)); link *fetype; nregssaved = 0; /* create the function header */ - emitcode(";","-----------------------------------------"); - emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); - emitcode(";","-----------------------------------------"); + emit2("!functionheader", sym->name); + /* PENDING: portability. */ + emit2("__%s_start:", sym->rname); + emit2("!functionlabeldef", sym->rname); - emitcode("","%s:",sym->rname); fetype = getSpec(operandType(IC_LEFT(ic))); /* if critical function then turn interrupts off */ if (SPEC_CRTCL(fetype)) - emitcode("di",""); + emit2("!di"); /* if this is an interrupt service routine then save acc, b, dpl, dph */ if (IS_ISR(sym->etype)) { - emitcode("push", "af"); - emitcode("push", "bc"); - emitcode("push", "de"); - emitcode("push", "hl"); + emit2("!pusha"); } /* PENDING: callee-save etc */ /* adjust the stack for the function */ - emitcode("push", "bc"); - if (!IS_GB) { - emitcode("push", "de"); - emitcode("push", "ix"); - emitcode("ld", "ix,#0"); - emitcode("add", "ix,sp"); - } - - _lastStack = sym->stack; + _G.stack.last = sym->stack; - if (sym->stack) { - emitcode("ld", "hl,#-%d", sym->stack); - emitcode("add", "hl,sp"); - emitcode("ld", "sp,hl"); - } - _spoffset = sym->stack; + if (sym->stack) + emit2("!enterx", sym->stack); + else + emit2("!enter"); + _G.stack.offset = sym->stack; } /*-----------------------------------------------------------------*/ @@ -1349,11 +1653,11 @@ static void genEndFunction (iCode *ic) symbol *sym = OP_SYMBOL(IC_LEFT(ic)); if (IS_ISR(sym->etype)) { - assert(0); + wassert(0); } else { if (SPEC_CRTCL(sym->etype)) - emitcode("ei", ""); + emit2("!ei"); /* PENDING: calleeSave */ @@ -1369,23 +1673,15 @@ static void genEndFunction (iCode *ic) emitcode("","XG$%s$0$0 ==.",currFunc->name); debugLine = 0; } - if (!IS_GB) { - emitcode("ld", "sp,ix"); - emitcode("pop", "ix"); - emitcode("pop", "de"); - } - else { - if (_spoffset) { - emitcode("ld", "hl,#%d", _spoffset); - emitcode("add", "hl,sp"); - emitcode("ld", "sp,hl"); - } - } - emitcode("pop", "bc"); - emitcode("ret", ""); + if (_G.stack.offset) + emit2("!leavex", _G.stack.offset); + else + emit2("!leave"); + /* PENDING: portability. */ + emit2("__%s_end:", sym->rname); } - _pushed = 0; - _spoffset = 0; + _G.stack.pushed = 0; + _G.stack.offset = 0; } /*-----------------------------------------------------------------*/ @@ -1405,18 +1701,29 @@ static void genRet (iCode *ic) /* we have something to return then move the return value into place */ - aopOp(IC_LEFT(ic),ic,FALSE); + aopOp(IC_LEFT(ic),ic,FALSE, FALSE); size = AOP_SIZE(IC_LEFT(ic)); if ((size == 2) && ((l = aopGetWord(AOP(IC_LEFT(ic)), 0)))) { + if (IS_GB) { + emitcode("ld", "de,%s", l); + } + else { emitcode("ld", "hl,%s", l); + } } else { - while (size--) { - l = aopGet(AOP(IC_LEFT(ic)),offset, - FALSE); - if (strcmp(_fReturn[offset],l)) - emitcode("ld","%s,%s", _fReturn[offset++],l); + if (IS_GB && size == 4 && requiresHL(AOP(IC_LEFT(ic)))) { + fetchPair(PAIR_DE, AOP(IC_LEFT(ic))); + fetchPairLong(PAIR_HL, AOP(IC_LEFT(ic)), 2); + } + else { + while (size--) { + l = aopGet(AOP(IC_LEFT(ic)),offset, + FALSE); + if (strcmp(_fReturn[offset],l)) + emitcode("ld","%s,%s", _fReturn[offset++],l); + } } } freeAsmop (IC_LEFT(ic),NULL,ic); @@ -1427,7 +1734,7 @@ static void genRet (iCode *ic) if (!(ic->next && ic->next->op == LABEL && IC_LABEL(ic->next) == returnLabel)) - emitcode("jp", LABEL_STR ,(returnLabel->key+100)); + emit2("jp !tlabel", returnLabel->key+100); } /*-----------------------------------------------------------------*/ @@ -1439,7 +1746,7 @@ static void genLabel (iCode *ic) if (IC_LABEL(ic) == entryLabel) return ; - emitcode("", LABEL_STR ":",(IC_LABEL(ic)->key+100)); + emitLabel(IC_LABEL(ic)->key+100); } /*-----------------------------------------------------------------*/ @@ -1447,7 +1754,7 @@ static void genLabel (iCode *ic) /*-----------------------------------------------------------------*/ static void genGoto (iCode *ic) { - emitcode ("jp", LABEL_STR ,(IC_LABEL(ic)->key+100)); + emit2("jp !tlabel", IC_LABEL(ic)->key+100); } /*-----------------------------------------------------------------*/ @@ -1457,7 +1764,8 @@ static bool genPlusIncr (iCode *ic) { unsigned int icount ; unsigned int size = getDataSize(IC_RESULT(ic)); - + PAIR_ID resultId = getPairId(AOP(IC_RESULT(ic))); + /* will try to generate an increment */ /* if the right side is not a literal we cannot */ @@ -1467,55 +1775,56 @@ static bool genPlusIncr (iCode *ic) emitcode("", "; genPlusIncr"); icount = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - + /* If result is a pair */ - if (isPair(AOP(IC_RESULT(ic)))) { - char *left = aopGetWordLong(AOP(IC_LEFT(ic)), 0, FALSE); - if (left) { - /* Both a lit on the right and a true symbol on the left */ - emitcode("ld", "%s,#%s + %d", getPairName(AOP(IC_RESULT(ic))), left, icount); + if (resultId != PAIR_INVALID) { + if (isLitWord(AOP(IC_LEFT(ic)))) { + fetchLitPair(getPairId(AOP(IC_RESULT(ic))), AOP(IC_LEFT(ic)), icount); return TRUE; } + if (isPair(AOP(IC_LEFT(ic))) && resultId == PAIR_HL && icount > 2) { + fetchPair(resultId, AOP(IC_RIGHT(ic))); + emitcode("add", "hl,%s", getPairName(AOP(IC_LEFT(ic)))); + return TRUE; + } + if (icount > 5) + return FALSE; + /* Inc a pair */ + if (!sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { + if (icount > 2) + return FALSE; + movLeft2Result(IC_LEFT(ic), 0, IC_RESULT(ic), 0, 0); + movLeft2Result(IC_LEFT(ic), 1, IC_RESULT(ic), 1, 0); + } + while (icount--) { + emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic)))); + } + return TRUE; } /* if the literal value of the right hand side is greater than 4 then it is not worth it */ if (icount > 4) - return FALSE ; + return FALSE; - /* Inc a pair */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) && - isPair(AOP(IC_RESULT(ic)))) { - while (icount--) { - emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic)))); - } - return TRUE; - } /* if increment 16 bits in register */ if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) && - (size > 1) && - (icount == 1)) { - symbol *tlbl = newiTempLabel(NULL); - emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE)); - emitcode("jp", "nz," LABEL_STR ,tlbl->key+100); - - emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE)); - if(size == 4) { - assert(0); + size > 1 && + icount == 1 + ) { + int offset = 0; + symbol *tlbl = NULL; + tlbl = newiTempLabel(NULL); + while (size--) { + emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)), offset++, FALSE)); + if (size) { + emit2("!shortjp nz,!tlabel", tlbl->key+100); + } } - emitcode("", LABEL_STR ":",tlbl->key+100); + emitLabel(tlbl->key+100); return TRUE; } - /* If result is a pair */ - if (isPair(AOP(IC_RESULT(ic)))) { - movLeft2Result(IC_LEFT(ic), 0, IC_RESULT(ic), 0, 0); - movLeft2Result(IC_LEFT(ic), 1, IC_RESULT(ic), 1, 0); - while (icount--) - emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic)))); - return TRUE; - } - /* if the sizes are greater than 1 then we cannot */ if (AOP_SIZE(IC_RESULT(ic)) > 1 || AOP_SIZE(IC_LEFT(ic)) > 1 ) @@ -1527,7 +1836,6 @@ static bool genPlusIncr (iCode *ic) if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { while (icount--) emitcode ("inc","%s",aopGet(AOP(IC_LEFT(ic)),0, FALSE)); - return TRUE ; } @@ -1542,12 +1850,12 @@ void outBitAcc(operand *result) symbol *tlbl = newiTempLabel(NULL); /* if the result is a bit */ if (AOP_TYPE(result) == AOP_CRY){ - assert(0); + wassert(0); } else { - emitcode("jp","z," LABEL_STR ,tlbl->key+100); - emitcode("ld","a,%s",one); - emitcode("", LABEL_STR ":",tlbl->key+100); + emit2("!shortjp z,!tlabel", tlbl->key+100); + emit2("ld a,!one"); + emitLabel(tlbl->key+100); outAcc(result); } } @@ -1561,9 +1869,9 @@ static void genPlus (iCode *ic) /* special cases :- */ - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RIGHT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); + aopOp (IC_LEFT(ic),ic,FALSE, FALSE); + aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); + aopOp (IC_RESULT(ic),ic,TRUE, FALSE); /* Swap the left and right operands if: @@ -1584,14 +1892,14 @@ static void genPlus (iCode *ic) if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { /* Cant happen */ - assert(0); + wassert(0); } /* if left in bit space & right literal */ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) { /* Can happen I guess */ - assert(0); + wassert(0); } /* if I can do an increment instead @@ -1605,8 +1913,8 @@ static void genPlus (iCode *ic) if (isPair(AOP(IC_RESULT(ic)))) { char *left, *right; - left = aopGetWordLong(AOP(IC_LEFT(ic)), 0, FALSE); - right = aopGetWordLong(AOP(IC_RIGHT(ic)), 0, FALSE); + left = aopGetLitWordLong(AOP(IC_LEFT(ic)), 0, FALSE); + right = aopGetLitWordLong(AOP(IC_RIGHT(ic)), 0, FALSE); if (left && right) { /* It's a pair */ /* PENDING: fix */ @@ -1617,6 +1925,14 @@ static void genPlus (iCode *ic) } } + if (isPair(AOP(IC_RIGHT(ic))) && getPairId(AOP(IC_RESULT(ic))) == PAIR_HL) { + /* Fetch into HL then do the add */ + spillPair(PAIR_HL); + fetchPair(PAIR_HL, AOP(IC_LEFT(ic))); + emitcode("add", "hl,%s", getPairName(AOP(IC_RIGHT(ic)))); + goto release; + } + while(size--) { if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE)); @@ -1627,13 +1943,13 @@ static void genPlus (iCode *ic) emitcode("adc","a,%s", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE)); } else { - MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE)); + MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE)); if(offset == 0) emitcode("add","a,%s", - aopGet(AOP(IC_LEFT(ic)),offset,FALSE)); + aopGet(AOP(IC_RIGHT(ic)),offset,FALSE)); else emitcode("adc","a,%s", - aopGet(AOP(IC_LEFT(ic)),offset,FALSE)); + aopGet(AOP(IC_RIGHT(ic)),offset,FALSE)); } aopPut(AOP(IC_RESULT(ic)),"a",offset++); } @@ -1642,12 +1958,12 @@ static void genPlus (iCode *ic) if (AOP_SIZE(IC_RESULT(ic)) == 3 && AOP_SIZE(IC_LEFT(ic)) == 3 && !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) - assert(0); + wassert(0); if (AOP_SIZE(IC_RESULT(ic)) == 3 && AOP_SIZE(IC_RIGHT(ic)) == 3 && !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) - assert(0); + wassert(0); release: @@ -1688,9 +2004,9 @@ static bool genMinusDec (iCode *ic) emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE)); if(size == 4) { - assert(0); + wassert(0); } - emitcode("", LABEL_STR ":",tlbl->key+100); + emitLabel(tlbl->key+100); return TRUE; } #endif @@ -1736,15 +2052,15 @@ static void genMinus (iCode *ic) int size, offset = 0; unsigned long lit = 0L; - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RIGHT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); + aopOp (IC_LEFT(ic),ic,FALSE, FALSE); + aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); + aopOp (IC_RESULT(ic),ic,TRUE, FALSE); /* special cases :- */ /* if both left & right are in bit space */ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - assert(0); + wassert(0); goto release ; } @@ -1776,11 +2092,9 @@ static void genMinus (iCode *ic) else{ /* first add without previous c */ if (!offset) - emitcode("add","a,#0x%02x", - (unsigned int)(lit & 0x0FFL)); + emit2("add a,!immedbyte", (unsigned int)(lit & 0x0FFL)); else - emitcode("adc","a,#0x%02x", - (unsigned int)((lit >> (offset*8)) & 0x0FFL)); + emit2("adc a,!immedbyte", (unsigned int)((lit >> (offset*8)) & 0x0FFL)); } aopPut(AOP(IC_RESULT(ic)),"a",offset++); } @@ -1788,7 +2102,7 @@ static void genMinus (iCode *ic) if (AOP_SIZE(IC_RESULT(ic)) == 3 && AOP_SIZE(IC_LEFT(ic)) == 3 && !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) - assert(0); + wassert(0); release: freeAsmop(IC_LEFT(ic),NULL,ic); @@ -1802,7 +2116,7 @@ release: static void genMult (iCode *ic) { /* Shouldn't occur - all done through function calls */ - assert(0); + wassert(0); } /*-----------------------------------------------------------------*/ @@ -1811,7 +2125,7 @@ static void genMult (iCode *ic) static void genDiv (iCode *ic) { /* Shouldn't occur - all done through function calls */ - assert(0); + wassert(0); } /*-----------------------------------------------------------------*/ @@ -1820,7 +2134,7 @@ static void genDiv (iCode *ic) static void genMod (iCode *ic) { /* Shouldn't occur - all done through function calls */ - assert(0); + wassert(0); } /*-----------------------------------------------------------------*/ @@ -1869,7 +2183,7 @@ static void genIfxJump (iCode *ic, char *jval) else { emitcode("bit", "%s,a", jval); } - emitcode("jp", "%s," LABEL_STR , inst, jlbl->key+100); + emit2("jp %s,!tlabel", inst, jlbl->key+100); /* mark the icode as generated */ ic->generated = 1; @@ -1887,7 +2201,7 @@ static void genCmp (operand *left,operand *right, if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY ) { /* Cant happen on the Z80 */ - assert(0); + wassert(0); } else { /* subtract right from left if at the end the carry flag is set then we know that @@ -1899,11 +2213,11 @@ static void genCmp (operand *left,operand *right, (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){ emitcode("ld", "a,%s", aopGet(AOP(left), offset, FALSE)); if (sign) { - emitcode("xor", "a,#0x80"); - emitcode("cp", "%s^0x80", aopGet(AOP(right), offset, FALSE)); + emit2("xor a,!immedbyte", 0x80); + emit2("cp %s^!constbyte", aopGet(AOP(right), offset, FALSE), 0x80); } else - emitcode("cp", "%s ; 7", aopGet(AOP(right), offset, FALSE)); + emitcode("cp", "%s", aopGet(AOP(right), offset, FALSE)); } else { if(AOP_TYPE(right) == AOP_LIT) { @@ -1933,24 +2247,24 @@ static void genCmp (operand *left,operand *right, if (AOP_TYPE(left) == AOP_LIT){ unsigned long lit = (unsigned long) floatFromVal(AOP(left)->aopu.aop_lit); - emitcode("ld", "%s,#0x%02x", _fTmp[0], + emit2("ld %s,!immedbyte", _fTmp[0], 0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL)); } else { emitcode("ld", "a,%s", aopGet(AOP(left), size-1, FALSE)); - emitcode("xor", "a,#0x80"); + emit2("xor a,!immedbyte", 0x80); emitcode("ld", "%s,a", _fTmp[0]); fDidXor = TRUE; } if (AOP_TYPE(right) == AOP_LIT) { unsigned long lit = (unsigned long) floatFromVal(AOP(right)->aopu.aop_lit); - emitcode("ld", "%s,#0x%02x", _fTmp[1], + emit2("ld %s,!immedbyte", _fTmp[1], 0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL)); } else { emitcode("ld", "a,%s", aopGet(AOP(right), size-1, FALSE)); - emitcode("xor", "a,#0x80"); + emit2("xor a,!immedbyte", 0x80); emitcode("ld", "%s,a", _fTmp[1]); fDidXor = TRUE; } @@ -1962,15 +2276,16 @@ static void genCmp (operand *left,operand *right, } while (size--) { /* Do a long subtract */ - if (!sign || size) + if (!sign || size ) { MOVA(aopGet(AOP(left),offset,FALSE)); + } if (sign && size == 0) { emitcode("ld", "a,%s", _fTmp[0]); emitcode("sbc", "a,%s", _fTmp[1]); } else { /* Subtract through, propagating the carry */ - emitcode("sbc","a,%s",aopGet(AOP(right),offset++,FALSE)); + emitcode("sbc","a,%s ; 2",aopGet(AOP(right),offset++,FALSE)); } } } @@ -2008,9 +2323,9 @@ static void genCmpGt (iCode *ic, iCode *ifx) retype =getSpec(operandType(right)); sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); + aopOp (left,ic,FALSE, FALSE); + aopOp (right,ic,FALSE, FALSE); + aopOp (result,ic,TRUE, FALSE); genCmp(right, left, result, ifx, sign); @@ -2037,9 +2352,9 @@ static void genCmpLt (iCode *ic, iCode *ifx) sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); + aopOp (left,ic,FALSE, FALSE); + aopOp (right,ic,FALSE, FALSE); + aopOp (result,ic,TRUE, FALSE); genCmp(left, right, result, ifx, sign); @@ -2070,15 +2385,31 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl) /* if the right side is a literal then anything goes */ if (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR ) { - while (size--) { - emitcode("ld", "a,%s ; 2", aopGet(AOP(left),offset,FALSE)); - if ((AOP_TYPE(right) == AOP_LIT) && lit == 0) + if (lit == 0) { + emitcode("ld", "a,%s", aopGet(AOP(left), offset, FALSE)); + if (size > 1) { + size--; + offset++; + while (size--) { + emitcode("or", "a,%s", aopGet(AOP(left), offset, FALSE)); + } + } + else { emitcode("or", "a,a"); - else - emitcode("cp", "a,%s", aopGet(AOP(right),offset,FALSE)); - emitcode("jp", "nz," LABEL_STR , lbl->key+100); - offset++; - } + } + emit2("jp nz,!tlabel", lbl->key+100); + } + else { + while (size--) { + emitcode("ld", "a,%s ; 2", aopGet(AOP(left),offset,FALSE)); + if ((AOP_TYPE(right) == AOP_LIT) && lit == 0) + emitcode("or", "a,a"); + else + emitcode("cp", "a,%s", aopGet(AOP(right),offset,FALSE)); + emit2("jp nz,!tlabel", lbl->key+100); + offset++; + } + } } /* if the right side is in a register or in direct space or if the left is a pointer register & right is not */ @@ -2090,10 +2421,10 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl) if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) && ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0)) /* PENDING */ - emitcode("jp","nz," LABEL_STR ,lbl->key+100); + emit2("jp nz,!tlabel", lbl->key+100); else { emitcode("cp", "%s ; 4", aopGet(AOP(right),offset,FALSE)); - emitcode("jp", "nz," LABEL_STR , lbl->key+100); + emit2("jp nz,!tlabel", lbl->key+100); } offset++; } @@ -2101,10 +2432,9 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl) /* right is a pointer reg need both a & b */ /* PENDING: is this required? */ while(size--) { - char *l = aopGet(AOP(left),offset,FALSE); MOVA(aopGet(AOP(right),offset,FALSE)); - emitcode("cp", "%s ; 5", l); - emitcode("jr", "nz," LABEL_STR, lbl->key+100); + emitcode("cp", "%s ; 5", aopGet(AOP(left), offset, FALSE)); + emit2("!shortjp nz,!tlabel", lbl->key+100); offset++; } } @@ -2120,11 +2450,11 @@ static void gencjne(operand *left, operand *right, symbol *lbl) gencjneshort(left, right, lbl); /* PENDING: ?? */ - emitcode("ld","a,%s",one); - emitcode("jp", LABEL_STR ,tlbl->key+100); - emitcode("", LABEL_STR ":",lbl->key+100); + emit2("ld a,!one"); + emit2("!shortjp !tlabel", tlbl->key+100); + emitLabel(lbl->key+100); emitcode("xor","a,a"); - emitcode("", LABEL_STR ":",tlbl->key+100); + emitLabel(tlbl->key+100); } /*-----------------------------------------------------------------*/ @@ -2134,9 +2464,9 @@ static void genCmpEq (iCode *ic, iCode *ifx) { operand *left, *right, *result; - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); + aopOp((left=IC_LEFT(ic)),ic,FALSE, FALSE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE, FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE); /* Swap operands if it makes the operation easier. ie if: 1. Left is a literal. @@ -2152,20 +2482,20 @@ static void genCmpEq (iCode *ic, iCode *ifx) /* if they are both bit variables */ if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { - assert(0); + wassert(0); } else { tlbl = newiTempLabel(NULL); gencjneshort(left, right, tlbl); if ( IC_TRUE(ifx) ) { - emitcode("jp", LABEL_STR ,IC_TRUE(ifx)->key+100); - emitcode("", LABEL_STR ":",tlbl->key+100); + emit2("jp !tlabel", IC_TRUE(ifx)->key+100); + emitLabel(tlbl->key+100); } else { /* PENDING: do this better */ symbol *lbl = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,lbl->key+100); - emitcode("", LABEL_STR ":",tlbl->key+100); - emitcode("jp", LABEL_STR ,IC_FALSE(ifx)->key+100); - emitcode("", LABEL_STR ":",lbl->key+100); + emit2("!shortjp !tlabel", lbl->key+100); + emitLabel(tlbl->key+100); + emit2("jp !tlabel", IC_FALSE(ifx)->key+100); + emitLabel(lbl->key+100); } } /* mark the icode as generated */ @@ -2176,11 +2506,11 @@ static void genCmpEq (iCode *ic, iCode *ifx) /* if they are both bit variables */ if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { - assert(0); + wassert(0); } else { gencjne(left,right,newiTempLabel(NULL)); if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - assert(0); + wassert(0); } if (ifx) { genIfxJump(ifx,"a"); @@ -2232,20 +2562,20 @@ static void genAndOp (iCode *ic) /* note here that && operations that are in an if statement are taken away by backPatchLabels only those used in arthmetic operations remain */ - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,FALSE); + aopOp((left=IC_LEFT(ic)),ic,FALSE, TRUE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE, TRUE); + aopOp((result=IC_RESULT(ic)),ic,FALSE, FALSE); /* if both are bit variables */ if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY ) { - assert(0); + wassert(0); } else { tlbl = newiTempLabel(NULL); toBoolean(left); - emitcode("jp","z," LABEL_STR ,tlbl->key+100); + emit2("!shortjp z,!tlabel", tlbl->key+100); toBoolean(right); - emitcode("", LABEL_STR ":",tlbl->key+100); + emitLabel(tlbl->key+100); outBitAcc(result); } @@ -2265,20 +2595,20 @@ static void genOrOp (iCode *ic) /* note here that || operations that are in an if statement are taken away by backPatchLabels only those used in arthmetic operations remain */ - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,FALSE); + aopOp((left=IC_LEFT(ic)),ic,FALSE, TRUE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE, TRUE); + aopOp((result=IC_RESULT(ic)),ic,FALSE, FALSE); /* if both are bit variables */ if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY ) { - assert(0); + wassert(0); } else { tlbl = newiTempLabel(NULL); toBoolean(left); - emitcode("jp","nz," LABEL_STR,tlbl->key+100); + emit2("!shortjp nz,!tlabel", tlbl->key+100); toBoolean(right); - emitcode("", LABEL_STR,tlbl->key+100); + emitLabel(tlbl->key+100); outBitAcc(result); } @@ -2307,6 +2637,26 @@ int isLiteralBit(unsigned long lit) return 0; } +/*-----------------------------------------------------------------*/ +/* jmpTrueOrFalse - */ +/*-----------------------------------------------------------------*/ +static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) +{ + // ugly but optimized by peephole + if(IC_TRUE(ic)){ + symbol *nlbl = newiTempLabel(NULL); + emit2("jp !tlabel", nlbl->key+100); + emitLabel(tlbl->key+100); + emit2("jp !tlabel", IC_TRUE(ic)->key+100); + emitLabel(nlbl->key+100); + } + else{ + emit2("jp !tlabel", IC_FALSE(ic)->key+100); + emitLabel(tlbl->key+100); + } + ic->generated = 1; +} + /*-----------------------------------------------------------------*/ /* genAnd - code for and */ /*-----------------------------------------------------------------*/ @@ -2317,9 +2667,9 @@ static void genAnd (iCode *ic, iCode *ifx) unsigned long lit = 0L; int bytelit = 0; - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); + aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE, FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE); #ifdef DEBUG_TYPE emitcode("","; Type res[%d] = l[%d]&r[%d]", @@ -2358,7 +2708,7 @@ static void genAnd (iCode *ic, iCode *ifx) size = AOP_SIZE(result); if (AOP_TYPE(left) == AOP_CRY){ - assert(0); + wassert(0); goto release ; } @@ -2374,7 +2724,7 @@ static void genAnd (iCode *ic, iCode *ifx) MOVA(aopGet(AOP(left),posbit>>3,FALSE)); // bit = left & 2^n if(size) { - assert(0); + wassert(0); emitcode("mov","c,acc.%d",posbit&0x07); } // if(left & 2^n) @@ -2384,7 +2734,7 @@ static void genAnd (iCode *ic, iCode *ifx) genIfxJump(ifx, buffer); } else { - assert(0); + wassert(0); } goto release; } @@ -2392,7 +2742,7 @@ static void genAnd (iCode *ic, iCode *ifx) symbol *tlbl = newiTempLabel(NULL); int sizel = AOP_SIZE(left); if(size) { - assert(0); + wassert(0); emitcode("setb","c"); } while(sizel--){ @@ -2400,14 +2750,14 @@ static void genAnd (iCode *ic, iCode *ifx) MOVA( aopGet(AOP(left),offset,FALSE)); // byte == 2^n ? if((posbit = isLiteralBit(bytelit)) != 0) { - assert(0); + wassert(0); emitcode("jb","acc.%d,%05d$",(posbit-1)&0x07,tlbl->key+100); } else{ if(bytelit != 0x0FFL) emitcode("and","a,%s", aopGet(AOP(right),offset,FALSE)); - emitcode("jr","nz, %05d$",tlbl->key+100); + emit2("!shortjp nz,!tlabel", tlbl->key+100); } } offset++; @@ -2415,16 +2765,12 @@ static void genAnd (iCode *ic, iCode *ifx) // bit = left & literal if (size){ emitcode("clr","c"); - emitcode("","%05d$:",tlbl->key+100); + emit2("!tlabeldef", tlbl->key+100); } // if(left & literal) else{ if(ifx) -#if 0 jmpTrueOrFalse(ifx, tlbl); -#else - assert(0); -#endif goto release ; } } @@ -2445,25 +2791,26 @@ static void genAnd (iCode *ic, iCode *ifx) MOVA(aopGet(AOP(left),offset,FALSE)); emitcode("and","a,%s", aopGet(AOP(right),offset,FALSE)); - emitcode("ld", "%s,a", aopGet(AOP(left),offset,FALSE)); + aopPut(AOP(left), "a", offset); } } } else { if (AOP_TYPE(left) == AOP_ACC) { - assert(0); + wassert(0); } else { - MOVA(aopGet(AOP(right),offset,FALSE)); - emitcode("and","%s,a", - aopGet(AOP(left),offset,FALSE)); + MOVA(aopGet(AOP(left),offset,FALSE)); + emitcode("and","a,%s", + aopGet(AOP(right),offset,FALSE)); + aopPut(AOP(left), "a", offset); } } } } else { // left & result in different registers if(AOP_TYPE(result) == AOP_CRY){ - assert(0); + wassert(0); } else { for(;(size--);offset++) { // normal case @@ -2484,9 +2831,9 @@ static void genAnd (iCode *ic, iCode *ifx) if (AOP_TYPE(left) == AOP_ACC) emitcode("and","a,%s",aopGet(AOP(right),offset,FALSE)); else { - MOVA(aopGet(AOP(right),offset,FALSE)); + MOVA(aopGet(AOP(left),offset,FALSE)); emitcode("and","a,%s", - aopGet(AOP(left),offset,FALSE)); + aopGet(AOP(right),offset,FALSE)); } aopPut(AOP(result),"a",offset); } @@ -2509,9 +2856,9 @@ static void genOr (iCode *ic, iCode *ifx) int size, offset=0; unsigned long lit = 0L; - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); + aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE, FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE); #if 1 emitcode("","; Type res[%d] = l[%d]&r[%d]", @@ -2550,14 +2897,14 @@ static void genOr (iCode *ic, iCode *ifx) size = AOP_SIZE(result); if (AOP_TYPE(left) == AOP_CRY){ - assert(0); + wassert(0); goto release ; } if((AOP_TYPE(right) == AOP_LIT) && (AOP_TYPE(result) == AOP_CRY) && (AOP_TYPE(left) != AOP_CRY)){ - assert(0); + wassert(0); goto release ; } @@ -2567,25 +2914,27 @@ static void genOr (iCode *ic, iCode *ifx) if(AOP_TYPE(right) == AOP_LIT){ if(((lit >> (offset*8)) & 0x0FFL) == 0x00L) continue; - else - emitcode("or","%s,%s; 5", - aopGet(AOP(left),offset,FALSE), + else { + MOVA(aopGet(AOP(left),offset,FALSE)); + emitcode("or","a,%s", aopGet(AOP(right),offset,FALSE)); + aopPut(AOP(result),"a", offset); + } } else { if (AOP_TYPE(left) == AOP_ACC) - emitcode("or","a,%s ; 6",aopGet(AOP(right),offset,FALSE)); + emitcode("or","a,%s",aopGet(AOP(right),offset,FALSE)); else { - MOVA(aopGet(AOP(right),offset,FALSE)); - emitcode("or","a,%s ; 7", - aopGet(AOP(left),offset,FALSE)); - aopPut(AOP(result),"a ; 8",0); + MOVA(aopGet(AOP(left),offset,FALSE)); + emitcode("or","a,%s", + aopGet(AOP(right),offset,FALSE)); + aopPut(AOP(result),"a", offset); } } } } else { // left & result in different registers if(AOP_TYPE(result) == AOP_CRY){ - assert(0); + wassert(0); } else for(;(size--);offset++){ // normal case // result = left & right @@ -2602,9 +2951,9 @@ static void genOr (iCode *ic, iCode *ifx) if (AOP_TYPE(left) == AOP_ACC) emitcode("or","a,%s",aopGet(AOP(right),offset,FALSE)); else { - MOVA(aopGet(AOP(right),offset,FALSE)); + MOVA(aopGet(AOP(left),offset,FALSE)); emitcode("or","a,%s", - aopGet(AOP(left),offset,FALSE)); + aopGet(AOP(right),offset,FALSE)); } aopPut(AOP(result),"a",offset); /* PENDING: something weird is going on here. Add exception. */ @@ -2628,9 +2977,9 @@ static void genXor (iCode *ic, iCode *ifx) int size, offset=0; unsigned long lit = 0L; - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); + aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE, FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE); /* if left is a literal & right is not then exchange them */ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || @@ -2660,14 +3009,14 @@ static void genXor (iCode *ic, iCode *ifx) size = AOP_SIZE(result); if (AOP_TYPE(left) == AOP_CRY){ - assert(0); + wassert(0); goto release ; } if((AOP_TYPE(right) == AOP_LIT) && (AOP_TYPE(result) == AOP_CRY) && (AOP_TYPE(left) != AOP_CRY)){ - assert(0); + wassert(0); goto release ; } @@ -2697,7 +3046,7 @@ static void genXor (iCode *ic, iCode *ifx) } else { // left & result in different registers if(AOP_TYPE(result) == AOP_CRY){ - assert(0); + wassert(0); } else for(;(size--);offset++){ // normal case // result = left & right @@ -2769,7 +3118,7 @@ static void genInline (iCode *ic) /*-----------------------------------------------------------------*/ static void genRRC (iCode *ic) { - assert(0); + wassert(0); } /*-----------------------------------------------------------------*/ @@ -2777,7 +3126,7 @@ static void genRRC (iCode *ic) /*-----------------------------------------------------------------*/ static void genRLC (iCode *ic) { - assert(0); + wassert(0); } /*-----------------------------------------------------------------*/ @@ -2789,14 +3138,14 @@ static void shiftR2Left2Result (operand *left, int offl, { if(sameRegs(AOP(result), AOP(left)) && ((offl + MSB16) == offr)){ - assert(0); + wassert(0); } else { movLeft2Result(left, offl, result, offr, 0); movLeft2Result(left, offl+1, result, offr+1, 0); } if (sign) { - assert(0); + wassert(0); } else { /* if (AOP(result)->type == AOP_REG) {*/ @@ -2807,11 +3156,11 @@ static void shiftR2Left2Result (operand *left, int offl, /* Left is already in result - so now do the shift */ if (shCount>1) { - emitcode("ld","a,#%u+1", shCount); + emit2("ld a,!immedbyte+1", shCount); tlbl = newiTempLabel(NULL); tlbl1 = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,tlbl1->key+100); - emitcode("", LABEL_STR ":",tlbl->key+100); + emit2("!shortjp !tlabel", tlbl1->key+100); + emitLabel(tlbl->key+100); } emitcode("or", "a,a"); @@ -2821,9 +3170,9 @@ static void shiftR2Left2Result (operand *left, int offl, emitcode("rr","%s", l); } if (shCount>1) { - emitcode("", LABEL_STR ":",tlbl1->key+100); + emitLabel(tlbl1->key+100); emitcode("dec", "a"); - emitcode("jp","nz," LABEL_STR ,tlbl->key+100); + emit2("!shortjp nz,!tlabel", tlbl->key+100); } } } @@ -2836,7 +3185,7 @@ static void shiftL2Left2Result (operand *left, int offl, { if(sameRegs(AOP(result), AOP(left)) && ((offl + MSB16) == offr)){ - assert(0); + wassert(0); } else { /* Copy left into result */ movLeft2Result(left, offl, result, offr, 0); @@ -2852,11 +3201,11 @@ static void shiftL2Left2Result (operand *left, int offl, /* Left is already in result - so now do the shift */ if (shCount>1) { - emitcode("ld","a,#%u+1", shCount); + emit2("ld a,!immedbyte+1", shCount); tlbl = newiTempLabel(NULL); tlbl1 = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,tlbl1->key+100); - emitcode("", LABEL_STR ":",tlbl->key+100); + emit2("!shortjp !tlabel", tlbl1->key+100); + emitLabel(tlbl->key+100); } emitcode("or", "a,a"); @@ -2865,9 +3214,9 @@ static void shiftL2Left2Result (operand *left, int offl, emitcode("rl","%s", l); } if (shCount>1) { - emitcode("", LABEL_STR ":",tlbl1->key+100); + emitLabel(tlbl1->key+100); emitcode("dec", "a"); - emitcode("jp","nz," LABEL_STR ,tlbl->key+100); + emit2("!shortjp nz,!tlabel", tlbl->key+100); } } } @@ -2930,7 +3279,7 @@ static void AccLsh (int shCount) /* rotate left accumulator */ AccRol(shCount); /* and kill the lower order bits */ - emitcode("and","a,#0x%02x", SLMask[shCount]); + emit2("and a,!immedbyte", SLMask[shCount]); } } } @@ -2957,7 +3306,7 @@ static void genlshTwo (operand *result,operand *left, int shCount) { int size = AOP_SIZE(result); - assert(size==2); + wassert(size==2); /* if shCount >= 8 */ if (shCount >= 8) { @@ -2979,7 +3328,7 @@ static void genlshTwo (operand *result,operand *left, int shCount) /* 1 <= shCount <= 7 */ else { if(size == 1) { - assert(0); + wassert(0); } else { shiftL2Left2Result(left, LSB, result, LSB, shCount); @@ -3008,8 +3357,8 @@ static void genLeftShiftLiteral (operand *left, freeAsmop(right,NULL,ic); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + aopOp(left,ic,FALSE, FALSE); + aopOp(result,ic,FALSE, FALSE); size = getSize(operandType(result)); @@ -3020,7 +3369,7 @@ static void genLeftShiftLiteral (operand *left, /* I suppose that the left size >= result size */ if (shCount == 0) { - assert(0); + wassert(0); } else if(shCount >= (size * 8)) @@ -3035,10 +3384,10 @@ static void genLeftShiftLiteral (operand *left, genlshTwo (result,left,shCount); break; case 4: - assert(0); + wassert(0); break; default: - assert(0); + wassert(0); } } freeAsmop(left,NULL,ic); @@ -3059,7 +3408,7 @@ static void genLeftShift (iCode *ic) left = IC_LEFT(ic); result = IC_RESULT(ic); - aopOp(right,ic,FALSE); + aopOp(right,ic,FALSE, FALSE); /* if the shift count is known then do it as efficiently as possible */ @@ -3075,8 +3424,8 @@ static void genLeftShift (iCode *ic) emitcode("ld","a,%s",aopGet(AOP(right),0,FALSE)); emitcode("inc","a"); freeAsmop (right,NULL,ic); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + aopOp(left,ic,FALSE, FALSE); + aopOp(result,ic,FALSE, FALSE); /* now move the left to the result if they are not the same */ @@ -3107,22 +3456,23 @@ static void genLeftShift (iCode *ic) offset = 0 ; tlbl1 = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,tlbl1->key+100); - emitcode("", LABEL_STR ":",tlbl->key+100); + emit2("!shortjp !tlabel", tlbl1->key+100); + emitLabel(tlbl->key+100); l = aopGet(AOP(result),offset,FALSE); emitcode("or", "a,a"); while (size--) { l = aopGet(AOP(result),offset++,FALSE); emitcode("rl","%s", l); } - emitcode("", LABEL_STR ":",tlbl1->key+100); + emitLabel(tlbl1->key+100); emitcode("dec", "a"); - emitcode("jp","nz," LABEL_STR ,tlbl->key+100); + emit2("!shortjp nz,!tlabel", tlbl->key+100); freeAsmop(left,NULL,ic); freeAsmop(result,NULL,ic); } +/*-----------------------------------------------------------------*/ /* genlshTwo - left shift two bytes by known amount != 0 */ /*-----------------------------------------------------------------*/ static void genrshOne (operand *result,operand *left, int shCount) @@ -3131,8 +3481,8 @@ static void genrshOne (operand *result,operand *left, int shCount) int size = AOP_SIZE(result); char *l; - assert(size==1); - assert(shCount<8); + wassert(size==1); + wassert(shCount<8); l = aopGet(AOP(left),0,FALSE); if (AOP(result)->type == AOP_REG) { @@ -3163,7 +3513,7 @@ static void AccRsh (int shCount) /* rotate right accumulator */ AccRol(8 - shCount); /* and kill the higher order bits */ - emitcode("and","a,#0x%02x", SRMask[shCount]); + emit2("and a,!immedbyte", SRMask[shCount]); } } } @@ -3177,7 +3527,7 @@ static void shiftR1Left2Result (operand *left, int offl, { MOVA(aopGet(AOP(left),offl,FALSE)); if (sign) { - assert(0); + wassert(0); } else { AccRsh(shCount); @@ -3195,7 +3545,7 @@ static void genrshTwo (operand *result,operand *left, if (shCount >= 8) { shCount -= 8 ; if (shCount) { - assert(0); + wassert(0); shiftR1Left2Result(left, MSB16, result, LSB, shCount, sign); } @@ -3223,8 +3573,8 @@ static void genRightShiftLiteral (operand *left, freeAsmop(right,NULL,ic); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + aopOp(left,ic,FALSE, FALSE); + aopOp(result,ic,FALSE, FALSE); size = getSize(operandType(result)); @@ -3233,7 +3583,7 @@ static void genRightShiftLiteral (operand *left, /* I suppose that the left size >= result size */ if (shCount == 0) { - assert(0); + wassert(0); } else if(shCount >= (size * 8)) @@ -3249,10 +3599,10 @@ static void genRightShiftLiteral (operand *left, genrshTwo(result, left, shCount, FALSE); break; case 4: - assert(0); + wassert(0); break; default: - assert(0); + wassert(0); } } freeAsmop(left,NULL,ic); @@ -3264,23 +3614,86 @@ static void genRightShiftLiteral (operand *left, /*-----------------------------------------------------------------*/ static void genRightShift (iCode *ic) { - operand *left,*right, *result; + operand *right, *left, *result; + link *retype ; + int size, offset, first = 1; + char *l; + bool is_signed; + + symbol *tlbl, *tlbl1 ; + + /* if signed then we do it the hard way preserve the + sign bit moving it inwards */ + retype = getSpec(operandType(IC_RESULT(ic))); + + is_signed = !SPEC_USIGN(retype); + + /* signed & unsigned types are treated the same : i.e. the + signed is NOT propagated inwards : quoting from the + ANSI - standard : "for E1 >> E2, is equivalent to division + by 2**E2 if unsigned or if it has a non-negative value, + otherwise the result is implementation defined ", MY definition + is that the sign does not get propagated */ right = IC_RIGHT(ic); left = IC_LEFT(ic); result = IC_RESULT(ic); - aopOp(right,ic,FALSE); + aopOp(right,ic,FALSE, FALSE); /* if the shift count is known then do it as efficiently as possible */ if (AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic); - return ; + genRightShiftLiteral(left,right,result,ic); + return; } - else { - assert(0); + + aopOp(left,ic,FALSE, FALSE); + aopOp(result,ic,FALSE, FALSE); + + /* now move the left to the result if they are not the + same */ + if (!sameRegs(AOP(left),AOP(result)) && + AOP_SIZE(result) > 1) { + + size = AOP_SIZE(result); + offset=0; + while (size--) { + l = aopGet(AOP(left),offset,FALSE); + aopPut(AOP(result),l,offset); + offset++; + } } + + emitcode("ld", "a,%s",aopGet(AOP(right),0,FALSE)); + emitcode("inc","a"); + freeAsmop (right, NULL, ic); + + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); + size = AOP_SIZE(result); + offset = size - 1; + + emit2("!shortjp !tlabel", tlbl1->key+100); + emitLabel(tlbl->key+100); + while (size--) { + l = aopGet(AOP(result),offset--,FALSE); + if (first) { + if (is_signed) + emitcode("sra", "%s", l); + else + emitcode("srl", "%s", l); + first = 0; + } + else + emitcode("rr", "%s", l); + } + emitLabel(tlbl1->key+100); + emitcode("dec", "a"); + emit2("!shortjp nz,!tlabel", tlbl->key+100); + + freeAsmop(left,NULL,ic); + freeAsmop(result,NULL,ic); } /*-----------------------------------------------------------------*/ @@ -3291,31 +3704,39 @@ static void genGenPointerGet (operand *left, { int size, offset ; link *retype = getSpec(operandType(result)); + int pair = PAIR_HL; - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + if (IS_GB) + pair = PAIR_DE; - if (isPair(AOP(left)) && (AOP_SIZE(result)==1)) { + aopOp(left,ic,FALSE, FALSE); + aopOp(result,ic,FALSE, FALSE); + + if (isPair(AOP(left)) && AOP_SIZE(result)==1) { /* Just do it */ - emitcode("ld", "a,(%s)", getPairName(AOP(left))); - aopPut(AOP(result),"a", 0); + if (isPtrPair(AOP(left))) + { + tsprintf(buffer, "!*pair", getPairName(AOP(left))); + aopPut(AOP(result), buffer, 0); + } + else { + emit2("ld a,!*pair", getPairName(AOP(left))); + aopPut(AOP(result),"a", 0); + } freeAsmop(left,NULL,ic); goto release; } /* For now we always load into IY */ /* if this is remateriazable */ - if (AOP_TYPE(left) == AOP_IMMD) - emitcode("ld","hl,%s",aopGet(AOP(left),0,TRUE)); - else { /* we need to get it byte by byte */ - fetchHL(AOP(left)); - } + fetchPair(pair, AOP(left)); + /* so iy now contains the address */ freeAsmop(left,NULL,ic); /* if bit then unpack */ if (IS_BITVAR(retype)) { - assert(0); + wassert(0); } else { size = AOP_SIZE(result); @@ -3323,15 +3744,15 @@ static void genGenPointerGet (operand *left, while (size--) { /* PENDING: make this better */ - if (AOP(result)->type == AOP_REG) { - aopPut(AOP(result),"(hl)",offset++); + if (!IS_GB && AOP(result)->type == AOP_REG) { + aopPut(AOP(result), "!*hl", offset++); } else { - emitcode("ld", "a,(hl)", offset); + emit2("ld a,!*pair", _pairs[pair].name); aopPut(AOP(result),"a",offset++); } if (size) { - emitcode("inc", "hl"); + emit2("inc %s", _pairs[pair].name); } } } @@ -3374,39 +3795,40 @@ static void genGenPointerSet (operand *right, { int size, offset ; link *retype = getSpec(operandType(right)); + PAIR_ID pairId = PAIR_HL; + + aopOp(result,ic,FALSE, FALSE); + aopOp(right,ic,FALSE, FALSE); - aopOp(result,ic,FALSE); - aopOp(right,ic,FALSE); + if (IS_GB) + pairId = PAIR_DE; /* Handle the exceptions first */ if (isPair(AOP(result)) && (AOP_SIZE(right)==1)) { /* Just do it */ char *l = aopGet(AOP(right), 0, FALSE); - MOVA(l); - emitcode("ld", "(%s),a", getPairName(AOP(result))); - freeAsmop(result,NULL,ic); + const char *pair = getPairName(AOP(result)); + if (canAssignToPtr(l) && isPtr(pair)) { + emit2("ld !*pair,%s", pair, l); + } + else { + MOVA(l); + emit2("ld !*pair,a", pair); + } goto release; } /* if the operand is already in dptr then we do nothing else we move the value to dptr */ if (AOP_TYPE(result) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(result) == AOP_IMMD) { - emitcode("", "; Error 2"); - emitcode("ld", "hl,%s", aopGet(AOP(result), 0, TRUE)); - } - else { /* we need to get it byte by byte */ - /* PENDING: do this better */ - fetchHL(AOP(result)); - } + fetchPair(pairId, AOP(result)); } /* so hl know contains the address */ freeAsmop(result,NULL,ic); /* if bit then unpack */ if (IS_BITVAR(retype)) { - assert(0); + wassert(0); } else { size = AOP_SIZE(right); @@ -3414,16 +3836,15 @@ static void genGenPointerSet (operand *right, while (size--) { char *l = aopGet(AOP(right),offset,FALSE); - - if (isRegOrLit(AOP(right))) { - emitcode("ld", "(hl),%s", l); + if (isRegOrLit(AOP(right)) && !IS_GB) { + emit2("ld !*pair,%s", _pairs[pairId].name, l); } else { MOVA(l); - emitcode("ld", "(hl),a", offset); + emit2("ld !*pair,a", _pairs[pairId].name); } if (size) { - emitcode("inc", "hl"); + emitcode("inc", _pairs[pairId].name); } offset++; } @@ -3459,7 +3880,7 @@ static void genIfx (iCode *ic, iCode *popIc) operand *cond = IC_COND(ic); int isbit =0; - aopOp(cond,ic,FALSE); + aopOp(cond,ic,FALSE, TRUE); /* get the value into acc */ if (AOP_TYPE(cond) != AOP_CRY) @@ -3493,36 +3914,37 @@ static void genAddrOf (iCode *ic) { symbol *sym = OP_SYMBOL(IC_LEFT(ic)); - aopOp(IC_RESULT(ic),ic,FALSE); + aopOp(IC_RESULT(ic),ic,FALSE, FALSE); /* if the operand is on the stack then we need to get the stack offset of this variable */ - if (sym->onStack) { - /* if it has an offset then we need to compute it */ - if (IS_GB) { - emitcode("lda", "hl,%d+%d(sp)", sym->stack, _spoffset); + if (IS_GB) { + if (sym->onStack) { + spillCached(); + emit2("!ldahlsp", sym->stack + _G.stack.pushed + _G.stack.offset); emitcode("ld", "d,h"); emitcode("ld", "e,l"); - aopPut(AOP(IC_RESULT(ic)), "e", 0); - aopPut(AOP(IC_RESULT(ic)), "d", 1); - goto end; } else { - emitcode("push", "de"); - emitcode("push", "ix"); - emitcode("pop", "hl"); - emitcode("ld", "de,#%d", sym->stack); - emitcode("add", "hl,de"); - emitcode("pop", "de"); + emitcode("ld", "de,#%s", sym->rname); } + aopPut(AOP(IC_RESULT(ic)), "e", 0); + aopPut(AOP(IC_RESULT(ic)), "d", 1); } else { - emitcode("ld", "hl,#%s", sym->rname); + spillCached(); + if (sym->onStack) { + /* if it has an offset then we need to compute it */ + emitcode("ld", "hl,#%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset); + emitcode("add", "hl,sp"); + } + else { + emitcode("ld", "hl,#%s", sym->rname); + } + aopPut(AOP(IC_RESULT(ic)), "l", 0); + aopPut(AOP(IC_RESULT(ic)), "h", 1); } - aopPut(AOP(IC_RESULT(ic)), "l", 0); - aopPut(AOP(IC_RESULT(ic)), "h", 1); -end: freeAsmop(IC_RESULT(ic),NULL,ic); } @@ -3546,8 +3968,8 @@ static void genAssign (iCode *ic) } #endif - aopOp(right,ic,FALSE); - aopOp(result,ic,TRUE); + aopOp(right,ic,FALSE, FALSE); + aopOp(result,ic,TRUE, FALSE); /* if they are the same registers */ if (sameRegs(AOP(right),AOP(result))) { @@ -3557,7 +3979,7 @@ static void genAssign (iCode *ic) /* if the result is a bit */ if (AOP_TYPE(result) == AOP_CRY) { - assert(0); + wassert(0); } /* general case */ @@ -3566,7 +3988,10 @@ static void genAssign (iCode *ic) if(AOP_TYPE(right) == AOP_LIT) lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - if((size > 1) && + if (isPair(AOP(result)) && isLitWord(AOP(right))) { + emitcode("ld", "%s,%s", getPairName(AOP(result)), aopGetWord(AOP(right), 0)); + } + else if((size > 1) && (AOP_TYPE(result) != AOP_REG) && (AOP_TYPE(right) == AOP_LIT) && !IS_FLOAT(operandType(right)) && @@ -3586,7 +4011,7 @@ static void genAssign (iCode *ic) aopPut(AOP(result),"a",offset); } else { - aopPut(AOP(result), "#0", offset); + aopPut(AOP(result), zero, offset); } } else @@ -3595,11 +4020,24 @@ static void genAssign (iCode *ic) offset); offset++; } + } + else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result))) { + /* Special case. Load into a and d, then load out. */ + MOVA(aopGet(AOP(right), 0, FALSE)); + emitcode("ld", "e,%s", aopGet(AOP(right), 1, FALSE)); + aopPut(AOP(result), "a", 0); + aopPut(AOP(result), "e", 1); } else { while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE), - offset); + /* PENDING: do this check better */ + if (requiresHL(AOP(right)) && requiresHL(AOP(result))) { + MOVA(aopGet(AOP(right), offset, FALSE)); + aopPut(AOP(result), "a", offset); + } + else + aopPut(AOP(result), + aopGet(AOP(right),offset,FALSE), + offset); offset++; } } @@ -3617,27 +4055,28 @@ static void genJumpTab (iCode *ic) symbol *jtab; char *l; - aopOp(IC_JTCOND(ic),ic,FALSE); + aopOp(IC_JTCOND(ic),ic,FALSE, FALSE); /* get the condition into accumulator */ l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE); - MOVA(l); if (!IS_GB) emitcode("push", "de"); emitcode("ld", "e,%s", l); - emitcode("ld", "d,#0"); + emit2("ld d,!zero"); jtab = newiTempLabel(NULL); - emitcode("ld", "hl,#" LABEL_STR, jtab->key+100); + spillCached(); + emit2("ld hl,!immed!tlabel", jtab->key+100); + emitcode("add", "hl,de"); emitcode("add", "hl,de"); emitcode("add", "hl,de"); freeAsmop(IC_JTCOND(ic),NULL,ic); if (!IS_GB) emitcode("pop", "de"); - emitcode("jp", "(hl)"); - emitcode("","%05d$:",jtab->key+100); + emit2("jp !*hl"); + emitLabel(jtab->key+100); /* now generate the jump labels */ for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab; jtab = setNextItem(IC_JTLABELS(ic))) - emitcode("jp", LABEL_STR, jtab->key+100); + emit2("jp !tlabel", jtab->key+100); } /*-----------------------------------------------------------------*/ @@ -3654,12 +4093,12 @@ static void genCast (iCode *ic) if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) return ; - aopOp(right,ic,FALSE) ; - aopOp(result,ic,FALSE); + aopOp(right,ic,FALSE, FALSE); + aopOp(result,ic,FALSE, FALSE); /* if the result is a bit */ if (AOP_TYPE(result) == AOP_CRY) { - assert(0); + wassert(0); } /* if they are the same size : or less */ @@ -3685,7 +4124,7 @@ static void genCast (iCode *ic) #if 0 /* if the result is of type pointer */ if (IS_PTR(ctype)) { - assert(0); + wassert(0); } #endif @@ -3732,10 +4171,10 @@ static void genReceive (iCode *ic) if (isOperandInFarSpace(IC_RESULT(ic)) && ( OP_SYMBOL(IC_RESULT(ic))->isspilt || IS_TRUE_SYMOP(IC_RESULT(ic))) ) { - assert(0); + wassert(0); } else { accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); + aopOp(IC_RESULT(ic),ic,FALSE, FALSE); accInUse--; assignResultValue(IC_RESULT(ic)); } @@ -3760,6 +4199,7 @@ void genZ80Code (iCode *lic) _fReturn = _z80_return; _fTmp = _z80_return; } + tsprintf(zero, "!zero"); lineHead = lineCurr = NULL; @@ -3965,7 +4405,7 @@ void genZ80Code (iCode *lic) case GETHBIT: emitcode("", "; genHBIT"); - assert(0); + wassert(0); case LEFT_OP: emitcode("", "; genLeftShift");