import gdb-19990504 snapshot
[deliverable/binutils-gdb.git] / gdb / config / m68k / tm-m68k.h
index 7c397099107d396f91b8d7684c58d7d0299bc149..9cbb41f0801633a1a7d44950ddec90361abfd559 100644 (file)
@@ -15,14 +15,11 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-/* Generic 68000 stuff, to be included by other tm-*.h files.
-   Define HAVE_68881 if that is the case.  */
+/* Generic 68000 stuff, to be included by other tm-*.h files.  */
 
-#if defined (HAVE_68881)
 #define IEEE_FLOAT 1
-#endif
 
 /* Define the bit, byte, and word ordering of the machine.  */
 #define TARGET_BYTE_ORDER BIG_ENDIAN
@@ -36,21 +33,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    to reach some "real" code.  */
 
 #if !defined(SKIP_PROLOGUE)
-#define SKIP_PROLOGUE(ip)   {(ip) = m68k_skip_prologue(ip);}
-extern CORE_ADDR m68k_skip_prologue PARAMS ((CORE_ADDR ip));
+#define SKIP_PROLOGUE(ip) (m68k_skip_prologue (ip))
 #endif
+extern CORE_ADDR m68k_skip_prologue PARAMS ((CORE_ADDR ip));
 
 /* Immediately after a function call, return the saved pc.
    Can't always go through the frames for this because on some machines
    the new frame is not set up until the new function executes
    some instructions.  */
 
+#ifdef __STDC__
+struct frame_info;
+struct frame_saved_regs;
+#endif
+
+extern CORE_ADDR m68k_saved_pc_after_call PARAMS ((struct frame_info *));
+extern void m68k_find_saved_regs PARAMS ((struct frame_info *, struct frame_saved_regs *));
+
 #define SAVED_PC_AFTER_CALL(frame) \
-read_memory_integer (read_register (SP_REGNUM), 4)
+  m68k_saved_pc_after_call(frame)
 
 /* Stack grows downward.  */
 
-#define INNER_THAN <
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Stack must be kept short aligned when doing function calls.  */
+
+#define STACK_ALIGN(ADDR) (((ADDR) + 1) & ~1)
 
 /* Sequence of bytes for breakpoint instruction.
    This is a TRAP instruction.  The last 4 bits (0xf below) is the
@@ -65,6 +74,16 @@ read_memory_integer (read_register (SP_REGNUM), 4)
 #define BREAKPOINT {0x4e, (0x40 | BPT_VECTOR)}
 #endif
 
+/* We default to vector 1 for the "remote" target, but allow targets
+   to override.  */
+#if !defined (REMOTE_BPT_VECTOR)
+#define REMOTE_BPT_VECTOR 1
+#endif
+
+#if !defined (REMOTE_BREAKPOINT)
+#define REMOTE_BREAKPOINT {0x4e, (0x40 | REMOTE_BPT_VECTOR)}
+#endif
+
 /* If your kernel resets the pc after the trap happens you may need to
    define this before including this file.  */
 
@@ -72,42 +91,34 @@ read_memory_integer (read_register (SP_REGNUM), 4)
 #define DECR_PC_AFTER_BREAK 2
 #endif
 
-/* Nonzero if instruction at PC is a return instruction.  */
-/* Allow any of the return instructions, including a trapv and a return
-   from interupt.  */
+/* Say how long (ordinary) registers are.  This is a piece of bogosity
+   used in push_word and a few other places; REGISTER_RAW_SIZE is the
+   real way to know how big a register is.  */
 
-#define ABOUT_TO_RETURN(pc) ((read_memory_integer (pc, 2) & ~0x3) == 0x4e74)
+#define REGISTER_SIZE 4
 
-/* Return 1 if P points to an invalid floating point value.  */
+#define REGISTER_BYTES_FP (16*4 + 8 + 8*12 + 3*4)
+#define REGISTER_BYTES_NOFP (16*4 + 8)
 
-#define INVALID_FLOAT(p, len) 0   /* Just a first guess; not checked */
+#ifndef NUM_REGS
+#define NUM_REGS 29
+#endif
 
-/* Say how long registers are.  */
+#define NUM_FREGS (NUM_REGS-24)
 
-#define REGISTER_TYPE long
+#ifndef REGISTER_BYTES_OK
+#define REGISTER_BYTES_OK(b) \
+   ((b) == REGISTER_BYTES_FP \
+    || (b) == REGISTER_BYTES_NOFP)
+#endif
 
