* config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve
authorBob Manson <manson@cygnus>
Fri, 8 May 1998 05:30:24 +0000 (05:30 +0000)
committerBob Manson <manson@cygnus>
Fri, 8 May 1998 05:30:24 +0000 (05:30 +0000)
%o0-%o5 as 64-bit values; compensate for stack bias.
(USE_STRUCT_CONVENTION): We only pass pointers to structs
if they're larger than 32 bytes.
(REG_STRUCT_HAS_ADDR): Ditto.

* sparc-tdep.c (sparc_init_extra_frame_info): Use read_sp()
  instead of read_register. If the target is a sparc64 and the frame
  pointer is odd, compensate for the stack bias.
(get_saved_register): Use read_sp().
(DUMMY_STACK_REG_BUF_SIZE): Use FP_REGISTER_BYTES.
(sparc_push_dummy_frame): Use read_sp()/write_sp(). On sparc64,
  save the PC, NPC, CCR, FSR, FPRS, Y and ASI registers.
(sparc_frame_find_saved_regs): Use read_sp(). Read the PC, NPC,
  CCR, FSR, FPRS, Y and ASI registers from the frame, if it's a
  dummy frame.
(sparc_pop_frame): Use write_sp(). If the target is a sparc64 and
  the FP is odd, compensate for stack bias.
(sparc_store_return_value): Right-justify the return value before
  writing it to %o0.
(sparc_fix_call_dummy): Don't NOP out part of the call dummy on
  sparc64.
(sparc64_read_sp, sparc64_read_fp, sparc64_write_sp,
  sparc64_write_fp, sp64_push_arguments,
  sparc64_extract_return_value): New functions to support the
  sparc64 ABI.

* dwarfread.c (handle_producer): Set processing_gcc_compilation to
  the right version number.

* dwarf2read.c (read_file_scope): Assume we're processing
GCC2 output.

gdb/config/sparc/tm-sp64.h
gdb/config/sparc/tm-sparc.h
gdb/dwarf2read.c
gdb/dwarfread.c

