* avr-tdep.c (avr_return_value): New function.
authorUlrich Weigand <uweigand@de.ibm.com>
Sat, 13 Oct 2007 00:05:07 +0000 (00:05 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Sat, 13 Oct 2007 00:05:07 +0000 (00:05 +0000)
(avr_gdbarch_init): Call set_gdbarch_return_value instead of
set_gdbarch_extract_return_value.

* fvr-tdep.c (frv_return_value): New function.
(frv_gdbarch_init): Call set_gdbarch_return_value instead of
set_gdbarch_extract_return_value, set_gdbarch_store_return_value,
and set_gdbarch_deprecated_use_struct_convention.

* ia64-tdep.c (ia64_use_struct_convention): Make static.
Add check for structure, union, or array types.
(ia64_extract_return_value): Make static.
(ia64_store_return_value): Make static.  Support multi-word values.
(ia64_return_value): New function.
(ia64_gdbarch_init): Call set_gdbarch_return_value instead of
set_gdbarch_extract_return_value, set_gdbarch_store_return_value,
and set_gdbarch_deprecated_use_struct_convention.

gdb/ChangeLog
gdb/avr-tdep.c
gdb/frv-tdep.c
gdb/ia64-tdep.c

index 7a13c9ea73accda0f6be2ef12956593b51ad8f83..743f1440cf2a7902ceb5bf750335c040f4280520 100644 (file)
@@ -1,3 +1,23 @@
+2007-10-12  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * avr-tdep.c (avr_return_value): New function.
+       (avr_gdbarch_init): Call set_gdbarch_return_value instead of
+       set_gdbarch_extract_return_value.
+
+       * fvr-tdep.c (frv_return_value): New function.
+       (frv_gdbarch_init): Call set_gdbarch_return_value instead of
+       set_gdbarch_extract_return_value, set_gdbarch_store_return_value,
+       and set_gdbarch_deprecated_use_struct_convention.
+
+       * ia64-tdep.c (ia64_use_struct_convention): Make static.
+       Add check for structure, union, or array types.
+       (ia64_extract_return_value): Make static.
+       (ia64_store_return_value): Make static.  Support multi-word values.
+       (ia64_return_value): New function.
+       (ia64_gdbarch_init): Call set_gdbarch_return_value instead of
+       set_gdbarch_extract_return_value, set_gdbarch_store_return_value,
+       and set_gdbarch_deprecated_use_struct_convention.
+
 2007-10-12  Joel Brobecker  <brobecker@adacore.com>
 
        * solib-target.c (solib_target_parse_libraries)
index 3db8530c14dde88c97518dbf3f6bbf03a9ef6d94..d3ecf2b5d6493fcb8eb93a65495aed7cffdf9cd0 100644 (file)
@@ -827,6 +827,44 @@ avr_extract_return_value (struct type *type, struct regcache *regcache,
     }
 }
 
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+   should be returned.  If it is supposed to be returned in registers,
+   and READBUF is non-zero, read the appropriate value from REGCACHE,
+   and copy it into READBUF.  If WRITEBUF is non-zero, write the value
+   from WRITEBUF into REGCACHE.  */
+
+enum return_value_convention
+avr_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                 struct regcache *regcache, gdb_byte *readbuf,
+                 const gdb_byte *writebuf)
+{
+  int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+                       || TYPE_CODE (valtype) == TYPE_CODE_UNION
+                       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
+                      && !(TYPE_LENGTH (valtype) == 1
+                           || TYPE_LENGTH (valtype) == 2
+                           || TYPE_LENGTH (valtype) == 4
+                           || TYPE_LENGTH (valtype) == 8));
+
+  if (writebuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      error (_("Cannot store return value."));
+    }
+
+  if (readbuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      avr_extract_return_value (valtype, regcache, readbuf);
+    }
+
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+
 /* Put here the code to store, into fi->saved_regs, the addresses of
    the saved registers of frame described by FRAME_INFO.  This
    includes special registers such as pc and fp saved in special ways
@@ -1271,7 +1309,7 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_name (gdbarch, avr_register_name);
   set_gdbarch_register_type (gdbarch, avr_register_type);
 
-  set_gdbarch_extract_return_value (gdbarch, avr_extract_return_value);
+  set_gdbarch_return_value (gdbarch, avr_return_value);
   set_gdbarch_print_insn (gdbarch, print_insn_avr);
 
   set_gdbarch_push_dummy_call (gdbarch, avr_push_dummy_call);
index c6746b99b289875317ca047578073c5810a6be29..6dd7d365d176d11b8180095026958aa96bd3ecc9 100644 (file)
@@ -1247,6 +1247,33 @@ frv_store_return_value (struct type *type, struct regcache *regcache,
                     _("Don't know how to return a %d-byte value."), len);
 }
 
+enum return_value_convention
+frv_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                 struct regcache *regcache, gdb_byte *readbuf,
+                 const gdb_byte *writebuf)
+{
+  int struct_return = TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+                     || TYPE_CODE (valtype) == TYPE_CODE_UNION
+                     || TYPE_CODE (valtype) == TYPE_CODE_ARRAY;
+
+  if (writebuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      frv_store_return_value (valtype, regcache, writebuf);
+    }
+
+  if (readbuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      frv_extract_return_value (valtype, regcache, readbuf);
+    }
+
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
 
 /* Hardware watchpoint / breakpoint support for the FR500
    and FR400.  */
