* arm-tdep.c (arm_use_struct_convention): Make static. Move to be

with other related struct-returning functions.
(arm_extract_struct_value_address): New function.
(arm_gdbarch_init): Initialize the above in multi-arch vector.  Also
initialize float_format, double_format and long_double_format as
appropriate to the endianness of the target.
* config/arm/tm-arm.h (TARGET_DOUBLE_FORMAT): Delete.
(arm_use_struct_convention): Delete declaration.
(USE_STRUCT_CONVENTION, EXTRACT_STRUCT_VALUE_ADDRESS): Delete.
This commit is contained in:
Richard Earnshaw 2002-02-13 16:32:34 +00:00
parent 9ae9b4eac4
commit 67255d04f2
3 changed files with 140 additions and 114 deletions

View File

@ -1,3 +1,15 @@
2002-02-13 Richard Earnshaw <rearnsha@arm.com>
* arm-tdep.c (arm_use_struct_convention): Make static. Move to be
with other related struct-returning functions.
(arm_extract_struct_value_address): New function.
(arm_gdbarch_init): Initialize the above in multi-arch vector. Also
initialize float_format, double_format and long_double_format as
appropriate to the endianness of the target.
* config/arm/tm-arm.h (TARGET_DOUBLE_FORMAT): Delete.
(arm_use_struct_convention): Delete declaration.
(USE_STRUCT_CONVENTION, EXTRACT_STRUCT_VALUE_ADDRESS): Delete.
2002-02-13 Keith Seitz <keiths@redhat.com>
* defs.h (core_addr_to_string_nz): New function.

View File

