mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
gdb/testsuite/
* gdb.base/callfuncs.exp (do_function_calls): Use t_double_int and t_int_double. * gdb.base/callfuncs.c (t_double_int, t_int_double): New. gdb/ * mips-tdep.c (mips_n32n64_fp_arg_chunk_p): New. (mips_n32n64_push_dummy_call): Always increment float_argreg along with argreg. Use mips_n32n64_fp_arg_chunk_p.
This commit is contained in:
parent
65728c2698
commit
8d26208a1e
@ -1,3 +1,9 @@
|
||||
2007-08-22 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* mips-tdep.c (mips_n32n64_fp_arg_chunk_p): New.
|
||||
(mips_n32n64_push_dummy_call): Always increment float_argreg along
|
||||
with argreg. Use mips_n32n64_fp_arg_chunk_p.
|
||||
|
||||
2007-08-22 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* solib-svr4.c (scan_dyntag): Only read target memory when necessary.
|
||||
|
@ -2781,6 +2781,59 @@ mips_eabi_return_value (struct gdbarch *gdbarch,
|
||||
|
||||
/* N32/N64 ABI stuff. */
|
||||
|
||||
/* Search for a naturally aligned double at OFFSET inside a struct
|
||||
ARG_TYPE. The N32 / N64 ABIs pass these in floating point
|
||||
registers. */
|
||||
|
||||
static int
|
||||
mips_n32n64_fp_arg_chunk_p (struct type *arg_type, int offset)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (TYPE_CODE (arg_type) != TYPE_CODE_STRUCT)
|
||||
return 0;
|
||||
|
||||
if (MIPS_FPU_TYPE != MIPS_FPU_DOUBLE)
|
||||
return 0;
|
||||
|
||||
if (TYPE_LENGTH (arg_type) < offset + MIPS64_REGSIZE)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < TYPE_NFIELDS (arg_type); i++)
|
||||
{
|
||||
int pos;
|
||||
struct type *field_type;
|
||||
|
||||
/* We're only looking at normal fields. */
|
||||
if (TYPE_FIELD_STATIC (arg_type, i)
|
||||
|| (TYPE_FIELD_BITPOS (arg_type, i) % 8) != 0)
|
||||
continue;
|
||||
|
||||
/* If we have gone past the offset, there is no double to pass. */
|
||||
pos = TYPE_FIELD_BITPOS (arg_type, i) / 8;
|
||||
if (pos > offset)
|
||||
return 0;
|
||||
|
||||
field_type = check_typedef (TYPE_FIELD_TYPE (arg_type, i));
|
||||
|
||||
/* If this field is entirely before the requested offset, go
|
||||
on to the next one. */
|
||||
if (pos + TYPE_LENGTH (field_type) <= offset)
|
||||
continue;
|
||||
|
||||
/* If this is our special aligned double, we can stop. */
|
||||
if (TYPE_CODE (field_type) == TYPE_CODE_FLT
|
||||
&& TYPE_LENGTH (field_type) == MIPS64_REGSIZE)
|
||||
return 1;
|
||||
|
||||
/* This field starts at or before the requested offset, and
|
||||
overlaps it. If it is a structure, recurse inwards. */
|
||||
return mips_n32n64_fp_arg_chunk_p (field_type, offset - pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||
struct regcache *regcache, CORE_ADDR bp_addr,
|
||||
@ -2855,23 +2908,22 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||
val = value_contents (arg);
|
||||
|
||||
if (fp_register_arg_p (typecode, arg_type)
|
||||
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
|
||||
&& argreg <= MIPS_LAST_ARG_REGNUM)
|
||||
{
|
||||
/* This is a floating point value that fits entirely
|
||||
in a single register. */
|
||||
/* On 32 bit ABI's the float_argreg is further adjusted
|
||||
above to ensure that it is even register aligned. */
|
||||
LONGEST regval = extract_unsigned_integer (val, len);
|
||||
if (mips_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
|
||||
float_argreg, phex (regval, len));
|
||||
regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
|
||||
regcache_cooked_write_unsigned (regcache, float_argreg, regval);
|
||||
|
||||
if (mips_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
|
||||
argreg, phex (regval, len));
|
||||
regcache_cooked_write_unsigned (regcache, argreg, regval);
|
||||
argreg += 1;
|
||||
float_argreg++;
|
||||
argreg++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2896,10 +2948,12 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||
fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
|
||||
partial_len);
|
||||
|
||||
if (fp_register_arg_p (typecode, arg_type))
|
||||
gdb_assert (argreg > MIPS_LAST_ARG_REGNUM);
|
||||
|
||||
/* Write this portion of the argument to the stack. */
|
||||
if (argreg > MIPS_LAST_ARG_REGNUM
|
||||
|| odd_sized_struct
|
||||
|| fp_register_arg_p (typecode, arg_type))
|
||||
|| odd_sized_struct)
|
||||
{
|
||||
/* Should shorter than int integer values be
|
||||
promoted to int before being stored? */
|
||||
@ -2940,12 +2994,10 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||
}
|
||||
|
||||
/* Note!!! This is NOT an else clause. Odd sized
|
||||
structs may go thru BOTH paths. Floating point
|
||||
arguments will not. */
|
||||
structs may go thru BOTH paths. */
|
||||
/* Write this portion of the argument to a general
|
||||
purpose register. */
|
||||
if (argreg <= MIPS_LAST_ARG_REGNUM
|
||||
&& !fp_register_arg_p (typecode, arg_type))
|
||||
if (argreg <= MIPS_LAST_ARG_REGNUM)
|
||||
{
|
||||
LONGEST regval =
|
||||
extract_unsigned_integer (val, partial_len);
|
||||
@ -2971,6 +3023,19 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||
argreg,
|
||||
phex (regval, MIPS64_REGSIZE));
|
||||
regcache_cooked_write_unsigned (regcache, argreg, regval);
|
||||
|
||||
if (mips_n32n64_fp_arg_chunk_p (arg_type,
|
||||
TYPE_LENGTH (arg_type) - len))
|
||||
{
|
||||
if (mips_debug)
|
||||
fprintf_filtered (gdb_stdlog, " - fpreg=%d val=%s",
|
||||
float_argreg,
|
||||
phex (regval, MIPS64_REGSIZE));
|
||||
regcache_cooked_write_unsigned (regcache, float_argreg,
|
||||
regval);
|
||||
}
|
||||
|
||||
float_argreg++;
|
||||
argreg++;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2007-08-22 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* gdb.base/callfuncs.exp (do_function_calls): Use t_double_int
|
||||
and t_int_double.
|
||||
* gdb.base/callfuncs.c (t_double_int, t_int_double): New.
|
||||
|
||||
2007-08-17 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.base/step-line.c: Switch license to GPL version 3, and
|
||||
|
@ -334,6 +334,29 @@ char char_array_arg1[], char_array_arg2[];
|
||||
!strcmp (char_array_arg2, char_array_val2));
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int t_double_int (double double_arg1, int int_arg2)
|
||||
#else
|
||||
int t_double_int (double_arg1, int_arg2)
|
||||
double double_arg1;
|
||||
int int_arg2;
|
||||
#endif
|
||||
{
|
||||
return ((double_arg1 - int_arg2) < DELTA
|
||||
&& (double_arg1 - int_arg2) > -DELTA);
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int t_int_double (int int_arg1, double double_arg2)
|
||||
#else
|
||||
int t_int_double (int_arg1, double_arg2)
|
||||
int int_arg1;
|
||||
double double_arg2;
|
||||
#endif
|
||||
{
|
||||
return ((int_arg1 - double_arg2) < DELTA
|
||||
&& (int_arg1 - double_arg2) > -DELTA);
|
||||
}
|
||||
|
||||
/* This used to simply compare the function pointer arguments with
|
||||
known values for func_val1 and func_val2. Doing so is valid ANSI
|
||||
|
@ -163,6 +163,11 @@ proc do_function_calls {} {
|
||||
gdb_test "p t_double_values(double_val1,double_val2)" " = 1"
|
||||
gdb_test "p t_double_values(45.654,double_val2)" " = 1"
|
||||
gdb_test "p t_double_values(double_val1,-67.66)" " = 1"
|
||||
|
||||
gdb_test "p t_double_int(99.0, 1)" " = 0"
|
||||
gdb_test "p t_double_int(99.0, 99)" " = 1"
|
||||
gdb_test "p t_int_double(99, 1.0)" " = 0"
|
||||
gdb_test "p t_int_double(99, 99.0)" " = 1"
|
||||
}
|
||||
|
||||
gdb_test "p t_string_values(string_val2,string_val1)" " = 0"
|
||||
|
Loading…
Reference in New Issue
Block a user