This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
PATCH ARM initial support for different floating-point models
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: gdb-patches at sources dot redhat dot com
- Cc: Richard dot Earnshaw at arm dot com
- Date: Tue, 19 Feb 2002 19:23:57 +0000
- Subject: PATCH ARM initial support for different floating-point models
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
Different ARM targets can use different conventions for passing and
returning floating point numbers. This is some initial support for that.
It fixes 6 testsuite failures on ARM/NetBSD, which uses soft-float
variants.
R.
2002-02-19 Richard Earnshaw <rearnsha@arm.com>
* arm-tdep.h (enum arm_float_model): New enum.
(struct gdbarch_tdep): Add fp_model.
* arm-tdep.c (arm_gdbarch_init): Set fp_model in tdep. Defer setting
up floating-point conversions until we know the floating-point model
in use by the inferior. Don't complain about being unable to
determine the ABI of the inferior when we don't have one.
(arm_extract_return_value): Support different floating-point models.
(arm_store_return_value): Likewise.
* armnbsd-tdep.c (arm_netbsd_aout_init_abi): Set fp_model in tdep to
ARM_FLOAT_SOFT.
(arm_netbsd_elf_init_abi): Set fp_model to ARM_FLOAT_SOFT_VFP.
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.47
diff -p -r1.47 arm-tdep.c
*** arm-tdep.c 2002/02/19 13:57:35 1.47
--- arm-tdep.c 2002/02/19 19:14:40
*************** arm_extract_return_value (struct type *t
*** 2139,2145 ****
char *valbuf)
{
if (TYPE_CODE_FLT == TYPE_CODE (type))
! convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf);
else
memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)],
TYPE_LENGTH (type));
--- 2139,2167 ----
char *valbuf)
{
if (TYPE_CODE_FLT == TYPE_CODE (type))
! {
! struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
!
! switch (tdep->fp_model)
! {
! case ARM_FLOAT_FPA:
! convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)],
! valbuf);
! break;
!
! case ARM_FLOAT_SOFT:
! case ARM_FLOAT_SOFT_VFP:
! memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)],
! TYPE_LENGTH (type));
! break;
!
! default:
! internal_error
! (__FILE__, __LINE__,
! "arm_extract_return_value: Floating point model not supported");
! break;
! }
! }
else
memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)],
TYPE_LENGTH (type));
*************** arm_store_return_value (struct type *typ
*** 2256,2270 ****
{
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
char buf[MAX_REGISTER_RAW_SIZE];
! convert_to_extended (valbuf, buf);
! /* XXX Is this correct for soft-float? */
! write_register_bytes (REGISTER_BYTE (ARM_F0_REGNUM), buf,
! MAX_REGISTER_RAW_SIZE);
}
else
! write_register_bytes (0, valbuf, TYPE_LENGTH (type));
}
/* Store the address of the place in which to copy the structure the
--- 2278,2309 ----
{
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
char buf[MAX_REGISTER_RAW_SIZE];
! switch (tdep->fp_model)
! {
! case ARM_FLOAT_FPA:
!
! convert_to_extended (valbuf, buf);
! write_register_bytes (REGISTER_BYTE (ARM_F0_REGNUM), buf,
! MAX_REGISTER_RAW_SIZE);
! break;
!
! case ARM_FLOAT_SOFT:
! case ARM_FLOAT_SOFT_VFP:
! write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type));
! break;
!
! default:
! internal_error
! (__FILE__, __LINE__,
! "arm_store_return_value: Floating point model not supported");
! break;
! }
}
else
! write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type));
}
/* Store the address of the place in which to copy the structure the
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2762,2768 ****
tdep->abi_name = "<invalid>";
}
! /* Breakpoints and floating point sizes and format. */
switch (info.byte_order)
{
case BFD_ENDIAN_BIG:
--- 2801,2810 ----
tdep->abi_name = "<invalid>";
}
! /* This is the way it has always defaulted. */
! tdep->fp_model = ARM_FLOAT_FPA;
!
! /* Breakpoints. */
switch (info.byte_order)
{
case BFD_ENDIAN_BIG:
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2771,2780 ****
tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint;
tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint);
- set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
- set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
- set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
-
break;
case BFD_ENDIAN_LITTLE:
--- 2813,2818 ----
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2783,2794 ****
tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint;
tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint);
- set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
- set_gdbarch_double_format (gdbarch,
- &floatformat_ieee_double_littlebyte_bigword);
- set_gdbarch_long_double_format (gdbarch,
- &floatformat_ieee_double_littlebyte_bigword);
-
break;
default:
--- 2821,2826 ----
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2905,2913 ****
/* Hook in the ABI-specific overrides, if they have been registered. */
if (arm_abi == ARM_ABI_UNKNOWN)
{
! fprintf_filtered
! (gdb_stderr, "GDB doesn't recognize the ABI of the inferior. "
! "Attempting to continue with the default ARM settings");
}
else
{
--- 2937,2948 ----
/* Hook in the ABI-specific overrides, if they have been registered. */
if (arm_abi == ARM_ABI_UNKNOWN)
{
! /* Don't complain about not knowing the ABI variant if we don't
! have an inferior. */
! if (info.abfd)
! fprintf_filtered
! (gdb_stderr, "GDB doesn't recognize the ABI of the inferior. "
! "Attempting to continue with the default ARM settings");
}
else
{
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2938,2943 ****
--- 2973,3011 ----
if (tdep->jb_pc >= 0)
set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
+
+ /* Floating point sizes and format. */
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+
+ break;
+
+ case BFD_ENDIAN_LITTLE:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+ if (tdep->fp_model == ARM_FLOAT_VFP
+ || tdep->fp_model == ARM_FLOAT_SOFT_VFP)
+ {
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
+ set_gdbarch_long_double_format (gdbarch,
+ &floatformat_ieee_double_little);
+ }
+ else
+ {
+ set_gdbarch_double_format
+ (gdbarch, &floatformat_ieee_double_littlebyte_bigword);
+ set_gdbarch_long_double_format
+ (gdbarch, &floatformat_ieee_double_littlebyte_bigword);
+ }
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ "arm_gdbarch_init: bad byte order for float format");
+ }
/* We can't use SIZEOF_FRAME_SAVED_REGS here, since that still
references the old architecture vector, not the one we are
Index: arm-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.h,v
retrieving revision 1.5
diff -p -r1.5 arm-tdep.h
*** arm-tdep.h 2002/02/18 13:35:29 1.5
--- arm-tdep.h 2002/02/19 19:14:40
*************** enum arm_abi
*** 116,126 ****
--- 116,144 ----
ARM_ABI_INVALID /* Keep this last. */
};
+ /* Type of floating-point code in use by inferior. There are really 3 models
+ that are traditionally supported (plus the endianness issue), but gcc can
+ only generate 2 of those. The third is APCS_FLOAT, where arguments to
+ functions are passed in floating-point registers.
+
+ In addition to the traditional models, VFP adds two more. */
+
+ enum arm_float_model
+ {
+ ARM_FLOAT_SOFT,
+ ARM_FLOAT_FPA,
+ ARM_FLOAT_SOFT_VFP,
+ ARM_FLOAT_VFP
+ };
+
/* Target-dependent structure in gdbarch. */
struct gdbarch_tdep
{
enum arm_abi arm_abi; /* OS/ABI of inferior. */
const char *abi_name; /* Name of the above. */
+
+ enum arm_float_model fp_model; /* Floating point calling conventions. */
+
CORE_ADDR lowest_pc; /* Lowest address at which instructions
will appear. */
Index: armnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/armnbsd-tdep.c,v
retrieving revision 1.3
diff -p -r1.3 armnbsd-tdep.c
*** armnbsd-tdep.c 2002/02/19 11:46:14 1.3
--- armnbsd-tdep.c 2002/02/19 19:14:40
*************** static void
*** 57,73 ****
--- 57,80 ----
arm_netbsd_aout_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
arm_netbsd_init_abi_common (info, gdbarch);
set_gdbarch_in_solib_call_trampoline
(gdbarch, arm_netbsd_aout_in_solib_call_trampoline);
+ tdep->fp_model = ARM_FLOAT_SOFT;
}
static void
arm_netbsd_elf_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
arm_netbsd_init_abi_common (info, gdbarch);
+
+ tdep->fp_model = ARM_FLOAT_SOFT_VFP;
}
void