X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fm68k-tdep.c;h=90cb169234f4ad1144056ec3ba5ade395e1d55c6;hb=df1f7f58bb9018211615ce880b558408e52fef2e;hp=be1845ee548f1bf2f9109b0a790ba762fc461d32;hpb=e2e0b3e57f11bb2539724fc955af7e22380613c1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index be1845ee54..90cb169234 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -1,7 +1,7 @@ /* Target-dependent code for the Motorola 68000 series. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, - 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GDB. @@ -17,15 +17,15 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "dwarf2-frame.h" #include "frame.h" #include "frame-base.h" #include "frame-unwind.h" -#include "floatformat.h" +#include "gdbtypes.h" #include "symtab.h" #include "gdbcore.h" #include "value.h" @@ -65,10 +65,10 @@ #define BPT_VECTOR 0xf #endif -static const unsigned char * +static const gdb_byte * m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) { - static unsigned char break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; + static gdb_byte break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; *lenptr = sizeof (break_insn); return break_insn; } @@ -122,8 +122,7 @@ m68k_register_name (int regnum) "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" }; - if (regnum < 0 || - regnum >= sizeof (register_names) / sizeof (register_names[0])) + if (regnum < 0 || regnum >= ARRAY_SIZE (register_names)) internal_error (__FILE__, __LINE__, _("m68k_register_name: illegal register number %d"), regnum); else @@ -144,9 +143,9 @@ m68k_convert_register_p (int regnum, struct type *type) static void m68k_register_to_value (struct frame_info *frame, int regnum, - struct type *type, void *to) + struct type *type, gdb_byte *to) { - char from[M68K_MAX_REGISTER_SIZE]; + gdb_byte from[M68K_MAX_REGISTER_SIZE]; /* We only support floating-point values. */ if (TYPE_CODE (type) != TYPE_CODE_FLT) @@ -167,9 +166,9 @@ m68k_register_to_value (struct frame_info *frame, int regnum, static void m68k_value_to_register (struct frame_info *frame, int regnum, - struct type *type, const void *from) + struct type *type, const gdb_byte *from) { - char to[M68K_MAX_REGISTER_SIZE]; + gdb_byte to[M68K_MAX_REGISTER_SIZE]; /* We only support floating-point values. */ if (TYPE_CODE (type) != TYPE_CODE_FLT) @@ -220,10 +219,10 @@ m68k_value_to_register (struct frame_info *frame, int regnum, static void m68k_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) + gdb_byte *valbuf) { int len = TYPE_LENGTH (type); - char buf[M68K_MAX_REGISTER_SIZE]; + gdb_byte buf[M68K_MAX_REGISTER_SIZE]; if (len <= 4) { @@ -234,8 +233,7 @@ m68k_extract_return_value (struct type *type, struct regcache *regcache, { regcache_raw_read (regcache, M68K_D0_REGNUM, buf); memcpy (valbuf, buf + (8 - len), len - 4); - regcache_raw_read (regcache, M68K_D1_REGNUM, - (char *) valbuf + (len - 4)); + regcache_raw_read (regcache, M68K_D1_REGNUM, valbuf + (len - 4)); } else internal_error (__FILE__, __LINE__, @@ -244,10 +242,10 @@ m68k_extract_return_value (struct type *type, struct regcache *regcache, static void m68k_svr4_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) + gdb_byte *valbuf) { int len = TYPE_LENGTH (type); - char buf[M68K_MAX_REGISTER_SIZE]; + gdb_byte buf[M68K_MAX_REGISTER_SIZE]; if (TYPE_CODE (type) == TYPE_CODE_FLT) { @@ -264,7 +262,7 @@ m68k_svr4_extract_return_value (struct type *type, struct regcache *regcache, static void m68k_store_return_value (struct type *type, struct regcache *regcache, - const void *valbuf) + const gdb_byte *valbuf) { int len = TYPE_LENGTH (type); @@ -274,8 +272,7 @@ m68k_store_return_value (struct type *type, struct regcache *regcache, { regcache_raw_write_part (regcache, M68K_D0_REGNUM, 8 - len, len - 4, valbuf); - regcache_raw_write (regcache, M68K_D1_REGNUM, - (char *) valbuf + (len - 4)); + regcache_raw_write (regcache, M68K_D1_REGNUM, valbuf + (len - 4)); } else internal_error (__FILE__, __LINE__, @@ -284,13 +281,13 @@ m68k_store_return_value (struct type *type, struct regcache *regcache, static void m68k_svr4_store_return_value (struct type *type, struct regcache *regcache, - const void *valbuf) + const gdb_byte *valbuf) { int len = TYPE_LENGTH (type); if (TYPE_CODE (type) == TYPE_CODE_FLT) { - char buf[M68K_MAX_REGISTER_SIZE]; + gdb_byte buf[M68K_MAX_REGISTER_SIZE]; convert_typed_floating (valbuf, type, buf, builtin_type_m68881_ext); regcache_raw_write (regcache, M68K_FP0_REGNUM, buf); } @@ -330,18 +327,30 @@ m68k_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type) static enum return_value_convention m68k_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, void *readbuf, - const void *writebuf) + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); - if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) - && !m68k_reg_struct_return_p (gdbarch, type)) - return RETURN_VALUE_STRUCT_CONVENTION; + /* GCC returns a `long double' in memory too. */ + if (((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) + && !m68k_reg_struct_return_p (gdbarch, type)) + || (code == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12)) + { + /* The default on m68k is to return structures in static memory. + Consequently a function must return the address where we can + find the return value. */ + + if (readbuf) + { + ULONGEST addr; + + regcache_raw_read_unsigned (regcache, M68K_D0_REGNUM, &addr); + read_memory (addr, readbuf, TYPE_LENGTH (type)); + } - /* GCC returns a `long double' in memory. */ - if (code == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12) - return RETURN_VALUE_STRUCT_CONVENTION; + return RETURN_VALUE_ABI_RETURNS_ADDRESS; + } if (readbuf) m68k_extract_return_value (type, regcache, readbuf); @@ -353,8 +362,8 @@ m68k_return_value (struct gdbarch *gdbarch, struct type *type, static enum return_value_convention m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, void *readbuf, - const void *writebuf) + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); @@ -404,6 +413,16 @@ m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *type, } +/* Always align the frame to a 4-byte boundary. This is required on + coldfire and harmless on the rest. */ + +static CORE_ADDR +m68k_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) +{ + /* Align the stack to four bytes. */ + return sp & ~3; +} + static CORE_ADDR m68k_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, @@ -411,7 +430,7 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, struct value *function, CORE_ADDR struct_addr) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - char buf[4]; + gdb_byte buf[4]; int i; /* Push arguments in reverse order. */ @@ -458,6 +477,28 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, struct value *function, frame's CFA. */ return sp + 8; } + +/* Convert a dwarf or dwarf2 regnumber to a GDB regnum. */ + +static int +m68k_dwarf_reg_to_regnum (int num) +{ + if (num < 8) + /* d0..7 */ + return (num - 0) + M68K_D0_REGNUM; + else if (num < 16) + /* a0..7 */ + return (num - 8) + M68K_A0_REGNUM; + else if (num < 24) + /* fp0..7 */ + return (num - 16) + M68K_FP0_REGNUM; + else if (num == 25) + /* pc */ + return M68K_PC_REGNUM; + else + return NUM_REGS + NUM_PSEUDO_REGS; +} + struct m68k_frame_cache { @@ -636,10 +677,10 @@ m68k_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc, else break; } - else if ((op & 0170677) == P_MOVEL_SP) + else if ((op & 0177760) == P_MOVEL_SP) { /* move.l %R,-(%sp) */ - regno = ((op & 07000) >> 9) | ((op & 0100) >> 3); + regno = op & 017; cache->saved_regs[regno] = offset; offset -= 4; pc += 2; @@ -740,7 +781,7 @@ m68k_skip_prologue (CORE_ADDR start_pc) static CORE_ADDR m68k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - char buf[8]; + gdb_byte buf[8]; frame_unwind_register (next_frame, PC_REGNUM, buf); return extract_typed_address (buf, builtin_type_void_func_ptr); @@ -752,7 +793,7 @@ static struct m68k_frame_cache * m68k_frame_cache (struct frame_info *next_frame, void **this_cache) { struct m68k_frame_cache *cache; - char buf[4]; + gdb_byte buf[4]; int i; if (*this_cache) @@ -778,7 +819,7 @@ m68k_frame_cache (struct frame_info *next_frame, void **this_cache) /* For normal frames, %pc is stored at 4(%fp). */ cache->saved_regs[M68K_PC_REGNUM] = 4; - cache->pc = frame_func_unwind (next_frame); + cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME); if (cache->pc != 0) m68k_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache); @@ -827,7 +868,7 @@ static void m68k_frame_prev_register (struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *valuep) + int *realnump, gdb_byte *valuep) { struct m68k_frame_cache *cache = m68k_frame_cache (next_frame, this_cache); @@ -902,7 +943,7 @@ static const struct frame_base m68k_frame_base = static struct frame_id m68k_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { - char buf[4]; + gdb_byte buf[4]; CORE_ADDR fp; frame_unwind_register (next_frame, M68K_FP_REGNUM, buf); @@ -1054,7 +1095,7 @@ fill_fpregset (fpregset_t *fpregsetp, int regno) static int m68k_get_longjmp_target (CORE_ADDR *pc) { - char *buf; + gdb_byte *buf; CORE_ADDR sp, jb_addr; struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); @@ -1116,7 +1157,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep = xmalloc (sizeof (struct gdbarch_tdep)); gdbarch = gdbarch_alloc (&info, tdep); - set_gdbarch_long_double_format (gdbarch, &floatformat_m68881_ext); + set_gdbarch_long_double_format (gdbarch, floatformats_m68881_ext); set_gdbarch_long_double_bit (gdbarch, 96); set_gdbarch_skip_prologue (gdbarch, m68k_skip_prologue); @@ -1124,15 +1165,18 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Stack grows down. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_frame_align (gdbarch, m68k_frame_align); set_gdbarch_believe_pcc_promotion (gdbarch, 1); set_gdbarch_decr_pc_after_break (gdbarch, 2); set_gdbarch_frame_args_skip (gdbarch, 8); + set_gdbarch_dwarf_reg_to_regnum (gdbarch, m68k_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, m68k_dwarf_reg_to_regnum); set_gdbarch_register_type (gdbarch, m68k_register_type); set_gdbarch_register_name (gdbarch, m68k_register_name); - set_gdbarch_num_regs (gdbarch, 29); + set_gdbarch_num_regs (gdbarch, M68K_NUM_REGS); set_gdbarch_register_bytes_ok (gdbarch, m68k_register_bytes_ok); set_gdbarch_sp_regnum (gdbarch, M68K_SP_REGNUM); set_gdbarch_pc_regnum (gdbarch, M68K_PC_REGNUM);