From 08216dd78d5f1a8976771db9ca7008126ccf3ece Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Tue, 19 Feb 2002 19:20:31 +0000 Subject: * 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. --- gdb/ChangeLog | 14 +++++++ gdb/arm-tdep.c | 108 +++++++++++++++++++++++++++++++++++++++++++---------- gdb/arm-tdep.h | 18 +++++++++ gdb/armnbsd-tdep.c | 7 ++++ 4 files changed, 127 insertions(+), 20 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a82dc9b..c63cff8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2002-02-19 Richard Earnshaw + + * 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. + 2002-02-19 Peter Schauer * i386-tdep.c (i386_gdbarch_init): Eliminate incorrect use diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 2b940bc..b164f8e 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -2139,7 +2139,29 @@ arm_extract_return_value (struct type *type, char *valbuf) { if (TYPE_CODE_FLT == TYPE_CODE (type)) - convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf); + { + 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)); @@ -2256,15 +2278,32 @@ arm_store_return_value (struct type *type, char *valbuf) { if (TYPE_CODE (type) == TYPE_CODE_FLT) { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 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); + 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 (0, valbuf, TYPE_LENGTH (type)); + write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type)); } /* Store the address of the place in which to copy the structure the @@ -2762,7 +2801,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->abi_name = ""; } - /* Breakpoints and floating point sizes and format. */ + /* This is the way it has always defaulted. */ + tdep->fp_model = ARM_FLOAT_FPA; + + /* Breakpoints. */ switch (info.byte_order) { case BFD_ENDIAN_BIG: @@ -2771,10 +2813,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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: @@ -2783,12 +2821,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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: @@ -2905,9 +2937,12 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* 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"); + /* 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 { @@ -2939,6 +2974,39 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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 building here. */ diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index 29c8bc9..a4c52dc 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -116,11 +116,29 @@ enum arm_abi 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. */ diff --git a/gdb/armnbsd-tdep.c b/gdb/armnbsd-tdep.c index 4a3aeb8..7f6e639 100644 --- a/gdb/armnbsd-tdep.c +++ b/gdb/armnbsd-tdep.c @@ -57,17 +57,24 @@ static void 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 -- cgit v1.1