* Makefile.in (LDFLAGS): Allow the configure script to establish a
[deliverable/binutils-gdb.git] / gdb / m68k-tdep.c
index c66615bea233218c55191375bd6cfde045f561f0..b00b0ee3c94407523c8ef2246aa165bfc2fa4fd8 100644 (file)
@@ -1,5 +1,5 @@
 /* Target dependent code for the Motorola 68000 series.
 /* Target dependent code for the Motorola 68000 series.
-   Copyright (C) 1990, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GDB.
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -26,6 +26,8 @@
 #include "value.h"
 #include "gdb_string.h"
 #include "inferior.h"
 #include "value.h"
 #include "gdb_string.h"
 #include "inferior.h"
+#include "regcache.h"
+#include "arch-utils.h"
 \f
 
 #define P_LINKL_FP     0x480e
 \f
 
 #define P_LINKL_FP     0x480e
 #define P_FMOVM                0xf237
 #define P_TRAP         0x4e40
 
 #define P_FMOVM                0xf237
 #define P_TRAP         0x4e40
 
-/* The only reason this is here is the tm-altos.h reference below.  It
-   was moved back here from tm-m68k.h.  FIXME? */
 
 
-extern CORE_ADDR
-altos_skip_prologue (CORE_ADDR pc)
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+/* Note: Since they are used in files other than this (monitor files), 
+   D0_REGNUM and A0_REGNUM are currently defined in tm-m68k.h.  */
+
+enum
 {
 {
-  register int op = read_memory_integer (pc, 2);
-  if (op == P_LINKW_FP)
-    pc += 4;                   /* Skip link #word */
-  else if (op == P_LINKL_FP)
-    pc += 6;                   /* Skip link #long */
-  /* Not sure why branches are here.  */
-  /* From tm-isi.h, tm-altos.h */
-  else if (op == 0060000)
-    pc += 4;                   /* Skip bra #word */
-  else if (op == 00600377)
-    pc += 6;                   /* skip bra #long */
-  else if ((op & 0177400) == 0060000)
-    pc += 2;                   /* skip bra #char */
-  return pc;
+  E_A1_REGNUM = 9,
+  E_FP_REGNUM = 14,            /* Contains address of executing stack frame */
+  E_SP_REGNUM = 15,            /* Contains address of top of stack */
+  E_PS_REGNUM = 16,            /* Contains processor status */
+  E_PC_REGNUM = 17,            /* Contains program counter */
+  E_FP0_REGNUM = 18,           /* Floating point register 0 */
+  E_FPC_REGNUM = 26,           /* 68881 control register */
+  E_FPS_REGNUM = 27,           /* 68881 status register */
+  E_FPI_REGNUM = 28
+};
+
+#define REGISTER_BYTES_FP (16*4 + 8 + 8*12 + 3*4)
+#define REGISTER_BYTES_NOFP (16*4 + 8)
+
+#define NUM_FREGS (NUM_REGS-24)
+
+/* Offset from SP to first arg on stack at first instruction of a function */
+
+#define SP_ARG0 (1 * 4)
+
+/* This was determined by experimentation on hp300 BSD 4.3.  Perhaps
+   it corresponds to some offset in /usr/include/sys/user.h or
+   something like that.  Using some system include file would
+   have the advantage of probably being more robust in the face
+   of OS upgrades, but the disadvantage of being wrong for
+   cross-debugging.  */
+
+#define SIG_PC_FP_OFFSET 530
+
+#define TARGET_M68K
+
+
+#if !defined (BPT_VECTOR)
+#define BPT_VECTOR 0xf
+#endif
+
+#if !defined (REMOTE_BPT_VECTOR)
+#define REMOTE_BPT_VECTOR 1
+#endif
+
+
+void m68k_frame_init_saved_regs (struct frame_info *frame_info);
+
+
+/* gdbarch_breakpoint_from_pc is set to m68k_local_breakpoint_from_pc
+   so m68k_remote_breakpoint_from_pc is currently not used.  */
+
+const static unsigned char *
+m68k_remote_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+  static unsigned char break_insn[] = {0x4e, (0x40 | REMOTE_BPT_VECTOR)};
+  *lenptr = sizeof (break_insn);
+  return break_insn;
+}
+
+const static unsigned char *
+m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+  static unsigned char break_insn[] = {0x4e, (0x40 | BPT_VECTOR)};
+  *lenptr = sizeof (break_insn);
+  return break_insn;
+}
+
+
+static int
+m68k_register_bytes_ok (long numbytes)
+{
+  return ((numbytes == REGISTER_BYTES_FP)
+         || (numbytes == REGISTER_BYTES_NOFP));
+}
+
+/* Number of bytes of storage in the actual machine representation
+   for register regnum.  On the 68000, all regs are 4 bytes
+   except the floating point regs which are 12 bytes.  */
+/* Note that the unsigned cast here forces the result of the
+   subtraction to very high positive values if regnum < FP0_REGNUM */
+
+static int
+m68k_register_raw_size (int regnum)
+{
+  return (((unsigned) (regnum) - FP0_REGNUM) < 8 ? 12 : 4);
+}
+
+/* Number of bytes of storage in the program's representation
+   for register regnum.  On the 68000, all regs are 4 bytes
+   except the floating point regs which are 12-byte long doubles.  */
+
+static int
+m68k_register_virtual_size (int regnum)
+{
+  return (((unsigned) (regnum) - FP0_REGNUM) < 8 ? 12 : 4);
+}
+
+/* Return the GDB type object for the "standard" data type of data 
+   in register N.  This should be int for D0-D7, long double for FP0-FP7,
+   and void pointer for all others (A0-A7, PC, SR, FPCONTROL etc).
+   Note, for registers which contain addresses return pointer to void, 
+   not pointer to char, because we don't want to attempt to print 
+   the string after printing the address.  */
+
+static struct type *
+m68k_register_virtual_type (int regnum)
+{
+  if ((unsigned) regnum >= E_FPC_REGNUM)
+    return lookup_pointer_type (builtin_type_void);
+  else if ((unsigned) regnum >= FP0_REGNUM)
+    return builtin_type_long_double;
+  else if ((unsigned) regnum >= A0_REGNUM)
+    return lookup_pointer_type (builtin_type_void);
+  else
+    return builtin_type_int;
+}
+
+/* Function: m68k_register_name
+   Returns the name of the standard m68k register regnum. */
+
+static const char *
+m68k_register_name (int regnum)
+{
+  static char *register_names[] = {
+    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+    "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp",
+    "ps", "pc",
+    "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
+    "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags"
+  };
+
+  if (regnum < 0 ||
+      regnum >= sizeof (register_names) / sizeof (register_names[0]))
+    internal_error (__FILE__, __LINE__,
+                   "m68k_register_name: illegal register number %d", regnum);
+  else
+    return register_names[regnum];
+}
+
+/* Stack must be kept short aligned when doing function calls.  */
+
+static CORE_ADDR
+m68k_stack_align (CORE_ADDR addr)
+{
+  return ((addr + 1) & ~1);
+}
+
+/* Index within `registers' of the first byte of the space for
+   register regnum.  */
+
+static int
+m68k_register_byte (int regnum)
+{
+  if (regnum >= E_FPC_REGNUM)
+    return (((regnum - E_FPC_REGNUM) * 4) + 168);
+  else if (regnum >= FP0_REGNUM)
+    return (((regnum - FP0_REGNUM) * 12) + 72);
+  else
+    return (regnum * 4);
+}
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+static void
+m68k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+  write_register (E_A1_REGNUM, addr);
+}
+
+/* Extract from an array regbuf containing the (raw) register state
+   a function return value of type type, and copy that, in virtual format,
+   into valbuf.  This is assuming that floating point values are returned
+   as doubles in d0/d1.  */
+
+static void
+m68k_deprecated_extract_return_value (struct type *type, char *regbuf,
+                                     char *valbuf)
+{
+  int offset = 0;
+  int typeLength = TYPE_LENGTH (type);
+
+  if (typeLength < 4)
+    offset = 4 - typeLength;
+
+  memcpy (valbuf, regbuf + offset, typeLength);
+}
+
+static CORE_ADDR
+m68k_deprecated_extract_struct_value_address (char *regbuf)
+{
+  return (*(CORE_ADDR *) (regbuf));
 }
 
 }
 
