* config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve

%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.
This commit is contained in:
Bob Manson 1998-05-08 05:30:24 +00:00
parent d67094c621
commit 1e9c814fb9
4 changed files with 132 additions and 9 deletions

View 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));

View 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. */

View 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)

View 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