===================================================================
@@ -383,6 +383,11 @@ v:const struct floatformat **:double_for
v:int:long_double_bit:::8 * sizeof (long double):8*TARGET_CHAR_BIT::0
v:const struct floatformat **:long_double_format:::::floatformats_ieee_double::pformat (gdbarch->long_double_format)
+# Returns the floating-point format to be used for values of length LENGTH.
+# NAME, if non-NULL, is the type name, which may be used to distinguish
+# different target formats of the same length.
+m:const struct floatformat **:floatformat_for_type:const char *name, int length:name, length:0:default_floatformat_for_type::0
+
# For most targets, a pointer on the target and its representation as an
# address in GDB have the same size and "look the same". For such a
# target, you need only set gdbarch_ptr_bit and gdbarch_addr_bit
===================================================================
@@ -187,6 +187,14 @@ extern void set_gdbarch_long_double_bit
extern const struct floatformat ** gdbarch_long_double_format (struct gdbarch *gdbarch);
extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struct floatformat ** long_double_format);
+/* Returns the floating-point format to be used for values of length LENGTH.
+ NAME, if non-NULL, is the type name, which may be used to distinguish
+ different target formats of the same length. */
+
+typedef const struct floatformat ** (gdbarch_floatformat_for_type_ftype) (struct gdbarch *gdbarch, const char *name, int length);
+extern const struct floatformat ** gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, int length);
+extern void set_gdbarch_floatformat_for_type (struct gdbarch *gdbarch, gdbarch_floatformat_for_type_ftype *floatformat_for_type);
+
/* For most targets, a pointer on the target and its representation as an
address in GDB have the same size and "look the same". For such a
target, you need only set gdbarch_ptr_bit and gdbarch_addr_bit
===================================================================
@@ -176,6 +176,7 @@ struct gdbarch
const struct floatformat ** double_format;
int long_double_bit;
const struct floatformat ** long_double_format;
+ gdbarch_floatformat_for_type_ftype *floatformat_for_type;
int ptr_bit;
int addr_bit;
int dwarf2_addr_size;
@@ -376,6 +377,7 @@ gdbarch_alloc (const struct gdbarch_info
gdbarch->float_bit = 4*TARGET_CHAR_BIT;
gdbarch->double_bit = 8*TARGET_CHAR_BIT;
gdbarch->long_double_bit = 8*TARGET_CHAR_BIT;
+ gdbarch->floatformat_for_type = default_floatformat_for_type;
gdbarch->ptr_bit = gdbarch->int_bit;
gdbarch->char_signed = -1;
gdbarch->virtual_frame_pointer = legacy_virtual_frame_pointer;
@@ -522,6 +524,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of long_double_bit, invalid_p == 0 */
if (gdbarch->long_double_format == 0)
gdbarch->long_double_format = floatformats_ieee_double;
+ /* Skip verify of floatformat_for_type, invalid_p == 0 */
/* Skip verify of ptr_bit, invalid_p == 0 */
if (gdbarch->addr_bit == 0)
gdbarch->addr_bit = gdbarch_ptr_bit (gdbarch);
@@ -973,6 +976,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"gdbarch_dump: float_format = %s\n",
pformat (gdbarch->float_format));
fprintf_unfiltered (file,
+ "gdbarch_dump: floatformat_for_type = <%s>\n",
+ host_address_to_string (gdbarch->floatformat_for_type));
+ fprintf_unfiltered (file,
"gdbarch_dump: fp0_regnum = %s\n",
plongest (gdbarch->fp0_regnum));
fprintf_unfiltered (file,
@@ -1729,6 +1735,23 @@ set_gdbarch_long_double_format (struct g
gdbarch->long_double_format = long_double_format;
}
+const struct floatformat **
+gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, int length)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->floatformat_for_type != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_floatformat_for_type called\n");
+ return gdbarch->floatformat_for_type (gdbarch, name, length);
+}
+
+void
+set_gdbarch_floatformat_for_type (struct gdbarch *gdbarch,
+ gdbarch_floatformat_for_type_ftype floatformat_for_type)
+{
+ gdbarch->floatformat_for_type = floatformat_for_type;
+}
+
int
gdbarch_ptr_bit (struct gdbarch *gdbarch)
{
===================================================================
@@ -95,6 +95,11 @@ int cannot_register_not (struct gdbarch
extern gdbarch_virtual_frame_pointer_ftype legacy_virtual_frame_pointer;
+/* Default implementation of gdbarch_floatformat_for_type. */
+extern const struct floatformat **
+ default_floatformat_for_type (struct gdbarch *gdbarch,
+ const char *name, int len);
+
extern CORE_ADDR generic_skip_trampoline_code (struct frame_info *frame,
CORE_ADDR pc);
===================================================================
@@ -241,6 +241,34 @@ legacy_virtual_frame_pointer (struct gdb
*frame_offset = 0;
}
+/* Return a floating-point format for a floating-point variable of
+ length LEN in bits. If non-NULL, NAME is the name of its type.
+ If no suitable type is found, return NULL. */
+
+const struct floatformat **
+default_floatformat_for_type (struct gdbarch *gdbarch,
+ const char *name, int len)
+{
+ const struct floatformat **format = NULL;
+
+ if (len == gdbarch_half_bit (gdbarch))
+ format = gdbarch_half_format (gdbarch);
+ else if (len == gdbarch_float_bit (gdbarch))
+ format = gdbarch_float_format (gdbarch);
+ else if (len == gdbarch_double_bit (gdbarch))
+ format = gdbarch_double_format (gdbarch);
+ else if (len == gdbarch_long_double_bit (gdbarch))
+ format = gdbarch_long_double_format (gdbarch);
+ /* On i386 the 'long double' type takes 96 bits,
+ while the real number of used bits is only 80,
+ both in processor and in memory.
+ The code below accepts the real bit size. */
+ else if (gdbarch_long_double_format (gdbarch) != NULL
+ && len == gdbarch_long_double_format (gdbarch)[0]->totalsize)
+ format = gdbarch_long_double_format (gdbarch);
+
+ return format;
+}
int
generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
===================================================================
@@ -770,52 +770,8 @@ floatformat_from_doublest (const struct
}
-/* Return a floating-point format for a floating-point variable of
- length LEN. If no suitable floating-point format is found, an
- error is thrown.
-
- We need this functionality since information about the
- floating-point format of a type is not always available to GDB; the
- debug information typically only tells us the size of a
- floating-point type.
-
- FIXME: kettenis/2001-10-28: In many places, particularly in
- target-dependent code, the format of floating-point types is known,
- but not passed on by GDB. This should be fixed. */
-
-static const struct floatformat *
-floatformat_from_length (struct gdbarch *gdbarch, int len)
-{
- const struct floatformat *format;
-
- if (len * TARGET_CHAR_BIT == gdbarch_half_bit (gdbarch))
- format = gdbarch_half_format (gdbarch)
- [gdbarch_byte_order (gdbarch)];
- else if (len * TARGET_CHAR_BIT == gdbarch_float_bit (gdbarch))
- format = gdbarch_float_format (gdbarch)
- [gdbarch_byte_order (gdbarch)];
- else if (len * TARGET_CHAR_BIT == gdbarch_double_bit (gdbarch))
- format = gdbarch_double_format (gdbarch)
- [gdbarch_byte_order (gdbarch)];
- else if (len * TARGET_CHAR_BIT == gdbarch_long_double_bit (gdbarch))
- format = gdbarch_long_double_format (gdbarch)
- [gdbarch_byte_order (gdbarch)];
- /* On i386 the 'long double' type takes 96 bits,
- while the real number of used bits is only 80,
- both in processor and in memory.
- The code below accepts the real bit size. */
- else if ((gdbarch_long_double_format (gdbarch) != NULL)
- && (len * TARGET_CHAR_BIT
- == gdbarch_long_double_format (gdbarch)[0]->totalsize))
- format = gdbarch_long_double_format (gdbarch)
- [gdbarch_byte_order (gdbarch)];
- else
- format = NULL;
- if (format == NULL)
- error (_("Unrecognized %d-bit floating-point type."),
- len * TARGET_CHAR_BIT);
- return format;
-}
+/* Return the floating-point format for a floating-point variable of
+ type TYPE. */
const struct floatformat *
floatformat_from_type (const struct type *type)
@@ -824,11 +780,8 @@ floatformat_from_type (const struct type
const struct floatformat *fmt;
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
- if (TYPE_FLOATFORMAT (type) != NULL)
- fmt = TYPE_FLOATFORMAT (type)[gdbarch_byte_order (gdbarch)];
- else
- fmt = floatformat_from_length (gdbarch, TYPE_LENGTH (type));
-
+ gdb_assert (TYPE_FLOATFORMAT (type));
+ fmt = TYPE_FLOATFORMAT (type)[gdbarch_byte_order (gdbarch)];
gdb_assert (TYPE_LENGTH (type) >= floatformat_totalsize_bytes (fmt));
return fmt;
}
===================================================================
@@ -2712,21 +2712,16 @@ set_type_code (struct type *type, enum t
static int
verify_floatformat (int bit, const struct floatformat **floatformats)
{
+ gdb_assert (floatformats != NULL);
+ gdb_assert (floatformats[0] != NULL && floatformats[1] != NULL);
+
if (bit == -1)
- {
- gdb_assert (floatformats != NULL);
- gdb_assert (floatformats[0] != NULL && floatformats[1] != NULL);
- bit = floatformats[0]->totalsize;
- }
+ bit = floatformats[0]->totalsize;
gdb_assert (bit >= 0);
- if (floatformats != NULL)
- {
- size_t len = bit / TARGET_CHAR_BIT;
-
- gdb_assert (len >= floatformat_totalsize_bytes (floatformats[0]));
- gdb_assert (len >= floatformat_totalsize_bytes (floatformats[1]));
- }
+ size_t len = bit / TARGET_CHAR_BIT;
+ gdb_assert (len >= floatformat_totalsize_bytes (floatformats[0]));
+ gdb_assert (len >= floatformat_totalsize_bytes (floatformats[1]));
return bit;
}
===================================================================
@@ -14757,6 +14757,27 @@ read_typedef (struct die_info *die, stru
return this_type;
}
+/* Allocate a floating-point type of size BITS and name NAME. Pass NAME_HINT
+ (which may be different from NAME) to the architecture back-end to allow
+ it to guess the correct format if necessary. */
+
+static struct type *
+dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
+ const char *name_hint)
+{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const struct floatformat **format;
+ struct type *type;
+
+ format = gdbarch_floatformat_for_type (gdbarch, name_hint, bits);
+ if (format)
+ type = init_float_type (objfile, bits, name, format);
+ else
+ type = init_type (objfile, TYPE_CODE_ERROR, bits / TARGET_CHAR_BIT, name);
+
+ return type;
+}
+
/* Find a representation of a given base type and install
it in the TYPE field of the die. */
@@ -14797,14 +14818,14 @@ read_base_type (struct die_info *die, st
type = init_boolean_type (objfile, bits, 1, name);
break;
case DW_ATE_complex_float:
- type = init_float_type (objfile, bits / 2, NULL, NULL);
+ type = dwarf2_init_float_type (objfile, bits / 2, NULL, name);
type = init_complex_type (objfile, name, type);
break;
case DW_ATE_decimal_float:
type = init_decfloat_type (objfile, bits, name);
break;
case DW_ATE_float:
- type = init_float_type (objfile, bits, name, NULL);
+ type = dwarf2_init_float_type (objfile, bits, name, name);
break;
case DW_ATE_signed:
type = init_integer_type (objfile, bits, 0, name);
===================================================================
@@ -353,6 +353,24 @@ dbx_alloc_type (int typenums[2], struct
return (*type_addr);
}
+/* Allocate a floating-point type of size BITS. */
+
+static struct type *
+dbx_init_float_type (struct objfile *objfile, int bits)
+{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const struct floatformat **format;
+ struct type *type;
+
+ format = gdbarch_floatformat_for_type (gdbarch, NULL, bits);
+ if (format)
+ type = init_float_type (objfile, bits, NULL, format);
+ else
+ type = init_type (objfile, TYPE_CODE_ERROR, bits / TARGET_CHAR_BIT, NULL);
+
+ return type;
+}
+
/* for all the stabs in a given stab vector, build appropriate types
and fix their symbols in given symbol vector. */
@@ -3847,11 +3865,11 @@ read_sun_floating_type (char **pp, int t
if (details == NF_COMPLEX || details == NF_COMPLEX16
|| details == NF_COMPLEX32)
{
- rettype = init_float_type (objfile, nbits / 2, NULL, NULL);
+ rettype = dbx_init_float_type (objfile, nbits / 2);
return init_complex_type (objfile, NULL, rettype);
}
- return init_float_type (objfile, nbits, NULL, NULL);
+ return dbx_init_float_type (objfile, nbits);
}
/* Read a number from the string pointed to by *PP.
@@ -4138,7 +4156,7 @@ read_range_type (char **pp, int typenums
if (n3 == 0 && n2 > 0)
{
struct type *float_type
- = init_float_type (objfile, n2 * TARGET_CHAR_BIT, NULL, NULL);
+ = dbx_init_float_type (objfile, n2 * TARGET_CHAR_BIT);
if (self_subrange)
return init_complex_type (objfile, NULL, float_type);