2000-03-26 Mark Kettenis <kettenis@gnu.org>

Provide `long double' support for most i386 targets.
	* config/i386/tm-i386.h (TARGET_LONG_DOUBLE_FORMAT): Define as
	&floatformat_i387_ext.
	(TARGET_LONG_DOUBLE_BITS): Define as 96.
	(REGISTER_VIRTUAL_TYPE): Change type for FPU registers to
	`builtin_type_long_double'.
	(REGISTER_CONVERT_TO_VIRTUAL): Call
	i386_register_convert_to_virtual.
	(REGISTER_CONVERT_TO_RAW): Call i386_register_convert_to_raw.
	(i387_to_double, double_to_i387): Remove prototypes.
	(i386_extract_return_value): Change prototype to match definition
	in i386-tdep.c.
	* config/i386/tm-i386mk.h (TARGET_LONG_DOUBLE_FORMAT): #undef.
	(TARGET_LONG_DOUBLE_BITS): #undef.
	* config/i386/tm-linux.h (TARGET_LONG_DOUBLE_BIT): Remove.
	[HAVE_LONG_DOUBLE && HOST_I386] (LD_I387): Remove.
	(i387_extract_floating, i387_store_floating): Remove prototypes.
	(TARGET_EXTRACT_FLOATING, TARGET_STORE_FLOATING): Remove.
	(REGISTER_CONVERT_TO_VIRTUAL, REGOISTER_CONVERT_TO_RAW): Remove.
	(REGISTER_VIRTUAL_TYPE): Remove.
	* i386-tdep.c (i386_register_convert_to_virtual): New function.
	(i386_register_convert_to_raw): New function.
	* i387-tdep.c [LD_I387] (i387_extract_floating): Remove.
	(i387_store_floating): Remove.
This commit is contained in:
Mark Kettenis 2000-03-26 21:21:50 +00:00
parent 9f10757c40
commit ac27f131b2
6 changed files with 102 additions and 104 deletions

View File

@ -1,3 +1,30 @@
2000-03-26 Mark Kettenis <kettenis@gnu.org>
Provide `long double' support for most i386 targets.
* config/i386/tm-i386.h (TARGET_LONG_DOUBLE_FORMAT): Define as
&floatformat_i387_ext.
(TARGET_LONG_DOUBLE_BITS): Define as 96.
(REGISTER_VIRTUAL_TYPE): Change type for FPU registers to
`builtin_type_long_double'.
(REGISTER_CONVERT_TO_VIRTUAL): Call
i386_register_convert_to_virtual.
(REGISTER_CONVERT_TO_RAW): Call i386_register_convert_to_raw.
(i387_to_double, double_to_i387): Remove prototypes.
(i386_extract_return_value): Change prototype to match definition
in i386-tdep.c.
* config/i386/tm-i386mk.h (TARGET_LONG_DOUBLE_FORMAT): #undef.
(TARGET_LONG_DOUBLE_BITS): #undef.
* config/i386/tm-linux.h (TARGET_LONG_DOUBLE_BIT): Remove.
[HAVE_LONG_DOUBLE && HOST_I386] (LD_I387): Remove.
(i387_extract_floating, i387_store_floating): Remove prototypes.
(TARGET_EXTRACT_FLOATING, TARGET_STORE_FLOATING): Remove.
(REGISTER_CONVERT_TO_VIRTUAL, REGOISTER_CONVERT_TO_RAW): Remove.
(REGISTER_VIRTUAL_TYPE): Remove.
* i386-tdep.c (i386_register_convert_to_virtual): New function.
(i386_register_convert_to_raw): New function.
* i387-tdep.c [LD_I387] (i387_extract_floating): Remove.
(i387_store_floating): Remove.
Sat Mar 25 18:55:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
* maint.c: Re-indent.

View File

