]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/rl78-tdep.c
Make gdb.base/index-cache.exp work with readnow board (PR 24669)
[thirdparty/binutils-gdb.git] / gdb / rl78-tdep.c
index 3be2579fb6e5b1ff8b7fa6c4dcaec1c18d64987d..f66cda88179b7f27be99cd52a8cd9c0c17515b61 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the Renesas RL78 for GDB, the GNU debugger.
 
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
+   Copyright (C) 2011-2019 Free Software Foundation, Inc.
 
    Contributed by Red Hat, Inc.
 
@@ -222,7 +222,8 @@ struct gdbarch_tdep
              *rl78_uint32,
              *rl78_int32,
              *rl78_data_pointer,
-             *rl78_code_pointer;
+             *rl78_code_pointer,
+             *rl78_psw_type;
 };
 
 /* This structure holds the results of a prologue analysis.  */
@@ -260,6 +261,30 @@ struct rl78_prologue
   int reg_offset[RL78_NUM_TOTAL_REGS];
 };
 
+/* Construct type for PSW register.  */
+
+static struct type *
+rl78_psw_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->rl78_psw_type == NULL)
+    {
+      tdep->rl78_psw_type = arch_flags_type (gdbarch,
+                                            "builtin_type_rl78_psw", 8);
+      append_flags_type_flag (tdep->rl78_psw_type, 0, "CY");
+      append_flags_type_flag (tdep->rl78_psw_type, 1, "ISP0");
+      append_flags_type_flag (tdep->rl78_psw_type, 2, "ISP1");
+      append_flags_type_flag (tdep->rl78_psw_type, 3, "RBS0");
+      append_flags_type_flag (tdep->rl78_psw_type, 4, "AC");
+      append_flags_type_flag (tdep->rl78_psw_type, 5, "RBS1");
+      append_flags_type_flag (tdep->rl78_psw_type, 6, "Z");
+      append_flags_type_flag (tdep->rl78_psw_type, 7, "IE");
+    }
+
+  return tdep->rl78_psw_type;
+}
+
 /* Implement the "register_type" gdbarch method.  */
 
 static struct type *
@@ -271,6 +296,8 @@ rl78_register_type (struct gdbarch *gdbarch, int reg_nr)
     return tdep->rl78_code_pointer;
   else if (reg_nr == RL78_RAW_PC_REGNUM)
     return tdep->rl78_uint32;
