]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Bring COERCE_FLOAT_TO_DOUBLE under gdbarch's control.
authorJim Blandy <jimb@codesourcery.com>
Tue, 22 Feb 2000 19:18:53 +0000 (19:18 +0000)
committerJim Blandy <jimb@codesourcery.com>
Tue, 22 Feb 2000 19:18:53 +0000 (19:18 +0000)
* valops.c (COERCE_FLOAT_TO_DOUBLE): Rework definition to be
more function-like.
(default_coerce_float_to_double, standard_coerce_float_to_double):
New functions.
(value_arg_coerce): Adjust for new definition.
* value.h (default_coerce_float_to_double,
standard_coerce_float_to_double): New declarations for the above.
* gdbarch.sh (coerce_float_to_double): New entry, replacing macro.
* gdbarch.c, gdbarch.h: Regenerated.
* tm-alpha.h, tm-fr30.h, tm-m32r.h, tm-mips.h, tm-hppa.h,
tm-rs6000.h, tm-sh.h, tm-sparc.h (COERCE_FLOAT_TO_DOUBLE): Change
definitions.
* mips-tdep.c (mips_coerce_float_to_double): Supply our own custom
function here.
(mips_gdbarch_init): Install that as our coerce_float_to_double
function.

13 files changed:
gdb/config/alpha/tm-alpha.h
gdb/config/fr30/tm-fr30.h
gdb/config/m32r/tm-m32r.h
gdb/config/mips/tm-mips.h
gdb/config/pa/tm-hppa.h
gdb/config/rs6000/tm-rs6000.h
gdb/config/sh/tm-sh.h
gdb/config/sparc/tm-sparc.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/mips-tdep.c
gdb/valops.c
gdb/value.h

index 8b3c5ba76ffbf55d86b6e38886449f0907f80614..d63dcc1296d1f3ccf31fe9430e3105089e0873c8 100644 (file)
@@ -445,7 +445,7 @@ extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
    values are always passed in as doubles.  Thus by setting this to 1, both
    types of calls will work. */
 
-#define COERCE_FLOAT_TO_DOUBLE 1
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
 
 /* Return TRUE if procedure descriptor PROC is a procedure descriptor
    that refers to a dynamically generated sigtramp function.
index c530ad3ba731145338f8306352d45ea5a324441b..d289f6e3450d6a5804b8184d2fd537ccdb2909b9 100644 (file)
@@ -234,4 +234,4 @@ extern CORE_ADDR
    should be true on any system where you can rely on the prototyping
    information.  When this is true, value_arg_coerce will promote
    floats to doubles iff the function is not prototyped.  */
-#define COERCE_FLOAT_TO_DOUBLE 1
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
index 7aad4c95e12b1c22f4137b54ac4743383b6ea9f3..a68720a984ecfcfef574b7208144b6dc13b9f0e7 100644 (file)
@@ -166,7 +166,7 @@ extern CORE_ADDR m32r_skip_prologue PARAMS ((CORE_ADDR pc));
 /* mvs_no_check  FRAME_NUM_ARGS */
 #define FRAME_NUM_ARGS(fi) (-1)
 
-#define COERCE_FLOAT_TO_DOUBLE 1
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
 
 extern void m32r_write_sp (CORE_ADDR val);
 #define TARGET_WRITE_SP m32r_write_sp
index ea9d04c9eeae29928598950f535eed27b74d76b9..3b8330fb0e8569bbbb240a9f8cc7bb009c2116df 100644 (file)
@@ -500,6 +500,7 @@ extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
 
 #define ECOFF_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32)
 
+#if !GDB_MULTI_ARCH
 /* If the current gcc for for this target does not produce correct debugging
    information for float parameters, both prototyped and unprototyped, then
    define this macro.  This forces gdb to  always assume that floats are
@@ -512,7 +513,8 @@ extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
    for C and break the prototyped case, since the non-prototyped case is
    probably much more common.  (FIXME). */
 
-#define COERCE_FLOAT_TO_DOUBLE (current_language -> la_language == language_c)
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (current_language -> la_language == language_c)
+#endif
 
 /* Select the default mips disassembler */
 
index a5a70646e104404f47a6fb146857a15c26c887c6..9307fa567212cb88a8bd4c174940b77d337a62bc 100644 (file)
@@ -793,7 +793,7 @@ PARAMS ((CORE_ADDR, int))
    for C and break the prototyped case, since the non-prototyped case is
    probably much more common.  (FIXME). */
 
-#define COERCE_FLOAT_TO_DOUBLE (current_language -> la_language == language_c)
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (current_language -> la_language == language_c)
 
 /* Here's how to step off a permanent breakpoint.  */
 #define SKIP_PERMANENT_BREAKPOINT (hppa_skip_permanent_breakpoint)
index 89a0bd1cfeba7e5c37b4bf30438919c923c1a4de..3b3e190541c237ec895f937c99892e888792c7b4 100644 (file)
@@ -559,4 +559,4 @@ extern CORE_ADDR get_toc_offset PARAMS ((struct objfile *));
    values are always passed in as doubles.  Thus by setting this to 1, both
    types of calls will work. */
 
