From fd50bc42f4703d05287bf0daca15cc641a687e17 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Sat, 22 Mar 2003 20:39:21 +0000 Subject: [PATCH] * arm-tdep.h (arm_float_model): Add AUTO and LAST values. (arm_get_fp_model): Declare. * arm-tdep.c (fp_model_strings): New string array. (arm_fp_model, current_fp_model): New variables. (arm_get_fp_model): New function. (arm_set_fp): New function. (set_fp_model_sfunc): New function. (show_fp_model): New function. (_initialize_arm_tdep): Add new command to set/show the FPU. (arm_extract_return_value): Use arm_get_fp_model. (arm_store_return_value): Likewise. (arm_gdbarch_init): Default fpa model is softfpa. Call arm_set_fp to initialize the floating-point data types. * arm-linux-tdep.c (arm_linux_init_abi): The default floating point model is FPA. --- gdb/ChangeLog | 18 +++++++ gdb/arm-linux-tdep.c | 2 + gdb/arm-tdep.c | 124 +++++++++++++++++++++++++++++++++++-------- gdb/arm-tdep.h | 18 +++++-- 4 files changed, 134 insertions(+), 28 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 18904e1f66e..58963592853 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2003-03-22 Richard Earnshaw + + * arm-tdep.h (arm_float_model): Add AUTO and LAST values. + (arm_get_fp_model): Declare. + * arm-tdep.c (fp_model_strings): New string array. + (arm_fp_model, current_fp_model): New variables. + (arm_get_fp_model): New function. + (arm_set_fp): New function. + (set_fp_model_sfunc): New function. + (show_fp_model): New function. + (_initialize_arm_tdep): Add new command to set/show the FPU. + (arm_extract_return_value): Use arm_get_fp_model. + (arm_store_return_value): Likewise. + (arm_gdbarch_init): Default fpa model is softfpa. Call arm_set_fp + to initialize the floating-point data types. + * arm-linux-tdep.c (arm_linux_init_abi): The default floating point + model is FPA. + 2003-03-22 Richard Earnshaw * arm-tdep.c (show_arm_command): Don't print out help. Instead, show diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 1ebe600191f..01b45f13f89 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -525,6 +525,8 @@ arm_linux_init_abi (struct gdbarch_info info, tdep->arm_breakpoint = arm_linux_arm_le_breakpoint; tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint); + tdep->fp_model = ARM_FLOAT_FPA; + tdep->jb_pc = ARM_LINUX_JB_PC; tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE; diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 53a36929147..da60ade72ff 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -103,6 +103,21 @@ static int arm_debug; static struct cmd_list_element *setarmcmdlist = NULL; static struct cmd_list_element *showarmcmdlist = NULL; +/* The type of floating-point to use. Keep this in sync with enum + arm_float_model, and the help string in _initialize_arm_tdep. */ +static const char *fp_model_strings[] = +{ + "auto", + "softfpa", + "fpa", + "softvfp", + "vfp" +}; + +/* A variable that can be configured by the user. */ +static enum arm_float_model arm_fp_model = ARM_FLOAT_AUTO; +static const char *current_fp_model = "auto"; + /* Number of different reg name sets (options). */ static int num_disassembly_options; @@ -2170,9 +2185,7 @@ arm_extract_return_value (struct type *type, if (TYPE_CODE_FLT == TYPE_CODE (type)) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - switch (tdep->fp_model) + switch (arm_get_fp_model (current_gdbarch)) { case ARM_FLOAT_FPA: { @@ -2187,7 +2200,7 @@ arm_extract_return_value (struct type *type, } break; - case ARM_FLOAT_SOFT: + case ARM_FLOAT_SOFT_FPA: case ARM_FLOAT_SOFT_VFP: regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf); if (TYPE_LENGTH (type) > 4) @@ -2365,10 +2378,9 @@ arm_store_return_value (struct type *type, struct regcache *regs, if (TYPE_CODE (type) == TYPE_CODE_FLT) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); char buf[ARM_MAX_REGISTER_RAW_SIZE]; - switch (tdep->fp_model) + switch (arm_get_fp_model (current_gdbarch)) { case ARM_FLOAT_FPA: @@ -2376,7 +2388,7 @@ arm_store_return_value (struct type *type, struct regcache *regs, regcache_cooked_write (regs, ARM_F0_REGNUM, buf); break; - case ARM_FLOAT_SOFT: + case ARM_FLOAT_SOFT_FPA: case ARM_FLOAT_SOFT_VFP: regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf); if (TYPE_LENGTH (type) > 4) @@ -2533,6 +2545,69 @@ show_arm_command (char *args, int from_tty) cmd_show_list (showarmcmdlist, from_tty, ""); } +enum arm_float_model +arm_get_fp_model (struct gdbarch *gdbarch) +{ + if (arm_fp_model == ARM_FLOAT_AUTO) + return gdbarch_tdep (gdbarch)->fp_model; + + return arm_fp_model; +} + +static void +arm_set_fp (struct gdbarch *gdbarch) +{ + enum arm_float_model fp_model = arm_get_fp_model (gdbarch); + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE + && (fp_model == ARM_FLOAT_SOFT_FPA || fp_model == ARM_FLOAT_FPA)) + { + set_gdbarch_double_format (gdbarch, + &floatformat_ieee_double_littlebyte_bigword); + set_gdbarch_long_double_format + (gdbarch, &floatformat_ieee_double_littlebyte_bigword); + } + else + { + set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little); + set_gdbarch_long_double_format (gdbarch, + &floatformat_ieee_double_little); + } +} + +static void +set_fp_model_sfunc (char *args, int from_tty, + struct cmd_list_element *c) +{ + enum arm_float_model fp_model; + + for (fp_model = ARM_FLOAT_AUTO; fp_model != ARM_FLOAT_LAST; fp_model++) + if (strcmp (current_fp_model, fp_model_strings[fp_model]) == 0) + { + arm_fp_model = fp_model; + break; + } + + if (fp_model == ARM_FLOAT_LAST) + internal_error (__FILE__, __LINE__, "Invalid fp model accepted: %s.", + current_fp_model); + + if (gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) + arm_set_fp (current_gdbarch); +} + +static void +show_fp_model (char *args, int from_tty, + struct cmd_list_element *c) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (arm_fp_model == ARM_FLOAT_AUTO + && gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) + printf_filtered (" - the default for the current ABI is \"%s\".\n", + fp_model_strings[tdep->fp_model]); +} + /* If the user changes the register disassembly style used for info register and other commands, we have to also switch the style used in opcodes for disassembly output. This function is run in the "set @@ -2804,8 +2879,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) ready to unwind the PC first (see frame.c:get_prev_frame()). */ set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default); - /* This is the way it has always defaulted. */ - tdep->fp_model = ARM_FLOAT_FPA; + /* We used to default to FPA for generic ARM, but almost nobody uses that + now, and we now provide a way for the user to force the model. So + default to the most useful variant. */ + tdep->fp_model = ARM_FLOAT_SOFT_FPA; /* Breakpoints. */ switch (info.byte_order) @@ -2953,20 +3030,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); - } + arm_set_fp (gdbarch); break; default: @@ -3103,6 +3167,7 @@ _initialize_arm_tdep (void) valid_disassembly_styles, &disassembly_style, helptext, &setarmcmdlist); + set_cmd_sfunc (new_set, set_disassembly_style_sfunc); add_show_from_set (new_set, &showarmcmdlist); add_setshow_cmd_full ("apcs32", no_class, @@ -3122,6 +3187,19 @@ _initialize_arm_tdep (void) NULL, NULL, &setarmcmdlist, &showarmcmdlist); + /* Add a command to allow the user to force the FPU model. */ + new_set = add_set_enum_cmd + ("fpu", no_class, fp_model_strings, ¤t_fp_model, + "Set the floating point type.\n" + "auto - Determine the FP typefrom the OS-ABI.\n" + "softfpa - Software FP, mixed-endian doubles on little-endian ARMs.\n" + "fpa - FPA co-processor (GCC compiled).\n" + "softvfp - Software FP with pure-endian doubles.\n" + "vfp - VFP co-processor.", + &setarmcmdlist); + set_cmd_sfunc (new_set, set_fp_model_sfunc); + set_cmd_sfunc (add_show_from_set (new_set, &showarmcmdlist), show_fp_model); + /* Add the deprecated "othernames" command. */ deprecate_cmd (add_com ("othernames", class_obscure, arm_othernames, "Switch to the next set of register names."), diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index b8c4711838e..26f3a83a973 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -109,16 +109,24 @@ enum gdb_regnum { 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. */ + In addition to the traditional models, VFP adds two more. + + If you update this enum, don't forget to update fp_model_strings in + arm-tdep.c. */ enum arm_float_model { - ARM_FLOAT_SOFT, - ARM_FLOAT_FPA, - ARM_FLOAT_SOFT_VFP, - ARM_FLOAT_VFP + ARM_FLOAT_AUTO, /* Automatic detection. Do not set in tdep. */ + ARM_FLOAT_SOFT_FPA, /* Traditional soft-float (mixed-endian on LE ARM). */ + ARM_FLOAT_FPA, /* FPA co-processor. GCC calling convention. */ + ARM_FLOAT_SOFT_VFP, /* Soft-float with pure-endian doubles. */ + ARM_FLOAT_VFP, /* Full VFP calling convention. */ + ARM_FLOAT_LAST /* Keep at end. */ }; +/* A method to the setting based on user's choice and ABI setting. */ +enum arm_float_model arm_get_fp_model (struct gdbarch *); + /* Target-dependent structure in gdbarch. */ struct gdbarch_tdep { -- 2.30.2