*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / h8300-tdep.c
index 0ebcf226d8df6fb001008d23cc11acd965d0a3ca..f6bdb151d52cacc422b0741ea369851f417aa029 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
 {
@@ -73,6 +81,9 @@ enum gdb_regnum
   E_VBR_REGNUM
 };
 
+#define E_PSEUDO_CCR_REGNUM (NUM_REGS)
+#define E_PSEUDO_EXR_REGNUM (NUM_REGS+1)
+
 #define UNSIGNED_SHORT(X) ((X) & 0xffff)
 
 #define IS_PUSH(x) ((x & 0xfff0)==0x6df0)
@@ -91,13 +102,23 @@ enum gdb_regnum
    An argument register spill is an instruction that moves an argument
    from the register in which it was passed to the stack slot in which
    it really lives.  It is a byte, word, or longword move from an
-   argument register to a negative offset from the frame pointer.  */
+   argument register to a negative offset from the frame pointer.
+   
+   CV, 2003-06-16: Or, in optimized code or when the `register' qualifier
+   is used, it could be a byte, word or long move to registers r3-r5.  */
 
 static int
 h8300_is_argument_spill (CORE_ADDR pc)
 {
   int w = read_memory_unsigned_integer (pc, 2);
 
+  if (((w & 0xff88) == 0x0c88                 /* mov.b Rsl, Rdl */
+       || (w & 0xff88) == 0x0d00              /* mov.w Rs, Rd */
+       || (w & 0xff88) == 0x0f80)             /* mov.l Rs, Rd */
+      && (w & 0x70) <= 0x20                   /* Rs is R0, R1 or R2 */
+      && (w & 0x7) >= 0x3 && (w & 0x7) <= 0x5)/* Rd is R3, R4 or R5 */
+    return 2;
+
   if ((w & 0xfff0) == 0x6ee0                  /* mov.b Rs,@(d:16,er6) */
       && 8 <= (w & 0xf) && (w & 0xf) <= 10)   /* Rs is R0L, R1L, or R2L  */
     {
@@ -240,6 +261,17 @@ h8300_skip_prologue (CORE_ADDR start_pc)
   if (IS_SUBL_SP (w))
     start_pc += 6 + adjust;
 
+  /* Skip past another possible stm insn for registers R3 to R5 (possibly used
+     for register qualified arguments.  */
+  w = read_memory_unsigned_integer (start_pc, 2);
+  /* First look for push insns.  */
+  if (w == 0x0110 || w == 0x0120 || w == 0x0130)
+    {
+      w = read_memory_unsigned_integer (start_pc + 2, 2);
+      if (IS_PUSH (w) && (w & 0xf) >= 0x3 && (w & 0xf) <= 0x5)
+       start_pc += 4;
+    }
+
   /* Check for spilling an argument register to the stack frame.
      This could also be an initializing store from non-prologue code,
      but I don't think there's any harm in skipping that.  */
@@ -254,17 +286,6 @@ h8300_skip_prologue (CORE_ADDR start_pc)
   return start_pc;
 }
 
-static int
-gdb_print_insn_h8300 (bfd_vma memaddr, disassemble_info * info)
-{
-  if (h8300smode)
-    return print_insn_h8300s (memaddr, info);
-  else if (h8300hmode)
-    return print_insn_h8300h (memaddr, info);
-  else
-    return print_insn_h8300 (memaddr, info);
-}
-
 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
    is not the address of a valid instruction, the address of the next
    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
@@ -307,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;
@@ -336,12 +357,13 @@ 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);
 
-  if (insn_word == 0x0100)
+  if (insn_word == 0x0100)     /* mov.l */
     {
       insn_word = read_memory_unsigned_integer (ip + 2, 2);
       adjust = 2;
@@ -464,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);
 
@@ -478,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. */
@@ -507,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.
@@ -545,13 +567,7 @@ 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_arguments
+/* 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
    on the H8/300H.
@@ -616,35 +632,33 @@ h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
      to begin with.  */
 
 static CORE_ADDR
-h8300_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
-                     int struct_return, CORE_ADDR struct_addr)
+h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+                      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+                      struct value **args, CORE_ADDR sp, int struct_return,
+                      CORE_ADDR struct_addr)
 {
-  int stack_align, stack_alloc, stack_offset;
+  int stack_alloc = 0, stack_offset = 0;
   int wordsize = BINWORD;
-  int reg;
+  int reg = E_ARG0_REGNUM;
   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.  */
-  stack_alloc = 0;
   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;
 
   /* Now load as many arguments as possible into registers, and push
-     the rest onto the stack.  */
-  reg = E_ARG0_REGNUM;
-  stack_offset = 0;
-
-  /* If we're returning a structure by value, then we must pass a
+     the rest onto the stack.
+     If we're returning a structure by value, then we must pass a
      pointer to the buffer for the return value as an invisible first
      argument.  */
   if (struct_return)
-    write_register (reg++, struct_addr);
+    regcache_cooked_write_unsigned (regcache, reg++, struct_addr);
 
   for (argument = 0; argument < nargs; argument++)
     {
@@ -653,7 +667,7 @@ h8300_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
       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);
@@ -688,7 +702,7 @@ h8300_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                 {
                   ULONGEST word = extract_unsigned_integer (padded + offset, 
                                                            wordsize);
-                  write_register (reg++, word);
+                 regcache_cooked_write_unsigned (regcache, reg++, word);
                 }
             }
         }
@@ -704,24 +718,13 @@ h8300_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
         }
     }
 
-  return sp;
-}
-
-/* Function: push_return_address
-   Setup the return address for a dummy frame, as called by
-   call_function_by_hand.  Only necessary when you are using an
-   empty CALL_DUMMY, ie. the target will not actually be executing
-   a JSR/BSR instruction.  */
+  /* Store return address.  */
+  sp -= wordsize;
+  write_memory_unsigned_integer (sp, wordsize, bp_addr);
 
-static CORE_ADDR
-h8300_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
-{
-  unsigned char buf[4];
-  int wordsize = BINWORD;
+  /* Update stack pointer.  */
+  regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);
 
-  sp -= wordsize;
-  store_unsigned_integer (buf, wordsize, CALL_DUMMY_ADDRESS ());
-  write_memory (sp, buf, wordsize);
   return sp;
 }
 
@@ -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;
     }
 }
@@ -878,7 +897,8 @@ h8300_register_name (int regno)
      type is selected. */
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6",
-    "sp", "ccr","pc","cycles", "tick", "inst", ""
+    "sp", "","pc","cycles", "tick", "inst",
+    "ccr", /* pseudo register */
   };
   if (regno < 0
       || regno >= (sizeof (register_names) / sizeof (*register_names)))
@@ -893,7 +913,9 @@ h8300s_register_name (int regno)
 {
   static char *register_names[] = {
     "er0", "er1", "er2", "er3", "er4", "er5", "er6",
-    "sp", "ccr", "pc", "cycles", "exr", "tick", "inst"
+    "sp", "", "pc", "cycles", "", "tick", "inst",
+    "mach", "macl",
+    "ccr", "exr" /* pseudo registers */
   };
   if (regno < 0
       || regno >= (sizeof (register_names) / sizeof (*register_names)))
@@ -908,8 +930,9 @@ h8300sx_register_name (int regno)
 {
   static char *register_names[] = {
     "er0", "er1", "er2", "er3", "er4", "er5", "er6",
-    "sp", "ccr", "pc", "cycles", "exr", "tick", "inst",
-    "mach", "macl", "sbr", "vbr"
+    "sp", "", "pc", "cycles", "", "tick", "inst",
+    "mach", "macl", "sbr", "vbr",
+    "ccr", "exr" /* pseudo registers */
   };
   if (regno < 0
       || regno >= (sizeof (register_names) / sizeof (*register_names)))
@@ -929,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_CCR_REGNUM || (regno == E_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);
@@ -942,7 +966,7 @@ h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
       fprintf_filtered (file, "0x%s  ", phex ((ULONGEST)rval, BINWORD));
       print_longest (file, 'd', 1, rval);
     }
-  if (regno == E_CCR_REGNUM)
+  if (regno == E_PSEUDO_CCR_REGNUM)
     {
       /* CCR register */
       int C, Z, N, V;
@@ -981,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_EXR_REGNUM && h8300smode)
+  else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
     {
       /* EXR register */
       unsigned char l = rval & 0xff;
@@ -999,10 +1023,41 @@ h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
                            struct frame_info *frame, int regno, int cpregs)
 {
   if (regno < 0)
-    for (regno = 0; regno < NUM_REGS; ++regno)
-      h8300_print_register (gdbarch, file, frame, regno);
+    {
+      for (regno = E_R0_REGNUM; regno <= E_SP_REGNUM; ++regno)
+       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 (is_h8300smode (current_gdbarch))
+        {
+         h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
+         if (is_h8300sxmode (current_gdbarch))
+           {
+             h8300_print_register (gdbarch, file, frame, E_SBR_REGNUM);
+             h8300_print_register (gdbarch, file, frame, E_VBR_REGNUM);
+           }
+         h8300_print_register (gdbarch, file, frame, E_MACH_REGNUM);
+         h8300_print_register (gdbarch, file, frame, E_MACL_REGNUM);
+         h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
+         h8300_print_register (gdbarch, file, frame, E_TICKS_REGNUM);
+         h8300_print_register (gdbarch, file, frame, E_INSTS_REGNUM);
+       }
+      else
+        {
+         h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
+         h8300_print_register (gdbarch, file, frame, E_TICK_REGNUM);
+         h8300_print_register (gdbarch, file, frame, E_INST_REGNUM);
+       }
+    }
   else
-    h8300_print_register (gdbarch, file, frame, regno);
+    {
+      if (regno == E_CCR_REGNUM)
+        h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
+      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);
+    }
 }
 
 static CORE_ADDR
@@ -1014,7 +1069,7 @@ h8300_saved_pc_after_call (struct frame_info *ignore)
 static struct type *
 h8300_register_type (struct gdbarch *gdbarch, int regno)
 {
-  if (regno < 0 || regno >= NUM_REGS)
+  if (regno < 0 || regno >= NUM_REGS + NUM_PSEUDO_REGS)
     internal_error (__FILE__, __LINE__,
                    "h8300_register_type: illegal register number %d",
                    regno);
@@ -1027,19 +1082,61 @@ h8300_register_type (struct gdbarch *gdbarch, int regno)
          case E_SP_REGNUM:
          case E_FP_REGNUM:
            return builtin_type_void_data_ptr;
-         case E_CCR_REGNUM:
-           return builtin_type_uint8;
-         case E_EXR_REGNUM:
-           if (h8300smode)
-             return builtin_type_uint8;
-           /*FALLTHRU*/
          default:
-           return h8300hmode ? builtin_type_int32
-                             : builtin_type_int16;
+           if (regno == E_PSEUDO_CCR_REGNUM)
+             return builtin_type_uint8;
+           else if (regno == E_PSEUDO_EXR_REGNUM)
+             return builtin_type_uint8;
+           else if (is_h8300hmode (current_gdbarch))
+             return builtin_type_int32;
+           else
+             return builtin_type_int16;
         }
     }
 }
 
+static void
+h8300_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+                           int regno, void *buf)
+{
+  if (regno == E_PSEUDO_CCR_REGNUM)
+    regcache_raw_read (regcache, E_CCR_REGNUM, buf);
+  else if (regno == E_PSEUDO_EXR_REGNUM)
+    regcache_raw_read (regcache, E_EXR_REGNUM, buf);
+  else
+    regcache_raw_read (regcache, regno, buf);
+}
+
+static void
+h8300_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                            int regno, const void *buf)
+{
+  if (regno == E_PSEUDO_CCR_REGNUM)
+    regcache_raw_write (regcache, E_CCR_REGNUM, buf);
+  else if (regno == E_PSEUDO_EXR_REGNUM)
+    regcache_raw_write (regcache, E_EXR_REGNUM, buf);
+  else
+    regcache_raw_write (regcache, regno, buf);
+}
+
+static int
+h8300_dbg_reg_to_regnum (int regno)
+{
+  if (regno == E_CCR_REGNUM)
+    return E_PSEUDO_CCR_REGNUM;
+  return regno;
+}
+
+static int
+h8300s_dbg_reg_to_regnum (int regno)
+{
+  if (regno == E_CCR_REGNUM)
+    return E_PSEUDO_CCR_REGNUM;
+  if (regno == E_EXR_REGNUM)
+    return E_PSEUDO_EXR_REGNUM;
+  return regno;
+}
+
 static CORE_ADDR
 h8300_extract_struct_value_address (struct regcache *regcache)
 {
@@ -1104,63 +1201,101 @@ 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);
+      set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
+      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, 2 * TARGET_CHAR_BIT);
       set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
       set_gdbarch_extract_return_value (gdbarch, h8300_extract_return_value);
       set_gdbarch_store_return_value (gdbarch, h8300_store_return_value);
+      set_gdbarch_print_insn (gdbarch, print_insn_h8300);
       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);
+      set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
+      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, 14);
+      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);
+      set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
+      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);
+      set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
+      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);
       break;
     }
 
+  set_gdbarch_pseudo_register_read (gdbarch, h8300_pseudo_register_read);
+  set_gdbarch_pseudo_register_write (gdbarch, h8300_pseudo_register_write);
+
   /* 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.
    */
 
-  set_gdbarch_num_pseudo_regs (gdbarch, 0);
   set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
   set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
@@ -1181,48 +1316,34 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_deprecated_saved_pc_after_call (gdbarch, 
                                              h8300_saved_pc_after_call);
   set_gdbarch_deprecated_frame_saved_pc (gdbarch, h8300_frame_saved_pc);
+  set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame);
 
   /* 
    * Miscelany
    */
   /* Stack grows up. */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-  /* PC stops zero byte after a trap instruction
-     (which means: exactly on trap instruction). */
-  set_gdbarch_decr_pc_after_break (gdbarch, 0);
-  /* This value is almost never non-zero... */
-  set_gdbarch_function_start_offset (gdbarch, 0);
   /* This value is almost never non-zero... */
   set_gdbarch_frame_args_skip (gdbarch, 0);
   set_gdbarch_frameless_function_invocation (gdbarch,
                                             frameless_look_for_prologue);
 
-  set_gdbarch_extract_struct_value_address (gdbarch,
-                                           h8300_extract_struct_value_address);
+  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, h8300_extract_struct_value_address);
   set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention);
   set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc);
   set_gdbarch_push_dummy_code (gdbarch, h8300_push_dummy_code);
+  set_gdbarch_push_dummy_call (gdbarch, h8300_push_dummy_call);
 
   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);
 
-  /*
-   * Call Dummies
-   * 
-   * These values and methods are used when gdb calls a target function.  */
-  /* Can all be replaced by push_dummy_call */
-  set_gdbarch_deprecated_push_return_address (gdbarch, 
-                                             h8300_push_return_address);
-  set_gdbarch_deprecated_push_arguments (gdbarch, h8300_push_arguments);
-  set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame);
-  set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
-
+  /* Char is unsigned.  */
+  set_gdbarch_char_signed (gdbarch, 0);
 
   return gdbarch;
 }
@@ -1232,6 +1353,41 @@ extern initialize_file_ftype _initialize_h8300_tdep; /* -Wmissing-prototypes */
 void
 _initialize_h8300_tdep (void)
 {
-  deprecated_tm_print_insn = gdb_print_insn_h8300;
   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.047558 seconds and 4 git commands to generate.