* 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. /* 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. 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. This is (obviously) based on the SPARC Vn (n<9) port.
Contributed by Doug Evans (dje@cygnus.com). Contributed by Doug Evans (dje@cygnus.com).
Further modified by Bob Manson (manson@cygnus.com).
This file is part of GDB. 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 #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" #include "sparc/tm-sparc.h"
/* Stack must be aligned on 128-bit boundaries when synthesizing /* 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 #undef TARGET_PTR_BIT
#define TARGET_PTR_BIT 64 #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 /* Does the specified function use the "struct returning" convention
or the "value returning" convention? The "value returning" convention or the "value returning" convention? The "value returning" convention
almost invariably returns the entire value in registers. The 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, 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 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 #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 /* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */ subroutine will return. This is called from call_function. */
@ -281,3 +369,26 @@ extern int
get_longjmp_target PARAMS ((CORE_ADDR *)); get_longjmp_target PARAMS ((CORE_ADDR *));
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(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) #define CANNOT_STORE_REGISTER(regno) ((regno) == G0_REGNUM)
/* Store the address of the place in which to copy the structure the /* 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) \ #define STORE_STRUCT_RETURN(ADDR, SP) \
{ char val[4]; \ { 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)); void sparc_push_dummy_frame PARAMS ((void)), sparc_pop_frame PARAMS ((void));
#ifndef CALL_DUMMY
/* This sequence of words is the instructions /* This sequence of words is the instructions
0: mov %g1, %fp 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 #define CALL_DUMMY_STACK_ADJUST 68
#endif
/* Insert the specified number of args and function address /* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */ 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)); set_cu_language (DW_UNSND (attr));
} }
/* We assume that we're processing GCC output. */
processing_gcc_compilation = 2;
#if 0 #if 0
/* FIXME:Do something here. */ /* FIXME:Do something here. */
if (dip->at_producer != NULL) 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 /* If this compilation unit was compiled with g++ or gcc, then set the
processing_gcc_compilation flag. */ processing_gcc_compilation flag. */
processing_gcc_compilation = if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)) {
|| STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER)) char version = producer[strlen (GCC_PRODUCER)];
|| STREQN (producer, GCC_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 /* 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 the current style is auto. We leave the current style alone if it