-/* The only reason this is here is the tm-isi.h reference below.  It
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  Assumes floats are passed
+   in d0/d1.  */
+
+static void
+m68k_store_return_value (struct type *type, char *valbuf)
+{
+  write_register_bytes (0, valbuf, TYPE_LENGTH (type));
+}
+
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
+   chain-pointer.
+   In the case of the 68000, the frame's nominal address
+   is the address of a 4-byte word containing the calling frame's address.  */
+
+/* If we are chaining from sigtramp, then manufacture a sigtramp frame
+   (which isn't really on the stack.  I'm not sure this is right for anything
+   but BSD4.3 on an hp300.  */
+
+static CORE_ADDR
+m68k_frame_chain (struct frame_info *thisframe)
+{
+  if (thisframe->signal_handler_caller)
+    return thisframe->frame;
+  else if (!inside_entry_file ((thisframe)->pc))
+    return read_memory_integer ((thisframe)->frame, 4);
+  else
+    return 0;
+}
+
+/* A function that tells us whether the function invocation represented
+   by fi does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+
+static int
+m68k_frameless_function_invocation (struct frame_info *fi)
+{
+  if (fi->signal_handler_caller)
+    return 0;
+  else
+    return frameless_look_for_prologue (fi);
+}
+
+static CORE_ADDR
+m68k_frame_saved_pc (struct frame_info *frame)
+{
+  if (frame->signal_handler_caller)
+    {
+      if (frame->next)
+       return read_memory_integer (frame->next->frame + SIG_PC_FP_OFFSET, 4);
+      else
+       return read_memory_integer (read_register (SP_REGNUM)
+                                   + SIG_PC_FP_OFFSET - 8, 4);
+    }
+  else
+    return read_memory_integer (frame->frame + 4, 4);
+}
+
+
+/* The only reason this is here is the tm-altos.h reference below.  It
    was moved back here from tm-m68k.h.  FIXME? */
 
 extern CORE_ADDR
    was moved back here from tm-m68k.h.  FIXME? */
 
 extern CORE_ADDR
