* i386-tdep.c: Add missing ')' in comment.

(i386_extract_return_value): Return directly after issuing the
warning and filling *VALBUF with zeroes if we cannot get at the
floating-point registers.
(i386_store_return_value): New function.
* config/i386/tm-i386.h (STORE_RETURN_VALUE): Simply call
i386_store_return_value.
Add prototype for i386_store_return_value.
This commit is contained in:
Mark Kettenis 2000-12-21 20:52:59 +00:00
parent 2866d30574
commit ef9dff19c4
3 changed files with 74 additions and 12 deletions

View file

@ -1,5 +1,14 @@
2000-12-21 Mark Kettenis <kettenis@gnu.org>
* i386-tdep.c: Add missing ')' in comment.
(i386_extract_return_value): Return directly after issuing the
warning and filling *VALBUF with zeroes if we cannot get at the
floating-point registers.
(i386_store_return_value): New function.
* config/i386/tm-i386.h (STORE_RETURN_VALUE): Simply call
i386_store_return_value.
Add prototype for i386_store_return_value.
* i386-linux-nat.c (store_fpxregs): Add code to detect support for
the PTRACE_GETFPXREGS request, and return zero if it's not.

View file

@ -296,17 +296,11 @@ extern void i387_float_info (void);
extern void i386_extract_return_value (struct type *type, char *regbuf,
char *valbuf);
/* Write into appropriate registers a function return value of type TYPE, given
in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
{ \
if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
write_register_bytes (REGISTER_BYTE (FP0_REGNUM), (VALBUF), \
TYPE_LENGTH (TYPE)); \
else \
write_register_bytes (0, (VALBUF), TYPE_LENGTH (TYPE)); \
}
/* Write into the appropriate registers a function return value stored
in VALBUF of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(type, valbuf) \
i386_store_return_value ((type), (valbuf))
extern void i386_store_return_value (struct type *type, char *valbuf);
/* Extract from an array REGBUF containing the (raw) register state the address
in which a function should return its structure value, as a CORE_ADDR (or an

View file

@ -713,7 +713,7 @@ get_longjmp_target (CORE_ADDR *pc)
/* These registers are used for returning integers (and on some
targets also for returning `struct' and `union' values when their
size and alignment match an integer type. */
size and alignment match an integer type). */
#define LOW_RETURN_REGNUM 0 /* %eax */
#define HIGH_RETURN_REGNUM 2 /* %edx */
@ -732,6 +732,7 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
warning ("Cannot find floating-point return value.");
memset (valbuf, 0, len);
return;
}
/* Floating-point return values can be found in %st(0). */
@ -774,6 +775,64 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
}
}
/* Write into the appropriate registers a function return value stored
in VALBUF of type TYPE, given in virtual format. */
void
i386_store_return_value (struct type *type, char *valbuf)
{
int len = TYPE_LENGTH (type);
if (TYPE_CODE_FLT == TYPE_CODE (type))
{
if (NUM_FREGS == 0)
{
warning ("Cannot set floating-point return value.");
return;
}
/* Floating-point return values can be found in %st(0). */
if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT
&& TARGET_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
{
/* Copy straight over. */
write_register_bytes (REGISTER_BYTE (FP0_REGNUM), valbuf,
FPU_REG_RAW_SIZE);
}
else
{
char buf[FPU_REG_RAW_SIZE];
DOUBLEST val;
/* Convert the value found in VALBUF to the extended
floating point format used by the FPU. This is probably
not exactly how it would happen on the target itself, but
it is the best we can do. */
val = extract_floating (valbuf, TYPE_LENGTH (type));
floatformat_from_doublest (&floatformat_i387_ext, &val, buf);
write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf,
FPU_REG_RAW_SIZE);
}
}
else
{
int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
if (len <= low_size)
write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM), valbuf, len);
else if (len <= (low_size + high_size))
{
write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM),
valbuf, low_size);
write_register_bytes (REGISTER_BYTE (HIGH_RETURN_REGNUM),
valbuf + low_size, len - low_size);
}
else
internal_error ("Cannot store return value of %d bytes long.", len);
}
}
/* Convert data from raw format for register REGNUM in buffer FROM to
virtual format with type TYPE in buffer TO. In principle both
formats are identical except that the virtual format has two extra