+  else if (reg_nr == RL78_PSW_REGNUM)
+    return rl78_psw_type (gdbarch);
   else if (reg_nr <= RL78_MEM_REGNUM
            || (RL78_X_REGNUM <= reg_nr && reg_nr <= RL78_H_REGNUM)
           || (RL78_BANK0_R0_REGNUM <= reg_nr
@@ -613,7 +640,7 @@ rl78_make_data_address (CORE_ADDR addr)
 
 static enum register_status
 rl78_pseudo_register_read (struct gdbarch *gdbarch,
-                           struct regcache *regcache,
+                          readable_regcache *regcache,
                            int reg, gdb_byte *buffer)
 {
   enum register_status status;
@@ -623,68 +650,67 @@ rl78_pseudo_register_read (struct gdbarch *gdbarch,
       int raw_regnum = RL78_RAW_BANK0_R0_REGNUM
                        + (reg - RL78_BANK0_R0_REGNUM);
 
-      status = regcache_raw_read (regcache, raw_regnum, buffer);
+      status = regcache->raw_read (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_RAW_BANK0_R0_REGNUM;
 
-      status = regcache_raw_read (regcache, raw_regnum, buffer);
+      status = regcache->raw_read (raw_regnum, buffer);
       if (status == REG_VALID)
-       status = regcache_raw_read (regcache, raw_regnum + 1, buffer + 1);
+       status = regcache->raw_read (raw_regnum + 1, buffer + 1);
     }
   else if (RL78_BANK0_RP0_PTR_REGNUM <= reg && reg <= RL78_BANK3_RP3_PTR_REGNUM)
     {
       int raw_regnum = 2 * (reg - RL78_BANK0_RP0_PTR_REGNUM)
                        + RL78_RAW_BANK0_R0_REGNUM;
 
-      status = regcache_raw_read (regcache, raw_regnum, buffer);
+      status = regcache->raw_read (raw_regnum, buffer);
       if (status == REG_VALID)
-       status = regcache_raw_read (regcache, raw_regnum + 1, buffer + 1);
+       status = regcache->raw_read (raw_regnum + 1, buffer + 1);
     }
   else if (reg == RL78_SP_REGNUM)
     {
-      status = regcache_raw_read (regcache, RL78_SPL_REGNUM, buffer);
+      status = regcache->raw_read (RL78_SPL_REGNUM, buffer);
       if (status == REG_VALID)
-       status = regcache_raw_read (regcache, RL78_SPH_REGNUM, buffer + 1);
+       status = regcache->raw_read (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);
+      status = regcache->raw_read (RL78_RAW_PC_REGNUM, rawbuf);
       memcpy (buffer, rawbuf, 3);
     }
   else if (RL78_X_REGNUM <= reg && reg <= RL78_H_REGNUM)
     {
       ULONGEST psw;
 
-      status = regcache_raw_read_unsigned (regcache, RL78_PSW_REGNUM, &psw);
+      status = regcache->raw_read (RL78_PSW_REGNUM, &psw);
       if (status == REG_VALID)
        {
          /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
          int bank = ((psw >> 3) & 1) | ((psw >> 4) & 1);
          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);
+         status = regcache->raw_read (raw_regnum, buffer);
        }
     }
   else if (RL78_AX_REGNUM <= reg && reg <= RL78_HL_REGNUM)
     {
       ULONGEST psw;
 
-      status = regcache_raw_read_unsigned (regcache, RL78_PSW_REGNUM, &psw);
+      status = regcache->raw_read (RL78_PSW_REGNUM, &psw);
       if (status == REG_VALID)
        {
          /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
          int bank = ((psw >> 3) & 1) | ((psw >> 4) & 1);
          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);
+         status = regcache->raw_read (raw_regnum, buffer);
          if (status == REG_VALID)
-           status = regcache_raw_read (regcache, raw_regnum + 1,
-                                       buffer + 1);
+           status = regcache->raw_read (raw_regnum + 1, buffer + 1);
        }
     }
   else
@@ -704,28 +730,28 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
       int raw_regnum = RL78_RAW_BANK0_R0_REGNUM
                        + (reg - RL78_BANK0_R0_REGNUM);
 
-      regcache_raw_write (regcache, raw_regnum, buffer);
+      regcache->raw_write (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_RAW_BANK0_R0_REGNUM;
 
-      regcache_raw_write (regcache, raw_regnum, buffer);
-      regcache_raw_write (regcache, raw_regnum + 1, buffer + 1);
+      regcache->raw_write (raw_regnum, buffer);
+      regcache->raw_write (raw_regnum + 1, buffer + 1);
     }
   else if (RL78_BANK0_RP0_PTR_REGNUM <= reg && reg <= RL78_BANK3_RP3_PTR_REGNUM)
     {
       int raw_regnum = 2 * (reg - RL78_BANK0_RP0_PTR_REGNUM)
                        + RL78_RAW_BANK0_R0_REGNUM;
 
-      regcache_raw_write (regcache, raw_regnum, buffer);
-      regcache_raw_write (regcache, raw_regnum + 1, buffer + 1);
+      regcache->raw_write (raw_regnum, buffer);
+      regcache->raw_write (raw_regnum + 1, buffer + 1);
     }
   else if (reg == RL78_SP_REGNUM)
     {
-      regcache_raw_write (regcache, RL78_SPL_REGNUM, buffer);
-      regcache_raw_write (regcache, RL78_SPH_REGNUM, buffer + 1);
+      regcache->raw_write (RL78_SPL_REGNUM, buffer);
+      regcache->raw_write (RL78_SPH_REGNUM, buffer + 1);
     }
   else if (reg == RL78_PC_REGNUM)
     {
@@ -733,7 +759,7 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
 
       memcpy (rawbuf, buffer, 3);
       rawbuf[3] = 0;
-      regcache_raw_write (regcache, RL78_RAW_PC_REGNUM, rawbuf);
+      regcache->raw_write (RL78_RAW_PC_REGNUM, rawbuf);
     }
   else if (RL78_X_REGNUM <= reg && reg <= RL78_H_REGNUM)
     {
@@ -746,7 +772,7 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
       /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
       raw_regnum = RL78_RAW_BANK0_R0_REGNUM + bank * RL78_REGS_PER_BANK
                   + (reg - RL78_X_REGNUM);
-      regcache_raw_write (regcache, raw_regnum, buffer);
+      regcache->raw_write (raw_regnum, buffer);
     }
   else if (RL78_AX_REGNUM <= reg && reg <= RL78_HL_REGNUM)
     {
@@ -758,28 +784,20 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch,
       /* RSB0 is at bit 3; RSBS1 is at bit 5.  */
       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);
+      regcache->raw_write (raw_regnum, buffer);
+      regcache->raw_write (raw_regnum + 1, buffer + 1);
     }
   else
     gdb_assert_not_reached ("invalid pseudo register number");
 }
 
