X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fgen.c;h=f28007c9d07e43b7f25aa8b1af8166132e55956a;hb=6a1dc660c75db28421a812eb7e53e9a9d215b9ad;hp=11e5217fb3265f83b9cdfef8d18e8a23a18f5167;hpb=e11feadad9ddbb3a4a37629d283ff98f1518856d;p=fw%2Fsdcc diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 11e5217f..f28007c9 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -4,6 +4,7 @@ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) and - Jean-Louis VERN.jlvern@writeme.com (1999) Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a) + DS390 adaptation by Kevin Vigor This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -38,15 +39,19 @@ #ifdef HAVE_SYS_ISA_DEFS_H #include #else +#ifdef HAVE_MACHINE_ENDIAN_H +#include +#else #ifdef HAVE_ENDIAN_H #include #else -#if !defined(__BORLANDC__) && !defined(_MSC_VER) +#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__) #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN" #warning "If you running sdcc on an INTEL 80x86 Platform you are okay" #endif #endif #endif +#endif #define BETTER_LITERAL_SHIFT @@ -63,9 +68,15 @@ static char *spname; #define D(x) x +#define TR_DPTR(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_DPTR1 %s ", s); } +#define TR_AP(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_AP %s ", s); } + unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */ -static char *fReturn[] = +static char *fReturn24[] = {"dpl", "dph", "dpx", "b", "a"}; +static char *fReturn16[] = +{"dpl", "dph", "b", "a"}; +static char **fReturn = fReturn24; static char *accUse[] = {"a", "b"}; @@ -76,6 +87,7 @@ static struct short r0Pushed; short r1Pushed; short accInUse; + short bInUse; short inLine; short debugLine; short nRegsSaved; @@ -83,7 +95,7 @@ static struct } _G; -static void saverbank (int, iCode *, bool); +static void saveRBank (int, iCode *, bool); #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ @@ -126,7 +138,7 @@ static void emitcode (char *inst, char *fmt,...) { va_list ap; - char lb[MAX_INLINEASM]; + char lb[INITIAL_INLINEASM]; char *lbp = lb; va_start (ap, fmt); @@ -137,10 +149,10 @@ emitcode (char *inst, char *fmt,...) sprintf (lb, "%s\t", inst); else sprintf (lb, "%s", inst); - vsprintf (lb + (strlen (lb)), fmt, ap); + tvsprintf (lb + (strlen (lb)), fmt, ap); } else - vsprintf (lb, fmt, ap); + tvsprintf (lb, fmt, ap); while (isspace (*lbp)) lbp++; @@ -168,9 +180,9 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result) /* first check if r0 & r1 are used by this instruction, in which case we are in trouble */ - if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) && - (r1iu = bitVectBitValue (ic->rUsed, R1_IDX))) - { + r0iu = bitVectBitValue (ic->rUsed, R0_IDX); + r1iu = bitVectBitValue (ic->rUsed, R1_IDX); + if (r0iu && r1iu) { goto endOfWorld; } @@ -286,6 +298,7 @@ genSetDPTR (int n) } else { + TR_DPTR("#1"); emitcode ("mov", "dps, #0x01"); } } @@ -417,14 +430,20 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (_G.accInUse) emitcode ("push", "acc"); + if (_G.bInUse) + emitcode ("push", "b"); + emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", + emitcode ("add", "a,#!constbyte", ((sym->stack < 0) ? ((char) (sym->stack - _G.nRegsSaved)) : ((char) sym->stack)) & 0xff); emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name); + if (_G.bInUse) + emitcode ("pop", "b"); + if (_G.accInUse) emitcode ("pop", "acc"); } @@ -448,24 +467,35 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (_G.accInUse) emitcode ("push", "acc"); - emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", - ((sym->stack < 0) ? - ((char) (sym->stack - _G.nRegsSaved)) : - ((char) sym->stack)) & 0xff); + if (_G.bInUse) + emitcode ("push", "b"); - if (useDP2) - { - emitcode ("mov", "dpx1,#0x40"); - emitcode ("mov", "dph1,#0x00"); - emitcode ("mov", "dpl1, a"); - } - else - { - emitcode ("mov", "dpx,#0x40"); - emitcode ("mov", "dph,#0x00"); - emitcode ("mov", "dpl, a"); - } + emitcode ("mov", "a,_bpx"); + emitcode ("clr","c"); + emitcode ("subb", "a,#!constbyte", + -((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) & 0xff); + emitcode ("mov","b,a"); + emitcode ("mov","a,_bpx+1"); + emitcode ("subb","a,#!constbyte",(-((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) >> 8) & 0xff); + if (useDP2) { + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx1,#!constbyte", (options.stack_loc >> 16) & 0xff); + TR_DPTR("#2"); + emitcode ("mov", "dph1,a"); + emitcode ("mov", "dpl1,b"); + } else { + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,#!constbyte", (options.stack_loc >> 16) & 0xff); + emitcode ("mov", "dph,a"); + emitcode ("mov", "dpl,b"); + } + + if (_G.bInUse) + emitcode ("pop", "b"); if (_G.accInUse) emitcode ("pop", "acc"); @@ -496,8 +526,8 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (IS_FUNC (sym->type)) { sym->aop = aop = newAsmop (AOP_IMMD); - aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1); - strcpy (aop->aopu.aop_immd, sym->rname); + aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1); + strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname); aop->size = FPTRSIZE; return aop; } @@ -533,7 +563,7 @@ aopForRemat (symbol * sym) { iCode *ic = sym->rematiCode; asmop *aop = newAsmop (AOP_IMMD); - + int ptr_type =0; int val = 0; for (;;) @@ -542,9 +572,18 @@ aopForRemat (symbol * sym) val += (int) operandLitValue (IC_RIGHT (ic)); else if (ic->op == '-') val -= (int) operandLitValue (IC_RIGHT (ic)); - else - break; - + else if (IS_CAST_ICODE(ic)) { + sym_link *from_type = operandType(IC_RIGHT(ic)); + aop->aopu.aop_immd.from_cast_remat = 1; + ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode; + ptr_type = DCL_TYPE(from_type); + if (ptr_type == IPOINTER) { + // bug #481053 + ptr_type = POINTER; + } + continue ; + } else break; + ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; } @@ -556,8 +595,15 @@ aopForRemat (symbol * sym) else strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname); - aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1); - strcpy (aop->aopu.aop_immd, buffer); + aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1); + strcpy (aop->aopu.aop_immd.aop_immd1, buffer); + /* set immd2 field if required */ + if (aop->aopu.aop_immd.from_cast_remat) { + tsprintf(buffer,"#!constbyte",ptr_type); + aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1); + strcpy (aop->aopu.aop_immd.aop_immd2, buffer); + } + return aop; } @@ -770,7 +816,7 @@ aopOp (operand * op, iCode * ic, bool result, bool useDP2) /* a AOP_STR uses DPTR, but DPTR is already in use; * we're just hosed. */ - fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use!\n"); + fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use! for operand %s\n",sym->name); } aop = op->aop = sym->aop = newAsmop (AOP_STR); @@ -864,7 +910,7 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop) if (stk) { emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff); + emitcode ("add", "a,#!constbyte", ((char) stk) & 0xff); emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name); } else @@ -973,7 +1019,8 @@ aopGet (asmop * aop, genSetDPTR (1); if (!canClobberACC) { - emitcode ("xch", "a, %s", DP2_RESULT_REG); + TR_AP("#1"); + emitcode ("xch", "a, %s", DP2_RESULT_REG); } } @@ -1007,6 +1054,7 @@ aopGet (asmop * aop, genSetDPTR (0); if (!canClobberACC) { + TR_AP("#2"); emitcode ("xch", "a, %s", DP2_RESULT_REG); return DP2_RESULT_REG; } @@ -1014,15 +1062,30 @@ aopGet (asmop * aop, return (dname ? "acc" : "a"); case AOP_IMMD: - if (bit16) - sprintf (s, "#%s", aop->aopu.aop_immd); - else if (offset) - sprintf (s, "#(%s >> %d)", - aop->aopu.aop_immd, - offset * 8); + if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) { + sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2); + } else if (bit16) + sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1); + else if (offset) { + switch (offset) { + case 1: + tsprintf(s,"#!his",aop->aopu.aop_immd.aop_immd1); + break; + case 2: + tsprintf(s,"#!hihis",aop->aopu.aop_immd.aop_immd1); + break; + case 3: + tsprintf(s,"#!hihihis",aop->aopu.aop_immd.aop_immd1); + break; + default: /* should not need this (just in case) */ + sprintf (s, "#(%s >> %d)", + aop->aopu.aop_immd.aop_immd1, + offset * 8); + } + } else sprintf (s, "#%s", - aop->aopu.aop_immd); + aop->aopu.aop_immd.aop_immd1); rs = Safe_calloc (1, strlen (s) + 1); strcpy (rs, s); return rs; @@ -1213,7 +1276,12 @@ aopPut (asmop * aop, char *s, int offset) if (strcmp (s, "a") == 0) emitcode ("push", "acc"); else - emitcode ("push", "%s", s); + if (*s=='@') { + MOVA(s); + emitcode ("push", "acc"); + } else { + emitcode ("push", s); + } break; @@ -1241,9 +1309,9 @@ aopPut (asmop * aop, char *s, int offset) { symbol *lbl = newiTempLabel (NULL); emitcode ("clr", "c"); - emitcode ("jz", "%05d$", lbl->key + 100); + emitcode ("jz", "!tlabel", lbl->key + 100); emitcode ("cpl", "c"); - emitcode ("", "%05d$:", lbl->key + 100); + emitcode ("", "!tlabeldef", lbl->key + 100); emitcode ("mov", "%s,c", aop->aopu.aop_dir); } } @@ -1387,9 +1455,9 @@ genNotFloat (operand * op, operand * res) tlbl = newiTempLabel (NULL); aopPut (res->aop, one, 1); - emitcode ("jz", "%05d$", (tlbl->key + 100)); + emitcode ("jz", "!tlabel", (tlbl->key + 100)); aopPut (res->aop, zero, 1); - emitcode ("", "%05d$:", (tlbl->key + 100)); + emitcode ("", "!tlabeldef", (tlbl->key + 100)); size = res->aop->size - 2; offset = 2; @@ -1565,8 +1633,8 @@ genNot (iCode * ic) toBoolean (IC_LEFT (ic)); tlbl = newiTempLabel (NULL); - emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("cjne", "a,#0x01,!tlabel", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); outBitC (IC_RESULT (ic)); release: @@ -1758,14 +1826,23 @@ saveRegisters (iCode * lic) /* if the registers have been saved already then do nothing */ - if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave)) - return; - - /* find the registers in use at this time - and push them away to safety */ - rsave = bitVectCplAnd (bitVectCopy (ic->rMask), - ic->rUsed); - + if (ic->regsSaved || IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))) return ; + + /* special case if DPTR alive across a function call then must save it + even though callee saves */ + if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) { + int i =0; + rsave = newBitVect(ic->rMask->size); + for (i = DPL_IDX ; i <= B_IDX ; i++ ) { + if (bitVectBitValue(ic->rMask,i)) + rsave = bitVectSetBit(rsave,i); + } + } else { + /* find the registers in use at this time + and push them away to safety */ + rsave = bitVectCplAnd (bitVectCopy (ic->rMask), + ic->rUsed); + } ic->regsSaved = 1; if (options.useXstack) { @@ -1792,18 +1869,12 @@ saveRegisters (iCode * lic) for (i = 0; i < ds390_nRegs; i++) { if (bitVectBitValue (rsave, i)) - emitcode ("push", "%s ;jwk saveRegisters", ds390_regWithIdx (i)->dname); + emitcode ("push", "%s", ds390_regWithIdx (i)->dname); } detype = getSpec (operandType (IC_LEFT (ic))); - if (detype && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype) && - !ic->bankSaved) - - saverbank (SPEC_BANK (detype), ic, TRUE); - } + /*-----------------------------------------------------------------*/ /* unsaveRegisters - pop the pushed registers */ /*-----------------------------------------------------------------*/ @@ -1812,11 +1883,20 @@ unsaveRegisters (iCode * ic) { int i; bitVect *rsave; - /* find the registers in use at this time - and push them away to safety */ - rsave = bitVectCplAnd (bitVectCopy (ic->rMask), - ic->rUsed); + if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) { + int i =0; + rsave = newBitVect(ic->rMask->size); + for (i = DPL_IDX ; i <= B_IDX ; i++ ) { + if (bitVectBitValue(ic->rMask,i)) + rsave = bitVectSetBit(rsave,i); + } + } else { + /* find the registers in use at this time + and push them away to safety */ + rsave = bitVectCplAnd (bitVectCopy (ic->rMask), + ic->rUsed); + } if (options.useXstack) { emitcode ("mov", "r0,%s", spname); @@ -1841,7 +1921,7 @@ unsaveRegisters (iCode * ic) for (i = ds390_nRegs; i >= 0; i--) { if (bitVectBitValue (rsave, i)) - emitcode ("pop", "%s ;jwk unsaveRegisters", ds390_regWithIdx (i)->dname); + emitcode ("pop", "%s", ds390_regWithIdx (i)->dname); } } @@ -1963,7 +2043,7 @@ genIpush (iCode * ic) MOVA (l); l = "acc"; } - emitcode ("push", "%s ;jwk genIpush: !parm", l); + emitcode ("push", "%s", l); } _endLazyDPSEvaluation (); return; @@ -2000,7 +2080,7 @@ genIpush (iCode * ic) emitcode ("push", "acc"); } else - emitcode ("push", "%s ;jwk genIpush", l); + emitcode ("push", "%s", l); } _endLazyDPSEvaluation (); @@ -2029,7 +2109,7 @@ genIpop (iCode * ic) _startLazyDPSEvaluation (); while (size--) { - emitcode ("pop", "%s ;jwk genIpop", aopGet (AOP (IC_LEFT (ic)), offset--, + emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--, FALSE, TRUE, TRUE)); } _endLazyDPSEvaluation (); @@ -2038,31 +2118,42 @@ genIpop (iCode * ic) } /*-----------------------------------------------------------------*/ -/* unsaverbank - restores the resgister bank from stack */ +/* unsaveRBank - restores the resgister bank from stack */ /*-----------------------------------------------------------------*/ static void -unsaverbank (int bank, iCode * ic, bool popPsw) +unsaveRBank (int bank, iCode * ic, bool popPsw) { int i; - asmop *aop; + asmop *aop = NULL; regs *r = NULL; + if (options.useXstack) + { + if (!ic) + { + /* Assume r0 is available for use. */ + r = ds390_regWithIdx (R0_IDX);; + } + else + { + aop = newAsmop (0); + r = getFreePtr (ic, &aop, FALSE); + } + emitcode ("mov", "%s,_spx", r->name); + } + if (popPsw) { if (options.useXstack) - { - aop = newAsmop (0); - r = getFreePtr (ic, &aop, FALSE); - - - emitcode ("mov", "%s,_spx", r->name); + { emitcode ("movx", "a,@%s", r->name); emitcode ("mov", "psw,a"); emitcode ("dec", "%s", r->name); - } else + { emitcode ("pop", "psw"); + } } for (i = (ds390_nRegs - 1); i >= 0; i--) @@ -2082,30 +2173,38 @@ unsaverbank (int bank, iCode * ic, bool popPsw) if (options.useXstack) { - emitcode ("mov", "_spx,%s", r->name); - freeAsmop (NULL, aop, ic, TRUE); - } + + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } } /*-----------------------------------------------------------------*/ -/* saverbank - saves an entire register bank on the stack */ +/* saveRBank - saves an entire register bank on the stack */ /*-----------------------------------------------------------------*/ static void -saverbank (int bank, iCode * ic, bool pushPsw) +saveRBank (int bank, iCode * ic, bool pushPsw) { int i; - asmop *aop; + asmop *aop = NULL; regs *r = NULL; if (options.useXstack) { - - aop = newAsmop (0); - r = getFreePtr (ic, &aop, FALSE); - emitcode ("mov", "%s,_spx", r->name); - + if (!ic) + { + /* Assume r0 is available for use. */ + r = ds390_regWithIdx (R0_IDX);; + } + else + { + aop = newAsmop (0); + r = getFreePtr (ic, &aop, FALSE); + } + emitcode ("mov", "%s,_spx", r->name); } for (i = 0; i < ds390_nRegs; i++) @@ -2130,16 +2229,24 @@ saverbank (int bank, iCode * ic, bool pushPsw) emitcode ("movx", "@%s,a", r->name); emitcode ("inc", "%s", r->name); emitcode ("mov", "_spx,%s", r->name); - freeAsmop (NULL, aop, ic, TRUE); - } else + { emitcode ("push", "psw"); + } - emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); + emitcode ("mov", "psw,#!constbyte", (bank << 3) & 0x00ff); } - ic->bankSaved = 1; - + + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } + + if (ic) + { + ic->bankSaved = 1; + } } /*-----------------------------------------------------------------*/ @@ -2148,27 +2255,41 @@ saverbank (int bank, iCode * ic, bool pushPsw) static void genCall (iCode * ic) { - sym_link *detype; + sym_link *dtype; + bool restoreBank = FALSE; + bool swapBanks = FALSE; - D (emitcode (";", "genCall "); - ); - - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) - saveRegisters (ic); + D (emitcode (";", "genCall ");); - /* if we are calling a function that is not using + /* if we are calling a not _naked function that is not using the same register bank then we need to save the destination registers on the stack */ - detype = getSpec (operandType (IC_LEFT (ic))); - if (detype && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype) && - !ic->bankSaved) - - saverbank (SPEC_BANK (detype), ic, TRUE); - + dtype = operandType (IC_LEFT (ic)); + if (dtype && !IFFUNC_ISNAKED(dtype) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) && + IFFUNC_ISISR (currFunc->type)) + { + if (!ic->bankSaved) + { + /* This is unexpected; the bank should have been saved in + * genFunction. + */ + saveRBank (FUNC_REGBANK (dtype), ic, FALSE); + restoreBank = TRUE; + } + swapBanks = TRUE; + } + + /* if caller saves & we have not saved then */ + if (!ic->regsSaved) + saveRegisters (ic); + /* if send set is not empty the assign */ + /* We've saved all the registers we care about; + * therefore, we may clobber any register not used + * in the calling convention (i.e. anything not in + * fReturn. + */ if (_G.sendSet) { iCode *sic; @@ -2178,36 +2299,92 @@ genCall (iCode * ic) { int size, offset = 0; - aopOp (IC_LEFT (sic), sic, FALSE, TRUE); +#if 0 + aopOp (IC_LEFT (sic), sic, FALSE, FALSE); size = AOP_SIZE (IC_LEFT (sic)); _startLazyDPSEvaluation (); while (size--) { - char *l = aopGet (AOP (IC_LEFT (sic)), offset, + char *l = aopGet (AOP(IC_LEFT(sic)), offset, FALSE, FALSE, TRUE); - if (strcmp (l, fReturn[offset])) { - genSetDPTR(0); - _flushLazyDPS(); - emitcode ("mov", "%s,%s ;jwk lazy genCall", - fReturn[offset], - l); + if ((AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR) && size) + { + emitcode("mov", "%s,%s", regs390[offset].name, l); + } + else if (strcmp (l, fReturn[offset])) + { + emitcode ("mov", "%s,%s", + fReturn[offset], + l); + } + offset++; + } + _endLazyDPSEvaluation (); + if (AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR) + { + size = AOP_SIZE (IC_LEFT (sic)); + if (size) + { + size--; } + while (size) + { + size--; + emitcode("mov", "%s,%s", + fReturn[size], regs390[size].name); + } + } +#else + // we know that dpl(hxb) is the result, so + _startLazyDPSEvaluation (); + size=getSize(operandType(IC_LEFT(sic))); + if (size>1) { + aopOp (IC_LEFT (sic), sic, FALSE, + (IS_SYMOP(IC_LEFT(sic)) && OP_SYMBOL(IC_LEFT(sic))->ruonly ? FALSE : TRUE)); + } else { + aopOp (IC_LEFT (sic), sic, FALSE, FALSE); + } + while (size--) + { + char *l = aopGet (AOP (IC_LEFT (sic)), offset, + FALSE, FALSE, TRUE); + if (strcmp (l, fReturn[offset])) + { + emitcode ("mov", "%s,%s", + fReturn[offset], + l); + } offset++; } _endLazyDPSEvaluation (); +#endif freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); } _G.sendSet = NULL; - } + } + + if (swapBanks) + { + emitcode ("mov", "psw,#!constbyte", + ((FUNC_REGBANK(dtype)) << 3) & 0xff); + } + /* make the call */ emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ? OP_SYMBOL (IC_LEFT (ic))->rname : OP_SYMBOL (IC_LEFT (ic))->name)); + if (swapBanks) + { + emitcode ("mov", "psw,#!constbyte", + ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); + } + /* if we need assign a result value */ if ((IS_ITEMP (IC_RESULT (ic)) && (OP_SYMBOL (IC_RESULT (ic))->nRegs || + OP_SYMBOL (IC_RESULT (ic))->accuse || OP_SYMBOL (IC_RESULT (ic))->spildir)) || IS_TRUE_SYMOP (IC_RESULT (ic))) { @@ -2246,30 +2423,34 @@ genCall (iCode * ic) /* adjust the stack for parameters if required */ - if (ic->parmBytes) - { - int i; - if (ic->parmBytes > 3) - { - emitcode ("mov", "a,%s", spname); - emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff); - emitcode ("mov", "%s,a", spname); - } - else - for (i = 0; i < ic->parmBytes; i++) - emitcode ("dec", "%s", spname); - - } - - /* if register bank was saved then pop them */ - if (ic->bankSaved) - unsaverbank (SPEC_BANK (detype), ic, TRUE); + if (ic->parmBytes) { + if (options.stack10bit) { + emitcode ("clr","c"); + emitcode ("mov","a,sp"); + emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff); + emitcode ("mov","sp,a"); + emitcode ("mov","a,esp"); + emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff); + emitcode ("mov","esp,a"); + } else { + int i; + if (ic->parmBytes > 3) { + emitcode ("mov", "a,%s", spname); + emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff); + emitcode ("mov", "%s,a", spname); + } else + for (i = 0; i < ic->parmBytes; i++) + emitcode ("dec", "%s", spname); + } + } /* if we hade saved some registers then unsave them */ - if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave)) + if (ic->regsSaved) unsaveRegisters (ic); - + /* if register bank was saved then pop them */ + if (restoreBank) + unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE); } /*-----------------------------------------------------------------*/ @@ -2278,8 +2459,9 @@ genCall (iCode * ic) static void genPcall (iCode * ic) { - sym_link *detype; + sym_link *dtype; symbol *rlbl = newiTempLabel (NULL); + bool restoreBank=FALSE; D (emitcode (";", "genPcall "); ); @@ -2292,22 +2474,23 @@ genPcall (iCode * ic) /* if we are calling a function that is not using the same register bank then we need to save the destination registers on the stack */ - detype = getSpec (operandType (IC_LEFT (ic))); - if (detype && - IS_ISR (currFunc->etype) && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - saverbank (SPEC_BANK (detype), ic, TRUE); - + dtype = operandType (IC_LEFT (ic)); + if (dtype && !IFFUNC_ISNAKED(dtype) && + IFFUNC_ISISR (currFunc->type) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) { + saveRBank (FUNC_REGBANK (dtype), ic, TRUE); + restoreBank=TRUE; + } /* push the return address on to the stack */ - emitcode ("mov", "a,#%05d$", (rlbl->key + 100)); + emitcode ("mov", "a,#!tlabel", (rlbl->key + 100)); emitcode ("push", "acc"); - emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100)); + emitcode ("mov", "a,#!hil", (rlbl->key + 100)); emitcode ("push", "acc"); if (options.model == MODEL_FLAT24) { - emitcode ("mov", "a,#(%05d$ >> 16)", (rlbl->key + 100)); + emitcode ("mov", "a,#!hihil", (rlbl->key + 100)); emitcode ("push", "acc"); } @@ -2328,9 +2511,14 @@ genPcall (iCode * ic) { int size, offset = 0; - aopOp (IC_LEFT (sic), sic, FALSE, FALSE); - size = AOP_SIZE (IC_LEFT (sic)); + // we know that dpl(hxb) is the result, so _startLazyDPSEvaluation (); + size=getSize(operandType(IC_LEFT(sic))); + if (size>1) { + aopOp (IC_LEFT (sic), sic, FALSE, TRUE); + } else { + aopOp (IC_LEFT (sic), sic, FALSE, FALSE); + } while (size--) { char *l = aopGet (AOP (IC_LEFT (sic)), offset, @@ -2350,7 +2538,7 @@ genPcall (iCode * ic) } emitcode ("ret", ""); - emitcode ("", "%05d$:", (rlbl->key + 100)); + emitcode ("", "!tlabeldef", (rlbl->key + 100)); /* if we need assign a result value */ @@ -2377,7 +2565,7 @@ genPcall (iCode * ic) if (ic->parmBytes > 3) { emitcode ("mov", "a,%s", spname); - emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff); + emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff); emitcode ("mov", "%s,a", spname); } else @@ -2387,11 +2575,9 @@ genPcall (iCode * ic) } /* if register bank was saved then unsave them */ - if (detype && - (SPEC_BANK (currFunc->etype) != - SPEC_BANK (detype))) - unsaverbank (SPEC_BANK (detype), ic, TRUE); - + if (restoreBank) + unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE); + /* if we hade saved some registers then unsave them */ if (ic->regsSaved) @@ -2452,10 +2638,10 @@ static void genFunction (iCode * ic) { symbol *sym; - sym_link *fetype; + sym_link *ftype; + bool switchedPSW = FALSE; - D (emitcode (";", "genFunction "); - ); + D (emitcode (";", "genFunction ");); _G.nRegsSaved = 0; /* create the function header */ @@ -2464,36 +2650,46 @@ genFunction (iCode * ic) emitcode (";", "-----------------------------------------"); emitcode ("", "%s:", sym->rname); - fetype = getSpec (operandType (IC_LEFT (ic))); + ftype = operandType (IC_LEFT (ic)); + if (IFFUNC_ISNAKED(ftype)) + { + emitcode(";", "naked function: no prologue."); + return; + } + + if (options.stack_probe) + emitcode ("lcall","__stack_probe"); /* if critical function then turn interrupts off */ - if (SPEC_CRTCL (fetype)) + if (IFFUNC_ISCRITICAL (ftype)) emitcode ("clr", "ea"); /* here we need to generate the equates for the register bank if required */ - if (SPEC_BANK (fetype) != rbank) + if (FUNC_REGBANK (ftype) != rbank) { int i; - rbank = SPEC_BANK (fetype); + rbank = FUNC_REGBANK (ftype); for (i = 0; i < ds390_nRegs; i++) { - if (strcmp (regs390[i].base, "0") == 0) - emitcode ("", "%s = 0x%02x", - regs390[i].dname, - 8 * rbank + regs390[i].offset); - else - emitcode ("", "%s = %s + 0x%02x", - regs390[i].dname, - regs390[i].base, - 8 * rbank + regs390[i].offset); + if (regs390[i].print) { + if (strcmp (regs390[i].base, "0") == 0) + emitcode ("", "%s = !constbyte", + regs390[i].dname, + 8 * rbank + regs390[i].offset); + else + emitcode ("", "%s = %s + !constbyte", + regs390[i].dname, + regs390[i].base, + 8 * rbank + regs390[i].offset); + } } } /* if this is an interrupt service routine then save acc, b, dpl, dph */ - if (IS_ISR (sym->etype)) + if (IFFUNC_ISISR (sym->type)) { if (!inExcludeList ("acc")) @@ -2522,13 +2718,13 @@ genFunction (iCode * ic) /* if this isr has no bank i.e. is going to run with bank 0 , then we need to save more registers :-) */ - if (!SPEC_BANK (sym->etype)) + if (!FUNC_REGBANK (sym->type)) { /* if this function does not call any other function then we can be economical and save only those registers that are used */ - if (!sym->hasFcall) + if (!IFFUNC_HASFCALL(sym->type)) { int i; @@ -2548,17 +2744,107 @@ genFunction (iCode * ic) else { /* this function has a function call cannot - determines register usage so we will have the + determines register usage so we will have to push the entire bank */ - saverbank (0, ic, FALSE); + saveRBank (0, ic, FALSE); } } + else + { + /* This ISR uses a non-zero bank. + * + * We assume that the bank is available for our + * exclusive use. + * + * However, if this ISR calls a function which uses some + * other bank, we must save that bank entirely. + */ + unsigned long banksToSave = 0; + + if (IFFUNC_HASFCALL(sym->type)) + { + +#define MAX_REGISTER_BANKS 4 + + iCode *i; + int ix; + + for (i = ic; i; i = i->next) + { + if (i->op == ENDFUNCTION) + { + /* we got to the end OK. */ + break; + } + + if (i->op == CALL) + { + sym_link *dtype; + + dtype = operandType (IC_LEFT(i)); + if (dtype + && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type)) + { + /* Mark this bank for saving. */ + if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS) + { + werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype)); + } + else + { + banksToSave |= (1 << FUNC_REGBANK(dtype)); + } + + /* And note that we don't need to do it in + * genCall. + */ + i->bankSaved = 1; + } + } + if (i->op == PCALL) + { + /* This is a mess; we have no idea what + * register bank the called function might + * use. + * + * The only thing I can think of to do is + * throw a warning and hope. + */ + werror(W_FUNCPTR_IN_USING_ISR); + } + } + + if (banksToSave && options.useXstack) + { + /* Since we aren't passing it an ic, + * saveRBank will assume r0 is available to abuse. + * + * So switch to our (trashable) bank now, so + * the caller's R0 isn't trashed. + */ + emitcode ("push", "psw"); + emitcode ("mov", "psw,#!constbyte", + (FUNC_REGBANK (sym->type) << 3) & 0x00ff); + switchedPSW = TRUE; + } + + for (ix = 0; ix < MAX_REGISTER_BANKS; ix++) + { + if (banksToSave & (1 << ix)) + { + saveRBank(ix, NULL, FALSE); + } + } + } + // jwk: this needs a closer look + SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; + } } else { /* if callee-save to be used for this function then save the registers being used in this function */ - if (sym->calleeSave) + if (IFFUNC_CALLEESAVES(sym->type)) { int i; @@ -2580,56 +2866,67 @@ genFunction (iCode * ic) } /* set the register bank to the desired value */ - if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + if ((FUNC_REGBANK (sym->type) || FUNC_ISISR (sym->type)) + && !switchedPSW) { emitcode ("push", "psw"); - emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff); - } - - if (IS_RENT (sym->etype) || options.stackAuto) - { - - if (options.useXstack) - { - emitcode ("mov", "r0,%s", spname); - emitcode ("mov", "a,_bp"); - emitcode ("movx", "@r0,a"); - emitcode ("inc", "%s", spname); - } - else - { - /* set up the stack */ - emitcode ("push", "_bp"); /* save the callers stack */ - } - emitcode ("mov", "_bp,%s", spname); - } + emitcode ("mov", "psw,#!constbyte", (FUNC_REGBANK (sym->type) << 3) & 0x00ff); + } + + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { + if (options.stack10bit) { + emitcode ("push","_bpx"); + emitcode ("push","_bpx+1"); + emitcode ("mov","_bpx,%s",spname); + emitcode ("mov","_bpx+1,esp"); + emitcode ("anl","_bpx+1,#3"); + } else { + if (options.useXstack) { + emitcode ("mov", "r0,%s", spname); + emitcode ("mov", "a,_bp"); + emitcode ("movx", "@r0,a"); + emitcode ("inc", "%s", spname); + } else { + /* set up the stack */ + emitcode ("push", "_bp"); /* save the callers stack */ + } + emitcode ("mov", "_bp,%s", spname); + } + } /* adjust the stack for the function */ - if (sym->stack) - { - + if (sym->stack) { int i = sym->stack; - if (i > 256) - werror (W_STACK_OVERFLOW, sym->name); - - if (i > 3 && sym->recvSize < 4) - { - - emitcode ("mov", "a,sp"); - emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); - emitcode ("mov", "sp,a"); - - } - else - while (i--) - emitcode ("inc", "sp"); - } + if (options.stack10bit) { + if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name); + assert (sym->recvSize <= 4); + emitcode ("mov","a,sp"); + emitcode ("add","a,#!constbyte", ((short) sym->stack & 0xff)); + emitcode ("mov","sp,a"); + emitcode ("mov","a,esp"); + emitcode ("addc","a,#!constbyte", (((short) sym->stack) >> 8) & 0xff); + emitcode ("mov","esp,a"); + } else { + if (i > 256) + werror (W_STACK_OVERFLOW, sym->name); + + if (i > 3 && sym->recvSize < 4) { + + emitcode ("mov", "a,sp"); + emitcode ("add", "a,#!constbyte", ((char) sym->stack & 0xff)); + emitcode ("mov", "sp,a"); + + } else + while (i--) + emitcode ("inc", "sp"); + } + } if (sym->xstack) { emitcode ("mov", "a,_spx"); - emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff)); + emitcode ("add", "a,#!constbyte", ((char) sym->xstack & 0xff)); emitcode ("mov", "_spx,a"); } @@ -2643,58 +2940,75 @@ genEndFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); - D (emitcode (";", "genEndFunction "); - ); + D (emitcode (";", "genEndFunction ");); - if (IS_RENT (sym->etype) || options.stackAuto) - { - emitcode ("mov", "%s,_bp", spname); - } + if (IFFUNC_ISNAKED(sym->type)) + { + emitcode(";", "naked function: no epilogue."); + return; + } + + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { + if (options.stack10bit) { + emitcode ("mov", "sp,_bpx", spname); + emitcode ("mov", "esp,_bpx+1", spname); + } else { + emitcode ("mov", "%s,_bp", spname); + } + } /* if use external stack but some variables were added to the local stack then decrement the local stack */ - if (options.useXstack && sym->stack) - { + if (options.useXstack && sym->stack) { emitcode ("mov", "a,sp"); - emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff); + emitcode ("add", "a,#!constbyte", ((char) -sym->stack) & 0xff); emitcode ("mov", "sp,a"); - } + } - if ((IS_RENT (sym->etype) || options.stackAuto)) - { - if (options.useXstack) - { + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) { + if (options.useXstack) { emitcode ("mov", "r0,%s", spname); emitcode ("movx", "a,@r0"); emitcode ("mov", "_bp,a"); emitcode ("dec", "%s", spname); - } - else - { - emitcode ("pop", "_bp"); - } - } + } else { + if (options.stack10bit) { + emitcode ("pop", "_bpx+1"); + emitcode ("pop", "_bpx"); + } else { + emitcode ("pop", "_bp"); + } + } + } /* restore the register bank */ - if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) - emitcode ("pop", "psw"); + if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type)) + { + if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type) + || !options.useXstack) + { + /* Special case of ISR using non-zero bank with useXstack + * is handled below. + */ + emitcode ("pop", "psw"); + } + } - if (IS_ISR (sym->etype)) + if (IFFUNC_ISISR (sym->type)) { /* now we need to restore the registers */ /* if this isr has no bank i.e. is going to run with bank 0 , then we need to save more registers :-) */ - if (!SPEC_BANK (sym->etype)) + if (!FUNC_REGBANK (sym->type)) { - /* if this function does not call any other function then we can be economical and save only those registers that are used */ - if (!sym->hasFcall) + if (!IFFUNC_HASFCALL(sym->type)) { int i; @@ -2714,9 +3028,36 @@ genEndFunction (iCode * ic) else { /* this function has a function call cannot - determines register usage so we will have the + determines register usage so we will have to pop the entire bank */ - unsaverbank (0, ic, FALSE); + unsaveRBank (0, ic, FALSE); + } + } + else + { + /* This ISR uses a non-zero bank. + * + * Restore any register banks saved by genFunction + * in reverse order. + */ + // jwk: this needs a closer look + unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype); + int ix; + + for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--) + { + if (savedBanks & (1 << ix)) + { + unsaveRBank(ix, NULL, FALSE); + } + } + + if (options.useXstack) + { + /* Restore bank AFTER calling unsaveRBank, + * since it can trash r0. + */ + emitcode ("pop", "psw"); } } @@ -2741,13 +3082,11 @@ genEndFunction (iCode * ic) if (!inExcludeList ("acc")) emitcode ("pop", "acc"); - if (SPEC_CRTCL (sym->etype)) + if (IFFUNC_ISCRITICAL (sym->type)) emitcode ("setb", "ea"); /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) - { + if (options.debug && currFunc) { _G.debugLine = 1; emitcode ("", "C$%s$%d$%d$%d ==.", FileBaseName (ic->filename), currFunc->lastLine, @@ -2763,10 +3102,10 @@ genEndFunction (iCode * ic) } else { - if (SPEC_CRTCL (sym->etype)) + if (IFFUNC_ISCRITICAL (sym->type)) emitcode ("setb", "ea"); - if (sym->calleeSave) + if (IFFUNC_CALLEESAVES(sym->type)) { int i; @@ -2785,7 +3124,7 @@ genEndFunction (iCode * ic) } /* if debug then send end of function */ - if (currFunc) + if (options.debug && currFunc) { _G.debugLine = 1; emitcode ("", "C$%s$%d$%d$%d ==.", @@ -2821,7 +3160,8 @@ genRet (iCode * ic) /* we have something to return then move the return value into place */ - aopOp (IC_LEFT (ic), ic, FALSE, TRUE); + aopOp (IC_LEFT (ic), ic, FALSE, + (IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly ? FALSE :TRUE)); size = AOP_SIZE (IC_LEFT (ic)); _startLazyDPSEvaluation (); @@ -2837,8 +3177,11 @@ genRet (iCode * ic) } else { + /* Since A is the last element of fReturn, + * is is OK to clobber it in the aopGet. + */ l = aopGet (AOP (IC_LEFT (ic)), offset, - FALSE, FALSE, FALSE); + FALSE, FALSE, TRUE); if (strcmp (fReturn[offset], l)) emitcode ("mov", "%s,%s", fReturn[offset++], l); } @@ -2864,7 +3207,7 @@ jumpret: if (!(ic->next && ic->next->op == LABEL && IC_LABEL (ic->next) == returnLabel)) - emitcode ("ljmp", "%05d$", (returnLabel->key + 100)); + emitcode ("ljmp", "!tlabel", (returnLabel->key + 100)); } @@ -2881,7 +3224,7 @@ genLabel (iCode * ic) D (emitcode (";", "genLabel "); ); - emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100)); + emitcode ("", "!tlabeldef", (IC_LABEL (ic)->key + 100)); } /*-----------------------------------------------------------------*/ @@ -2892,7 +3235,7 @@ genGoto (iCode * ic) { D (emitcode (";", "genGoto "); ); - emitcode ("ljmp", "%05d$", (IC_LABEL (ic)->key + 100)); + emitcode ("ljmp", "!tlabel", (IC_LABEL (ic)->key + 100)); } /*-----------------------------------------------------------------*/ @@ -2973,13 +3316,13 @@ genPlusIncr (iCode * ic) emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)); if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0x00,%05d$" + emitcode ("cjne", "%s,#0x00,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE) ,tlbl->key + 100); else { emitcode ("clr", "a"); - emitcode ("cjne", "a,%s,%05d$" + emitcode ("cjne", "a,%s,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE) ,tlbl->key + 100); } @@ -2989,11 +3332,11 @@ genPlusIncr (iCode * ic) { if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0x00,%05d$" + emitcode ("cjne", "%s,#0x00,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE) ,tlbl->key + 100); else - emitcode ("cjne", "a,%s,%05d$" + emitcode ("cjne", "a,%s,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE) ,tlbl->key + 100); @@ -3003,12 +3346,12 @@ genPlusIncr (iCode * ic) { if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0x00,%05d$" + emitcode ("cjne", "%s,#0x00,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE) ,tlbl->key + 100); else { - emitcode ("cjne", "a,%s,%05d$" + emitcode ("cjne", "a,%s,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE) ,tlbl->key + 100); } @@ -3017,7 +3360,7 @@ genPlusIncr (iCode * ic) if (emitTlbl) { - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } return TRUE; } @@ -3039,7 +3382,7 @@ genPlusIncr (iCode * ic) if (icount > 3) { MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, TRUE)); - emitcode ("add", "a,#0x%02x", ((char) icount) & 0xff); + emitcode ("add", "a,#!constbyte", ((char) icount) & 0xff); aopPut (AOP (IC_RESULT (ic)), "a", 0); } else @@ -3073,9 +3416,9 @@ outBitAcc (operand * result) } else { - emitcode ("jz", "%05d$", tlbl->key + 100); + emitcode ("jz", "!tlabel", tlbl->key + 100); emitcode ("mov", "a,%s", one); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); outAcc (result); } } @@ -3092,9 +3435,9 @@ genPlusBits (iCode * ic) { symbol *lbl = newiTempLabel (NULL); emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir); - emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100)); + emitcode ("jnb", "%s,!tlabel", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100)); emitcode ("cpl", "c"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); outBitC (IC_RESULT (ic)); } else @@ -3141,6 +3484,8 @@ adjustArithmeticResult (iCode * ic) } } +#if 0 // AOP_OP_3 is deprecated; nobody likes Ack errors. + // Please don't bring it back without a really good reason. // Macro to aopOp all three operands of an ic. Will fatal if this cannot be done // (because all three operands are in far space). #define AOP_OP_3(ic) \ @@ -3155,6 +3500,7 @@ adjustArithmeticResult (iCode * ic) fprintf(stderr, \ "Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno); \ } +#endif // Macro to aopOp all three operands of an ic. If this cannot be done, // the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter @@ -3162,9 +3508,10 @@ adjustArithmeticResult (iCode * ic) // that the IC_RESULT operand is not aopOp'd. #define AOP_OP_3_NOFATAL(ic, rc) \ aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \ - aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \ + aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || \ + (OP_SYMBOL(IC_RESULT(ic))->ruonly)); \ if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \ - isOperandInFarSpace(IC_RESULT(ic))) \ + (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \ { \ /* No can do; DPTR & DPTR2 in use, and we need another. */ \ rc = TRUE; \ @@ -3238,7 +3585,34 @@ genPlus (iCode * ic) D (emitcode (";", "genPlus ");); /* special cases :- */ - + if ( IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly && + isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) { + aopOp (IC_RIGHT (ic), ic, TRUE, FALSE); + size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit); + if (size <= 9) { + while (size--) emitcode ("inc","dptr"); + } else { + emitcode ("mov","a,dpl"); + emitcode ("add","a,#!constbyte",size & 0xff); + emitcode ("mov","dpl,a"); + emitcode ("mov","a,dph"); + emitcode ("addc","a,#!constbyte",(size >> 8) & 0xff); + emitcode ("mov","dph,a"); + emitcode ("mov","a,dpx"); + emitcode ("addc","a,#!constbyte",(size >> 16) & 0xff); + emitcode ("mov","dpx,a"); + } + freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE); + return ; + } + if ( IS_SYMOP(IC_LEFT(ic)) && + OP_SYMBOL(IC_LEFT(ic))->remat && + isOperandInFarSpace(IC_RIGHT(ic))) { + operand *op = IC_RIGHT(ic); + IC_RIGHT(ic) = IC_LEFT(ic); + IC_LEFT(ic) = op; + } + AOP_OP_3_NOFATAL (ic, pushResult); if (pushResult) { @@ -3310,7 +3684,7 @@ genPlus (iCode * ic) _startLazyDPSEvaluation (); while (size--) { - if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC) + if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && !AOP_NEEDSACC(IC_RIGHT(ic))) { MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE)); if (offset == 0) @@ -3322,13 +3696,35 @@ genPlus (iCode * ic) } else { + if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && (offset == 0)) + { + /* right is going to use ACC or we would have taken the + * above branch. + */ + assert(AOP_NEEDSACC(IC_RIGHT(ic))); + TR_AP("#3"); + D(emitcode(";", "+ AOP_ACC special case.");); + emitcode("xch", "a, %s", DP2_RESULT_REG); + } MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE)); if (offset == 0) - emitcode ("add", "a,%s", - aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE)); + { + if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) + { + TR_AP("#4"); + emitcode("add", "a, %s", DP2_RESULT_REG); + } + else + { + emitcode ("add", "a,%s", + aopGet (AOP(IC_LEFT(ic)), offset, FALSE, FALSE, FALSE)); + } + } else + { emitcode ("addc", "a,%s", aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE)); + } } if (!pushResult) { @@ -3421,13 +3817,13 @@ genMinusDec (iCode * ic) if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0xff,%05d$" + emitcode ("cjne", "%s,#0xff,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE) ,tlbl->key + 100); else { emitcode ("mov", "a,#0xff"); - emitcode ("cjne", "a,%s,%05d$" + emitcode ("cjne", "a,%s,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE) ,tlbl->key + 100); } @@ -3437,12 +3833,12 @@ genMinusDec (iCode * ic) if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0xff,%05d$" + emitcode ("cjne", "%s,#0xff,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE) ,tlbl->key + 100); else { - emitcode ("cjne", "a,%s,%05d$" + emitcode ("cjne", "a,%s,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE) ,tlbl->key + 100); } @@ -3453,12 +3849,12 @@ genMinusDec (iCode * ic) if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0xff,%05d$" + emitcode ("cjne", "%s,#0xff,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE) ,tlbl->key + 100); else { - emitcode ("cjne", "a,%s,%05d$" + emitcode ("cjne", "a,%s,!tlabel" ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE) ,tlbl->key + 100); } @@ -3466,7 +3862,7 @@ genMinusDec (iCode * ic) } if (emitTlbl) { - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } return TRUE; } @@ -3541,18 +3937,18 @@ genMinusBits (iCode * ic) if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir); - emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100)); + emitcode ("jnb", "%s,!tlabel", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100)); emitcode ("cpl", "c"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); outBitC (IC_RESULT (ic)); } else { emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir); emitcode ("subb", "a,acc"); - emitcode ("jnb", "%s,%05d$", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100)); + emitcode ("jnb", "%s,!tlabel", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100)); emitcode ("inc", "a"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); aopPut (AOP (IC_RESULT (ic)), "a", 0); addSign (IC_RESULT (ic), MSB16, SPEC_USIGN (getSpec (operandType (IC_RESULT (ic))))); } @@ -3622,12 +4018,17 @@ genMinus (iCode * ic) else { /* first add without previous c */ - if (!offset) - emitcode ("add", "a,#0x%02x", - (unsigned int) (lit & 0x0FFL)); - else - emitcode ("addc", "a,#0x%02x", + if (!offset) { + if (!size && lit==-1) { + emitcode ("dec", "a"); + } else { + emitcode ("add", "a,#!constbyte", + (unsigned int) (lit & 0x0FFL)); + } + } else { + emitcode ("addc", "a,#!constbyte", (unsigned int) ((lit >> (offset * 8)) & 0x0FFL)); + } } if (pushResult) @@ -3675,10 +4076,12 @@ release: static void genMultbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir); emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir); + aopOp(result, ic, TRUE, FALSE); outBitC (result); } @@ -3689,19 +4092,12 @@ genMultbits (operand * left, static void genMultOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); symbol *lbl; - int size=AOP_SIZE(result); - emitcode (";",__FUNCTION__); - if (size<1 || size>2) { - // this should never happen - fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", - AOP_SIZE(result), __FUNCTION__, lineno); - exit (1); - } /* (if two literals: the value is computed before) */ /* if one literal, literal on the right */ @@ -3722,8 +4118,22 @@ genMultOneByte (operand * left, emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE)); MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); emitcode ("mul", "ab"); + + _G.accInUse++; _G.bInUse++; + aopOp(result, ic, TRUE, FALSE); + + if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) + { + // this should never happen + fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", + AOP_SIZE(result), __FILE__, lineno); + exit (1); + } + aopPut (AOP (result), "a", 0); - if (size==2) { + _G.accInUse--; _G.bInUse--; + if (AOP_SIZE(result)==2) + { aopPut (AOP (result), "b", 1); } return; @@ -3733,44 +4143,56 @@ genMultOneByte (operand * left, emitcode (";", "signed"); emitcode ("clr", "F0"); // reset sign flag - emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE)); MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); lbl=newiTempLabel(NULL); - emitcode ("jnb", "acc.7,%05d$", lbl->key+100); + emitcode ("jnb", "acc.7,!tlabel", lbl->key+100); // left side is negative, 8-bit two's complement, this fails for -128 emitcode ("setb", "F0"); // set sign flag emitcode ("cpl", "a"); emitcode ("inc", "a"); - emitcode ("", "%05d$:", lbl->key+100); - emitcode ("xch", "a,b"); + emitcode ("", "!tlabeldef", lbl->key+100); /* if literal */ if (AOP_TYPE(right)==AOP_LIT) { + signed char val=floatFromVal (AOP (right)->aopu.aop_lit); /* AND literal negative */ - if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) { - // two's complement for literal<0 - emitcode ("xrl", "PSW,#0x20"); // xrl sign flag - emitcode ("cpl", "a"); - emitcode ("inc", "a"); + if ((int) val < 0) { + emitcode ("cpl", "F0"); // complement sign flag + emitcode ("mov", "b,#!constbyte", -val); + } else { + emitcode ("mov", "b,#!constbyte", val); } } else { lbl=newiTempLabel(NULL); - emitcode ("jnb", "acc.7,%05d$", lbl->key+100); + emitcode ("mov", "b,a"); + emitcode ("mov", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE)); + emitcode ("jnb", "acc.7,!tlabel", lbl->key+100); // right side is negative, 8-bit two's complement - emitcode ("xrl", "PSW,#0x20"); // xrl sign flag + emitcode ("cpl", "F0"); // complement sign flag emitcode ("cpl", "a"); emitcode ("inc", "a"); - emitcode ("", "%05d$:", lbl->key+100); + emitcode ("", "!tlabeldef", lbl->key+100); } emitcode ("mul", "ab"); + _G.accInUse++;_G.bInUse++; + aopOp(result, ic, TRUE, FALSE); + + if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) + { + // this should never happen + fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", + AOP_SIZE(result), __FILE__, lineno); + exit (1); + } + lbl=newiTempLabel(NULL); - emitcode ("jnb", "F0,%05d$", lbl->key+100); + emitcode ("jnb", "F0,!tlabel", lbl->key+100); // only ONE op was negative, we have to do a 8/16-bit two's complement emitcode ("cpl", "a"); // lsb - if (size==1) { + if (AOP_SIZE(result)==1) { emitcode ("inc", "a"); } else { emitcode ("add", "a,#1"); @@ -3780,11 +4202,172 @@ genMultOneByte (operand * left, emitcode ("xch", "a,b"); } - emitcode ("", "%05d$:", lbl->key+100); - aopPut (AOP (result), "a", 0); - if (size==2) { - aopPut (AOP (result), "b", 1); - } + emitcode ("", "!tlabeldef", lbl->key+100); + aopPut (AOP (result), "a", 0); + _G.accInUse--;_G.bInUse--; + if (AOP_SIZE(result)==2) { + aopPut (AOP (result), "b", 1); + } +} + +/*-----------------------------------------------------------------*/ +/* genMultTwoByte - use the DS390 MAC unit to do 16*16 multiply */ +/*-----------------------------------------------------------------*/ +static void genMultTwoByte (operand *left, operand *right, + operand *result, iCode *ic) +{ + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(operandType(left)); + int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype); + symbol *lbl; + + if (AOP_TYPE (left) == AOP_LIT) { + operand *t = right; + right = left; + left = t; + } + /* save EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("setb","F1"); + emitcode ("jbc","EA,!tlabel",lbl->key+100); + emitcode ("clr","F1"); + emitcode("","!tlabeldef",lbl->key+100); + + /* load up MB with right */ + if (!umult) { + emitcode("clr","F0"); + if (AOP_TYPE(right) == AOP_LIT) { + int val=floatFromVal (AOP (right)->aopu.aop_lit); + if (val < 0) { + emitcode("setb","F0"); + val = -val; + } + emitcode ("mov","mb,#!constbyte",val & 0xff); + emitcode ("mov","mb,#!constbyte",(val >> 8) & 0xff); + } else { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,!tlabel",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("setb","F0"); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("mov","mb,b"); + emitcode ("mov","mb,a"); + } + } else { + emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + } + /* load up MA with left */ + if (!umult) { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,!tlabel",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc","a,#0"); + emitcode ("jbc","F0,!tlabel",lbl->key+100); + emitcode ("setb","F0"); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("mov","ma,b"); + emitcode ("mov","ma,a"); + } else { + emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + } + /* wait for multiplication to finish */ + lbl = newiTempLabel(NULL); + emitcode("","!tlabeldef", lbl->key+100); + emitcode("mov","a,mcnt1"); + emitcode("anl","a,#0x80"); + emitcode("jnz","!tlabel",lbl->key+100); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (right, NULL, ic,TRUE); + aopOp(result, ic, TRUE, FALSE); + + /* if unsigned then simple */ + if (umult) { + emitcode ("mov","a,ma"); + if (AOP_SIZE(result) >= 4) aopPut(AOP(result),"a",3); + emitcode ("mov","a,ma"); + if (AOP_SIZE(result) >= 3) aopPut(AOP(result),"a",2); + aopPut(AOP(result),"ma",1); + aopPut(AOP(result),"ma",0); + } else { + emitcode("push","ma"); + emitcode("push","ma"); + emitcode("push","ma"); + MOVA("ma"); + /* negate result if needed */ + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,!tlabel",lbl->key+100); + emitcode("cpl","a"); + emitcode("add","a,#1"); + emitcode("","!tlabeldef", lbl->key+100); + if (AOP_TYPE(result) == AOP_ACC) + { + D(emitcode(";", "ACC special case.");); + /* We know result is the only live aop, and + * it's obviously not a DPTR2, so AP is available. + */ + emitcode("mov", "%s,acc", DP2_RESULT_REG); + } + else + { + aopPut(AOP(result),"a",0); + } + + emitcode("pop","acc"); + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,!tlabel",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","!tlabeldef", lbl->key+100); + aopPut(AOP(result),"a",1); + emitcode("pop","acc"); + if (AOP_SIZE(result) >= 3) { + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,!tlabel",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","!tlabeldef", lbl->key+100); + aopPut(AOP(result),"a",2); + } + emitcode("pop","acc"); + if (AOP_SIZE(result) >= 4) { + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,!tlabel",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","!tlabeldef", lbl->key+100); + aopPut(AOP(result),"a",3); + } + if (AOP_TYPE(result) == AOP_ACC) + { + /* We stashed the result away above. */ + emitcode("mov", "acc,%s", DP2_RESULT_REG); + } + + } + freeAsmop (result, NULL, ic, TRUE); + + /* restore EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("jnb","F1,!tlabel",lbl->key+100); + emitcode ("setb","EA"); + emitcode("","!tlabeldef",lbl->key+100); + return ; } /*-----------------------------------------------------------------*/ @@ -3800,14 +4383,14 @@ genMult (iCode * ic) D (emitcode (";", "genMult ");); /* assign the amsops */ - AOP_OP_3 (ic); + AOP_OP_2 (ic); /* special cases first */ /* both are bits */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { - genMultbits (left, right, result); + genMultbits (left, right, result, ic); goto release; } @@ -3815,12 +4398,17 @@ genMult (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genMultOneByte (left, right, result); + genMultOneByte (left, right, result, ic); goto release; } + if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) { + /* use the ds390 ARITHMETIC accel UNIT */ + genMultTwoByte (left, right, result, ic); + return ; + } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -3834,7 +4422,8 @@ release: static void genDivbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { char *l; @@ -3843,6 +4432,8 @@ genDivbits (operand * left, LOAD_AB_FOR_DIV (left, right, l); emitcode ("div", "ab"); emitcode ("rrc", "a"); + aopOp(result, ic, TRUE, FALSE); + aopPut (AOP (result), "c", 0); } @@ -3852,24 +4443,33 @@ genDivbits (operand * left, static void genDivOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); char *l; symbol *lbl; int size, offset; - size = AOP_SIZE (result) - 1; offset = 1; /* signed or unsigned */ if (SPEC_USIGN (opetype)) { - /* unsigned is easy */ - LOAD_AB_FOR_DIV (left, right, l); - emitcode ("div", "ab"); - aopPut (AOP (result), "a", 0); - while (size--) - aopPut (AOP (result), zero, offset++); + /* unsigned is easy */ + LOAD_AB_FOR_DIV (left, right, l); + emitcode ("div", "ab"); + + _G.accInUse++; + aopOp(result, ic, TRUE, FALSE); + aopPut (AOP (result), "a", 0); + _G.accInUse--; + + size = AOP_SIZE (result) - 1; + + while (size--) + { + aopPut (AOP (result), zero, offset++); + } return; } @@ -3885,10 +4485,10 @@ genDivOneByte (operand * left, l = aopGet (AOP (right), 0, FALSE, FALSE, TRUE); MOVA (l); lbl = newiTempLabel (NULL); - emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100)); + emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100)); emitcode ("cpl", "a"); emitcode ("inc", "a"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); emitcode ("mov", "b,a"); /* sign adjust left side */ @@ -3896,10 +4496,10 @@ genDivOneByte (operand * left, MOVA (l); lbl = newiTempLabel (NULL); - emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100)); + emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100)); emitcode ("cpl", "a"); emitcode ("inc", "a"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); /* now the division */ emitcode ("nop", "; workaround for DS80C390 div bug."); @@ -3911,24 +4511,150 @@ genDivOneByte (operand * left, emitcode ("pop", "acc"); /* if there was an over flow we don't adjust the sign of the result */ - emitcode ("jb", "ov,%05d$", (lbl->key + 100)); - emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100)); + emitcode ("jb", "ov,!tlabel", (lbl->key + 100)); + emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100)); CLRC; emitcode ("clr", "a"); emitcode ("subb", "a,b"); emitcode ("mov", "b,a"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); /* now we are done */ - aopPut (AOP (result), "b", 0); - if (size > 0) + _G.accInUse++; _G.bInUse++; + aopOp(result, ic, TRUE, FALSE); + + aopPut (AOP (result), "b", 0); + + size = AOP_SIZE (result) - 1; + + if (size > 0) { emitcode ("mov", "c,b.7"); emitcode ("subb", "a,acc"); } - while (size--) - aopPut (AOP (result), "a", offset++); - + while (size--) + { + aopPut (AOP (result), "a", offset++); + } + _G.accInUse--; _G.bInUse--; + +} + +/*-----------------------------------------------------------------*/ +/* genDivTwoByte - use the DS390 MAC unit to do 16/16 divide */ +/*-----------------------------------------------------------------*/ +static void genDivTwoByte (operand *left, operand *right, + operand *result, iCode *ic) +{ + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(operandType(left)); + int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype); + symbol *lbl; + + /* save EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("setb","F1"); + emitcode ("jbc","EA,!tlabel",lbl->key+100); + emitcode ("clr","F1"); + emitcode("","!tlabeldef",lbl->key+100); + + /* load up MA with left */ + if (!umult) { + emitcode("clr","F0"); + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,!tlabel",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc","a,#0"); + emitcode ("setb","F0"); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("mov","ma,b"); + emitcode ("mov","ma,a"); + } else { + emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + } + + /* load up MB with right */ + if (!umult) { + if (AOP_TYPE(right) == AOP_LIT) { + int val=floatFromVal (AOP (right)->aopu.aop_lit); + if (val < 0) { + lbl = newiTempLabel(NULL); + emitcode ("jbc","F0,!tlabel",lbl->key+100); + emitcode("setb","F0"); + emitcode ("","!tlabeldef",lbl->key+100); + val = -val; + } + emitcode ("mov","mb,#!constbyte",val & 0xff); + emitcode ("mov","mb,#!constbyte",(val >> 8) & 0xff); + } else { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,!tlabel",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("jbc","F0,!tlabel",lbl->key+100); + emitcode ("setb","F0"); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("mov","mb,b"); + emitcode ("mov","mb,a"); + } + } else { + emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + } + + /* wait for multiplication to finish */ + lbl = newiTempLabel(NULL); + emitcode("","!tlabeldef", lbl->key+100); + emitcode("mov","a,mcnt1"); + emitcode("anl","a,#0x80"); + emitcode("jnz","!tlabel",lbl->key+100); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (right, NULL, ic,TRUE); + aopOp(result, ic, TRUE, FALSE); + + /* if unsigned then simple */ + if (umult) { + aopPut(AOP(result),"ma",1); + aopPut(AOP(result),"ma",0); + } else { + emitcode("push","ma"); + MOVA("ma"); + /* negate result if needed */ + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,!tlabel",lbl->key+100); + emitcode("cpl","a"); + emitcode("add","a,#1"); + emitcode("","!tlabeldef", lbl->key+100); + aopPut(AOP(result),"a",0); + emitcode("pop","acc"); + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,!tlabel",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","!tlabeldef", lbl->key+100); + aopPut(AOP(result),"a",1); + } + freeAsmop (result, NULL, ic, TRUE); + /* restore EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("jnb","F1,!tlabel",lbl->key+100); + emitcode ("setb","EA"); + emitcode("","!tlabeldef",lbl->key+100); + return ; } /*-----------------------------------------------------------------*/ @@ -3941,18 +4667,17 @@ genDiv (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); - D (emitcode (";", "genDiv "); - ); + D (emitcode (";", "genDiv ");); /* assign the amsops */ - AOP_OP_3 (ic); + AOP_OP_2 (ic); /* special cases first */ /* both are bits */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { - genDivbits (left, right, result); + genDivbits (left, right, result, ic); goto release; } @@ -3960,12 +4685,17 @@ genDiv (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genDivOneByte (left, right, result); + genDivOneByte (left, right, result, ic); goto release; } + if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) { + /* use the ds390 ARITHMETIC accel UNIT */ + genDivTwoByte (left, right, result, ic); + return ; + } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -3978,7 +4708,8 @@ release: static void genModbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { char *l; @@ -3988,6 +4719,7 @@ genModbits (operand * left, emitcode ("div", "ab"); emitcode ("mov", "a,b"); emitcode ("rrc", "a"); + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "c", 0); } @@ -3997,7 +4729,8 @@ genModbits (operand * left, static void genModOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); char *l; @@ -4009,6 +4742,7 @@ genModOneByte (operand * left, /* unsigned is easy */ LOAD_AB_FOR_DIV (left, right, l); emitcode ("div", "ab"); + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "b", 0); return; } @@ -4027,10 +4761,10 @@ genModOneByte (operand * left, MOVA (l); lbl = newiTempLabel (NULL); - emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100)); + emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100)); emitcode ("cpl", "a"); emitcode ("inc", "a"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); emitcode ("mov", "b,a"); /* sign adjust left side */ @@ -4038,10 +4772,10 @@ genModOneByte (operand * left, MOVA (l); lbl = newiTempLabel (NULL); - emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100)); + emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100)); emitcode ("cpl", "a"); emitcode ("inc", "a"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); /* now the multiplication */ emitcode ("nop", "; workaround for DS80C390 div bug."); @@ -4052,17 +4786,110 @@ genModOneByte (operand * left, emitcode ("pop", "acc"); /* if there was an over flow we don't adjust the sign of the result */ - emitcode ("jb", "ov,%05d$", (lbl->key + 100)); - emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100)); + emitcode ("jb", "ov,!tlabel", (lbl->key + 100)); + emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100)); CLRC; emitcode ("clr", "a"); emitcode ("subb", "a,b"); emitcode ("mov", "b,a"); - emitcode ("", "%05d$:", (lbl->key + 100)); - + emitcode ("", "!tlabeldef", (lbl->key + 100)); + + _G.bInUse++; /* now we are done */ + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "b", 0); + _G.bInUse--; + +} + +/*-----------------------------------------------------------------*/ +/* genModTwoByte - use the DS390 MAC unit to do 16%16 modulus */ +/*-----------------------------------------------------------------*/ +static void genModTwoByte (operand *left, operand *right, + operand *result, iCode *ic) +{ + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(operandType(left)); + int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype); + symbol *lbl; + + /* load up MA with left */ + /* save EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("setb","F1"); + emitcode ("jbc","EA,!tlabel",lbl->key+100); + emitcode ("clr","F1"); + emitcode("","!tlabeldef",lbl->key+100); + + if (!umult) { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,!tlabel",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc","a,#0"); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("mov","ma,b"); + emitcode ("mov","ma,a"); + } else { + emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + } + + /* load up MB with right */ + if (!umult) { + if (AOP_TYPE(right) == AOP_LIT) { + int val=floatFromVal (AOP (right)->aopu.aop_lit); + if (val < 0) { + val = -val; + } + emitcode ("mov","mb,#!constbyte",val & 0xff); + emitcode ("mov","mb,#!constbyte",(val >> 8) & 0xff); + } else { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,!tlabel",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("mov","mb,b"); + emitcode ("mov","mb,a"); + } + } else { + emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + } + /* wait for multiplication to finish */ + lbl = newiTempLabel(NULL); + emitcode("","!tlabeldef", lbl->key+100); + emitcode("mov","a,mcnt1"); + emitcode("anl","a,#0x80"); + emitcode("jnz","!tlabel",lbl->key+100); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (right, NULL, ic,TRUE); + aopOp(result, ic, TRUE, FALSE); + + aopPut(AOP(result),"mb",1); + aopPut(AOP(result),"mb",0); + freeAsmop (result, NULL, ic, TRUE); + + /* restore EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("jnb","F1,!tlabel",lbl->key+100); + emitcode ("setb","EA"); + emitcode("","!tlabeldef",lbl->key+100); + return ; } /*-----------------------------------------------------------------*/ @@ -4075,18 +4902,17 @@ genMod (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); - D (emitcode (";", "genMod "); - ); + D (emitcode (";", "genMod "); ); /* assign the amsops */ - AOP_OP_3 (ic); + AOP_OP_2 (ic); /* special cases first */ /* both are bits */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { - genModbits (left, right, result); + genModbits (left, right, result, ic); goto release; } @@ -4094,12 +4920,18 @@ genMod (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genModOneByte (left, right, result); + genModOneByte (left, right, result, ic); goto release; } + if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) { + /* use the ds390 ARITHMETIC accel UNIT */ + genModTwoByte (left, right, result, ic); + return ; + } + /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4136,11 +4968,11 @@ genIfxJump (iCode * ic, char *jval) (strcmp (jval, "c") == 0 ? "jc" : "jb"))); } if (strcmp (inst, "jb") == 0 || strcmp (inst, "jnb") == 0) - emitcode (inst, "%s,%05d$", jval, (tlbl->key + 100)); + emitcode (inst, "%s,!tlabel", jval, (tlbl->key + 100)); else - emitcode (inst, "%05d$", tlbl->key + 100); - emitcode ("ljmp", "%05d$", jlbl->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode (inst, "!tlabel", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", jlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); /* mark the icode as generated */ ic->generated = 1; @@ -4181,11 +5013,11 @@ genCmp (operand * left, operand * right, (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR)) { symbol *lbl = newiTempLabel (NULL); - emitcode ("cjne", "%s,%s,%05d$", + emitcode ("cjne", "%s,%s,!tlabel", aopGet (AOP (left), offset, FALSE, FALSE, FALSE), aopGet (AOP (right), offset, FALSE, FALSE, FALSE), lbl->key + 100); - emitcode ("", "%05d$:", lbl->key + 100); + emitcode ("", "!tlabeldef", lbl->key + 100); } else { @@ -4238,7 +5070,7 @@ genCmp (operand * left, operand * right, unsigned long lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); emitcode (";", "genCmp #3.1"); - emitcode ("subb", "a,#0x%02x", + emitcode ("subb", "a,#!constbyte", 0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL)); } else @@ -4412,7 +5244,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) { char *l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE); MOVA (l); - emitcode ("cjne", "a,%s,%05d$", + emitcode ("cjne", "a,%s,!tlabel", aopGet (AOP (right), offset, FALSE, FALSE, FALSE), lbl->key + 100); offset++; @@ -4431,9 +5263,9 @@ gencjneshort (operand * left, operand * right, symbol * lbl) MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) && ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0)) - emitcode ("jnz", "%05d$", lbl->key + 100); + emitcode ("jnz", "!tlabel", lbl->key + 100); else - emitcode ("cjne", "a,%s,%05d$", + emitcode ("cjne", "a,%s,!tlabel", aopGet (AOP (right), offset, FALSE, TRUE, FALSE), lbl->key + 100); offset++; @@ -4448,7 +5280,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) if (strcmp (l, "b")) emitcode ("mov", "b,%s", l); MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("cjne", "a,b,%05d$", lbl->key + 100); + emitcode ("cjne", "a,b,!tlabel", lbl->key + 100); offset++; } } @@ -4468,10 +5300,10 @@ gencjne (operand * left, operand * right, symbol * lbl) gencjneshort (left, right, lbl); emitcode ("mov", "a,%s", one); - emitcode ("sjmp", "%05d$", tlbl->key + 100); - emitcode ("", "%05d$:", lbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl->key + 100); + emitcode ("", "!tlabeldef", lbl->key + 100); emitcode ("clr", "a"); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } /*-----------------------------------------------------------------*/ @@ -4530,24 +5362,24 @@ genCmpEq (iCode * ic, iCode * ifx) { symbol *lbl = newiTempLabel (NULL); emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir); - emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100)); + emitcode ("jb", "%s,!tlabel", AOP (right)->aopu.aop_dir, (lbl->key + 100)); emitcode ("cpl", "c"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); } /* if true label then we jump if condition supplied is true */ tlbl = newiTempLabel (NULL); if (IC_TRUE (ifx)) { - emitcode ("jnc", "%05d$", tlbl->key + 100); - emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100); + emitcode ("jnc", "!tlabel", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100); } else { - emitcode ("jc", "%05d$", tlbl->key + 100); - emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100); + emitcode ("jc", "!tlabel", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_FALSE (ifx)->key + 100); } - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } else { @@ -4555,16 +5387,16 @@ genCmpEq (iCode * ic, iCode * ifx) gencjneshort (left, right, tlbl); if (IC_TRUE (ifx)) { - emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } else { symbol *lbl = newiTempLabel (NULL); - emitcode ("sjmp", "%05d$", lbl->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); - emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100); - emitcode ("", "%05d$:", lbl->key + 100); + emitcode ("sjmp", "!tlabel", lbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_FALSE (ifx)->key + 100); + emitcode ("", "!tlabeldef", lbl->key + 100); } } /* mark the icode as generated */ @@ -4601,9 +5433,9 @@ genCmpEq (iCode * ic, iCode * ifx) { symbol *lbl = newiTempLabel (NULL); emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir); - emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100)); + emitcode ("jb", "%s,!tlabel", AOP (right)->aopu.aop_dir, (lbl->key + 100)); emitcode ("cpl", "c"); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "!tlabeldef", (lbl->key + 100)); } freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4677,6 +5509,41 @@ ifxForOp (operand * op, iCode * ic) return NULL; } +/*-----------------------------------------------------------------*/ +/* hasInc - operand is incremented before any other use */ +/*-----------------------------------------------------------------*/ +static iCode * +hasInc (operand *op, iCode *ic) +{ + sym_link *type = operandType(op); + sym_link *retype = getSpec (type); + iCode *lic = ic->next; + int isize ; + + /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */ + if (!IS_SYMOP(op)) return NULL; + + if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL; + isize = getSize(type->next); + while (lic) { + /* if operand of the form op = op + */ + if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) && + isOperandEqual(IC_RESULT(lic),op) && + isOperandLiteral(IC_RIGHT(lic)) && + operandLitValue(IC_RIGHT(lic)) == isize) { + return lic; + } + /* if the operand used or deffed */ + if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) { + return NULL; + } + /* if GOTO or IFX */ + if (lic->op == IFX || lic->op == GOTO) break; + lic = lic->next; + } + return NULL; +} + /*-----------------------------------------------------------------*/ /* genAndOp - for && operation */ /*-----------------------------------------------------------------*/ @@ -4710,9 +5577,9 @@ genAndOp (iCode * ic) { tlbl = newiTempLabel (NULL); toBoolean (left); - emitcode ("jz", "%05d$", tlbl->key + 100); + emitcode ("jz", "!tlabel", tlbl->key + 100); toBoolean (right); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4757,9 +5624,9 @@ genOrOp (iCode * ic) { tlbl = newiTempLabel (NULL); toBoolean (left); - emitcode ("jnz", "%05d$", tlbl->key + 100); + emitcode ("jnz", "!tlabel", tlbl->key + 100); toBoolean (right); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4800,7 +5667,7 @@ static void continueIfTrue (iCode * ic) { if (IC_TRUE (ic)) - emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100); + emitcode ("ljmp", "!tlabel", IC_TRUE (ic)->key + 100); ic->generated = 1; } @@ -4811,7 +5678,7 @@ static void jumpIfTrue (iCode * ic) { if (!IC_TRUE (ic)) - emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100); + emitcode ("ljmp", "!tlabel", IC_FALSE (ic)->key + 100); ic->generated = 1; } @@ -4825,15 +5692,15 @@ jmpTrueOrFalse (iCode * ic, symbol * tlbl) if (IC_TRUE (ic)) { symbol *nlbl = newiTempLabel (NULL); - emitcode ("sjmp", "%05d$", nlbl->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); - emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100); - emitcode ("", "%05d$:", nlbl->key + 100); + emitcode ("sjmp", "!tlabel", nlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_TRUE (ic)->key + 100); + emitcode ("", "!tlabeldef", nlbl->key + 100); } else { - emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_FALSE (ic)->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } ic->generated = 1; } @@ -4849,6 +5716,7 @@ genFarFarLogicOp(iCode *ic, char *logicOp) int size, resultSize, compSize; int offset = 0; + TR_AP("#5"); D(emitcode(";", "%s special case for 3 far operands.", logicOp);); compSize = AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RIGHT(ic)) ? AOP_SIZE(IC_LEFT(ic)) : AOP_SIZE(IC_RIGHT(ic)); @@ -4918,8 +5786,11 @@ genAnd (iCode * ic, iCode * ifx) #endif /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || - AOP_NEEDSACC (left)) + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) +#ifdef LOGIC_OPS_BROKEN + || AOP_NEEDSACC (left) +#endif + ) { operand *tmp = right; right = left; @@ -5043,13 +5914,13 @@ genAnd (iCode * ic, iCode * ifx) MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); // byte == 2^n ? if ((posbit = isLiteralBit (bytelit)) != 0) - emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100); + emitcode ("jb", "acc.%d,!tlabel", (posbit - 1) & 0x07, tlbl->key + 100); else { if (bytelit != 0x0FFL) emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, TRUE, FALSE)); - emitcode ("jnz", "%05d$", tlbl->key + 100); + emitcode ("jnz", "!tlabel", tlbl->key + 100); } } offset++; @@ -5058,7 +5929,7 @@ genAnd (iCode * ic, iCode * ifx) if (size) { emitcode ("clr", "c"); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } // if(left & literal) else @@ -5128,16 +5999,27 @@ genAnd (iCode * ic, iCode * ifx) emitcode ("setb", "c"); while (sizer--) { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("anl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); - emitcode ("jnz", "%05d$", tlbl->key + 100); + if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { + emitcode ("anl", "a,%s", + aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); + } else { + if (AOP_TYPE(left)==AOP_ACC) { + emitcode("mov", "b,a"); + MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); + emitcode("anl", "a,b"); + }else { + MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); + emitcode ("anl", "a,%s", + aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); + } + } + emitcode ("jnz", "!tlabel", tlbl->key + 100); offset++; } if (size) { CLRC; - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); outBitC (result); } else if (ifx) @@ -5163,8 +6045,7 @@ genAnd (iCode * ic, iCode * ifx) aopPut (AOP (result), zero, offset); continue; } - D (emitcode (";", "better literal AND."); - ); + D (emitcode (";", "better literal AND.");); MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); emitcode ("anl", "a, %s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); @@ -5181,10 +6062,16 @@ genAnd (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("anl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); - } + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("anl", "a,%s", rOp); + } } aopPut (AOP (result), "a", offset); } @@ -5231,8 +6118,11 @@ genOr (iCode * ic, iCode * ifx) #endif /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || - AOP_NEEDSACC (left)) + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) +#ifdef LOGIC_OPS_BROKEN + || AOP_NEEDSACC (left) // I think this is a net loss now. +#endif + ) { operand *tmp = right; right = left; @@ -5302,10 +6192,10 @@ genOr (iCode * ic, iCode * ifx) symbol *tlbl = newiTempLabel (NULL); if (!((AOP_TYPE (result) == AOP_CRY) && ifx)) emitcode ("setb", "c"); - emitcode ("jb", "%s,%05d$", + emitcode ("jb", "%s,!tlabel", AOP (left)->aopu.aop_dir, tlbl->key + 100); toBoolean (right); - emitcode ("jnz", "%05d$", tlbl->key + 100); + emitcode ("jnz", "!tlabel", tlbl->key + 100); if ((AOP_TYPE (result) == AOP_CRY) && ifx) { jmpTrueOrFalse (ifx, tlbl); @@ -5314,7 +6204,7 @@ genOr (iCode * ic, iCode * ifx) else { CLRC; - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } } } @@ -5352,9 +6242,9 @@ genOr (iCode * ic, iCode * ifx) if (size) { symbol *tlbl = newiTempLabel (NULL); - emitcode ("jnz", "%05d$", tlbl->key + 100); + emitcode ("jnz", "!tlabel", tlbl->key + 100); CLRC; - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } else { @@ -5430,16 +6320,21 @@ genOr (iCode * ic, iCode * ifx) emitcode ("setb", "c"); while (sizer--) { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("orl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); - emitcode ("jnz", "%05d$", tlbl->key + 100); + if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { + emitcode ("orl", "a,%s", + aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); + } else { + MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); + emitcode ("orl", "a,%s", + aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); + } + emitcode ("jnz", "!tlabel", tlbl->key + 100); offset++; } if (size) { CLRC; - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); outBitC (result); } else if (ifx) @@ -5447,6 +6342,7 @@ genOr (iCode * ic, iCode * ifx) } else { + _startLazyDPSEvaluation(); for (; (size--); offset++) { // normal case @@ -5460,8 +6356,7 @@ genOr (iCode * ic, iCode * ifx) offset); continue; } - D (emitcode (";", "better literal OR."); - ); + D (emitcode (";", "better literal OR.");); MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); emitcode ("orl", "a, %s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); @@ -5478,13 +6373,21 @@ genOr (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("orl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("orl", "a,%s", rOp); } } aopPut (AOP (result), "a", offset); } + _endLazyDPSEvaluation(); } } @@ -5527,8 +6430,11 @@ genXor (iCode * ic, iCode * ifx) /* if left is a literal & right is not || if left needs acc & right does not */ - if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || - (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right))) + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) +#ifdef LOGIC_OPS_BROKEN + || (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)) +#endif + ) { operand *tmp = right; right = left; @@ -5624,15 +6530,15 @@ genXor (iCode * ic, iCode * ifx) if (sizer == 1) // test the msb of the lsb emitcode ("anl", "a,#0xfe"); - emitcode ("jnz", "%05d$", tlbl->key + 100); + emitcode ("jnz", "!tlabel", tlbl->key + 100); sizer--; } // val = (0,1) emitcode ("rrc", "a"); } - emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100)); + emitcode ("jnb", "%s,!tlabel", AOP (left)->aopu.aop_dir, (tlbl->key + 100)); emitcode ("cpl", "c"); - emitcode ("", "%05d$:", (tlbl->key + 100)); + emitcode ("", "!tlabeldef", (tlbl->key + 100)); } // bit = c // val = c @@ -5693,6 +6599,7 @@ genXor (iCode * ic, iCode * ifx) // if(!size && ifx), conditional oper: if(left ^ right) symbol *tlbl = newiTempLabel (NULL); int sizer = max (AOP_SIZE (left), AOP_SIZE (right)); + if (size) emitcode ("setb", "c"); while (sizer--) @@ -5704,23 +6611,35 @@ genXor (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("xrl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); + if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { + emitcode ("xrl", "a,%s", + aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); + } else { + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("xrl", "a,%s", rOp); + } } - emitcode ("jnz", "%05d$", tlbl->key + 100); + emitcode ("jnz", "!tlabel", tlbl->key + 100); offset++; } if (size) { CLRC; - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); outBitC (result); } else if (ifx) jmpTrueOrFalse (ifx, tlbl); } else + { for (; (size--); offset++) { // normal case @@ -5734,8 +6653,7 @@ genXor (iCode * ic, iCode * ifx) offset); continue; } - D (emitcode (";", "better literal XOR."); - ); + D (emitcode (";", "better literal XOR.");); MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); emitcode ("xrl", "a, %s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); @@ -5751,13 +6669,21 @@ genXor (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("xrl", "a,%s", - aopGet (AOP (left), offset, FALSE, TRUE, FALSE)); + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("xrl", "a,%s", rOp); } } aopPut (AOP (result), "a", offset); } + } + } release: @@ -5772,14 +6698,14 @@ release: static void genInline (iCode * ic) { - char buffer[MAX_INLINEASM]; - char *bp = buffer; - char *bp1 = buffer; + char *buffer, *bp, *bp1; D (emitcode (";", "genInline "); ); _G.inLine += (!options.asmpeep); + + buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy (buffer, IC_INLINE (ic)); /* emit each line as a code */ @@ -6009,7 +6935,7 @@ AccLsh (int shCount) /* rotate left accumulator */ AccRol (shCount); /* and kill the lower order bits */ - emitcode ("anl", "a,#0x%02x", SLMask[shCount]); + emitcode ("anl", "a,#!constbyte", SLMask[shCount]); } } } @@ -6032,7 +6958,7 @@ AccRsh (int shCount) /* rotate right accumulator */ AccRol (8 - shCount); /* and kill the higher order bits */ - emitcode ("anl", "a,#0x%02x", SRMask[shCount]); + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); } } } @@ -6065,11 +6991,11 @@ AccSRsh (int shCount) /* rotate right accumulator */ AccRol (8 - shCount); /* and kill the higher order bits */ - emitcode ("anl", "a,#0x%02x", SRMask[shCount]); - emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100); - emitcode ("orl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); + emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100); + emitcode ("orl", "a,#!constbyte", (unsigned char) ~SRMask[shCount]); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); } } } @@ -6214,7 +7140,7 @@ AccAXLsh (char *x, int shCount) AccRol (shCount); // BBBAAAAA:CCCCCDDD - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SLMask[shCount]); // BBB00000:CCCCCDDD emitcode ("xch", "a,%s", x); // CCCCCDDD:BBB00000 @@ -6227,7 +7153,7 @@ AccAXLsh (char *x, int shCount) emitcode ("xch", "a,%s", x); // DDDCCCCC:(BBB^DDD)CCCCC - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC emitcode ("xch", "a,%s", x); // (BBB^DDD)CCCCC:DDD00000 @@ -6236,7 +7162,7 @@ AccAXLsh (char *x, int shCount) break; case 6: // AAAAAABB:CCCCCCDD - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000000BB:CCCCCCDD emitcode ("mov", "c,acc.0"); // c = B emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB @@ -6258,7 +7184,7 @@ AccAXLsh (char *x, int shCount) break; case 7: // a:x <<= 7 - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 0000000B:CCCCCCCD emitcode ("mov", "c,acc.0"); // c = B @@ -6309,14 +7235,14 @@ AccAXRsh (char *x, int shCount) AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000CCCCC:BBBAAAAA emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA) - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA) emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA @@ -6335,7 +7261,7 @@ AccAXRsh (char *x, int shCount) emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000000AA:BBBBBBCC break; @@ -6347,7 +7273,7 @@ AccAXRsh (char *x, int shCount) emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 0000000A:BBBBBBBC break; @@ -6358,7 +7284,6 @@ AccAXRsh (char *x, int shCount) #endif #ifdef BETTER_LITERAL_SHIFT -//REMOVE ME!!! /*-----------------------------------------------------------------*/ /* AccAXRshS - right shift signed a:x known count (0..7) */ /*-----------------------------------------------------------------*/ @@ -6394,14 +7319,14 @@ AccAXRshS (char *x, int shCount) AccRol (8 - shCount); // DDDCCCCC:BBBAAAAA - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000CCCCC:BBBAAAAA emitcode ("xrl", "a,%s", x); // BBB(CCCCC^AAAAA):BBBAAAAA emitcode ("xch", "a,%s", x); // BBBAAAAA:BBB(CCCCC^AAAAA) - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA) emitcode ("xch", "a,%s", x); // BBB(CCCCC^AAAAA):000AAAAA @@ -6410,11 +7335,11 @@ AccAXRshS (char *x, int shCount) emitcode ("xch", "a,%s", x); // 000SAAAA:BBBCCCCC - emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100); - emitcode ("orl", "a,#0x%02x", + emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100); + emitcode ("orl", "a,#!constbyte", (unsigned char) ~SRMask[shCount]); // 111AAAAA:BBBCCCCC - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); break; // SSSSAAAA:BBBCCCCC case 6: // AABBBBBB:CCDDDDDD @@ -6427,14 +7352,14 @@ AccAXRshS (char *x, int shCount) emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 000000AA:BBBBBBCC - emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100); - emitcode ("orl", "a,#0x%02x", + emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100); + emitcode ("orl", "a,#!constbyte", (unsigned char) ~SRMask[shCount]); // 111111AA:BBBBBBCC - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); break; case 7: // ABBBBBBB:CDDDDDDD @@ -6445,14 +7370,14 @@ AccAXRshS (char *x, int shCount) emitcode ("xch", "a,%s", x); // DDDDDDDA:BBBBBBCC - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", SRMask[shCount]); // 0000000A:BBBBBBBC - emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100); - emitcode ("orl", "a,#0x%02x", + emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100); + emitcode ("orl", "a,#!constbyte", (unsigned char) ~SRMask[shCount]); // 1111111A:BBBBBBBC - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); break; default: break; @@ -6482,7 +7407,7 @@ _loadLeftIntoAx(char **lsb, char *leftByte; _startLazyDPSEvaluation(); - if (AOP_TYPE(left) == AOP_DPTR2) + if (AOP_TYPE(left) == AOP_DPTR2) { // Get MSB in A. MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE)); @@ -6496,6 +7421,7 @@ _loadLeftIntoAx(char **lsb, leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE); if (strcmp(leftByte, DP2_RESULT_REG)) { + TR_AP("#7"); emitcode("mov","%s,%s", DP2_RESULT_REG, leftByte); } // And MSB in A. @@ -6580,11 +7506,11 @@ shiftR2Left2Result (operand * left, int offl, /* a:x >> shCount (x = lsb(result)) */ if (sign) { - AccAXRshS(aopGet(AOP(result), offr, FALSE, FALSE, FALSE), shCount); + AccAXRshS(lsb, shCount); } else { - AccAXRsh(aopGet(AOP(result), offr, FALSE, FALSE, FALSE), shCount); + AccAXRsh(lsb, shCount); } _storeAxResults(lsb, result, offr); @@ -7015,7 +7941,7 @@ genLeftShift (iCode * ic) * but since I'm too lazy to fix that today, at least we can make * some small improvement. */ - emitcode("mov", "b,#0x%02x", + emitcode("mov", "b,#!constbyte", ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1); } else @@ -7064,19 +7990,19 @@ genLeftShift (iCode * ic) l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE); MOVA (l); - emitcode ("sjmp", "%05d$", tlbl1->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl1->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); emitcode ("add", "a,acc"); - emitcode ("", "%05d$:", tlbl1->key + 100); - emitcode ("djnz", "b,%05d$", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl1->key + 100); + emitcode ("djnz", "b,!tlabel", tlbl->key + 100); aopPut (AOP (result), "a", 0); goto release; } reAdjustPreg (AOP (result)); - emitcode ("sjmp", "%05d$", tlbl1->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl1->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE); MOVA (l); emitcode ("add", "a,acc"); @@ -7092,8 +8018,8 @@ genLeftShift (iCode * ic) _endLazyDPSEvaluation (); reAdjustPreg (AOP (result)); - emitcode ("", "%05d$:", tlbl1->key + 100); - emitcode ("djnz", "b,%05d$", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl1->key + 100); + emitcode ("djnz", "b,!tlabel", tlbl->key + 100); release: freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); @@ -7158,28 +8084,54 @@ static void shiftRLong (operand * left, int offl, operand * result, int sign) { - if (!sign) + int isSameRegs=sameRegs(AOP(left),AOP(result)); + + if (isSameRegs && offl>1) { + // we are in big trouble, but this shouldn't happen + werror(E_INTERNAL_ERROR, __FILE__, __LINE__); + } + + MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE)); + + if (offl==MSB16) { + // shift is > 8 + if (sign) { + emitcode ("rlc", "a"); + emitcode ("subb", "a,acc"); + emitcode ("xch", "a,%s", aopGet(AOP(left), MSB32, FALSE, FALSE)); + } else { + aopPut (AOP(result), zero, MSB32); + } + } + + if (!sign) { emitcode ("clr", "c"); - MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE, TRUE)); - if (sign) + } else { emitcode ("mov", "c,acc.7"); - emitcode ("rrc", "a"); - aopPut (AOP (result), "a", MSB32 - offl); - if (offl == MSB16) - /* add sign of "a" */ - addSign (result, MSB32, sign); + } - MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE, TRUE)); emitcode ("rrc", "a"); - aopPut (AOP (result), "a", MSB24 - offl); - MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE, TRUE)); + if (isSameRegs && offl==MSB16) { + emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE)); + } else { + aopPut (AOP (result), "a", MSB32); + MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE)); + } + + emitcode ("rrc", "a"); + if (isSameRegs && offl==1) { + emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE)); + } else { + aopPut (AOP (result), "a", MSB24); + MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE)); + } emitcode ("rrc", "a"); aopPut (AOP (result), "a", MSB16 - offl); if (offl == LSB) { - MOVA (aopGet (AOP (left), LSB, FALSE, FALSE, TRUE)); + MOVA (aopGet (AOP (left), LSB, FALSE, FALSE)); emitcode ("rrc", "a"); aopPut (AOP (result), "a", LSB); } @@ -7389,7 +8341,7 @@ genSignedRightShift (iCode * ic) * but since I'm too lazy to fix that today, at least we can make * some small improvement. */ - emitcode("mov", "b,#0x%02x", + emitcode("mov", "b,#!constbyte", ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1); } else @@ -7440,19 +8392,19 @@ genSignedRightShift (iCode * ic) { l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE); MOVA (l); - emitcode ("sjmp", "%05d$", tlbl1->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl1->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); emitcode ("mov", "c,ov"); emitcode ("rrc", "a"); - emitcode ("", "%05d$:", tlbl1->key + 100); - emitcode ("djnz", "b,%05d$", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl1->key + 100); + emitcode ("djnz", "b,!tlabel", tlbl->key + 100); aopPut (AOP (result), "a", 0); goto release; } reAdjustPreg (AOP (result)); - emitcode ("sjmp", "%05d$", tlbl1->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl1->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); emitcode ("mov", "c,ov"); _startLazyDPSEvaluation (); while (size--) @@ -7464,8 +8416,8 @@ genSignedRightShift (iCode * ic) } _endLazyDPSEvaluation (); reAdjustPreg (AOP (result)); - emitcode ("", "%05d$:", tlbl1->key + 100); - emitcode ("djnz", "b,%05d$", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl1->key + 100); + emitcode ("djnz", "b,!tlabel", tlbl->key + 100); release: freeAsmop (left, NULL, ic, TRUE); @@ -7533,7 +8485,7 @@ genRightShift (iCode * ic) * but since I'm too lazy to fix that today, at least we can make * some small improvement. */ - emitcode("mov", "b,#0x%02x", + emitcode("mov", "b,#!constbyte", ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1); } else @@ -7580,19 +8532,19 @@ genRightShift (iCode * ic) { l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE); MOVA (l); - emitcode ("sjmp", "%05d$", tlbl1->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl1->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); CLRC; emitcode ("rrc", "a"); - emitcode ("", "%05d$:", tlbl1->key + 100); - emitcode ("djnz", "b,%05d$", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl1->key + 100); + emitcode ("djnz", "b,!tlabel", tlbl->key + 100); aopPut (AOP (result), "a", 0); goto release; } reAdjustPreg (AOP (result)); - emitcode ("sjmp", "%05d$", tlbl1->key + 100); - emitcode ("", "%05d$:", tlbl->key + 100); + emitcode ("sjmp", "!tlabel", tlbl1->key + 100); + emitcode ("", "!tlabeldef", tlbl->key + 100); CLRC; _startLazyDPSEvaluation (); while (size--) @@ -7605,8 +8557,8 @@ genRightShift (iCode * ic) _endLazyDPSEvaluation (); reAdjustPreg (AOP (result)); - emitcode ("", "%05d$:", tlbl1->key + 100); - emitcode ("djnz", "b,%05d$", tlbl->key + 100); + emitcode ("", "!tlabeldef", tlbl1->key + 100); + emitcode ("djnz", "b,!tlabel", tlbl->key + 100); release: freeAsmop (left, NULL, ic, TRUE); @@ -7648,7 +8600,7 @@ genUnpackBits (operand * result, char *rname, int ptype) case CPOINTER: emitcode ("clr", "a"); - emitcode ("movc", "a", "@a+dptr"); + emitcode ("movc", "a,@a+dptr"); break; case GPOINTER: @@ -7666,7 +8618,7 @@ genUnpackBits (operand * result, char *rname, int ptype) /* shift right acc */ AccRsh (shCnt); - emitcode ("anl", "a,#0x%02x", + emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8 - SPEC_BLEN (etype))); aopPut (AOP (result), "a", offset); return; @@ -7700,7 +8652,7 @@ genUnpackBits (operand * result, char *rname, int ptype) case CPOINTER: emitcode ("clr", "a"); emitcode ("inc", "dptr"); - emitcode ("movc", "a", "@a+dptr"); + emitcode ("movc", "a,@a+dptr"); break; case GPOINTER: @@ -7720,7 +8672,7 @@ genUnpackBits (operand * result, char *rname, int ptype) if (rlen) { - emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (rlen)); + emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (rlen)); aopPut (AOP (result), "a", offset); } @@ -7765,7 +8717,8 @@ genDataPointerGet (operand * left, static void genNearPointerGet (operand * left, operand * result, - iCode * ic) + iCode * ic, + iCode *pi) { asmop *aop = NULL; regs *preg = NULL; @@ -7834,7 +8787,7 @@ genNearPointerGet (operand * left, aopPut (AOP (result), buffer, offset); } offset++; - if (size) + if (size || pi) emitcode ("inc", "%s", rname); } } @@ -7843,6 +8796,9 @@ genNearPointerGet (operand * left, if (aop) { /* we had to allocate for this iCode */ + if (pi) { /* post increment present */ + aopPut(AOP ( left ),rname,0); + } freeAsmop (NULL, aop, ic, TRUE); } else @@ -7855,7 +8811,8 @@ genNearPointerGet (operand * left, if (AOP_SIZE (result) > 1 && !OP_SYMBOL (left)->remat && (OP_SYMBOL (left)->liveTo > ic->seq || - ic->depth)) + ic->depth) && + !pi) { int size = AOP_SIZE (result) - 1; while (size--) @@ -7865,7 +8822,7 @@ genNearPointerGet (operand * left, /* done */ freeAsmop (result, NULL, ic, TRUE); - + if (pi) pi->generated = 1; } /*-----------------------------------------------------------------*/ @@ -7874,7 +8831,8 @@ genNearPointerGet (operand * left, static void genPagedPointerGet (operand * left, operand * result, - iCode * ic) + iCode * ic, + iCode * pi) { asmop *aop = NULL; regs *preg = NULL; @@ -7921,7 +8879,7 @@ genPagedPointerGet (operand * left, offset++; - if (size) + if (size || pi) emitcode ("inc", "%s", rname); } } @@ -7930,6 +8888,7 @@ genPagedPointerGet (operand * left, if (aop) { /* we had to allocate for this iCode */ + if (pi) aopPut ( AOP (left), rname, 0); freeAsmop (NULL, aop, ic, TRUE); } else @@ -7942,7 +8901,8 @@ genPagedPointerGet (operand * left, if (AOP_SIZE (result) > 1 && !OP_SYMBOL (left)->remat && (OP_SYMBOL (left)->liveTo > ic->seq || - ic->depth)) + ic->depth) && + !pi) { int size = AOP_SIZE (result) - 1; while (size--) @@ -7952,8 +8912,7 @@ genPagedPointerGet (operand * left, /* done */ freeAsmop (result, NULL, ic, TRUE); - - + if (pi) pi->generated = 1; } /*-----------------------------------------------------------------*/ @@ -7961,9 +8920,9 @@ genPagedPointerGet (operand * left, /*-----------------------------------------------------------------*/ static void genFarPointerGet (operand * left, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode *pi) { - int size, offset; + int size, offset, dopi=1; sym_link *retype = getSpec (operandType (result)); sym_link *letype = getSpec (operandType (left)); D (emitcode (";", "genFarPointerGet"); @@ -7988,7 +8947,8 @@ genFarPointerGet (operand * left, { emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); } else { @@ -7997,15 +8957,16 @@ genFarPointerGet (operand * left, ); emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE)); emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); emitcode ("pop", "dph"); emitcode ("pop", "dpl"); + dopi =0; } _endLazyDPSEvaluation (); } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8024,14 +8985,27 @@ genFarPointerGet (operand * left, _flushLazyDPS (); emitcode ("movx", "a,@dptr"); - if (size) + if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD)) emitcode ("inc", "dptr"); aopPut (AOP (result), "a", offset++); } _endLazyDPSEvaluation (); } + if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + if (options.model == MODEL_FLAT24) + aopPut ( AOP (left), "dpx", 2); + pi->generated = 1; + } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 && + (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (result) - 1; + while (size--) emitcode ("lcall","__decdptr"); + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8040,9 +9014,9 @@ genFarPointerGet (operand * left, /*-----------------------------------------------------------------*/ static void emitcodePointerGet (operand * left, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode *pi) { - int size, offset; + int size, offset, dopi=1; sym_link *retype = getSpec (operandType (result)); aopOp (left, ic, FALSE, FALSE); @@ -8063,7 +9037,8 @@ emitcodePointerGet (operand * left, { emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); } else { @@ -8072,15 +9047,16 @@ emitcodePointerGet (operand * left, ); emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE)); emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); emitcode ("pop", "dph"); emitcode ("pop", "dpl"); + dopi=0; } _endLazyDPSEvaluation (); } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8099,13 +9075,26 @@ emitcodePointerGet (operand * left, emitcode ("clr", "a"); emitcode ("movc", "a,@a+dptr"); - if (size) + if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD)) emitcode ("inc", "dptr"); aopPut (AOP (result), "a", offset++); } _endLazyDPSEvaluation (); } - + if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + if (options.model == MODEL_FLAT24) + aopPut ( AOP (left), "dpx", 2); + pi->generated = 1; + } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 && + (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (result) - 1; + while (size--) emitcode ("lcall","__decdptr"); + } + + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8114,7 +9103,7 @@ emitcodePointerGet (operand * left, /*-----------------------------------------------------------------*/ static void genGenPointerGet (operand * left, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode * pi) { int size, offset; sym_link *retype = getSpec (operandType (result)); @@ -8122,7 +9111,7 @@ genGenPointerGet (operand * left, D (emitcode (";", "genGenPointerGet "); ); - aopOp (left, ic, FALSE, TRUE); + aopOp (left, ic, FALSE, (OP_SYMBOL(left)->ruonly ? FALSE : TRUE)); /* if the operand is already in dptr then we do nothing else we move the value to dptr */ @@ -8132,7 +9121,10 @@ genGenPointerGet (operand * left, if (AOP_TYPE (left) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE)); - emitcode ("mov", "b,#%d", pointerCode (retype)); + if (AOP(left)->aopu.aop_immd.from_cast_remat) + emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE, FALSE)); + else + emitcode ("mov", "b,#%d", pointerCode (retype)); } else { /* we need to get it byte by byte */ @@ -8142,27 +9134,34 @@ genGenPointerGet (operand * left, l=aopGet(AOP(left),0,FALSE,FALSE,TRUE); genSetDPTR(0); _flushLazyDPS(); - emitcode ("mov", "dpl,%s ;jwk lazy genGenPointerGet", l); + emitcode ("mov", "dpl,%s", l); l=aopGet(AOP(left),1,FALSE,FALSE,TRUE); genSetDPTR(0); _flushLazyDPS(); - emitcode ("mov", "dph,%s ;jwk lazy genGenPointerGet", l); - l=aopGet(AOP(left),2,FALSE,FALSE,TRUE); - genSetDPTR(0); - _flushLazyDPS(); - emitcode ("mov", "dpx,%s ;jwk lazy genGenPointerGet", l); - emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + emitcode ("mov", "dph,%s", l); + if (options.model == MODEL_FLAT24) { + l=aopGet(AOP(left),2,FALSE,FALSE,TRUE); + genSetDPTR(0); + _flushLazyDPS(); + emitcode ("mov", "dpx,%s", l); + emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); + } } else { emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); - emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); + emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); + } } _endLazyDPSEvaluation (); } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8177,11 +9176,27 @@ genGenPointerGet (operand * left, { emitcode ("lcall", "__gptrget"); aopPut (AOP (result), "a", offset++); - if (size) + if (size || (pi && AOP_TYPE (left) != AOP_IMMD)) emitcode ("inc", "dptr"); } } + if (pi && AOP_TYPE (left) != AOP_IMMD) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + if (options.model == MODEL_FLAT24) { + aopPut ( AOP (left), "dpx", 2); + aopPut ( AOP (left), "b", 3); + } else aopPut ( AOP (left), "b", 2); + pi->generated = 1; + } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 && + (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (result) - 1; + while (size--) emitcode ("lcall","__decdptr"); + } + + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8189,7 +9204,7 @@ genGenPointerGet (operand * left, /* genPointerGet - generate code for pointer get */ /*-----------------------------------------------------------------*/ static void -genPointerGet (iCode * ic) +genPointerGet (iCode * ic, iCode *pi) { operand *left, *result; sym_link *type, *etype; @@ -8213,7 +9228,13 @@ genPointerGet (iCode * ic) /* we have to go by the storage class */ p_type = PTR_TYPE (SPEC_OCLS (etype)); } - + /* special case when cast remat */ + if (p_type == GPOINTER && OP_SYMBOL(left)->remat && + IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) { + left = IC_RIGHT(OP_SYMBOL(left)->rematiCode); + type = type = operandType (left); + p_type = DCL_TYPE (type); + } /* now that we have the pointer type we assign the pointer values */ switch (p_type) @@ -8221,23 +9242,23 @@ genPointerGet (iCode * ic) case POINTER: case IPOINTER: - genNearPointerGet (left, result, ic); + genNearPointerGet (left, result, ic, pi); break; case PPOINTER: - genPagedPointerGet (left, result, ic); + genPagedPointerGet (left, result, ic, pi); break; case FPOINTER: - genFarPointerGet (left, result, ic); + genFarPointerGet (left, result, ic, pi); break; case CPOINTER: - emitcodePointerGet (left, result, ic); + emitcodePointerGet (left, result, ic, pi); break; case GPOINTER: - genGenPointerGet (left, result, ic); + genGenPointerGet (left, result, ic, pi); break; } @@ -8296,7 +9317,7 @@ genPackBits (sym_link * etype, break; } - emitcode ("anl", "a,#0x%02x", (unsigned char) + emitcode ("anl", "a,#!constbyte", (unsigned char) ((unsigned char) (0xFF << (blen + bstr)) | (unsigned char) (0xFF >> (8 - bstr)))); emitcode ("orl", "a,b"); @@ -8388,7 +9409,7 @@ genPackBits (sym_link * etype, break; } - emitcode ("anl", "a,#0x%02x", ((unsigned char) -1 << rLen)); + emitcode ("anl", "a,#!constbyte", ((unsigned char) -1 << rLen)); emitcode ("orl", "a,b"); } @@ -8446,7 +9467,8 @@ genDataPointerSet (operand * right, static void genNearPointerSet (operand * right, operand * result, - iCode * ic) + iCode * ic, + iCode * pi) { asmop *aop = NULL; regs *preg = NULL; @@ -8485,7 +9507,6 @@ genNearPointerSet (operand * right, else rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE); - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE, FALSE); /* if bitfield then unpack the bits */ @@ -8507,7 +9528,7 @@ genNearPointerSet (operand * right, } else emitcode ("mov", "@%s,%s", rname, l); - if (size) + if (size || pi) emitcode ("inc", "%s", rname); offset++; } @@ -8517,6 +9538,7 @@ genNearPointerSet (operand * right, if (aop) { /* we had to allocate for this iCode */ + if (pi) aopPut (AOP (result),rname,0); freeAsmop (NULL, aop, ic, TRUE); } else @@ -8529,7 +9551,8 @@ genNearPointerSet (operand * right, if (AOP_SIZE (right) > 1 && !OP_SYMBOL (result)->remat && (OP_SYMBOL (result)->liveTo > ic->seq || - ic->depth)) + ic->depth) && + !pi) { int size = AOP_SIZE (right) - 1; while (size--) @@ -8538,6 +9561,8 @@ genNearPointerSet (operand * right, } /* done */ + if (pi) pi->generated = 1; + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); @@ -8549,7 +9574,8 @@ genNearPointerSet (operand * right, static void genPagedPointerSet (operand * right, operand * result, - iCode * ic) + iCode * ic, + iCode *pi) { asmop *aop = NULL; regs *preg = NULL; @@ -8576,7 +9602,6 @@ genPagedPointerSet (operand * right, else rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE); - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE, FALSE); /* if bitfield then unpack the bits */ @@ -8595,7 +9620,7 @@ genPagedPointerSet (operand * right, MOVA (l); emitcode ("movx", "@%s,a", rname); - if (size) + if (size || pi) emitcode ("inc", "%s", rname); offset++; @@ -8605,6 +9630,7 @@ genPagedPointerSet (operand * right, /* now some housekeeping stuff */ if (aop) { + if (pi) aopPut (AOP (result),rname,0); /* we had to allocate for this iCode */ freeAsmop (NULL, aop, ic, TRUE); } @@ -8618,7 +9644,8 @@ genPagedPointerSet (operand * right, if (AOP_SIZE (right) > 1 && !OP_SYMBOL (result)->remat && (OP_SYMBOL (result)->liveTo > ic->seq || - ic->depth)) + ic->depth) && + !pi) { int size = AOP_SIZE (right) - 1; while (size--) @@ -8627,6 +9654,8 @@ genPagedPointerSet (operand * right, } /* done */ + if (pi) pi->generated = 1; + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); @@ -8637,9 +9666,9 @@ genPagedPointerSet (operand * right, /*-----------------------------------------------------------------*/ static void genFarPointerSet (operand * right, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode *pi) { - int size, offset; + int size, offset, dopi=1; sym_link *retype = getSpec (operandType (right)); sym_link *letype = getSpec (operandType (result)); @@ -8660,7 +9689,8 @@ genFarPointerSet (operand * right, { emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); } else { @@ -8669,15 +9699,16 @@ genFarPointerSet (operand * right, ); emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, TRUE)); emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); emitcode ("pop", "dph"); emitcode ("pop", "dpl"); + dopi=0; } _endLazyDPSEvaluation (); } } /* so dptr know contains the address */ - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8698,12 +9729,25 @@ genFarPointerSet (operand * right, _flushLazyDPS (); emitcode ("movx", "@dptr,a"); - if (size) + if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD)) emitcode ("inc", "dptr"); } _endLazyDPSEvaluation (); } + if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) { + aopPut (AOP(result),"dpl",0); + aopPut (AOP(result),"dph",1); + if (options.model == MODEL_FLAT24) + aopPut (AOP(result),"dpx",2); + pi->generated=1; + } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 && + (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (right) - 1; + while (size--) emitcode ("lcall","__decdptr"); + } + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); } @@ -8712,13 +9756,13 @@ genFarPointerSet (operand * right, /*-----------------------------------------------------------------*/ static void genGenPointerSet (operand * right, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode *pi) { int size, offset; sym_link *retype = getSpec (operandType (right)); sym_link *letype = getSpec (operandType (result)); - aopOp (result, ic, FALSE, TRUE); + aopOp (result, ic, FALSE, OP_SYMBOL(result)->ruonly ? FALSE : TRUE); /* if the operand is already in dptr then we do nothing else we move the value to dptr */ @@ -8729,19 +9773,25 @@ genGenPointerSet (operand * right, if (AOP_TYPE (result) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE)); - emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE)); + if (AOP(result)->aopu.aop_immd.from_cast_remat) + emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, FALSE)); + else + emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE)); } else { /* we need to get it byte by byte */ emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); - emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + } } _endLazyDPSEvaluation (); } /* so dptr know contains the address */ - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8762,12 +9812,29 @@ genGenPointerSet (operand * right, _flushLazyDPS (); emitcode ("lcall", "__gptrput"); - if (size) + if (size || (pi && AOP_TYPE (result) != AOP_IMMD)) emitcode ("inc", "dptr"); } _endLazyDPSEvaluation (); } + if (pi && AOP_TYPE (result) != AOP_IMMD) { + aopPut (AOP(result),"dpl",0); + aopPut (AOP(result),"dph",1); + if (options.model == MODEL_FLAT24) { + aopPut (AOP(result),"dpx",2); + aopPut (AOP(result),"b",3); + } else { + aopPut (AOP(result),"b",2); + } + pi->generated=1; + } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 && + (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (right) - 1; + while (size--) emitcode ("lcall","__decdptr"); + } + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); } @@ -8775,7 +9842,7 @@ genGenPointerSet (operand * right, /* genPointerSet - stores the value into a pointer location */ /*-----------------------------------------------------------------*/ static void -genPointerSet (iCode * ic) +genPointerSet (iCode * ic, iCode *pi) { operand *right, *result; sym_link *type, *etype; @@ -8801,6 +9868,13 @@ genPointerSet (iCode * ic) /* we have to go by the storage class */ p_type = PTR_TYPE (SPEC_OCLS (etype)); } + /* special case when cast remat */ + if (p_type == GPOINTER && OP_SYMBOL(result)->remat && + IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) { + result = IC_RIGHT(OP_SYMBOL(result)->rematiCode); + type = type = operandType (result); + p_type = DCL_TYPE (type); + } /* now that we have the pointer type we assign the pointer values */ @@ -8809,19 +9883,19 @@ genPointerSet (iCode * ic) case POINTER: case IPOINTER: - genNearPointerSet (right, result, ic); + genNearPointerSet (right, result, ic, pi); break; case PPOINTER: - genPagedPointerSet (right, result, ic); + genPagedPointerSet (right, result, ic, pi); break; case FPOINTER: - genFarPointerSet (right, result, ic); + genFarPointerSet (right, result, ic, pi); break; case GPOINTER: - genGenPointerSet (right, result, ic); + genGenPointerSet (right, result, ic, pi); break; } @@ -8881,47 +9955,66 @@ genAddrOf (iCode * ic) /* 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 (sym->stack) - { - emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); - aopPut (AOP (IC_RESULT (ic)), "a", 0); - } - else - { - /* we can just move _bp */ - aopPut (AOP (IC_RESULT (ic)), "_bp", 0); - } - /* fill the result with zero */ - size = AOP_SIZE (IC_RESULT (ic)) - 1; - - - if (options.stack10bit && size < (FPTRSIZE - 1)) - { - fprintf (stderr, - "*** warning: pointer to stack var truncated.\n"); - } + if (sym->onStack) { + + /* if 10 bit stack */ + if (options.stack10bit) { + char buff[10]; + tsprintf(buff,"#!constbyte",(options.stack_loc >> 16) & 0xff); + /* if it has an offset then we need to compute it */ + emitcode ("subb", "a,#!constbyte", + -((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) & 0xff); + emitcode ("mov","b,a"); + emitcode ("mov","a,#!constbyte",(-((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) >> 8) & 0xff); + if (sym->stack) { + emitcode ("mov", "a,_bpx"); + emitcode ("add", "a,#!constbyte", ((sym->stack < 0) ? + ((char) (sym->stack - _G.nRegsSaved)) : + ((char) sym->stack )) & 0xff); + emitcode ("mov", "b,a"); + emitcode ("mov", "a,_bpx+1"); + emitcode ("addc","a,#!constbyte", (((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack )) >> 8) & 0xff); + aopPut (AOP (IC_RESULT (ic)), "b", 0); + aopPut (AOP (IC_RESULT (ic)), "a", 1); + aopPut (AOP (IC_RESULT (ic)), buff, 2); + } else { + /* we can just move _bp */ + aopPut (AOP (IC_RESULT (ic)), "_bpx", 0); + aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1); + aopPut (AOP (IC_RESULT (ic)), buff, 2); + } + } else { + /* if it has an offset then we need to compute it */ + if (sym->stack) { + emitcode ("mov", "a,_bp"); + emitcode ("add", "a,#!constbyte", ((char) sym->stack & 0xff)); + aopPut (AOP (IC_RESULT (ic)), "a", 0); + } else { + /* we can just move _bp */ + aopPut (AOP (IC_RESULT (ic)), "_bp", 0); + } + /* fill the result with zero */ + size = AOP_SIZE (IC_RESULT (ic)) - 1; + + + if (options.stack10bit && size < (FPTRSIZE - 1)) { + fprintf (stderr, + "*** warning: pointer to stack var truncated.\n"); + } - offset = 1; - while (size--) - { - /* Yuck! */ - if (options.stack10bit && offset == 2) - { - aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++); - } - else - { + offset = 1; + while (size--) { aopPut (AOP (IC_RESULT (ic)), zero, offset++); - } - } - + } + } goto release; - } + } /* object not on stack then we need the name */ size = AOP_SIZE (IC_RESULT (ic)); @@ -8930,12 +10023,24 @@ genAddrOf (iCode * ic) while (size--) { char s[SDCC_NAME_MAX]; - if (offset) - sprintf (s, "#(%s >> %d)", - sym->rname, - offset * 8); - else - sprintf (s, "#%s", sym->rname); + if (offset) { + switch (offset) { + case 1: + tsprintf(s,"!his",sym->rname); + break; + case 2: + tsprintf(s,"!hihis",sym->rname); + break; + case 3: + tsprintf(s,"!hihihis",sym->rname); + break; + default: /* should not need this (just in case) */ + sprintf (s, "#(%s >> %d)", + sym->rname, + offset * 8); + } + } else + sprintf (s, "#%s", sym->rname); aopPut (AOP (IC_RESULT (ic)), s, offset++); } @@ -8944,6 +10049,115 @@ release: } +/*-----------------------------------------------------------------*/ +/* genArrayInit - generates code for address of */ +/*-----------------------------------------------------------------*/ +static void +genArrayInit (iCode * ic) +{ + literalList *iLoop; + int ix, count; + int elementSize = 0, eIndex; + unsigned val, lastVal; + sym_link *type; + operand *left=IC_LEFT(ic); + + D (emitcode (";", "genArrayInit ");); + + aopOp (IC_LEFT(ic), ic, FALSE, FALSE); + + if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) + { + // Load immediate value into DPTR. + emitcode("mov", "dptr, %s", + aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE)); + } + else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR) + { +#if 0 + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "Unexpected operand to genArrayInit.\n"); + exit(1); +#else + // a regression because of SDCCcse.c:1.52 + emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); + emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); +#endif + } + + type = operandType(IC_LEFT(ic)); + + if (type && type->next) + { + elementSize = getSize(type->next); + } + else + { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "can't determine element size in genArrayInit.\n"); + exit(1); + } + + iLoop = IC_ARRAYILIST(ic); + lastVal = 0xffff; + + while (iLoop) + { + bool firstpass = TRUE; + + emitcode(";", "store %d x 0x%x to DPTR (element size %d)", + iLoop->count, (int)iLoop->literalValue, elementSize); + + ix = iLoop->count; + + while (ix) + { + symbol *tlbl = NULL; + + count = ix > 256 ? 256 : ix; + + if (count > 1) + { + tlbl = newiTempLabel (NULL); + if (firstpass || (count & 0xff)) + { + emitcode("mov", "b, #!constbyte", count & 0xff); + } + + emitcode ("", "!tlabeldef", tlbl->key + 100); + } + + firstpass = FALSE; + + for (eIndex = 0; eIndex < elementSize; eIndex++) + { + val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff; + if (val != lastVal) + { + emitcode("mov", "a, #!constbyte", val); + lastVal = val; + } + + emitcode("movx", "@dptr, a"); + emitcode("inc", "dptr"); + } + + if (count > 1) + { + emitcode("djnz", "b, !tlabel", tlbl->key + 100); + } + + ix -= count; + } + + iLoop = iLoop->next; + } + + freeAsmop (IC_LEFT(ic), NULL, ic, TRUE); +} + /*-----------------------------------------------------------------*/ /* genFarFarAssign - assignment when both are in far space */ /*-----------------------------------------------------------------*/ @@ -8986,7 +10200,7 @@ genFarFarAssign (operand * result, operand * right, iCode * ic) { /* We can use the '390 auto-toggle feature to good effect here. */ - D(emitcode(";","genFarFarAssign ('390 auto-toggle fun)");); + D(emitcode(";","genFarFarAssign (390 auto-toggle fun)");); emitcode("mov", "dps, #0x21"); /* Select DPTR2 & auto-toggle. */ emitcode ("mov", "dptr,#%s", rSym->rname); /* DP2 = result, DP1 = right, DP1 is current. */ @@ -9002,6 +10216,28 @@ genFarFarAssign (operand * result, operand * right, iCode * ic) } emitcode("mov", "dps, #0"); freeAsmop (right, NULL, ic, FALSE); +#if 0 +some alternative code for processors without auto-toggle +no time to test now, so later well put in...kpb + D(emitcode(";","genFarFarAssign (dual-dptr fun)");); + emitcode("mov", "dps, #0x01"); /* Select DPTR2. */ + emitcode ("mov", "dptr,#%s", rSym->rname); + /* DP2 = result, DP1 = right, DP1 is current. */ + while (size) + { + --size; + emitcode("movx", "a,@dptr"); + if (size) + emitcode("inc", "dptr"); + emitcode("inc", "dps"); + emitcode("movx", "@dptr,a"); + if (size) + emitcode("inc", "dptr"); + emitcode("inc", "dps"); + } + emitcode("mov", "dps, #0"); + freeAsmop (right, NULL, ic, FALSE); +#endif } else { @@ -9065,9 +10301,8 @@ genAssign (iCode * ic) goto release; /* if the result is a bit */ - if (AOP_TYPE (result) == AOP_CRY) + if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */ { - /* if the right size is a literal then we know what the value is */ if (AOP_TYPE (right) == AOP_LIT) @@ -9165,13 +10400,13 @@ genJumpTab (iCode * ic) freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE); jtab = newiTempLabel (NULL); - emitcode ("mov", "dptr,#%05d$", jtab->key + 100); + emitcode ("mov", "dptr,#!tlabel", jtab->key + 100); emitcode ("jmp", "@a+dptr"); - emitcode ("", "%05d$:", jtab->key + 100); + emitcode ("", "!tlabeldef", jtab->key + 100); /* now generate the jump labels */ for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab; jtab = setNextItem (IC_JTLABELS (ic))) - emitcode ("ljmp", "%05d$", jtab->key + 100); + emitcode ("ljmp", "!tlabel", jtab->key + 100); } @@ -9198,7 +10433,8 @@ genCast (iCode * ic) aopOp (result, ic, FALSE, AOP_TYPE (right) == AOP_DPTR); /* if the result is a bit */ - if (AOP_TYPE (result) == AOP_CRY) + // if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */ + if (IS_BITVAR(OP_SYMBOL(result)->type)) { /* if the right size is a literal then we know what the value is */ @@ -9468,24 +10704,24 @@ genDjnz (iCode * ic, iCode * ifx) } emitcode ("dec", "%s", rByte); aopPut(AOP(IC_RESULT(ic)), rByte, 0); - emitcode ("jnz", "%05d$", lbl->key + 100); + emitcode ("jnz", "!tlabel", lbl->key + 100); } else if (IS_AOP_PREG (IC_RESULT (ic))) { emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE)); emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE)); - emitcode ("jnz", "%05d$", lbl->key + 100); + emitcode ("jnz", "!tlabel", lbl->key + 100); } else { - emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE), + emitcode ("djnz", "%s,!tlabel", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE), lbl->key + 100); } - emitcode ("sjmp", "%05d$", lbl1->key + 100); - emitcode ("", "%05d$:", lbl->key + 100); - emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100); - emitcode ("", "%05d$:", lbl1->key + 100); + emitcode ("sjmp", "!tlabel", lbl1->key + 100); + emitcode ("", "!tlabeldef", lbl->key + 100); + emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100); + emitcode ("", "!tlabeldef", lbl1->key + 100); freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); ifx->generated = 1; @@ -9535,6 +10771,225 @@ genReceive (iCode * ic) freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); } +/*-----------------------------------------------------------------*/ +/* genMemcpyX2X - gen code for memcpy xdata to xdata */ +/*-----------------------------------------------------------------*/ +static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc) +{ + operand *from , *to , *count; + symbol *lbl; + + /* we know it has to be 3 parameters */ + assert (nparms == 3); + + to = parms[0]; + from = parms[1]; + count = parms[2]; + + aopOp (from, ic->next, FALSE, FALSE); + + /* get from into DPTR1 */ + emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE)); + emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE)); + } + + freeAsmop (from, NULL, ic, FALSE); + aopOp (to, ic, FALSE, FALSE); + /* get "to" into DPTR */ + /* if the operand is already in dptr + then we do nothing else we move the value to dptr */ + if (AOP_TYPE (to) != AOP_STR) { + /* if already in DPTR then we need to push */ + if (AOP_TYPE(to) == AOP_DPTR) { + emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE)); + emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE)); + emitcode ("pop", "dph"); + emitcode ("pop", "dpl"); + } else { + _startLazyDPSEvaluation (); + /* if this is remateriazable */ + if (AOP_TYPE (to) == AOP_IMMD) { + emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE)); + } else { /* we need to get it byte by byte */ + emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE)); + emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE)); + } + } + _endLazyDPSEvaluation (); + } + } + freeAsmop (to, NULL, ic, FALSE); + + aopOp (count, ic->next->next, FALSE,FALSE); + lbl =newiTempLabel(NULL); + + /* now for the actual copy */ + if (AOP_TYPE(count) == AOP_LIT && + (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) { + emitcode (";","OH! JOY auto increment with djnz (very fast)"); + emitcode ("mov", "dps, #0x21"); /* Select DPTR2 & auto-toggle. */ + emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE)); + emitcode ("","!tlabeldef",lbl->key+100); + if (fromc) { + emitcode ("clr","a"); + emitcode ("movc", "a,@a+dptr"); + } else + emitcode ("movx", "a,@dptr"); + emitcode ("movx", "@dptr,a"); + emitcode ("inc", "dptr"); + emitcode ("inc", "dptr"); + emitcode ("djnz","b,!tlabel",lbl->key+100); + } else { + symbol *lbl1 = newiTempLabel(NULL); + + emitcode (";"," Auto increment but no djnz"); + emitcode ("mov","ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE)); + emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE)); + emitcode ("mov", "dps, #0x21"); /* Select DPTR2 & auto-toggle. */ + emitcode ("","!tlabeldef",lbl->key+100); + if (fromc) { + emitcode ("clr","a"); + emitcode ("movc", "a,@a+dptr"); + } else + emitcode ("movx", "a,@dptr"); + emitcode ("movx", "@dptr,a"); + emitcode ("inc", "dptr"); + emitcode ("inc", "dptr"); + emitcode ("mov","a,b"); + emitcode ("orl","a,ap"); + emitcode ("jz","!tlabel",lbl1->key+100); + emitcode ("mov","a,ap"); + emitcode ("add","a,#0xFF"); + emitcode ("mov","ap,a"); + emitcode ("mov","a,b"); + emitcode ("addc","a,#0xFF"); + emitcode ("mov","b,a"); + emitcode ("sjmp","!tlabel",lbl->key+100); + emitcode ("","!tlabeldef",lbl1->key+100); + } + emitcode ("mov", "dps, #0"); + freeAsmop (count, NULL, ic, FALSE); + +} + +/*-----------------------------------------------------------------*/ +/* genMemsetX - gencode for memSetX data */ +/*-----------------------------------------------------------------*/ +static void genMemsetX(iCode *ic, int nparms, operand **parms) +{ + operand *to , *val , *count; + symbol *lbl; + char *l; + /* we know it has to be 3 parameters */ + assert (nparms == 3); + + to = parms[0]; + val = parms[1]; + count = parms[2]; + + aopOp (to, ic, FALSE, FALSE); + /* get "to" into DPTR */ + /* if the operand is already in dptr + then we do nothing else we move the value to dptr */ + if (AOP_TYPE (to) != AOP_STR) { + /* if already in DPTR then we need to push */ + if (AOP_TYPE(to) == AOP_DPTR) { + emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE)); + emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE)); + emitcode ("pop", "dph"); + emitcode ("pop", "dpl"); + } else { + _startLazyDPSEvaluation (); + /* if this is remateriazable */ + if (AOP_TYPE (to) == AOP_IMMD) { + emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE)); + } else { /* we need to get it byte by byte */ + emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE)); + emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE)); + } + } + _endLazyDPSEvaluation (); + } + } + freeAsmop (to, NULL, ic, FALSE); + + aopOp (val, ic->next->next, FALSE,FALSE); + aopOp (count, ic->next->next, FALSE,FALSE); + lbl =newiTempLabel(NULL); + /* now for the actual copy */ + if (AOP_TYPE(count) == AOP_LIT && + (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) { + l = aopGet(AOP (val), 0, FALSE, FALSE, TRUE); + emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE)); + MOVA(l); + emitcode ("","!tlabeldef",lbl->key+100); + emitcode ("movx", "@dptr,a"); + emitcode ("inc", "dptr"); + emitcode ("djnz","b,!tlabel",lbl->key+100); + } else { + symbol *lbl1 = newiTempLabel(NULL); + + emitcode ("mov","ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE)); + emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE)); + emitcode ("","!tlabeldef",lbl->key+100); + l = aopGet(AOP (val), 0, FALSE, FALSE, TRUE); + MOVA(l); + emitcode ("movx", "a,@dptr"); + emitcode ("inc", "dptr"); + emitcode ("mov","a,b"); + emitcode ("orl","a,ap"); + emitcode ("jz","!tlabel",lbl1->key+100); + emitcode ("mov","a,ap"); + emitcode ("add","a,#0xFF"); + emitcode ("mov","ap,a"); + emitcode ("mov","a,b"); + emitcode ("addc","a,#0xFF"); + emitcode ("mov","b,a"); + emitcode ("sjmp","!tlabel",lbl->key+100); + emitcode ("","!tlabeldef",lbl1->key+100); + } + freeAsmop (count, NULL, ic, FALSE); +} + +/*-----------------------------------------------------------------*/ +/* genBuiltIn - calls the appropriate function to generating code */ +/* for a built in function */ +/*-----------------------------------------------------------------*/ +static void genBuiltIn (iCode *ic) +{ + operand *bi_parms[MAX_BUILTIN_ARGS]; + int nbi_parms; + iCode *bi_iCode; + symbol *bif; + + /* get all the arguments for a built in function */ + bi_iCode = getBuiltinParms(ic,&nbi_parms,bi_parms); + + /* which function is it */ + bif = OP_SYMBOL(IC_LEFT(bi_iCode)); + if (strcmp(bif->name,"__builtin_memcpy_x2x")==0) { + genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,0); + } else if (strcmp(bif->name,"__builtin_memcpy_c2x")==0) { + genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,1); + } else if (strcmp(bif->name,"__builtin_memset_x")==0) { + genMemsetX(bi_iCode,nbi_parms,bi_parms); + } else { + werror(E_INTERNAL_ERROR,"unknown builtin function encountered\n"); + return ; + } + return ; +} + /*-----------------------------------------------------------------*/ /* gen390Code - generate code for Dallas 390 based controllers */ /*-----------------------------------------------------------------*/ @@ -9546,6 +11001,14 @@ gen390Code (iCode * lic) lineHead = lineCurr = NULL; + if (options.model == MODEL_FLAT24) { + fReturnSizeDS390 = 5; + fReturn = fReturn24; + } else { + fReturnSizeDS390 = 4; + fReturn = fReturn16; + options.stack10bit=0; + } #if 0 //REMOVE ME!!! /* print the allocation information */ @@ -9743,12 +11206,12 @@ gen390Code (iCode * lic) break; case GET_VALUE_AT_ADDRESS: - genPointerGet (ic); + genPointerGet (ic,hasInc(IC_LEFT(ic),ic)); break; case '=': if (POINTER_SET (ic)) - genPointerSet (ic); + genPointerSet (ic,hasInc(IC_RESULT(ic),ic)); else genAssign (ic); break; @@ -9774,9 +11237,14 @@ gen390Code (iCode * lic) break; case SEND: - addSet (&_G.sendSet, ic); + if (ic->builtinSEND) genBuiltIn(ic); + else addSet (&_G.sendSet, ic); break; + case ARRAYINIT: + genArrayInit(ic); + break; + default: ic = ic; }