Implement pahole-like 'ptype /o' option
[deliverable/binutils-gdb.git] / gdb / ft32-tdep.c
index a988421ec3964cf78105d56f27e9a6080e0a94b5..85c5dd074b8cb4b43c8fa39864d30247525d8723 100644 (file)
@@ -123,7 +123,7 @@ static void
 ft32_store_return_value (struct type *type, struct regcache *regcache,
                         const gdb_byte *valbuf)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR regval;
   int len = TYPE_LENGTH (type);
@@ -139,6 +139,25 @@ ft32_store_return_value (struct type *type, struct regcache *regcache,
     }
 }
 
+/* Fetch a single 32-bit instruction from address a. If memory contains
+   a compressed instruction pair, return the expanded instruction.  */
+
+static ULONGEST
+ft32_fetch_instruction (CORE_ADDR a, int *isize,
+                       enum bfd_endian byte_order)
+{
+  unsigned int sc[2];
+  ULONGEST inst;
+
+  CORE_ADDR a4 = a & ~3;
+  inst = read_code_unsigned_integer (a4, 4, byte_order);
+  *isize = ft32_decode_shortcode (a4, inst, sc) ? 2 : 4;
+  if (*isize == 2)
+    return sc[1 & (a >> 1)];
+  else
+    return inst;
+}
+
 /* Decode the instructions within the given address range.  Decide
    when we must have reached the end of the function prologue.  If a
    frame_info pointer is provided, fill in its saved_regs etc.
@@ -153,6 +172,7 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR next_addr;
   ULONGEST inst;
+  int isize = 0;
   int regnum, pushreg;
   struct bound_minimal_symbol msymbol;
   const int first_saved_reg = 13;      /* The first saved register.  */
@@ -186,16 +206,15 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
     return end_addr;
 
   cache->established = 0;
-  for (next_addr = start_addr; next_addr < end_addr;)
+  for (next_addr = start_addr; next_addr < end_addr; next_addr += isize)
     {
-      inst = read_memory_unsigned_integer (next_addr, 4, byte_order);
+      inst = ft32_fetch_instruction (next_addr, &isize, byte_order);
 
       if (FT32_IS_PUSH (inst))
        {
          pushreg = FT32_PUSH_REG (inst);
          cache->framesize += 4;
          cache->saved_regs[FT32_R0_REGNUM + pushreg] = cache->framesize;
-         next_addr += 4;
        }
       else if (FT32_IS_CALL (inst))
        {
@@ -210,7 +229,6 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
                      cache->saved_regs[FT32_R0_REGNUM + pushreg] =
                        cache->framesize;
                    }
-                 next_addr += 4;
                }
            }
          break;
@@ -229,7 +247,7 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
   /* It is a LINK?  */
   if (next_addr < end_addr)
     {
-      inst = read_memory_unsigned_integer (next_addr, 4, byte_order);
+      inst = ft32_fetch_instruction (next_addr, &isize, byte_order);
       if (FT32_IS_LINK (inst))
        {
          cache->established = 1;
@@ -241,7 +259,7 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
          cache->saved_regs[FT32_PC_REGNUM] = cache->framesize + 4;
          cache->saved_regs[FT32_FP_REGNUM] = 0;
          cache->framesize += FT32_LINK_SIZE (inst);
-         next_addr += 4;
+         next_addr += isize;
        }
     }
 
@@ -400,7 +418,7 @@ static void
 ft32_extract_return_value (struct type *type, struct regcache *regcache,
                           gdb_byte *dst)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   bfd_byte *valbuf = dst;
   int len = TYPE_LENGTH (type);
@@ -598,7 +616,7 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Create a type for PC.  We can't use builtin types here, as they may not
      be defined.  */
-  void_type = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
+  void_type = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
   func_void_type = make_function_type (void_type, NULL);
   tdep->pc_type = arch_pointer_type (gdbarch, 4 * TARGET_CHAR_BIT, NULL,
                                     func_void_type);
This page took 0.025569 seconds and 4 git commands to generate.