This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH ARM initial support for different floating-point models



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 (&regbuf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf);
    else
      memcpy (valbuf, &regbuf[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 (&regbuf[REGISTER_BYTE (ARM_F0_REGNUM)],
! 				 valbuf);
! 	  break;
! 
! 	case ARM_FLOAT_SOFT:
! 	case ARM_FLOAT_SOFT_VFP:
! 	  memcpy (valbuf, &regbuf[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, &regbuf[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]