mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-14 12:28:37 +08:00
* hppa-tdep.c (hppa32_return_value): Move further down.
(hppa64_return_value): Re-implement.
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
2004-12-21 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
|
* hppa-tdep.c (hppa32_return_value): Move further down.
|
||||||
|
(hppa64_return_value): Re-implement.
|
||||||
|
|
||||||
2004-12-21 Jim Blandy <jimb@redhat.com>
|
2004-12-21 Jim Blandy <jimb@redhat.com>
|
||||||
|
|
||||||
* remote.c (fetch_register_using_p): Fix formatting.
|
* remote.c (fetch_register_using_p): Fix formatting.
|
||||||
|
233
gdb/hppa-tdep.c
233
gdb/hppa-tdep.c
@ -72,102 +72,6 @@ const struct objfile_data *hppa_objfile_priv_data = NULL;
|
|||||||
following functions static, once we hppa is partially multiarched. */
|
following functions static, once we hppa is partially multiarched. */
|
||||||
int hppa_pc_requires_run_before_use (CORE_ADDR pc);
|
int hppa_pc_requires_run_before_use (CORE_ADDR pc);
|
||||||
|
|
||||||
/* Handle 32/64-bit struct return conventions. */
|
|
||||||
|
|
||||||
static enum return_value_convention
|
|
||||||
hppa32_return_value (struct gdbarch *gdbarch,
|
|
||||||
struct type *type, struct regcache *regcache,
|
|
||||||
void *readbuf, const void *writebuf)
|
|
||||||
{
|
|
||||||
if (TYPE_LENGTH (type) <= 2 * 4)
|
|
||||||
{
|
|
||||||
/* The value always lives in the right hand end of the register
|
|
||||||
(or register pair)? */
|
|
||||||
int b;
|
|
||||||
int reg = TYPE_CODE (type) == TYPE_CODE_FLT ? HPPA_FP4_REGNUM : 28;
|
|
||||||
int part = TYPE_LENGTH (type) % 4;
|
|
||||||
/* The left hand register contains only part of the value,
|
|
||||||
transfer that first so that the rest can be xfered as entire
|
|
||||||
4-byte registers. */
|
|
||||||
if (part > 0)
|
|
||||||
{
|
|
||||||
if (readbuf != NULL)
|
|
||||||
regcache_cooked_read_part (regcache, reg, 4 - part,
|
|
||||||
part, readbuf);
|
|
||||||
if (writebuf != NULL)
|
|
||||||
regcache_cooked_write_part (regcache, reg, 4 - part,
|
|
||||||
part, writebuf);
|
|
||||||
reg++;
|
|
||||||
}
|
|
||||||
/* Now transfer the remaining register values. */
|
|
||||||
for (b = part; b < TYPE_LENGTH (type); b += 4)
|
|
||||||
{
|
|
||||||
if (readbuf != NULL)
|
|
||||||
regcache_cooked_read (regcache, reg, (char *) readbuf + b);
|
|
||||||
if (writebuf != NULL)
|
|
||||||
regcache_cooked_write (regcache, reg, (const char *) writebuf + b);
|
|
||||||
reg++;
|
|
||||||
}
|
|
||||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return RETURN_VALUE_STRUCT_CONVENTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum return_value_convention
|
|
||||||
hppa64_return_value (struct gdbarch *gdbarch,
|
|
||||||
struct type *type, struct regcache *regcache,
|
|
||||||
void *readbuf, const void *writebuf)
|
|
||||||
{
|
|
||||||
/* RM: Floats are returned in FR4R, doubles in FR4. Integral values
|
|
||||||
are in r28, padded on the left. Aggregates less that 65 bits are
|
|
||||||
in r28, right padded. Aggregates upto 128 bits are in r28 and
|
|
||||||
r29, right padded. */
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_FLT
|
|
||||||
&& TYPE_LENGTH (type) <= 8)
|
|
||||||
{
|
|
||||||
/* Floats are right aligned? */
|
|
||||||
int offset = register_size (gdbarch, HPPA_FP4_REGNUM) - TYPE_LENGTH (type);
|
|
||||||
if (readbuf != NULL)
|
|
||||||
regcache_cooked_read_part (regcache, HPPA_FP4_REGNUM, offset,
|
|
||||||
TYPE_LENGTH (type), readbuf);
|
|
||||||
if (writebuf != NULL)
|
|
||||||
regcache_cooked_write_part (regcache, HPPA_FP4_REGNUM, offset,
|
|
||||||
TYPE_LENGTH (type), writebuf);
|
|
||||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
|
||||||
}
|
|
||||||
else if (TYPE_LENGTH (type) <= 8 && is_integral_type (type))
|
|
||||||
{
|
|
||||||
/* Integrals are right aligned. */
|
|
||||||
int offset = register_size (gdbarch, HPPA_FP4_REGNUM) - TYPE_LENGTH (type);
|
|
||||||
if (readbuf != NULL)
|
|
||||||
regcache_cooked_read_part (regcache, 28, offset,
|
|
||||||
TYPE_LENGTH (type), readbuf);
|
|
||||||
if (writebuf != NULL)
|
|
||||||
regcache_cooked_write_part (regcache, 28, offset,
|
|
||||||
TYPE_LENGTH (type), writebuf);
|
|
||||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
|
||||||
}
|
|
||||||
else if (TYPE_LENGTH (type) <= 2 * 8)
|
|
||||||
{
|
|
||||||
/* Composite values are left aligned. */
|
|
||||||
int b;
|
|
||||||
for (b = 0; b < TYPE_LENGTH (type); b += 8)
|
|
||||||
{
|
|
||||||
int part = min (8, TYPE_LENGTH (type) - b);
|
|
||||||
if (readbuf != NULL)
|
|
||||||
regcache_cooked_read_part (regcache, 28 + b / 8, 0, part,
|
|
||||||
(char *) readbuf + b);
|
|
||||||
if (writebuf != NULL)
|
|
||||||
regcache_cooked_write_part (regcache, 28 + b / 8, 0, part,
|
|
||||||
(const char *) writebuf + b);
|
|
||||||
}
|
|
||||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return RETURN_VALUE_STRUCT_CONVENTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Routines to extract various sized constants out of hppa
|
/* Routines to extract various sized constants out of hppa
|
||||||
instructions. */
|
instructions. */
|
||||||
|
|
||||||
@ -1126,6 +1030,143 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Handle 32/64-bit struct return conventions. */
|
||||||
|
|
||||||
|
static enum return_value_convention
|
||||||
|
hppa32_return_value (struct gdbarch *gdbarch,
|
||||||
|
struct type *type, struct regcache *regcache,
|
||||||
|
void *readbuf, const void *writebuf)
|
||||||
|
{
|
||||||
|
if (TYPE_LENGTH (type) <= 2 * 4)
|
||||||
|
{
|
||||||
|
/* The value always lives in the right hand end of the register
|
||||||
|
(or register pair)? */
|
||||||
|
int b;
|
||||||
|
int reg = TYPE_CODE (type) == TYPE_CODE_FLT ? HPPA_FP4_REGNUM : 28;
|
||||||
|
int part = TYPE_LENGTH (type) % 4;
|
||||||
|
/* The left hand register contains only part of the value,
|
||||||
|
transfer that first so that the rest can be xfered as entire
|
||||||
|
4-byte registers. */
|
||||||
|
if (part > 0)
|
||||||
|
{
|
||||||
|
if (readbuf != NULL)
|
||||||
|
regcache_cooked_read_part (regcache, reg, 4 - part,
|
||||||
|
part, readbuf);
|
||||||
|
if (writebuf != NULL)
|
||||||
|
regcache_cooked_write_part (regcache, reg, 4 - part,
|
||||||
|
part, writebuf);
|
||||||
|
reg++;
|
||||||
|
}
|
||||||
|
/* Now transfer the remaining register values. */
|
||||||
|
for (b = part; b < TYPE_LENGTH (type); b += 4)
|
||||||
|
{
|
||||||
|
if (readbuf != NULL)
|
||||||
|
regcache_cooked_read (regcache, reg, (char *) readbuf + b);
|
||||||
|
if (writebuf != NULL)
|
||||||
|
regcache_cooked_write (regcache, reg, (const char *) writebuf + b);
|
||||||
|
reg++;
|
||||||
|
}
|
||||||
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum return_value_convention
|
||||||
|
hppa64_return_value (struct gdbarch *gdbarch,
|
||||||
|
struct type *type, struct regcache *regcache,
|
||||||
|
void *readbuf, const void *writebuf)
|
||||||
|
{
|
||||||
|
int len = TYPE_LENGTH (type);
|
||||||
|
int regnum, offset;
|
||||||
|
|
||||||
|
if (len > 16)
|
||||||
|
{
|
||||||
|
/* All return values larget than 128 bits must be aggregate
|
||||||
|
return values. */
|
||||||
|
gdb_assert (!hppa64_integral_or_pointer_p());
|
||||||
|
gdb_assert (!hppa64_floating_p());
|
||||||
|
|
||||||
|
/* "Aggregate return values larger than 128 bits are returned in
|
||||||
|
a buffer allocated by the caller. The address of the buffer
|
||||||
|
must be passed in GR 28." */
|
||||||
|
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hppa64_integral_or_pointer_p (type))
|
||||||
|
{
|
||||||
|
/* "Integral return values are returned in GR 28. Values
|
||||||
|
smaller than 64 bits are padded on the left (with garbage)." */
|
||||||
|
regnum = HPPA_RET0_REGNUM;
|
||||||
|
offset = 8 - len;
|
||||||
|
}
|
||||||
|
else if (hppa64_floating_p (type))
|
||||||
|
{
|
||||||
|
if (len > 8)
|
||||||
|
{
|
||||||
|
/* "Double-extended- and quad-precision floating-point
|
||||||
|
values are returned in GRs 28 and 29. The sign,
|
||||||
|
exponent, and most-significant bits of the mantissa are
|
||||||
|
returned in GR 28; the least-significant bits of the
|
||||||
|
mantissa are passed in GR 29. For double-extended
|
||||||
|
precision values, GR 29 is padded on the right with 48
|
||||||
|
bits of garbage." */
|
||||||
|
regnum = HPPA_RET0_REGNUM;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* "Single-precision and double-precision floating-point
|
||||||
|
return values are returned in FR 4R (single precision) or
|
||||||
|
FR 4 (double-precision)." */
|
||||||
|
regnum = HPPA64_FP4_REGNUM;
|
||||||
|
offset = 8 - len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* "Aggregate return values up to 64 bits in size are returned
|
||||||
|
in GR 28. Aggregates smaller than 64 bits are left aligned
|
||||||
|
in the register; the pad bits on the right are undefined."
|
||||||
|
|
||||||
|
"Aggregate return values between 65 and 128 bits are returned
|
||||||
|
in GRs 28 and 29. The first 64 bits are placed in GR 28, and
|
||||||
|
the remaining bits are placed, left aligned, in GR 29. The
|
||||||
|
pad bits on the right of GR 29 (if any) are undefined." */
|
||||||
|
regnum = HPPA_RET0_REGNUM;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readbuf)
|
||||||
|
{
|
||||||
|
char *buf = readbuf;
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
regcache_cooked_read_part (regcache, regnum, offset,
|
||||||
|
min (len, 8), buf);
|
||||||
|
buf += min (len, 8);
|
||||||
|
len -= min (len, 8);
|
||||||
|
regnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writebuf)
|
||||||
|
{
|
||||||
|
const char *buf = writebuf;
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
regcache_cooked_write_part (regcache, regnum, offset,
|
||||||
|
min (len, 8), buf);
|
||||||
|
buf += min (len, 8);
|
||||||
|
len -= min (len, 8);
|
||||||
|
regnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
hppa32_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
|
hppa32_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
|
||||||
CORE_ADDR addr,
|
CORE_ADDR addr,
|
||||||
|
Reference in New Issue
Block a user