* src/regression/compare10.c,
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 28 Feb 2009 19:09:08 +0000 (19:09 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 28 Feb 2009 19:09:08 +0000 (19:09 +0000)
  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

ChangeLog
src/pic/glue.c
src/pic/pcode.c
src/pic/pcodepeep.c
src/regression/compare10.c
src/regression/compare7.c
src/regression/compare8.c
src/regression/compare9.c

index 077d2dccbd06ace8ccc406a9638aef99fd039d51..97a730fdacaa1c0a4013c128ad19ebf840ce889d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-02-28 Raphael Neider <rneider AT web.de>
+
+       * 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 <rneider AT web.de>
 
        * device/include/pic16/signal.h: avoid multiline inline
index 50b9ba17e5daa3bfa708b12a927f1173d2c53e6e..41afbc4c75fe85a19a481c2309137d5682d0a6a8 100644 (file)
@@ -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");
index 43a97d7a9c6aa4ed3dbdd59dd226ef22f1da3e89..b97ff171e477bf22c313c255df3c82c34aac0f23 100644 (file)
@@ -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
 }
 
 /*-----------------------------------------------------------------*/
index 129158937e6f6e782c6f669e0a0e5dc533c6afe0..c3f3602d44f9da1102da2881129722cc36d891a6 100644 (file)
@@ -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) {
index b7178eb389832b155db5c2181bc2ee35f62d3f3b..b3ed5cb6a262e793be4f63a6433a4626035ef311 100644 (file)
@@ -312,8 +312,11 @@ void
 main (void)
 {
   char_compare();
+  __asm clrwdt __endasm;
   int_compare1();
+  __asm clrwdt __endasm;
   int_compare2();
+  __asm clrwdt __endasm;
 
   done ();
 }
index 5f0f6ad5aa29cce340ba28844fa00f3f5c9a65f3..1c025c6486cad1603ff11c4026419c7e2cd3bec5 100644 (file)
@@ -301,8 +301,11 @@ void
 main (void)
 {
   char_compare();
+  __asm clrwdt __endasm;
   int_compare1();
+  __asm clrwdt __endasm;
   int_compare2();
+  __asm clrwdt __endasm;
 
   done ();
 }
index f7b1b4a83424c097cdd55ca63664d025b89c03a5..19da23a4825cfab1afff4f2318e33c983cb8b83d 100644 (file)
@@ -312,8 +312,11 @@ void
 main (void)
 {
   char_compare();
+  __asm clrwdt __endasm;
   int_compare1();
+  __asm clrwdt __endasm;
   int_compare2();
+  __asm clrwdt __endasm;
 
   done ();
 }
index 96e7682766b82463b1f28e8213137369af9f5ed1..d8caad0e8a2940af6ae133741a66fe85bf119b9b 100644 (file)
@@ -295,8 +295,11 @@ void
 main (void)
 {
   char_compare();
+  __asm clrwdt __endasm;
   int_compare1();
+  __asm clrwdt __endasm;
   int_compare2();
+  __asm clrwdt __endasm;
 
   done ();
 }