-#if defined (HAVE_68881)
-#  if defined (GDB_TARGET_IS_SUN3)
-    /* Sun3 status includes fpflags, which shows whether the FPU has been used
-       by the process, and whether the FPU was done with an instruction or 
-       was interrupted in the middle of a long instruction.  See
-       <machine/reg.h>.  */
-    /*                      a&d, pc,sr, fp, fpstat, fpflags   */
-#    define NUM_REGS 31
-#    define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4 + 4)
-#  else /* Not sun3.  */
-#    define NUM_REGS 29
-#    define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4)
-#  endif /* Not sun3.  */
-#else /* No 68881.  */
-#  define NUM_REGS 18
-#  define REGISTER_BYTES (16*4 + 8)
-#endif /* No 68881.  */
+#ifndef REGISTER_BYTES
+#define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4)
+#endif
 
 /* Index within `registers' of the first byte of the space for
    register N.  */
 
-#if defined (HAVE_68881)
 #define REGISTER_BYTE(N)  \
  ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168   \
   : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
@@ -140,87 +151,42 @@ read_memory_integer (read_register (SP_REGNUM), 4)
 
 #define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
 
-/* Put the declaration out here because if it's in the macros, PCC
-   will complain.  */
-extern const struct ext_format ext_format_68881;
-
-/* Convert data from raw format for register REGNUM
-   to virtual format for register REGNUM.  */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
-{ \
-  if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
-    ieee_extended_to_double (&ext_format_68881, (FROM), (double *)(TO)); \
-  else                                 \
-    memcpy ((TO), (FROM), 4);  \
-}
-
-/* Convert data from virtual format for register REGNUM
-   to raw format for register REGNUM.  */
-
-#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
-{ \
-  if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
-    double_to_ieee_extended (&ext_format_68881, (double *)(FROM), (TO)); \
-  else                                 \
-    memcpy ((TO), (FROM), 4);  \
-}
-
-/* Return the GDB type object for the "standard" data type
-   of data in register N.  */
-/* 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.  */
-#define REGISTER_VIRTUAL_TYPE(N) \
- (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double :           \
-  (N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM ?         \
-  lookup_pointer_type (builtin_type_void) : builtin_type_int)
-
-#else /* no 68881.  */
-/* Index within `registers' of the first byte of the space for
-   register N.  */
-
-#define REGISTER_BYTE(N)  ((N) * 4)
-
-/* Number of bytes of storage in the actual machine representation
-   for register N.  On the 68000, all regs are 4 bytes.  */
-
-#define REGISTER_RAW_SIZE(N) 4
+#include "floatformat.h"
 
-/* Number of bytes of storage in the program's representation
-   for register N.  On the 68000, all regs are 4 bytes.  */
-
-#define REGISTER_VIRTUAL_SIZE(N) 4
-
-/* Largest value REGISTER_RAW_SIZE can have.  */
-
-#define MAX_REGISTER_RAW_SIZE 4
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
-
-#define MAX_REGISTER_VIRTUAL_SIZE 4
-
-/* Nonzero if register N requires conversion
-   from raw format to virtual format.  */
-
-#define REGISTER_CONVERTIBLE(N) 0
+/* Convert data from raw format for register REGNUM in buffer FROM
+   to virtual format with type TYPE in buffer TO.  */
 
-/* Convert data from raw format for register REGNUM
-   to virtual format for register REGNUM.  */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)  memcpy ((TO), (FROM), 4);
-
-/* Convert data from virtual format for register REGNUM
-   to raw format for register REGNUM.  */
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
+do                                                                     \
+  {                                                                    \
+    DOUBLEST dbl_tmp_val;                                                      \
+    floatformat_to_doublest (&floatformat_m68881_ext, (FROM), &dbl_tmp_val); \
+    store_floating ((TO), TYPE_LENGTH (TYPE), dbl_tmp_val);            \
+  } while (0)
 
-#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)  memcpy ((TO), (FROM), 4);
+/* Convert data from virtual format with type TYPE in buffer FROM
+   to raw format for register REGNUM in buffer TO.  */
 
-/* Return the GDB type object for the "standard" data type
-   of data in register N.  */
+#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO)   \
+do                                                                     \
+  {                                                                    \
+    DOUBLEST dbl_tmp_val;                                              \
+    dbl_tmp_val = extract_floating ((FROM), TYPE_LENGTH (TYPE));       \
+    floatformat_from_doublest (&floatformat_m68881_ext, &dbl_tmp_val, (TO)); \
+  } while (0)
 
-#define REGISTER_VIRTUAL_TYPE(N)  builtin_type_int
+/* Return the GDB type object for the "standard" data type of data 
+   in register N.  This should be int for D0-D7, 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.  */
 
-#endif /* No 68881.  */
+#define REGISTER_VIRTUAL_TYPE(N) \
+  ((unsigned) (N) >= FPC_REGNUM ? lookup_pointer_type (builtin_type_void) : \
+   (unsigned) (N) >= FP0_REGNUM ? builtin_type_double :                     \
+   (unsigned) (N) >=  A0_REGNUM ? lookup_pointer_type (builtin_type_void) : \
+   builtin_type_int)
 
 /* Initializer for an array of names of registers.
    Entries beyond the first NUM_REGS are ignored.  */