@ -1,5 +1,5 @@
/* Macro definitions for GDB on an Intel i[345]86.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
This file is part of GDB.
@ -28,6 +28,19 @@ struct type;
#define TARGET_BYTE_ORDER LITTLE_ENDIAN
/* The format used for `long double' on almost all i386 targets is the
i387 extended floating-point format. In fact, of all targets in the
GCC 2.95 tree, only OSF/1 does it different, and insists on having
a `long double' that's not `long' at all. */
#define TARGET_LONG_DOUBLE_FORMAT &floatformat_i387_ext
/* Although the i386 extended floating-point has only 80 significant
bits, a `long double' actually takes up 96, probably to enforce
alignment. */
#define TARGET_LONG_DOUBLE_BITS 96
/* Used for example in valprint.c:print_floating() to enable checking
for NaN's */
@ -229,7 +242,7 @@ extern int i386_register_virtual_size[];
#define REGISTER_VIRTUAL_TYPE(N) \
(((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM) \
? lookup_pointer_type (builtin_type_void) \
: IS_FP_REGNUM(N) ? builtin_type_double \
: IS_FP_REGNUM(N) ? builtin_type_long_double \
: IS_SSE_REGNUM(N) ? builtin_type_v4sf \
: builtin_type_int)
@ -240,24 +253,21 @@ extern int i386_register_virtual_size[];
counterexample, this is still sloppy. */
#define REGISTER_CONVERTIBLE(n) (IS_FP_REGNUM (n))
/* Convert data from raw format for register REGNUM in buffer FROM
to virtual format with type TYPE in buffer TO. */
extern void i387_to_double (char *, char *);
/* Convert data from raw format for register REGNUM in buffer FROM to
virtual format with type TYPE in buffer TO. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
{ \
double val; \
i387_to_double ((FROM), (char *)&val); \
store_floating ((TO), TYPE_LENGTH (TYPE), val); \
}
#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) \
i386_register_convert_to_virtual ((regnum), (type), (from), (to));
extern void i386_register_convert_to_virtual (int regnum, struct type *type,
char *from, char *to);
extern void double_to_i387 (char *, char *);
/* Convert data from virtual format with type TYPE in buffer FROM to
raw format for register REGNUM in buffer TO. */
#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
{ \
double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
double_to_i387((char *)&val, (TO)); \
}
#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) \
i386_register_convert_to_raw ((type), (regnum), (from), (to));
extern void i386_register_convert_to_raw (struct type *type, int regnum,
char *from, char *to);
/* Print out the i387 floating point state. */
#ifdef HAVE_I387_REGS
@ -279,10 +289,10 @@ extern void i387_float_info (void);
a function return value of type TYPE, and copy that, in virtual format,
into VALBUF. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
i386_extract_return_value ((TYPE),(REGBUF),(VALBUF))
extern void i386_extract_return_value PARAMS ((struct type *, char[], char *));
#define EXTRACT_RETURN_VALUE(type, regbuf, valbuf) \
i386_extract_return_value ((type), (regbuf), (valbuf))
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. */

View File

@ -1,5 +1,5 @@
/* Macro definitions for i386, Mach 3.0, OSF 1/MK
Copyright (C) 1992 Free Software Foundation, Inc.
Copyright (C) 1992, 2000 Free Software Foundation, Inc.
This file is part of GDB.
@ -24,3 +24,15 @@
#define MK67 1
#include "i386/tm-i386m3.h"
/* FIMXE: kettenis/2000-03-26: On OSF 1, `long double' is equivalent
to `double'. However, I'm not sure what is the consequence of:
#define TARGET_LONG_DOUBLE_FORMAT TARGET_DOUBLE_FORMAT
#define TARGET_LONG_DOUBLE_BITS TARGET_DOUBLE_BITS
So I'll go with the current status quo instead. It looks like this
target won't compile anyway. Perhaps it should be obsoleted? */
#undef TARGET_LONG_DOUBLE_FORMAT
#undef TARGET_LONG_DOUBLE_BITS

View File

@ -30,20 +30,15 @@
#include "i386/tm-i386.h"
#include "tm-linux.h"
/* This should probably move to tm-i386.h. */
#define TARGET_LONG_DOUBLE_BIT 80
/* FIXME: kettenis/2000-03-26: We should get rid of this last piece of
Linux-specific `long double'-support code, probably by adding code
to valprint.c:print_floating() to recognize various extended
floating-point formats. */
#if defined(HAVE_LONG_DOUBLE) && defined(HOST_I386)
/* The host and target are i386 machines and the compiler supports
long doubles. Long doubles on the host therefore have the same
layout as a 387 FPU stack register. */
#define LD_I387
extern int i387_extract_floating (PTR addr, int len, long double *dretptr);
extern int i387_store_floating (PTR addr, int len, long double val);
#define TARGET_EXTRACT_FLOATING i387_extract_floating
#define TARGET_STORE_FLOATING i387_store_floating
#define TARGET_ANALYZE_FLOATING \
do \
@ -61,30 +56,6 @@ extern int i387_store_floating (PTR addr, int len, long double val);
} \
while (0)
#undef REGISTER_CONVERT_TO_VIRTUAL
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
{ \
long double val = *((long double *)FROM); \
store_floating ((TO), TYPE_LENGTH (TYPE), val); \
}
#undef REGISTER_CONVERT_TO_RAW
#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
{ \
long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
*((long double *)TO) = val; \
}
/* Return the GDB type object for the "standard" data type
of data in register N. */
#undef REGISTER_VIRTUAL_TYPE
#define REGISTER_VIRTUAL_TYPE(N) \
(((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM) \
? lookup_pointer_type (builtin_type_void) \
: IS_FP_REGNUM(N) ? builtin_type_long_double \
: IS_SSE_REGNUM(N) ? builtin_type_v4sf \
: builtin_type_int)
#endif
/* The following works around a problem with /usr/include/sys/procfs.h */

View File

@ -761,6 +761,32 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
}
}
/* 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
bytes appended that aren't used. We set these to zero. */
void
i386_register_convert_to_virtual (int regnum, struct type *type,
char *from, char *to)
{
/* Copy straight over, but take care of the padding. */
memcpy (to, from, FPU_REG_RAW_SIZE);
memset (to + FPU_REG_RAW_SIZE, 0, TYPE_LENGTH (type) - FPU_REG_RAW_SIZE);
}
/* Convert data from virtual format with type TYPE in buffer FROM to
raw format for register REGNUM in buffer TO. Simply omit the two
unused bytes. */
void
i386_register_convert_to_raw (struct type *type, int regnum,
char *from, char *to)
{
memcpy (to, from, FPU_REG_RAW_SIZE);
}
#ifdef I386V4_SIGTRAMP_SAVED_PC
/* Get saved user PC for sigtramp from the pushed ucontext on the stack
for all three variants of SVR4 sigtramps. */

