Give every interpreter a command_loop_proc.
[deliverable/binutils-gdb.git] / gdb / rl78-tdep.c
index 2cd80051bf0972d50a718436aab4ee28e5bdb702..c727eb57859818d35f14609c7af79a59505d027f 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the Renesas RL78 for GDB, the GNU debugger.
 
-   Copyright (C) 2011-2012 Free Software Foundation, Inc.
+   Copyright (C) 2011-2013 Free Software Foundation, Inc.
 
    Contributed by Red Hat, Inc.
 
@@ -33,6 +33,7 @@
 #include "value.h"
 #include "gdbcore.h"
 #include "dwarf2-frame.h"
+#include "reggroups.h"
 
 #include "elf/rl78.h"
 #include "elf-bfd.h"
@@ -54,7 +55,74 @@ enum
 enum
 {
   /* All general purpose registers are 8 bits wide.  */
-  RL78_BANK0_R0_REGNUM = 0,
+  RL78_RAW_BANK0_R0_REGNUM = 0,
+  RL78_RAW_BANK0_R1_REGNUM,
+  RL78_RAW_BANK0_R2_REGNUM,
+  RL78_RAW_BANK0_R3_REGNUM,
+  RL78_RAW_BANK0_R4_REGNUM,
+  RL78_RAW_BANK0_R5_REGNUM,
+  RL78_RAW_BANK0_R6_REGNUM,
+  RL78_RAW_BANK0_R7_REGNUM,
+
+  RL78_RAW_BANK1_R0_REGNUM,
+  RL78_RAW_BANK1_R1_REGNUM,
+  RL78_RAW_BANK1_R2_REGNUM,
+  RL78_RAW_BANK1_R3_REGNUM,
+  RL78_RAW_BANK1_R4_REGNUM,
+  RL78_RAW_BANK1_R5_REGNUM,
+  RL78_RAW_BANK1_R6_REGNUM,
+  RL78_RAW_BANK1_R7_REGNUM,
+
+  RL78_RAW_BANK2_R0_REGNUM,
+  RL78_RAW_BANK2_R1_REGNUM,
+  RL78_RAW_BANK2_R2_REGNUM,
+  RL78_RAW_BANK2_R3_REGNUM,
+  RL78_RAW_BANK2_R4_REGNUM,
+  RL78_RAW_BANK2_R5_REGNUM,
+  RL78_RAW_BANK2_R6_REGNUM,
+  RL78_RAW_BANK2_R7_REGNUM,
+
+  RL78_RAW_BANK3_R0_REGNUM,
+  RL78_RAW_BANK3_R1_REGNUM,
+  RL78_RAW_BANK3_R2_REGNUM,
+  RL78_RAW_BANK3_R3_REGNUM,
+  RL78_RAW_BANK3_R4_REGNUM,
+  RL78_RAW_BANK3_R5_REGNUM,
+  RL78_RAW_BANK3_R6_REGNUM,
+  RL78_RAW_BANK3_R7_REGNUM,
+
+  RL78_PSW_REGNUM,     /* 8 bits */
+  RL78_ES_REGNUM,      /* 8 bits */
+  RL78_CS_REGNUM,      /* 8 bits */
+  RL78_RAW_PC_REGNUM,  /* 20 bits; we'll use 32 bits for it.  */
+
+  /* Fixed address SFRs (some of those above are SFRs too.) */
+  RL78_SPL_REGNUM,     /* 8 bits; lower half of SP */
+  RL78_SPH_REGNUM,     /* 8 bits; upper half of SP */
+  RL78_PMC_REGNUM,     /* 8 bits */
+  RL78_MEM_REGNUM,     /* 8 bits ?? */
+
+  RL78_NUM_REGS,
+
+  /* Pseudo registers.  */
+  RL78_PC_REGNUM = RL78_NUM_REGS,
+  RL78_SP_REGNUM,
+
+  RL78_X_REGNUM,
+  RL78_A_REGNUM,
+  RL78_C_REGNUM,
+  RL78_B_REGNUM,
+  RL78_E_REGNUM,
+  RL78_D_REGNUM,
+  RL78_L_REGNUM,
+  RL78_H_REGNUM,
+
+  RL78_AX_REGNUM,
+  RL78_BC_REGNUM,
+  RL78_DE_REGNUM,
+  RL78_HL_REGNUM,
+
+  RL78_BANK0_R0_REGNUM,
   RL78_BANK0_R1_REGNUM,
   RL78_BANK0_R2_REGNUM,
   RL78_BANK0_R3_REGNUM,
@@ -90,21 +158,7 @@ enum
   RL78_BANK3_R6_REGNUM,
   RL78_BANK3_R7_REGNUM,
 
-  RL78_PSW_REGNUM,     /* 8 bits */
-  RL78_ES_REGNUM,      /* 8 bits */
-  RL78_CS_REGNUM,      /* 8 bits */
-  RL78_PC_REGNUM,      /* 20 bits; we'll use 32 bits for it.  */
-
-  /* Fixed address SFRs (some of those above are SFRs too.) */
-  RL78_SPL_REGNUM,     /* 8 bits; lower half of SP */
-  RL78_SPH_REGNUM,     /* 8 bits; upper half of SP */
-  RL78_PMC_REGNUM,     /* 8 bits */
-  RL78_MEM_REGNUM,     /* 8 bits ?? */
-
-  RL78_NUM_REGS,
-
-  /* Pseudo registers.  */
-  RL78_BANK0_RP0_REGNUM = RL78_NUM_REGS,
+  RL78_BANK0_RP0_REGNUM,
   RL78_BANK0_RP1_REGNUM,
   RL78_BANK0_RP2_REGNUM,
   RL78_BANK0_RP3_REGNUM,
@@ -124,21 +178,6 @@ enum
   RL78_BANK3_RP2_REGNUM,
   RL78_BANK3_RP3_REGNUM,
 
-  RL78_SP_REGNUM,
-
-  RL78_X_REGNUM,
-  RL78_A_REGNUM,
-  RL78_C_REGNUM,
-  RL78_B_REGNUM,
-  RL78_E_REGNUM,
-  RL78_D_REGNUM,
-  RL78_L_REGNUM,
-  RL78_H_REGNUM,
-
-  RL78_AX_REGNUM,
-  RL78_BC_REGNUM,
-  RL78_DE_REGNUM,
-  RL78_HL_REGNUM,
   RL78_NUM_TOTAL_REGS,
   RL78_NUM_PSEUDO_REGS = RL78_NUM_TOTAL_REGS - RL78_NUM_REGS
 };
