diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2003-06-13 10:17:05 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2003-06-13 10:17:05 +0000 |
commit | 0261a0d0958db4c66c7a9989a9ac3d778040fe79 (patch) | |
tree | d6ab77c5ec4d75692780c2194a8710ec00843f36 /gdb/h8300-tdep.c | |
parent | 055c394ab6ae368d91af6c40b48287a5339c6891 (diff) | |
download | gdb-0261a0d0958db4c66c7a9989a9ac3d778040fe79.zip gdb-0261a0d0958db4c66c7a9989a9ac3d778040fe79.tar.gz gdb-0261a0d0958db4c66c7a9989a9ac3d778040fe79.tar.bz2 |
* h8300-tdep.c: Add definitions E_RET0_REGNUM and E_RET1_REGNUM to
indicate registers used for return values.
(struct frame_extra_info): Drop args_pointer and locals_pointer.
(h8300_examine_prologue): Remove initializing dropped frame_extra_info
members.
(h8300_init_extra_frame_info): Ditto.
(h8300_frame_locals_address): Removed.
(h8300_frame_args_address): Removed.
(h8300_extract_return_value): Use new regcache structure. Only care
for 16 bit CPUs.
(h8300h_extract_return_value): Same function for 32 bit CPUs.
(h8300_store_return_value): Use new regcache structure. Only care
for 16 bit CPUs.
(h8300h_store_return_value): Same function for 32 bit CPUs.
(h8300_store_struct_return): Removed.
(h8300_extract_struct_value_address): Use new regcache structure.
(h8300h_extract_struct_value_address): Removed.
(h8300_push_dummy_code): New function.
(h8300_gdbarch_init): Slightly rearranged to stress deprecated calls.
Remove call_dummy_words. Call set_gdbarch_extract_return_value and
set_gdbarch_store_return_value architecture dependent.
Call set_gdbarch_push_dummy_code and
set_gdbarch_extract_struct_value_address.
Remove calls to set_gdbarch_frame_args_address,
set_gdbarch_frame_locals_address,
set_gdbarch_deprecated_store_struct_return,
set_gdbarch_deprecated_extract_return_value,
set_gdbarch_deprecated_extract_struct_value_address,
set_gdbarch_deprecated_call_dummy_words and
set_gdbarch_deprecated_sizeof_call_dummy_words.
Diffstat (limited to 'gdb/h8300-tdep.c')
-rw-r--r-- | gdb/h8300-tdep.c | 242 |
1 files changed, 126 insertions, 116 deletions
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c index e9443e7..0ebcf22 100644 --- a/gdb/h8300-tdep.c +++ b/gdb/h8300-tdep.c @@ -40,8 +40,6 @@ struct frame_extra_info { CORE_ADDR from_pc; - CORE_ADDR args_pointer; - CORE_ADDR locals_pointer; }; enum @@ -55,7 +53,8 @@ enum enum gdb_regnum { E_R0_REGNUM, E_ER0_REGNUM = E_R0_REGNUM, E_ARG0_REGNUM = E_R0_REGNUM, - E_R1_REGNUM, E_ER1_REGNUM = E_R1_REGNUM, + E_RET0_REGNUM = E_R0_REGNUM, + E_R1_REGNUM, E_ER1_REGNUM = E_R1_REGNUM, E_RET1_REGNUM = E_R1_REGNUM, E_R2_REGNUM, E_ER2_REGNUM = E_R2_REGNUM, E_ARGLAST_REGNUM = E_R2_REGNUM, E_R3_REGNUM, E_ER3_REGNUM = E_R3_REGNUM, E_R4_REGNUM, E_ER4_REGNUM = E_R4_REGNUM, @@ -443,10 +442,6 @@ h8300_examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit, break; } - /* The args are always reffed based from the stack pointer */ - get_frame_extra_info (fi)->args_pointer = after_prolog_fp; - /* Locals are always reffed based from the fp */ - get_frame_extra_info (fi)->locals_pointer = after_prolog_fp; /* The PC is at a known place */ get_frame_extra_info (fi)->from_pc = read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD); @@ -540,8 +535,6 @@ h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi) { frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info)); get_frame_extra_info (fi)->from_pc = 0; - get_frame_extra_info (fi)->args_pointer = 0; /* Unknown */ - get_frame_extra_info (fi)->locals_pointer = 0; /* Unknown */ if (!get_frame_pc (fi)) { @@ -552,27 +545,6 @@ h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi) } } -static CORE_ADDR -h8300_frame_locals_address (struct frame_info *fi) -{ - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi), - get_frame_base (fi))) - return (CORE_ADDR) 0; /* Not sure what else to do... */ - return get_frame_extra_info (fi)->locals_pointer; -} - -/* Return the address of the argument block for the frame - described by FI. Returns 0 if the address is unknown. */ - -static CORE_ADDR -h8300_frame_args_address (struct frame_info *fi) -{ - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi), - get_frame_base (fi))) - return (CORE_ADDR) 0; /* Not sure what else to do... */ - return get_frame_extra_info (fi)->args_pointer; -} - /* Round N up or down to the nearest multiple of UNIT. Evaluate N only once, UNIT several times. UNIT must be a power of two. */ @@ -795,69 +767,105 @@ h8300_pop_frame (void) Copy that into VALBUF. Be sure to account for CPU type. */ static void -h8300_extract_return_value (struct type *type, char *regbuf, char *valbuf) +h8300_extract_return_value (struct type *type, struct regcache *regcache, + void *valbuf) { - int wordsize = BINWORD; int len = TYPE_LENGTH (type); + ULONGEST c; switch (len) { - case 1: /* (char) */ - case 2: /* (short), (int) */ - memcpy (valbuf, regbuf + REGISTER_BYTE (0) + (wordsize - len), len); - break; - case 4: /* (long), (float) */ - if (wordsize == 4) - { - memcpy (valbuf, regbuf + REGISTER_BYTE (0), 4); - } - else - { - memcpy (valbuf, regbuf + REGISTER_BYTE (0), 2); - memcpy (valbuf + 2, regbuf + REGISTER_BYTE (1), 2); - } - break; - case 8: /* (double) (doesn't seem to happen, which is good, - because this almost certainly isn't right. - FIXME: it will happen for h8sx... */ - error ("I don't know how a double is returned."); - break; + case 1: + case 2: + regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c); + store_unsigned_integer (valbuf, len, c); + break; + case 4: /* Needs two registers on plain H8/300 */ + regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c); + store_unsigned_integer (valbuf, 2, c); + regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c); + store_unsigned_integer ((void*)((char *)valbuf + 2), 2, c); + break; + case 8: /* long long, double and long double are all defined + as 4 byte types so far so this shouldn't happen. */ + error ("I don't know how a 8 byte value is returned."); + break; + } +} + +static void +h8300h_extract_return_value (struct type *type, struct regcache *regcache, + void *valbuf) +{ + int len = TYPE_LENGTH (type); + ULONGEST c; + + switch (len) + { + case 1: + case 2: + case 4: + regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c); + store_unsigned_integer (valbuf, len, c); + break; + case 8: /* long long, double and long double are all defined + as 4 byte types so far so this shouldn't happen. */ + error ("I don't know how a 8 byte value is returned."); + break; } } + /* Function: store_return_value Place the appropriate value in the appropriate registers. Primarily used by the RETURN command. */ static void -h8300_store_return_value (struct type *type, char *valbuf) +h8300_store_return_value (struct type *type, struct regcache *regcache, + const void *valbuf) { - int regval; - int wordsize = BINWORD; int len = TYPE_LENGTH (type); + ULONGEST val; switch (len) { - case 1: /* char */ - case 2: /* short, int */ - regval = extract_unsigned_integer (valbuf, len); - write_register (0, regval); - break; - case 4: /* long, float */ - regval = extract_unsigned_integer (valbuf, len); - if (wordsize == 4) - { - write_register (0, regval); - } - else - { - write_register (0, regval >> 16); - write_register (1, regval & 0xffff); - } - break; - case 8: /* presumeably double, but doesn't seem to happen */ - error ("I don't know how to return a double."); - break; + case 1: + case 2: + val = extract_unsigned_integer (valbuf, len); + regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val); + break; + case 4: /* long, float */ + val = extract_unsigned_integer (valbuf, len); + regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, + (val >> 16) &0xffff); + regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff); + break; + case 8: /* long long, double and long double are all defined + as 4 byte types so far so this shouldn't happen. */ + error ("I don't know how to return a 8 byte value."); + break; + } +} + +static void +h8300h_store_return_value (struct type *type, struct regcache *regcache, + const void *valbuf) +{ + int len = TYPE_LENGTH (type); + ULONGEST val; + + switch (len) + { + case 1: + case 2: + case 4: /* long, float */ + val = extract_unsigned_integer (valbuf, len); + regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val); + break; + case 8: /* long long, double and long double are all defined + as 4 byte types so far so this shouldn't happen. */ + error ("I don't know how to return a 8 byte value."); + break; } } @@ -1032,26 +1040,12 @@ h8300_register_type (struct gdbarch *gdbarch, int regno) } } -static void -h8300_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - write_register (0, addr); -} - static CORE_ADDR -h8300_extract_struct_value_address (char *regbuf) +h8300_extract_struct_value_address (struct regcache *regcache) { - return - extract_unsigned_integer (regbuf + h8300_reg_size * E_ARG0_REGNUM, - h8300_reg_size); -} - -static CORE_ADDR -h8300h_extract_struct_value_address (char *regbuf) -{ - return - extract_unsigned_integer (regbuf + h8300h_reg_size * E_ARG0_REGNUM, - h8300h_reg_size); + ULONGEST addr; + regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr); + return addr; } const static unsigned char * @@ -1064,6 +1058,22 @@ h8300_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) return breakpoint; } +static CORE_ADDR +h8300_push_dummy_code (struct gdbarch *gdbarch, + CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, + struct value **args, int nargs, + struct type *value_type, + CORE_ADDR *real_pc, CORE_ADDR *bp_addr) +{ + /* Allocate space sufficient for a breakpoint. */ + sp = (sp - 2) & ~1; + /* Store the address of that breakpoint */ + *bp_addr = sp; + /* h8300 always starts the call at the callee's entry point. */ + *real_pc = funaddr; + return sp; +} + static void h8300_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args) @@ -1075,7 +1085,6 @@ No floating-point info available for this processor.\n"); static struct gdbarch * h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - static LONGEST call_dummy_words[1] = { 0 }; struct gdbarch_tdep *tdep = NULL; struct gdbarch *gdbarch; @@ -1102,6 +1111,8 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, h8300_register_name); set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT); + set_gdbarch_extract_return_value (gdbarch, h8300_extract_return_value); + set_gdbarch_store_return_value (gdbarch, h8300_store_return_value); break; case bfd_mach_h8300h: case bfd_mach_h8300hn: @@ -1112,6 +1123,8 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, h8300_register_name); set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT); + set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value); + set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value); break; case bfd_mach_h8300s: case bfd_mach_h8300sn: @@ -1122,6 +1135,8 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, h8300s_register_name); set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT); + set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value); + set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value); break; case bfd_mach_h8300sx: case bfd_mach_h8300sxn: @@ -1132,6 +1147,8 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, h8300sx_register_name); set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT); + set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value); + set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value); break; } @@ -1154,6 +1171,8 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* * Frame Info */ + set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue); + set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, h8300_frame_init_saved_regs); set_gdbarch_deprecated_init_extra_frame_info (gdbarch, @@ -1162,9 +1181,6 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_deprecated_saved_pc_after_call (gdbarch, h8300_saved_pc_after_call); set_gdbarch_deprecated_frame_saved_pc (gdbarch, h8300_frame_saved_pc); - set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue); - set_gdbarch_frame_args_address (gdbarch, h8300_frame_args_address); - set_gdbarch_frame_locals_address (gdbarch, h8300_frame_locals_address); /* * Miscelany @@ -1181,26 +1197,11 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue); - /* - * Call Dummies - * - * These values and methods are used when gdb calls a target function. */ - set_gdbarch_deprecated_push_return_address (gdbarch, - h8300_push_return_address); - set_gdbarch_deprecated_extract_return_value (gdbarch, - h8300_extract_return_value); - set_gdbarch_deprecated_push_arguments (gdbarch, h8300_push_arguments); - set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame); - set_gdbarch_deprecated_store_struct_return (gdbarch, - h8300_store_struct_return); - set_gdbarch_deprecated_store_return_value (gdbarch, - h8300_store_return_value); - set_gdbarch_deprecated_extract_struct_value_address - (gdbarch, h8300_extract_struct_value_address); + set_gdbarch_extract_struct_value_address (gdbarch, + h8300_extract_struct_value_address); set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention); - set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_words); - set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0); set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc); + set_gdbarch_push_dummy_code (gdbarch, h8300_push_dummy_code); set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT); @@ -1211,9 +1212,18 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* set_gdbarch_stack_align (gdbarch, SOME_stack_align); */ set_gdbarch_believe_pcc_promotion (gdbarch, 1); - /* Should be using push_dummy_call. */ + /* + * Call Dummies + * + * These values and methods are used when gdb calls a target function. */ + /* Can all be replaced by push_dummy_call */ + set_gdbarch_deprecated_push_return_address (gdbarch, + h8300_push_return_address); + set_gdbarch_deprecated_push_arguments (gdbarch, h8300_push_arguments); + set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame); set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp); + return gdbarch; } |