This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] passing float arguments on SH
- From: Michael Snyder <msnyder at redhat dot com>
- To: gdb-patches at sources dot redhat dot com, Elena Zannoni <ezannoni at redhat dot com>
- Date: Wed, 30 Jul 2003 11:54:25 -0700
- Subject: [RFA] passing float arguments on SH
The sh4 passes floating point arguments in FP registers.
2003-07-30 Michael Snyder <msnyder@redhat.com>
* sh-tdep.h (struct gdbarch_tdep): New member FLOAT_ARGLAST_REG.
* sh-tdep.c (sh_gdbarch_init): For sh4, set FLOAT_ARG0_REGNUM
and FLOAT_ARGLAST_REGNUM, to be used for argument passing.
(sh_push_dummy_call): Use the above to pass floating point
arguments in floating point registers when called for.
Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.134
diff -p -r1.134 sh-tdep.c
*** sh-tdep.c 16 Jul 2003 09:45:56 -0000 1.134
--- sh-tdep.c 30 Jul 2003 18:32:10 -0000
*************** sh64_pop_frame (void)
*** 2028,2034 ****
flush_cached_frames ();
}
! /* Function: push_arguments
Setup the function arguments for calling a function in the inferior.
On the Hitachi SH architecture, there are four registers (R4 to R7)
--- 2028,2034 ----
flush_cached_frames ();
}
! /* Function: sh_push_dummy_call (formerly push_arguments)
Setup the function arguments for calling a function in the inferior.
On the Hitachi SH architecture, there are four registers (R4 to R7)
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2079,2085 ****
{
int stack_offset, stack_alloc;
! int argreg;
int argnum;
struct type *type;
CORE_ADDR regval;
--- 2079,2085 ----
{
int stack_offset, stack_alloc;
! int argreg, flt_argreg;
int argnum;
struct type *type;
CORE_ADDR regval;
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2095,2101 ****
/* The "struct return pointer" pseudo-argument has its own dedicated
register */
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++)
--- 2095,2103 ----
/* The "struct return pointer" pseudo-argument has its own dedicated
register */
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++)
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2107,2112 ****
--- 2109,2115 ----
in four registers available. Loop thru args from first to last. */
argreg = tdep->ARG0_REGNUM;
+ flt_argreg = tdep->FLOAT_ARG0_REGNUM;
for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
{
type = VALUE_TYPE (args[argnum]);
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2131,2137 ****
odd_sized_struct = 0;
while (len > 0)
{
! if (argreg > tdep->ARGLAST_REGNUM
|| odd_sized_struct)
{
/* must go on the stack */
--- 2134,2142 ----
odd_sized_struct = 0;
while (len > 0)
{
! if ((TYPE_CODE (type) == TYPE_CODE_FLT
! && flt_argreg > tdep->FLOAT_ARGLAST_REGNUM)
! || argreg > tdep->ARGLAST_REGNUM
|| odd_sized_struct)
{
/* must go on the stack */
*************** sh_push_dummy_call (struct gdbarch *gdba
*** 2141,2147 ****
/* 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 <= tdep->ARGLAST_REGNUM)
{
/* there's room in a register */
regval = extract_unsigned_integer (val, register_size (gdbarch,
--- 2146,2160 ----
/* 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 <= tdep->FLOAT_ARGLAST_REGNUM)
! {
! /* Argument goes in a single-precision fp reg. */
! regval = extract_unsigned_integer (val, register_size (gdbarch,
! argreg));
! regcache_cooked_write_unsigned (regcache, flt_argreg++, regval);
! }
! else if (argreg <= tdep->ARGLAST_REGNUM)
{
/* there's room in a register */
regval = extract_unsigned_integer (val, register_size (gdbarch,
*************** sh_gdbarch_init (struct gdbarch_info inf
*** 4523,4528 ****
--- 4536,4543 ----
tdep->DR_LAST_REGNUM = 66;
tdep->FV0_REGNUM = 67;
tdep->FV_LAST_REGNUM = 70;
+ tdep->FLOAT_ARG0_REGNUM = 29; /* FIXME use constants! */
+ tdep->FLOAT_ARGLAST_REGNUM = 36; /* FIXME use constants! */
set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
break;
Index: sh-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.h,v
retrieving revision 1.3
diff -p -r1.3 sh-tdep.h
*** sh-tdep.h 4 Jan 2003 23:38:45 -0000 1.3
--- sh-tdep.h 30 Jul 2003 18:32:10 -0000
*************** struct gdbarch_tdep
*** 85,91 ****
int FV_LAST_C_REGNUM; /* sh5-compact*/
int ARG0_REGNUM;
int ARGLAST_REGNUM;
! int FLOAT_ARGLAST_REGNUM;
int RETURN_REGNUM;
enum sh_abi sh_abi;
};
--- 85,92 ----
int FV_LAST_C_REGNUM; /* sh5-compact*/
int ARG0_REGNUM;
int ARGLAST_REGNUM;
! int FLOAT_ARG0_REGNUM; /* sh4 */
! int FLOAT_ARGLAST_REGNUM; /* sh4, sh5 */
int RETURN_REGNUM;
enum sh_abi sh_abi;
};