PATCH ARM Add set/show commands for changing the FPU model

Richard Earnshaw rearnsha@arm.com
Sat Mar 22 20:44:00 GMT 2003


This patch adds the ability for the user to change the floating-point 
model that gdb understands for the session.  Previously we could only 
control this via the OSABI setting, which was not sufficiently flexible.

Now that we have this level of control it seems reasonable to make the 
default setting match what gcc normally generates for arm-elf (ie softfpa, 
the software floating-point with FPA-style mixed-endian doubles on a 
little-endian ARM).

Because we now default to software floating point, this effectively fixes 
8 regression failures in the testsuite.

R.

2003-03-22  Richard Earnshaw  <rearnsha@arm.com>

	* 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.


-------------- next part --------------
Index: arm-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-linux-tdep.c,v
retrieving revision 1.26
diff -p -r1.26 arm-linux-tdep.c
*** arm-linux-tdep.c	25 Feb 2003 21:36:16 -0000	1.26
--- arm-linux-tdep.c	22 Mar 2003 20:29:52 -0000
*************** arm_linux_init_abi (struct gdbarch_info 
*** 525,530 ****
--- 525,532 ----
    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;
  
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.110
diff -p -r1.110 arm-tdep.c
*** arm-tdep.c	22 Mar 2003 18:01:38 -0000	1.110
--- arm-tdep.c	22 Mar 2003 20:29:52 -0000
*************** static int arm_debug;
*** 103,108 ****
--- 103,123 ----
  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;
  
*************** arm_extract_return_value (struct type *t
*** 2170,2178 ****
  
    if (TYPE_CODE_FLT == TYPE_CODE (type))
      {
!       struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
! 
!       switch (tdep->fp_model)
  	{
  	case ARM_FLOAT_FPA:
  	  {
--- 2185,2191 ----
  
    if (TYPE_CODE_FLT == TYPE_CODE (type))
      {
!       switch (arm_get_fp_model (current_gdbarch))
  	{
  	case ARM_FLOAT_FPA:
  	  {
*************** arm_extract_return_value (struct type *t
*** 2187,2193 ****
  	  }
  	  break;
  
! 	case ARM_FLOAT_SOFT:
  	case ARM_FLOAT_SOFT_VFP:
  	  regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf);
  	  if (TYPE_LENGTH (type) > 4)
--- 2200,2206 ----
  	  }
  	  break;
  
! 	case ARM_FLOAT_SOFT_FPA:
  	case ARM_FLOAT_SOFT_VFP:
  	  regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf);
  	  if (TYPE_LENGTH (type) > 4)
*************** arm_store_return_value (struct type *typ
*** 2365,2374 ****
  
    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)
  	{
  	case ARM_FLOAT_FPA:
  
--- 2378,2386 ----
  
    if (TYPE_CODE (type) == TYPE_CODE_FLT)
      {
        char buf[ARM_MAX_REGISTER_RAW_SIZE];
  
!       switch (arm_get_fp_model (current_gdbarch))
  	{
  	case ARM_FLOAT_FPA:
  
*************** arm_store_return_value (struct type *typ
*** 2376,2382 ****
  	  regcache_cooked_write (regs, ARM_F0_REGNUM, buf);
  	  break;
  
! 	case ARM_FLOAT_SOFT:
  	case ARM_FLOAT_SOFT_VFP:
  	  regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf);
  	  if (TYPE_LENGTH (type) > 4)
--- 2388,2394 ----
  	  regcache_cooked_write (regs, ARM_F0_REGNUM, buf);
  	  break;
  
! 	case ARM_FLOAT_SOFT_FPA:
  	case ARM_FLOAT_SOFT_VFP:
  	  regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf);
  	  if (TYPE_LENGTH (type) > 4)
*************** show_arm_command (char *args, int from_t
*** 2533,2538 ****
--- 2545,2613 ----
    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
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2804,2811 ****
       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;
  
    /* Breakpoints.  */
    switch (info.byte_order)
--- 2879,2888 ----
       ready to unwind the PC first (see frame.c:get_prev_frame()).  */
    set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
  
!   /* 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)
*************** arm_gdbarch_init (struct gdbarch_info in
*** 2953,2972 ****
  
      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:
--- 3030,3036 ----
  
      case BFD_ENDIAN_LITTLE:
        set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
!       arm_set_fp (gdbarch);
        break;
  
      default:
*************** _initialize_arm_tdep (void)
*** 3103,3108 ****
--- 3167,3173 ----
  			      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,
*************** _initialize_arm_tdep (void)
*** 3121,3126 ****
--- 3186,3204 ----
  			   "When off, a 26-bit PC will be used.",
  			   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, &current_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,
Index: arm-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.h,v
retrieving revision 1.10
diff -p -r1.10 arm-tdep.h
*** arm-tdep.h	4 Jan 2003 23:38:44 -0000	1.10
--- arm-tdep.h	22 Mar 2003 20:29:52 -0000
*************** enum gdb_regnum {
*** 109,123 ****
     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
--- 109,131 ----
     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. 
! 
!    If you update this enum, don't forget to update fp_model_strings in 
!    arm-tdep.c.  */
  
  enum arm_float_model
  {
!   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


More information about the Gdb-patches mailing list