@@ -205,8 +244,12 @@ rl78_register_type (struct gdbarch *gdbarch, int reg_nr)
 
   if (reg_nr == RL78_PC_REGNUM)
     return tdep->rl78_code_pointer;
+  else if (reg_nr == RL78_RAW_PC_REGNUM)
+    return tdep->rl78_uint32;
   else if (reg_nr <= RL78_MEM_REGNUM
-           || (RL78_X_REGNUM <= reg_nr && reg_nr <= RL78_H_REGNUM))
+           || (RL78_X_REGNUM <= reg_nr && reg_nr <= RL78_H_REGNUM)
+          || (RL78_BANK0_R0_REGNUM <= reg_nr
+              && reg_nr <= RL78_BANK3_R7_REGNUM))
     return tdep->rl78_int8;
   else
     return tdep->rl78_data_pointer;
@@ -219,6 +262,69 @@ rl78_register_name (struct gdbarch *gdbarch, int regnr)
 {
   static const char *const reg_names[] =
   {
+    "",                /* bank0_r0 */
+    "",                /* bank0_r1 */
+    "",                /* bank0_r2 */
+    "",                /* bank0_r3 */
+    "",                /* bank0_r4 */
+    "",                /* bank0_r5 */
+    "",                /* bank0_r6 */
+    "",                /* bank0_r7 */
+
+    "",                /* bank1_r0 */
+    "",                /* bank1_r1 */
+    "",                /* bank1_r2 */
+    "",                /* bank1_r3 */
+    "",                /* bank1_r4 */
+    "",                /* bank1_r5 */
+    "",                /* bank1_r6 */
+    "",                /* bank1_r7 */
+
+    "",                /* bank2_r0 */
+    "",                /* bank2_r1 */
+    "",                /* bank2_r2 */
+    "",                /* bank2_r3 */
+    "",                /* bank2_r4 */
+    "",                /* bank2_r5 */
+    "",                /* bank2_r6 */
+    "",                /* bank2_r7 */
+
+    "",                /* bank3_r0 */
+    "",                /* bank3_r1 */
+    "",                /* bank3_r2 */
+    "",                /* bank3_r3 */
+    "",                /* bank3_r4 */
+    "",                /* bank3_r5 */
+    "",                /* bank3_r6 */
+    "",                /* bank3_r7 */
+
+    "psw",
+    "es",
+    "cs",
+    "",
+
+    "",                /* spl */
+    "",                /* sph */
+    "pmc",
+    "mem",
+
+    "pc",
+    "sp",
+
+    "x",
+    "a",
+    "c",
+    "b",
+    "e",
+    "d",
+    "l",
+    "h",
+
+    "ax",
+    "bc",
+    "de",
+    "hl",
+
     "bank0_r0",
     "bank0_r1",
     "bank0_r2",
@@ -255,16 +361,6 @@ rl78_register_name (struct gdbarch *gdbarch, int regnr)
     "bank3_r6",
     "bank3_r7",
 
-    "psw",
-    "es",
-    "cs",
-    "pc",
-
-    "spl",
-    "sph",
-    "pmc",
-    "mem",
-
     "bank0_rp0",
     "bank0_rp1",
     "bank0_rp2",
@@ -283,26 +379,47 @@ rl78_register_name (struct gdbarch *gdbarch, int regnr)
     "bank3_rp0",
     "bank3_rp1",
     "bank3_rp2",
-    "bank3_rp3",
+    "bank3_rp3"
+  };
 
-    "sp",
+  return reg_names[regnr];
+}
 