@@ -239,17 +205,17 @@ extern const struct ext_format ext_format_68881;
    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.  */
 
+#define D0_REGNUM 0
+#define A0_REGNUM 8
 #define A1_REGNUM 9
 #define FP_REGNUM 14           /* Contains address of executing stack frame */
 #define SP_REGNUM 15           /* Contains address of top of stack */
 #define PS_REGNUM 16           /* Contains processor status */
 #define PC_REGNUM 17           /* Contains program counter */
-#if defined (HAVE_68881)
 #define FP0_REGNUM 18          /* Floating point register 0 */
 #define FPC_REGNUM 26          /* 68881 control register */
 #define FPS_REGNUM 27          /* 68881 status register */
 #define FPI_REGNUM 28          /* 68881 iaddr register */
-#endif /* 68881.  */
 
 /* Store the address of the place in which to copy the structure the
    subroutine will return.  This is called from call_function. */
@@ -363,25 +329,23 @@ extern const struct ext_format ext_format_68881;
 #endif /* no FIND_FRAME_SAVED_REGS.  */
 
 \f
-/* Things needed for making the inferior call functions.
-   It seems like every m68k based machine has almost identical definitions
-   in the individual machine's configuration files.  Most other cpu types
-   (mips, i386, etc) have routines in their *-tdep.c files to handle this
-   for most configurations.  The m68k family should be able to do this as
-   well.  These macros can still be overridden when necessary.  */
+/* Things needed for making the inferior call functions.  */
 
 /* The CALL_DUMMY macro is the sequence of instructions, as disassembled
    by gdb itself:
 
+   These instructions exist only so that m68k_find_saved_regs can parse
+   them as a "prologue"; they are never executed.
+
        fmovemx fp0-fp7,sp@-                    0xf227 0xe0ff
        moveml d0-a5,sp@-                       0x48e7 0xfffc
        clrw sp@-                               0x4267
        movew ccr,sp@-                          0x42e7
 
-       /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
+   The arguments are pushed at this point by GDB; no code is needed in
+   the dummy for this.  The CALL_DUMMY_START_OFFSET gives the position
+   of the following jsr instruction.  That is where we start
+   executing.
 
        jsr @#0x32323232                        0x4eb9 0x3232 0x3232
        addal #0x69696969,sp                    0xdffc 0x6969 0x6969
@@ -389,35 +353,26 @@ extern const struct ext_format ext_format_68881;
        nop                                     0x4e71
 
    Note this is CALL_DUMMY_LENGTH bytes (28 for the above example).
-   We actually start executing at the jsr, since the pushing of the
-   registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-   the arguments for the function called by the jsr would be pushed
-   between the moveml and the jsr, and we could allow it to execute through.
-   But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is
-   done, and we cannot allow the moveml to push the registers again lest
-   they be taken for the arguments.  */
 
-#if defined (HAVE_68881)
+   The dummy frame always saves the floating-point registers, whether they
+   actually exist on this target or not.  */
+
+/* FIXME: Wrong to hardwire this as BPT_VECTOR when sometimes it
+   should be REMOTE_BPT_VECTOR.  Best way to fix it would be to define
+   CALL_DUMMY_BREAKPOINT_OFFSET.  */
 
 #define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, (0x4e404e71 | (BPT_VECTOR << 16))}
 #define CALL_DUMMY_LENGTH 28           /* Size of CALL_DUMMY */
 #define CALL_DUMMY_START_OFFSET 12     /* Offset to jsr instruction*/
-
-#else
-
-#define CALL_DUMMY {0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, (0x4e404e71 | (BPT_VECTOR << 16))}
-#define CALL_DUMMY_LENGTH 24           /* Size of CALL_DUMMY */
-#define CALL_DUMMY_START_OFFSET 8      /* Offset to jsr instruction*/
-
-#endif /* HAVE_68881 */
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + 12)
 
 /* 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.  */
 
 #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ _do_putb32 (fun,     (char *) dummyname + CALL_DUMMY_START_OFFSET + 2);  \
-  _do_putb32 (nargs*4, (char *) dummyname + CALL_DUMMY_START_OFFSET + 8); }
+{ bfd_putb32 (fun,     (unsigned char *) dummyname + CALL_DUMMY_START_OFFSET + 2);  \
+  bfd_putb32 (nargs*4, (unsigned char *) dummyname + CALL_DUMMY_START_OFFSET + 8); }
 
 /* Push an empty stack frame, to record the current PC, etc.  */
 
@@ -434,3 +389,5 @@ extern void m68k_pop_frame PARAMS ((void));
 /* Offset from SP to first arg on stack at first instruction of a function */
 
 #define SP_ARG0 (1 * 4)
+
+#define TARGET_M68K
This page took 0.029293 seconds and 4 git commands to generate.