* gdbint.texinfo (POP_FRAME): Document use by return_command.
[deliverable/binutils-gdb.git] / gdb / sh-tdep.c
index bf10c6c7500ff566f171cae11893c8cffb6945e6..74783bf2a607c3dc5cb251323f7d386aae2c9a60 100644 (file)
@@ -56,8 +56,6 @@ static gdbarch_frame_init_saved_regs_ftype sh_fp_frame_init_saved_regs;
 static gdbarch_init_extra_frame_info_ftype sh_init_extra_frame_info;
 static gdbarch_pop_frame_ftype sh_pop_frame;
 static gdbarch_saved_pc_after_call_ftype sh_saved_pc_after_call;
-static gdbarch_frame_args_address_ftype sh_frame_args_address;
-static gdbarch_frame_locals_address_ftype sh_frame_locals_address;
 
 /* Function call related functions. */
 static gdbarch_extract_return_value_ftype sh_extract_return_value;
@@ -104,6 +102,7 @@ static gdbarch_fetch_pseudo_register_ftype sh_fetch_pseudo_register;
 static gdbarch_store_pseudo_register_ftype sh_store_pseudo_register;
 static int fv_reg_base_num (int);
 static int dr_reg_base_num (int);
+static gdbarch_do_registers_info_ftype sh_do_registers_info;
 static void do_fv_register_info (int fv_regnum);
 static void do_dr_register_info (int dr_regnum);
 static void sh_do_pseudo_register (int regnum);
@@ -271,17 +270,28 @@ sh_sh4_register_name (int reg_nr)
 {
   static char *register_names[] =
   {
+    /* general registers 0-15 */
     "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
     "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
+    /* 16 - 22 */
     "pc",   "pr",   "gbr",  "vbr",  "mach", "macl", "sr",
+    /* 23, 24 */
     "fpul", "fpscr",
+    /* floating point registers 25 - 40 */
     "fr0",  "fr1",  "fr2",  "fr3",  "fr4",  "fr5",  "fr6",  "fr7",
     "fr8",  "fr9",  "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+    /* 41, 42 */
     "ssr",  "spc",
+    /* bank 0 43 - 50 */
     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
+    /* bank 1 51 - 58 */
     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+    /* double precision (pseudo) 59 - 66 */
     "dr0",  "dr2",  "dr4",  "dr6",  "dr8",  "dr10", "dr12", "dr14",
+    /* vectors (pseudo) 67 - 70 */
     "fv0",  "fv4",  "fv8",  "fv12",
+    /* FIXME: missing XF 71 - 86 */
+    /* FIXME: missing XD 87 - 94 */
   };
   if (reg_nr < 0)
     return NULL;
@@ -826,9 +836,8 @@ sh_init_extra_frame_info (int fromleaf, struct frame_info *fi)
 /* Extract from an array REGBUF containing the (raw) register state
    the address in which a function should return its structure value,
    as a CORE_ADDR (or an expression that can be used as one).  */
-CORE_ADDR
-static sh_extract_struct_value_address (regbuf)
-     char *regbuf;
+static CORE_ADDR
+sh_extract_struct_value_address (char *regbuf)
 {
   return (extract_address ((regbuf), REGISTER_RAW_SIZE (0)));
 }
@@ -839,18 +848,6 @@ sh_frame_saved_pc (struct frame_info *frame)
   return ((frame)->extra_info->return_pc);
 }
 
-static CORE_ADDR
-sh_frame_args_address (struct frame_info *fi)
-{
-  return (fi)->frame;
-}
-
-static CORE_ADDR
-sh_frame_locals_address (struct frame_info *fi)
-{
-  return (fi)->frame;
-}
-
 /* Discard from the stack the innermost frame,
    restoring all saved registers.  */
 static void
