2004-01-07 Michael Chastain <mec.gnu@mindspring.com>
[deliverable/binutils-gdb.git] / gdb / h8300-tdep.c
index 1253b4d6ca15f0da935c04fb82fb8840f5f29b29..4a66d806a511e5326f1f0d3d20c5a5fe6319d0a4 100644 (file)
@@ -1,4 +1,4 @@
-/* Target-machine dependent code for Hitachi H8/300, for GDB.
+/* Target-machine dependent code for Renesas H8/300, for GDB.
 
    Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
    1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@@ -35,6 +35,7 @@
 #include "objfiles.h"
 #include "gdbcmd.h"
 #include "gdb_assert.h"
+#include "dis-asm.h"
 
 /* Extra info which is saved in each frame_info. */
 struct frame_extra_info
@@ -48,7 +49,14 @@ enum
   h8300h_reg_size = 4,
   h8300_max_reg_size = 4,
 };
-#define BINWORD (h8300hmode ? h8300h_reg_size : h8300_reg_size)
+
+static int is_h8300hmode (struct gdbarch *gdbarch);
+static int is_h8300smode (struct gdbarch *gdbarch);
+static int is_h8300sxmode (struct gdbarch *gdbarch);
+static int is_h8300_normal_mode (struct gdbarch *gdbarch);
+
+#define BINWORD (is_h8300hmode (current_gdbarch) && \
+                 !is_h8300_normal_mode (current_gdbarch) ? h8300h_reg_size : h8300_reg_size)
 
 enum gdb_regnum
 {
@@ -320,11 +328,11 @@ h8300_next_prologue_insn (CORE_ADDR addr,
  */
 
 static CORE_ADDR
-h8300_examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
+h8300_examine_prologue (CORE_ADDR ip, CORE_ADDR limit,
                        CORE_ADDR after_prolog_fp, CORE_ADDR *fsr,
                        struct frame_info *fi)
 {
-  register CORE_ADDR next_ip;
+  CORE_ADDR next_ip;
   int r;
   int have_fp = 0;
   unsigned short insn_word;
@@ -349,7 +357,8 @@ h8300_examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
     }
 
   /* If the PC isn't valid, quit now.  */
-  if (ip == 0 || ip & (h8300hmode ? ~0xffffff : ~0xffff))
+  if (ip == 0 || ip & (is_h8300hmode (current_gdbarch) &&
+                        !is_h8300_normal_mode (current_gdbarch) ? ~0xffffff : ~0xffff))
     return 0;
 
   next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
@@ -477,7 +486,7 @@ h8300_frame_init_saved_regs (struct frame_info *fi)
 {
   CORE_ADDR func_addr, func_end;
 
-  if (!get_frame_saved_regs (fi))
+  if (!deprecated_get_frame_saved_regs (fi))
     {
       frame_saved_regs_zalloc (fi);
 
@@ -491,7 +500,7 @@ h8300_frame_init_saved_regs (struct frame_info *fi)
            ? sal.end : get_frame_pc (fi);
          /* This will fill in fields in fi. */
          h8300_examine_prologue (func_addr, limit, get_frame_base (fi),
-                                 get_frame_saved_regs (fi), fi);
+                                 deprecated_get_frame_saved_regs (fi), fi);
        }
       /* Else we're out of luck (can't debug completely stripped code). 
         FIXME. */
@@ -520,7 +529,7 @@ h8300_frame_chain (struct frame_info *thisframe)
                                        E_PC_REGNUM);
       return get_frame_base (thisframe);
     }
-  return get_frame_saved_regs (thisframe)[E_SP_REGNUM];
+  return deprecated_get_frame_saved_regs (thisframe)[E_SP_REGNUM];
 }
 
 /* Return the saved PC from this frame.
@@ -558,12 +567,6 @@ h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
     }
 }
 
-/* Round N up or down to the nearest multiple of UNIT.
-   Evaluate N only once, UNIT several times.
-   UNIT must be a power of two.  */
-#define round_up(n, unit)   (((n) + (unit) - 1) & -(unit))
-#define round_down(n, unit) ((n) & -(unit))
-
 /* Function: push_dummy_call
    Setup the function arguments for calling a function in the inferior.
    In this discussion, a `word' is 16 bits on the H8/300s, and 32 bits
@@ -640,12 +643,12 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   int argument;
 
   /* First, make sure the stack is properly aligned.  */
-  sp = round_down (sp, wordsize);
+  sp = align_down (sp, wordsize);
 
   /* Now make sure there's space on the stack for the arguments.  We
      may over-allocate a little here, but that won't hurt anything.  */
   for (argument = 0; argument < nargs; argument++)
