* [rfa] Add e500 function call support to PPC
@ 2003-03-08 19:11 Andrew Cagney
2003-03-09 1:00 ` Kevin Buettner
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Cagney @ 2003-03-08 19:11 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 190 bytes --]
Hello,
This adds support for the e500's function call convention to the PPC
(ppc-sysv-tdep.c to be exact).
The e500 passes everything in GPRs (which are extended to 64 bits).
ok?
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 7717 bytes --]
2003-03-08 Andrew Cagney <cagney@redhat.com>
From Elena Zannoni <ezannoni@redhat.com>
* ppc-sysv-tdep.c (ppc_sysv_abi_push_arguments): Handle e500
vector and floating-point parameters.
(ppc_sysv_abi_use_struct_convention): Handle e500 struct return
convention.
(ppc_sysv_abi_broken_use_struct_convention): Ditto.
Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.3
diff -u -r1.3 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c 14 Nov 2002 20:37:28 -0000 1.3
+++ ppc-sysv-tdep.c 8 Mar 2003 18:59:54 -0000
@@ -61,11 +61,12 @@
int structstkspace;
int argoffset;
int structoffset;
- struct value *arg;
struct type *type;
int len;
char old_sp_buf[4];
CORE_ADDR saved_sp;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
greg = struct_return ? 4 : 3;
freg = 1;
@@ -79,11 +80,12 @@
are put in registers. */
for (argno = 0; argno < nargs; argno++)
{
- arg = args[argno];
+ struct value *arg = args[argno];
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && arch_info->mach != bfd_mach_ppc_e500)
{
if (freg <= 8)
freg++;
@@ -96,7 +98,10 @@
argstkspace += 8;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ else if (len == 8
+ && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+ || (arch_info->mach == bfd_mach_ppc_e500
+ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
{
if (greg > 9)
{
@@ -144,6 +149,20 @@
argstkspace += 16;
}
}
+ else if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ if (greg <= 10)
+ greg++;
+ else
+ {
+ /* Vector arguments must be aligned to 8 bytes on
+ the stack. */
+ argstkspace += round2 (argstkspace, 8);
+ argstkspace += 8;
+ }
+ }
}
}
@@ -170,30 +189,33 @@
freg = 1;
greg = 3;
vreg = 2;
+
/* Fill in r3 with the return structure, if any */
if (struct_return)
{
- char val_buf[4];
- store_address (val_buf, 4, struct_addr);
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, struct_addr);
greg++;
}
+
/* Now fill in the registers and stack... */
for (argno = 0; argno < nargs; argno++)
{
- arg = args[argno];
+ struct value *arg = args[argno];
+ char *val = VALUE_CONTENTS (arg);
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && arch_info->mach != bfd_mach_ppc_e500)
{
if (freg <= 8)
{
+ ULONGEST regval;
if (len > 8)
printf_unfiltered (
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
- memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + freg)],
- VALUE_CONTENTS (arg), len);
+ regval = extract_unsigned_integer (val, len);
+ write_register (FP0_REGNUM + freg, regval);
freg++;
}
else
@@ -203,29 +225,32 @@
/* FIXME: Convert floats to doubles */
if (argoffset & 0x4)
argoffset += 4;
- write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + argoffset, val, len);
argoffset += 8;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ else if (len == 8
+ && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+ || (arch_info->mach == bfd_mach_ppc_e500
+ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
{
if (greg > 9)
{
greg = 11;
if (argoffset & 0x4)
argoffset += 4;
- write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + argoffset, val, len);
argoffset += 8;
}
else
{
+ ULONGEST regval;
if ((greg & 1) == 0)
greg++;
-
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)],
- VALUE_CONTENTS (arg), 4);
- memcpy (&deprecated_registers[REGISTER_BYTE (greg + 1)],
- VALUE_CONTENTS (arg) + 4, 4);
+ regval = extract_unsigned_integer (val, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, regval);
+ regval = extract_unsigned_integer (val + 4, 4);
+ write_register (tdep->ppc_gp0_regnum + greg + 1, regval);
greg += 2;
}
}
@@ -236,18 +261,19 @@
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION)
{
- write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+ write_memory (sp + structoffset, val, len);
store_address (val_buf, 4, sp + structoffset);
structoffset += round2 (len, 8);
}
else
{
memset (val_buf, 0, 4);
- memcpy (val_buf, VALUE_CONTENTS (arg), len);
+ memcpy (val_buf, val, len);
}
if (greg <= 10)
{
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+ ULONGEST regval = extract_unsigned_integer (val_buf, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, regval);
greg++;
}
else
@@ -262,15 +288,14 @@
&& 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);
+ memcpy (v_val_buf, val, len);
if (vreg <= 13)
{
- memcpy (&deprecated_registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
- + vreg)],
- v_val_buf, 16);
+ regcache_cooked_write (current_regcache,
+ tdep->ppc_vr0_regnum + vreg,
+ v_val_buf);
vreg++;
}
else
@@ -279,6 +304,26 @@
argoffset += 16;
}
}
+ else if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ char *v_val_buf = alloca (8);
+ memset (v_val_buf, 0, 8);
+ memcpy (v_val_buf, val, len);
+ if (greg <= 10)
+ {
+ regcache_cooked_write (current_regcache,
+ tdep->ppc_ev0_regnum + greg,
+ v_val_buf);
+ greg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, v_val_buf, 8);
+ argoffset += 8;
+ }
+ }
}
}
@@ -293,7 +338,7 @@
int
ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
{
- if (TYPE_LENGTH (value_type) == 16
+ if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
&& TYPE_VECTOR (value_type))
return 0;
@@ -305,7 +350,7 @@
int
ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
{
- if (TYPE_LENGTH (value_type) == 16
+ if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
&& TYPE_VECTOR (value_type))
return 0;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-08 19:11 [rfa] Add e500 function call support to PPC Andrew Cagney
@ 2003-03-09 1:00 ` Kevin Buettner
2003-03-10 15:11 ` Andrew Cagney
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2003-03-09 1:00 UTC (permalink / raw)
To: Andrew Cagney, gdb-patches
On Mar 8, 2:11pm, Andrew Cagney wrote:
> This adds support for the e500's function call convention to the PPC
> (ppc-sysv-tdep.c to be exact).
>
> The e500 passes everything in GPRs (which are extended to 64 bits).
>
[...]
> - if (TYPE_CODE (type) == TYPE_CODE_FLT)
> + if (TYPE_CODE (type) == TYPE_CODE_FLT
> + && arch_info->mach != bfd_mach_ppc_e500)
This construct bothers me. If it occurred only once, it might not
bother me so much, but (arch_info->mach != bfd_mach_ppc_e500) appears
far too often in the code for me to be comfortable with it. Suppose
we have another core with a similar property (of passing everything
in GPRs). If this happens, we'll end up with a proliferation of
additional checks for all of these different cores and things will
become quite unreadable. Please introduce a predicate into which
we can put this test and perhaps others as they arise. Then, only
the predicate will need to be modified.
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-09 1:00 ` Kevin Buettner
@ 2003-03-10 15:11 ` Andrew Cagney
2003-03-10 17:54 ` Kevin Buettner
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Cagney @ 2003-03-10 15:11 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
> On Mar 8, 2:11pm, Andrew Cagney wrote:
>
>
>> This adds support for the e500's function call convention to the PPC
>> (ppc-sysv-tdep.c to be exact).
>>
>> The e500 passes everything in GPRs (which are extended to 64 bits).
>>
>
> [...]
>
>> - if (TYPE_CODE (type) == TYPE_CODE_FLT)
>> + if (TYPE_CODE (type) == TYPE_CODE_FLT
>> + && arch_info->mach != bfd_mach_ppc_e500)
>
>
> This construct bothers me. If it occurred only once, it might not
> bother me so much, but (arch_info->mach != bfd_mach_ppc_e500) appears
> far too often in the code for me to be comfortable with it. Suppose
> we have another core with a similar property (of passing everything
> in GPRs). If this happens, we'll end up with a proliferation of
> additional checks for all of these different cores and things will
> become quite unreadable. Please introduce a predicate into which
> we can put this test and perhaps others as they arise. Then, only
> the predicate will need to be modified.
Such as:
if (.....
&& tdep->ppc_fp0_regnum >= 0)
?
Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-10 15:11 ` Andrew Cagney
@ 2003-03-10 17:54 ` Kevin Buettner
2003-03-10 19:56 ` Andrew Cagney
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2003-03-10 17:54 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
On Mar 10, 10:11am, Andrew Cagney wrote:
> > This construct bothers me. If it occurred only once, it might not
> > bother me so much, but (arch_info->mach != bfd_mach_ppc_e500) appears
> > far too often in the code for me to be comfortable with it. Suppose
> > we have another core with a similar property (of passing everything
> > in GPRs). If this happens, we'll end up with a proliferation of
> > additional checks for all of these different cores and things will
> > become quite unreadable. Please introduce a predicate into which
> > we can put this test and perhaps others as they arise. Then, only
> > the predicate will need to be modified.
>
> Such as:
>
> if (.....
> && tdep->ppc_fp0_regnum >= 0)
>
> ?
If the ppc's tdep struct had such a member that would probably be okay.
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-10 17:54 ` Kevin Buettner
@ 2003-03-10 19:56 ` Andrew Cagney
2003-03-10 21:47 ` Kevin Buettner
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Cagney @ 2003-03-10 19:56 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
> On Mar 10, 10:11am, Andrew Cagney wrote:
>
>
>> > This construct bothers me. If it occurred only once, it might not
>> > bother me so much, but (arch_info->mach != bfd_mach_ppc_e500) appears
>> > far too often in the code for me to be comfortable with it. Suppose
>> > we have another core with a similar property (of passing everything
>> > in GPRs). If this happens, we'll end up with a proliferation of
>> > additional checks for all of these different cores and things will
>> > become quite unreadable. Please introduce a predicate into which
>> > we can put this test and perhaps others as they arise. Then, only
>> > the predicate will need to be modified.
>
>>
>> Such as:
>>
>> if (.....
>> && tdep->ppc_fp0_regnum >= 0)
>>
>> ?
>
>
> If the ppc's tdep struct had such a member that would probably be okay.
It currently doesn't. However, it occured to me that it should be added
anyway. There is nothing indicating to the shared PPC code that the
e500 doesn't have FPRs.
Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-10 19:56 ` Andrew Cagney
@ 2003-03-10 21:47 ` Kevin Buettner
2003-03-17 16:59 ` Andrew Cagney
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2003-03-10 21:47 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
On Mar 10, 2:56pm, Andrew Cagney wrote:
> > On Mar 10, 10:11am, Andrew Cagney wrote:
> >
> >> > This construct bothers me. If it occurred only once, it might not
> >> > bother me so much, but (arch_info->mach != bfd_mach_ppc_e500) appears
> >> > far too often in the code for me to be comfortable with it. Suppose
> >> > we have another core with a similar property (of passing everything
> >> > in GPRs). If this happens, we'll end up with a proliferation of
> >> > additional checks for all of these different cores and things will
> >> > become quite unreadable. Please introduce a predicate into which
> >> > we can put this test and perhaps others as they arise. Then, only
> >> > the predicate will need to be modified.
> >
> >>
> >> Such as:
> >>
> >> if (.....
> >> && tdep->ppc_fp0_regnum >= 0)
> >>
> >> ?
> >
> > If the ppc's tdep struct had such a member that would probably be okay.
>
> It currently doesn't. However, it occured to me that it should be added
> anyway. There is nothing indicating to the shared PPC code that the
> e500 doesn't have FPRs.
For the time being, how about introducing a predicate (function) to
ppc-sysv-tdep.c (or perhaps rs6000-tdep.c) named
have_floating_point_registers_p() (or something along those lines).
In the short term this could be defined as:
int
have_floating_point_registers_p (struct gdbarch *gdbarch)
{
const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
/* Note: It has been proposed that a ``ppc_fp0_regnum'' member be added
to the ppc tdep struct. If/when this occurs, it may be preferable to
implement this as:
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
return tdep->ppc_fp0_regnum >= 0;
*/
return arch_info->mach != bfd_mach_ppc_e500;
}
It occurs to me that such a predicate would be useful for checking
the state of a global variable in the event that a command similar to
``set nomipsfpu'' were added for the powerpc. (Well, maybe. Then
again, maybe it'd be better to just set ppc_fp0_regnum to -1 when
such a setting were made.)
In any event, a name like have_floating_point_registers_p() is
reasonably self docuementing whereas ``tdep->ppc_fp0_regnum >= 0''
requires a little bit more thought to discern the meaning.
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-10 21:47 ` Kevin Buettner
@ 2003-03-17 16:59 ` Andrew Cagney
2003-03-17 17:45 ` Kevin Buettner
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Cagney @ 2003-03-17 16:59 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1463 bytes --]
> For the time being, how about introducing a predicate (function) to
> ppc-sysv-tdep.c (or perhaps rs6000-tdep.c) named
> have_floating_point_registers_p() (or something along those lines).
>
> In the short term this could be defined as:
>
> int
> have_floating_point_registers_p (struct gdbarch *gdbarch)
> {
> const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
>
> /* Note: It has been proposed that a ``ppc_fp0_regnum'' member be added
> to the ppc tdep struct. If/when this occurs, it may be preferable to
> implement this as:
>
> struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>
> return tdep->ppc_fp0_regnum >= 0;
> */
>
> return arch_info->mach != bfd_mach_ppc_e500;
> }
I called it ppc_floating_point_unit_p().
> It occurs to me that such a predicate would be useful for checking
> the state of a global variable in the event that a command similar to
> ``set nomipsfpu'' were added for the powerpc. (Well, maybe. Then
> again, maybe it'd be better to just set ppc_fp0_regnum to -1 when
> such a setting were made.)
It is definitly better than a ppc_fp0_regnum test. As with the MIPS,
it's one thing to have FP registers, it is another to use them.
> In any event, a name like have_floating_point_registers_p() is
> reasonably self docuementing whereas ``tdep->ppc_fp0_regnum >= 0''
> requires a little bit more thought to discern the meaning.
How about the attached?
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 9306 bytes --]
2003-03-17 Andrew Cagney <cagney@redhat.com>
* rs6000-tdep.c (ppc_floating_point_unit_p): New function.
* ppc-tdep.h (ppc_floating_point_unit_p): Declare.
From Elena Zannoni <ezannoni@redhat.com>
* ppc-sysv-tdep.c (ppc_sysv_abi_push_arguments): Handle e500
vector and floating-point parameters.
(ppc_sysv_abi_use_struct_convention): Handle e500 struct return
convention.
(ppc_sysv_abi_broken_use_struct_convention): Ditto.
Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.3
diff -u -r1.3 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c 14 Nov 2002 20:37:28 -0000 1.3
+++ ppc-sysv-tdep.c 17 Mar 2003 16:43:36 -0000
@@ -61,11 +61,12 @@
int structstkspace;
int argoffset;
int structoffset;
- struct value *arg;
struct type *type;
int len;
char old_sp_buf[4];
CORE_ADDR saved_sp;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
greg = struct_return ? 4 : 3;
freg = 1;
@@ -79,11 +80,12 @@
are put in registers. */
for (argno = 0; argno < nargs; argno++)
{
- arg = args[argno];
+ struct value *arg = args[argno];
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && ppc_floating_point_unit_p (current_gdbarch))
{
if (freg <= 8)
freg++;
@@ -96,7 +98,10 @@
argstkspace += 8;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ else if (len == 8
+ && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+ || (!ppc_floating_point_unit_p (current_gdbarch)
+ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
{
if (greg > 9)
{
@@ -144,6 +149,20 @@
argstkspace += 16;
}
}
+ else if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ if (greg <= 10)
+ greg++;
+ else
+ {
+ /* Vector arguments must be aligned to 8 bytes on
+ the stack. */
+ argstkspace += round2 (argstkspace, 8);
+ argstkspace += 8;
+ }
+ }
}
}
@@ -170,30 +189,33 @@
freg = 1;
greg = 3;
vreg = 2;
+
/* Fill in r3 with the return structure, if any */
if (struct_return)
{
- char val_buf[4];
- store_address (val_buf, 4, struct_addr);
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, struct_addr);
greg++;
}
+
/* Now fill in the registers and stack... */
for (argno = 0; argno < nargs; argno++)
{
- arg = args[argno];
+ struct value *arg = args[argno];
+ char *val = VALUE_CONTENTS (arg);
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && ppc_floating_point_unit_p (current_gdbarch))
{
if (freg <= 8)
{
+ ULONGEST regval;
if (len > 8)
printf_unfiltered (
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
- memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + freg)],
- VALUE_CONTENTS (arg), len);
+ regval = extract_unsigned_integer (val, len);
+ write_register (FP0_REGNUM + freg, regval);
freg++;
}
else
@@ -203,29 +225,32 @@
/* FIXME: Convert floats to doubles */
if (argoffset & 0x4)
argoffset += 4;
- write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + argoffset, val, len);
argoffset += 8;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ else if (len == 8
+ && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+ || (!ppc_floating_point_unit_p (current_gdbarch)
+ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
{
if (greg > 9)
{
greg = 11;
if (argoffset & 0x4)
argoffset += 4;
- write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + argoffset, val, len);
argoffset += 8;
}
else
{
+ ULONGEST regval;
if ((greg & 1) == 0)
greg++;
-
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)],
- VALUE_CONTENTS (arg), 4);
- memcpy (&deprecated_registers[REGISTER_BYTE (greg + 1)],
- VALUE_CONTENTS (arg) + 4, 4);
+ regval = extract_unsigned_integer (val, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, regval);
+ regval = extract_unsigned_integer (val + 4, 4);
+ write_register (tdep->ppc_gp0_regnum + greg + 1, regval);
greg += 2;
}
}
@@ -236,18 +261,19 @@
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION)
{
- write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+ write_memory (sp + structoffset, val, len);
store_address (val_buf, 4, sp + structoffset);
structoffset += round2 (len, 8);
}
else
{
memset (val_buf, 0, 4);
- memcpy (val_buf, VALUE_CONTENTS (arg), len);
+ memcpy (val_buf, val, len);
}
if (greg <= 10)
{
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+ ULONGEST regval = extract_unsigned_integer (val_buf, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, regval);
greg++;
}
else
@@ -262,15 +288,14 @@
&& 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);
+ memcpy (v_val_buf, val, len);
if (vreg <= 13)
{
- memcpy (&deprecated_registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
- + vreg)],
- v_val_buf, 16);
+ regcache_cooked_write (current_regcache,
+ tdep->ppc_vr0_regnum + vreg,
+ v_val_buf);
vreg++;
}
else
@@ -279,6 +304,26 @@
argoffset += 16;
}
}
+ else if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ char *v_val_buf = alloca (8);
+ memset (v_val_buf, 0, 8);
+ memcpy (v_val_buf, val, len);
+ if (greg <= 10)
+ {
+ regcache_cooked_write (current_regcache,
+ tdep->ppc_ev0_regnum + greg,
+ v_val_buf);
+ greg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, v_val_buf, 8);
+ argoffset += 8;
+ }
+ }
}
}
@@ -293,7 +338,7 @@
int
ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
{
- if (TYPE_LENGTH (value_type) == 16
+ if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
&& TYPE_VECTOR (value_type))
return 0;
@@ -305,7 +350,7 @@
int
ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
{
- if (TYPE_LENGTH (value_type) == 16
+ if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
&& TYPE_VECTOR (value_type))
return 0;
Index: ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.14
diff -u -r1.14 ppc-tdep.h
--- ppc-tdep.h 4 Jan 2003 23:38:45 -0000 1.14
+++ ppc-tdep.h 17 Mar 2003 16:43:36 -0000
@@ -49,6 +49,11 @@
CORE_ADDR rs6000_frame_chain (struct frame_info *);
int altivec_register_p (int regno);
+
+/* Return non-zero when the architecture has an FPU (or at least when
+ the ABI is using the FPU). */
+int ppc_floating_point_unit_p (struct gdbarch *gdbarch);
+
/* Private data that this module attaches to struct gdbarch. */
struct gdbarch_tdep
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.111
diff -u -r1.111 rs6000-tdep.c
--- rs6000-tdep.c 13 Mar 2003 21:45:41 -0000 1.111
+++ rs6000-tdep.c 17 Mar 2003 16:43:38 -0000
@@ -137,6 +137,18 @@
return (regno >= tdep->ppc_vr0_regnum && regno <= tdep->ppc_vrsave_regnum);
}
+/* Use the architectures FP registers? */
+int
+ppc_floating_point_unit_p (struct gdbarch *gdbarch)
+{
+ const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
+ if (info->arch == bfd_arch_powerpc)
+ return (info->mach != bfd_mach_ppc_e500);
+ if (info->arch == bfd_arch_rs6000)
+ return 1;
+ return 0;
+}
+
/* Read a LEN-byte address from debugged memory address MEMADDR. */
static CORE_ADDR
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-17 16:59 ` Andrew Cagney
@ 2003-03-17 17:45 ` Kevin Buettner
2003-03-17 18:28 ` Andrew Cagney
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2003-03-17 17:45 UTC (permalink / raw)
To: Andrew Cagney, Kevin Buettner; +Cc: gdb-patches
On Mar 17, 11:59am, Andrew Cagney wrote:
> How about the attached?
>
> 2003-03-17 Andrew Cagney <cagney@redhat.com>
>
> * rs6000-tdep.c (ppc_floating_point_unit_p): New function.
> * ppc-tdep.h (ppc_floating_point_unit_p): Declare.
>
> From Elena Zannoni <ezannoni@redhat.com>
> * ppc-sysv-tdep.c (ppc_sysv_abi_push_arguments): Handle e500
> vector and floating-point parameters.
> (ppc_sysv_abi_use_struct_convention): Handle e500 struct return
> convention.
> (ppc_sysv_abi_broken_use_struct_convention): Ditto.
>
> Index: ppc-sysv-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
> retrieving revision 1.3
> diff -u -r1.3 ppc-sysv-tdep.c
> --- ppc-sysv-tdep.c 14 Nov 2002 20:37:28 -0000 1.3
> +++ ppc-sysv-tdep.c 17 Mar 2003 16:43:36 -0000
> @@ -61,11 +61,12 @@
> int structstkspace;
> int argoffset;
> int structoffset;
> - struct value *arg;
> struct type *type;
> int len;
> char old_sp_buf[4];
> CORE_ADDR saved_sp;
> + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
> + const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
Now that you've introduced ppc_floating_point_unit_p(), I don't
think that arch_info is needed any longer.
Otherwise, okay.
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [rfa] Add e500 function call support to PPC
2003-03-17 17:45 ` Kevin Buettner
@ 2003-03-17 18:28 ` Andrew Cagney
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Cagney @ 2003-03-17 18:28 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 573 bytes --]
> int structstkspace;
>> int argoffset;
>> int structoffset;
>> - struct value *arg;
>> struct type *type;
>> int len;
>> char old_sp_buf[4];
>> CORE_ADDR saved_sp;
>> + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
>> + const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
>
>
> Now that you've introduced ppc_floating_point_unit_p(), I don't
> think that arch_info is needed any longer.
Good point (need to get -Wunused-local building). Removed.
> Otherwise, okay.
Checked in the attached.
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 9222 bytes --]
2003-03-17 Andrew Cagney <cagney@redhat.com>
* rs6000-tdep.c (ppc_floating_point_unit_p): New function.
* ppc-tdep.h (ppc_floating_point_unit_p): Declare.
From Elena Zannoni <ezannoni@redhat.com>
* ppc-sysv-tdep.c (ppc_sysv_abi_push_arguments): Handle e500
vector and floating-point parameters.
(ppc_sysv_abi_use_struct_convention): Handle e500 struct return
convention.
(ppc_sysv_abi_broken_use_struct_convention): Ditto.
Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.3
diff -u -r1.3 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c 14 Nov 2002 20:37:28 -0000 1.3
+++ ppc-sysv-tdep.c 17 Mar 2003 18:25:58 -0000
@@ -61,11 +61,11 @@
int structstkspace;
int argoffset;
int structoffset;
- struct value *arg;
struct type *type;
int len;
char old_sp_buf[4];
CORE_ADDR saved_sp;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
greg = struct_return ? 4 : 3;
freg = 1;
@@ -79,11 +79,12 @@
are put in registers. */
for (argno = 0; argno < nargs; argno++)
{
- arg = args[argno];
+ struct value *arg = args[argno];
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && ppc_floating_point_unit_p (current_gdbarch))
{
if (freg <= 8)
freg++;
@@ -96,7 +97,10 @@
argstkspace += 8;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ else if (len == 8
+ && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+ || (!ppc_floating_point_unit_p (current_gdbarch)
+ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
{
if (greg > 9)
{
@@ -144,6 +148,20 @@
argstkspace += 16;
}
}
+ else if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ if (greg <= 10)
+ greg++;
+ else
+ {
+ /* Vector arguments must be aligned to 8 bytes on
+ the stack. */
+ argstkspace += round2 (argstkspace, 8);
+ argstkspace += 8;
+ }
+ }
}
}
@@ -170,30 +188,33 @@
freg = 1;
greg = 3;
vreg = 2;
+
/* Fill in r3 with the return structure, if any */
if (struct_return)
{
- char val_buf[4];
- store_address (val_buf, 4, struct_addr);
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, struct_addr);
greg++;
}
+
/* Now fill in the registers and stack... */
for (argno = 0; argno < nargs; argno++)
{
- arg = args[argno];
+ struct value *arg = args[argno];
+ char *val = VALUE_CONTENTS (arg);
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && ppc_floating_point_unit_p (current_gdbarch))
{
if (freg <= 8)
{
+ ULONGEST regval;
if (len > 8)
printf_unfiltered (
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
- memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + freg)],
- VALUE_CONTENTS (arg), len);
+ regval = extract_unsigned_integer (val, len);
+ write_register (FP0_REGNUM + freg, regval);
freg++;
}
else
@@ -203,29 +224,32 @@
/* FIXME: Convert floats to doubles */
if (argoffset & 0x4)
argoffset += 4;
- write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + argoffset, val, len);
argoffset += 8;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ else if (len == 8
+ && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
+ || (!ppc_floating_point_unit_p (current_gdbarch)
+ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */
{
if (greg > 9)
{
greg = 11;
if (argoffset & 0x4)
argoffset += 4;
- write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + argoffset, val, len);
argoffset += 8;
}
else
{
+ ULONGEST regval;
if ((greg & 1) == 0)
greg++;
-
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)],
- VALUE_CONTENTS (arg), 4);
- memcpy (&deprecated_registers[REGISTER_BYTE (greg + 1)],
- VALUE_CONTENTS (arg) + 4, 4);
+ regval = extract_unsigned_integer (val, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, regval);
+ regval = extract_unsigned_integer (val + 4, 4);
+ write_register (tdep->ppc_gp0_regnum + greg + 1, regval);
greg += 2;
}
}
@@ -236,18 +260,19 @@
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION)
{
- write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+ write_memory (sp + structoffset, val, len);
store_address (val_buf, 4, sp + structoffset);
structoffset += round2 (len, 8);
}
else
{
memset (val_buf, 0, 4);
- memcpy (val_buf, VALUE_CONTENTS (arg), len);
+ memcpy (val_buf, val, len);
}
if (greg <= 10)
{
- memcpy (&deprecated_registers[REGISTER_BYTE (greg)], val_buf, 4);
+ ULONGEST regval = extract_unsigned_integer (val_buf, 4);
+ write_register (tdep->ppc_gp0_regnum + greg, regval);
greg++;
}
else
@@ -262,15 +287,14 @@
&& 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);
+ memcpy (v_val_buf, val, len);
if (vreg <= 13)
{
- memcpy (&deprecated_registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
- + vreg)],
- v_val_buf, 16);
+ regcache_cooked_write (current_regcache,
+ tdep->ppc_vr0_regnum + vreg,
+ v_val_buf);
vreg++;
}
else
@@ -279,6 +303,26 @@
argoffset += 16;
}
}
+ else if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ char *v_val_buf = alloca (8);
+ memset (v_val_buf, 0, 8);
+ memcpy (v_val_buf, val, len);
+ if (greg <= 10)
+ {
+ regcache_cooked_write (current_regcache,
+ tdep->ppc_ev0_regnum + greg,
+ v_val_buf);
+ greg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, v_val_buf, 8);
+ argoffset += 8;
+ }
+ }
}
}
@@ -293,7 +337,7 @@
int
ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
{
- if (TYPE_LENGTH (value_type) == 16
+ if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
&& TYPE_VECTOR (value_type))
return 0;
@@ -305,7 +349,7 @@
int
ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
{
- if (TYPE_LENGTH (value_type) == 16
+ if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
&& TYPE_VECTOR (value_type))
return 0;
Index: ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.14
diff -u -r1.14 ppc-tdep.h
--- ppc-tdep.h 4 Jan 2003 23:38:45 -0000 1.14
+++ ppc-tdep.h 17 Mar 2003 18:25:58 -0000
@@ -49,6 +49,11 @@
CORE_ADDR rs6000_frame_chain (struct frame_info *);
int altivec_register_p (int regno);
+
+/* Return non-zero when the architecture has an FPU (or at least when
+ the ABI is using the FPU). */
+int ppc_floating_point_unit_p (struct gdbarch *gdbarch);
+
/* Private data that this module attaches to struct gdbarch. */
struct gdbarch_tdep
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.111
diff -u -r1.111 rs6000-tdep.c
--- rs6000-tdep.c 13 Mar 2003 21:45:41 -0000 1.111
+++ rs6000-tdep.c 17 Mar 2003 18:25:58 -0000
@@ -137,6 +137,18 @@
return (regno >= tdep->ppc_vr0_regnum && regno <= tdep->ppc_vrsave_regnum);
}
+/* Use the architectures FP registers? */
+int
+ppc_floating_point_unit_p (struct gdbarch *gdbarch)
+{
+ const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
+ if (info->arch == bfd_arch_powerpc)
+ return (info->mach != bfd_mach_ppc_e500);
+ if (info->arch == bfd_arch_rs6000)
+ return 1;
+ return 0;
+}
+
/* Read a LEN-byte address from debugged memory address MEMADDR. */
static CORE_ADDR
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2003-03-17 18:28 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-08 19:11 [rfa] Add e500 function call support to PPC Andrew Cagney
2003-03-09 1:00 ` Kevin Buettner
2003-03-10 15:11 ` Andrew Cagney
2003-03-10 17:54 ` Kevin Buettner
2003-03-10 19:56 ` Andrew Cagney
2003-03-10 21:47 ` Kevin Buettner
2003-03-17 16:59 ` Andrew Cagney
2003-03-17 17:45 ` Kevin Buettner
2003-03-17 18:28 ` Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox