Add entry for change in solib-osf.c (osf_in_dynsym_resolve_code).
[deliverable/binutils-gdb.git] / gdb / sh-tdep.c
index f8681b2d4f903d2e4cfece6ef00a36baf79f5beb..78a4a25d4632beec202a19cc9de8eaa71a74361e 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for Hitachi Super-H, for GDB.
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 2000 Free Software
-   Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdb_string.h"
 #include "arch-utils.h"
 #include "floatformat.h"
+#include "regcache.h"
 
 #include "solib-svr4.h"
 
 #undef XMALLOC
 #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
 
-
-/* Frame interpretation related functions. */
-static gdbarch_breakpoint_from_pc_ftype sh_breakpoint_from_pc;
-static gdbarch_frame_chain_ftype sh_frame_chain;
-static gdbarch_frame_saved_pc_ftype sh_frame_saved_pc;
-static gdbarch_skip_prologue_ftype sh_skip_prologue;
-
-static gdbarch_frame_init_saved_regs_ftype sh_nofp_frame_init_saved_regs;
-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;
-static gdbarch_extract_struct_value_address_ftype sh_extract_struct_value_address;
-static gdbarch_use_struct_convention_ftype sh_use_struct_convention;
-static gdbarch_store_struct_return_ftype sh_store_struct_return;
-static gdbarch_push_arguments_ftype sh_push_arguments;
-static gdbarch_push_return_address_ftype sh_push_return_address;
-static gdbarch_coerce_float_to_double_ftype sh_coerce_float_to_double;
-static gdbarch_store_return_value_ftype        sh_default_store_return_value;
-static gdbarch_store_return_value_ftype        sh3e_sh4_store_return_value;
-
-static gdbarch_register_name_ftype sh_generic_register_name;
-static gdbarch_register_name_ftype sh_sh_register_name;
-static gdbarch_register_name_ftype sh_sh3_register_name;
-static gdbarch_register_name_ftype sh_sh3e_register_name;
-static gdbarch_register_name_ftype sh_sh_dsp_register_name;
-static gdbarch_register_name_ftype sh_sh3_dsp_register_name;
-
-/* Registers display related functions */
-static gdbarch_register_raw_size_ftype sh_default_register_raw_size;
-static gdbarch_register_raw_size_ftype sh_sh4_register_raw_size;
-
-static gdbarch_register_virtual_size_ftype sh_register_virtual_size;
-
-static gdbarch_register_byte_ftype sh_default_register_byte;
-static gdbarch_register_byte_ftype sh_sh4_register_byte;
-
-static gdbarch_register_virtual_type_ftype sh_sh3e_register_virtual_type;
-static gdbarch_register_virtual_type_ftype sh_sh4_register_virtual_type;
-static gdbarch_register_virtual_type_ftype sh_default_register_virtual_type;
-
-static void sh_generic_show_regs (void);
-static void sh3_show_regs (void);
-static void sh3e_show_regs (void);
-static void sh3_dsp_show_regs (void);
-static void sh_dsp_show_regs (void);
-static void sh4_show_regs (void);
-static void sh_show_regs_command (char *, int);
-
-static struct type *sh_sh4_build_float_register_type (int high);
-
-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);
-static void sh_do_fp_register (int regnum);
-static void sh_do_register (int regnum);
-static void sh_print_register (int regnum);
-
 void (*sh_show_regs) (void);
 int (*print_sh_insn) (bfd_vma, disassemble_info*);
 
@@ -126,14 +59,6 @@ struct frame_extra_info
   int f_offset;
 };
 
-#if 0
-#ifdef _WIN32_WCE
-char **sh_register_names = sh3_reg_names;
-#else
-char **sh_register_names = sh_generic_reg_names;
-#endif
-#endif
-
 static char *
 sh_generic_register_name (int reg_nr)
 {
@@ -850,18 +775,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
@@ -1056,11 +969,70 @@ static void
 sh_extract_return_value (struct type *type, char *regbuf, char *valbuf)
 {
   int len = TYPE_LENGTH (type);
-
+  int return_register = R0_REGNUM;
+  int offset;
+  
   if (len <= 4)
-    memcpy (valbuf, ((char *) regbuf) + 4 - len, len);
+    {
+      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+       offset = REGISTER_BYTE (return_register) + 4 - len;
+      else
+       offset = REGISTER_BYTE (return_register);
+      memcpy (valbuf, regbuf + offset, len);
+    }
   else if (len <= 8)
-    memcpy (valbuf, ((char *) regbuf) + 8 - len, len);
+    {
+      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+       offset = REGISTER_BYTE (return_register) + 8 - len;
+      else
+       offset = REGISTER_BYTE (return_register);
+      memcpy (valbuf, regbuf + offset, len);
+    }
+  else
+    error ("bad size for return value");
+}
+
+static void
+sh3e_sh4_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+  int return_register;
+  int offset;
+  int len = TYPE_LENGTH (type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+    return_register = FP0_REGNUM;
+  else
+    return_register = R0_REGNUM;
+  
+  if (len == 8 && TYPE_CODE (type) == TYPE_CODE_FLT)
+    {
+      DOUBLEST val;
+      if (TARGET_BYTE_ORDER == LITTLE_ENDIAN)
+       floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
+                                (char *) regbuf + REGISTER_BYTE (return_register),
+                                &val);
+      else
+       floatformat_to_doublest (&floatformat_ieee_double_big,
+                                (char *) regbuf + REGISTER_BYTE (return_register),
+                                &val);
+      store_floating (valbuf, len, val);
+    }
+  else if (len <= 4)
+    {
+      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+       offset = REGISTER_BYTE (return_register) + 4 - len;
+      else
+       offset = REGISTER_BYTE (return_register);
+      memcpy (valbuf, regbuf + offset, len);
+    }
+  else if (len <= 8)
+    {
+      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+       offset = REGISTER_BYTE (return_register) + 8 - len;
+      else
+       offset = REGISTER_BYTE (return_register);
+      memcpy (valbuf, regbuf + offset, len);
+    }
   else
     error ("bad size for return value");
 }
