* [rfa:ppc64] Fix return value
@ 2003-09-21 0:36 Andrew Cagney
2003-09-22 23:23 ` Kevin Buettner
0 siblings, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2003-09-21 0:36 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1891 bytes --]
Hello,
The attached impements PPC64 SYSV specific versions of:
use_struct_convention
extract_return_value
store_return_value
It fixes:
gdb.base/return2.exp: char value returned successfully
gdb.base/return2.exp: int value returned successfully
gdb.base/return2.exp: short value returned successfully
gdb.base/structs.exp: p fun1
gdb.base/structs.exp: p fun2
gdb.base/structs.exp: p fun3
gdb.base/structs.exp: p fun4
gdb.base/structs.exp: p fun5
gdb.base/structs.exp: p fun6
gdb.base/structs.exp: p fun7
gdb.base/structs.exp: p fun8
gdb.c++/userdef.exp: print !one
gdb.c++/userdef.exp: print -one
gdb.c++/userdef.exp: print one != two
gdb.c++/userdef.exp: print one % two
gdb.c++/userdef.exp: print one & two
gdb.c++/userdef.exp: print one && two
gdb.c++/userdef.exp: print one * two
gdb.c++/userdef.exp: print one + two
gdb.c++/userdef.exp: print one - two
gdb.c++/userdef.exp: print one / two
gdb.c++/userdef.exp: print one < two
gdb.c++/userdef.exp: print one << 31
gdb.c++/userdef.exp: print one <= two
gdb.c++/userdef.exp: print one == two
gdb.c++/userdef.exp: print one > two
gdb.c++/userdef.exp: print one >= two
gdb.c++/userdef.exp: print one >> 31
gdb.c++/userdef.exp: print one ^ two
gdb.c++/userdef.exp: print one | two
gdb.c++/userdef.exp: print one || two
gdb.c++/userdef.exp: print ~one
gdb.c++/userdef.exp: re-selected 'main' frame after inferior call
Note the way I implemented it - the above wrap a generic
ppc64_sysv_abi_return_value function and that handles all cases. I was
finding that the more traditional technique (per my ppc post) was too
error proned. Converting it to this style caused several mysterious
regressions to mysteriously disappear.
I'm thinking of proposing that this technique become the norm.
Anyway, ok to commit?
Andrew
PS: I should note that PPC64's call function code is still on life
support - it's not in a good shape at all.
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 9098 bytes --]
2003-09-20 Andrew Cagney <cagney@redhat.com>
* rs6000-tdep.c (rs6000_gdbarch_init): When the 64 bit SysV ABI,
set extract_return_value, store_return_value and
use_struct_convention to ppc64_sysv_abi_extract_return_value,
ppc64_sysv_abi_store_return_value and
ppc64_sysv_abi_use_struct_convention.
* ppc-tdep.h (ppc64_sysv_abi_extract_return_value): Declare.
(ppc64_sysv_abi_store_return_value): Declare.
(ppc64_sysv_abi_use_struct_convention): Declare.
* ppc-sysv-tdep.c (ppc64_sysv_abi_extract_return_value): New
function.
(ppc64_sysv_abi_store_return_value): New function.
(ppc64_sysv_abi_use_struct_convention): New function.
(ppc64_sysv_abi_return_value): New function.
Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.12
diff -u -r1.12 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c 19 Sep 2003 16:22:39 -0000 1.12
+++ ppc-sysv-tdep.c 21 Sep 2003 00:06:28 -0000
@@ -325,3 +325,180 @@
return (TYPE_LENGTH (value_type) > 8);
}
+
+
+/* The 64 bit ABI retun value convention.
+
+ Return non-zero if the return-value is stored in a register, return
+ 0 if the return-value is instead stored on the stack (a.k.a.,
+ struct return convention).
+
+ For a return-value stored in a register: when INVAL is non-NULL,
+ copy the buffer to the corresponding register return-value location
+ location; when OUTVAL is non-NULL, fill the buffer from the
+ corresponding register return-value location. */
+
+static int
+ppc64_sysv_abi_return_value (struct type *valtype, struct regcache *regcache,
+ const void *inval, void *outval)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ /* Floats and doubles in F1. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT
+ && TYPE_LENGTH (valtype) <= 8)
+ {
+ char regval[MAX_REGISTER_SIZE];
+ struct type *regtype = register_type (current_gdbarch, FP0_REGNUM);
+ if (inval != NULL)
+ {
+ convert_typed_floating (inval, valtype, regval, regtype);
+ regcache_cooked_write (regcache, FP0_REGNUM + 1, regval);
+ }
+ if (outval != NULL)
+ {
+ regcache_cooked_read (regcache, FP0_REGNUM + 1, regval);
+ convert_typed_floating (regval, regtype, outval, valtype);
+ }
+ return 1;
+ }
+ if (TYPE_CODE (valtype) == TYPE_CODE_INT
+ && TYPE_LENGTH (valtype) <= 8)
+ {
+ /* Integers in r3. */
+ if (inval != NULL)
+ {
+ /* Be careful to sign extend the value. */
+ regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
+ unpack_long (valtype, inval));
+ }
+ if (outval != NULL)
+ {
+ /* Extract the integer from r3. Since this is truncating the
+ value, there isn't a sign extension problem. */
+ ULONGEST regval;
+ regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
+ ®val);
+ store_unsigned_integer (outval, TYPE_LENGTH (valtype), regval);
+ }
+ return 1;
+ }
+ /* All pointers live in r3. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_PTR)
+ {
+ /* All pointers live in r3. */
+ if (inval != NULL)
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, inval);
+ if (outval != NULL)
+ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, outval);
+ return 1;
+ }
+ if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
+ && TYPE_LENGTH (valtype) <= 8
+ && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1)
+ {
+ /* Small character arrays are returned, right justified, in r3. */
+ int offset = (register_size (current_gdbarch, tdep->ppc_gp0_regnum + 3)
+ - TYPE_LENGTH (valtype));
+ if (inval != NULL)
+ regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3,
+ offset, TYPE_LENGTH (valtype), inval);
+ if (outval != NULL)
+ regcache_cooked_read_part (regcache, tdep->ppc_gp0_regnum + 3,
+ offset, TYPE_LENGTH (valtype), outval);
+ return 1;
+ }
+ /* Big floating point values get stored in adjacent floating
+ point registers. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT
+ && (TYPE_LENGTH (valtype) == 16
+ || TYPE_LENGTH (valtype) == 32))
+ {
+ if (inval || outval != NULL)
+ {
+ int i;
+ for (i = 0; i < TYPE_LENGTH (valtype) / 8; i++)
+ {
+ if (inval != NULL)
+ regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+ (const bfd_byte *) inval + i * 8);
+ if (outval != NULL)
+ regcache_cooked_read (regcache, FP0_REGNUM + 1 + i,
+ (bfd_byte *) outval + i * 8);
+ }
+ }
+ return 1;
+ }
+ /* Complex values get returned in f1:f2, need to convert. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX
+ && (TYPE_LENGTH (valtype) == 8 || TYPE_LENGTH (valtype) == 16))
+ {
+ if (regcache != NULL)
+ {
+ int i;
+ for (i = 0; i < 2; i++)
+ {
+ char regval[MAX_REGISTER_SIZE];
+ struct type *regtype = register_type (current_gdbarch, FP0_REGNUM);
+ if (inval != NULL)
+ {
+ convert_typed_floating ((const bfd_byte *) inval + i * (TYPE_LENGTH (valtype) / 2),
+ valtype, regval, regtype);
+ regcache_cooked_write (regcache, FP0_REGNUM + 1 + i, regval);
+ }
+ if (outval != NULL)
+ {
+ regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, regval);
+ convert_typed_floating (regval, regtype,
+ (bfd_byte *) outval + i * (TYPE_LENGTH (valtype) / 2),
+ valtype);
+ }
+ }
+ }
+ return 1;
+ }
+ /* Big complex values get stored in f1:f4. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX
+ && TYPE_LENGTH (valtype) == 32)
+ {
+ if (regcache != NULL)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ if (inval != NULL)
+ regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+ (const bfd_byte *) inval + i * 8);
+ if (outval != NULL)
+ regcache_cooked_read (regcache, FP0_REGNUM + 1 + i,
+ (bfd_byte *) outval + i * 8);
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int
+ppc64_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ return !ppc64_sysv_abi_return_value (value_type, NULL, NULL, NULL);
+}
+
+void
+ppc64_sysv_abi_extract_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ void *valbuf)
+{
+ if (!ppc64_sysv_abi_return_value (valtype, regbuf, NULL, valbuf))
+ error ("Function return value unknown");
+}
+
+void
+ppc64_sysv_abi_store_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ const void *valbuf)
+{
+ if (!ppc64_sysv_abi_return_value (valtype, regbuf, valbuf, NULL))
+ error ("Function return value location unknown");
+}
Index: ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.18
diff -u -r1.18 ppc-tdep.h
--- ppc-tdep.h 14 Sep 2003 02:04:44 -0000 1.18
+++ ppc-tdep.h 21 Sep 2003 00:06:28 -0000
@@ -47,6 +47,14 @@
void ppc_linux_supply_gregset (char *buf);
void ppc_linux_supply_fpregset (char *buf);
+int ppc64_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type);
+void ppc64_sysv_abi_extract_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ void *valbuf);
+void ppc64_sysv_abi_store_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ const void *valbuf);
+
/* From rs6000-tdep.c... */
CORE_ADDR rs6000_frame_saved_pc (struct frame_info *fi);
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.161
diff -u -r1.161 rs6000-tdep.c
--- rs6000-tdep.c 17 Sep 2003 14:24:30 -0000 1.161
+++ rs6000-tdep.c 21 Sep 2003 00:06:29 -0000
@@ -2830,9 +2830,16 @@
set_gdbarch_pc_regnum (gdbarch, 64);
set_gdbarch_sp_regnum (gdbarch, 1);
set_gdbarch_deprecated_fp_regnum (gdbarch, 1);
- set_gdbarch_deprecated_extract_return_value (gdbarch,
- rs6000_extract_return_value);
- set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+ if (sysv_abi && wordsize == 8)
+ {
+ set_gdbarch_extract_return_value (gdbarch, ppc64_sysv_abi_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, ppc64_sysv_abi_store_return_value);
+ }
+ else
+ {
+ set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value);
+ set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+ }
if (v->arch == bfd_arch_powerpc)
switch (v->mach)
@@ -2964,9 +2971,11 @@
/* Not sure on this. FIXMEmgo */
set_gdbarch_frame_args_skip (gdbarch, 8);
- if (sysv_abi)
+ if (sysv_abi && wordsize == 4)
set_gdbarch_use_struct_convention (gdbarch,
ppc_sysv_abi_use_struct_convention);
+ else if (sysv_abi && wordsize == 8)
+ set_gdbarch_use_struct_convention (gdbarch, ppc64_sysv_abi_use_struct_convention);
else
set_gdbarch_use_struct_convention (gdbarch,
rs6000_use_struct_convention);
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [rfa:ppc64] Fix return value
2003-09-21 0:36 [rfa:ppc64] Fix return value Andrew Cagney
@ 2003-09-22 23:23 ` Kevin Buettner
2003-10-03 21:10 ` Andrew Cagney
0 siblings, 1 reply; 4+ messages in thread
From: Kevin Buettner @ 2003-09-22 23:23 UTC (permalink / raw)
To: Andrew Cagney, gdb-patches
On Sep 20, 8:36pm, Andrew Cagney wrote:
> Note the way I implemented it - the above wrap a generic
> ppc64_sysv_abi_return_value function and that handles all cases. I was
Nice.
> finding that the more traditional technique (per my ppc post) was too
> error proned. Converting it to this style caused several mysterious
> regressions to mysteriously disappear.
>
> I'm thinking of proposing that this technique become the norm.
>
> Anyway, ok to commit?
Yes, okay.
Kevin
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [rfa:ppc64] Fix return value
2003-09-22 23:23 ` Kevin Buettner
@ 2003-10-03 21:10 ` Andrew Cagney
2003-10-03 21:23 ` Kevin Buettner
0 siblings, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2003-10-03 21:10 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 755 bytes --]
> On Sep 20, 8:36pm, Andrew Cagney wrote:
>
>
>> Note the way I implemented it - the above wrap a generic
>> ppc64_sysv_abi_return_value function and that handles all cases. I was
>
>
> Nice.
>
>
>> finding that the more traditional technique (per my ppc post) was too
>> error proned. Converting it to this style caused several mysterious
>> regressions to mysteriously disappear.
>>
>> I'm thinking of proposing that this technique become the norm.
>>
>> Anyway, ok to commit?
>
>
> Yes, okay.
I've committed it with one tweak. The ..._return_value() method now
returns "enum return_value_convention" instead of an int. This is to
better align its function signature with the new gdbarch_return_value
method I've posted.
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 10131 bytes --]
2003-10-03 Andrew Cagney <cagney@redhat.com>
* rs6000-tdep.c (rs6000_gdbarch_init): When the 64 bit SysV ABI,
set extract_return_value, store_return_value and
use_struct_convention to ppc64_sysv_abi_extract_return_value,
ppc64_sysv_abi_store_return_value and
ppc64_sysv_abi_use_struct_convention.
* ppc-tdep.h (ppc64_sysv_abi_extract_return_value): Declare.
(ppc64_sysv_abi_store_return_value): Declare.
(ppc64_sysv_abi_use_struct_convention): Declare.
* ppc-sysv-tdep.c (enum return_value_convention): Define.
(ppc64_sysv_abi_extract_return_value): New function.
(ppc64_sysv_abi_store_return_value): New function.
(ppc64_sysv_abi_use_struct_convention): New function.
(ppc64_sysv_abi_return_value): New function.
Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.12
diff -u -r1.12 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c 19 Sep 2003 16:22:39 -0000 1.12
+++ ppc-sysv-tdep.c 3 Oct 2003 21:02:58 -0000
@@ -325,3 +325,197 @@
return (TYPE_LENGTH (value_type) > 8);
}
+
+
+/* The 64 bit ABI retun value convention.
+
+ Return non-zero if the return-value is stored in a register, return
+ 0 if the return-value is instead stored on the stack (a.k.a.,
+ struct return convention).
+
+ For a return-value stored in a register: when INVAL is non-NULL,
+ copy the buffer to the corresponding register return-value location
+ location; when OUTVAL is non-NULL, fill the buffer from the
+ corresponding register return-value location. */
+
+/* Potential ways that a function can return a value of a given type. */
+enum return_value_convention
+{
+ /* Where the return value has been squeezed into one or more
+ registers. */
+ RETURN_VALUE_REGISTER_CONVENTION,
+ /* Commonly known as the "struct return convention". The caller
+ passes an additional hidden first parameter to the caller. That
+ parameter contains the address at which the value being returned
+ should be stored. While typically, and historically, used for
+ large structs, this is convention is applied to values of many
+ different types. */
+ RETURN_VALUE_STRUCT_CONVENTION
+};
+
+static enum return_value_convention
+ppc64_sysv_abi_return_value (struct type *valtype, struct regcache *regcache,
+ const void *inval, void *outval)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ /* Floats and doubles in F1. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT
+ && TYPE_LENGTH (valtype) <= 8)
+ {
+ char regval[MAX_REGISTER_SIZE];
+ struct type *regtype = register_type (current_gdbarch, FP0_REGNUM);
+ if (inval != NULL)
+ {
+ convert_typed_floating (inval, valtype, regval, regtype);
+ regcache_cooked_write (regcache, FP0_REGNUM + 1, regval);
+ }
+ if (outval != NULL)
+ {
+ regcache_cooked_read (regcache, FP0_REGNUM + 1, regval);
+ convert_typed_floating (regval, regtype, outval, valtype);
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ if (TYPE_CODE (valtype) == TYPE_CODE_INT
+ && TYPE_LENGTH (valtype) <= 8)
+ {
+ /* Integers in r3. */
+ if (inval != NULL)
+ {
+ /* Be careful to sign extend the value. */
+ regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
+ unpack_long (valtype, inval));
+ }
+ if (outval != NULL)
+ {
+ /* Extract the integer from r3. Since this is truncating the
+ value, there isn't a sign extension problem. */
+ ULONGEST regval;
+ regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
+ ®val);
+ store_unsigned_integer (outval, TYPE_LENGTH (valtype), regval);
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ /* All pointers live in r3. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_PTR)
+ {
+ /* All pointers live in r3. */
+ if (inval != NULL)
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, inval);
+ if (outval != NULL)
+ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, outval);
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
+ && TYPE_LENGTH (valtype) <= 8
+ && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1)
+ {
+ /* Small character arrays are returned, right justified, in r3. */
+ int offset = (register_size (current_gdbarch, tdep->ppc_gp0_regnum + 3)
+ - TYPE_LENGTH (valtype));
+ if (inval != NULL)
+ regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3,
+ offset, TYPE_LENGTH (valtype), inval);
+ if (outval != NULL)
+ regcache_cooked_read_part (regcache, tdep->ppc_gp0_regnum + 3,
+ offset, TYPE_LENGTH (valtype), outval);
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ /* Big floating point values get stored in adjacent floating
+ point registers. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT
+ && (TYPE_LENGTH (valtype) == 16
+ || TYPE_LENGTH (valtype) == 32))
+ {
+ if (inval || outval != NULL)
+ {
+ int i;
+ for (i = 0; i < TYPE_LENGTH (valtype) / 8; i++)
+ {
+ if (inval != NULL)
+ regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+ (const bfd_byte *) inval + i * 8);
+ if (outval != NULL)
+ regcache_cooked_read (regcache, FP0_REGNUM + 1 + i,
+ (bfd_byte *) outval + i * 8);
+ }
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ /* Complex values get returned in f1:f2, need to convert. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX
+ && (TYPE_LENGTH (valtype) == 8 || TYPE_LENGTH (valtype) == 16))
+ {
+ if (regcache != NULL)
+ {
+ int i;
+ for (i = 0; i < 2; i++)
+ {
+ char regval[MAX_REGISTER_SIZE];
+ struct type *regtype = register_type (current_gdbarch, FP0_REGNUM);
+ if (inval != NULL)
+ {
+ convert_typed_floating ((const bfd_byte *) inval + i * (TYPE_LENGTH (valtype) / 2),
+ valtype, regval, regtype);
+ regcache_cooked_write (regcache, FP0_REGNUM + 1 + i, regval);
+ }
+ if (outval != NULL)
+ {
+ regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, regval);
+ convert_typed_floating (regval, regtype,
+ (bfd_byte *) outval + i * (TYPE_LENGTH (valtype) / 2),
+ valtype);
+ }
+ }
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ /* Big complex values get stored in f1:f4. */
+ if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX
+ && TYPE_LENGTH (valtype) == 32)
+ {
+ if (regcache != NULL)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ if (inval != NULL)
+ regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+ (const bfd_byte *) inval + i * 8);
+ if (outval != NULL)
+ regcache_cooked_read (regcache, FP0_REGNUM + 1 + i,
+ (bfd_byte *) outval + i * 8);
+ }
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ return RETURN_VALUE_STRUCT_CONVENTION;
+}
+
+int
+ppc64_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ return (ppc64_sysv_abi_return_value (value_type, NULL, NULL, NULL)
+ == RETURN_VALUE_STRUCT_CONVENTION);
+}
+
+void
+ppc64_sysv_abi_extract_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ void *valbuf)
+{
+ if (ppc64_sysv_abi_return_value (valtype, regbuf, NULL, valbuf)
+ != RETURN_VALUE_REGISTER_CONVENTION)
+ error ("Function return value unknown");
+}
+
+void
+ppc64_sysv_abi_store_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ const void *valbuf)
+{
+ if (!ppc64_sysv_abi_return_value (valtype, regbuf, valbuf, NULL))
+ error ("Function return value location unknown");
+}
Index: ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.18
diff -u -r1.18 ppc-tdep.h
--- ppc-tdep.h 14 Sep 2003 02:04:44 -0000 1.18
+++ ppc-tdep.h 3 Oct 2003 21:02:58 -0000
@@ -47,6 +47,14 @@
void ppc_linux_supply_gregset (char *buf);
void ppc_linux_supply_fpregset (char *buf);
+int ppc64_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type);
+void ppc64_sysv_abi_extract_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ void *valbuf);
+void ppc64_sysv_abi_store_return_value (struct type *valtype,
+ struct regcache *regbuf,
+ const void *valbuf);
+
/* From rs6000-tdep.c... */
CORE_ADDR rs6000_frame_saved_pc (struct frame_info *fi);
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.165
diff -u -r1.165 rs6000-tdep.c
--- rs6000-tdep.c 2 Oct 2003 20:28:30 -0000 1.165
+++ rs6000-tdep.c 3 Oct 2003 21:02:59 -0000
@@ -2830,9 +2830,16 @@
set_gdbarch_pc_regnum (gdbarch, 64);
set_gdbarch_sp_regnum (gdbarch, 1);
set_gdbarch_deprecated_fp_regnum (gdbarch, 1);
- set_gdbarch_deprecated_extract_return_value (gdbarch,
- rs6000_extract_return_value);
- set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+ if (sysv_abi && wordsize == 8)
+ {
+ set_gdbarch_extract_return_value (gdbarch, ppc64_sysv_abi_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, ppc64_sysv_abi_store_return_value);
+ }
+ else
+ {
+ set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value);
+ set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+ }
if (v->arch == bfd_arch_powerpc)
switch (v->mach)
@@ -2967,9 +2974,11 @@
/* Not sure on this. FIXMEmgo */
set_gdbarch_frame_args_skip (gdbarch, 8);
- if (sysv_abi)
+ if (sysv_abi && wordsize == 4)
set_gdbarch_use_struct_convention (gdbarch,
ppc_sysv_abi_use_struct_convention);
+ else if (sysv_abi && wordsize == 8)
+ set_gdbarch_use_struct_convention (gdbarch, ppc64_sysv_abi_use_struct_convention);
else
set_gdbarch_use_struct_convention (gdbarch,
rs6000_use_struct_convention);
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [rfa:ppc64] Fix return value
2003-10-03 21:10 ` Andrew Cagney
@ 2003-10-03 21:23 ` Kevin Buettner
0 siblings, 0 replies; 4+ messages in thread
From: Kevin Buettner @ 2003-10-03 21:23 UTC (permalink / raw)
To: Andrew Cagney, Kevin Buettner; +Cc: gdb-patches
On Oct 3, 5:10pm, Andrew Cagney wrote:
> >> Anyway, ok to commit?
> >
> > Yes, okay.
>
> I've committed it with one tweak. The ..._return_value() method now
> returns "enum return_value_convention" instead of an int. This is to
> better align its function signature with the new gdbarch_return_value
> method I've posted.
Sounds good.
Kevin
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-10-03 21:23 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-21 0:36 [rfa:ppc64] Fix return value Andrew Cagney
2003-09-22 23:23 ` Kevin Buettner
2003-10-03 21:10 ` Andrew Cagney
2003-10-03 21:23 ` Kevin Buettner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox