mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00
Bring COERCE_FLOAT_TO_DOUBLE under gdbarch's control.
* 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.
This commit is contained in:
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
51
gdb/valops.c
51
gdb/valops.c
@ -34,15 +34,6 @@
|
||||
#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;
|
||||
|
@ -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 *));
|
||||
|
Reference in New Issue
Block a user