* tm-sparc.c (EXTRA_FRAME_INFO): New field sp_offset.
[deliverable/binutils-gdb.git] / gdb / config / sparc / tm-sparc.h
index a6e5e38dd5e27d38480b8feb9848882fddc40535..de0956e7a6e54896bccfb6c1874946b16449a975 100644 (file)
@@ -1,6 +1,7 @@
 /* Target machine sub-parameters for SPARC, for GDB, the GNU debugger.
    This is included by other tm-*.h files to define SPARC cpu-related info.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
+   Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@mcc.com)
 
 This file is part of GDB.
@@ -24,28 +25,51 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* Floating point is IEEE compatible.  */
 #define IEEE_FLOAT
 
+/* If an argument is declared "register", Sun cc will keep it in a register,
+   never saving it onto the stack.  So we better not believe the "p" symbol
+   descriptor stab.  */
+
+#define USE_REGISTER_NOT_ARG
+
 /* When passing a structure to a function, Sun cc passes the address
    not the structure itself.  It (under SunOS4) creates two symbols,
    which we need to combine to a LOC_REGPARM.  Gcc version two (as of
    1.92) behaves like sun cc.  REG_STRUCT_HAS_ADDR is smart enough to
-   distinguish between Sun cc, gcc version 1 and gcc version 2.
+   distinguish between Sun cc, gcc version 1 and gcc version 2.  */
+
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) (gcc_p != 1)
+
+/* Sun /bin/cc gets this right as of SunOS 4.1.x.  We need to define
+   BELIEVE_PCC_PROMOTION to get this right now that the code which
+   detects gcc2_compiled. is broken.  This loses for SunOS 4.0.x and
+   earlier.  */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* For acc, there's no need to correct LBRAC entries by guessing how
+   they should work.  In fact, this is harmful because the LBRAC
+   entries now all appear at the end of the function, not intermixed
+   with the SLINE entries.  n_opt_found detects acc for Solaris binaries;
+   function_stab_type detects acc for SunOS4 binaries.
+
+   For binary from SunOS4 /bin/cc, need to correct LBRAC's.
+
+   For gcc, like acc, don't correct.  */
 
-   This still doesn't work if the argument is not one passed in a
-   register (i.e. it's the 7th or later argument).  */
-#define REG_STRUCT_HAS_ADDR(gcc_p) (gcc_p != 1)
+#define        SUN_FIXED_LBRAC_BUG \
+  (n_opt_found \
+   || function_stab_type == N_STSYM \
+   || function_stab_type == N_GSYM \
+   || processing_gcc_compilation)
 
-/* If Pcc says that a parameter is a short, it's a short.  This is
-   because the parameter does get passed in in a register as an int,
-   but pcc puts it onto the stack frame as a short (not nailing
-   whatever else might be there.  I'm not sure that I consider this
-   swift.  Sigh.)
+/* Do variables in the debug stabs occur after the N_LBRAC or before it?
+   acc: after, gcc: before, SunOS4 /bin/cc: before.  */
 
-   No, don't do this.  The problem here is that pcc says that the
-   argument is in the upper half of the word reserved on the stack,
-   but puts it in the lower half.  */
-/* #define BELIEVE_PCC_PROMOTION 1 */
-/* OK, I've added code to dbxread.c to deal with this case.  */
-#define BELIEVE_PCC_PROMOTION_TYPE
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) \
+  (!(gcc_p) \
+   && (n_opt_found \
+       || function_stab_type == N_STSYM \
+       || function_stab_type == N_GSYM))
 
 /* Offset from address of function to start of its code.
    Zero on most machines.  */
@@ -62,7 +86,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
   { pc = skip_prologue (pc, 0); }
 #define SKIP_PROLOGUE_FRAMELESS_P(pc) \
   { pc = skip_prologue (pc, 1); }
-extern CORE_ADDR skip_prologue ();
+extern CORE_ADDR skip_prologue PARAMS ((CORE_ADDR, int));
 
 /* Immediately after a function call, return the saved pc.
    Can't go through the frames for this because on some machines
@@ -74,7 +98,7 @@ extern CORE_ADDR skip_prologue ();
    a fake insn, step past it.  */
 
 #define PC_ADJUST(pc) sparc_pc_adjust(pc)
-extern CORE_ADDR sparc_pc_adjust();
+extern CORE_ADDR sparc_pc_adjust PARAMS ((CORE_ADDR));
 
 #define SAVED_PC_AFTER_CALL(frame) PC_ADJUST (read_register (RP_REGNUM))
 
