From: kvigor Date: Tue, 29 May 2001 23:21:18 +0000 (+0000) Subject: fix combination of --xstack & ISRs using non-zero banks X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=29f45bc8d565ff6138f0ee39b60b5d7d317a3f75;p=fw%2Fsdcc fix combination of --xstack & ISRs using non-zero banks git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@860 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/ds390/gen.c b/src/ds390/gen.c index a02ac7f7..79dfc23c 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -2046,32 +2046,36 @@ static void 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) - { - if (!ic) - { - werror(E_INTERNAL_ERROR, __FILE__, __LINE__, - "unexpected null IC in saveRBank"); - return; - } - - 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--) @@ -2091,11 +2095,13 @@ 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); + } } /*-----------------------------------------------------------------*/ @@ -2105,21 +2111,22 @@ static void saveRBank (int bank, iCode * ic, bool pushPsw) { int i; - asmop *aop; + asmop *aop = NULL; regs *r = NULL; if (options.useXstack) { - if (!ic) - { - werror(E_INTERNAL_ERROR, __FILE__, __LINE__, - "unexpected null IC in saveRBank"); - return; - } - 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++) @@ -2144,8 +2151,6 @@ 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 { @@ -2154,6 +2159,11 @@ saveRBank (int bank, iCode * ic, bool pushPsw) emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); } + + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } if (ic) { @@ -2513,6 +2523,7 @@ genFunction (iCode * ic) { symbol *sym; sym_link *fetype; + bool switchedPSW = FALSE; D (emitcode (";", "genFunction ");); @@ -2632,8 +2643,6 @@ genFunction (iCode * ic) iCode *i; int ix; - D(emitcode(";", "seeking function calls...");); - for (i = ic; i; i = i->next) { if (i->op == ENDFUNCTION) @@ -2657,8 +2666,6 @@ genFunction (iCode * ic) } else { - D(emitcode(";", "should save bank %d", - SPEC_BANK(detype));); banksToSave |= (1 << SPEC_BANK(detype)); } @@ -2680,7 +2687,21 @@ genFunction (iCode * ic) 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)) @@ -2718,7 +2739,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); @@ -2816,7 +2838,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)) { @@ -2827,7 +2858,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 */ @@ -2861,11 +2891,11 @@ genEndFunction (iCode * ic) /* This ISR uses a non-zero bank. * * Restore any register banks saved by genFunction - * in reverse order/ + * 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)) @@ -2873,6 +2903,14 @@ genEndFunction (iCode * ic) unsaveRBank(ix, NULL, FALSE); } } + + if (options.useXstack) + { + /* Restore bank AFTER calling unsaveRBank, + * since it can trash r0. + */ + emitcode ("pop", "psw"); + } } if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx")) diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 31fecdab..2d70a6af 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -1710,32 +1710,36 @@ static void 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 = mcs51_regWithIdx (R0_IDX);; + } + else + { + aop = newAsmop (0); + r = getFreePtr (ic, &aop, FALSE); + } + emitcode ("mov", "%s,_spx", r->name); + } + if (popPsw) { if (options.useXstack) - { - if (!ic) - { - werror(E_INTERNAL_ERROR, __FILE__, __LINE__, - "unexpected null IC in saveRBank"); - return; - } - - 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 = (mcs51_nRegs - 1); i >= 0; i--) @@ -1755,11 +1759,13 @@ 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); + } } /*-----------------------------------------------------------------*/ @@ -1769,21 +1775,22 @@ static void saveRBank (int bank, iCode * ic, bool pushPsw) { int i; - asmop *aop; + asmop *aop = NULL; regs *r = NULL; if (options.useXstack) { if (!ic) { - werror(E_INTERNAL_ERROR, __FILE__, __LINE__, - "unexpected null IC in saveRBank"); - return; + /* Assume r0 is available for use. */ + r = mcs51_regWithIdx (R0_IDX);; + } + else + { + aop = newAsmop (0); + r = getFreePtr (ic, &aop, FALSE); } - aop = newAsmop (0); - r = getFreePtr (ic, &aop, FALSE); emitcode ("mov", "%s,_spx", r->name); - } for (i = 0; i < mcs51_nRegs; i++) @@ -1808,7 +1815,6 @@ 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 @@ -1819,10 +1825,15 @@ saveRBank (int bank, iCode * ic, bool pushPsw) emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); } + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } + if (ic) { ic->bankSaved = 1; -} + } } /*-----------------------------------------------------------------*/ @@ -2109,6 +2120,7 @@ genFunction (iCode * ic) { symbol *sym; sym_link *fetype; + bool switchedPSW = FALSE; _G.nRegsSaved = 0; /* create the function header */ @@ -2255,7 +2267,21 @@ genFunction (iCode * ic) 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)) @@ -2293,7 +2319,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); @@ -2389,7 +2416,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)) { @@ -2400,7 +2436,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 */ @@ -2434,11 +2469,11 @@ genEndFunction (iCode * ic) /* This ISR uses a non-zero bank. * * Restore any register banks saved by genFunction - * in reverse order/ + * 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)) @@ -2446,6 +2481,14 @@ genEndFunction (iCode * ic) unsaveRBank(ix, NULL, FALSE); } } + + if (options.useXstack) + { + /* Restore bank AFTER calling unsaveRBank, + * since it can trash r0. + */ + emitcode ("pop", "psw"); + } } if (!inExcludeList ("dph"))