* [RFC/RFA] MIPS extract_return_value
@ 2004-06-04 1:38 Michael Snyder
2004-06-07 15:22 ` Andrew Cagney
0 siblings, 1 reply; 3+ messages in thread
From: Michael Snyder @ 2004-06-04 1:38 UTC (permalink / raw)
To: Andrew Cagney, gdb-patches, drow
[-- Attachment #1: Type: text/plain, Size: 768 bytes --]
Hey Andrew, Daniel,
I encountered another problem with 32/64 bit mips. Don't know if this
is the right way to fix it, but it illustrates it (and fixes several
hundred failures).
The problem is that extract_return_value and store_return_value both
call return_value_location, but then one of them uses the raw register
and the other uses the cooked register (which are not the same size).
So the offset into the register cache, computed by
return_value_location, has to be wrong for one of them.
The simple-minded approach I've taken below is to add a parameter
to return_value_location, telling it whether to use the raw or cooked
registers. I've only tested it on one architecture (isa64 with gcc
-mips32), so consider it more of a suggestion than a patch.
[-- Attachment #2: mips3 --]
[-- Type: text/plain, Size: 5629 bytes --]
2004-06-04 Michael Snyder <msnyder@redhat.com>
* mips-tdep.c (return_value_location): New parameter specifies
whether to use raw registers (for store_return_value), or
cooked registers (for extract_return_value).
(mips_eabi_extract_return_value): Add new parameter for above.
(mips_o64_extract_return_value): Ditto.
(mips_eabi_store_return_value): Ditto.
(mips_o64_store_return_value): Ditto.
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.294
diff -p -r1.294 mips-tdep.c
*** mips-tdep.c 3 May 2004 22:20:18 -0000 1.294
--- mips-tdep.c 4 Jun 2004 01:26:40 -0000
*************** struct return_value_word
*** 2638,2647 ****
int buf_offset;
};
static void
return_value_location (struct type *valtype,
struct return_value_word *hi,
! struct return_value_word *lo)
{
int len = TYPE_LENGTH (valtype);
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
--- 2638,2653 ----
int buf_offset;
};
+ enum {
+ STORE_RAW,
+ EXTRACT_COOKED
+ };
+
static void
return_value_location (struct type *valtype,
struct return_value_word *hi,
! struct return_value_word *lo,
! int storextract)
{
int len = TYPE_LENGTH (valtype);
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
*************** return_value_location (struct type *valt
*** 2663,2668 ****
--- 2669,2679 ----
hi->reg_offset = lo->reg_offset;
lo->reg = mips_regnum (current_gdbarch)->fp0 + 0;
hi->reg = mips_regnum (current_gdbarch)->fp0 + 1;
+ if (storextract == EXTRACT_COOKED)
+ {
+ lo->reg += NUM_REGS;
+ hi->reg += NUM_REGS;
+ }
lo->len = 4;
hi->len = 4;
}
*************** return_value_location (struct type *valt
*** 2676,2681 ****
--- 2687,2694 ----
fp0) == 8
&& len == 4) ? 4 : 0);
lo->reg = mips_regnum (current_gdbarch)->fp0;
+ if (storextract == EXTRACT_COOKED)
+ lo->reg += NUM_REGS;
lo->len = len;
lo->buf_offset = 0;
hi->len = 0;
*************** return_value_location (struct type *valt
*** 2688,2693 ****
--- 2701,2709 ----
{
/* Locate a result possibly spread across two registers. */
int regnum = 2;
+ if (storextract == EXTRACT_COOKED)
+ regnum += NUM_REGS;
+
lo->reg = regnum + 0;
hi->reg = regnum + 1;
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
*************** mips_eabi_extract_return_value (struct t
*** 3042,3056 ****
{
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo);
memcpy (valbuf + lo.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) +
lo.reg_offset, lo.len);
if (hi.len > 0)
memcpy (valbuf + hi.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) +
hi.reg_offset, hi.len);
}
--- 3058,3072 ----
{
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo, EXTRACT_COOKED);
memcpy (valbuf + lo.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) +
lo.reg_offset, lo.len);
if (hi.len > 0)
memcpy (valbuf + hi.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) +
hi.reg_offset, hi.len);
}
*************** mips_eabi_store_return_value (struct typ
*** 3063,3069 ****
char raw_buffer[MAX_REGISTER_SIZE];
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo);
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
--- 3079,3085 ----
char raw_buffer[MAX_REGISTER_SIZE];
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo, STORE_RAW);
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
*************** mips_o64_extract_return_value (struct ty
*** 4191,4205 ****
{
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo);
memcpy (valbuf + lo.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) +
lo.reg_offset, lo.len);
if (hi.len > 0)
memcpy (valbuf + hi.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) +
hi.reg_offset, hi.len);
}
--- 4207,4221 ----
{
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo, EXTRACT_COOKED);
memcpy (valbuf + lo.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) +
lo.reg_offset, lo.len);
if (hi.len > 0)
memcpy (valbuf + hi.buf_offset,
! regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) +
hi.reg_offset, hi.len);
}
*************** mips_o64_store_return_value (struct type
*** 4209,4215 ****
char raw_buffer[MAX_REGISTER_SIZE];
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo);
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
--- 4225,4231 ----
char raw_buffer[MAX_REGISTER_SIZE];
struct return_value_word lo;
struct return_value_word hi;
! return_value_location (valtype, &hi, &lo, STORE_RAW);
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [RFC/RFA] MIPS extract_return_value
2004-06-04 1:38 [RFC/RFA] MIPS extract_return_value Michael Snyder
@ 2004-06-07 15:22 ` Andrew Cagney
2004-06-07 19:24 ` Michael Snyder
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Cagney @ 2004-06-07 15:22 UTC (permalink / raw)
To: Michael Snyder; +Cc: gdb-patches, drow
> Hey Andrew, Daniel,
>
> I encountered another problem with 32/64 bit mips. Don't know if this
> is the right way to fix it, but it illustrates it (and fixes several
> hundred failures).
>
> The problem is that extract_return_value and store_return_value both
> call return_value_location, but then one of them uses the raw register
> and the other uses the cooked register (which are not the same size).
> So the offset into the register cache, computed by
> return_value_location, has to be wrong for one of them.
The underlying problem here is that eabi (32 and 64) and o64 still use:
set_gdbarch_deprecated_store_return_value (gdbarch,
set_gdbarch_deprecated_extract_return_value (gdbarch,
There should instead be separate eabi and o64 return_value methods (see
mips_n32n64_return_value for an example).
If this is done the return/finish code will really be fixed (and as a
side effect return_value_location will be eliminated). Can that be done?
> The simple-minded approach I've taken below is to add a parameter
> to return_value_location, telling it whether to use the raw or cooked
> registers. I've only tested it on one architecture (isa64 with gcc
> -mips32), so consider it more of a suggestion than a patch.
Just FYI, the code should just manipulate the cooked registers.
Andrew
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [RFC/RFA] MIPS extract_return_value
2004-06-07 15:22 ` Andrew Cagney
@ 2004-06-07 19:24 ` Michael Snyder
0 siblings, 0 replies; 3+ messages in thread
From: Michael Snyder @ 2004-06-07 19:24 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches, drow
Andrew Cagney wrote:
>> Hey Andrew, Daniel,
>>
>> I encountered another problem with 32/64 bit mips. Don't know if this
>> is the right way to fix it, but it illustrates it (and fixes several
>> hundred failures).
>>
>> The problem is that extract_return_value and store_return_value both
>> call return_value_location, but then one of them uses the raw register
>> and the other uses the cooked register (which are not the same size).
>> So the offset into the register cache, computed by
>> return_value_location, has to be wrong for one of them.
>
>
> The underlying problem here is that eabi (32 and 64) and o64 still use:
>
> set_gdbarch_deprecated_store_return_value (gdbarch,
> set_gdbarch_deprecated_extract_return_value (gdbarch,
>
> There should instead be separate eabi and o64 return_value methods (see
> mips_n32n64_return_value for an example).
>
> If this is done the return/finish code will really be fixed (and as a
> side effect return_value_location will be eliminated). Can that be done?
Obviously this is the correct thing to do, but it requires more
investment than I have to give in the foreseeable future.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2004-06-07 19:24 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-04 1:38 [RFC/RFA] MIPS extract_return_value Michael Snyder
2004-06-07 15:22 ` Andrew Cagney
2004-06-07 19:24 ` Michael Snyder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox