forked from Imagelibrary/binutils-gdb
2002-04-29 Elena Zannoni <ezannoni@redhat.com>
* rs6000-tdep.c (rs6000_extract_return_value, rs6000_store_return_value): Handle returning vectors. (rs6000_gdbarch_init): Use ppc_sysv_abi_broken_use_struct_convention for native sysv cases. * ppc-linux-tdep.c (ppc_sysv_abi_broken_use_struct_convention): New function. (ppc_sysv_abi_use_struct_convention): Deal with functions returning vectors. (ppc_sysv_abi_push_arguments): Handle vector parameters. * ppc-tdep.h (ppc_sysv_abi_broken_use_struct_convention): Export.
This commit is contained in:
@@ -34,6 +34,24 @@
|
||||
* target.c (do_xfer_memory): Correct reference to the new option
|
||||
"trust-readonly-sections".
|
||||
|
||||
2002-04-26 Elena Zannoni <ezannoni@redhat.com>
|
||||
|
||||
* rs6000-tdep.c (rs6000_extract_return_value,
|
||||
rs6000_store_return_value): Handle returning vectors.
|
||||
(rs6000_gdbarch_init): Use
|
||||
ppc_sysv_abi_broken_use_struct_convention for native sysv cases.
|
||||
* ppc-linux-tdep.c (ppc_sysv_abi_broken_use_struct_convention):
|
||||
New function.
|
||||
(ppc_sysv_abi_use_struct_convention): Deal with functions returning
|
||||
vectors.
|
||||
(ppc_sysv_abi_push_arguments): Handle vector parameters.
|
||||
* ppc-tdep.h (ppc_sysv_abi_broken_use_struct_convention): Export.
|
||||
|
||||
2002-04-26 Elena Zannoni <ezannoni@redhat.com>
|
||||
|
||||
* Makefile.in (thread-db.o): This file cannot be built with
|
||||
,-Werror enabled.
|
||||
|
||||
2002-04-26 Elena Zannoni <ezannoni@redhat.com>
|
||||
|
||||
* gdbtypes.h (TYPE_FLAG_VECTOR, TYPE_VECTOR): Define.
|
||||
|
||||
@@ -415,11 +415,29 @@ ppc_linux_frame_chain (struct frame_info *thisframe)
|
||||
it may be used generically by ports which use either the SysV ABI or
|
||||
the EABI */
|
||||
|
||||
/* Until November 2001, gcc was not complying to the SYSV ABI for
|
||||
returning structures less than or equal to 8 bytes in size. It was
|
||||
returning everything in memory. When this was corrected, it wasn't
|
||||
fixed for native platforms. */
|
||||
int
|
||||
ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
|
||||
{
|
||||
if (TYPE_LENGTH (value_type) == 16
|
||||
&& TYPE_VECTOR (value_type))
|
||||
return 0;
|
||||
|
||||
return generic_use_struct_convention (gcc_p, value_type);
|
||||
}
|
||||
|
||||
/* Structures 8 bytes or less long are returned in the r3 & r4
|
||||
registers, according to the SYSV ABI. */
|
||||
int
|
||||
ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
|
||||
{
|
||||
if (TYPE_LENGTH (value_type) == 16
|
||||
&& TYPE_VECTOR (value_type))
|
||||
return 0;
|
||||
|
||||
return (TYPE_LENGTH (value_type) > 8);
|
||||
}
|
||||
|
||||
@@ -445,7 +463,12 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
int struct_return, CORE_ADDR struct_addr)
|
||||
{
|
||||
int argno;
|
||||
int greg, freg;
|
||||
/* Next available general register for non-float, non-vector arguments. */
|
||||
int greg;
|
||||
/* Next available floating point register for float arguments. */
|
||||
int freg;
|
||||
/* Next available vector register for vector arguments. */
|
||||
int vreg;
|
||||
int argstkspace;
|
||||
int structstkspace;
|
||||
int argoffset;
|
||||
@@ -458,6 +481,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
|
||||
greg = struct_return ? 4 : 3;
|
||||
freg = 1;
|
||||
vreg = 2;
|
||||
argstkspace = 0;
|
||||
structstkspace = 0;
|
||||
|
||||
@@ -500,21 +524,38 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
greg += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else if (!TYPE_VECTOR (type))
|
||||
{
|
||||
if (len > 4
|
||||
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (type) == TYPE_CODE_UNION)
|
||||
{
|
||||
/* Rounding to the nearest multiple of 8 may not be necessary,
|
||||
but it is safe. Particularly since we don't know the
|
||||
field types of the structure */
|
||||
but it is safe. Particularly since we don't know the
|
||||
field types of the structure */
|
||||
structstkspace += round2 (len, 8);
|
||||
}
|
||||
if (greg <= 10)
|
||||
greg++;
|
||||
else
|
||||
argstkspace += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len == 16
|
||||
&& TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
&& TYPE_VECTOR (type))
|
||||
{
|
||||
if (vreg <= 13)
|
||||
vreg++;
|
||||
else
|
||||
{
|
||||
/* Vector arguments must be aligned to 16 bytes on
|
||||
the stack. */
|
||||
argstkspace += round2 (argstkspace, 16);
|
||||
argstkspace += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,6 +581,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
structoffset = argoffset + argstkspace;
|
||||
freg = 1;
|
||||
greg = 3;
|
||||
vreg = 2;
|
||||
/* Fill in r3 with the return structure, if any */
|
||||
if (struct_return)
|
||||
{
|
||||
@@ -561,7 +603,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
{
|
||||
if (len > 8)
|
||||
printf_unfiltered (
|
||||
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
|
||||
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
|
||||
memcpy (®isters[REGISTER_BYTE (FP0_REGNUM + freg)],
|
||||
VALUE_CONTENTS (arg), len);
|
||||
freg++;
|
||||
@@ -599,7 +641,7 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
greg += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!TYPE_VECTOR (type))
|
||||
{
|
||||
char val_buf[4];
|
||||
if (len > 4
|
||||
@@ -617,7 +659,6 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
}
|
||||
if (greg <= 10)
|
||||
{
|
||||
*(int *) ®isters[REGISTER_BYTE (greg)] = 0;
|
||||
memcpy (®isters[REGISTER_BYTE (greg)], val_buf, 4);
|
||||
greg++;
|
||||
}
|
||||
@@ -627,6 +668,30 @@ ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
argoffset += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len == 16
|
||||
&& TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
&& TYPE_VECTOR (type))
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
char *v_val_buf = alloca (16);
|
||||
memset (v_val_buf, 0, 16);
|
||||
memcpy (v_val_buf, VALUE_CONTENTS (arg), len);
|
||||
if (vreg <= 13)
|
||||
{
|
||||
memcpy (®isters[REGISTER_BYTE (tdep->ppc_vr0_regnum
|
||||
+ vreg)],
|
||||
v_val_buf, 16);
|
||||
vreg++;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_memory (sp + argoffset, v_val_buf, 16);
|
||||
argoffset += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target_store_registers (-1);
|
||||
|
||||
@@ -32,6 +32,7 @@ int ppc_linux_frameless_function_invocation (struct frame_info *);
|
||||
void ppc_linux_frame_init_saved_regs (struct frame_info *);
|
||||
CORE_ADDR ppc_linux_frame_chain (struct frame_info *);
|
||||
int ppc_sysv_abi_use_struct_convention (int, struct type *);
|
||||
int ppc_sysv_abi_broken_use_struct_convention (int, struct type *);
|
||||
CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int,
|
||||
CORE_ADDR);
|
||||
int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
|
||||
|
||||
@@ -1144,6 +1144,7 @@ static void
|
||||
rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
|
||||
{
|
||||
int offset = 0;
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
|
||||
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
|
||||
{
|
||||
@@ -1165,6 +1166,13 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
|
||||
memcpy (valbuf, &ff, sizeof (float));
|
||||
}
|
||||
}
|
||||
else if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
|
||||
&& TYPE_LENGTH (valtype) == 16
|
||||
&& TYPE_VECTOR (valtype))
|
||||
{
|
||||
memcpy (valbuf, regbuf + REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
|
||||
TYPE_LENGTH (valtype));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* return value is copied starting from r3. */
|
||||
@@ -1909,6 +1917,8 @@ rs6000_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
|
||||
static void
|
||||
rs6000_store_return_value (struct type *type, char *valbuf)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||
|
||||
/* Floating point values are returned starting from FPR1 and up.
|
||||
@@ -1917,6 +1927,13 @@ rs6000_store_return_value (struct type *type, char *valbuf)
|
||||
|
||||
write_register_bytes (REGISTER_BYTE (FP0_REGNUM + 1), valbuf,
|
||||
TYPE_LENGTH (type));
|
||||
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
if (TYPE_LENGTH (type) == 16
|
||||
&& TYPE_VECTOR (type))
|
||||
write_register_bytes (REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
|
||||
valbuf, TYPE_LENGTH (type));
|
||||
}
|
||||
else
|
||||
/* Everything else is returned in GPR3 and up. */
|
||||
write_register_bytes (REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3),
|
||||
@@ -2706,7 +2723,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
|| osabi == ELFOSABI_NETBSD
|
||||
|| osabi == ELFOSABI_FREEBSD)
|
||||
set_gdbarch_use_struct_convention (gdbarch,
|
||||
generic_use_struct_convention);
|
||||
ppc_sysv_abi_broken_use_struct_convention);
|
||||
else
|
||||
set_gdbarch_use_struct_convention (gdbarch,
|
||||
ppc_sysv_abi_use_struct_convention);
|
||||
|
||||
Reference in New Issue
Block a user