X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fgen.c;h=9d27211c2a728064c7ef45bfe326a802140c5ef7;hb=52922c7343d4dfe7122d0d905691513cb2724da7;hp=e2609d6b21f3e8a5a62dd735657a2172215d8758;hpb=7902425be4d2e2f30ea56958a8f812c1fca24625;p=fw%2Fsdcc diff --git a/src/ds390/gen.c b/src/ds390/gen.c index e2609d6b..9d27211c 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -41,7 +41,7 @@ #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 @@ -63,9 +63,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"}; @@ -83,7 +89,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 +132,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); @@ -168,9 +174,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 +292,7 @@ genSetDPTR (int n) } else { + TR_DPTR("#1"); emitcode ("mov", "dps, #0x01"); } } @@ -456,13 +463,16 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (useDP2) { - emitcode ("mov", "dpx1,#0x40"); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx1,#0x40"); + TR_DPTR("#2"); emitcode ("mov", "dph1,#0x00"); emitcode ("mov", "dpl1, a"); } else { - emitcode ("mov", "dpx,#0x40"); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,#0x40"); emitcode ("mov", "dph,#0x00"); emitcode ("mov", "dpl, a"); } @@ -973,6 +983,7 @@ aopGet (asmop * aop, genSetDPTR (1); if (!canClobberACC) { + TR_AP("#1"); emitcode ("xch", "a, %s", DP2_RESULT_REG); } } @@ -1007,6 +1018,7 @@ aopGet (asmop * aop, genSetDPTR (0); if (!canClobberACC) { + TR_AP("#2"); emitcode ("xch", "a, %s", DP2_RESULT_REG); return DP2_RESULT_REG; } @@ -1758,7 +1770,8 @@ saveRegisters (iCode * lic) /* if the registers have been saved already then do nothing */ - if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave)) + if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave) || + SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT(ic)))) return; /* find the registers in use at this time @@ -1796,14 +1809,8 @@ saveRegisters (iCode * lic) } detype = getSpec (operandType (IC_LEFT (ic))); - if (/* why would we do this?: jwk20010511 */ 0 && - 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 */ /*-----------------------------------------------------------------*/ @@ -2038,31 +2045,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 +2100,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 +2156,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); } - ic->bankSaved = 1; - + + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } + + if (ic) + { + ic->bankSaved = 1; + } } /*-----------------------------------------------------------------*/ @@ -2149,31 +2183,40 @@ static void genCall (iCode * ic) { sym_link *detype; - int bankSwitched=0; + bool restoreBank = FALSE; + bool swapBanks = FALSE; 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 && + if (detype && !SPEC_NAKED(detype) && (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype) && - !ic->bankSaved) { - bankSwitched=1; + IS_ISR (currFunc->etype)) + { + if (!ic->bankSaved) + { + /* This is unexpected; the bank should have been saved in + * genFunction. + */ + saveRBank (SPEC_BANK (detype), ic, FALSE); + restoreBank = TRUE; + } + swapBanks = TRUE; } - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) { - if (bankSwitched) { - // no need to save if we switch banks - } else { + /* 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; @@ -2183,31 +2226,50 @@ genCall (iCode * ic) { int size, offset = 0; - aopOp (IC_LEFT (sic), sic, FALSE, TRUE); + 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", - 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); + } + } freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); } _G.sendSet = NULL; - } - - if (bankSwitched) { - saverbank(SPEC_BANK(detype), ic, TRUE); + } + + if (swapBanks) + { + emitcode ("mov", "psw,#0x%02x", + ((SPEC_BANK(detype)) << 3) & 0xff); } /* make the call */ @@ -2215,6 +2277,12 @@ genCall (iCode * ic) OP_SYMBOL (IC_LEFT (ic))->rname : OP_SYMBOL (IC_LEFT (ic))->name)); + if (swapBanks) + { + emitcode ("mov", "psw,#0x%02x", + ((SPEC_BANK(currFunc->etype)) << 3) & 0xff); + } + /* if we need assign a result value */ if ((IS_ITEMP (IC_RESULT (ic)) && (OP_SYMBOL (IC_RESULT (ic))->nRegs || @@ -2270,14 +2338,13 @@ genCall (iCode * ic) emitcode ("dec", "%s", spname); } + /* if we hade saved some registers then unsave them */ + if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave)) + unsaveRegisters (ic); + /* if register bank was saved then pop them */ - if (bankSwitched) { - unsaverbank (SPEC_BANK (detype), ic, TRUE); - } else { - /* if we have saved some registers then unsave them */ - if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave)) - unsaveRegisters (ic); - } + if (restoreBank) + unsaveRBank (SPEC_BANK (detype), ic, FALSE); } /*-----------------------------------------------------------------*/ @@ -2292,6 +2359,7 @@ genPcall (iCode * ic) D (emitcode (";", "genPcall "); ); + /* if caller saves & we have not saved then */ if (!ic->regsSaved) saveRegisters (ic); @@ -2303,7 +2371,8 @@ genPcall (iCode * ic) if (detype && IS_ISR (currFunc->etype) && (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - saverbank (SPEC_BANK (detype), ic, TRUE); + saveRBank (SPEC_BANK (detype), ic, TRUE); + /* push the return address on to the stack */ emitcode ("mov", "a,#%05d$", (rlbl->key + 100)); @@ -2396,7 +2465,7 @@ genPcall (iCode * ic) if (detype && (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - unsaverbank (SPEC_BANK (detype), ic, TRUE); + unsaveRBank (SPEC_BANK (detype), ic, TRUE); /* if we hade saved some registers then unsave them */ @@ -2459,9 +2528,9 @@ genFunction (iCode * ic) { symbol *sym; sym_link *fetype; + bool switchedPSW = FALSE; - D (emitcode (";", "genFunction "); - ); + D (emitcode (";", "genFunction ");); _G.nRegsSaved = 0; /* create the function header */ @@ -2472,6 +2541,12 @@ genFunction (iCode * ic) emitcode ("", "%s:", sym->rname); fetype = getSpec (operandType (IC_LEFT (ic))); + if (SPEC_NAKED(fetype)) + { + emitcode(";", "naked function: no prologue."); + return; + } + /* if critical function then turn interrupts off */ if (SPEC_CRTCL (fetype)) emitcode ("clr", "ea"); @@ -2554,10 +2629,99 @@ 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 (sym->hasFcall) + { + +#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 *detype; + + detype = getSpec(operandType (IC_LEFT(i))); + if (detype + && SPEC_BANK(detype) != SPEC_BANK(sym->etype)) + { + /* Mark this bank for saving. */ + if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS) + { + werror(E_NO_SUCH_BANK, SPEC_BANK(detype)); + } + else + { + banksToSave |= (1 << SPEC_BANK(detype)); + } + + /* 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,#0x%02x", + (SPEC_BANK (sym->etype) << 3) & 0x00ff); + switchedPSW = TRUE; + } + + for (ix = 0; ix < MAX_REGISTER_BANKS; ix++) + { + if (banksToSave & (1 << ix)) + { + saveRBank(ix, NULL, FALSE); + } + } } + SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; } } else @@ -2586,7 +2750,8 @@ genFunction (iCode * ic) } /* set the register bank to the desired value */ - if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + && !switchedPSW) { emitcode ("push", "psw"); emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff); @@ -2649,8 +2814,13 @@ genEndFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); - D (emitcode (";", "genEndFunction "); - ); + D (emitcode (";", "genEndFunction ");); + + if (SPEC_NAKED(sym->etype)) + { + emitcode(";", "naked function: no epilogue."); + return; + } if (IS_RENT (sym->etype) || options.stackAuto) { @@ -2685,7 +2855,16 @@ genEndFunction (iCode * ic) /* restore the register bank */ if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) - emitcode ("pop", "psw"); + { + if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype) + || !options.useXstack) + { + /* Special case of ISR using non-zero bank with useXstack + * is handled below. + */ + emitcode ("pop", "psw"); + } + } if (IS_ISR (sym->etype)) { @@ -2696,7 +2875,6 @@ genEndFunction (iCode * ic) registers :-) */ if (!SPEC_BANK (sym->etype)) { - /* if this function does not call any other function then we can be economical and save only those registers that are used */ @@ -2720,9 +2898,35 @@ 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. + */ + 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"); } } @@ -2751,9 +2955,7 @@ genEndFunction (iCode * ic) 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, @@ -2791,7 +2993,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 ==.", @@ -2843,8 +3045,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); } @@ -3316,7 +3521,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) @@ -3328,13 +3533,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) { @@ -3628,12 +3855,17 @@ genMinus (iCode * ic) else { /* first add without previous c */ - if (!offset) - emitcode ("add", "a,#0x%02x", - (unsigned int) (lit & 0x0FFL)); - else + if (!offset) { + if (!size && lit==-1) { + emitcode ("dec", "a"); + } else { + emitcode ("add", "a,#0x%02x", + (unsigned int) (lit & 0x0FFL)); + } + } else { emitcode ("addc", "a,#0x%02x", (unsigned int) ((lit >> (offset * 8)) & 0x0FFL)); + } } if (pushResult) @@ -3701,11 +3933,10 @@ genMultOneByte (operand * left, 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); + AOP_SIZE(result), __FILE__, lineno); exit (1); } @@ -3739,7 +3970,6 @@ 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); @@ -3750,22 +3980,24 @@ genMultOneByte (operand * left, emitcode ("inc", "a"); emitcode ("", "%05d$:", lbl->key+100); - emitcode ("xch", "a,b"); /* 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,#0x%02x", -val); + } else { + emitcode ("mov", "b,#0x%02x", val); } } else { lbl=newiTempLabel(NULL); + emitcode ("mov", "b,a"); + emitcode ("mov", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE)); emitcode ("jnb", "acc.7,%05d$", 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); @@ -4855,6 +5087,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)); @@ -5134,9 +5367,20 @@ 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)); + 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", "%05d$", tlbl->key + 100); offset++; } @@ -5436,9 +5680,14 @@ 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)); + 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", "%05d$", tlbl->key + 100); offset++; } @@ -5710,9 +5959,14 @@ 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 { + MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); + emitcode ("xrl", "a,%s", + aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); + } } emitcode ("jnz", "%05d$", tlbl->key + 100); offset++; @@ -5778,14 +6032,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 */ @@ -6364,7 +6618,6 @@ AccAXRsh (char *x, int shCount) #endif #ifdef BETTER_LITERAL_SHIFT -//REMOVE ME!!! /*-----------------------------------------------------------------*/ /* AccAXRshS - right shift signed a:x known count (0..7) */ /*-----------------------------------------------------------------*/ @@ -6488,7 +6741,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)); @@ -6502,6 +6755,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. @@ -6586,11 +6840,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); @@ -7164,28 +7418,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); } @@ -7654,7 +7934,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: @@ -7706,7 +7986,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: @@ -7994,7 +8274,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 { @@ -8003,7 +8284,8 @@ 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"); } @@ -8069,7 +8351,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 { @@ -8078,7 +8361,8 @@ 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"); } @@ -8153,16 +8437,24 @@ genGenPointerGet (operand * left, genSetDPTR(0); _flushLazyDPS(); emitcode ("mov", "dph,%s", l); - 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)); + 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 (); } @@ -8666,7 +8958,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 { @@ -8675,7 +8968,8 @@ 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"); } @@ -8741,8 +9035,12 @@ genGenPointerSet (operand * right, { /* 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 (); } @@ -8950,6 +9248,106 @@ 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; + + 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) + { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "Unexpected operand to genArrayInit.\n"); + exit(1); + } + + 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, #0x%x", count & 0xff); + } + + emitcode ("", "%05d$:", tlbl->key + 100); + } + + firstpass = FALSE; + + for (eIndex = 0; eIndex < elementSize; eIndex++) + { + val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff; + if (val != lastVal) + { + emitcode("mov", "a, #0x%x", val); + lastVal = val; + } + + emitcode("movx", "@dptr, a"); + emitcode("inc", "dptr"); + } + + if (count > 1) + { + emitcode("djnz", "b, %05d$", tlbl->key + 100); + } + + ix -= count; + } + + iLoop = iLoop->next; + } + + freeAsmop (IC_LEFT(ic), NULL, ic, TRUE); +} + /*-----------------------------------------------------------------*/ /* genFarFarAssign - assignment when both are in far space */ /*-----------------------------------------------------------------*/ @@ -8992,7 +9390,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. */ @@ -9008,6 +9406,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 { @@ -9552,6 +9972,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 */ @@ -9783,6 +10211,10 @@ gen390Code (iCode * lic) addSet (&_G.sendSet, ic); break; + case ARRAYINIT: + genArrayInit(ic); + break; + default: ic = ic; }