Index: m32r-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m32r-tdep.c,v
retrieving revision 1.32
diff -u -r1.32 m32r-tdep.c
--- m32r-tdep.c	5 Oct 2004 04:07:10 -0000	1.32
+++ m32r-tdep.c	5 Oct 2004 09:26:33 -0000
@@ -258,13 +258,13 @@
 
 static void
 decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit,
-		 CORE_ADDR *pl_endptr)
+		 CORE_ADDR *pl_endptr, unsigned long *framelength)
 {
   unsigned long framesize;
   int insn;
   int op1;
-  int maybe_one_more = 0;
   CORE_ADDR after_prologue = 0;
+  CORE_ADDR after_push = 0;
   CORE_ADDR after_stack_adjust = 0;
   CORE_ADDR current_pc;
 
@@ -275,29 +275,18 @@
     {
       insn = read_memory_unsigned_integer (current_pc, 2);
 
+      if (insn == 0x0000)
+	break;
+
       /* If this is a 32 bit instruction, we dont want to examine its
          immediate data as though it were an instruction */
       if (current_pc & 0x02)
 	{
-	  /* Clear the parallel execution bit from 16 bit instruction */
-	  if (maybe_one_more)
-	    {
-	      /* The last instruction was a branch, usually terminates
-	         the series, but if this is a parallel instruction,
-	         it may be a stack framing instruction */
-	      if (!(insn & 0x8000))
-		{
-		  /* nope, we are really done */
-		  break;
-		}
-	    }
 	  /* decode this instruction further */
 	  insn &= 0x7fff;
 	}
       else
 	{
-	  if (maybe_one_more)
-	    break;		/* This isnt the one more */
 	  if (insn & 0x8000)
 	    {
 	      if (current_pc == scan_limit)
@@ -324,7 +313,7 @@
 		      framesize += insn;
 		    }
 		}
-	      after_prologue = current_pc;
+	      after_push = current_pc + 2;
 	      continue;
 	    }
 	}
@@ -363,17 +352,23 @@
 	  after_prologue = current_pc + 2;
 	  break;		/* end of stack adjustments */
 	}
+
       /* Nop looks like a branch, continue explicitly */
       if (insn == 0x7000)
 	{
 	  after_prologue = current_pc + 2;
 	  continue;		/* nop occurs between pushes */
 	}
+      /* End of prolog if any of these are trap instructions */
+      if ((insn & 0xfff0) == 0x10f0)
+	{
+	  after_prologue = current_pc;
+	  break;
+	}
       /* End of prolog if any of these are branch instructions */
       if ((op1 == 0x7000) || (op1 == 0xb000) || (op1 == 0xf000))
 	{
 	  after_prologue = current_pc;
-	  maybe_one_more = 1;
 	  continue;
 	}
       /* Some of the branch instructions are mixed with other types */
@@ -383,12 +378,14 @@
 	  if ((subop == 0x0ec0) || (subop == 0x0fc0))
 	    {
 	      after_prologue = current_pc;
-	      maybe_one_more = 1;
 	      continue;		/* jmp , jl */
 	    }
 	}
     }
 
+  if (framelength)
+    *framelength = framesize;
+
   if (current_pc >= scan_limit)
     {
       if (pl_endptr)
@@ -400,6 +397,13 @@
 	    {
 	      *pl_endptr = after_stack_adjust;
 	    }
+	  else if (after_push != 0)
+	    /* We did not find a "mv fp,sp", but we DID find
+	       a push.  Is it safe to use that as the
+	       end of the prologue?  I just don't know. */
+	    {
+	      *pl_endptr = after_push;
+	    }
 	  else
 	    /* We reached the end of the loop without finding the end
 	       of the prologue.  No way to win -- we should report failure.  
@@ -409,6 +413,7 @@
 	}
       return;
     }
+
   if (after_prologue == 0)
     after_prologue = current_pc;
 
@@ -419,13 +424,14 @@
 /* Function: skip_prologue
    Find end of function prologue */
 
-#define DEFAULT_SEARCH_LIMIT 44
+#define DEFAULT_SEARCH_LIMIT 128
 
 CORE_ADDR
 m32r_skip_prologue (CORE_ADDR pc)
 {
   CORE_ADDR func_addr, func_end;
   struct symtab_and_line sal;
+  LONGEST return_value;
 
   /* See what the symbol table says */
 
@@ -447,11 +453,15 @@
     }
   else
     func_end = pc + DEFAULT_SEARCH_LIMIT;
-  decode_prologue (pc, func_end, &sal.end);
+
+  /* If pc's location is not readable, just quit. */
+  if (!safe_read_memory_integer (pc, 4, &return_value))
+    return 0;
+
+  decode_prologue (pc, func_end, &sal.end, NULL);
   return sal.end;
 }
 
-
 struct m32r_unwind_cache
 {
   /* The previous frame's inner most stack address.  Used as this
@@ -480,13 +490,14 @@
 m32r_frame_unwind_cache (struct frame_info *next_frame,
 			 void **this_prologue_cache)
 {
-  CORE_ADDR pc;
+  CORE_ADDR pc, scan_limit;
   ULONGEST prev_sp;
   ULONGEST this_base;
-  unsigned long op;
+  unsigned long op, op2;
   int i;
   struct m32r_unwind_cache *info;
 
+
   if ((*this_prologue_cache))
     return (*this_prologue_cache);
 
@@ -496,10 +507,11 @@
 
   info->size = 0;
   info->sp_offset = 0;
-
   info->uses_frame = 0;
+
+  scan_limit = frame_pc_unwind (next_frame);
   for (pc = frame_func_unwind (next_frame);
-       pc > 0 && pc < frame_pc_unwind (next_frame); pc += 2)
+       pc > 0 && pc < scan_limit; pc += 2)
     {
       if ((pc & 2) == 0)
 	{
@@ -513,18 +525,19 @@
 		  short n = op & 0xffff;
 		  info->sp_offset += n;
 		}
-	      else if (((op >> 8) == 0xe4)	/* ld24 r4, xxxxxx; sub sp, r4 */
-		       && get_frame_memory_unsigned (next_frame, pc + 4,
+	      else if (((op >> 8) == 0xe4)
+		       && get_frame_memory_unsigned (next_frame, pc + 2,
 						     2) == 0x0f24)
 		{
+		  /* ld24 r4, xxxxxx; sub sp, r4 */
 		  unsigned long n = op & 0xffffff;
 		  info->sp_offset += n;
-		  pc += 2;
+		  pc += 2;	/* skip sub instruction */
 		}
-	      else
-		break;
 
-	      pc += 2;
+	      if (pc == scan_limit)
+		scan_limit += 2;	/* extend the search */
+	      pc += 2;		/* skip the immediate data */
 	      continue;
 	    }
 	}
@@ -549,12 +562,13 @@
 	  /* mv fp, sp */
 	  info->uses_frame = 1;
 	  info->r13_offset = info->sp_offset;
+	  break;		/* end of stack adjustments */
+	}
+      else if ((op & 0xfff0) == 0x10f0)
+	{
+	  /* end of prologue if this is a trap instruction */
+	  break;		/* end of stack adjustments */
 	}
-      else if (op == 0x7000)
-	/* nop */
-	continue;
-      else
-	break;
     }
 
   info->size = -info->sp_offset;
