X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fm68k-tdep.c;h=a42f699d746f6c2a77437597433d99fe6cf17e80;hb=9b254dd1ce46c19dde1dde5b8d1e22e862dfacce;hp=a3b0b307051b4a5d35d7061d1386840a9b67aa34;hpb=8ed86d01ca8b14c14f37429df136130158066f8a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index a3b0b30705..a42f699d74 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -1,13 +1,13 @@ /* Target-dependent code for the Motorola 68000 series. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,9 +16,7 @@ GNU General Public License for more details. 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "dwarf2-frame.h" @@ -63,12 +61,39 @@ #endif static const gdb_byte * -m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +m68k_local_breakpoint_from_pc (struct gdbarch *gdbarch, + CORE_ADDR *pcptr, int *lenptr) { static gdb_byte break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; *lenptr = sizeof (break_insn); return break_insn; } + + +/* Type for %ps. */ +struct type *m68k_ps_type; + +/* Construct types for ISA-specific registers. */ +static void +m68k_init_types (void) +{ + struct type *type; + + type = init_flags_type ("builtin_type_m68k_ps", 4); + append_flags_type_flag (type, 0, "C"); + append_flags_type_flag (type, 1, "V"); + append_flags_type_flag (type, 2, "Z"); + append_flags_type_flag (type, 3, "N"); + append_flags_type_flag (type, 4, "X"); + append_flags_type_flag (type, 8, "I0"); + append_flags_type_flag (type, 9, "I1"); + append_flags_type_flag (type, 10, "I2"); + append_flags_type_flag (type, 12, "M"); + append_flags_type_flag (type, 13, "S"); + append_flags_type_flag (type, 14, "T0"); + append_flags_type_flag (type, 15, "T1"); + m68k_ps_type = type; +} /* Return the GDB type object for the "standard" data type of data in register N. This should be int for D0-D7, SR, FPCONTROL and @@ -81,11 +106,12 @@ m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) static struct type * m68k_register_type (struct gdbarch *gdbarch, int regnum) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep->fpregs_present) { - if (regnum >= FP0_REGNUM && regnum <= FP0_REGNUM + 7) + if (regnum >= gdbarch_fp0_regnum (gdbarch) + && regnum <= gdbarch_fp0_regnum (gdbarch) + 7) { if (tdep->flavour == m68k_coldfire_flavour) return builtin_type (gdbarch)->builtin_double; @@ -105,12 +131,15 @@ m68k_register_type (struct gdbarch *gdbarch, int regnum) return builtin_type_int0; } - if (regnum == PC_REGNUM) + if (regnum == gdbarch_pc_regnum (gdbarch)) return builtin_type_void_func_ptr; if (regnum >= M68K_A0_REGNUM && regnum <= M68K_A0_REGNUM + 7) return builtin_type_void_data_ptr; + if (regnum == M68K_PS_REGNUM) + return m68k_ps_type; + return builtin_type_int32; } @@ -126,7 +155,7 @@ static const char *m68k_register_names[] = { Returns the name of the standard m68k register regnum. */ static const char * -m68k_register_name (int regnum) +m68k_register_name (struct gdbarch *gdbarch, int regnum) { if (regnum < 0 || regnum >= ARRAY_SIZE (m68k_register_names)) internal_error (__FILE__, __LINE__, @@ -139,11 +168,12 @@ m68k_register_name (int regnum) needs any special handling. */ static int -m68k_convert_register_p (int regnum, struct type *type) +m68k_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) { - if (!gdbarch_tdep (current_gdbarch)->fpregs_present) + if (!gdbarch_tdep (gdbarch)->fpregs_present) return 0; - return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FP0_REGNUM + 7); + return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FP0_REGNUM + 7 + && type != builtin_type_m68881_ext); } /* Read a value of type TYPE from register REGNUM in frame FRAME, and @@ -154,7 +184,8 @@ m68k_register_to_value (struct frame_info *frame, int regnum, struct type *type, gdb_byte *to) { gdb_byte from[M68K_MAX_REGISTER_SIZE]; - struct type *fpreg_type = register_type (current_gdbarch, M68K_FP0_REGNUM); + struct type *fpreg_type = register_type (get_frame_arch (frame), + M68K_FP0_REGNUM); /* We only support floating-point values. */ if (TYPE_CODE (type) != TYPE_CODE_FLT) @@ -164,8 +195,7 @@ m68k_register_to_value (struct frame_info *frame, int regnum, return; } - /* Convert to TYPE. This should be a no-op if TYPE is equivalent to - the extended floating-point format used by the FPU. */ + /* Convert to TYPE. */ get_frame_register (frame, regnum, from); convert_typed_floating (from, fpreg_type, to, type); } @@ -178,7 +208,8 @@ m68k_value_to_register (struct frame_info *frame, int regnum, struct type *type, const gdb_byte *from) { gdb_byte to[M68K_MAX_REGISTER_SIZE]; - struct type *fpreg_type = register_type (current_gdbarch, M68K_FP0_REGNUM); + struct type *fpreg_type = register_type (get_frame_arch (frame), + M68K_FP0_REGNUM); /* We only support floating-point values. */ if (TYPE_CODE (type) != TYPE_CODE_FLT) @@ -188,8 +219,7 @@ m68k_value_to_register (struct frame_info *frame, int regnum, return; } - /* Convert from TYPE. This should be a no-op if TYPE is equivalent - to the extended floating-point format used by the FPU. */ + /* Convert from TYPE. */ convert_typed_floating (from, type, to, fpreg_type); put_frame_register (frame, regnum, to); } @@ -256,12 +286,12 @@ m68k_svr4_extract_return_value (struct type *type, struct regcache *regcache, { int len = TYPE_LENGTH (type); gdb_byte buf[M68K_MAX_REGISTER_SIZE]; - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep->float_return && TYPE_CODE (type) == TYPE_CODE_FLT) { - struct type *fpreg_type = register_type - (current_gdbarch, M68K_FP0_REGNUM); + struct type *fpreg_type = register_type (gdbarch, M68K_FP0_REGNUM); regcache_raw_read (regcache, M68K_FP0_REGNUM, buf); convert_typed_floating (buf, fpreg_type, valbuf, type); } @@ -297,12 +327,12 @@ m68k_svr4_store_return_value (struct type *type, struct regcache *regcache, const gdb_byte *valbuf) { int len = TYPE_LENGTH (type); - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep->float_return && TYPE_CODE (type) == TYPE_CODE_FLT) { - struct type *fpreg_type = register_type - (current_gdbarch, M68K_FP0_REGNUM); + struct type *fpreg_type = register_type (gdbarch, M68K_FP0_REGNUM); gdb_byte buf[M68K_MAX_REGISTER_SIZE]; convert_typed_floating (valbuf, type, buf, fpreg_type); regcache_raw_write (regcache, M68K_FP0_REGNUM, buf); @@ -497,7 +527,7 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Convert a dwarf or dwarf2 regnumber to a GDB regnum. */ static int -m68k_dwarf_reg_to_regnum (int num) +m68k_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num) { if (num < 8) /* d0..7 */ @@ -505,15 +535,14 @@ m68k_dwarf_reg_to_regnum (int num) else if (num < 16) /* a0..7 */ return (num - 8) + M68K_A0_REGNUM; - else if (num < 24 && gdbarch_tdep (current_gdbarch)->fpregs_present) + else if (num < 24 && gdbarch_tdep (gdbarch)->fpregs_present) /* fp0..7 */ return (num - 16) + M68K_FP0_REGNUM; else if (num == 25) /* pc */ return M68K_PC_REGNUM; else - return gdbarch_num_regs (current_gdbarch) - + gdbarch_num_pseudo_regs (current_gdbarch); + return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); } @@ -801,7 +830,7 @@ m68k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { gdb_byte buf[8]; - frame_unwind_register (next_frame, PC_REGNUM, buf); + frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf); return extract_typed_address (buf, builtin_type_void_func_ptr); } @@ -916,7 +945,7 @@ m68k_frame_prev_register (struct frame_info *next_frame, void **this_cache, { /* Read the value in from memory. */ read_memory (*addrp, valuep, - register_size (current_gdbarch, regnum)); + register_size (get_frame_arch (next_frame), regnum)); } return; } @@ -978,11 +1007,12 @@ m68k_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) This routine returns true on success. */ static int -m68k_get_longjmp_target (CORE_ADDR *pc) +m68k_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { gdb_byte *buf; CORE_ADDR sp, jb_addr; - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); if (tdep->jb_pc < 0) { @@ -991,22 +1021,21 @@ m68k_get_longjmp_target (CORE_ADDR *pc) return 0; } - buf = alloca (gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT); - sp = read_register (SP_REGNUM); + buf = alloca (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + sp = get_frame_register_unsigned (frame, gdbarch_sp_regnum (gdbarch)); if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */ - buf, - gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT)) + buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT)) return 0; - jb_addr = extract_unsigned_integer (buf, gdbarch_ptr_bit (current_gdbarch) + jb_addr = extract_unsigned_integer (buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf, - gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT)) + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT)) return 0; - *pc = extract_unsigned_integer (buf, gdbarch_ptr_bit (current_gdbarch) + *pc = extract_unsigned_integer (buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); return 1; } @@ -1109,14 +1138,14 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) and the type of long double depend on whether we're on ColdFire or standard m68k. */ - if (info.bfd_arch_info) + if (info.bfd_arch_info && info.bfd_arch_info->mach != 0) { const bfd_arch_info_type *coldfire_arch = bfd_lookup_arch (bfd_arch_m68k, bfd_mach_mcf_isa_a_nodiv); if (coldfire_arch - && (*info.bfd_arch_info->compatible) - (info.bfd_arch_info, coldfire_arch)) + && ((*info.bfd_arch_info->compatible) + (info.bfd_arch_info, coldfire_arch))) flavour = m68k_coldfire_flavour; } @@ -1227,16 +1256,16 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) frame_unwind_append_sniffer (gdbarch, m68k_frame_sniffer); if (tdesc_data) - tdesc_use_registers (gdbarch, tdesc_data); + tdesc_use_registers (gdbarch, info.target_desc, tdesc_data); return gdbarch; } static void -m68k_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +m68k_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep == NULL) return; @@ -1248,4 +1277,7 @@ void _initialize_m68k_tdep (void) { gdbarch_register (bfd_arch_m68k, m68k_gdbarch_init, m68k_dump_tdep); + + /* Initialize the m68k-specific register types. */ + m68k_init_types (); }