-/* Implement the "breakpoint_from_pc" gdbarch method.  */
+/* The documented BRK instruction is actually a two byte sequence,
+   {0x61, 0xcc}, but instructions may be as short as one byte.
+   Correspondence with Renesas revealed that the one byte sequence
+   0xff is used when a one byte breakpoint instruction is required.  */
+constexpr gdb_byte rl78_break_insn[] = { 0xff };
 
-static const gdb_byte *
-rl78_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
-                         int *lenptr)
-{
-  /* The documented BRK instruction is actually a two byte sequence,
-     {0x61, 0xcc}, but instructions may be as short as one byte.
-     Correspondence with Renesas revealed that the one byte sequence
-     0xff is used when a one byte breakpoint instruction is required.  */
-  static gdb_byte breakpoint[] = { 0xff };
-
-  *lenptr = sizeof breakpoint;
-  return breakpoint;
-}
+typedef BP_MANIPULATION (rl78_break_insn) rl78_breakpoint;
 
 /* Define a "handle" struct for fetching the next opcode.  */
 
@@ -848,7 +866,8 @@ opc_reg_to_gdb_regnum (int opcreg)
 static int
 rl78_get_opcode_byte (void *handle)
 {
-  struct rl78_get_opcode_byte_handle *opcdata = handle;
+  struct rl78_get_opcode_byte_handle *opcdata
+    = (struct rl78_get_opcode_byte_handle *) handle;
   int status;
   gdb_byte byte;
 
@@ -863,7 +882,7 @@ rl78_get_opcode_byte (void *handle)
 }
 
 /* Function for finding saved registers in a 'struct pv_area'; this
-   function is passed to pv_area_scan.
+   function is passed to pv_area::scan.
 
    If VALUE is a saved register, ADDR says it was saved at a constant
    offset from the frame base, and SIZE indicates that the whole
@@ -892,8 +911,6 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
   CORE_ADDR pc, next_pc;
   int rn;
   pv_t reg[RL78_NUM_TOTAL_REGS];
-  struct pv_area *stack;
-  struct cleanup *back_to;
   CORE_ADDR after_last_frame_setup_insn = start_pc;
   int bank = 0;
 
@@ -905,12 +922,11 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
       result->reg_offset[rn] = 1;
     }
 
-  stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
-  back_to = make_cleanup_free_pv_area (stack);
+  pv_area stack (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
 
   /* The call instruction has saved the return address on the stack.  */
   reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -4);
-  pv_area_store (stack, reg[RL78_SP_REGNUM], 4, reg[RL78_PC_REGNUM]);
+  stack.store (reg[RL78_SP_REGNUM], 4, reg[RL78_PC_REGNUM]);
 
   pc = start_pc;
   while (pc < limit_pc)
@@ -934,12 +950,12 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
               && opc.op[1].type == RL78_Operand_Register)
        {
          int rsrc = (bank * RL78_REGS_PER_BANK) 
-                  + 2 * (opc.op[1].reg - RL78_Reg_AX);
+           + 2 * (opc.op[1].reg - RL78_Reg_AX);
 
          reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -1);
-         pv_area_store (stack, reg[RL78_SP_REGNUM], 1, reg[rsrc]);
+         stack.store (reg[RL78_SP_REGNUM], 1, reg[rsrc]);
          reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -1);
-         pv_area_store (stack, reg[RL78_SP_REGNUM], 1, reg[rsrc + 1]);
+         stack.store (reg[RL78_SP_REGNUM], 1, reg[rsrc + 1]);
          after_last_frame_setup_insn = next_pc;
        }
       else if (opc.id == RLO_sub
@@ -996,11 +1012,9 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
     result->frame_size = reg[RL78_SP_REGNUM].k;
 
   /* Record where all the registers were saved.  */
-  pv_area_scan (stack, check_for_saved, (void *) result);
+  stack.scan (check_for_saved, (void *) result);
 
   result->prologue_end = after_last_frame_setup_insn;
-
-  do_cleanups (back_to);
 }
 
 /* Implement the "addr_bits_remove" gdbarch method.  */
@@ -1070,14 +1084,6 @@ rl78_unwind_pc (struct gdbarch *arch, struct frame_info *next_frame)
                                                  RL78_PC_REGNUM));
 }
 