@ -145,100 +145,6 @@ struct frame_extra_info
#define MAKE_THUMB_ADDR(addr) ((addr) | 1)
#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
/* Will a function return an aggregate type in memory or in a
register? Return 0 if an aggregate type can be returned in a
register, 1 if it must be returned in memory. */
int
arm_use_struct_convention (int gcc_p, struct type *type)
{
int nRc;
register enum type_code code;
/* In the ARM ABI, "integer" like aggregate types are returned in
registers. For an aggregate type to be integer like, its size
must be less than or equal to REGISTER_SIZE and the offset of
each addressable subfield must be zero. Note that bit fields are
not addressable, and all addressable subfields of unions always
start at offset zero.
This function is based on the behaviour of GCC 2.95.1.
See: gcc/arm.c: arm_return_in_memory() for details.
Note: All versions of GCC before GCC 2.95.2 do not set up the
parameters correctly for a function returning the following
structure: struct { float f;}; This should be returned in memory,
not a register. Richard Earnshaw sent me a patch, but I do not
know of any way to detect if a function like the above has been
compiled with the correct calling convention. */
/* All aggregate types that won't fit in a register must be returned
in memory. */
if (TYPE_LENGTH (type) > REGISTER_SIZE)
{
return 1;
}
/* The only aggregate types that can be returned in a register are
structs and unions. Arrays must be returned in memory. */
code = TYPE_CODE (type);
if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code))
{
return 1;
}
/* Assume all other aggregate types can be returned in a register.
Run a check for structures, unions and arrays. */
nRc = 0;
if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
{
int i;
/* Need to check if this struct/union is "integer" like. For
this to be true, its size must be less than or equal to
REGISTER_SIZE and the offset of each addressable subfield
must be zero. Note that bit fields are not addressable, and
unions always start at offset zero. If any of the subfields
is a floating point type, the struct/union cannot be an
integer type. */
/* For each field in the object, check:
1) Is it FP? --> yes, nRc = 1;
2) Is it addressable (bitpos != 0) and
not packed (bitsize == 0)?
--> yes, nRc = 1
*/
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
enum type_code field_type_code;
field_type_code = TYPE_CODE (TYPE_FIELD_TYPE (type, i));
/* Is it a floating point type field? */
if (field_type_code == TYPE_CODE_FLT)
{
nRc = 1;
break;
}
/* If bitpos != 0, then we have to care about it. */
if (TYPE_FIELD_BITPOS (type, i) != 0)
{
/* Bitfields are not addressable. If the field bitsize is
zero, then the field is not packed. Hence it cannot be
a bitfield or any other packed type. */
if (TYPE_FIELD_BITSIZE (type, i) == 0)
{
nRc = 1;
break;
}
}
}
}
return nRc;
}
static int
arm_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
{
@ -2206,6 +2112,109 @@ arm_extract_return_value (struct type *type,
TYPE_LENGTH (type));
}
/* Extract from an array REGBUF containing the (raw) register state
the address in which a function should return its structure value. */
static CORE_ADDR
arm_extract_struct_value_address (char *regbuf)
{
return extract_address (regbuf, REGISTER_RAW_SIZE(ARM_A1_REGNUM));
}
/* Will a function return an aggregate type in memory or in a
register? Return 0 if an aggregate type can be returned in a
register, 1 if it must be returned in memory. */
static int
arm_use_struct_convention (int gcc_p, struct type *type)
{
int nRc;
register enum type_code code;
/* In the ARM ABI, "integer" like aggregate types are returned in
registers. For an aggregate type to be integer like, its size
must be less than or equal to REGISTER_SIZE and the offset of
each addressable subfield must be zero. Note that bit fields are
not addressable, and all addressable subfields of unions always
start at offset zero.
This function is based on the behaviour of GCC 2.95.1.
See: gcc/arm.c: arm_return_in_memory() for details.
Note: All versions of GCC before GCC 2.95.2 do not set up the
parameters correctly for a function returning the following
structure: struct { float f;}; This should be returned in memory,
not a register. Richard Earnshaw sent me a patch, but I do not
know of any way to detect if a function like the above has been
compiled with the correct calling convention. */
/* All aggregate types that won't fit in a register must be returned
in memory. */
if (TYPE_LENGTH (type) > REGISTER_SIZE)
{
return 1;
}
/* The only aggregate types that can be returned in a register are
structs and unions. Arrays must be returned in memory. */
code = TYPE_CODE (type);
if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code))
{
return 1;
}
/* Assume all other aggregate types can be returned in a register.
Run a check for structures, unions and arrays. */
nRc = 0;
if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
{
int i;
/* Need to check if this struct/union is "integer" like. For
this to be true, its size must be less than or equal to
REGISTER_SIZE and the offset of each addressable subfield
must be zero. Note that bit fields are not addressable, and
unions always start at offset zero. If any of the subfields
is a floating point type, the struct/union cannot be an
integer type. */
/* For each field in the object, check:
1) Is it FP? --> yes, nRc = 1;
2) Is it addressable (bitpos != 0) and
not packed (bitsize == 0)?
--> yes, nRc = 1
*/
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
enum type_code field_type_code;
field_type_code = TYPE_CODE (TYPE_FIELD_TYPE (type, i));
/* Is it a floating point type field? */
if (field_type_code == TYPE_CODE_FLT)
{
nRc = 1;
break;
}
/* If bitpos != 0, then we have to care about it. */
if (TYPE_FIELD_BITPOS (type, i) != 0)
{
/* Bitfields are not addressable. If the field bitsize is
zero, then the field is not packed. Hence it cannot be
a bitfield or any other packed type. */
if (TYPE_FIELD_BITSIZE (type, i) == 0)
{
nRc = 1;
break;
}
}
}
}
return nRc;
}
/* Write into appropriate registers a function return value of type
TYPE, given in virtual format. */
@ -2442,6 +2451,28 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* XXX We'll probably need to set the tdep field soon. */
gdbarch = gdbarch_alloc (&info, NULL);
/* 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);
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");
}
set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
/* Call dummy code. */
@ -2522,6 +2553,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value);
set_gdbarch_store_return_value (gdbarch, arm_store_return_value);
set_gdbarch_store_struct_return (gdbarch, arm_store_struct_return);
set_gdbarch_use_struct_convention (gdbarch, arm_use_struct_convention);
set_gdbarch_extract_struct_value_address (gdbarch,
arm_extract_struct_value_address);
/* Single stepping. */
/* XXX For an RDI target we should ask the target if it can single-step. */

View File

@ -26,14 +26,6 @@
#define GDB_MULTI_ARCH 1
#endif
#include "regcache.h"
#include "floatformat.h"
/* IEEE format floating point. */
#define TARGET_DOUBLE_FORMAT (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG \
? &floatformat_ieee_double_big \
: &floatformat_ieee_double_littlebyte_bigword)
/* The following define instruction sequences that will cause ARM
cpu's to take an undefined instruction trap. These are used to
signal a breakpoint to GDB.
@ -69,18 +61,6 @@
#define THUMB_LE_BREAKPOINT {0xfe,0xdf}
#define THUMB_BE_BREAKPOINT {0xdf,0xfe}
/* The system C compiler uses a similar structure return convention to gcc */
extern use_struct_convention_fn arm_use_struct_convention;
#define USE_STRUCT_CONVENTION(gcc_p, type) \
arm_use_struct_convention (gcc_p, type)
/* Extract from an array REGBUF containing the (raw) register state
the address in which a function should return its structure value,
as a CORE_ADDR (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
(extract_address ((PTR)(REGBUF), REGISTER_RAW_SIZE(0)))
/* Specify that for the native compiler variables for a particular
lexical context are listed after the beginning LBRAC instead of
before in the executables list of symbols. */