@@ -103,13 +127,11 @@ extern CORE_ADDR sparc_pc_adjust();
 #define ABOUT_TO_RETURN(pc) \
   ((read_memory_integer (pc, 4)|0x00040000) == 0x81c7e008)
 
-/* Return 1 if P points to an invalid floating point value.  */
+/* 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 INVALID_FLOAT(p, len) 0   /* Just a first guess; not checked */
-
-/* Say how long (ordinary) registers are.  */
-
-#define REGISTER_TYPE long
+#define REGISTER_SIZE 4
 
 /* Number of machine registers */
 
@@ -162,7 +184,16 @@ extern CORE_ADDR sparc_pc_adjust();
 #define        CPS_REGNUM 71           /* Coprocessor status register */
 
 /* Total amount of space needed to store our copies of the machine's
-   register state, the array `registers'.  */
+   register state, the array `registers'.  On the sparc, `registers'
+   contains the ins and locals, even though they are saved on the
+   stack rather than with the other registers, and this causes hair
+   and confusion in places like pop_frame.  It might be
+   better to remove the ins and locals from `registers', make sure
+   that get_saved_register can get them from the stack (even in the
+   innermost frame), and make this the way to access them.  For the
+   frame pointer we would do that via TARGET_READ_FP.  On the other hand,
+   that is likely to be confusing or worse for flat frames.  */
+
 #define REGISTER_BYTES (32*4+32*4+8*4)
 
 /* Index within `registers' of the first byte of the space for
@@ -170,20 +201,11 @@ extern CORE_ADDR sparc_pc_adjust();
 /* ?? */
 #define REGISTER_BYTE(N)  ((N)*4)
 
-/* The SPARC processor has register windows.  */
-
-#define HAVE_REGISTER_WINDOWS
-
-/* Is this register part of the register window system?  A yes answer
-   implies that 1) The name of this register will not be the same in
-   other frames, and 2) This register is automatically "saved" (out
-   registers shifting into ins counts) upon subroutine calls and thus
-   there is no need to search more than one stack frame for it. */
-
-#define REGISTER_IN_WINDOW_P(regnum)   \
-  ((regnum) >= 8 && (regnum) < 32)
-
+/* We need to override GET_SAVED_REGISTER so that we can deal with the way
+   outs change into ins in different frames.  HAVE_REGISTER_WINDOWS can't
+   deal with this case and also handle flat frames at the same time.  */
 
+#define GET_SAVED_REGISTER 1
 
 /* Number of bytes of storage in the actual machine representation
    for register N.  */
@@ -207,23 +229,6 @@ extern CORE_ADDR sparc_pc_adjust();
 
 #define MAX_REGISTER_VIRTUAL_SIZE 8
 
-/* 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
-   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_RAW(REGNUM,FROM,TO)        \
-{ memcpy ((TO), (FROM), 4); }
-
 /* Return the GDB type object for the "standard" data type
    of data in register N.  */
 
@@ -315,18 +320,53 @@ sparc_extract_struct_value_address PARAMS ((char [REGISTER_BYTES]));
    The bottom field is misnamed, since it might imply that memory from
    bottom to frame contains this frame.  That need not be true if
    stack frames are allocated in different segments (e.g. some on a
-   stack, some on a heap in the data segment).  */
+   stack, some on a heap in the data segment).
+
+   GCC 2.6 and later can generate ``flat register window'' code that
+   makes frames by explicitly saving those registers that need to be
+   saved.  %i7 is used as the frame pointer, and the frame is laid out so
+   that flat and non-flat calls can be intermixed freely within a
+   program.  Unfortunately for GDB, this means it must detect and record
+   the flatness of frames.
+
+   Since the prologue in a flat frame also tells us where fp and pc
+   have been stashed (the frame is of variable size, so their location
+   is not fixed), it's convenient to record them in the frame info.  */
+
+#define EXTRA_FRAME_INFO  \
+  CORE_ADDR bottom;  \
+  int flat;  \
+  /* Following fields only relevant for flat frames.  */ \
+  CORE_ADDR pc_addr;  \
+  CORE_ADDR fp_addr;  \
+  /* Add this to ->frame to get the value of the stack pointer at the */ \
+  /* time of the register saves.  */ \
+  int sp_offset;
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) \
+  sparc_init_extra_frame_info (fromleaf, fci)
+extern void sparc_init_extra_frame_info ();
+
+#define        PRINT_EXTRA_FRAME_INFO(fi) \
+  { \
+    if ((fi) && (fi)->flat) \
+      printf_filtered (" flat, pc saved at 0x%x, fp saved at 0x%x\n", \
+                       (fi)->pc_addr, (fi)->fp_addr); \
+  }
 
