From 07edf36e98bfb0c41c64ba4f2c8ac0be469d4d8f Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 10 Jul 2001 21:24:48 +0000 Subject: Clean up the D10V port so that GDB and the target program no longer disagree on how big pointers are. * findvar.c (value_from_register): Remove special case code for D10V. * printcmd.c (print_frame_args): Same. * valops.c (value_at, value_fetch_lazy): Same. * values.c (unpack_long): Same. * gdbarch.sh: Changes to effect the following: * gdbarch.h (GDB_TARGET_IS_D10V, D10V_MAKE_DADDR, gdbarch_d10v_make_daddr_ftype, gdbarch_d10v_make_daddr, set_gdbarch_d10v_make_daddr, D10V_MAKE_IADDR, gdbarch_d10v_make_iaddr_ftype, gdbarch_d10v_make_iaddr, set_gdbarch_d10v_make_iaddr, D10V_DADDR_P, gdbarch_d10v_daddr_p_ftype, gdbarch_d10v_daddr_p, set_gdbarch_d10v_daddr_p, D10V_IADDR_P, gdbarch_d10v_iaddr_p_ftype, gdbarch_d10v_iaddr_p, set_gdbarch_d10v_iaddr_p, D10V_CONVERT_DADDR_TO_RAW, gdbarch_d10v_convert_daddr_to_raw_ftype, gdbarch_d10v_convert_daddr_to_raw, set_gdbarch_d10v_convert_daddr_to_raw, D10V_CONVERT_IADDR_TO_RAW, gdbarch_d10v_convert_iaddr_to_raw_ftype, gdbarch_d10v_convert_iaddr_to_raw, set_gdbarch_d10v_convert_iaddr_to_raw): Delete declarations. * gdbarch.c: Delete the corresponding definitions. (struct gdbarch): Delete members d10v_make_daddr, d10v_make_iaddr, d10v_daddr_p, d10v_iaddr_p, d10v_convert_daddr_to_raw, and d10v_convert_iaddr_to_raw. (startup_gdbarch): Remove initializers for the above. (verify_gdbarch, gdbarch_dump): Don't verify or dump them any more. * d10v-tdep.c (d10v_register_virtual_type): Rather that claiming the stack pointer and PC are 32 bits long (which they aren't), say that the stack pointer is an int16_t, and the program counter is a function pointer. This allows the rest of GDB to make the appropriate conversions between the code pointer format and real addresses. (d10v_register_convertible, d10v_register_convert_to_virtual, d10v_register_convert_to_raw): Delete function; no registers are convertible now, so we use generic_register_convertible_not instead. (d10v_address_to_pointer, d10v_pointer_to_address): New gdbarch methods. (d10v_push_arguments, d10v_extract_return_value): Remove special cases for code and data pointers. (d10v_gdbarch_init): Set gdbarch_ptr_bit to 16, so that GDB and the target agree on how large pointers are. Say that addresses are 32 bits long. Register the address_to_pointer and pointer_to_address conversion functions. Since no registers are convertible now, register generic_register_convertible_not as the gdbarch_register_convertible method instead of d10v_register_convertible. Remove registrations for d10v_register_convert_to_virtual, d10v_register_convert_to_raw, gdbarch_d10v_make_daddr, gdbarch_d10v_make_iaddr, gdbarch_d10v_daddr_p, gdbarch_d10v_iaddr_p, gdbarch_d10v_convert_daddr_to_raw, and gdbarch_d10v_convert_iaddr_to_raw. --- gdb/d10v-tdep.c | 148 +++++++++++++++++++------------------------------------- 1 file changed, 49 insertions(+), 99 deletions(-) (limited to 'gdb/d10v-tdep.c') diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index 2a3c18b5c5a..e2e66bf387e 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -332,47 +332,15 @@ d10v_register_virtual_size (int reg_nr) static struct type * d10v_register_virtual_type (int reg_nr) { - if (reg_nr >= A0_REGNUM + if (reg_nr == PC_REGNUM) + return builtin_type_void_func_ptr; + else if (reg_nr >= A0_REGNUM && reg_nr < (A0_REGNUM + NR_A_REGS)) return builtin_type_int64; - else if (reg_nr == PC_REGNUM - || reg_nr == SP_REGNUM) - return builtin_type_int32; else return builtin_type_int16; } -/* convert $pc and $sp to/from virtual addresses */ -static int -d10v_register_convertible (int nr) -{ - return ((nr) == PC_REGNUM || (nr) == SP_REGNUM); -} - -static void -d10v_register_convert_to_virtual (int regnum, struct type *type, char *from, - char *to) -{ - ULONGEST x = extract_unsigned_integer (from, REGISTER_RAW_SIZE (regnum)); - if (regnum == PC_REGNUM) - x = (x << 2) | IMEM_START; - else - x |= DMEM_START; - store_unsigned_integer (to, TYPE_LENGTH (type), x); -} - -static void -d10v_register_convert_to_raw (struct type *type, int regnum, char *from, - char *to) -{ - ULONGEST x = extract_unsigned_integer (from, TYPE_LENGTH (type)); - x &= 0x3ffff; - if (regnum == PC_REGNUM) - x >>= 2; - store_unsigned_integer (to, 2, x); -} - - static CORE_ADDR d10v_make_daddr (CORE_ADDR x) { @@ -410,6 +378,48 @@ d10v_convert_daddr_to_raw (CORE_ADDR x) return ((x) & 0xffff); } +static void +d10v_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr) +{ + /* Is it a code address? */ + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC + || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD) + { +#if 0 + if (! d10v_iaddr_p (addr)) + { + warning_begin (); + fprintf_unfiltered (gdb_stderr, "address `"); + print_address_numeric (addr, 1, gdb_stderr); + fprintf_unfiltered (gdb_stderr, "' is not a code address\n"); + } +#endif + + store_unsigned_integer (buf, TYPE_LENGTH (type), + d10v_convert_iaddr_to_raw (addr)); + } + else + { + /* Strip off any upper segment bits. */ + store_unsigned_integer (buf, TYPE_LENGTH (type), + d10v_convert_daddr_to_raw (addr)); + } +} + +static CORE_ADDR +d10v_pointer_to_address (struct type *type, void *buf) +{ + CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type)); + + /* Is it a code address? */ + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC + || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD) + return d10v_make_iaddr (addr); + else + return d10v_make_daddr (addr); +} + + /* Store the address of the place in which to copy the structure the subroutine will return. This is called from call_function. @@ -1011,39 +1021,6 @@ d10v_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp, char *contents = VALUE_CONTENTS (arg); int len = TYPE_LENGTH (type); /* printf ("push: type=%d len=%d\n", type->code, len); */ - if (TYPE_CODE (type) == TYPE_CODE_PTR) - { - /* pointers require special handling - first convert and - then store */ - long val = extract_signed_integer (contents, len); - len = 2; - if (TYPE_TARGET_TYPE (type) - && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)) - { - /* function pointer */ - val = d10v_convert_iaddr_to_raw (val); - } - else if (d10v_iaddr_p (val)) - { - /* also function pointer! */ - val = d10v_convert_daddr_to_raw (val); - } - else - { - /* data pointer */ - val &= 0xFFFF; - } - if (regnum <= ARGN_REGNUM) - write_register (regnum++, val & 0xffff); - else - { - char ptr[2]; - /* arg will go onto stack */ - store_address (ptr, 2, val & 0xffff); - si = push_stack_item (si, ptr, 2); - } - } - else { int aligned_regnum = (regnum + 1) & ~1; if (len <= 2 && regnum <= ARGN_REGNUM) @@ -1098,25 +1075,6 @@ d10v_extract_return_value (struct type *type, char regbuf[REGISTER_BYTES], { int len; /* printf("RET: TYPE=%d len=%d r%d=0x%x\n",type->code, TYPE_LENGTH (type), RET1_REGNUM - R0_REGNUM, (int) extract_unsigned_integer (regbuf + REGISTER_BYTE(RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM))); */ - if (TYPE_CODE (type) == TYPE_CODE_PTR - && TYPE_TARGET_TYPE (type) - && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)) - { - /* pointer to function */ - int num; - short snum; - snum = extract_address (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM)); - store_address (valbuf, 4, d10v_make_iaddr (snum)); - } - else if (TYPE_CODE (type) == TYPE_CODE_PTR) - { - /* pointer to data */ - int num; - short snum; - snum = extract_address (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM)); - store_address (valbuf, 4, d10v_make_daddr (snum)); - } - else { len = TYPE_LENGTH (type); if (len == 1) @@ -1516,7 +1474,10 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_max_register_virtual_size (gdbarch, 8); set_gdbarch_register_virtual_type (gdbarch, d10v_register_virtual_type); - set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT); + set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT); + set_gdbarch_addr_bit (gdbarch, 32); + set_gdbarch_address_to_pointer (gdbarch, d10v_address_to_pointer); + set_gdbarch_pointer_to_address (gdbarch, d10v_pointer_to_address); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT); @@ -1558,22 +1519,11 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register); set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy); - set_gdbarch_register_convertible (gdbarch, d10v_register_convertible); - set_gdbarch_register_convert_to_virtual (gdbarch, d10v_register_convert_to_virtual); - set_gdbarch_register_convert_to_raw (gdbarch, d10v_register_convert_to_raw); - set_gdbarch_extract_return_value (gdbarch, d10v_extract_return_value); set_gdbarch_push_arguments (gdbarch, d10v_push_arguments); set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame); set_gdbarch_push_return_address (gdbarch, d10v_push_return_address); - set_gdbarch_d10v_make_daddr (gdbarch, d10v_make_daddr); - set_gdbarch_d10v_make_iaddr (gdbarch, d10v_make_iaddr); - set_gdbarch_d10v_daddr_p (gdbarch, d10v_daddr_p); - set_gdbarch_d10v_iaddr_p (gdbarch, d10v_iaddr_p); - set_gdbarch_d10v_convert_daddr_to_raw (gdbarch, d10v_convert_daddr_to_raw); - set_gdbarch_d10v_convert_iaddr_to_raw (gdbarch, d10v_convert_iaddr_to_raw); - set_gdbarch_store_struct_return (gdbarch, d10v_store_struct_return); set_gdbarch_store_return_value (gdbarch, d10v_store_return_value); set_gdbarch_extract_struct_value_address (gdbarch, d10v_extract_struct_value_address); -- cgit v1.2.1