2002-08-19 Andrew Cagney <ac131313@redhat.com>
* mips-tdep.c (mips_xfer_register): New function. (mips_n32n64_extract_return_value): Rewrite. (mips_gdbarch_init): For N32 and N64, set extract_return_value instead of deprecated_extract_return_value.
This commit is contained in:
parent
d62b1198f8
commit
88658117fa
@ -1,3 +1,10 @@
|
|||||||
|
2002-08-19 Andrew Cagney <ac131313@redhat.com>
|
||||||
|
|
||||||
|
* mips-tdep.c (mips_xfer_register): New function.
|
||||||
|
(mips_n32n64_extract_return_value): Rewrite.
|
||||||
|
(mips_gdbarch_init): For N32 and N64, set extract_return_value
|
||||||
|
instead of deprecated_extract_return_value.
|
||||||
|
|
||||||
2002-08-19 Elena Zannoni <ezannoni@redhat.com>
|
2002-08-19 Elena Zannoni <ezannoni@redhat.com>
|
||||||
|
|
||||||
* rs6000-tdep.c (TDEP): Delete macro.
|
* rs6000-tdep.c (TDEP): Delete macro.
|
||||||
|
192
gdb/mips-tdep.c
192
gdb/mips-tdep.c
@ -173,6 +173,57 @@ mips_saved_regsize (void)
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XFER a value from the big/little/left end of the register.
|
||||||
|
Depending on the size of the value it might occupy the entire
|
||||||
|
register or just part of it. Make an allowance for this, aligning
|
||||||
|
things accordingly. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_xfer_register (struct regcache *regcache, int reg_num, int length,
|
||||||
|
enum bfd_endian endian, bfd_byte *in, const bfd_byte *out,
|
||||||
|
int buf_offset)
|
||||||
|
{
|
||||||
|
bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
|
||||||
|
int reg_offset = 0;
|
||||||
|
switch (endian)
|
||||||
|
{
|
||||||
|
case BFD_ENDIAN_BIG:
|
||||||
|
reg_offset = REGISTER_RAW_SIZE (reg_num) - length;
|
||||||
|
break;
|
||||||
|
case BFD_ENDIAN_LITTLE:
|
||||||
|
reg_offset = 0;
|
||||||
|
break;
|
||||||
|
case BFD_ENDIAN_UNKNOWN: /* Indicates no alignment. */
|
||||||
|
reg_offset = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
internal_error (__FILE__, __LINE__, "bad switch");
|
||||||
|
}
|
||||||
|
if (mips_debug)
|
||||||
|
fprintf_unfiltered (gdb_stderr, "xfer $%d[%d..%d] ",
|
||||||
|
reg_num, reg_offset, reg_offset + length);
|
||||||
|
if (mips_debug && out != NULL)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "out: ");
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "%02x", out[i]);
|
||||||
|
}
|
||||||
|
if (in != NULL)
|
||||||
|
regcache_raw_read_part (regcache, reg_num, reg_offset, length, in + buf_offset);
|
||||||
|
if (out != NULL)
|
||||||
|
regcache_raw_write_part (regcache, reg_num, reg_offset, length, out + buf_offset);
|
||||||
|
if (mips_debug && in != NULL)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "in: ");
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "%02x", in[i]);
|
||||||
|
}
|
||||||
|
if (mips_debug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
|
/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
|
||||||
compatiblity mode. A return value of 1 means that we have
|
compatiblity mode. A return value of 1 means that we have
|
||||||
physical 64-bit registers, but should treat them as 32-bit registers. */
|
physical 64-bit registers, but should treat them as 32-bit registers. */
|
||||||
@ -4526,25 +4577,6 @@ mips_o64_extract_return_value (struct type *valtype,
|
|||||||
hi.len);
|
hi.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
mips_n32n64_extract_return_value (struct type *valtype,
|
|
||||||
char regbuf[REGISTER_BYTES],
|
|
||||||
char *valbuf)
|
|
||||||
{
|
|
||||||
struct return_value_word lo;
|
|
||||||
struct return_value_word hi;
|
|
||||||
return_value_location (valtype, &hi, &lo);
|
|
||||||
|
|
||||||
memcpy (valbuf + lo.buf_offset,
|
|
||||||
regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
|
|
||||||
lo.len);
|
|
||||||
|
|
||||||
if (hi.len > 0)
|
|
||||||
memcpy (valbuf + hi.buf_offset,
|
|
||||||
regbuf + REGISTER_BYTE (hi.reg) + hi.reg_offset,
|
|
||||||
hi.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a return value in `valbuf' with a type `valtype', write it's
|
/* Given a return value in `valbuf' with a type `valtype', write it's
|
||||||
value into the appropriate register. */
|
value into the appropriate register. */
|
||||||
|
|
||||||
@ -4621,27 +4653,109 @@ mips_o64_store_return_value (struct type *valtype, char *valbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_n32n64_store_return_value (struct type *valtype, char *valbuf)
|
mips_n32n64_xfer_return_value (struct type *type,
|
||||||
|
struct regcache *regcache,
|
||||||
|
bfd_byte *in, const bfd_byte *out)
|
||||||
{
|
{
|
||||||
char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||||
struct return_value_word lo;
|
if (TYPE_CODE (type) == TYPE_CODE_FLT
|
||||||
struct return_value_word hi;
|
&& tdep->mips_fpu_type != MIPS_FPU_NONE)
|
||||||
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);
|
|
||||||
write_register_bytes (REGISTER_BYTE (lo.reg),
|
|
||||||
raw_buffer,
|
|
||||||
REGISTER_RAW_SIZE (lo.reg));
|
|
||||||
|
|
||||||
if (hi.len > 0)
|
|
||||||
{
|
{
|
||||||
memset (raw_buffer, 0, sizeof (raw_buffer));
|
/* A floating-point value belongs in the least significant part
|
||||||
memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len);
|
of FP0. */
|
||||||
write_register_bytes (REGISTER_BYTE (hi.reg),
|
if (mips_debug)
|
||||||
raw_buffer,
|
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
|
||||||
REGISTER_RAW_SIZE (hi.reg));
|
mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type),
|
||||||
|
TARGET_BYTE_ORDER, in, out, 0);
|
||||||
}
|
}
|
||||||
|
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||||
|
&& TYPE_NFIELDS (type) <= 2
|
||||||
|
&& TYPE_NFIELDS (type) >= 1
|
||||||
|
&& ((TYPE_NFIELDS (type) == 1
|
||||||
|
&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
|
||||||
|
== TYPE_CODE_FLT))
|
||||||
|
|| (TYPE_NFIELDS (type) == 2
|
||||||
|
&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
|
||||||
|
== TYPE_CODE_FLT)
|
||||||
|
&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 1))
|
||||||
|
== TYPE_CODE_FLT)))
|
||||||
|
&& tdep->mips_fpu_type != MIPS_FPU_NONE)
|
||||||
|
{
|
||||||
|
/* A struct that contains one or two floats. Each value is part
|
||||||
|
in the least significant part of their floating point
|
||||||
|
register.. */
|
||||||
|
bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
|
||||||
|
int regnum;
|
||||||
|
int field;
|
||||||
|
for (field = 0, regnum = FP0_REGNUM;
|
||||||
|
field < TYPE_NFIELDS (type);
|
||||||
|
field++, regnum += 2)
|
||||||
|
{
|
||||||
|
int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field])
|
||||||
|
/ TARGET_CHAR_BIT);
|
||||||
|
if (mips_debug)
|
||||||
|
fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
|
||||||
|
mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
|
||||||
|
TARGET_BYTE_ORDER, in, out, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||||
|
|| TYPE_CODE (type) == TYPE_CODE_UNION)
|
||||||
|
{
|
||||||
|
/* A structure or union. Extract the left justified value,
|
||||||
|
regardless of the byte order. I.e. DO NOT USE
|
||||||
|
mips_xfer_lower. */
|
||||||
|
int offset;
|
||||||
|
int regnum;
|
||||||
|
for (offset = 0, regnum = V0_REGNUM;
|
||||||
|
offset < TYPE_LENGTH (type);
|
||||||
|
offset += REGISTER_RAW_SIZE (regnum), regnum++)
|
||||||
|
{
|
||||||
|
int xfer = REGISTER_RAW_SIZE (regnum);
|
||||||
|
if (offset + xfer > TYPE_LENGTH (type))
|
||||||
|
xfer = TYPE_LENGTH (type) - offset;
|
||||||
|
if (mips_debug)
|
||||||
|
fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
|
||||||
|
offset, xfer, regnum);
|
||||||
|
mips_xfer_register (regcache, regnum, xfer, BFD_ENDIAN_UNKNOWN,
|
||||||
|
in, out, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* A scalar extract each part but least-significant-byte
|
||||||
|
justified. */
|
||||||
|
int offset;
|
||||||
|
int regnum;
|
||||||
|
for (offset = 0, regnum = V0_REGNUM;
|
||||||
|
offset < TYPE_LENGTH (type);
|
||||||
|
offset += REGISTER_RAW_SIZE (regnum), regnum++)
|
||||||
|
{
|
||||||
|
int xfer = REGISTER_RAW_SIZE (regnum);
|
||||||
|
int pos = 0;
|
||||||
|
if (offset + xfer > TYPE_LENGTH (type))
|
||||||
|
xfer = TYPE_LENGTH (type) - offset;
|
||||||
|
if (mips_debug)
|
||||||
|
fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
|
||||||
|
offset, xfer, regnum);
|
||||||
|
mips_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
|
||||||
|
in, out, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_n32n64_extract_return_value (struct type *type,
|
||||||
|
struct regcache *regcache,
|
||||||
|
char *valbuf)
|
||||||
|
{
|
||||||
|
mips_n32n64_xfer_return_value (type, regcache, valbuf, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_n32n64_store_return_value (struct type *type, char *valbuf)
|
||||||
|
{
|
||||||
|
mips_n32n64_xfer_return_value (type, current_regcache, NULL, valbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exported procedure: Is PC in the signal trampoline code */
|
/* Exported procedure: Is PC in the signal trampoline code */
|
||||||
@ -5535,7 +5649,7 @@ mips_gdbarch_init (struct gdbarch_info info,
|
|||||||
case MIPS_ABI_N32:
|
case MIPS_ABI_N32:
|
||||||
set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments);
|
set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments);
|
||||||
set_gdbarch_store_return_value (gdbarch, mips_n32n64_store_return_value);
|
set_gdbarch_store_return_value (gdbarch, mips_n32n64_store_return_value);
|
||||||
set_gdbarch_deprecated_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
|
set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
|
||||||
tdep->mips_default_saved_regsize = 8;
|
tdep->mips_default_saved_regsize = 8;
|
||||||
tdep->mips_default_stack_argsize = 8;
|
tdep->mips_default_stack_argsize = 8;
|
||||||
tdep->mips_fp_register_double = 1;
|
tdep->mips_fp_register_double = 1;
|
||||||
@ -5566,7 +5680,7 @@ mips_gdbarch_init (struct gdbarch_info info,
|
|||||||
case MIPS_ABI_N64:
|
case MIPS_ABI_N64:
|
||||||
set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments);
|
set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments);
|
||||||
set_gdbarch_store_return_value (gdbarch, mips_n32n64_store_return_value);
|
set_gdbarch_store_return_value (gdbarch, mips_n32n64_store_return_value);
|
||||||
set_gdbarch_deprecated_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
|
set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
|
||||||
tdep->mips_default_saved_regsize = 8;
|
tdep->mips_default_saved_regsize = 8;
|
||||||
tdep->mips_default_stack_argsize = 8;
|
tdep->mips_default_stack_argsize = 8;
|
||||||
tdep->mips_fp_register_double = 1;
|
tdep->mips_fp_register_double = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user