View File

@ -1,5 +1,5 @@
/* Intel 387 floating point stuff.
Copyright (C) 1988, 1989, 1991, 1998, 1999 Free Software Foundation, Inc.
Copyright (C) 1988, 89, 91, 98, 99, 2000 Free Software Foundation, Inc.
This file is part of GDB.
@ -387,51 +387,3 @@ i387_float_info (void)
printf_filtered ("Opcode: %s\n",
local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
}
/* FIXME: The functions on this page are used to provide `long double'
support for Linux. However, the approach does not seem to be the
right one, and we are planning to solve this in a way that should
work for all i386 targets. These functions will disappear in the
near future, so please don't use them. */
#ifdef LD_I387
int
i387_extract_floating (PTR addr, int len, DOUBLEST *dretptr)
{
if (len == TARGET_LONG_DOUBLE_BIT / 8)
{
if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
{
DOUBLEST retval;
memcpy (dretptr, addr, sizeof (retval));
}
else
floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, dretptr);
return 1;
}
else
return 0;
}
int
i387_store_floating (PTR addr, int len, DOUBLEST val)
{
if (len == TARGET_LONG_DOUBLE_BIT / 8)
{
/* This `if' may be totally stupid. I just put it in here to be
absolutely sure I'm preserving the semantics of the code I'm
frobbing, while I try to maintain portability boundaries; I
don't actually know exactly what it's doing. -JimB, May 1999 */
if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
memcpy (addr, &val, sizeof (val));
else
floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
return 1;
}
else
return 0;
}
#endif /* LD_I387 */