@@ -1063,8 +1060,20 @@ sh_extract_return_value (struct type *type, char *regbuf, char *valbuf)
 static void
 sh_default_store_return_value (struct type *type, char *valbuf)
 {
-  write_register_bytes (REGISTER_BYTE (0), 
-                       valbuf, TYPE_LENGTH (type));
+  char buf[32];        /* more than enough... */
+
+  if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (R0_REGNUM))
+    {
+      /* Add leading zeros to the value. */
+      memset (buf, 0, REGISTER_RAW_SIZE (R0_REGNUM));
+      memcpy (buf + REGISTER_RAW_SIZE (R0_REGNUM) - TYPE_LENGTH (type),
+             valbuf, TYPE_LENGTH (type));
+      write_register_bytes (REGISTER_BYTE (R0_REGNUM), buf, 
+                           REGISTER_RAW_SIZE (R0_REGNUM));
+    }
+  else
+    write_register_bytes (REGISTER_BYTE (R0_REGNUM), valbuf, 
+                         TYPE_LENGTH (type));
 }
 
 static void
@@ -1074,8 +1083,7 @@ sh3e_sh4_store_return_value (struct type *type, char *valbuf)
     write_register_bytes (REGISTER_BYTE (FP0_REGNUM), 
                          valbuf, TYPE_LENGTH (type));
   else
-    write_register_bytes (REGISTER_BYTE (0), 
-                         valbuf, TYPE_LENGTH (type));
+    sh_default_store_return_value (type, valbuf);
 }
 
 
