From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21225 invoked by alias); 23 Sep 2003 20:34:29 -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 21218 invoked from network); 23 Sep 2003 20:34:27 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 23 Sep 2003 20:34:27 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h8NKYQ114481 for ; Tue, 23 Sep 2003 16:34:26 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h8NKYPc30577 for ; Tue, 23 Sep 2003 16:34:25 -0400 Received: from localhost.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by pobox.corp.redhat.com (8.12.8/8.12.8) with ESMTP id h8NKYORC005746 for ; Tue, 23 Sep 2003 16:34:25 -0400 Received: by localhost.redhat.com (Postfix, from userid 469) id 8EF242CC8B; Tue, 23 Sep 2003 16:44:03 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16240.45203.260059.116019@localhost.redhat.com> Date: Tue, 23 Sep 2003 20:34:00 -0000 To: gdb-patches@sources.redhat.com Subject: Re: [RFA] sh-tdep.c: Follow up patch to implement two different ABIs In-Reply-To: <20030917161127.GM9981@cygbert.vinschen.de> References: <20030917161127.GM9981@cygbert.vinschen.de> X-SW-Source: 2003-09/txt/msg00508.txt.bz2 Corinna Vinschen writes: > Hi, > > the below patch is a follow up patch which relies on the pending sh frame > stuff patch. This patch now adds the ability to switch between two > different ABIs on the gdb command line, the "gcc" and the "renesas" ABI. > The patch also implements the differences between these ABIs which changes > the way how arguments are passed and values are returned. Additionally it > fixes the argument passing of doubles in the gcc ABI on sh variations with > FPU. The changes in detail: I think this patch has too much stuff in it. Can you change it to fix the gcc abi (the fpu stuff), and then add the rest for the renesas variant? > > - Add the commands `set calling_convention ' and > `show calling_convention' with being one of "gcc" and "renesas". > Default to "gcc". Should be using hyphen, not underscore. What happens if you have a file compiled with renesas ABI but you set the calling convention to the gcc (or vice versa)? How are the abi supported by gcc? Is there a -with-abi-renesas to be given when one compiles the tests? I.e. is it possible to run the testsuite with the one specific abi? > > - Differ between a fpu and a nofpu version of sh_use_struct_convention. > The nofpu version behaves like the fpu version, except that it uses > struct convention also for all types >= 8 bytes when the Renesas ABI > is active. This especially affects long longs and doubles which are > then passed on the stack. > > - The Renesas ABI passes the address in which structs have to be returned > not in r2 as the gcc ABI, but instead this return address is pushed > onto the stack after all arguments have been pushed. This affects > sh_extract_struct_value_address() as well as the sh_push_dummy_call*() > functions. > > - To simplify the sh_push_dummy_call*() functions, I created two helper > functions which took the part of right-justifying values < 4 byte, > called sh_justify_value_in_reg(), and to count the number of bytes > to be allocated on stack for all arguments, called sh_stack_allocsize(). > > - Two new functions are now used to evaluate the next floating point > register to use for an argument. The tricky part with floats is > that gcc and Renesas ABI are different in two situations: > > - gcc passes floats in little-endian mode using regsters criss-crossing, > fr5, fr4, fr7, fr6, fr9, fr8 ... In big-endian mode or in Renesas > ABI, the order is simple fr4, fr5, fr6, ... > > - In both ABIs doubles are passed in even register pairs, fr4/fr5, > fr6/fr7, ... The difference is when a register is skipped to pass > the next double. Example: > > void foo(float a, double b, float c); > > In gcc ABI, a is passed in fr4, b then skips the odd-numbered fr5 > register, so it's passed in fr6/fr7 and c is then passed in the next > free register, fr8. > > In Renesas ABI, a is passed in fr4, b is passed as in gcc ABI in > fr6/fr7 but c is passed in the lowest unused register, in this example > in fr5. > > - In the Renesas ABI for CPUs with FPU, long longs are not passed in > registers but on stack. > > - The struct_return code in both sh_push_dummy_call*() functions is moved > to the end of the function since it must be done after the argument > passing for the Rensas ABI. > > - I renamed the flag `odd_sized_struct' to a more descriptive name, > `pass_on_stack' since the old name does in no way reflect how the > decision about passing on stack or in register is actually made. The > actual decision is as follows: > > - On FPU CPUs, pass in registers unless the datatype is bigger than > 16 bytes. Renesas ABI additionally passes long longs on the stack > as well. > > - On non-FPU CPUs, doubles and long doubles are passed always on the stack. > > - On all CPUs, everything else is passed in registers until the argument > registers are filled up, the remaining arguments are passed on stack. > If an argument doesn't fit entirely in the remaining registers, it's > split between regs and stack as see fit. > > - The code and comment that some data is sometimes passed in registers > *and* stack simultaneously is dropped. That's not how it works. > Seems to be something sh5 specific but that's now in sh64-tdep.c. > Actually this is part of the original port as contributed by Steve Chamberlain. Is this true of gcc or of the original hitachi abi? > - Also in sh_push_dummy_call*(), the code which adds 4 for every 4 bytes > managed, is changed from e.g. > > len -= register_size (gdbarch, argreg); > > to > > len -= 4; > > The reason is that the original line is not exactly correct. It adds the > register_size of the *next* register, not the register actually filled > with data. Since all data and registers in question are 4 byte regs (and > the target specific code should know that anyway), I've simplified the > affected code. > I don't like to have harcoded register sizes, if argreg is wrong, is there a way to get the correct parameter? elena > > Corinna > > > ChangeLog: > ========== > > * sh-tdep.c (sh_cc_gcc): New static string. > (sh_cc_renesas): Ditto. > (sh_cc_enum): New array pointing to calling convention strings. > (sh_active_calling_convention): New variable pointing to > current active calling convention. > (sh_use_struct_convention_fpu): New function. > (sh_use_struct_convention_nofpu): New function. > (sh_use_struct_convention): Remove. Superseeded by the previous > two functions. > (sh_extract_struct_value_address): Care for Renesas ABI. > (sh_justify_value_in_reg): New function. > (sh_stack_allocsize): Ditto. > (flt_argreg_array): New array used for floating point argument > passing. > (sh_init_flt_argreg): New function. > (sh_next_flt_argreg): Ditto. > (sh_push_dummy_call_fpu): Simplify. Rename "odd_sized_struct" to > "pass_on_stack". Use new helper functions. Accomodate Renesas ABI. > Fix argument passing strategy. > (sh_push_dummy_call_nofpu): Ditto. > (sh_gdbarch_init): Accomodate new sh_use_struct_convention_fpu and > sh_use_struct_convention_nofpu functions. > (_initialize_sh_tdep): Initialize new "set calling_convention", > "show calling_convention" commands. > > --- sh-tdep.c.AFTERPATCH2 2003-09-15 17:14:33.000000000 +0200 > +++ sh-tdep.c 2003-09-16 18:17:39.000000000 +0200 > @@ -55,6 +55,17 @@ > /* registers numbers shared with the simulator */ > #include "gdb/sim-sh.h" > > +static const char sh_cc_gcc[] = "gcc"; > +static const char sh_cc_renesas[] = "renesas"; > +static const char *sh_cc_enum[] = > +{ > + sh_cc_gcc, > + sh_cc_renesas, > + NULL > +}; > + > +static const char *sh_active_calling_convention = sh_cc_gcc; > + > static void (*sh_show_regs) (void); > > #define SH_NUM_REGS 59 > @@ -569,10 +580,25 @@ sh_skip_prologue (CORE_ADDR start_pc) > > /* Should call_function allocate stack space for a struct return? */ > static int > -sh_use_struct_convention (int gcc_p, struct type *type) > +sh_use_struct_convention_fpu (int gcc_p, struct type *type) > +{ > + int len = TYPE_LENGTH (type); > + int nelem = TYPE_NFIELDS (type); > + > + return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) && > + (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4); > +} > + > +static int > +sh_use_struct_convention_nofpu (int gcc_p, struct type *type) > { > int len = TYPE_LENGTH (type); > int nelem = TYPE_NFIELDS (type); > + > + /* The Renesas ABI returns long longs/doubles etc. always on stack. */ > + if (sh_active_calling_convention == sh_cc_renesas && len >= 8) > + return 1; > + > return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) && > (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4); > } > @@ -584,8 +610,13 @@ static CORE_ADDR > sh_extract_struct_value_address (struct regcache *regcache) > { > ULONGEST addr; > - > - regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr); > + if (sh_active_calling_convention != sh_cc_renesas) > + regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr); > + else > + { > + regcache_cooked_read_unsigned (regcache, SP_REGNUM, &addr); > + addr = read_memory_unsigned_integer (addr, 4); > + } > return addr; > } > > @@ -647,6 +678,102 @@ sh_frame_align (struct gdbarch *ignore, > not displace any of the other arguments passed in via registers R4 > to R7. */ > > +/* Helper function to justify value in register according to endianess. */ > +static char * > +sh_justify_value_in_reg (struct value *val, int len) > +{ > + static char valbuf[4]; > + > + memset (valbuf, 0, sizeof (valbuf)); > + if (len < 4) > + { > + /* value gets right-justified in the register or stack word */ > + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) > + memcpy (valbuf + (4 - len), (char *) VALUE_CONTENTS (val), len); > + else > + memcpy (valbuf, (char *) VALUE_CONTENTS (val), len); > + return valbuf; > + } > + return (char *) VALUE_CONTENTS (val); > +} > + > +/* Helper function to eval number of bytes to allocate on stack. */ > +static CORE_ADDR > +sh_stack_allocsize (int nargs, struct value **args) > +{ > + int stack_alloc = 0; > + while (nargs-- > 0) > + stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[nargs])) + 3) & ~3); > + return stack_alloc; > +} > + > +/* Helper functions for getting the float arguments right. Registers usage > + depends on the ABI and the endianess. The comments should enlighten how > + it's intended to work. */ > + > +/* This array stores which of the float arg registers are already in use. */ > +static int flt_argreg_array[FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM + 1]; > + > +/* This function just resets the above array to "no reg used so far". */ > +static void > +sh_init_flt_argreg (void) > +{ > + memset (flt_argreg_array, 0, sizeof flt_argreg_array); > +} > + > +/* This function returns the next register to use for float arg passing. > + It returns either a valid value between FLOAT_ARG0_REGNUM and > + FLOAT_ARGLAST_REGNUM if a register is available, otherwise it returns > + FLOAT_ARGLAST_REGNUM + 1 to indicate that no register is available. > + > + Note that register number 0 in flt_argreg_array corresponds with the > + real float register fr4. In contrast to FLOAT_ARG0_REGNUM (value is > + 29) the parity of the register number is preserved, which is important > + for the double register passing test (see the "argreg & 1" test below). */ > +static int > +sh_next_flt_argreg (int len) > +{ > + int argreg; > + > + /* First search for the next free register. */ > + for (argreg = 0; argreg <= FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM; ++argreg) > + if (!flt_argreg_array[argreg]) > + break; > + > + /* No register left? */ > + if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM) > + return FLOAT_ARGLAST_REGNUM + 1; > + > + if (len == 8) > + { > + /* Doubles are always starting in a even register number. */ > + if (argreg & 1) > + { > + /* In gcc ABI, the skipped register is lost for further argument > + passing now. Not so in Renesas ABI. */ > + if (sh_active_calling_convention != sh_cc_renesas) > + flt_argreg_array[argreg] = 1; > + > + ++argreg; > + > + /* No register left? */ > + if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM) > + return FLOAT_ARGLAST_REGNUM + 1; > + } > + /* Also mark the next register as used. */ > + flt_argreg_array[argreg + 1] = 1; > + } > + else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE > + && sh_active_calling_convention != sh_cc_renesas) > + { > + /* In little endian, gcc passes floats like this: f5, f4, f7, f6, ... */ > + if (!flt_argreg_array[argreg + 1]) > + ++argreg; > + } > + flt_argreg_array[argreg] = 1; > + return FLOAT_ARG0_REGNUM + argreg; > +} > + > static CORE_ADDR > sh_push_dummy_call_fpu (struct gdbarch *gdbarch, > CORE_ADDR func_addr, > @@ -656,77 +783,61 @@ sh_push_dummy_call_fpu (struct gdbarch * > CORE_ADDR sp, int struct_return, > CORE_ADDR struct_addr) > { > - int stack_offset, stack_alloc; > - int argreg, flt_argreg; > + int stack_offset = 0; > + int argreg = ARG0_REGNUM; > + int flt_argreg; > int argnum; > struct type *type; > CORE_ADDR regval; > char *val; > - char valbuf[4]; > int len; > - int odd_sized_struct; > + int pass_on_stack; > > /* first force sp to a 4-byte alignment */ > sp = sh_frame_align (gdbarch, sp); > > - if (struct_return) > - regcache_cooked_write_unsigned (regcache, > - STRUCT_RETURN_REGNUM, > - struct_addr); > - > - /* Now make sure there's space on the stack */ > - for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++) > - stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); > - sp -= stack_alloc; /* make room on stack for args */ > + /* make room on stack for args */ > + sp -= sh_stack_allocsize (nargs, args); > + > + /* Initialize float argument mechanism. */ > + sh_init_flt_argreg (); > > /* Now load as many as possible of the first arguments into > registers, and push the rest onto the stack. There are 16 bytes > in four registers available. Loop thru args from first to last. */ > - > - argreg = ARG0_REGNUM; > - flt_argreg = FLOAT_ARG0_REGNUM; > - for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) > + for (argnum = 0; argnum < nargs; argnum++) > { > type = VALUE_TYPE (args[argnum]); > len = TYPE_LENGTH (type); > - memset (valbuf, 0, sizeof (valbuf)); > - if (len < 4) > - { > - /* value gets right-justified in the register or stack word */ > - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) > - memcpy (valbuf + (4 - len), > - (char *) VALUE_CONTENTS (args[argnum]), len); > - else > - memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len); > - val = valbuf; > - } > - else > - val = (char *) VALUE_CONTENTS (args[argnum]); > + val = sh_justify_value_in_reg (args[argnum], len); > + > + /* Some decisions have to be made how various types are handled. > + This also differs in different ABIs. */ > + pass_on_stack = 0; > + if (len > 16) > + pass_on_stack = 1; /* Types bigger than 16 bytes are passed on stack. */ > + else if (sh_active_calling_convention == sh_cc_renesas > + && TYPE_CODE (type) == TYPE_CODE_INT && len == 8) > + pass_on_stack = 1; /* So are long longs in renesas ABI */ > + > + /* Find out the next register to use for a floating point value. */ > + if (TYPE_CODE (type) == TYPE_CODE_FLT) > + flt_argreg = sh_next_flt_argreg (len); > > - if (len > 4 && (len & 3) != 0) > - odd_sized_struct = 1; /* Such structs go entirely on stack. */ > - else if (len > 16) > - odd_sized_struct = 1; /* So do aggregates bigger than 4 words. */ > - else > - odd_sized_struct = 0; > while (len > 0) > { > if ((TYPE_CODE (type) == TYPE_CODE_FLT > && flt_argreg > FLOAT_ARGLAST_REGNUM) > || argreg > ARGLAST_REGNUM > - || odd_sized_struct) > + || pass_on_stack) > { > - /* must go on the stack */ > write_memory (sp + stack_offset, val, 4); > stack_offset += 4; > } > - /* NOTE WELL!!!!! This is not an "else if" clause!!! > - That's because some *&^%$ things get passed on the stack > - AND in the registers! */ > - if (TYPE_CODE (type) == TYPE_CODE_FLT && > - flt_argreg > 0 && flt_argreg <= FLOAT_ARGLAST_REGNUM) > + else if (TYPE_CODE (type) == TYPE_CODE_FLT > + && flt_argreg <= FLOAT_ARGLAST_REGNUM) > { > - /* Argument goes in a single-precision fp reg. */ > + /* Argument goes in a float argument register. */ > regval = extract_unsigned_integer (val, register_size (gdbarch, > argreg)); > regcache_cooked_write_unsigned (regcache, flt_argreg++, regval); > @@ -741,11 +852,25 @@ sh_push_dummy_call_fpu (struct gdbarch * > /* Store the value 4 bytes at a time. This means that things > larger than 4 bytes may go partly in registers and partly > on the stack. */ > - len -= register_size (gdbarch, argreg); > - val += register_size (gdbarch, argreg); > + len -= 4; > + val += 4; > } > } > > + if (struct_return) > + { > + if (sh_active_calling_convention != sh_cc_renesas) > + /* Using the gcc ABI, the "struct return pointer" pseudo-argument has > + its own dedicated register */ > + regcache_cooked_write_unsigned (regcache, > + STRUCT_RETURN_REGNUM, > + struct_addr); > + else > + /* If the function uses the renesas ABI, subtract another 4 bytes from > + the stack and store the struct return address there. */ > + write_memory_unsigned_integer (sp -= 4, 4, struct_addr); > + } > + > /* Store return address. */ > regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr); > > @@ -764,69 +889,45 @@ sh_push_dummy_call_nofpu (struct gdbarch > CORE_ADDR sp, int struct_return, > CORE_ADDR struct_addr) > { > - int stack_offset, stack_alloc; > - int argreg; > + int stack_offset = 0; > + int argreg = ARG0_REGNUM; > int argnum; > struct type *type; > CORE_ADDR regval; > char *val; > - char valbuf[4]; > int len; > - int odd_sized_struct; > + int pass_on_stack; > > /* first force sp to a 4-byte alignment */ > sp = sh_frame_align (gdbarch, sp); > > - if (struct_return) > - regcache_cooked_write_unsigned (regcache, > - STRUCT_RETURN_REGNUM, > - struct_addr); > - > - /* Now make sure there's space on the stack */ > - for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++) > - stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); > - sp -= stack_alloc; /* make room on stack for args */ > + /* make room on stack for args */ > + sp -= sh_stack_allocsize (nargs, args); > > /* Now load as many as possible of the first arguments into > registers, and push the rest onto the stack. There are 16 bytes > in four registers available. Loop thru args from first to last. */ > - > - argreg = ARG0_REGNUM; > - for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) > + for (argnum = 0; argnum < nargs; argnum++) > { > type = VALUE_TYPE (args[argnum]); > len = TYPE_LENGTH (type); > - memset (valbuf, 0, sizeof (valbuf)); > - if (len < 4) > - { > - /* value gets right-justified in the register or stack word */ > - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) > - memcpy (valbuf + (4 - len), > - (char *) VALUE_CONTENTS (args[argnum]), len); > - else > - memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len); > - val = valbuf; > - } > - else > - val = (char *) VALUE_CONTENTS (args[argnum]); > + val = sh_justify_value_in_reg (args[argnum], len); > + > + /* Some decisions have to be made how various types are handled. > + This also differs in different ABIs. */ > + pass_on_stack = 0; > + if (TYPE_CODE (type) == TYPE_CODE_FLT && len > 4 > + && sh_active_calling_convention == sh_cc_renesas) > + pass_on_stack = 1; /* Renesas ABI pushes doubles entirely on stack. */ > > - if (len > 4 && (len & 3) != 0) > - odd_sized_struct = 1; /* such structs go entirely on stack */ > - else > - odd_sized_struct = 0; > while (len > 0) > { > - if (argreg > ARGLAST_REGNUM > - || odd_sized_struct) > + if (argreg > ARGLAST_REGNUM || pass_on_stack) > { > - /* must go on the stack */ > write_memory (sp + stack_offset, val, 4); > stack_offset += 4; > } > - /* NOTE WELL!!!!! This is not an "else if" clause!!! > - That's because some *&^%$ things get passed on the stack > - AND in the registers! */ > - if (argreg <= ARGLAST_REGNUM) > + else if (argreg <= ARGLAST_REGNUM) > { > /* there's room in a register */ > regval = extract_unsigned_integer (val, register_size (gdbarch, > @@ -836,11 +937,25 @@ sh_push_dummy_call_nofpu (struct gdbarch > /* Store the value 4 bytes at a time. This means that things > larger than 4 bytes may go partly in registers and partly > on the stack. */ > - len -= register_size (gdbarch, argreg); > - val += register_size (gdbarch, argreg); > + len -= 4; > + val += 4; > } > } > > + if (struct_return) > + { > + if (sh_active_calling_convention != sh_cc_renesas) > + /* Using the gcc ABI, the "struct return pointer" pseudo-argument has > + its own dedicated register */ > + regcache_cooked_write_unsigned (regcache, > + STRUCT_RETURN_REGNUM, > + struct_addr); > + else > + /* If the function uses the renesas ABI, subtract another 4 bytes from > + the stack and store the struct return address there. */ > + write_memory_unsigned_integer (sp -= 4, 4, struct_addr); > + } > + > /* Store return address. */ > regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr); > > @@ -2060,7 +2175,6 @@ sh_gdbarch_init (struct gdbarch_info inf > set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > > set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc); > - set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention); > > set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh); > set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno); > @@ -2079,6 +2193,7 @@ sh_gdbarch_init (struct gdbarch_info inf > > set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > + set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_nofpu); > > set_gdbarch_frame_args_skip (gdbarch, 0); > set_gdbarch_frameless_function_invocation (gdbarch, > @@ -2114,6 +2229,7 @@ sh_gdbarch_init (struct gdbarch_info inf > set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); > set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); > + set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_fpu); > break; > > case bfd_mach_sh_dsp: > @@ -2135,6 +2251,7 @@ sh_gdbarch_init (struct gdbarch_info inf > set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); > set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); > + set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_fpu); > break; > > case bfd_mach_sh3_dsp: > @@ -2152,6 +2269,7 @@ sh_gdbarch_init (struct gdbarch_info inf > set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); > set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); > + set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_fpu); > break; > > default: > @@ -2178,4 +2296,11 @@ _initialize_sh_tdep (void) > gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL); > > add_com ("regs", class_vars, sh_show_regs_command, "Print all registers"); > + > + add_show_from_set ( > + add_set_enum_cmd ("calling_convention", class_vars, sh_cc_enum, > + &sh_active_calling_convention, > + "Set calling convention used when calling target " > + "functions from GDB.", > + &setlist), &showlist); > } > > -- > Corinna Vinschen > Cygwin Developer > Red Hat, Inc.