-    stack_alloc += round_up (TYPE_LENGTH (VALUE_TYPE (args[argument])),
+    stack_alloc += align_up (TYPE_LENGTH (VALUE_TYPE (args[argument])),
                              wordsize);
   sp -= stack_alloc;
 
@@ -664,7 +667,7 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
       char *contents = (char *) VALUE_CONTENTS (args[argument]);
 
       /* Pad the argument appropriately.  */
-      int padded_len = round_up (len, wordsize);
+      int padded_len = align_up (len, wordsize);
       char *padded = alloca (padded_len);
 
       memset (padded, 0, padded_len);
@@ -748,11 +751,11 @@ h8300_pop_frame (void)
        {
          /* Don't forget E_SP_REGNUM is a frame_saved_regs struct is the
             actual value we want, not the address of the value we want.  */
-         if (get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
+         if (deprecated_get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
            write_register (regno,
                            read_memory_integer 
-                           (get_frame_saved_regs (frame)[regno], BINWORD));
-         else if (get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
+                           (deprecated_get_frame_saved_regs (frame)[regno], BINWORD));
+         else if (deprecated_get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
            write_register (regno, get_frame_base (frame) + 2 * BINWORD);
        }
 
@@ -771,7 +774,7 @@ h8300_extract_return_value (struct type *type, struct regcache *regcache,
                            void *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  ULONGEST c;
+  ULONGEST c, addr;
 
   switch (len)
     {
@@ -786,9 +789,17 @@ h8300_extract_return_value (struct type *type, struct regcache *regcache,
        regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
        store_unsigned_integer ((void*)((char *)valbuf + 2), 2, c);
        break;
-      case 8:          /* long long, double and long double are all defined
-                          as 4 byte types so far so this shouldn't happen. */
-       error ("I don't know how a 8 byte value is returned.");
+      case 8:  /* long long is now 8 bytes.  */
+       if (TYPE_CODE (type) == TYPE_CODE_INT)
+         {
+           regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
+           c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
+           store_unsigned_integer (valbuf, len, c);
+         }
+       else
+         {
+           error ("I don't know how this 8 byte value is returned.");
+         }
        break;
     }
 }
@@ -798,7 +809,7 @@ h8300h_extract_return_value (struct type *type, struct regcache *regcache,
                            void *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  ULONGEST c;
+  ULONGEST c, addr;
 
   switch (len)
     {
@@ -808,9 +819,17 @@ h8300h_extract_return_value (struct type *type, struct regcache *regcache,
        regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
        store_unsigned_integer (valbuf, len, c);
        break;
-      case 8:          /* long long, double and long double are all defined
-                          as 4 byte types so far so this shouldn't happen. */
-       error ("I don't know how a 8 byte value is returned.");
+      case 8:  /* long long is now 8 bytes.  */
+       if (TYPE_CODE (type) == TYPE_CODE_INT)
+         {
+           regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
+           c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
+           store_unsigned_integer (valbuf, len, c);
+         }
+       else
+         {
+           error ("I don't know how this 8 byte value is returned.");
+         }
        break;
     }
 }
@@ -830,19 +849,19 @@ h8300_store_return_value (struct type *type, struct regcache *regcache,
   switch (len)
     {
       case 1:
-      case 2:
+    case 2:    /* short... */
        val = extract_unsigned_integer (valbuf, len);
        regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
        break;
-      case 4:                  /* long, float */
+      case 4:  /* long, float */
        val = extract_unsigned_integer (valbuf, len);
        regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM,
                                        (val >> 16) &0xffff);
        regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff);
        break;
-      case 8:          /* long long, double and long double are all defined
-                            as 4 byte types so far so this shouldn't happen. */
-       error ("I don't know how to return a 8 byte value.");
+      case 8:  /* long long, double and long double are all defined
+                  as 4 byte types so far so this shouldn't happen.  */
+       error ("I don't know how to return an 8 byte value.");
        break;
     }
 }
@@ -858,13 +877,13 @@ h8300h_store_return_value (struct type *type, struct regcache *regcache,
     {
       case 1:
       case 2:
-      case 4:                  /* long, float */
+      case 4:  /* long, float */
        val = extract_unsigned_integer (valbuf, len);
        regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
        break;
-      case 8:          /* long long, double and long double are all defined
-                            as 4 byte types so far so this shouldn't happen. */
-       error ("I don't know how to return a 8 byte value.");
+      case 8:  /* long long, double and long double are all defined
+                  as 4 byte types so far so this shouldn't happen.  */
+       error ("I don't know how to return an 8 byte value.");
        break;
     }
 }
@@ -933,10 +952,11 @@ h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
   if (!name || !*name)
     return;
 
-  frame_read_signed_register (frame, regno, &rval);
+  rval = get_frame_register_signed (frame, regno);
 
   fprintf_filtered (file, "%-14s ", name);
-  if (regno == E_PSEUDO_CCR_REGNUM || (regno == E_PSEUDO_EXR_REGNUM && h8300smode))
+  if (regno == E_PSEUDO_CCR_REGNUM ||
+       (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
     {
       fprintf_filtered (file, "0x%02x        ", (unsigned char)rval);
       print_longest (file, 'u', 1, rval);
@@ -985,7 +1005,7 @@ h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
       if ((Z | (N ^ V)) == 1)
        fprintf_filtered (file, "<= ");
     }
-  else if (regno == E_PSEUDO_EXR_REGNUM && h8300smode)
+  else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
     {
       /* EXR register */
       unsigned char l = rval & 0xff;
@@ -1008,10 +1028,10 @@ h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
        h8300_print_register (gdbarch, file, frame, regno);
       h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
       h8300_print_register (gdbarch, file, frame, E_PC_REGNUM);
-      if (h8300smode)
+      if (is_h8300smode (current_gdbarch))
         {
          h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
-         if (h8300sxmode)
+         if (is_h8300sxmode (current_gdbarch))
            {
              h8300_print_register (gdbarch, file, frame, E_SBR_REGNUM);
              h8300_print_register (gdbarch, file, frame, E_VBR_REGNUM);
@@ -1033,7 +1053,7 @@ h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
     {
       if (regno == E_CCR_REGNUM)
         h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
-      else if (regno == E_PSEUDO_EXR_REGNUM && h8300smode)
+      else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
        h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
       else
        h8300_print_register (gdbarch, file, frame, regno);
@@ -1067,7 +1087,7 @@ h8300_register_type (struct gdbarch *gdbarch, int regno)
              return builtin_type_uint8;
            else if (regno == E_PSEUDO_EXR_REGNUM)
              return builtin_type_uint8;
-           else if (h8300hmode)
+           else if (is_h8300hmode (current_gdbarch))
              return builtin_type_int32;
            else
              return builtin_type_int16;
@@ -1181,9 +1201,6 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   switch (info.bfd_arch_info->mach)
     {
     case bfd_mach_h8300:
-      h8300sxmode = 0;
-      h8300smode = 0;
-      h8300hmode = 0;
       set_gdbarch_num_regs (gdbarch, 13);
       set_gdbarch_num_pseudo_regs (gdbarch, 1);
       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
@@ -1199,9 +1216,6 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       break;
     case bfd_mach_h8300h:
     case bfd_mach_h8300hn:
-      h8300sxmode = 0;
-      h8300smode = 0;
-      h8300hmode = 1;
       set_gdbarch_num_regs (gdbarch, 13);
       set_gdbarch_num_pseudo_regs (gdbarch, 1);
       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
@@ -1209,17 +1223,22 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
       set_gdbarch_register_name (gdbarch, h8300_register_name);
-      set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-      set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+      if(info.bfd_arch_info->mach != bfd_mach_h8300hn)
+        {
+          set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+          set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+        }
+      else
+        {
+          set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+          set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+        }
       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
       set_gdbarch_print_insn (gdbarch, print_insn_h8300h);
       break;
     case bfd_mach_h8300s:
     case bfd_mach_h8300sn:
-      h8300sxmode = 0;
-      h8300smode = 1;
-      h8300hmode = 1;
       set_gdbarch_num_regs (gdbarch, 16);
       set_gdbarch_num_pseudo_regs (gdbarch, 2);
       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
@@ -1227,17 +1246,22 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_register_name (gdbarch, h8300s_register_name);
-      set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-      set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+      if(info.bfd_arch_info->mach != bfd_mach_h8300sn)
+        {
+          set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+          set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+        }
+      else
+        {
+          set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+          set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+        }
       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
       set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
       break;
     case bfd_mach_h8300sx:
     case bfd_mach_h8300sxn:
-      h8300sxmode = 1;
-      h8300smode = 1;
-      h8300hmode = 1;
       set_gdbarch_num_regs (gdbarch, 18);
       set_gdbarch_num_pseudo_regs (gdbarch, 2);
       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
@@ -1245,8 +1269,16 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
       set_gdbarch_register_name (gdbarch, h8300sx_register_name);
-      set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-      set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+      if(info.bfd_arch_info->mach != bfd_mach_h8300sxn)
+        {
+          set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+          set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+        }
+      else
+        {
+          set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+          set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+        }
       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
       set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
@@ -1258,7 +1290,7 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
      ready to unwind the PC first (see frame.c:get_prev_frame()).  */
-  set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
+  set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
 
   /*
    * Basic register fields and methods.
@@ -1310,13 +1342,15 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-  set_gdbarch_long_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+  set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
   set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 
-  /* set_gdbarch_stack_align (gdbarch, SOME_stack_align); */
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
+  /* Char is unsigned.  */
+  set_gdbarch_char_signed (gdbarch, 0);
+
   return gdbarch;
 }
 
@@ -1327,3 +1361,39 @@ _initialize_h8300_tdep (void)
 {
   register_gdbarch_init (bfd_arch_h8300, h8300_gdbarch_init);
 }
+
+static int
+is_h8300hmode (struct gdbarch *gdbarch)
+{
+  return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300h
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
+}
+
+static int
+is_h8300smode (struct gdbarch *gdbarch)
+{
+  return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn;
+}
+
+static int
+is_h8300sxmode (struct gdbarch *gdbarch)
+{
+  return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn;
+}
+
+static int
+is_h8300_normal_mode (struct gdbarch *gdbarch)
+{
+  return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
+        || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
+}
+
This page took 0.030627 seconds and 4 git commands to generate.