From ac27f131b2fc0c5e0872c5855c599974b7416d07 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 26 Mar 2000 21:21:50 +0000 Subject: [PATCH] 2000-03-26 Mark Kettenis 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. --- gdb/ChangeLog | 27 +++++++++++++++++++ gdb/config/i386/tm-i386.h | 52 ++++++++++++++++++++++--------------- gdb/config/i386/tm-i386mk.h | 14 +++++++++- gdb/config/i386/tm-linux.h | 37 +++----------------------- gdb/i386-tdep.c | 26 +++++++++++++++++++ gdb/i387-tdep.c | 50 +---------------------------------- 6 files changed, 102 insertions(+), 104 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 79752b4bd01..de355b85143 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2000-03-26 Mark Kettenis + + 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 * maint.c: Re-indent. diff --git a/gdb/config/i386/tm-i386.h b/gdb/config/i386/tm-i386.h index 6e3207ef115..f241884de0b 100644 --- a/gdb/config/i386/tm-i386.h +++ b/gdb/config/i386/tm-i386.h @@ -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. */ diff --git a/gdb/config/i386/tm-i386mk.h b/gdb/config/i386/tm-i386mk.h index cb18e3c1875..de66a691966 100644 --- a/gdb/config/i386/tm-i386mk.h +++ b/gdb/config/i386/tm-i386mk.h @@ -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 diff --git a/gdb/config/i386/tm-linux.h b/gdb/config/i386/tm-linux.h index 2e86a5c2dbf..d6a4616620c 100644 --- a/gdb/config/i386/tm-linux.h +++ b/gdb/config/i386/tm-linux.h @@ -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 */ diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 421a7a094b5..39990db0688 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -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. */ diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index 0bb16319abe..20e446d2ff4 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -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 */ -- 2.30.2