-isi_skip_prologue (CORE_ADDR pc)
+altos_skip_prologue (CORE_ADDR pc)
 {
   register int op = read_memory_integer (pc, 2);
   if (op == P_LINKW_FP)
 {
   register int op = read_memory_integer (pc, 2);
   if (op == P_LINKW_FP)
@@ -74,7 +319,7 @@ isi_skip_prologue (CORE_ADDR pc)
   else if (op == P_LINKL_FP)
     pc += 6;                   /* Skip link #long */
   /* Not sure why branches are here.  */
   else if (op == P_LINKL_FP)
     pc += 6;                   /* Skip link #long */
   /* Not sure why branches are here.  */
-  /* From tm-isi.h, tm-altos.h */
+  /* From tm-altos.h */
   else if (op == 0060000)
     pc += 4;                   /* Skip bra #word */
   else if (op == 00600377)
   else if (op == 0060000)
     pc += 4;                   /* Skip bra #word */
   else if (op == 00600377)
@@ -102,11 +347,11 @@ delta68_frame_args_address (struct frame_info *frame_info)
     return frame_info->frame + 12;
   else if (frameless_look_for_prologue (frame_info))
     {
     return frame_info->frame + 12;
   else if (frameless_look_for_prologue (frame_info))
     {
-    /* Check for an interrupted system call */
-    if (frame_info->next && frame_info->next->signal_handler_caller)
-      return frame_info->next->frame + 16;
-    else
-      return frame_info->frame + 4;
+      /* Check for an interrupted system call */
+      if (frame_info->next && frame_info->next->signal_handler_caller)
+       return frame_info->next->frame + 16;
+      else
+       return frame_info->frame + 4;
     }
   else
     return frame_info->frame;
     }
   else
     return frame_info->frame;
@@ -187,6 +432,20 @@ news_frame_num_args (struct frame_info *fi)
   return val;
 }
 
   return val;
 }
 
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.
+   We use the BFD routines to store a big-endian value of known size.  */
+
+void
+m68k_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+                    struct value **args, struct type *type, int gcc_p)
+{
+  bfd_putb32 (fun, (unsigned char *) dummy + CALL_DUMMY_START_OFFSET + 2);
+  bfd_putb32 (nargs * 4,
+             (unsigned char *) dummy + CALL_DUMMY_START_OFFSET + 8);
+}
+
+
 /* Push an empty stack frame, to record the current PC, etc.  */
 
 void
 /* Push an empty stack frame, to record the current PC, etc.  */
 
 void
