diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index 8442c76..43c47d9 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -20,6 +20,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "inferior.h"
 #include "arch-utils.h"
 #include "prologue-value.h"
 #include "target.h"
@@ -57,6 +58,7 @@ enum
 
 /* RX frame types.  */
 enum rx_frame_type {
+  RX_FRAME_TYPE_NONE,			/* For frame type cache. */
   RX_FRAME_TYPE_NORMAL,
   RX_FRAME_TYPE_EXCEPTION,
   RX_FRAME_TYPE_FAST_INTERRUPT
@@ -451,6 +453,80 @@ rx_analyze_frame_prologue (struct frame_info *this_frame,
   return *this_prologue_cache;
 }
 
+/* Frame Type Cache.  Scanning memory for return instructions can be
+   slow.  This is a simple cache implemention which speeds things up
+   a bit.  */
+
+static const struct inferior_data *rx_frame_type_cache_key;
+
+struct rx_frame_type_cache
+{
+  CORE_ADDR addr;
+  enum rx_frame_type frame_type;
+};
+
+/* Free data structure associated with a frame type cache.  */
+
+static void
+rx_frame_type_cache_cleanup (struct inferior *inf, void *data)
+{
+  xfree (data);
+}
+
+/* Fetch frame type cache associated with current inferior.  */
+
+static struct rx_frame_type_cache *
+get_rx_frame_type_cache (void)
+{
+  struct inferior *inf = current_inferior ();
+  struct rx_frame_type_cache *cache
+    = inferior_data (inf, rx_frame_type_cache_key);
+
+  if (cache == NULL)
+    {
+      cache = XCNEWVEC (struct rx_frame_type_cache, 256);
+      set_inferior_data (inf, rx_frame_type_cache_key, cache);
+    }
+
+  gdb_assert (cache != NULL);
+
+  return cache;
+}
+
+/* Compute hash index for address ADDR.  */
+
+static int
+rx_frame_type_cache_hash_index (CORE_ADDR addr)
+{
+  return (addr + (addr >> 8) + (addr >> 16)) & 0xff;
+}
+
+/* Look up address ADDR in the frame type cache.  Return the frame
+   type if found, otherwise return RX_FRAME_TYPE_NONE.  */
+
+static enum rx_frame_type
+rx_frame_type_cache_lookup (CORE_ADDR addr)
+{
+  struct rx_frame_type_cache *c = get_rx_frame_type_cache ()
+                                + rx_frame_type_cache_hash_index (addr);
+
+  if (c->addr == addr)
+    return c->frame_type;
+  else
+    return RX_FRAME_TYPE_NONE;
+}
+
+/* Set cache entry for address ADDR using frame type FRAME_TYPE.  */
+
+static void
+rx_frame_type_cache_set (CORE_ADDR addr, enum rx_frame_type frame_type)
+{
+  struct rx_frame_type_cache *c = get_rx_frame_type_cache ()
+                                + rx_frame_type_cache_hash_index (addr);
+  c->addr = addr;
+  c->frame_type = frame_type;
+}
+
 /* Determine type of frame by scanning the function for a return
    instruction.  */
 
@@ -462,10 +538,11 @@ rx_frame_type (struct frame_info *this_frame, void **this_cache)
   int bytes_read;
   struct rx_get_opcode_byte_handle opcode_handle;
   RX_Opcode_Decoded opc;
+  enum rx_frame_type frame_type;
 
   gdb_assert (this_cache != NULL);
 
-  /* If we have a cached value, return it.  */
+  /* If we have a cached value in the prologue cache, return it.  */
 
   if (*this_cache != NULL)
     {
@@ -474,8 +551,9 @@ rx_frame_type (struct frame_info *this_frame, void **this_cache)
       return p->frame_type;
     }
 
-  /* No cached value; scan the function.  The frame type is cached in
-     rx_analyze_prologue / rx_analyze_frame_prologue.  */
+  /* No cached value; prepare to scan the function.  The frame type is
+     cached (in the prologue cache data structure) in rx_analyze_prologue 
+     and rx_analyze_frame_prologue.  */
   
   pc = get_frame_pc (this_frame);
   
@@ -485,6 +563,16 @@ rx_frame_type (struct frame_info *this_frame, void **this_cache)
   if (!find_pc_partial_function (pc, &name, &start_pc, &lim_pc))
     lim_pc = pc + 20;
 
+  /* See if frame type has been cached in per-inferior cache for
+     lim_pc.  Return that value if found.  */
+  frame_type = rx_frame_type_cache_lookup (lim_pc);
+  if (frame_type != RX_FRAME_TYPE_NONE)
+    return frame_type;
+
+  /* Frame type has not been cached in either the prologue cache data
+     structure or the per-inferior cache.  Scan instruction stream up
+     to lim_pc for some type of return instruction.  */
+  frame_type = RX_FRAME_TYPE_NORMAL;
   while (pc < lim_pc)
     {
       opcode_handle.pc = pc;
@@ -492,16 +580,28 @@ rx_frame_type (struct frame_info *this_frame, void **this_cache)
 				     &opcode_handle);
 
       if (bytes_read <= 0 || opc.id == RXO_rts)
-	return RX_FRAME_TYPE_NORMAL;
+	{
+	  frame_type = RX_FRAME_TYPE_NORMAL;
+	  break;
+	}
       else if (opc.id == RXO_rtfi)
-	return RX_FRAME_TYPE_FAST_INTERRUPT;
+	{
+	  frame_type = RX_FRAME_TYPE_FAST_INTERRUPT;
+	  break;
+	}
       else if (opc.id == RXO_rte)
-        return RX_FRAME_TYPE_EXCEPTION;
+	{
+	  frame_type = RX_FRAME_TYPE_EXCEPTION;
+	  break;
+	}
 
       pc += bytes_read;
     }
 
-  return RX_FRAME_TYPE_NORMAL;
+  /* Cache result in the per-inferior frame type cache.  */
+  rx_frame_type_cache_set (lim_pc, frame_type);
+
+  return frame_type;
 }
 
 
@@ -1158,4 +1258,7 @@ void
 _initialize_rx_tdep (void)
 {
   register_gdbarch_init (bfd_arch_rx, rx_gdbarch_init);
+
+  rx_frame_type_cache_key
+    = register_inferior_data_with_cleanup (NULL, rx_frame_type_cache_cleanup);
 }