@@ -1074,8 +1046,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
@@ -1085,8 +1069,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);
 }
 
 
@@ -1403,6 +1386,26 @@ void sh_show_regs_command (char *args, int from_tty)
     (*sh_show_regs)();
 }
 
+static int
+fv_reg_base_num (int fv_regnum)
+{
+  int fp_regnum;
+
+  fp_regnum = FP0_REGNUM + 
+    (fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4;
+  return fp_regnum;
+}
+
+static int
+dr_reg_base_num (int dr_regnum)
+{
+  int fp_regnum;
+
+  fp_regnum = FP0_REGNUM + 
+    (dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2;
+  return fp_regnum;
+}
+
 /* Index within `registers' of the first byte of the space for
    register N.  */
 static int
@@ -1467,6 +1470,15 @@ sh_sh3e_register_virtual_type (int reg_nr)
     return builtin_type_int;
 }
 
+static struct type *
+sh_sh4_build_float_register_type (int high)
+{
+  struct type *temp;
+
+  temp = create_range_type (NULL, builtin_type_int, 0, high);
+  return create_array_type (NULL, builtin_type_float, temp);
+}
+
 static struct type *
 sh_sh4_register_virtual_type (int reg_nr)
 {
@@ -1484,15 +1496,6 @@ sh_sh4_register_virtual_type (int reg_nr)
     return builtin_type_int;
 }
 
-static struct type *
-sh_sh4_build_float_register_type (int high)
-{
-  struct type *temp;
-
-  temp = create_range_type (NULL, builtin_type_int, 0, high);
-  return create_array_type (NULL, builtin_type_float, temp);
-}
-
 static struct type *
 sh_default_register_virtual_type (int reg_nr)
 {
@@ -1627,26 +1630,6 @@ sh_store_pseudo_register (int reg_nr)
     }
 }
 
-static int
-fv_reg_base_num (int fv_regnum)
-{
-  int fp_regnum;
-
-  fp_regnum = FP0_REGNUM + 
-    (fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4;
-  return fp_regnum;
-}
-
-static int
-dr_reg_base_num (int dr_regnum)
-{
-  int fp_regnum;
-
-  fp_regnum = FP0_REGNUM + 
-    (dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2;
-  return fp_regnum;
-}
-
 static void
 do_fv_register_info (int fv_regnum)
 {
@@ -1674,7 +1657,8 @@ static void
 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);
+    internal_error (__FILE__, __LINE__,
+                   "Invalid pseudo register number %d\n", regnum);
   else if (regnum >= gdbarch_tdep (current_gdbarch)->DR0_REGNUM
           && regnum < gdbarch_tdep (current_gdbarch)->DR_LAST_REGNUM)
     do_dr_register_info (regnum);
@@ -1707,7 +1691,10 @@ sh_do_fp_register (int regnum)
   print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), gdb_stdout);
 
   /* Print the value. */
-  printf_filtered (inv ? "<invalid float>" : "%-10.9g", flt);
+  if (inv)
+    printf_filtered ("<invalid float>");
+  else
+    printf_filtered ("%-10.9g", flt);
 
   /* Print the fp register as hex. */
   printf_filtered ("\t(raw 0x");
@@ -1745,9 +1732,10 @@ static void
 sh_print_register (int regnum)
 {
   if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
-    internal_error ("Invalid register number %d\n", regnum);
+    internal_error (__FILE__, __LINE__,
+                   "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 */
@@ -1920,6 +1908,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
+  set_gdbarch_extract_return_value (gdbarch, sh_extract_return_value);
   print_sh_insn = gdb_print_insn_sh;
 
   switch (info.bfd_arch_info->mach)
@@ -1985,6 +1974,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       sh_show_regs = sh3e_show_regs;
       sh_store_return_value = sh3e_sh4_store_return_value;
       sh_register_virtual_type = sh_sh3e_register_virtual_type;
+      set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
       set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
       set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
       set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
@@ -2027,6 +2017,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       sh_show_regs = sh4_show_regs;
       sh_store_return_value = sh3e_sh4_store_return_value;
       sh_register_virtual_type = sh_sh4_register_virtual_type;
+      set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
       set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
       set_gdbarch_fp0_regnum (gdbarch, 25);
       set_gdbarch_register_raw_size (gdbarch, sh_sh4_register_raw_size);
@@ -2095,7 +2086,6 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_coerce_float_to_double (gdbarch, 
                                      sh_coerce_float_to_double);
 
-  set_gdbarch_extract_return_value (gdbarch, sh_extract_return_value);
   set_gdbarch_push_arguments (gdbarch, sh_push_arguments);
   set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
   set_gdbarch_push_return_address (gdbarch, sh_push_return_address);
@@ -2116,8 +2106,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
This page took 0.027557 seconds and 4 git commands to generate.