aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/sh-tdep.c59
2 files changed, 51 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0f5deaf..99840d3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2003-10-09 Elena Zannoni <ezannoni@redhat.com>
+
+ * sh-tdep.c (sh_gdbarch_init): Delete setting of push_dummy_code.
+ (sh_gdbarch_init): Delete function, it's only used for dummy calls
+ on stack.
+
+ Based on input by Stephen Clarke (stephen.clarke@superh.com):
+ * sh-tdep.c (sh_use_struct_convention): Add comment explaining ABI
+ in detail.
+
2003-10-09 Daniel Jacobowitz <drow@mvista.com>
* remote-mips.c (mips_initialize): Remove unneeded call to
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 9d50fbd..35b9e71 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -266,22 +266,6 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
return breakpoint;
}
-static CORE_ADDR
-sh_push_dummy_code (struct gdbarch *gdbarch,
- CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc,
- struct value **args, int nargs,
- struct type *value_type,
- CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
-{
- /* Allocate space sufficient for a breakpoint. */
- sp = (sp - 2) & ~1;
- /* Store the address of that breakpoint */
- *bp_addr = sp;
- /* sh always starts the call at the callee's entry point. */
- *real_pc = funaddr;
- return sp;
-}
-
/* Prologue looks like
mov.l r14,@-r15
sts.l pr,@-r15
@@ -559,7 +543,47 @@ sh_skip_prologue (CORE_ADDR start_pc)
return pc;
}
-/* Should call_function allocate stack space for a struct return? */
+/* Should call_function allocate stack space for a struct return?
+
+ The ABI says:
+
+ Aggregate types not bigger than 8 bytes that have the same size and
+ alignment as one of the integer scalar types are returned in the
+ same registers as the integer type they match.
+
+ For example, a 2-byte aligned structure with size 2 bytes has the
+ same size and alignment as a short int, and will be returned in R0.
+ A 4-byte aligned structure with size 8 bytes has the same size and
+ alignment as a long long int, and will be returned in R0 and R1.
+
+ When an aggregate type is returned in R0 and R1, R0 contains the
+ first four bytes of the aggregate, and R1 contains the
+ remainder. If the size of the aggregate type is not a multiple of 4
+ bytes, the aggregate is tail-padded up to a multiple of 4
+ bytes. The value of the padding is undefined. For little-endian
+ targets the padding will appear at the most significant end of the
+ last element, for big-endian targets the padding appears at the
+ least significant end of the last element.
+
+ All other aggregate types are returned by address. The caller
+ function passes the address of an area large enough to hold the
+ aggregate value in R2. The called function stores the result in
+ this location."
+
+ To reiterate, structs smaller than 8 bytes could also be returned
+ in memory, if they don't pass the "same size and alignment as an
+ integer type" rule.
+
+ For example, in
+
+ struct s { char c[3]; } wibble;
+ struct s foo(void) { return wibble; }
+
+ the return value from foo() will be in memory, not
+ in R0, because there is no 3-byte integer type.
+
+*/
+
static int
sh_use_struct_convention (int gcc_p, struct type *type)
{
@@ -2032,7 +2056,6 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_decr_pc_after_break (gdbarch, 0);
set_gdbarch_function_start_offset (gdbarch, 0);
- set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
set_gdbarch_frame_args_skip (gdbarch, 0);