summaryrefslogtreecommitdiff
path: root/gdb/m68k-tdep.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2003-07-09 21:36:08 +0000
committerAndreas Schwab <schwab@suse.de>2003-07-09 21:36:08 +0000
commit71159d89b9b0fd23e1eb1085a9c3117f7f59f902 (patch)
treeb5af2aaf93a1e29c62d8b1f8a2c0c5c06d269eba /gdb/m68k-tdep.c
parentc81b613a69dad126009fa6bb8cf09b2cdded0535 (diff)
downloadgdb-71159d89b9b0fd23e1eb1085a9c3117f7f59f902.tar.gz
* m68k-tdep.h (enum struct_return): Define.
(struct gdbarch_tdep): Add struct_return. * m68k-tdep.c (m68k_push_dummy_call): Non-scalars bigger than 4 bytes are padded to the right, not to the left. Pass struct value address in register %a1, not on stack. (m68k_use_struct_convention): New function. (m68k_gdbarch_init): Set use_struct_convention. Initialize struct_return in tdep to pcc_struct_return. * m68klinux-tdep.c (m68k_linux_init_abi): Set struct_return to reg_struct_return.
Diffstat (limited to 'gdb/m68k-tdep.c')
-rw-r--r--gdb/m68k-tdep.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index 2a675e063de..97ac076ab53 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -235,6 +235,16 @@ m68k_extract_struct_value_address (struct regcache *regcache)
return extract_unsigned_integer (buf, 4);
}
+static int
+m68k_use_struct_convention (int gcc_p, struct type *type)
+{
+ enum struct_return struct_return;
+
+ struct_return = gdbarch_tdep (current_gdbarch)->struct_return;
+ return generic_use_struct_convention (struct_return == reg_struct_return,
+ type);
+}
+
/* A function that tells us whether the function invocation represented
by fi does not have a frame on the stack associated with it. If it
does not, FRAMELESS is set to 1, else 0. */
@@ -317,20 +327,29 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* Push arguments in reverse order. */
for (i = nargs - 1; i >= 0; i--)
{
- int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+ struct type *value_type = VALUE_ENCLOSING_TYPE (args[i]);
+ int len = TYPE_LENGTH (value_type);
int container_len = (len + 3) & ~3;
- int offset = container_len - len;
-
+ int offset;
+
+ /* Non-scalars bigger than 4 bytes are left aligned, others are
+ right aligned. */
+ if ((TYPE_CODE (value_type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (value_type) == TYPE_CODE_UNION
+ || TYPE_CODE (value_type) == TYPE_CODE_ARRAY)
+ && len > 4)
+ offset = 0;
+ else
+ offset = container_len - len;
sp -= container_len;
write_memory (sp + offset, VALUE_CONTENTS_ALL (args[i]), len);
}
- /* Push value address. */
+ /* Store struct value address. */
if (struct_return)
{
- sp -= 4;
store_unsigned_integer (buf, 4, struct_addr);
- write_memory (sp, buf, 4);
+ regcache_cooked_write (regcache, M68K_A1_REGNUM, buf);
}
/* Store return address. */
@@ -1100,6 +1119,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_store_return_value (gdbarch, m68k_store_return_value);
set_gdbarch_extract_struct_value_address (gdbarch,
m68k_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch, m68k_use_struct_convention);
set_gdbarch_frameless_function_invocation (gdbarch,
m68k_frameless_function_invocation);
@@ -1126,6 +1146,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->jb_pc = -1;
#endif
tdep->get_sigtramp_info = NULL;
+ tdep->struct_return = pcc_struct_return;
/* Frame unwinder. */
set_gdbarch_unwind_dummy_id (gdbarch, m68k_unwind_dummy_id);