From: tecodev Date: Sat, 28 Feb 2009 19:09:08 +0000 (+0000) Subject: * src/regression/compare10.c, X-Git-Url: https://git.gag.com/?p=fw%2Fsdcc;a=commitdiff_plain;h=7fb75bed98623e6e54e05ef78ab971f80f11f311 * src/regression/compare10.c, src/regression/compare7.c, src/regression/compare8.c, src/regression/compare9.c: reset watchdog timer in time * src/pic/glue.c (pic14createInterruptVect): pin RESET vector handler to 0x0000 as the linker no longer knows STARTUP sections * src/pic/pcode.c (register_reassign, ReuseReg): applied modified patch #2512926 to (mostly) fix #1762626, cosmetic changes * src/pic/pcodepeep.c: remove reference to nonexisting function git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5394 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 077d2dcc..97a730fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2009-02-28 Raphael Neider + + * src/regression/compare10.c, + src/regression/compare7.c, + src/regression/compare8.c, + src/regression/compare9.c: reset watchdog timer in time + * src/pic/glue.c (pic14createInterruptVect): pin RESET vector + handler to 0x0000 as the linker no longer knows STARTUP sections + * src/pic/pcode.c (register_reassign, ReuseReg): applied modified + patch #2512926 to (mostly) fix #1762626, cosmetic changes + * src/pic/pcodepeep.c: remove reference to nonexisting function + 2009-02-28 Raphael Neider * device/include/pic16/signal.h: avoid multiline inline diff --git a/src/pic/glue.c b/src/pic/glue.c index 50b9ba17..41afbc4c 100644 --- a/src/pic/glue.c +++ b/src/pic/glue.c @@ -262,7 +262,8 @@ pic14createInterruptVect (struct dbuf_s * vBuf) dbuf_printf (vBuf, "%s", iComments2); dbuf_printf (vBuf, "; reset vector \n"); dbuf_printf (vBuf, "%s", iComments2); - dbuf_printf (vBuf, "STARTUP\t%s\n", CODE_NAME); // Lkr file should place section STARTUP at address 0x0 + // Lkr file should place section STARTUP at address 0x0, but does not ... + dbuf_printf (vBuf, "STARTUP\t%s 0x0000\n", CODE_NAME); dbuf_printf (vBuf, "\tnop\n"); /* first location for used by incircuit debugger */ dbuf_printf (vBuf, "\tpagesel __sdcc_gsinit_startup\n"); dbuf_printf (vBuf, "\tgoto\t__sdcc_gsinit_startup\n"); diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 43a97d7a..b97ff171 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -4743,77 +4743,139 @@ static void InitReuseReg(void) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static unsigned register_reassign(pBlock *pb, unsigned idx, unsigned level) +static unsigned +register_reassign(pBlock *pb, unsigned startIdx, unsigned level) { - pCode *pc; + pCode *pc; + unsigned temp; + unsigned idx = startIdx; - /* check recursion */ - pc = setFirstItem(pb->function_entries); - if(!pc) - return idx; + /* check recursion */ + pc = setFirstItem(pb->function_entries); + if (!pc) + return idx; - if (pb->visited) { - /* TODO: Recursion detection missing, should emit a warning as recursive code will fail. */ - return idx; - } + if (pb->visited) + { + set *regset; + /* TODO: Recursion detection missing, should emit a warning as recursive code will fail. */ + + // Find the highest rIdx used by this function for return. + regset = pb->tregisters; + idx = 0; + while (regset) + { + temp = ((regs *)regset->item)->rIdx; + if (temp > idx) + idx = temp; + regset = regset->next; + } // while + DFPRINTF((stderr, + "%*s(%u) function \"%s\" already visited: max idx = %04x\n", + 4 * level, "", level,PCF(pc)->fname, idx)); + return idx + 1; + } // if - pb->visited = 1; + /* + * We now traverse the call tree depth first, assigning indices > startIdx + * to the registers of all called functions before assigning indices to + * the registers of the calling function, starting with one greater than + * the max. index used by any child function. + * This approach guarantees that, if f calls g, all registers of f have + * greater indices than those of g (also holds transitively). + * + * XXX: If a function f calls a function g in a different module, + * we should handle the case that g could call a function h + * in f's module. + * The consequence of this is that even though f and h might + * share registers (they do not call each other locally) when + * looking only at f's module, they actually must not do so! + * + * For a non-static function f, let ES(f) be the set of functions + * (including f) that can only be reached via f in the module-local + * call graph (ES(f) will hence be a subgraph). + * Let further REG(ES(f)) be the set of registers assigned to + * functions in ES(f). + * Then we should make sure that REG(ES(f)) and REG(ES(g)) are + * disjoint for all non-static functions f and g. + * + * Unfortunately, determining the sets ES(f) is non-trivial, + * so we ignore this problem and declare all modules non-reentrant. + * This is a bug. + */ + pb->visited = 1; + + DFPRINTF((stderr, + "%*s(%u) reassigning registers for functions called by \"%s\":base idx = %04x\n", + 4 * level, "", level, PCF(pc)->fname, startIdx)); + + for (pc = setFirstItem(pb->function_calls); pc; pc = setNextItem(pb->function_calls)) + { + if (pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) + { + char *dest = get_op_from_instruction(PCI(pc)); + pCode *pcn = findFunction(dest); + + if (pcn) + { + /* + * Reassign the registers of all called functions and record + * the max. index I used by any child function --> I+1 will be + * the first index available to this function. + * (Problem shown with regression test src/regression/sub2.c) + */ + unsigned childsMaxIdx; + childsMaxIdx = register_reassign(pcn->pb,startIdx,level+1); + if (childsMaxIdx > idx) + idx = childsMaxIdx; + } // if + } // if + } // for - DFPRINTF((stderr," (%u) reassigning registers for function \"%s\"\n",level,PCF(pc)->fname)); + pc = setFirstItem(pb->function_entries); + DFPRINTF((stderr, + "%*s(%u) reassigning registers for function \"%s\":idx = %04x\n", + 4 * level, "", level, PCF(pc)->fname, idx)); - if (pb->tregisters) { - regs *r; - for (r = setFirstItem(pb->tregisters); r; r = setNextItem(pb->tregisters)) { - if (r->type == REG_GPR) { - if (!r->isFixed) { - if (r->rIdx < (int)idx) { - char s[20]; - set *regset; - // make sure, idx is not yet used in this routine... - do { - regset = pb->tregisters; - // do not touch s->curr ==> outer loop! - while (regset && ((regs *)regset->item)->rIdx != idx) { - regset = regset->next; - } - if (regset) idx++; - } while (regset); - r->rIdx = idx++; - if (peakIdx < idx) peakIdx = idx; - sprintf(s,"r0x%02X", r->rIdx); - DFPRINTF((stderr," (%u) reassigning register %p \"%s\" to \"%s\"\n",level,r,r->name,s)); - free(r->name); - r->name = Safe_strdup(s); - } - } - } - } - } - for(pc = setFirstItem(pb->function_calls); pc; pc = setNextItem(pb->function_calls)) { - - if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) { - char *dest = get_op_from_instruction(PCI(pc)); - - pCode *pcn = findFunction(dest); - if(pcn) { - /* This index increment from subroutines is not required, as all subroutines - * may share registers NOT used by this one (< idx). - * BUT if called functions A and B share a register, which gets assigned - * rIdx = idx + 4 while analyzing A, we must not assign idx + 4 again while - * analyzing B! - * As an alternative to this "solution" we could check above whether an - * to-be-assigned rIdx is already present in the register set of the - * current function. This would increase the reused registers and make this - * `idx =' irrelevant. - * UPDATE: Implemented above; not fast, but works. - * (Problem shown with regression test src/regression/sub2.c) - */ - /*idx = */register_reassign(pcn->pb,idx,level+1); - } - } - } + if (pb->tregisters) + { + regs *r; + for (r = setFirstItem(pb->tregisters); r; r = setNextItem(pb->tregisters)) + { + if ((r->type == REG_GPR) && (!r->isFixed) && (r->rIdx < (int)idx)) + { + char s[20]; + set *regset; + /* + * Make sure, idx is not yet used in this routine ... + * XXX: This should no longer be required, as all functions + * are reassigned at most once ... + */ + do + { + regset = pb->tregisters; + // do not touch s->curr ==> outer loop! + while (regset && ((regs *)regset->item)->rIdx != idx) + regset = regset->next; + if (regset) + idx++; + } + while (regset); + r->rIdx = idx++; + if (peakIdx < idx) + peakIdx = idx; + sprintf(s,"r0x%02X", r->rIdx); + DFPRINTF((stderr, + "%*s(%u) reassigning register %p \"%s\" to \"%s\"\n", + 4 * level, "", level, r, r->name, s)); + free(r->name); + r->name = Safe_strdup(s); + } // if + } // for + } // if - return idx; + /* return lowest index available for caller's registers */ + return idx; } /*------------------------------------------------------------------*/ @@ -4837,16 +4899,26 @@ static unsigned register_reassign(pBlock *pb, unsigned idx, unsigned level) /* Note for this to work the functions need to be declared static. */ /* */ /*------------------------------------------------------------------*/ -void ReuseReg(void) +void +ReuseReg(void) { - pBlock *pb; - if (options.noOverlay || !the_pFile) return; - InitReuseReg(); - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - /* Non static functions can be called from other modules so their registers must reassign */ - if (pb->function_entries && (PCF(setFirstItem(pb->function_entries))->isPublic || !pb->visited)) - register_reassign(pb,peakIdx,0); - } + pBlock *pb; + + if (options.noOverlay || !the_pFile) + return; + + InitReuseReg(); + + for(pb = the_pFile->pbHead; pb; pb = pb->next) + { + /* Non static functions can be called from other modules, + * so their registers must reassign */ + if (pb->function_entries + && (PCF(setFirstItem(pb->function_entries))->isPublic || !pb->visited)) + { + register_reassign(pb,peakIdx,0); + } // if + } // for } /*-----------------------------------------------------------------*/ diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index 12915893..c3f3602d 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -1878,7 +1878,7 @@ int pCodePeepMatchRule(pCode *pc) inefficient code with the optimized version */ #ifdef PCODE_DEBUG DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n")); - printpCodeString(stderr,peepBlock->target.pb->pcHead,10); + //printpCodeString(stderr,peepBlock->target.pb->pcHead,10); DFPRINTF((stderr,"first thing matched\n")); pc->print(stderr,pc); if(pcin) { diff --git a/src/regression/compare10.c b/src/regression/compare10.c index b7178eb3..b3ed5cb6 100644 --- a/src/regression/compare10.c +++ b/src/regression/compare10.c @@ -312,8 +312,11 @@ void main (void) { char_compare(); + __asm clrwdt __endasm; int_compare1(); + __asm clrwdt __endasm; int_compare2(); + __asm clrwdt __endasm; done (); } diff --git a/src/regression/compare7.c b/src/regression/compare7.c index 5f0f6ad5..1c025c64 100644 --- a/src/regression/compare7.c +++ b/src/regression/compare7.c @@ -301,8 +301,11 @@ void main (void) { char_compare(); + __asm clrwdt __endasm; int_compare1(); + __asm clrwdt __endasm; int_compare2(); + __asm clrwdt __endasm; done (); } diff --git a/src/regression/compare8.c b/src/regression/compare8.c index f7b1b4a8..19da23a4 100644 --- a/src/regression/compare8.c +++ b/src/regression/compare8.c @@ -312,8 +312,11 @@ void main (void) { char_compare(); + __asm clrwdt __endasm; int_compare1(); + __asm clrwdt __endasm; int_compare2(); + __asm clrwdt __endasm; done (); } diff --git a/src/regression/compare9.c b/src/regression/compare9.c index 96e76827..d8caad0e 100644 --- a/src/regression/compare9.c +++ b/src/regression/compare9.c @@ -295,8 +295,11 @@ void main (void) { char_compare(); + __asm clrwdt __endasm; int_compare1(); + __asm clrwdt __endasm; int_compare2(); + __asm clrwdt __endasm; done (); }