@@ -1086,7 +1094,7 @@ sh_generic_show_regs (void)
 {
   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
                   paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
+                  (long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
                   (long) read_register (PR_REGNUM),
                   (long) read_register (MACH_REGNUM),
                   (long) read_register (MACL_REGNUM));
@@ -1120,7 +1128,7 @@ sh3_show_regs (void)
 {
   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
                   paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
+                  (long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
                   (long) read_register (PR_REGNUM),
                   (long) read_register (MACH_REGNUM),
                   (long) read_register (MACL_REGNUM));
@@ -1158,7 +1166,7 @@ sh3e_show_regs (void)
 {
   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
                   paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
+                  (long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
                   (long) read_register (PR_REGNUM),
                   (long) read_register (MACH_REGNUM),
                   (long) read_register (MACL_REGNUM));
@@ -1217,7 +1225,7 @@ sh3_dsp_show_regs (void)
 {
   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
                   paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
+                  (long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
                   (long) read_register (PR_REGNUM),
                   (long) read_register (MACH_REGNUM),
                   (long) read_register (MACL_REGNUM));
@@ -1275,7 +1283,7 @@ sh4_show_regs (void)
   int pr = read_register (gdbarch_tdep (current_gdbarch)->FPSCR_REGNUM) & 0x80000;
   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
                   paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
+                  (long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
                   (long) read_register (PR_REGNUM),
                   (long) read_register (MACH_REGNUM),
                   (long) read_register (MACL_REGNUM));
@@ -1338,7 +1346,7 @@ sh_dsp_show_regs (void)
 {
   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
                   paddr (read_register (PC_REGNUM)),
-                  (long) read_register (SR_REGNUM),
+                  (long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
                   (long) read_register (PR_REGNUM),
                   (long) read_register (MACH_REGNUM),
                   (long) read_register (MACL_REGNUM));
@@ -1664,11 +1672,11 @@ sh_do_pseudo_register (int regnum)
 {
   if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
     internal_error ("Invalid pseudo register number %d\n", regnum);
-  else if (regnum >= NUM_REGS && 
-          regnum < gdbarch_tdep (current_gdbarch)->FV0_REGNUM)
+  else if (regnum >= gdbarch_tdep (current_gdbarch)->DR0_REGNUM
+          && regnum < gdbarch_tdep (current_gdbarch)->DR_LAST_REGNUM)
     do_dr_register_info (regnum);
-  else if (regnum >= gdbarch_tdep (current_gdbarch)->FV0_REGNUM &&
-          regnum <= gdbarch_tdep (current_gdbarch)->FV_LAST_REGNUM)
+  else if (regnum >= gdbarch_tdep (current_gdbarch)->FV0_REGNUM
+          && regnum <= gdbarch_tdep (current_gdbarch)->FV_LAST_REGNUM)
     do_fv_register_info (regnum);
 }
 
@@ -1736,7 +1744,7 @@ sh_print_register (int regnum)
   if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
     internal_error ("Invalid register number %d\n", regnum);
 
-  else if (regnum > 0 && regnum < NUM_REGS)
+  else if (regnum >= 0 && regnum < NUM_REGS)
     {
       if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
        sh_do_fp_register (regnum);     /* FP regs */
@@ -1871,6 +1879,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      statement below. */
   tdep->FPUL_REGNUM = -1;
   tdep->FPSCR_REGNUM = -1;
+  tdep->SR_REGNUM = 22;
   tdep->DSR_REGNUM = -1;
   tdep->FP_LAST_REGNUM = -1;
   tdep->A0G_REGNUM = -1;
@@ -1892,10 +1901,22 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->DR_LAST_REGNUM = -1;
   tdep->FV0_REGNUM = -1;
   tdep->FV_LAST_REGNUM = -1;
+
   set_gdbarch_fp0_regnum (gdbarch, -1);
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   set_gdbarch_max_register_raw_size (gdbarch, 4);
   set_gdbarch_max_register_virtual_size (gdbarch, 4);
+  set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+  set_gdbarch_num_regs (gdbarch, 59);
+  set_gdbarch_sp_regnum (gdbarch, 15);
+  set_gdbarch_fp_regnum (gdbarch, 14);
+  set_gdbarch_pc_regnum (gdbarch, 16);
+  set_gdbarch_register_size (gdbarch, 4);
+  set_gdbarch_register_bytes (gdbarch, NUM_REGS * 4);
+  set_gdbarch_fetch_pseudo_register (gdbarch, sh_fetch_pseudo_register);
+  set_gdbarch_store_pseudo_register (gdbarch, sh_store_pseudo_register);
+  set_gdbarch_do_registers_info (gdbarch, sh_do_registers_info);
+  set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
   print_sh_insn = gdb_print_insn_sh;
 
   switch (info.bfd_arch_info->mach)
@@ -2043,23 +2064,16 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
   set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
 
-  set_gdbarch_num_regs (gdbarch, 59);
-  set_gdbarch_sp_regnum (gdbarch, 15);
-  set_gdbarch_fp_regnum (gdbarch, 14);
-  set_gdbarch_pc_regnum (gdbarch, 16);
   set_gdbarch_register_name (gdbarch, sh_register_name);
-  set_gdbarch_register_size (gdbarch, 4);
-  set_gdbarch_register_bytes (gdbarch, NUM_REGS * 4);
   set_gdbarch_register_virtual_type (gdbarch, sh_register_virtual_type);
 
-  set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
   set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
-  set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
+  set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);/*??should be 8?*/
 
   set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
   set_gdbarch_call_dummy_length (gdbarch, 0);
@@ -2093,21 +2107,19 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_decr_pc_after_break (gdbarch, 0);
   set_gdbarch_function_start_offset (gdbarch, 0);
-  set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
 
-  set_gdbarch_fetch_pseudo_register (gdbarch, sh_fetch_pseudo_register);
-  set_gdbarch_store_pseudo_register (gdbarch, sh_store_pseudo_register);
   set_gdbarch_frame_args_skip (gdbarch, 0);
   set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
   set_gdbarch_frame_chain (gdbarch, sh_frame_chain);
   set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
   set_gdbarch_frame_saved_pc (gdbarch, sh_frame_saved_pc);
-  set_gdbarch_frame_args_address (gdbarch, sh_frame_args_address);
-  set_gdbarch_frame_locals_address (gdbarch, sh_frame_locals_address);
+  set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+  set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
   set_gdbarch_saved_pc_after_call (gdbarch, sh_saved_pc_after_call);
   set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
   set_gdbarch_ieee_float (gdbarch, 1);
+  tm_print_insn = print_sh_insn;
 
   return gdbarch;
 }
@@ -2118,7 +2130,6 @@ _initialize_sh_tdep (void)
   struct cmd_list_element *c;
   
   register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init);
-  tm_print_insn = print_sh_insn;
 
   add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 }
This page took 0.027396 seconds and 4 git commands to generate.