-#define COERCE_FLOAT_TO_DOUBLE 1
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
index c6769e0c7c2e48d1d99ea982c9b50e0f9dd40076..a3367131180ce163ba9e8d8595168c4d15142115 100644 (file)
@@ -269,7 +269,7 @@ extern void sh_pop_frame PARAMS ((void));
 
 #define REGISTER_SIZE 4
 
-#define COERCE_FLOAT_TO_DOUBLE 1
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
 
 #define BELIEVE_PCC_PROMOTION 1
 
index 635a69379d11fde2659a7037ec386dcfcc478f55..5419ecb88e25302ab4fc537b882b73a7b99ee904 100644 (file)
@@ -569,7 +569,7 @@ extern int deferred_stores;
    define this macro.  This forces gdb to  always assume that floats are
    passed as doubles and then converted in the callee. */
 
-#define COERCE_FLOAT_TO_DOUBLE 1
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
 
 /* Select the sparc disassembler */
 
index e9f5f444f5314b93e4bd86401f0889e97d89f300..f33536d52e50014de4a35d622e165b5fc9294279 100644 (file)
@@ -169,6 +169,7 @@ struct gdbarch
   gdbarch_fix_call_dummy_ftype *fix_call_dummy;
   int believe_pcc_promotion;
   int believe_pcc_promotion_type;
+  gdbarch_coerce_float_to_double_ftype *coerce_float_to_double;
   gdbarch_get_saved_register_ftype *get_saved_register;
   gdbarch_register_convertible_ftype *register_convertible;
   gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual;
@@ -268,6 +269,7 @@ struct gdbarch default_gdbarch = {
   0,
   0,
   0,
+  0,
   generic_get_saved_register,
   0,
   0,
@@ -343,6 +345,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->call_dummy_length = -1;
   gdbarch->call_dummy_p = -1;
   gdbarch->call_dummy_stack_adjust_p = -1;
+  gdbarch->coerce_float_to_double = default_coerce_float_to_double;
   gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
   gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
   gdbarch->decr_pc_after_break = -1;
@@ -488,6 +491,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
   if ((GDB_MULTI_ARCH >= 2)
       && (gdbarch->fix_call_dummy == 0))
     internal_error ("gdbarch: verify_gdbarch: fix_call_dummy invalid");
+  if ((GDB_MULTI_ARCH >= 2)
+      && (gdbarch->coerce_float_to_double == default_coerce_float_to_double))
+    internal_error ("gdbarch: verify_gdbarch: coerce_float_to_double invalid");
   if ((GDB_MULTI_ARCH >= 1)
       && (gdbarch->get_saved_register == 0))
     internal_error ("gdbarch: verify_gdbarch: get_saved_register invalid");
@@ -769,6 +775,10 @@ gdbarch_dump (void)
                       "gdbarch_update: BELIEVE_PCC_PROMOTION_TYPE = %ld\n",
                       (long) BELIEVE_PCC_PROMOTION_TYPE);
 #endif
+  fprintf_unfiltered (gdb_stdlog,
+                      "gdbarch_update: COERCE_FLOAT_TO_DOUBLE = 0x%08lx\n",
+                      (long) current_gdbarch->coerce_float_to_double
+                      /*COERCE_FLOAT_TO_DOUBLE ()*/);
   fprintf_unfiltered (gdb_stdlog,
                       "gdbarch_update: GET_SAVED_REGISTER = 0x%08lx\n",
                       (long) current_gdbarch->get_saved_register
@@ -1732,6 +1742,24 @@ set_gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch,
   gdbarch->believe_pcc_promotion_type = believe_pcc_promotion_type;
 }
 
+int
+gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, struct type *formal, struct type *actual)
+{
+  if (gdbarch->coerce_float_to_double == 0)
+    internal_error ("gdbarch: gdbarch_coerce_float_to_double invalid");
+  if (gdbarch_debug >= 2)
+    /* FIXME: gdb_std??? */
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_coerce_float_to_double called\n");
+  return gdbarch->coerce_float_to_double (formal, actual);
+}
+
+void
+set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch,
+                                    gdbarch_coerce_float_to_double_ftype coerce_float_to_double)
+{
+  gdbarch->coerce_float_to_double = coerce_float_to_double;
+}
+
 void
 gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval)
 {
index a1f7c764671e08c2ff5b05f82635cb134eabe8d0..1244f930a489fe581dac0d91e4aa65db564dc9e8 100644 (file)
@@ -465,6 +465,15 @@ extern void set_gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch, int
 #endif
 #endif
 
+typedef int (gdbarch_coerce_float_to_double_ftype) (struct type *formal, struct type *actual);
+extern int gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, struct type *formal, struct type *actual);
+extern void set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, gdbarch_coerce_float_to_double_ftype *coerce_float_to_double);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > 1) || !defined (COERCE_FLOAT_TO_DOUBLE)
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (gdbarch_coerce_float_to_double (current_gdbarch, formal, actual))
+#endif
+#endif
+
 typedef void (gdbarch_get_saved_register_ftype) (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval);
 extern void gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval);
 extern void set_gdbarch_get_saved_register (struct gdbarch *gdbarch, gdbarch_get_saved_register_ftype *get_saved_register);
