Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / gdb / m68k-tdep.c
index a3b0b307051b4a5d35d7061d1386840a9b67aa34..a42f699d746f6c2a77437597433d99fe6cf17e80 100644 (file)
@@ -1,13 +1,13 @@
 /* Target-dependent code for the Motorola 68000 series.
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
 /* 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
 
    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,
    (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
    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 <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "dwarf2-frame.h"
 
 #include "defs.h"
 #include "dwarf2-frame.h"
 #endif
 
 static const gdb_byte *
 #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;
 }
 {
   static gdb_byte break_insn[] = {0x4e, (0x40 | BPT_VECTOR)};
   *lenptr = sizeof (break_insn);
   return break_insn;
 }
+\f
+
+/* 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
 
 /* 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)
 {
 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 (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;
        {
          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;
     }
 
        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;
 
     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;
 }
 
   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 *
    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__,
 {
   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
    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 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
 }
 
 /* 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 *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)
 
   /* 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;
     }
 
       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);
 }
   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 *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)
 
   /* 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;
     }
 
       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);
 }
   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];
 {
   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)
     {
 
   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);
     }
       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);
                              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)
     {
 
   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);
       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
 /* 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 */
 {
   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 < 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
     /* 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);
 }
 
 \f
 }
 
 \f
@@ -801,7 +830,7 @@ m68k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   gdb_byte buf[8];
 
 {
   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);
 }
 \f
   return extract_typed_address (buf, builtin_type_void_func_ptr);
 }
 \f
@@ -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,
        {
          /* Read the value in from memory.  */
          read_memory (*addrp, valuep,
-                      register_size (current_gdbarch, regnum));
+                      register_size (get_frame_arch (next_frame), regnum));
        }
       return;
     }
        }
       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
    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;
 {
   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)
     {
 
   if (tdep->jb_pc < 0)
     {
@@ -991,22 +1021,21 @@ m68k_get_longjmp_target (CORE_ADDR *pc)
       return 0;
     }
 
       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 */
 
   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;
 
     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,
                                             / 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;
 
     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;
 }
                                         / 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. */
 
      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
     {
       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;
     }
   
        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)
   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
 
   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;
 
   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_m68k_tdep (void)
 {
   gdbarch_register (bfd_arch_m68k, m68k_gdbarch_init, m68k_dump_tdep);
+
+  /* Initialize the m68k-specific register types.  */
+  m68k_init_types ();
 }
 }
This page took 0.040475 seconds and 4 git commands to generate.