@@ -225,29 +484,30 @@ m68k_pop_frame (void)
   register struct frame_info *frame = get_current_frame ();
   register CORE_ADDR fp;
   register int regnum;
   register struct frame_info *frame = get_current_frame ();
   register CORE_ADDR fp;
   register int regnum;
-  struct frame_saved_regs fsr;
   char raw_buffer[12];
 
   fp = FRAME_FP (frame);
   char raw_buffer[12];
 
   fp = FRAME_FP (frame);
-  get_frame_saved_regs (frame, &fsr);
+  m68k_frame_init_saved_regs (frame);
   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
     {
   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
     {
-      if (fsr.regs[regnum])
+      if (frame->saved_regs[regnum])
        {
        {
-         read_memory (fsr.regs[regnum], raw_buffer, 12);
+         read_memory (frame->saved_regs[regnum], raw_buffer, 12);
          write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
        }
     }
   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
     {
          write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
        }
     }
   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
     {
-      if (fsr.regs[regnum])
+      if (frame->saved_regs[regnum])
        {
        {
-         write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
+         write_register (regnum,
+                         read_memory_integer (frame->saved_regs[regnum], 4));
        }
     }
        }
     }
-  if (fsr.regs[PS_REGNUM])
+  if (frame->saved_regs[PS_REGNUM])
     {
     {
-      write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
+      write_register (PS_REGNUM,
+                     read_memory_integer (frame->saved_regs[PS_REGNUM], 4));
     }
   write_register (FP_REGNUM, read_memory_integer (fp, 4));
   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
     }
   write_register (FP_REGNUM, read_memory_integer (fp, 4));
   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
@@ -299,7 +559,7 @@ m68k_skip_prologue (CORE_ADDR ip)
      If so, ensure we don't go past it.  If not, assume "infinity". */
 
   sal = find_pc_line (ip, 0);
      If so, ensure we don't go past it.  If not, assume "infinity". */
 
   sal = find_pc_line (ip, 0);
-  limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
+  limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
 
   while (ip < limit)
     {
 
   while (ip < limit)
     {
@@ -319,14 +579,19 @@ m68k_skip_prologue (CORE_ADDR ip)
       else if (op == P_FMOVM)
        ip += 10;               /* Skip fmovm */
       else
       else if (op == P_FMOVM)
        ip += 10;               /* Skip fmovm */
       else
-       break;          /* Found unknown code, bail out. */
+       break;                  /* Found unknown code, bail out. */
     }
   return (ip);
 }
 
     }
   return (ip);
 }
 
+/* Store the addresses of the saved registers of the frame described by 
+   FRAME_INFO in its saved_regs field.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
 void
 void
-m68k_find_saved_regs (struct frame_info *frame_info,
-                     struct frame_saved_regs *saved_regs)
+m68k_frame_init_saved_regs (struct frame_info *frame_info)
 {
   register int regnum;
   register int regmask;
 {
   register int regnum;
   register int regmask;
@@ -335,10 +600,17 @@ m68k_find_saved_regs (struct frame_info *frame_info,
 
   /* First possible address for a pc in a call dummy for this frame.  */
   CORE_ADDR possible_call_dummy_start =
 
   /* First possible address for a pc in a call dummy for this frame.  */
   CORE_ADDR possible_call_dummy_start =