-    "x",
-    "a",
-    "c",
-    "b",
-    "e",
-    "d",
-    "l",
-    "h",
+/* Implement the "register_reggroup_p" gdbarch method.  */
 
-    "ax",
-    "bc",
-    "de",
-    "hl"
-  };
+static int
+rl78_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+                         struct reggroup *group)
+{
+  if (group == all_reggroup)
+    return 1;
 
-  return reg_names[regnr];
+  /* All other registers are saved and restored.  */
+  if (group == save_reggroup || group == restore_reggroup)
+    {
+      if ((regnum < RL78_NUM_REGS
+          && regnum != RL78_SPL_REGNUM
+          && regnum != RL78_SPH_REGNUM
+          && regnum != RL78_RAW_PC_REGNUM)
+         || regnum == RL78_SP_REGNUM
+         || regnum == RL78_PC_REGNUM)
+       return 1;
+      else
+       return 0;
+    }
+
+  if ((RL78_BANK0_R0_REGNUM <= regnum && regnum <= RL78_BANK3_R7_REGNUM)
+      || regnum == RL78_ES_REGNUM
+      || regnum == RL78_CS_REGNUM
+      || regnum == RL78_SPL_REGNUM
+      || regnum == RL78_SPH_REGNUM
+      || regnum == RL78_PMC_REGNUM
+      || regnum == RL78_MEM_REGNUM
+      || regnum == RL78_RAW_PC_REGNUM
+      || (RL78_BANK0_RP0_REGNUM <= regnum && regnum <= RL78_BANK3_RP3_REGNUM))
+    return group == system_reggroup;
+
+  return group == general_reggroup;
 }
 
 /* Strip bits to form an instruction address.  (When fetching a
@@ -332,10 +449,17 @@ rl78_pseudo_register_read (struct gdbarch *gdbarch,
 {
   enum register_status status;
 
-  if (RL78_BANK0_RP0_REGNUM <= reg && reg <= RL78_BANK3_RP3_REGNUM)
+  if (RL78_BANK0_R0_REGNUM <= reg && reg <= RL78_BANK3_R7_REGNUM)
+    {
+      int raw_regnum = RL78_RAW_BANK0_R0_REGNUM
+                       + (reg - RL78_BANK0_R0_REGNUM);
+
+      status = regcache_raw_read (regcache, raw_regnum, buffer);
+    }
+  else if (RL78_BANK0_RP0_REGNUM <= reg && reg <= RL78_BANK3_RP3_REGNUM)
     {
       int raw_regnum = 2 * (reg - RL78_BANK0_RP0_REGNUM)
-                       + RL78_BANK0_R0_REGNUM;
+                       + RL78_RAW_BANK0_R0_REGNUM;
 
       status = regcache_raw_read (regcache, raw_regnum, buffer);
       if (status == REG_VALID)
@@ -347,6 +471,13 @@ rl78_pseudo_register_read (struct gdbarch *gdbarch,
       if (status == REG_VALID)
        status = regcache_raw_read (regcache, RL78_SPH_REGNUM, buffer + 1);
     }
+  else if (reg == RL78_PC_REGNUM)
+    {
+      gdb_byte rawbuf[4];
+
+      status = regcache_raw_read (regcache, RL78_RAW_PC_REGNUM, rawbuf);
+      memcpy (buffer, rawbuf, 3);
+    }
   else if (RL78_X_REGNUM <= reg && reg <= RL78_H_REGNUM)
     {
       ULONGEST psw;
@@ -356,7 +487,7 @@ rl78_pseudo_register_read (struct gdbarch *gdbarch,
        {
          /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
          int bank = ((psw >> 3) & 1) | ((psw >> 4) & 1);
-         int raw_regnum = RL78_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
+         int raw_regnum = RL78_RAW_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
                           + (reg - RL78_X_REGNUM);
          status = regcache_raw_read (regcache, raw_regnum, buffer);
        }
@@ -370,7 +501,7 @@ rl78_pseudo_register_read (struct gdbarch *gdbarch,
        {
          /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
          int bank = ((psw >> 3) & 1) | ((psw >> 4) & 1);
-         int raw_regnum = RL78_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
+         int raw_regnum = RL78_RAW_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
                           + 2 * (reg - RL78_AX_REGNUM);
          status = regcache_raw_read (regcache, raw_regnum, buffer);
          if (status == REG_VALID)
@@ -390,10 +521,17 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
                             struct regcache *regcache,
                             int reg, const gdb_byte *buffer)
 {
-  if (RL78_BANK0_RP0_REGNUM <= reg && reg <= RL78_BANK3_RP3_REGNUM)
+  if (RL78_BANK0_R0_REGNUM <= reg && reg <= RL78_BANK3_R7_REGNUM)
+    {
+      int raw_regnum = RL78_RAW_BANK0_R0_REGNUM
+                       + (reg - RL78_BANK0_R0_REGNUM);
+
+      regcache_raw_write (regcache, raw_regnum, buffer);
+    }
+  else if (RL78_BANK0_RP0_REGNUM <= reg && reg <= RL78_BANK3_RP3_REGNUM)
     {
       int raw_regnum = 2 * (reg - RL78_BANK0_RP0_REGNUM)
-                       + RL78_BANK0_R0_REGNUM;
+                       + RL78_RAW_BANK0_R0_REGNUM;
 
       regcache_raw_write (regcache, raw_regnum, buffer);
       regcache_raw_write (regcache, raw_regnum + 1, buffer + 1);
@@ -403,6 +541,14 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
       regcache_raw_write (regcache, RL78_SPL_REGNUM, buffer);
       regcache_raw_write (regcache, RL78_SPH_REGNUM, buffer + 1);
     }
+  else if (reg == RL78_PC_REGNUM)
+    {
+      gdb_byte rawbuf[4];
+
+      memcpy (rawbuf, buffer, 3);
+      rawbuf[3] = 0;
+      regcache_raw_write (regcache, RL78_RAW_PC_REGNUM, rawbuf);
+    }
   else if (RL78_X_REGNUM <= reg && reg <= RL78_H_REGNUM)
     {
       ULONGEST psw;
@@ -412,7 +558,7 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
       regcache_raw_read_unsigned (regcache, RL78_PSW_REGNUM, &psw);
       bank = ((psw >> 3) & 1) | ((psw >> 4) & 1);
       /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
-      raw_regnum = RL78_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
+      raw_regnum = RL78_RAW_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
                   + (reg - RL78_X_REGNUM);
       regcache_raw_write (regcache, raw_regnum, buffer);
     }
@@ -424,7 +570,7 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
       regcache_raw_read_unsigned (regcache, RL78_PSW_REGNUM, &psw);
       bank = ((psw >> 3) & 1) | ((psw >> 4) & 1);
       /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
-      raw_regnum = RL78_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
+      raw_regnum = RL78_RAW_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
                   + 2 * (reg - RL78_AX_REGNUM);
       regcache_raw_write (regcache, raw_regnum, buffer);
       regcache_raw_write (regcache, raw_regnum + 1, buffer + 1);
@@ -435,7 +581,7 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
 
 /* Implement the "breakpoint_from_pc" gdbarch method.  */
 