index c35a45861e4e54e6a7e2392c17161ab644ecf7fb..7f48bdc15edc4434edc7fbe81b474eea0f3241f7 100644 (file)
@@ -1,8 +1,9 @@
 /* Target machine sub-parameters for SPARC64, for GDB, the GNU debugger.
    This is included by other tm-*.h files to define SPARC64 cpu-related info.
-   Copyright 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1998 Free Software Foundation, Inc.
    This is (obviously) based on the SPARC Vn (n<9) port.
    Contributed by Doug Evans (dje@cygnus.com).
+   Further modified by Bob Manson (manson@cygnus.com).
 
 This file is part of GDB.
 
@@ -22,6 +23,80 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #define GDB_TARGET_IS_SPARC64
 
+#ifdef __STDC__
+struct value;
+#endif
+
+/* Eeeew. Ok, we have to assume (for now) that the processor really is
+   in sparc64 mode. While this is the same instruction sequence as
+   on the Sparc, the stack frames are offset by +2047 (and the arguments
+   are 8 bytes instead of 4). */
+/* Instructions are:
+   std  %f10, [ %fp + 0x7a7 ]
+   std  %f8, [ %fp + 0x79f ]
+   std  %f6, [ %fp + 0x797 ]
+   std  %f4, [ %fp + 0x78f ]
+   std  %f2, [ %fp + 0x787 ]
+   std  %f0, [ %fp + 0x77f ]
+   std  %g6, [ %fp + 0x777 ]
+   std  %g4, [ %fp + 0x76f ]
+   std  %g2, [ %fp + 0x767 ]
+   std  %g0, [ %fp + 0x75f ]
+   std  %fp, [ %fp + 0x757 ]
+   std  %i4, [ %fp + 0x74f ]
+   std  %i2, [ %fp + 0x747 ]
+   std  %i0, [ %fp + 0x73f ]
+   nop
+   nop
+   nop
+   nop
+   rd  %tbr, %o0
+   st  %o0, [ %fp + 0x72b ]
+   rd  %tpc, %o0
+   st  %o0, [ %fp + 0x727 ]
+   rd  %psr, %o0
+   st  %o0, [ %fp + 0x723 ]
+   rd  %y, %o0
+   st  %o0, [ %fp + 0x71f ]
+   ldx  [ %sp + 0x8a7 ], %o5
+   ldx  [ %sp + 0x89f ], %o4
+   ldx  [ %sp + 0x897 ], %o3
+   ldx  [ %sp + 0x88f ], %o2
+   ldx  [ %sp + 0x887 ], %o1
+   call  %g0
+   ldx  [ %sp + 0x87f ], %o0
+   nop
+   ta  1
+   nop
+   nop
+   */
+
+#define CALL_DUMMY {            0x9de3bec0fd3fa7f7LL, 0xf93fa7eff53fa7e7LL,\
+                                0xf13fa7dfed3fa7d7LL, 0xe93fa7cfe53fa7c7LL,\
+                                0xe13fa7bfdd3fa7b7LL, 0xd93fa7afd53fa7a7LL,\
+                                0xd13fa79fcd3fa797LL, 0xc93fa78fc53fa787LL,\
+                                0xc13fa77fcc3fa777LL, 0xc83fa76fc43fa767LL,\
+                                0xc03fa75ffc3fa757LL, 0xf83fa74ff43fa747LL,\
+                                0xf03fa73f01000000LL, 0x0100000001000000LL,\
+                                0x0100000091580000LL, 0xd027a72b93500000LL,\
+                                0xd027a72791480000LL, 0xd027a72391400000LL,\
+                                0xd027a71fda5ba8a7LL, 0xd85ba89fd65ba897LL,\
+                                0xd45ba88fd25ba887LL, 0x9fc02000d05ba87fLL,\
+                                0x0100000091d02001LL, 0x0100000001000000LL }
+
+
+/* 128 is to reserve space to write the %i/%l registers that will be restored
+   when we resume. */
+#define CALL_DUMMY_STACK_ADJUST 128
+
+#define CALL_DUMMY_LENGTH 192
+
+#define CALL_DUMMY_START_OFFSET 148
+
+#define CALL_DUMMY_CALL_OFFSET (CALL_DUMMY_START_OFFSET + (5 * 4))
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + (8 * 4))
+
 #include "sparc/tm-sparc.h"
 
 /* Stack must be aligned on 128-bit boundaries when synthesizing
@@ -210,6 +285,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #undef  TARGET_PTR_BIT
 #define TARGET_PTR_BIT 64
 
+/* Longs are 64 bits. */
+#undef TARGET_LONG_BIT
+#define TARGET_LONG_BIT 64
+
+#undef TARGET_LONG_LONG_BIT
+#define TARGET_LONG_LONG_BIT 64
+
 /* Does the specified function use the "struct returning" convention
    or the "value returning" convention?  The "value returning" convention
    almost invariably returns the entire value in registers.  The
@@ -219,12 +301,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
    Since this sometimes depends on whether it was compiled with GCC,
    this is also an argument.  This is used in call_function to build a
-   stack, and in value_being_returned to print return values.
+   stack, and in value_being_returned to print return values. 
+
+   On Sparc64, we only pass pointers to structs if they're larger then
+   32 bytes. Otherwise they're stored in %o0-%o3 (floating-point
+   values go into %fp0-%fp3).  */
 
-   On sparc64, all structs are returned via a pointer.  */
 
 #undef  USE_STRUCT_CONVENTION
-#define USE_STRUCT_CONVENTION(gcc_p, type) 1
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 32)
+
+#undef REG_STRUCT_HAS_ADDR
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) (TYPE_LENGTH (type) > 32)
 
 /* Store the address of the place in which to copy the structure the
    subroutine will return.  This is called from call_function. */
@@ -281,3 +369,26 @@ extern int
 get_longjmp_target PARAMS ((CORE_ADDR *));
 
 #define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+extern CORE_ADDR sparc64_read_sp ();