index 5940f8422f7123c6c36d744232518901d21656b5..092ae3483f51a88eb3f6a1ab9f1b0892e75adcd9 100644 (file)
@@ -3639,6 +3639,24 @@ mips_call_dummy_address ()
 }
 
 
+/* If the current gcc for for this target does not produce correct debugging
+   information for float parameters, both prototyped and unprototyped, then
+   define this macro.  This forces gdb to  always assume that floats are
+   passed as doubles and then converted in the callee.
+
+   For the mips chip, it appears that the debug info marks the parameters as
+   floats regardless of whether the function is prototyped, but the actual
+   values are passed as doubles for the non-prototyped case and floats for
+   the prototyped case.  Thus we choose to make the non-prototyped case work
+   for C and break the prototyped case, since the non-prototyped case is
+   probably much more common.  (FIXME). */
+
+static int
+mips_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+  return current_language->la_language == language_c;
+}
+
 
 static gdbarch_init_ftype mips_gdbarch_init;
 static struct gdbarch *
@@ -3835,6 +3853,7 @@ mips_gdbarch_init (info, arches)
   set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
   set_gdbarch_push_arguments (gdbarch, mips_push_arguments);
   set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not);
+  set_gdbarch_coerce_float_to_double (gdbarch, mips_coerce_float_to_double);
 
   set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
   set_gdbarch_get_saved_register (gdbarch, default_get_saved_register);
index 3e1a619c3766d57f24ff2811007ae2b855a82447..5fd0fd8c1edc62b57c1765fd44e62b5c37b6d7d2 100644 (file)
 #include <errno.h>
 #include "gdb_string.h"
 
-/* Default to coercing float to double in function calls only when there is
-   no prototype.  Otherwise on targets where the debug information is incorrect
-   for either the prototype or non-prototype case, we can force it by defining
-   COERCE_FLOAT_TO_DOUBLE in the target configuration file. */
-
-#ifndef COERCE_FLOAT_TO_DOUBLE
-#define COERCE_FLOAT_TO_DOUBLE (param_type == NULL)
-#endif
-
 /* Flag indicating HP compilers were used; needed to correctly handle some
    value operations with HP aCC code/runtime. */
 extern int hp_som_som_object_present;
@@ -1124,6 +1115,46 @@ default_push_arguments (nargs, args, sp, struct_return, struct_addr)
 }
 
 
+/* If we're calling a function declared without a prototype, should we
+   promote floats to doubles?  FORMAL and ACTUAL are the types of the
+   arguments; FORMAL may be NULL.
+
+   If we have no definition for this macro, either from the target or
+   from gdbarch, provide a default.  */
+#ifndef COERCE_FLOAT_TO_DOUBLE
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) \
+  (default_coerce_float_to_double ((formal), (actual)))
+#endif   
+
+
+/* A default function for COERCE_FLOAT_TO_DOUBLE: do the coercion only
+   when we don't have any type for the argument at hand.  This occurs
+   when we have no debug info, or when passing varargs.
+
+   This is an annoying default: the rule the compiler follows is to do
+   the standard promotions whenever there is no prototype in scope,
+   and almost all targets want this behavior.  But there are some old
+   architectures which want this odd behavior.  If you want to go
+   through them all and fix them, please do.  Modern gdbarch-style
+   targets may find it convenient to use standard_coerce_float_to_double.  */
+int
+default_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+  return formal == NULL;
+}
+
+
+/* Always coerce floats to doubles when there is no prototype in scope.
+   If your architecture follows the standard type promotion rules for
+   calling unprototyped functions, your gdbarch init function can pass
+   this function to set_gdbarch_coerce_float_to_double to use its logic.  */
+int
+standard_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+  return 1;
+}
+
+
 /* Perform the standard coercions that are specified
    for arguments to be passed to C functions.
 
@@ -1171,7 +1202,7 @@ value_arg_coerce (arg, param_type, is_prototyped)
          non-prototyped case.  As many debugging formats include
          no information about prototyping, we have to live with
          COERCE_FLOAT_TO_DOUBLE for now.  */
-      if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE)
+      if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type))
        {
          if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
            type = builtin_type_double;
index ab22573a4806c064970530aa1721242c1d011e75..9b6989a28c2f6e403ff667166da0fddda8b52a9d 100644 (file)
@@ -549,6 +549,10 @@ extern value_ptr value_slice PARAMS ((value_ptr, int, int));
 
 extern value_ptr call_function_by_hand PARAMS ((value_ptr, int, value_ptr *));
 
+extern int default_coerce_float_to_double (struct type *, struct type *);
+
+extern int standard_coerce_float_to_double (struct type *, struct type *);
+
 extern value_ptr value_literal_complex PARAMS ((value_ptr, value_ptr, struct type *));
 
 extern void find_rt_vbase_offset PARAMS ((struct type *, struct type *, char *, int, int *, int *));