-const gdb_byte *
+static const gdb_byte *
 rl78_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
                          int *lenptr)
 {
@@ -495,7 +641,7 @@ check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size,
   if (value.kind == pvk_register
       && value.k == 0
       && pv_is_register (addr, RL78_SP_REGNUM)
-      && size == register_size (target_gdbarch, value.reg))
+      && size == register_size (target_gdbarch (), value.reg))
     result->reg_offset[value.reg] = addr.k;
 }
 
@@ -522,7 +668,7 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
       result->reg_offset[rn] = 1;
     }
 
-  stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch));
+  stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
   back_to = make_cleanup_free_pv_area (stack);
 
   /* The call instruction has saved the return address on the stack.  */
@@ -789,6 +935,14 @@ rl78_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   else if (reg == 32)
     return RL78_SP_REGNUM;
   else if (reg == 33)
+    return -1;                 /* ap */
+  else if (reg == 34)
+    return RL78_PSW_REGNUM;
+  else if (reg == 35)
+    return RL78_ES_REGNUM;
+  else if (reg == 36)
+    return RL78_CS_REGNUM;
+  else if (reg == 37)
     return RL78_PC_REGNUM;
   else
     internal_error (__FILE__, __LINE__,
@@ -796,11 +950,24 @@ rl78_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
                    reg);
 }
 