-#define EXTRA_FRAME_INFO       FRAME_ADDR bottom;
-#define INIT_EXTRA_FRAME_INFO(fromleaf, fci)  \
-  (fci)->bottom =                                      \
-   ((fci)->next ?                                      \
-    ((fci)->frame == (fci)->next->frame ?              \
-     (fci)->next->bottom : (fci)->next->frame) :       \
-    read_register (SP_REGNUM));
+#ifdef __STDC__
+struct frame_info;
+#endif
 
 #define FRAME_CHAIN(thisframe) (sparc_frame_chain (thisframe))
-CORE_ADDR sparc_frame_chain ();
+extern CORE_ADDR sparc_frame_chain PARAMS ((struct frame_info *));
+
+/* INIT_EXTRA_FRAME_INFO needs the PC to detect flat frames.  */
+
+#define        INIT_FRAME_PC(fromleaf, prev) /* nothing */
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
+  (prev)->pc = ((fromleaf) ? SAVED_PC_AFTER_CALL ((prev)->next) : \
+             (prev)->next ? FRAME_SAVED_PC ((prev)->next) : read_pc ());
 
 /* Define other aspects of the stack frame.  */
 
@@ -336,10 +376,18 @@ CORE_ADDR sparc_frame_chain ();
 #define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
   (FRAMELESS) = frameless_look_for_prologue(FI)
 
+/* The location of I0 w.r.t SP.  This is actually dependent on how the system's
+   window overflow/underflow routines are written.  Most vendors save the L regs
+   followed by the I regs (at the higher address).  Some vendors get it wrong.
+ */
+
+#define        FRAME_SAVED_L0  0
+#define        FRAME_SAVED_I0  (8 * REGISTER_RAW_SIZE (L0_REGNUM))
+
 /* Where is the PC for a specific frame */
 
-#define FRAME_SAVED_PC(FRAME) frame_saved_pc (FRAME)
-CORE_ADDR frame_saved_pc ();
+#define FRAME_SAVED_PC(FRAME) sparc_frame_saved_pc (FRAME)
+extern CORE_ADDR sparc_frame_saved_pc ();
 
 /* If the argument is on the stack, it will be here.  */
 #define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
@@ -358,14 +406,6 @@ CORE_ADDR frame_saved_pc ();
 /* Return number of bytes at start of arglist that are not really args.  */
 
 #define FRAME_ARGS_SKIP 68
-
-/* Put here the code to store, into a struct frame_saved_regs,
-   the addresses of the saved registers of frame described by FRAME_INFO.
-   The actual code is in sparc-tdep.c so we can debug it sanely.  */
-
-#define FRAME_FIND_SAVED_REGS(fi, frame_saved_regs)                \
-       sparc_frame_find_saved_regs ((fi), &(frame_saved_regs))
-extern void sparc_frame_find_saved_regs ();
 \f
 /* Things needed for making the inferior call functions.  */
 /*
@@ -523,6 +563,8 @@ arguments.  */
 
 #define CALL_DUMMY_START_OFFSET 148
 
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + (8 * 4))
+
 #define CALL_DUMMY_STACK_ADJUST 68
 
 /* Insert the specified number of args and function address
@@ -547,14 +589,12 @@ arguments.  */
 /* Sparc has no reliable single step ptrace call */
 
 #define NO_SINGLE_STEP 1
-extern void single_step ();
+extern void single_step PARAMS ((int));
 
 /* We need more arguments in a frame specification for the
    "frame" or "info frame" command.  */
 
 #define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
-/* FIXME:  Depends on equivalence between FRAME and "struct frame_info *",
-   and equivalence between CORE_ADDR and FRAME_ADDR. */
 extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
 
 /* To print every pair of float registers as a double, we use this hook.  */
@@ -562,10 +602,10 @@ extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
 #define        PRINT_REGISTER_HOOK(regno)      \
   if (((regno) >= FP0_REGNUM)          \
    && ((regno) <  FP0_REGNUM + 32)     \
-   && (0 == (regno & 1))) {            \
+   && (0 == ((regno) & 1))) {          \
     char doublereg[8];         /* two float regs */    \
-    if (!read_relative_register_raw_bytes (i  , doublereg  )   \
-     && !read_relative_register_raw_bytes (i+1, doublereg+4)) {        \
+    if (!read_relative_register_raw_bytes ((regno)  , doublereg  )     \
+     && !read_relative_register_raw_bytes ((regno)+1, doublereg+4)) {  \
       printf("\t");                    \
       print_floating (doublereg, builtin_type_double, stdout); \
     }                                  \
This page took 0.026429 seconds and 4 git commands to generate.