+extern CORE_ADDR sparc64_read_fp ();
+extern void sparc64_write_sp PARAMS ((CORE_ADDR));
+extern void sparc64_write_fp PARAMS ((CORE_ADDR));
+
+#define TARGET_READ_SP() (sparc64_read_sp ())
+#define TARGET_READ_FP() (sparc64_read_fp ())
+#define TARGET_WRITE_SP(X) (sparc64_write_sp (X))
+#define TARGET_WRITE_FP(X) (sparc64_write_fp (X))
+
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_sparc_v9a
+
+CORE_ADDR sp64_push_arguments PARAMS ((int, struct value **, CORE_ADDR, unsigned char, CORE_ADDR));
+#undef PUSH_ARGUMENTS
+#define PUSH_ARGUMENTS(A,B,C,D,E) (sp = sp64_push_arguments ((A), (B), (C), (D), (E)))
+
+#undef EXTRACT_RETURN_VALUE
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  sparc64_extract_return_value(TYPE, REGBUF, VALBUF, 0)
+extern void
+sparc64_extract_return_value PARAMS ((struct type *, char [], char *, int));
index 618fce49e4f5d7ca591c23f394e68a34d394028c..aaadc6b8f116c9c46e9534512b8d5c0cc555396e 100644 (file)
@@ -251,7 +251,8 @@ extern CORE_ADDR sparc_pc_adjust PARAMS ((CORE_ADDR));
 #define CANNOT_STORE_REGISTER(regno) ((regno) == G0_REGNUM)
 
 /* Store the address of the place in which to copy the structure the
-   subroutine will return.  This is called from call_function_by_hand. */
+   subroutine will return.  This is called from call_function_by_hand. 
+   The ultimate mystery is, tho, what is the value "16"?  */
 
 #define STORE_STRUCT_RETURN(ADDR, SP) \
   { char val[4]; \
@@ -466,6 +467,7 @@ extern CORE_ADDR sparc_frame_saved_pc PARAMS ((struct frame_info *));
 
 void sparc_push_dummy_frame PARAMS ((void)), sparc_pop_frame PARAMS ((void));
 
+#ifndef CALL_DUMMY
 /* This sequence of words is the instructions
 
  0:    mov     %g1, %fp
@@ -515,6 +517,7 @@ void sparc_push_dummy_frame PARAMS ((void)), sparc_pop_frame PARAMS ((void));
 
 #define CALL_DUMMY_STACK_ADJUST 68
 
+#endif
 /* Insert the specified number of args and function address
    into a call sequence of the above form stored at DUMMYNAME.  */
 
index b01c990405de19e8a3c90e2d0a1e52ccd82a6609..b6162d4bb918e277b59bb5d4e51eeaaa59ef96fb 100644 (file)
@@ -1513,6 +1513,8 @@ read_file_scope (die, objfile)
       set_cu_language (DW_UNSND (attr));
     }
 
+  /* We assume that we're processing GCC output. */
+  processing_gcc_compilation = 2;
 #if 0
     /* FIXME:Do something here.  */
     if (dip->at_producer != NULL)
index 323ceaf0023960d8bc63132092d28bb8bd22d611..eb95b1ad6b60dfcf438ca3ea0e30a4130332965d 100644 (file)
@@ -1902,10 +1902,17 @@ handle_producer (producer)
   /* If this compilation unit was compiled with g++ or gcc, then set the
      processing_gcc_compilation flag. */
 
-  processing_gcc_compilation =
-    STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
-      || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER))
-      || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+  if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
+    {
+      char version = producer[strlen (GCC_PRODUCER)];
+      processing_gcc_compilation = (version == '2' ? 2 : 1);
+    }
+  else
+    {
+      processing_gcc_compilation =
+       STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
+       || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER));
+    }
 
   /* Select a demangling style if we can identify the producer and if
      the current style is auto.  We leave the current style alone if it