-/* Implement the "unwind_sp" gdbarch method.  */
-
-static CORE_ADDR
-rl78_unwind_sp (struct gdbarch *arch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, RL78_SP_REGNUM);
-}
-
 /* Given a frame described by THIS_FRAME, decode the prologue of its
    associated function if there is not cache entry as specified by
    THIS_PROLOGUE_CACHE.  Save the decoded prologue in the cache and
@@ -1101,10 +1107,11 @@ rl78_analyze_frame_prologue (struct frame_info *this_frame,
       if (!func_start)
        stop_addr = func_start;
 
-      rl78_analyze_prologue (func_start, stop_addr, *this_prologue_cache);
+      rl78_analyze_prologue (func_start, stop_addr,
+                            (struct rl78_prologue *) *this_prologue_cache);
     }
 
-  return *this_prologue_cache;
+  return (struct rl78_prologue *) *this_prologue_cache;
 }
 
 /* Given a frame and a prologue cache, return this frame's base.  */
@@ -1212,9 +1219,7 @@ rl78_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   else if (reg == 37)
     return RL78_PC_REGNUM;
   else
-    internal_error (__FILE__, __LINE__,
-                    _("Undefined dwarf2 register mapping of reg %d"),
-                   reg);
+    return -1;
 }
 
 /* Implement the `register_sim_regno' gdbarch method.  */
@@ -1323,7 +1328,8 @@ static CORE_ADDR
 rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                      struct regcache *regcache, CORE_ADDR bp_addr,
                      int nargs, struct value **args, CORE_ADDR sp,
-                     int struct_return, CORE_ADDR struct_addr)
+                     function_call_return_method return_method,
+                     CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[4];
@@ -1342,7 +1348,7 @@ rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* Store struct value address.  */
-  if (struct_return)
+  if (return_method == return_method_struct)
     {
       store_unsigned_integer (buf, 2, byte_order, struct_addr);
       sp -= 2;
@@ -1393,12 +1399,13 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+  tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
   tdep->elf_flags = elf_flags;
 
   /* Initialize types.  */
-  tdep->rl78_void = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
+  tdep->rl78_void = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT,
+                              "void");
   tdep->rl78_uint8 = arch_integer_type (gdbarch, 8, 1, "uint8_t");
   tdep->rl78_int8 = arch_integer_type (gdbarch, 8, 0, "int8_t");
   tdep->rl78_uint16 = arch_integer_type (gdbarch, 16, 1, "uint16_t");
@@ -1407,16 +1414,9 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->rl78_int32 = arch_integer_type (gdbarch, 32, 0, "int32_t");
 
   tdep->rl78_data_pointer
-    = arch_type (gdbarch, TYPE_CODE_PTR, 16 / TARGET_CHAR_BIT,
-                 xstrdup ("rl78_data_addr_t"));
-  TYPE_TARGET_TYPE (tdep->rl78_data_pointer) = tdep->rl78_void;
-  TYPE_UNSIGNED (tdep->rl78_data_pointer) = 1;
-
+    = arch_pointer_type (gdbarch, 16, "rl78_data_addr_t", tdep->rl78_void);
   tdep->rl78_code_pointer
-    = arch_type (gdbarch, TYPE_CODE_PTR, 32 / TARGET_CHAR_BIT,
-                 xstrdup ("rl78_code_addr_t"));
-  TYPE_TARGET_TYPE (tdep->rl78_code_pointer) = tdep->rl78_void;
-  TYPE_UNSIGNED (tdep->rl78_code_pointer) = 1;
+    = arch_pointer_type (gdbarch, 32, "rl78_code_addr_t", tdep->rl78_void);
 
   /* Registers.  */
   set_gdbarch_num_regs (gdbarch, RL78_NUM_REGS);
@@ -1454,17 +1454,14 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_addr_bits_remove (gdbarch, rl78_addr_bits_remove);
 
   /* Breakpoints.  */
-  set_gdbarch_breakpoint_from_pc (gdbarch, rl78_breakpoint_from_pc);
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch, rl78_breakpoint::kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch, rl78_breakpoint::bp_from_kind);
   set_gdbarch_decr_pc_after_break (gdbarch, 1);
 
-  /* Disassembly.  */
-  set_gdbarch_print_insn (gdbarch, print_insn_rl78);
-
   /* Frames, prologues, etc.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_skip_prologue (gdbarch, rl78_skip_prologue);
   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);
@@ -1481,9 +1478,6 @@ 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