mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 20:49:43 +00:00
2003-11-09 Andrew Cagney <cagney@redhat.com>
* d10v-tdep.c (d10v_return_value): New function. (d10v_use_struct_convention): Delete function. (d10v_store_return_value): Delete function. (d10v_extract_struct_value_address): Delete function. (d10v_gdbarch_init): Set "return_value" instead of "extract_return_value", "store_return_value", "extract_struct_value_address", and "use_struct_convention". (RET1_REGNUM): Delete const.
This commit is contained in:
parent
00ce77f474
commit
181555e940
@ -1,3 +1,14 @@
|
|||||||
|
2003-11-09 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
|
* d10v-tdep.c (d10v_return_value): New function.
|
||||||
|
(d10v_use_struct_convention): Delete function.
|
||||||
|
(d10v_store_return_value): Delete function.
|
||||||
|
(d10v_extract_struct_value_address): Delete function.
|
||||||
|
(d10v_gdbarch_init): Set "return_value" instead of
|
||||||
|
"extract_return_value", "store_return_value",
|
||||||
|
"extract_struct_value_address", and "use_struct_convention".
|
||||||
|
(RET1_REGNUM): Delete const.
|
||||||
|
|
||||||
2003-11-09 Mark Kettenis <kettenis@gnu.org>
|
2003-11-09 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
From David S. Miller <davem@redhat.com>:
|
From David S. Miller <davem@redhat.com>:
|
||||||
|
199
gdb/d10v-tdep.c
199
gdb/d10v-tdep.c
@ -82,8 +82,7 @@ enum
|
|||||||
TS3_NUM_REGS = 42,
|
TS3_NUM_REGS = 42,
|
||||||
/* d10v calling convention. */
|
/* d10v calling convention. */
|
||||||
ARG1_REGNUM = R0_REGNUM,
|
ARG1_REGNUM = R0_REGNUM,
|
||||||
ARGN_REGNUM = R3_REGNUM,
|
ARGN_REGNUM = R3_REGNUM
|
||||||
RET1_REGNUM = R0_REGNUM,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -114,44 +113,6 @@ d10v_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
|
|||||||
return sp & ~3;
|
return sp & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
|
|
||||||
EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
|
|
||||||
and TYPE is the type (which is known to be struct, union or array).
|
|
||||||
|
|
||||||
The d10v returns anything less than 8 bytes in size in
|
|
||||||
registers. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
d10v_use_struct_convention (int gcc_p, struct type *type)
|
|
||||||
{
|
|
||||||
long alignment;
|
|
||||||
int i;
|
|
||||||
/* The d10v only passes a struct in a register when that structure
|
|
||||||
has an alignment that matches the size of a register. */
|
|
||||||
/* If the structure doesn't fit in 4 registers, put it on the
|
|
||||||
stack. */
|
|
||||||
if (TYPE_LENGTH (type) > 8)
|
|
||||||
return 1;
|
|
||||||
/* If the struct contains only one field, don't put it on the stack
|
|
||||||
- gcc can fit it in one or more registers. */
|
|
||||||
if (TYPE_NFIELDS (type) == 1)
|
|
||||||
return 0;
|
|
||||||
alignment = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
|
|
||||||
for (i = 1; i < TYPE_NFIELDS (type); i++)
|
|
||||||
{
|
|
||||||
/* If the alignment changes, just assume it goes on the
|
|
||||||
stack. */
|
|
||||||
if (TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)) != alignment)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* If the alignment is suitable for the d10v's 16 bit registers,
|
|
||||||
don't put it on the stack. */
|
|
||||||
if (alignment == 2 || alignment == 4)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const unsigned char *
|
static const unsigned char *
|
||||||
d10v_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
|
d10v_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
|
||||||
{
|
{
|
||||||
@ -413,54 +374,88 @@ d10v_integer_to_address (struct type *type, void *buf)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write into appropriate registers a function return value
|
/* Handle the d10v's return_value convention. */
|
||||||
of type TYPE, given in virtual format.
|
|
||||||
|
|
||||||
Things always get returned in RET1_REGNUM, RET2_REGNUM, ... */
|
static enum return_value_convention
|
||||||
|
d10v_return_value (struct gdbarch *gdbarch, struct type *valtype,
|
||||||
static void
|
struct regcache *regcache, const void *writebuf,
|
||||||
d10v_store_return_value (struct type *type, struct regcache *regcache,
|
void *readbuf)
|
||||||
const void *valbuf)
|
|
||||||
{
|
{
|
||||||
/* Only char return values need to be shifted right within the first
|
if (TYPE_LENGTH (valtype) > 8)
|
||||||
regnum. */
|
/* Anything larger than 8 bytes (4 registers) goes on the stack. */
|
||||||
if (TYPE_LENGTH (type) == 1
|
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||||
&& TYPE_CODE (type) == TYPE_CODE_INT)
|
if (TYPE_LENGTH (valtype) == 5
|
||||||
|
|| TYPE_LENGTH (valtype) == 6)
|
||||||
|
/* Anything 5 or 6 bytes in size goes in memory. Contents don't
|
||||||
|
appear to matter. Note that 7 and 8 byte objects do end up in
|
||||||
|
registers! */
|
||||||
|
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||||
|
if (TYPE_LENGTH (valtype) == 1)
|
||||||
{
|
{
|
||||||
bfd_byte tmp[2];
|
/* All single byte values go in a register stored right-aligned.
|
||||||
tmp[1] = *(bfd_byte *)valbuf;
|
Note: 2 byte integer values are handled further down. */
|
||||||
regcache_cooked_write (regcache, RET1_REGNUM, tmp);
|
if (readbuf)
|
||||||
|
{
|
||||||
|
/* Since TYPE is smaller than the register, there isn't a
|
||||||
|
sign extension problem. Let the extraction truncate the
|
||||||
|
register value. */
|
||||||
|
ULONGEST regval;
|
||||||
|
regcache_cooked_read_unsigned (regcache, R0_REGNUM,
|
||||||
|
®val);
|
||||||
|
store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (writebuf)
|
||||||
|
{
|
||||||
|
ULONGEST regval;
|
||||||
|
if (TYPE_CODE (valtype) == TYPE_CODE_INT)
|
||||||
|
/* Some sort of integer value stored in R0. Use
|
||||||
|
unpack_long since that should handle any required sign
|
||||||
|
extension. */
|
||||||
|
regval = unpack_long (valtype, writebuf);
|
||||||
|
else
|
||||||
|
/* Some other type. Don't sign-extend the value when
|
||||||
|
storing it in the register. */
|
||||||
|
regval = extract_unsigned_integer (writebuf, 1);
|
||||||
|
regcache_cooked_write_unsigned (regcache, R0_REGNUM, regval);
|
||||||
|
}
|
||||||
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
}
|
}
|
||||||
else
|
if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
|
||||||
|
|| TYPE_CODE (valtype) == TYPE_CODE_UNION)
|
||||||
|
&& TYPE_NFIELDS (valtype) > 1
|
||||||
|
&& TYPE_FIELD_BITPOS (valtype, 1) == 8)
|
||||||
|
/* If a composite is 8 bit aligned (determined by looking at the
|
||||||
|
start address of the second field), put it in memory. */
|
||||||
|
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||||
|
/* Assume it is in registers. */
|
||||||
|
if (writebuf || readbuf)
|
||||||
{
|
{
|
||||||
int reg;
|
int reg;
|
||||||
/* A structure is never more than 8 bytes long. See
|
/* Per above, the value is never more than 8 bytes long. */
|
||||||
use_struct_convention(). */
|
gdb_assert (TYPE_LENGTH (valtype) <= 8);
|
||||||
gdb_assert (TYPE_LENGTH (type) <= 8);
|
/* Xfer 2 bytes at a time. */
|
||||||
/* Write out most registers, stop loop before trying to write
|
for (reg = 0; (reg * 2) + 1 < TYPE_LENGTH (valtype); reg++)
|
||||||
out any dangling byte at the end of the buffer. */
|
|
||||||
for (reg = 0; (reg * 2) + 1 < TYPE_LENGTH (type); reg++)
|
|
||||||
{
|
{
|
||||||
regcache_cooked_write (regcache, RET1_REGNUM + reg,
|
if (readbuf)
|
||||||
(bfd_byte *) valbuf + reg * 2);
|
regcache_cooked_read (regcache, R0_REGNUM + reg,
|
||||||
|
(bfd_byte *) readbuf + reg * 2);
|
||||||
|
if (writebuf)
|
||||||
|
regcache_cooked_write (regcache, R0_REGNUM + reg,
|
||||||
|
(bfd_byte *) writebuf + reg * 2);
|
||||||
|
}
|
||||||
|
/* Any trailing byte ends up _left_ aligned. */
|
||||||
|
if ((reg * 2) < TYPE_LENGTH (valtype))
|
||||||
|
{
|
||||||
|
if (readbuf)
|
||||||
|
regcache_cooked_read_part (regcache, R0_REGNUM + reg,
|
||||||
|
0, 1, (bfd_byte *) readbuf + reg * 2);
|
||||||
|
if (writebuf)
|
||||||
|
regcache_cooked_write_part (regcache, R0_REGNUM + reg,
|
||||||
|
0, 1, (bfd_byte *) writebuf + reg * 2);
|
||||||
}
|
}
|
||||||
/* Write out any dangling byte at the end of the buffer. */
|
|
||||||
if ((reg * 2) + 1 == TYPE_LENGTH (type))
|
|
||||||
regcache_cooked_write_part (regcache, reg, 0, 1,
|
|
||||||
(bfd_byte *) valbuf + reg * 2);
|
|
||||||
}
|
}
|
||||||
}
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
|
|
||||||
/* Extract from an array REGBUF containing the (raw) register state
|
|
||||||
the address in which a function should return its structure value,
|
|
||||||
as a CORE_ADDR (or an expression that can be used as one). */
|
|
||||||
|
|
||||||
static CORE_ADDR
|
|
||||||
d10v_extract_struct_value_address (struct regcache *regcache)
|
|
||||||
{
|
|
||||||
ULONGEST addr;
|
|
||||||
regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &addr);
|
|
||||||
return (addr | DMEM_START);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1043,46 +1038,6 @@ d10v_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
|
|||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Given a return value in `regbuf' with a type `valtype',
|
|
||||||
extract and copy its value into `valbuf'. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
d10v_extract_return_value (struct type *type, struct regcache *regcache,
|
|
||||||
void *valbuf)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
if (TYPE_LENGTH (type) == 1)
|
|
||||||
{
|
|
||||||
ULONGEST c;
|
|
||||||
regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &c);
|
|
||||||
store_unsigned_integer (valbuf, 1, c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* For return values of odd size, the first byte is in the
|
|
||||||
least significant part of the first register. The
|
|
||||||
remaining bytes in remaining registers. Interestingly, when
|
|
||||||
such values are passed in, the last byte is in the most
|
|
||||||
significant byte of that same register - wierd. */
|
|
||||||
int reg = RET1_REGNUM;
|
|
||||||
int off = 0;
|
|
||||||
if (TYPE_LENGTH (type) & 1)
|
|
||||||
{
|
|
||||||
regcache_cooked_read_part (regcache, RET1_REGNUM, 1, 1,
|
|
||||||
(bfd_byte *)valbuf + off);
|
|
||||||
off++;
|
|
||||||
reg++;
|
|
||||||
}
|
|
||||||
/* Transfer the remaining registers. */
|
|
||||||
for (; off < TYPE_LENGTH (type); reg++, off += 2)
|
|
||||||
{
|
|
||||||
regcache_cooked_read (regcache, RET1_REGNUM + reg,
|
|
||||||
(bfd_byte *) valbuf + off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Translate a GDB virtual ADDR/LEN into a format the remote target
|
/* Translate a GDB virtual ADDR/LEN into a format the remote target
|
||||||
understands. Returns number of bytes that can be transfered
|
understands. Returns number of bytes that can be transfered
|
||||||
starting at TARG_ADDR. Return ZERO if no bytes can be transfered
|
starting at TARG_ADDR. Return ZERO if no bytes can be transfered
|
||||||
@ -1554,13 +1509,9 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||||||
"d10v_gdbarch_init: bad byte order for float format");
|
"d10v_gdbarch_init: bad byte order for float format");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_gdbarch_extract_return_value (gdbarch, d10v_extract_return_value);
|
set_gdbarch_return_value (gdbarch, d10v_return_value);
|
||||||
set_gdbarch_push_dummy_code (gdbarch, d10v_push_dummy_code);
|
set_gdbarch_push_dummy_code (gdbarch, d10v_push_dummy_code);
|
||||||
set_gdbarch_push_dummy_call (gdbarch, d10v_push_dummy_call);
|
set_gdbarch_push_dummy_call (gdbarch, d10v_push_dummy_call);
|
||||||
set_gdbarch_store_return_value (gdbarch, d10v_store_return_value);
|
|
||||||
set_gdbarch_extract_struct_value_address (gdbarch,
|
|
||||||
d10v_extract_struct_value_address);
|
|
||||||
set_gdbarch_use_struct_convention (gdbarch, d10v_use_struct_convention);
|
|
||||||
|
|
||||||
set_gdbarch_skip_prologue (gdbarch, d10v_skip_prologue);
|
set_gdbarch_skip_prologue (gdbarch, d10v_skip_prologue);
|
||||||
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
||||||
|
Loading…
Reference in New Issue
Block a user