@@ -1488,10 +1515,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_adjust_breakpoint_address
     (gdbarch, frv_adjust_breakpoint_address);
 
-  set_gdbarch_deprecated_use_struct_convention (gdbarch, always_use_struct_convention);
-  set_gdbarch_extract_return_value (gdbarch, frv_extract_return_value);
-
-  set_gdbarch_store_return_value (gdbarch, frv_store_return_value);
+  set_gdbarch_return_value (gdbarch, frv_return_value);
 
   /* Frame stuff.  */
   set_gdbarch_unwind_pc (gdbarch, frv_unwind_pc);
index dd938c95e854f460ee20c2adcfde048379d069ca..debee50851ce7e243af26cfb383ab6364a6de15f 100644 (file)
@@ -2929,14 +2929,18 @@ static struct libunwind_descr ia64_libunwind_descr =
 
 #endif /* HAVE_LIBUNWIND_IA64_H  */
 
-/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
-   gdbarch_extract_return_value?  GCC_P is true if compiled with gcc and TYPE
-   is the type (which is known to be struct, union or array).  */
-int
-ia64_use_struct_convention (int gcc_p, struct type *type)
+static int
+ia64_use_struct_convention (struct type *type)
 {
   struct type *float_elt_type;
 
+  /* Don't use the struct convention for anything but structure,
+     union, or array types.  */
+  if (!(TYPE_CODE (type) == TYPE_CODE_STRUCT
+       || TYPE_CODE (type) == TYPE_CODE_UNION
+       || TYPE_CODE (type) == TYPE_CODE_ARRAY))
+    return 0;
+
   /* HFAs are structures (or arrays) consisting entirely of floating
      point values of the same length.  Up to 8 of these are returned
      in registers.  Don't use the struct convention when this is the
@@ -2951,7 +2955,7 @@ ia64_use_struct_convention (int gcc_p, struct type *type)
   return TYPE_LENGTH (type) > 32;
 }
 
-void
+static void
 ia64_extract_return_value (struct type *type, struct regcache *regcache,
                           gdb_byte *valbuf)
 {
@@ -3001,6 +3005,80 @@ ia64_extract_return_value (struct type *type, struct regcache *regcache,
     }
 }
 
+static void
+ia64_store_return_value (struct type *type, struct regcache *regcache, 
+                        const gdb_byte *valbuf)
+{
+  struct type *float_elt_type;
+
+  float_elt_type = is_float_or_hfa_type (type);
+  if (float_elt_type != NULL)
+    {
+      char to[MAX_REGISTER_SIZE];
+      int offset = 0;
+      int regnum = IA64_FR8_REGNUM;
+      int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
+
+      while (n-- > 0)
+       {
+         convert_typed_floating ((char *)valbuf + offset, float_elt_type,
+                                 to, builtin_type_ia64_ext);
+         regcache_cooked_write (regcache, regnum, to);
+         offset += TYPE_LENGTH (float_elt_type);
+         regnum++;
+       }
+    }
+  else
+    {
+      ULONGEST val;
+      int offset = 0;
+      int regnum = IA64_GR8_REGNUM;
+      int reglen = TYPE_LENGTH (register_type (get_regcache_arch (regcache),
+                                              IA64_GR8_REGNUM));
+      int n = TYPE_LENGTH (type) / reglen;
+      int m = TYPE_LENGTH (type) % reglen;
+
+      while (n-- > 0)
+       {
+         ULONGEST val;
+         memcpy (&val, (char *)valbuf + offset, reglen);
+         regcache_cooked_write_unsigned (regcache, regnum, val);
+         offset += reglen;
+         regnum++;
+       }
+
+      if (m)
+       {
+         memcpy (&val, (char *)valbuf + offset, m);
+          regcache_cooked_write_unsigned (regcache, regnum, val);
+       }
+    }
+}
+  
+static enum return_value_convention
+ia64_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                  struct regcache *regcache, gdb_byte *readbuf,
+                  const gdb_byte *writebuf)
+{
+  int struct_return = ia64_use_struct_convention (valtype);
+
+  if (writebuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      ia64_store_return_value (valtype, regcache, writebuf);
+    }
+
+  if (readbuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      ia64_extract_return_value (valtype, regcache, readbuf);
+    }
+
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
+}
 
 static int
 is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
@@ -3462,21 +3540,6 @@ ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return pc;
 }
 
-static void
-ia64_store_return_value (struct type *type, struct regcache *regcache, 
-                       const gdb_byte *valbuf)
-{
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    {
-      char to[MAX_REGISTER_SIZE];
-      convert_typed_floating (valbuf, type, to, builtin_type_ia64_ext);
-      regcache_cooked_write (regcache, IA64_FR8_REGNUM, (void *)to);
-      target_store_registers (regcache, IA64_FR8_REGNUM);
-    }
-  else
-    regcache_cooked_write (regcache, IA64_GR8_REGNUM, valbuf);
-}
-
 static int
 ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
 {
@@ -3544,10 +3607,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
 
-  set_gdbarch_deprecated_use_struct_convention (gdbarch, ia64_use_struct_convention);
-  set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
-
-  set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
+  set_gdbarch_return_value (gdbarch, ia64_return_value);
 
   set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint);
   set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);