From: Bob Manson Date: Fri, 8 May 1998 05:30:24 +0000 (+0000) Subject: * config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1e9c814fb93ece8958aec6810e4e2e3c3859aa1a;p=binutils-gdb.git * 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. --- diff --git a/gdb/config/sparc/tm-sp64.h b/gdb/config/sparc/tm-sp64.h index c35a45861e4..7f48bdc15ed 100644 --- a/gdb/config/sparc/tm-sp64.h +++ b/gdb/config/sparc/tm-sp64.h @@ -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)); diff --git a/gdb/config/sparc/tm-sparc.h b/gdb/config/sparc/tm-sparc.h index 618fce49e4f..aaadc6b8f11 100644 --- a/gdb/config/sparc/tm-sparc.h +++ b/gdb/config/sparc/tm-sparc.h @@ -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. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b01c990405d..b6162d4bb91 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -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) diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 323ceaf0023..eb95b1ad6b6 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -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