From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23750 invoked by alias); 9 Jul 2003 21:33:25 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 23741 invoked from network); 9 Jul 2003 21:33:25 -0000 Received: from unknown (HELO lisa.goe.net) (134.76.166.209) by sources.redhat.com with SMTP; 9 Jul 2003 21:33:25 -0000 Received: from mutter.goe.net (mutter-lisa0.a11.local [192.168.31.26]) by lisa.goe.net (8.12.6/8.12.6) with ESMTP id h69LXNqI032678 for ; Wed, 9 Jul 2003 23:33:23 +0200 Received: from whitebox.a11.local ([192.168.31.90] helo=whitebox.as.local) by mutter.goe.net with esmtp (Exim 4.20) id 19aMZ0-000335-QJ for gdb-patches@sources.redhat.com; Wed, 09 Jul 2003 23:33:22 +0200 Received: from whitebox.as.local (localhost [127.0.0.1]) by whitebox.as.local (8.12.7/8.12.7/SuSE Linux 0.6) with ESMTP id h69LXN8P013153 for ; Wed, 9 Jul 2003 23:33:24 +0200 Received: (from andreas@localhost) by whitebox.as.local (8.12.7/8.12.7/Submit) id h69LXMuA013152; Wed, 9 Jul 2003 23:33:22 +0200 X-Authentication-Warning: whitebox.as.local: andreas set sender to schwab@suse.de using -f To: gdb-patches@sources.redhat.com Subject: Fix m68k structure passing From: Andreas Schwab X-Yow: I'm ANN LANDERS!! I can SHOPLIFT!! Date: Wed, 09 Jul 2003 21:33:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-07/txt/msg00197.txt.bz2 This fixes all remaining testsuite failures about structure passing and returning. Committing in 6.0 branch and mainline. Andreas. 2003-07-09 Andreas Schwab * 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. Index: gdb/m68k-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/m68k-tdep.c,v retrieving revision 1.69.4.1 diff -u -a -p -r1.69.4.1 m68k-tdep.c --- gdb/m68k-tdep.c 7 Jul 2003 15:07:23 -0000 1.69.4.1 +++ gdb/m68k-tdep.c 9 Jul 2003 21:11:16 -0000 @@ -235,6 +235,16 @@ m68k_extract_struct_value_address (struc 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 *gd /* 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 i 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 i 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); Index: gdb/m68k-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/m68k-tdep.h,v retrieving revision 1.2.8.1 diff -u -a -p -r1.2.8.1 m68k-tdep.h --- gdb/m68k-tdep.h 7 Jul 2003 15:07:23 -0000 1.2.8.1 +++ gdb/m68k-tdep.h 9 Jul 2003 21:11:17 -0000 @@ -61,6 +61,14 @@ struct m68k_sigtramp_info int *sc_reg_offset; }; +/* Convention for returning structures. */ + +enum struct_return +{ + pcc_struct_return, /* Return "short" structures in memory. */ + reg_struct_return /* Return "short" structures in registers. */ +}; + /* Target-dependent structure in gdbarch. */ struct gdbarch_tdep { @@ -72,6 +80,9 @@ struct gdbarch_tdep /* Get info about sigtramp. */ struct m68k_sigtramp_info (*get_sigtramp_info) (struct frame_info *); + + /* Convention for returning structures. */ + enum struct_return struct_return; }; #endif /* M68K_TDEP_H */ Index: gdb/m68klinux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/m68klinux-tdep.c,v retrieving revision 1.6.4.1 diff -u -a -p -r1.6.4.1 m68klinux-tdep.c --- gdb/m68klinux-tdep.c 7 Jul 2003 15:07:23 -0000 1.6.4.1 +++ gdb/m68klinux-tdep.c 9 Jul 2003 21:11:17 -0000 @@ -290,6 +290,7 @@ m68k_linux_init_abi (struct gdbarch_info tdep->jb_pc = M68K_LINUX_JB_PC; tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE; tdep->get_sigtramp_info = m68k_linux_get_sigtramp_info; + tdep->struct_return = reg_struct_return; set_gdbarch_extract_return_value (gdbarch, m68k_linux_extract_return_value); set_gdbarch_store_return_value (gdbarch, m68k_linux_store_return_value);