+/* Implement the `register_sim_regno' gdbarch method.  */
+
+static int
+rl78_register_sim_regno (struct gdbarch *gdbarch, int regnum)
+{
+  gdb_assert (regnum < RL78_NUM_REGS);
+
+  /* So long as regnum is in [0, RL78_NUM_REGS), it's valid.  We
+     just want to override the default here which disallows register
+     numbers which have no names.  */
+  return regnum;
+}
+
 /* Implement the "return_value" gdbarch method.  */
 
 static enum return_value_convention
 rl78_return_value (struct gdbarch *gdbarch,
-                  struct type *func_type,
+                  struct value *function,
                   struct type *valtype,
                   struct regcache *regcache,
                   gdb_byte *readbuf, const gdb_byte *writebuf)
@@ -814,7 +981,7 @@ rl78_return_value (struct gdbarch *gdbarch,
   if (readbuf)
     {
       ULONGEST u;
-      int argreg = RL78_BANK1_R0_REGNUM;
+      int argreg = RL78_RAW_BANK1_R0_REGNUM;
       int offset = 0;
 
       while (valtype_len > 0)
@@ -830,7 +997,7 @@ rl78_return_value (struct gdbarch *gdbarch,
   if (writebuf)
     {
       ULONGEST u;
-      int argreg = RL78_BANK1_R0_REGNUM;
+      int argreg = RL78_RAW_BANK1_R0_REGNUM;
       int offset = 0;
 
       while (valtype_len > 0)
@@ -887,7 +1054,6 @@ rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       struct type *value_type = value_enclosing_type (args[i]);
       int len = TYPE_LENGTH (value_type);
       int container_len = (len + 1) & ~1;
-      int offset;
 
       sp -= container_len;
       write_memory (rl78_make_data_address (sp),
@@ -981,6 +1147,8 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pseudo_register_read (gdbarch, rl78_pseudo_register_read);
   set_gdbarch_pseudo_register_write (gdbarch, rl78_pseudo_register_write);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rl78_dwarf_reg_to_regnum);
+  set_gdbarch_register_reggroup_p (gdbarch, rl78_register_reggroup_p);
+  set_gdbarch_register_sim_regno (gdbarch, rl78_register_sim_regno);
 
   /* Data types.  */
   set_gdbarch_char_signed (gdbarch, 0);
@@ -990,6 +1158,7 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_long_long_bit (gdbarch, 64);
   set_gdbarch_ptr_bit (gdbarch, 16);
   set_gdbarch_addr_bit (gdbarch, 32);
+  set_gdbarch_dwarf2_addr_size (gdbarch, 4);
   set_gdbarch_float_bit (gdbarch, 32);
   set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
   set_gdbarch_double_bit (gdbarch, 32);
@@ -1013,6 +1182,8 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_unwind_pc (gdbarch, rl78_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, rl78_unwind_sp);
   set_gdbarch_frame_align (gdbarch, rl78_frame_align);
+
+  dwarf2_append_unwinders (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &rl78_unwind);
 
   /* Dummy frames, return values.  */
@@ -1026,6 +1197,9 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   return gdbarch;
 }
 
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_rl78_tdep;
+
 /* Register the above initialization routine.  */
 
 void
This page took 0.038031 seconds and 4 git commands to generate.