From f92669107b65c9939a2ec5dfc5d0fef1d6387478 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Tue, 4 Sep 2007 08:40:18 +0000 Subject: [PATCH] * src/mcs51/peep.c (isCallerSaveFunc, termScanAtFunc): changed function name and behaviour to handle banked functions (scan4op): and use it to fix bug 1786213 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4908 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 6 ++++ src/mcs51/peep.c | 83 +++++++++++++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97e9f7fd..bf0217c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-09-04 Maarten Brock + + * src/mcs51/peep.c (isCallerSaveFunc, termScanAtFunc): changed function + name and behaviour to handle banked functions + (scan4op): and use it to fix bug 1786213 + 2007-09-03 Raphael Neider * device/include/pic16/pic18f248.h, diff --git a/src/mcs51/peep.c b/src/mcs51/peep.c index 213eb788..932fcc90 100644 --- a/src/mcs51/peep.c +++ b/src/mcs51/peep.c @@ -37,7 +37,8 @@ typedef enum S4O_RD_OP, S4O_TERM, S4O_VISITED, - S4O_ABORT + S4O_ABORT, + S4O_CONTINUE } S4O_RET; static struct @@ -215,16 +216,18 @@ isFunc (const lineNode *pl) } /*-----------------------------------------------------------------*/ -/* isCallerSaveFunc - returns TRUE if it's a 'normal' function */ -/* call and it's a 'caller save' (not 'callee save' or 'naked') */ +/* termScanAtFunc - returns S4O_TERM if it's a 'normal' function */ +/* call and it's a 'caller save'. returns S4O_CONTINUE if it's */ +/* 'callee save' or 'naked'. returns S4O_ABORT if it's 'banked' */ +/* uses the register for the destination. */ /*-----------------------------------------------------------------*/ -static bool -isCallerSaveFunc (const lineNode *pl) +static S4O_RET +termScanAtFunc (const lineNode *pl, int rIdx) { sym_link *ftype; if (!isFunc (pl)) - return FALSE; + return S4O_CONTINUE; // let's assume calls to literally given locations use the default // most notably : (*(void (*)()) 0) (); see bug 1749275 if (IS_VALOP (IC_LEFT (pl->ic))) @@ -234,10 +237,13 @@ isCallerSaveFunc (const lineNode *pl) if (IS_FUNCPTR (ftype)) ftype = ftype->next; if (FUNC_CALLEESAVES(ftype)) - return FALSE; + return S4O_CONTINUE; if (FUNC_ISNAKED(ftype)) - return FALSE; - return TRUE; + return S4O_CONTINUE; + if (FUNC_BANKED(ftype) && + (rIdx == R0_IDX) || (rIdx == R1_IDX) || (rIdx == R2_IDX)) + return S4O_ABORT; + return S4O_TERM; } /*-----------------------------------------------------------------*/ @@ -285,10 +291,24 @@ scan4op (lineNode **pl, const char *pReg, const char *untilOp, char *p; int len; bool isConditionalJump; + int rIdx; + S4O_RET ret; /* pReg points to e.g. "ar0"..."ar7" */ len = strlen (pReg); + /* get index into pReg table */ + for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx) + if (strcmp (regs8051[rIdx].name, pReg + 1) == 0) + break; + + /* sanity check */ + if (rIdx >= mcs51_nRegs) + { + D(fprintf (stderr, DEADMOVEERROR);) + return S4O_ABORT; + } + for (; *pl; *pl = (*pl)->next) { if (!(*pl)->line || (*pl)->isDebug || (*pl)->isComment) @@ -328,20 +348,6 @@ scan4op (lineNode **pl, const char *pReg, const char *untilOp, { /* ok, let's have a closer look */ - /* get index into pReg table */ - int rIdx; - - for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx) - if (strcmp (regs8051[rIdx].name, pReg + 1) == 0) - break; - - /* sanity check */ - if (rIdx >= mcs51_nRegs) - { - D(fprintf (stderr, DEADMOVEERROR);) - return S4O_ABORT; - } - /* does opcode read from pReg? */ if (bitVectBitValue (port->peep.getRegsRead ((*pl)), rIdx)) return S4O_RD_OP; @@ -382,8 +388,9 @@ scan4op (lineNode **pl, const char *pReg, const char *untilOp, if (strncmp ("acall", (*pl)->line, 5) == 0) { /* for comments see 'lcall' */ - if (isCallerSaveFunc (*pl)) - return S4O_TERM; + ret = termScanAtFunc (*pl, rIdx); + if (ret != S4O_CONTINUE) + return ret; break; } if (strncmp ("ajmp", (*pl)->line, 4) == 0) @@ -430,20 +437,21 @@ scan4op (lineNode **pl, const char *pReg, const char *untilOp, case 'l': if (strncmp ("lcall", (*pl)->line, 5) == 0) { - if (isCallerSaveFunc (*pl)) - { - /* If it's a 'normal' 'caller save' function call, all - registers have been saved until the 'lcall'. The - 'life range' of all registers end at the lcall, - and we can terminate our search. - */ - return S4O_TERM; - } - /* If it's a 'callee save' function call, registers are saved + ret = termScanAtFunc (*pl, rIdx); + /* If it's a 'normal' 'caller save' function call, all + registers have been saved until the 'lcall'. The + 'life range' of all registers end at the lcall, + and we can terminate our search. + * If the function is 'banked', the registers r0, r1 and r2 + are used to tell the trampoline the destination. After + that their 'life range' ends just like the other registers. + * If it's a 'callee save' function call, registers are saved by the callee. We've got no information, if the register might live beyond the lcall. Therefore we've to continue the search. */ + if (ret != S4O_CONTINUE) + return ret; break; } if (strncmp ("ljmp", (*pl)->line, 4) == 0) @@ -468,8 +476,9 @@ scan4op (lineNode **pl, const char *pReg, const char *untilOp, if (isFunc (*pl)) { /* for comments see 'lcall' */ - if (isCallerSaveFunc (*pl)) - return S4O_TERM; + ret = termScanAtFunc (*pl, rIdx); + if (ret != S4O_CONTINUE) + return ret; break; } -- 2.39.5