* i386-tdep.c (i386_extract_return_value,

i386_store_return_value): Add gdbarch argument.  Use it instead of
determining it from REGCACHE.  Remove recursive call for
structures with a single member.
(i386_use_struct_convention): Remove.
(i386_reg_struct_return_p): New function.
(i386_return_value): New function.
(i386_gdbarch_init): Set return_value, don't set
extract_return_value, store_return_value and
use_struct_convention.
* x86-64-tdep.c (x86_64_init_abi): Set return_value to NULL.
This commit is contained in:
Mark Kettenis 2003-11-20 22:37:50 +00:00
parent 0d78efdfab
commit c5e656c1c7
3 changed files with 78 additions and 38 deletions

View File

@ -1,3 +1,17 @@
2003-11-20 Mark Kettenis <kettenis@gnu.org>
* i386-tdep.c (i386_extract_return_value,
i386_store_return_value): Add gdbarch argument. Use it instead of
determining it from REGCACHE. Remove recursive call for
structures with a single member.
(i386_use_struct_convention): Remove.
(i386_reg_struct_return_p): New function.
(i386_return_value): New function.
(i386_gdbarch_init): Set return_value, don't set
extract_return_value, store_return_value and
use_struct_convention.
* x86-64-tdep.c (x86_64_init_abi): Set return_value to NULL.
2003-11-20 Jim Blandy <jimb@redhat.com>
* osabi.c (_initialize_gdb_osabi): Don't return before registering

View File

@ -1151,25 +1151,17 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
#define LOW_RETURN_REGNUM I386_EAX_REGNUM /* %eax */
#define HIGH_RETURN_REGNUM I386_EDX_REGNUM /* %edx */
/* Extract from an array REGBUF containing the (raw) register state, a
function return value of TYPE, and copy that, in virtual format,
into VALBUF. */
/* Read, for architecture GDBARCH, a function return value of TYPE
from REGCACHE, and copy that into VALBUF. */
static void
i386_extract_return_value (struct type *type, struct regcache *regcache,
void *valbuf)
i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache, void *valbuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int len = TYPE_LENGTH (type);
char buf[I386_MAX_REGISTER_SIZE];
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
&& TYPE_NFIELDS (type) == 1)
{
i386_extract_return_value (TYPE_FIELD_TYPE (type, 0), regcache, valbuf);
return;
}
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
if (tdep->st0_regnum < 0)
@ -1209,27 +1201,20 @@ i386_extract_return_value (struct type *type, struct regcache *regcache,
}
}
/* Write into the appropriate registers a function return value stored
in VALBUF of type TYPE, given in virtual format. */
/* Write, for architecture GDBARCH, a function return value of TYPE
from VALBUF into REGCACHE. */
static void
i386_store_return_value (struct type *type, struct regcache *regcache,
const void *valbuf)
i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache, const void *valbuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int len = TYPE_LENGTH (type);
/* Define I387_ST0_REGNUM such that we use the proper definitions
for the architecture. */
#define I387_ST0_REGNUM I386_ST0_REGNUM
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
&& TYPE_NFIELDS (type) == 1)
{
i386_store_return_value (TYPE_FIELD_TYPE (type, 0), regcache, valbuf);
return;
}
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
ULONGEST fstat;
@ -1314,20 +1299,62 @@ static const char *valid_conventions[] =
};
static const char *struct_convention = default_struct_convention;
/* Return non-zero if TYPE, which is assumed to be a structure or
union type, should be returned in registers for architecture
GDBARCH. */
static int
i386_use_struct_convention (int gcc_p, struct type *type)
i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
{
enum struct_return struct_return;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type);
if (struct_convention == default_struct_convention)
struct_return = gdbarch_tdep (current_gdbarch)->struct_return;
else if (struct_convention == pcc_struct_convention)
struct_return = pcc_struct_return;
else
struct_return = reg_struct_return;
gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
return generic_use_struct_convention (struct_return == reg_struct_return,
type);
if (struct_convention == pcc_struct_convention
|| (struct_convention == default_struct_convention
&& tdep->struct_return == pcc_struct_return))
return 0;
return (len == 1 || len == 2 || len == 4 || len == 8);
}
/* Determine, for architecture GDBARCH, how a return value of TYPE
should be returned. If it is supposed to be returned in registers,
and READBUF is non-zero, read the appropriate value from REGCACHE,
and copy it into READBUF. If WRITEBUF is non-zero, write the value
from WRITEBUF into REGCACHE. */
static enum return_value_convention
i386_return_value (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache, void *readbuf,
const void *writebuf)
{
enum type_code code = TYPE_CODE (type);
if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
&& !i386_reg_struct_return_p (gdbarch, type))
return RETURN_VALUE_STRUCT_CONVENTION;
/* This special case is for structures consisting of a single
`float' or `double' member. These structures are returned in
%st(0). For these structures, we call ourselves recursively,
changing TYPE into the type of the first member of the structure.
Since that should work for all structures that have only one
member, we don't bother to check the member's type here. */
if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
{
type = check_typedef (TYPE_FIELD_TYPE (type, 0));
return i386_return_value (gdbarch, type, regcache, readbuf, writebuf);
}
if (readbuf)
i386_extract_return_value (gdbarch, type, regcache, readbuf);
if (writebuf)
i386_store_return_value (gdbarch, type, regcache, writebuf);
return RETURN_VALUE_REGISTER_CONVENTION;
}
@ -1963,11 +1990,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
set_gdbarch_extract_return_value (gdbarch, i386_extract_return_value);
set_gdbarch_store_return_value (gdbarch, i386_store_return_value);
set_gdbarch_return_value (gdbarch, i386_return_value);
set_gdbarch_extract_struct_value_address (gdbarch,
i386_extract_struct_value_address);
set_gdbarch_use_struct_convention (gdbarch, i386_use_struct_convention);
set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);

View File

@ -1300,6 +1300,7 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
set_gdbarch_value_to_register (gdbarch, i387_value_to_register);
set_gdbarch_return_value (gdbarch, NULL);
set_gdbarch_extract_return_value (gdbarch, x86_64_extract_return_value);
set_gdbarch_store_return_value (gdbarch, x86_64_store_return_value);
/* Override, since this is handled by x86_64_extract_return_value. */