-  (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
+    (frame_info)->frame - 28 - FP_REGNUM * 4 - 4 - 8 * 12;
 
   int nextinsn;
 
   int nextinsn;
-  memset (saved_regs, 0, sizeof (*saved_regs));
+
+  if (frame_info->saved_regs)
+    return;
+
+  frame_saved_regs_zalloc (frame_info);
+
+  memset (frame_info->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+
   if ((frame_info)->pc >= possible_call_dummy_start
       && (frame_info)->pc <= (frame_info)->frame)
     {
   if ((frame_info)->pc >= possible_call_dummy_start
       && (frame_info)->pc <= (frame_info)->frame)
     {
@@ -388,7 +660,7 @@ m68k_find_saved_regs (struct frame_info *frame_info,
        next_addr += read_memory_integer (pc += 2, 4), pc += 4;
     }
 
        next_addr += read_memory_integer (pc += 2, 4), pc += 4;
     }
 
-  for ( ; ; )
+  for (;;)
     {
       nextinsn = 0xffff & read_memory_integer (pc, 2);
       regmask = read_memory_integer (pc + 2, 2);
     {
       nextinsn = 0xffff & read_memory_integer (pc, 2);
       regmask = read_memory_integer (pc + 2, 2);
@@ -398,7 +670,7 @@ m68k_find_saved_regs (struct frame_info *frame_info,
          /* Regmask's low bit is for register fp7, the first pushed */
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
            if (regmask & 1)
          /* Regmask's low bit is for register fp7, the first pushed */
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
            if (regmask & 1)
-             saved_regs->regs[regnum] = (next_addr -= 12);
+             frame_info->saved_regs[regnum] = (next_addr -= 12);
          pc += 4;
        }
       /* fmovemx to (fp + displacement) */
          pc += 4;
        }
       /* fmovemx to (fp + displacement) */
@@ -411,7 +683,7 @@ m68k_find_saved_regs (struct frame_info *frame_info,
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
            if (regmask & 1)
              {
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
            if (regmask & 1)
              {
-               saved_regs->regs[regnum] = addr;
+               frame_info->saved_regs[regnum] = addr;
                addr += 12;
              }
          pc += 6;
                addr += 12;
              }
          pc += 6;
@@ -423,7 +695,7 @@ m68k_find_saved_regs (struct frame_info *frame_info,
          for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
            if (regmask & 1)
              {
          for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
            if (regmask & 1)
              {
-               saved_regs->regs[regnum] = next_addr;
+               frame_info->saved_regs[regnum] = next_addr;
                next_addr += 4;
              }
          pc += 4;
                next_addr += 4;
              }
          pc += 4;
@@ -438,7 +710,7 @@ m68k_find_saved_regs (struct frame_info *frame_info,
          for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
            if (regmask & 1)
              {
          for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
            if (regmask & 1)
              {
-               saved_regs->regs[regnum] = addr;
+               frame_info->saved_regs[regnum] = addr;
                addr += 4;
              }
          pc += 6;
                addr += 4;
              }
          pc += 6;
@@ -449,14 +721,14 @@ m68k_find_saved_regs (struct frame_info *frame_info,
          /* Regmask's low bit is for register 15, the first pushed */
          for (regnum = 16; --regnum >= 0; regmask >>= 1)
            if (regmask & 1)
          /* Regmask's low bit is for register 15, the first pushed */
          for (regnum = 16; --regnum >= 0; regmask >>= 1)
            if (regmask & 1)
-             saved_regs->regs[regnum] = (next_addr -= 4);
+             frame_info->saved_regs[regnum] = (next_addr -= 4);
          pc += 4;
        }
       /* movl r,-(sp) */
       else if (0x2f00 == (0xfff0 & nextinsn))
        {
          regnum = 0xf & nextinsn;
          pc += 4;
        }
       /* movl r,-(sp) */
       else if (0x2f00 == (0xfff0 & nextinsn))
        {
          regnum = 0xf & nextinsn;
-         saved_regs->regs[regnum] = (next_addr -= 4);
+         frame_info->saved_regs[regnum] = (next_addr -= 4);
          pc += 2;
        }
       /* fmovemx to index of sp */
          pc += 2;
        }
       /* fmovemx to index of sp */
@@ -466,7 +738,7 @@ m68k_find_saved_regs (struct frame_info *frame_info,
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
            if (regmask & 1)
              {
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
            if (regmask & 1)
              {
-               saved_regs->regs[regnum] = next_addr;
+               frame_info->saved_regs[regnum] = next_addr;
                next_addr += 12;
              }
          pc += 10;
                next_addr += 12;
              }
          pc += 10;
@@ -474,20 +746,21 @@ m68k_find_saved_regs (struct frame_info *frame_info,
       /* clrw -(sp); movw ccr,-(sp) */
       else if (0x4267 == nextinsn && 0x42e7 == regmask)
        {
       /* clrw -(sp); movw ccr,-(sp) */
       else if (0x4267 == nextinsn && 0x42e7 == regmask)
        {
-         saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
+         frame_info->saved_regs[PS_REGNUM] = (next_addr -= 4);
          pc += 4;
        }
       else
        break;
     }
 lose:;
          pc += 4;
        }
       else
        break;
     }
 lose:;
-  saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
-  saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
-  saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
+  frame_info->saved_regs[SP_REGNUM] = (frame_info)->frame + 8;
+  frame_info->saved_regs[FP_REGNUM] = (frame_info)->frame;
+  frame_info->saved_regs[PC_REGNUM] = (frame_info)->frame + 4;
 #ifdef SIG_SP_FP_OFFSET
   /* Adjust saved SP_REGNUM for fake _sigtramp frames.  */
   if (frame_info->signal_handler_caller && frame_info->next)
 #ifdef SIG_SP_FP_OFFSET
   /* Adjust saved SP_REGNUM for fake _sigtramp frames.  */
   if (frame_info->signal_handler_caller && frame_info->next)
-    saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
+    frame_info->saved_regs[SP_REGNUM] =
+      frame_info->next->frame + SIG_SP_FP_OFFSET;
 #endif
 }
 
 #endif
 }
 
@@ -588,14 +861,14 @@ supply_fpregset (fpregset_t *fpregsetp)
   register int regi;
   char *from;
 
   register int regi;
   char *from;
 
-  for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
+  for (regi = FP0_REGNUM; regi < E_FPC_REGNUM; regi++)
     {
       from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
       supply_register (regi, from);
     }
     {
       from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
       supply_register (regi, from);
     }
-  supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
-  supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr));
-  supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
+  supply_register (E_FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
+  supply_register (E_FPS_REGNUM, (char *) &(fpregsetp->f_psr));
+  supply_register (E_FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
 }
 
 /*  Given a pointer to a floating point register set in /proc format
 }
 
 /*  Given a pointer to a floating point register set in /proc format
@@ -610,7 +883,7 @@ fill_fpregset (fpregset_t *fpregsetp, int regno)
   char *to;
   char *from;
 
   char *to;
   char *from;
 
-  for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
+  for (regi = FP0_REGNUM; regi < E_FPC_REGNUM; regi++)
     {
       if ((regno == -1) || (regno == regi))
        {
     {
       if ((regno == -1) || (regno == regi))
        {
@@ -619,17 +892,17 @@ fill_fpregset (fpregset_t *fpregsetp, int regno)
          memcpy (to, from, REGISTER_RAW_SIZE (regi));
        }
     }
          memcpy (to, from, REGISTER_RAW_SIZE (regi));
        }
     }
-  if ((regno == -1) || (regno == FPC_REGNUM))
+  if ((regno == -1) || (regno == E_FPC_REGNUM))
     {
     {
-      fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
+      fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (E_FPC_REGNUM)];
     }
     }
-  if ((regno == -1) || (regno == FPS_REGNUM))
+  if ((regno == -1) || (regno == E_FPS_REGNUM))
     {
     {
-      fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
+      fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (E_FPS_REGNUM)];
     }
     }
-  if ((regno == -1) || (regno == FPI_REGNUM))
+  if ((regno == -1) || (regno == E_FPI_REGNUM))
     {
     {
-      fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
+      fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (E_FPI_REGNUM)];
     }
 }
 
     }
 }
 
@@ -657,9 +930,8 @@ m68k_get_longjmp_target (CORE_ADDR *pc)
   buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
   sp = read_register (SP_REGNUM);
 
   buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
   sp = read_register (SP_REGNUM);
 
-  if (target_read_memory (sp + SP_ARG0,                /* Offset of first arg on stack */
-                         buf,
-                         TARGET_PTR_BIT / TARGET_CHAR_BIT))
+  if (target_read_memory (sp + SP_ARG0,        /* Offset of first arg on stack */
+                         buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
     return 0;
 
   jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
     return 0;
 
   jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
@@ -698,9 +970,112 @@ m68k_saved_pc_after_call (struct frame_info *frame)
     return read_memory_integer (read_register (SP_REGNUM), 4);
 }
 
     return read_memory_integer (read_register (SP_REGNUM), 4);
 }
 
+/* Function: m68k_gdbarch_init
+   Initializer function for the m68k gdbarch vector.
+   Called by gdbarch.  Sets up the gdbarch vector(s) for this target. */
+
+static struct gdbarch *
+m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  static LONGEST call_dummy_words[7] = { 0xf227e0ff, 0x48e7fffc, 0x426742e7,
+    0x4eb93232, 0x3232dffc, 0x69696969,
+    (0x4e404e71 | (BPT_VECTOR << 16))
+  };
+  struct gdbarch_tdep *tdep = NULL;
+  struct gdbarch *gdbarch;
+
+  /* find a candidate among the list of pre-declared architectures. */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return (arches->gdbarch);
+
+#if 0
+  tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+#endif
+  gdbarch = gdbarch_alloc (&info, 0);
+
+  set_gdbarch_long_double_format (gdbarch, &floatformat_m68881_ext);
+  set_gdbarch_long_double_bit (gdbarch, 96);
+
+  set_gdbarch_function_start_offset (gdbarch, 0);
+
+  set_gdbarch_skip_prologue (gdbarch, m68k_skip_prologue);
+  set_gdbarch_saved_pc_after_call (gdbarch, m68k_saved_pc_after_call);
+  set_gdbarch_breakpoint_from_pc (gdbarch, m68k_local_breakpoint_from_pc);
+
+  /* Stack grows down. */
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  set_gdbarch_stack_align (gdbarch, m68k_stack_align);
+
+
+  set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+  set_gdbarch_decr_pc_after_break (gdbarch, 2);
+
+  set_gdbarch_store_struct_return (gdbarch, m68k_store_struct_return);
+  set_gdbarch_deprecated_extract_return_value (gdbarch,
+                                              m68k_deprecated_extract_return_value);
+  set_gdbarch_store_return_value (gdbarch, m68k_store_return_value);
+
+  set_gdbarch_frame_chain (gdbarch, m68k_frame_chain);
+  set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid);
+  set_gdbarch_frame_saved_pc (gdbarch, m68k_frame_saved_pc);
+  set_gdbarch_frame_init_saved_regs (gdbarch, m68k_frame_init_saved_regs);
+  set_gdbarch_frameless_function_invocation (gdbarch,
+                                            m68k_frameless_function_invocation);
+  /* OK to default this value to 'unknown'. */
+  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+  set_gdbarch_frame_args_skip (gdbarch, 8);
+  set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+  set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+
+  set_gdbarch_register_raw_size (gdbarch, m68k_register_raw_size);
+  set_gdbarch_register_virtual_size (gdbarch, m68k_register_virtual_size);
+  set_gdbarch_max_register_raw_size (gdbarch, 12);
+  set_gdbarch_max_register_virtual_size (gdbarch, 12);
+  set_gdbarch_register_virtual_type (gdbarch, m68k_register_virtual_type);
+  set_gdbarch_register_name (gdbarch, m68k_register_name);
+  set_gdbarch_register_size (gdbarch, 4);
+  set_gdbarch_register_byte (gdbarch, m68k_register_byte);
+  set_gdbarch_num_regs (gdbarch, 29);
+  set_gdbarch_register_bytes_ok (gdbarch, m68k_register_bytes_ok);
+  set_gdbarch_register_bytes (gdbarch, (16 * 4 + 8 + 8 * 12 + 3 * 4));
+  set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
+  set_gdbarch_fp_regnum (gdbarch, E_FP_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
+  set_gdbarch_ps_regnum (gdbarch, E_PS_REGNUM);
+  set_gdbarch_fp0_regnum (gdbarch, E_FP0_REGNUM);
+
+  set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 24);
+  set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+  set_gdbarch_call_dummy_p (gdbarch, 1);
+  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+  set_gdbarch_call_dummy_length (gdbarch, 28);
+  set_gdbarch_call_dummy_start_offset (gdbarch, 12);
+
+  set_gdbarch_call_dummy_words (gdbarch, call_dummy_words);
+  set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_words));
+  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+  set_gdbarch_fix_call_dummy (gdbarch, m68k_fix_call_dummy);
+  set_gdbarch_push_dummy_frame (gdbarch, m68k_push_dummy_frame);
+  set_gdbarch_pop_frame (gdbarch, m68k_pop_frame);
+
+  return gdbarch;
+}
+
+
+static void
+m68k_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+
+}
 
 void
 _initialize_m68k_tdep (void)
 {
 
 void
 _initialize_m68k_tdep (void)
 {
+  gdbarch_register (bfd_arch_m68k, m68k_gdbarch_init, m68k_dump_tdep);
   tm_print_insn = print_insn_m68k;
 }
   tm_print_insn = print_insn_m68k;
 }
This page took 0.033127 seconds and 4 git commands to generate.