* arm-tdep.h (enum arm_float_model): New enum.
authorRichard Earnshaw <richard.earnshaw@arm.com>
Tue, 19 Feb 2002 19:20:31 +0000 (19:20 +0000)
committerRichard Earnshaw <richard.earnshaw@arm.com>
Tue, 19 Feb 2002 19:20:31 +0000 (19:20 +0000)
(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
gdb/arm-tdep.c
gdb/arm-tdep.h
gdb/armnbsd-tdep.c

index a82dc9b1606d57ec33f34c1675523a0b9eecc800..c63cff8d2ab93c9ecfd6cd81924f282562971c72 100644 (file)
@@ -1,3 +1,17 @@
+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.
+
 2002-02-19  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
 
        * i386-tdep.c (i386_gdbarch_init): Eliminate incorrect use
index 2b940bc4cf977a1be2626050a72d5cdfdaf64e87..b164f8e73a21a3b5a959157c55243b37885e4c94 100644 (file)
@@ -2139,7 +2139,29 @@ arm_extract_return_value (struct type *type,
                          char *valbuf)
 {
   if (TYPE_CODE_FLT == TYPE_CODE (type))
-    convert_from_extended (&regbuf[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 (&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));
@@ -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 = "<invalid>";
     }
 
-  /* 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.  */
index 29c8bc97dbc983a5842bf08eb3d0367cb0775050..a4c52dc6f6b0770d23c461e0205383a3fff645fb 100644 (file)
@@ -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.  */
 
index 4a3aeb882f322d8748a63ecc0a5c85ac77425af8..7f6e63992e20d523aaaed586bcb4db3bbca0d39e 100644 (file)
@@ -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