From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23953 invoked by alias); 12 Sep 2003 17:32:09 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 23931 invoked from network); 12 Sep 2003 17:32:04 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 12 Sep 2003 17:32:04 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h8CHW2l32551 for ; Fri, 12 Sep 2003 13:32:03 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h8CHW2e29979 for ; Fri, 12 Sep 2003 13:32:02 -0400 Received: from localhost.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by pobox.corp.redhat.com (8.12.8/8.12.8) with ESMTP id h8CHW1xI028200 for ; Fri, 12 Sep 2003 13:32:01 -0400 Received: by localhost.redhat.com (Postfix, from userid 469) id 885072CA3B; Fri, 12 Sep 2003 13:40:58 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16226.1322.230352.450541@localhost.redhat.com> Date: Fri, 12 Sep 2003 17:32:00 -0000 To: Corinna Vinschen Subject: Re: [RFA] SH: Deprecate deprecated functions, use new frame interface In-Reply-To: <20030908165510.GK1859@cygbert.vinschen.de> References: <20030908165510.GK1859@cygbert.vinschen.de> X-SW-Source: 2003-09/txt/msg00264.txt.bz2 Corinna Vinschen writes: > Hi, > > the attached patch switches sh-tdep.c to using all the new frame code > stuff. All deprecated functions are gone. It implements its own > heuristic frame sniffer plus it adds the dwarf2 frame sniffer to the > frame unwind sniffer list. This new code defines all register numbers > as enumeration values instead of as part of the tdep structure. The > result is that the tdep structure could be eliminated entirely. Some > defintions in sh-tdep.c have been changed for readability. > Seems ok, but....could you split the renaming of insn to inst and removal of tdep into a separate patch, and repost the 2 patches? I.e. the renaming/tdep and the real cleanups after that. It's not easy to see what's going on with this diff. thanks elena > ChangeLog: > > * sh-tdep.h (struct gdbarch_tdep): Remove. Change all register > numbers to enumeration values. > * sh-tdep.c: Accomodate above change. > (SH_NUM_REGS): Rename from SH_DEFAULT_NUM_REGS. > (struct frame_extra_info): Remove. > (struct sh_frame_cache): New structure. > (NUM_PSEUDO_REGS_SH_MEDIA): Remove (sh5 only). > (NUM_PSEUDO_REGS_SH_COMPACT): Remove (sh5 only). > (GET_SOURCE_REG): New macro extracting source register of an opcode. > (GET_TARGET_REG): Ditto but target register. > (GET_PUSHED_REG): Remove. > (IS_ADD_IMM_SP): Rename from IS_ADD_SP. > (IS_FPUSH): Rename from IS_FMOV. > (IS_MOV_ARG_TO_REG): New macro. > (IS_MOV_ARG_TO_IND_R14): New macro. > (IS_MOV_ARG_TO_IND_R14_WITH_DISP): New macro. > (IS_MOVW_PCREL_TO_REG): New macro. > (IS_MOVL_PCREL_TO_REG): New macro. > (IS_SUB_REG_FROM_SP): New macro. > (IS_ARG_MOV): Remove. > (IS_MOV_TO_R14): Remove. > (IS_RESTORE_FP): New macro. > (IS_RTS): New macro. > (IS_LDS): New macro. > (IS_MOV_FP_SP): New macro. > (IS_ADD_REG_TO_FP): New macro. > (IS_ADD_IMM_FP): New macro. > (sh_skip_prologue_hard_way): Remove. > (sh_saved_pc_after_call): Remove. > (sh_frame_chain): Remove. > (sh_find_callers_reg): Remove. > (sh_nofp_frame_init_saved_regs): Remove. > (sh_fp_frame_init_saved_regs): Remove. > (sh_init_extra_frame_info): Remove. > (sh_analyze_prologue): New function. > (sh_skip_prologue): Remove deprecated code. Rely on new function > sh_analyze_prologue when after_prologue fails. > (sh_extract_struct_value_address): Remove useless comment. > (sh_frame_saved_pc): Remove. > (sh_dsp_register_sim_regno): Use register values from sh-tdep.h > instead of own local values. > (sh_alloc_frame_cache): New function. > (sh_frame_cache): Ditto. > (sh_frame_prev_register): Ditto. > (sh_frame_this_id): Ditto. > (sh_frame_unwind): New structure defining the heuristic frame > sniffer interface. > (sh_frame_sniffer): New function. > (sh_unwind_sp): Ditto. > (sh_unwind_pc): Ditto. > (sh_unwind_dummy_id): Ditto. > (sh_frame_base_address): Ditto. > (sh_frame_base): New structure defining new frame base code. > (sh_in_function_epilogue_p): New function. > (sh_gdbarch_init): Restructure and simplify to eliminate deprecated > code and to call all new code instead. Initialize dwarf2 and > heuristic frame sniffer. > (sh_dump_tdep): Remove. > (_initialize_sh_tdep): Accomodate removing sh_dump_tdep. > * sh3-rom.c (sh3_supply_register): Accomodate sh-tdep.h changes. > > Index: sh-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/sh-tdep.c,v > retrieving revision 1.137 > diff -u -p -r1.137 sh-tdep.c > --- sh-tdep.c 8 Sep 2003 11:26:20 -0000 1.137 > +++ sh-tdep.c 8 Sep 2003 16:26:46 -0000 > @@ -26,6 +26,9 @@ > > #include "defs.h" > #include "frame.h" > +#include "frame-base.h" > +#include "frame-unwind.h" > +#include "dwarf2-frame.h" > #include "symtab.h" > #include "symfile.h" > #include "gdbtypes.h" > @@ -35,6 +38,7 @@ > #include "dis-asm.h" > #include "inferior.h" > #include "gdb_string.h" > +#include "gdb_assert.h" > #include "arch-utils.h" > #include "floatformat.h" > #include "regcache.h" > @@ -53,17 +57,21 @@ > > static void (*sh_show_regs) (void); > > -#define SH_DEFAULT_NUM_REGS 59 > +#define SH_NUM_REGS 59 > > -/* Define other aspects of the stack frame. > - we keep a copy of the worked out return pc lying around, since it > - is a useful bit of info */ > - > -struct frame_extra_info > +struct sh_frame_cache > { > - CORE_ADDR return_pc; > - int leaf_function; > - int f_offset; > + /* Base address. */ > + CORE_ADDR base; > + LONGEST sp_offset; > + CORE_ADDR pc; > + > + /* Flag showing that a frame has been created in the prologue code. */ > + int uses_fp; > + > + /* Saved registers. */ > + CORE_ADDR saved_regs[SH_NUM_REGS]; > + CORE_ADDR saved_sp; > }; > > static const char * > @@ -256,9 +264,6 @@ sh_sh4_register_name (int reg_nr) > return register_names[reg_nr]; > } > > -#define NUM_PSEUDO_REGS_SH_MEDIA 80 > -#define NUM_PSEUDO_REGS_SH_COMPACT 51 > - > static const unsigned char * > sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) > { > @@ -286,29 +291,18 @@ sh_push_dummy_code (struct gdbarch *gdba > } > > /* Prologue looks like > - [mov.l ,@-r15]... > - [sts.l pr,@-r15] > - [mov.l r14,@-r15] > - [mov r15,r14] > - > - Actually it can be more complicated than this. For instance, with > - newer gcc's: > - > - mov.l r14,@-r15 > - add #-12,r15 > - mov r15,r14 > - mov r4,r1 > - mov r5,r2 > - mov.l r6,@(4,r14) > - mov.l r7,@(8,r14) > - mov.b r1,@r14 > - mov r14,r1 > - mov r14,r1 > - add #2,r1 > - mov.w r2,@r1 > + mov.l r14,@-r15 > + sts.l pr,@-r15 > + mov.l ,@-r15 > + sub ,r15 > + mov r15,r14 > > + Actually it can be more complicated than this but that's it, basically. > */ > > +#define GET_SOURCE_REG(x) (((x) >> 4) & 0xf) > +#define GET_TARGET_REG(x) (((x) >> 8) & 0xf) > + > /* STS.L PR,@-r15 0100111100100010 > r15-4-->r15, PR-->(r15) */ > #define IS_STS(x) ((x) == 0x4f22) > @@ -317,15 +311,13 @@ sh_push_dummy_code (struct gdbarch *gdba > r15-4-->r15, Rm-->(R15) */ > #define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06) > > -#define GET_PUSHED_REG(x) (((x) >> 4) & 0xf) > - > /* MOV r15,r14 0110111011110011 > r15-->r14 */ > #define IS_MOV_SP_FP(x) ((x) == 0x6ef3) > > /* ADD #imm,r15 01111111iiiiiiii > r15+imm-->r15 */ > -#define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00) > +#define IS_ADD_IMM_SP(x) (((x) & 0xff00) == 0x7f00) > > #define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00) > #define IS_SHLL_R3(x) ((x) == 0x4300) > @@ -337,133 +329,43 @@ sh_push_dummy_code (struct gdbarch *gdba > /* FMOV.S FRm,@-Rn Rn-4-->Rn, FRm-->(Rn) 1111nnnnmmmm1011 > FMOV DRm,@-Rn Rn-8-->Rn, DRm-->(Rn) 1111nnnnmmm01011 > FMOV XDm,@-Rn Rn-8-->Rn, XDm-->(Rn) 1111nnnnmmm11011 */ > -#define IS_FMOV(x) (((x) & 0xf00f) == 0xf00b) > +/* CV, 2003-08-28: Only suitable with Rn == SP, therefore name changed to > + make this entirely clear. */ > +/* #define IS_FMOV(x) (((x) & 0xf00f) == 0xf00b) */ > +#define IS_FPUSH(x) (((x) & 0xff0f) == 0xff0b) > + > +/* MOV Rm,Rn Rm-->Rn 0110nnnnmmmm0011 4 <= m <= 7 */ > +#define IS_MOV_ARG_TO_REG(x) \ > + (((x) & 0xf00f) == 0x6003 && \ > + ((x) & 0x00f0) >= 0x0040 && \ > + ((x) & 0x00f0) <= 0x0070) > +/* MOV.L Rm,@Rn 0010nnnnmmmm0010 n = 14, 4 <= m <= 7 */ > +#define IS_MOV_ARG_TO_IND_R14(x) \ > + (((x) & 0xff0f) == 0x2e02 && \ > + ((x) & 0x00f0) >= 0x0040 && \ > + ((x) & 0x00f0) <= 0x0070) > +/* MOV.L Rm,@(disp*4,Rn) 00011110mmmmdddd n = 14, 4 <= m <= 7 */ > +#define IS_MOV_ARG_TO_IND_R14_WITH_DISP(x) \ > + (((x) & 0xff00) == 0x1e00 && \ > + ((x) & 0x00f0) >= 0x0040 && \ > + ((x) & 0x00f0) <= 0x0070) > + > +/* MOV.W @(disp*2,PC),Rn 1001nnnndddddddd */ > +#define IS_MOVW_PCREL_TO_REG(x) (((x) & 0xf000) == 0x9000) > +/* MOV.L @(disp*4,PC),Rn 1101nnnndddddddd */ > +#define IS_MOVL_PCREL_TO_REG(x) (((x) & 0xf000) == 0xd000) > +/* SUB Rn,R15 00111111nnnn1000 */ > +#define IS_SUB_REG_FROM_SP(x) (((x) & 0xff0f) == 0x3f08) > > -/* MOV Rm,Rn Rm-->Rn 0110nnnnmmmm0011 > - MOV.L Rm,@(disp,Rn) Rm-->(dispx4+Rn) 0001nnnnmmmmdddd > - MOV.L Rm,@Rn Rm-->(Rn) 0010nnnnmmmm0010 > - where Rm is one of r4,r5,r6,r7 which are the argument registers. */ > -#define IS_ARG_MOV(x) \ > -(((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \ > - || ((((x) & 0xf000) == 0x1000) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \ > - || ((((x) & 0xf00f) == 0x2002) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070))) > - > -/* MOV.L Rm,@(disp,r14) 00011110mmmmdddd > - Rm-->(dispx4+r14) where Rm is one of r4,r5,r6,r7 */ > -#define IS_MOV_TO_R14(x) \ > - ((((x) & 0xff00) == 0x1e) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) > - > #define FPSCR_SZ (1 << 20) > > -/* Skip any prologue before the guts of a function */ > - > -/* Skip the prologue using the debug information. If this fails we'll > - fall back on the 'guess' method below. */ > -static CORE_ADDR > -after_prologue (CORE_ADDR pc) > -{ > - struct symtab_and_line sal; > - CORE_ADDR func_addr, func_end; > - > - /* If we can not find the symbol in the partial symbol table, then > - there is no hope we can determine the function's start address > - with this code. */ > - if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) > - return 0; > - > - /* Get the line associated with FUNC_ADDR. */ > - sal = find_pc_line (func_addr, 0); > - > - /* There are only two cases to consider. First, the end of the source line > - is within the function bounds. In that case we return the end of the > - source line. Second is the end of the source line extends beyond the > - bounds of the current function. We need to use the slow code to > - examine instructions in that case. */ > - if (sal.end < func_end) > - return sal.end; > - else > - return 0; > -} > - > -/* Here we look at each instruction in the function, and try to guess > - where the prologue ends. Unfortunately this is not always > - accurate. */ > -static CORE_ADDR > -sh_skip_prologue_hard_way (CORE_ADDR start_pc) > -{ > - CORE_ADDR here, end; > - int updated_fp = 0; > - > - if (!start_pc) > - return 0; > - > - for (here = start_pc, end = start_pc + (2 * 28); here < end;) > - { > - int w = read_memory_integer (here, 2); > - here += 2; > - if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w) || IS_MOV_R3 (w) > - || IS_ADD_R3SP (w) || IS_ADD_SP (w) || IS_SHLL_R3 (w) > - || IS_ARG_MOV (w) || IS_MOV_TO_R14 (w)) > - { > - start_pc = here; > - } > - else if (IS_MOV_SP_FP (w)) > - { > - start_pc = here; > - updated_fp = 1; > - } > - else > - /* Don't bail out yet, if we are before the copy of sp. */ > - if (updated_fp) > - break; > - } > - > - return start_pc; > -} > - > -static CORE_ADDR > -sh_skip_prologue (CORE_ADDR pc) > -{ > - CORE_ADDR post_prologue_pc; > - > - /* See if we can determine the end of the prologue via the symbol table. > - If so, then return either PC, or the PC after the prologue, whichever > - is greater. */ > - post_prologue_pc = after_prologue (pc); > - > - /* If after_prologue returned a useful address, then use it. Else > - fall back on the instruction skipping code. */ > - if (post_prologue_pc != 0) > - return max (pc, post_prologue_pc); > - else > - return sh_skip_prologue_hard_way (pc); > -} > - > -/* Immediately after a function call, return the saved pc. > - Can't always go through the frames for this because on some machines > - the new frame is not set up until the new function executes > - some instructions. > - > - The return address is the value saved in the PR register + 4 */ > -static CORE_ADDR > -sh_saved_pc_after_call (struct frame_info *frame) > -{ > - return (ADDR_BITS_REMOVE (read_register (PR_REGNUM))); > -} > - > -/* Should call_function allocate stack space for a struct return? */ > -static int > -sh_use_struct_convention (int gcc_p, struct type *type) > -{ > -#if 0 > - return (TYPE_LENGTH (type) > 1); > -#else > - int len = TYPE_LENGTH (type); > - int nelem = TYPE_NFIELDS (type); > - return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) && > - (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4); > -#endif > -} > +/* The following instructions are used for epilogue testing. */ > +#define IS_RESTORE_FP(x) ((x) == 0x6ef6) > +#define IS_RTS(x) ((x) == 0x000b) > +#define IS_LDS(x) ((x) == 0x4f26) > +#define IS_MOV_FP_SP(x) ((x) == 0x6fe3) > +#define IS_ADD_REG_TO_FP(x) (((x) & 0xff0f) == 0x3e0c) > +#define IS_ADD_IMM_FP(x) (((x) & 0xff00) == 0x7e00) > > /* Disassemble an instruction. */ > static int > @@ -473,295 +375,133 @@ gdb_print_insn_sh (bfd_vma memaddr, disa > return print_insn_sh (memaddr, info); > } > > -/* Given a GDB frame, determine the address of the calling function's > - frame. This will be used to create a new GDB frame struct, and > - then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC > - will be called for the new frame. > - > - For us, the frame address is its stack pointer value, so we look up > - the function prologue to determine the caller's sp value, and return it. */ > static CORE_ADDR > -sh_frame_chain (struct frame_info *frame) > -{ > - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), > - get_frame_base (frame), > - get_frame_base (frame))) > - return get_frame_base (frame); /* dummy frame same as caller's frame */ > - if (get_frame_pc (frame) && !inside_entry_file (get_frame_pc (frame))) > - return read_memory_integer (get_frame_base (frame) > - + get_frame_extra_info (frame)->f_offset, 4); > - else > - return 0; > -} > - > -/* Find REGNUM on the stack. Otherwise, it's in an active register. One thing > - we might want to do here is to check REGNUM against the clobber mask, and > - somehow flag it as invalid if it isn't saved on the stack somewhere. This > - would provide a graceful failure mode when trying to get the value of > - caller-saves registers for an inner frame. */ > -static CORE_ADDR > -sh_find_callers_reg (struct frame_info *fi, int regnum) > -{ > - for (; fi; fi = get_next_frame (fi)) > - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi), > - get_frame_base (fi))) > - /* When the caller requests PR from the dummy frame, we return PC because > - that's where the previous routine appears to have done a call from. */ > - return deprecated_read_register_dummy (get_frame_pc (fi), > - get_frame_base (fi), regnum); > - else > - { > - DEPRECATED_FRAME_INIT_SAVED_REGS (fi); > - if (!get_frame_pc (fi)) > - return 0; > - if (get_frame_saved_regs (fi)[regnum] != 0) > - return read_memory_integer (get_frame_saved_regs (fi)[regnum], > - register_size (current_gdbarch, regnum)); > - } > - return read_register (regnum); > -} > - > -/* Put here the code to store, into a struct frame_saved_regs, the > - addresses of the saved registers of frame described by FRAME_INFO. > - This includes special registers such as pc and fp saved in special > - ways in the stack frame. sp is even more special: the address we > - return for it IS the sp for the next frame. */ > -static void > -sh_nofp_frame_init_saved_regs (struct frame_info *fi) > -{ > - int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof(int)); > - int rn; > - int have_fp = 0; > - int depth; > - int pc; > - int opc; > - int insn; > +sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, > + struct sh_frame_cache *cache) > +{ > + ULONGEST inst; > + CORE_ADDR opc; > + int offset; > + int sav_offset = 0; > int r3_val = 0; > - char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), > - get_frame_base (fi)); > - > - if (get_frame_saved_regs (fi) == NULL) > - frame_saved_regs_zalloc (fi); > - else > - memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS); > - > - if (dummy_regs) > - { > - /* DANGER! This is ONLY going to work if the char buffer format of > - the saved registers is byte-for-byte identical to the > - CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */ > - memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS); > - return; > - } > - > - get_frame_extra_info (fi)->leaf_function = 1; > - get_frame_extra_info (fi)->f_offset = 0; > + int reg, sav_reg = -1; > > - for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++) > - where[rn] = -1; > - > - depth = 0; > - > - /* Loop around examining the prologue insns until we find something > - that does not appear to be part of the prologue. But give up > - after 20 of them, since we're getting silly then. */ > - > - pc = get_frame_func (fi); > - if (!pc) > - { > - deprecated_update_frame_pc_hack (fi, 0); > - return; > - } > + if (pc >= current_pc) > + return current_pc; > > + cache->uses_fp = 0; > for (opc = pc + (2 * 28); pc < opc; pc += 2) > { > - insn = read_memory_integer (pc, 2); > + inst = read_memory_unsigned_integer (pc, 2); > /* See where the registers will be saved to */ > - if (IS_PUSH (insn)) > + if (IS_PUSH (inst)) > { > - rn = GET_PUSHED_REG (insn); > - where[rn] = depth; > - depth += 4; > + cache->saved_regs[GET_SOURCE_REG (inst)] = cache->sp_offset; > + cache->sp_offset += 4; > } > - else if (IS_STS (insn)) > + else if (IS_STS (inst)) > { > - where[PR_REGNUM] = depth; > - /* If we're storing the pr then this isn't a leaf */ > - get_frame_extra_info (fi)->leaf_function = 0; > - depth += 4; > + cache->saved_regs[PR_REGNUM] = cache->sp_offset; > + cache->sp_offset += 4; > } > - else if (IS_MOV_R3 (insn)) > + else if (IS_MOV_R3 (inst)) > { > - r3_val = ((insn & 0xff) ^ 0x80) - 0x80; > + r3_val = ((inst & 0xff) ^ 0x80) - 0x80; > } > - else if (IS_SHLL_R3 (insn)) > + else if (IS_SHLL_R3 (inst)) > { > r3_val <<= 1; > } > - else if (IS_ADD_R3SP (insn)) > + else if (IS_ADD_R3SP (inst)) > { > - depth += -r3_val; > + cache->sp_offset += -r3_val; > } > - else if (IS_ADD_SP (insn)) > + else if (IS_ADD_IMM_SP (inst)) > { > - depth -= ((insn & 0xff) ^ 0x80) - 0x80; > + offset = ((inst & 0xff) ^ 0x80) - 0x80; > + cache->sp_offset -= offset; > } > - else if (IS_MOV_SP_FP (insn)) > - break; > -#if 0 /* This used to just stop when it found an instruction that > - was not considered part of the prologue. Now, we just > - keep going looking for likely instructions. */ > - else > - break; > -#endif > - } > - > - /* Now we know how deep things are, we can work out their addresses */ > - > - for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++) > - { > - if (where[rn] >= 0) > - { > - if (rn == DEPRECATED_FP_REGNUM) > - have_fp = 1; > - > - get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - where[rn] + depth - 4; > - } > - else > - { > - get_frame_saved_regs (fi)[rn] = 0; > - } > - } > - > - if (have_fp) > - { > - get_frame_saved_regs (fi)[SP_REGNUM] = read_memory_integer (get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM], 4); > - } > - else > - { > - get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) - 4; > - } > - > - get_frame_extra_info (fi)->f_offset = depth - where[DEPRECATED_FP_REGNUM] - 4; > - /* Work out the return pc - either from the saved pr or the pr > - value */ > -} > - > -/* For vectors of 4 floating point registers. */ > -static int > -fv_reg_base_num (int fv_regnum) > -{ > - int fp_regnum; > - > - fp_regnum = FP0_REGNUM + > - (fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4; > - return fp_regnum; > -} > - > -/* For double precision floating point registers, i.e 2 fp regs.*/ > -static int > -dr_reg_base_num (int dr_regnum) > -{ > - int fp_regnum; > - > - fp_regnum = FP0_REGNUM + > - (dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2; > - return fp_regnum; > -} > - > -static void > -sh_fp_frame_init_saved_regs (struct frame_info *fi) > -{ > - int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int)); > - int rn; > - int have_fp = 0; > - int depth; > - int pc; > - int opc; > - int insn; > - int r3_val = 0; > - char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), get_frame_base (fi)); > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > - if (get_frame_saved_regs (fi) == NULL) > - frame_saved_regs_zalloc (fi); > - else > - memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS); > - > - if (dummy_regs) > - { > - /* DANGER! This is ONLY going to work if the char buffer format of > - the saved registers is byte-for-byte identical to the > - CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */ > - memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS); > - return; > - } > - > - get_frame_extra_info (fi)->leaf_function = 1; > - get_frame_extra_info (fi)->f_offset = 0; > - > - for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++) > - where[rn] = -1; > - > - depth = 0; > - > - /* Loop around examining the prologue insns until we find something > - that does not appear to be part of the prologue. But give up > - after 20 of them, since we're getting silly then. */ > - > - pc = get_frame_func (fi); > - if (!pc) > - { > - deprecated_update_frame_pc_hack (fi, 0); > - return; > - } > - > - for (opc = pc + (2 * 28); pc < opc; pc += 2) > - { > - insn = read_memory_integer (pc, 2); > - /* See where the registers will be saved to */ > - if (IS_PUSH (insn)) > - { > - rn = GET_PUSHED_REG (insn); > - where[rn] = depth; > - depth += 4; > - } > - else if (IS_STS (insn)) > - { > - where[PR_REGNUM] = depth; > - /* If we're storing the pr then this isn't a leaf */ > - get_frame_extra_info (fi)->leaf_function = 0; > - depth += 4; > - } > - else if (IS_MOV_R3 (insn)) > - { > - r3_val = ((insn & 0xff) ^ 0x80) - 0x80; > - } > - else if (IS_SHLL_R3 (insn)) > - { > - r3_val <<= 1; > + else if (IS_MOVW_PCREL_TO_REG (inst)) > + { > + if (sav_reg < 0) > + { > + reg = GET_TARGET_REG (inst); > + if (reg < 14) > + { > + sav_reg = reg; > + offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1; > + sav_offset = > + read_memory_integer (((pc + 4) & ~3) + offset, 2); > + } > + } > } > - else if (IS_ADD_R3SP (insn)) > - { > - depth += -r3_val; > + else if (IS_MOVL_PCREL_TO_REG (inst)) > + { > + if (sav_reg < 0) > + { > + reg = (inst & 0x0f00) >> 8; > + if (reg < 14) > + { > + sav_reg = reg; > + offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1; > + sav_offset = > + read_memory_integer (((pc + 4) & ~3) + offset, 4); > + } > + } > } > - else if (IS_ADD_SP (insn)) > - { > - depth -= ((insn & 0xff) ^ 0x80) - 0x80; > + else if (IS_SUB_REG_FROM_SP (inst)) > + { > + reg = GET_SOURCE_REG (inst); > + if (sav_reg > 0 && reg == sav_reg) > + { > + sav_reg = -1; > + } > + cache->sp_offset += sav_offset; > } > - else if (IS_FMOV (insn)) > + else if (IS_FPUSH (inst)) > { > - if (read_register (tdep->FPSCR_REGNUM) & FPSCR_SZ) > + if (read_register (FPSCR_REGNUM) & FPSCR_SZ) > { > - depth += 8; > + cache->sp_offset += 8; > } > else > { > - depth += 4; > + cache->sp_offset += 4; > } > } > - else if (IS_MOV_SP_FP (insn)) > - break; > + else if (IS_MOV_SP_FP (inst)) > + { > + if (!cache->uses_fp) > + cache->uses_fp = 1; > + /* At this point, only allow argument register moves to other > + registers or argument register moves to @(X,fp) which are > + moving the register arguments onto the stack area allocated > + by a former add somenumber to SP call. Don't allow moving > + to an fp indirect address above fp + cache->sp_offset. */ > + pc += 2; > + for (opc = pc + 12; pc < opc; pc += 2) > + { > + inst = read_memory_integer (pc, 2); > + if (IS_MOV_ARG_TO_IND_R14 (inst)) > + { > + reg = GET_SOURCE_REG (inst); > + if (cache->sp_offset > 0) > + cache->saved_regs[reg] = cache->sp_offset; > + } > + else if (IS_MOV_ARG_TO_IND_R14_WITH_DISP (inst)) > + { > + reg = GET_SOURCE_REG (inst); > + offset = (inst & 0xf) * 4; > + if (cache->sp_offset > offset) > + cache->saved_regs[reg] = cache->sp_offset - offset; > + } > + else if (IS_MOV_ARG_TO_REG (inst)) > + continue; > + else > + break; > + } > + break; > + } > #if 0 /* This used to just stop when it found an instruction that > was not considered part of the prologue. Now, we just > keep going looking for likely instructions. */ > @@ -770,68 +510,71 @@ sh_fp_frame_init_saved_regs (struct fram > #endif > } > > - /* Now we know how deep things are, we can work out their addresses */ > + return pc; > +} > > - for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++) > - { > - if (where[rn] >= 0) > - { > - if (rn == DEPRECATED_FP_REGNUM) > - have_fp = 1; > +/* Skip any prologue before the guts of a function */ > > - get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - where[rn] + depth - 4; > - } > - else > - { > - get_frame_saved_regs (fi)[rn] = 0; > - } > - } > +/* Skip the prologue using the debug information. If this fails we'll > + fall back on the 'guess' method below. */ > +static CORE_ADDR > +after_prologue (CORE_ADDR pc) > +{ > + struct symtab_and_line sal; > + CORE_ADDR func_addr, func_end; > > - if (have_fp) > - { > - get_frame_saved_regs (fi)[SP_REGNUM] = > - read_memory_integer (get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM], 4); > - } > - else > - { > - get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) - 4; > - } > + /* If we can not find the symbol in the partial symbol table, then > + there is no hope we can determine the function's start address > + with this code. */ > + if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) > + return 0; > + > + /* Get the line associated with FUNC_ADDR. */ > + sal = find_pc_line (func_addr, 0); > > - get_frame_extra_info (fi)->f_offset = depth - where[DEPRECATED_FP_REGNUM] - 4; > - /* Work out the return pc - either from the saved pr or the pr > - value */ > + /* There are only two cases to consider. First, the end of the source line > + is within the function bounds. In that case we return the end of the > + source line. Second is the end of the source line extends beyond the > + bounds of the current function. We need to use the slow code to > + examine instructions in that case. */ > + if (sal.end < func_end) > + return sal.end; > + else > + return 0; > } > > -/* Initialize the extra info saved in a FRAME */ > -static void > -sh_init_extra_frame_info (int fromleaf, struct frame_info *fi) > +static CORE_ADDR > +sh_skip_prologue (CORE_ADDR start_pc) > { > + CORE_ADDR pc; > + struct sh_frame_cache cache; > > - frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info)); > + /* See if we can determine the end of the prologue via the symbol table. > + If so, then return either PC, or the PC after the prologue, whichever > + is greater. */ > + pc = after_prologue (start_pc); > > - if (get_next_frame (fi)) > - deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi))); > + /* If after_prologue returned a useful address, then use it. Else > + fall back on the instruction skipping code. */ > + if (pc) > + return max (pc, start_pc); > > - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi), > - get_frame_base (fi))) > - { > - /* We need to setup fi->frame here because call_function_by_hand > - gets it wrong by assuming it's always FP. */ > - deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), > - SP_REGNUM)); > - get_frame_extra_info (fi)->return_pc = deprecated_read_register_dummy (get_frame_pc (fi), > - get_frame_base (fi), > - PC_REGNUM); > - get_frame_extra_info (fi)->f_offset = -(DEPRECATED_CALL_DUMMY_LENGTH + 4); > - get_frame_extra_info (fi)->leaf_function = 0; > - return; > - } > - else > - { > - DEPRECATED_FRAME_INIT_SAVED_REGS (fi); > - get_frame_extra_info (fi)->return_pc = > - sh_find_callers_reg (fi, PR_REGNUM); > - } > + cache.sp_offset = -4; > + pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache); > + if (!cache.uses_fp) > + return start_pc; > + > + return pc; > +} > + > +/* Should call_function allocate stack space for a struct return? */ > +static int > +sh_use_struct_convention (int gcc_p, struct type *type) > +{ > + int len = TYPE_LENGTH (type); > + int nelem = TYPE_NFIELDS (type); > + return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) && > + (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4); > } > > /* Extract from an array REGBUF containing the (raw) register state > @@ -841,48 +584,12 @@ static CORE_ADDR > sh_extract_struct_value_address (struct regcache *regcache) > { > ULONGEST addr; > - /*FIXME: Is R0 really correct here? Not STRUCT_RETURN_REGNUM? */ > + > regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr); > return addr; > } > > static CORE_ADDR > -sh_frame_saved_pc (struct frame_info *frame) > -{ > - return (get_frame_extra_info (frame)->return_pc); > -} > - > -/* Discard from the stack the innermost frame, > - restoring all saved registers. */ > -static void > -sh_pop_frame (void) > -{ > - register struct frame_info *frame = get_current_frame (); > - register CORE_ADDR fp; > - register int regnum; > - > - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), > - get_frame_base (frame), > - get_frame_base (frame))) > - generic_pop_dummy_frame (); > - else > - { > - fp = get_frame_base (frame); > - DEPRECATED_FRAME_INIT_SAVED_REGS (frame); > - > - /* Copy regs from where they were saved in the frame */ > - for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) > - if (get_frame_saved_regs (frame)[regnum]) > - write_register (regnum, > - read_memory_integer (get_frame_saved_regs (frame)[regnum], 4)); > - > - write_register (PC_REGNUM, get_frame_extra_info (frame)->return_pc); > - write_register (SP_REGNUM, fp + 4); > - } > - flush_cached_frames (); > -} > - > -static CORE_ADDR > sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp) > { > return sp & ~3; > @@ -958,16 +665,13 @@ sh_push_dummy_call_fpu (struct gdbarch * > char valbuf[4]; > int len; > int odd_sized_struct; > - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > > /* first force sp to a 4-byte alignment */ > sp = sh_frame_align (gdbarch, sp); > > - /* The "struct return pointer" pseudo-argument has its own dedicated > - register */ > if (struct_return) > - regcache_cooked_write_unsigned (regcache, > - STRUCT_RETURN_REGNUM, > + regcache_cooked_write_unsigned (regcache, > + STRUCT_RETURN_REGNUM, > struct_addr); > > /* Now make sure there's space on the stack */ > @@ -1069,13 +773,10 @@ sh_push_dummy_call_nofpu (struct gdbarch > char valbuf[4]; > int len; > int odd_sized_struct; > - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > > /* first force sp to a 4-byte alignment */ > sp = sh_frame_align (gdbarch, sp); > > - /* The "struct return pointer" pseudo-argument has its own dedicated > - register */ > if (struct_return) > regcache_cooked_write_unsigned (regcache, > STRUCT_RETURN_REGNUM, > @@ -1239,8 +940,6 @@ sh3e_sh4_store_return_value (struct type > static void > sh_generic_show_regs (void) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", > paddr (read_register (PC_REGNUM)), > (long) read_register (SR_REGNUM), > @@ -1275,8 +974,6 @@ sh_generic_show_regs (void) > static void > sh3_show_regs (void) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", > paddr (read_register (PC_REGNUM)), > (long) read_register (SR_REGNUM), > @@ -1288,8 +985,8 @@ sh3_show_regs (void) > (long) read_register (GBR_REGNUM), > (long) read_register (VBR_REGNUM)); > printf_filtered (" SSR=%08lx SPC=%08lx", > - (long) read_register (tdep->SSR_REGNUM), > - (long) read_register (tdep->SPC_REGNUM)); > + (long) read_register (SSR_REGNUM), > + (long) read_register (SPC_REGNUM)); > > printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", > (long) read_register (0), > @@ -1326,8 +1023,8 @@ sh2e_show_regs (void) > (long) read_register (GBR_REGNUM), > (long) read_register (VBR_REGNUM)); > printf_filtered (" FPUL=%08lx FPSCR=%08lx", > - (long) read_register (gdbarch_tdep (current_gdbarch)->FPUL_REGNUM), > - (long) read_register (gdbarch_tdep (current_gdbarch)->FPSCR_REGNUM)); > + (long) read_register (FPUL_REGNUM), > + (long) read_register (FPSCR_REGNUM)); > > printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", > (long) read_register (0), > @@ -1371,8 +1068,6 @@ sh2e_show_regs (void) > static void > sh3e_show_regs (void) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", > paddr (read_register (PC_REGNUM)), > (long) read_register (SR_REGNUM), > @@ -1384,11 +1079,11 @@ sh3e_show_regs (void) > (long) read_register (GBR_REGNUM), > (long) read_register (VBR_REGNUM)); > printf_filtered (" SSR=%08lx SPC=%08lx", > - (long) read_register (tdep->SSR_REGNUM), > - (long) read_register (tdep->SPC_REGNUM)); > + (long) read_register (SSR_REGNUM), > + (long) read_register (SPC_REGNUM)); > printf_filtered (" FPUL=%08lx FPSCR=%08lx", > - (long) read_register (tdep->FPUL_REGNUM), > - (long) read_register (tdep->FPSCR_REGNUM)); > + (long) read_register (FPUL_REGNUM), > + (long) read_register (FPSCR_REGNUM)); > > printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", > (long) read_register (0), > @@ -1432,8 +1127,6 @@ sh3e_show_regs (void) > static void > sh3_dsp_show_regs (void) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", > paddr (read_register (PC_REGNUM)), > (long) read_register (SR_REGNUM), > @@ -1446,11 +1139,11 @@ sh3_dsp_show_regs (void) > (long) read_register (VBR_REGNUM)); > > printf_filtered (" SSR=%08lx SPC=%08lx", > - (long) read_register (tdep->SSR_REGNUM), > - (long) read_register (tdep->SPC_REGNUM)); > + (long) read_register (SSR_REGNUM), > + (long) read_register (SPC_REGNUM)); > > printf_filtered (" DSR=%08lx", > - (long) read_register (tdep->DSR_REGNUM)); > + (long) read_register (DSR_REGNUM)); > > printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", > (long) read_register (0), > @@ -1472,28 +1165,26 @@ sh3_dsp_show_regs (void) > (long) read_register (15)); > > printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n", > - (long) read_register (tdep->A0G_REGNUM) & 0xff, > - (long) read_register (tdep->A0_REGNUM), > - (long) read_register (tdep->M0_REGNUM), > - (long) read_register (tdep->X0_REGNUM), > - (long) read_register (tdep->Y0_REGNUM), > - (long) read_register (tdep->RS_REGNUM), > - (long) read_register (tdep->MOD_REGNUM)); > + (long) read_register (A0G_REGNUM) & 0xff, > + (long) read_register (A0_REGNUM), > + (long) read_register (M0_REGNUM), > + (long) read_register (X0_REGNUM), > + (long) read_register (Y0_REGNUM), > + (long) read_register (RS_REGNUM), > + (long) read_register (MOD_REGNUM)); > printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n", > - (long) read_register (tdep->A1G_REGNUM) & 0xff, > - (long) read_register (tdep->A1_REGNUM), > - (long) read_register (tdep->M1_REGNUM), > - (long) read_register (tdep->X1_REGNUM), > - (long) read_register (tdep->Y1_REGNUM), > - (long) read_register (tdep->RE_REGNUM)); > + (long) read_register (A1G_REGNUM) & 0xff, > + (long) read_register (A1_REGNUM), > + (long) read_register (M1_REGNUM), > + (long) read_register (X1_REGNUM), > + (long) read_register (Y1_REGNUM), > + (long) read_register (RE_REGNUM)); > } > > static void > sh4_show_regs (void) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > - int pr = read_register (tdep->FPSCR_REGNUM) & 0x80000; > + int pr = read_register (FPSCR_REGNUM) & 0x80000; > printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", > paddr (read_register (PC_REGNUM)), > (long) read_register (SR_REGNUM), > @@ -1505,11 +1196,11 @@ sh4_show_regs (void) > (long) read_register (GBR_REGNUM), > (long) read_register (VBR_REGNUM)); > printf_filtered (" SSR=%08lx SPC=%08lx", > - (long) read_register (tdep->SSR_REGNUM), > - (long) read_register (tdep->SPC_REGNUM)); > + (long) read_register (SSR_REGNUM), > + (long) read_register (SPC_REGNUM)); > printf_filtered (" FPUL=%08lx FPSCR=%08lx", > - (long) read_register (tdep->FPUL_REGNUM), > - (long) read_register (tdep->FPSCR_REGNUM)); > + (long) read_register (FPUL_REGNUM), > + (long) read_register (FPSCR_REGNUM)); > > printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", > (long) read_register (0), > @@ -1557,8 +1248,6 @@ sh4_show_regs (void) > static void > sh_dsp_show_regs (void) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", > paddr (read_register (PC_REGNUM)), > (long) read_register (SR_REGNUM), > @@ -1571,7 +1260,7 @@ sh_dsp_show_regs (void) > (long) read_register (VBR_REGNUM)); > > printf_filtered (" DSR=%08lx", > - (long) read_register (tdep->DSR_REGNUM)); > + (long) read_register (DSR_REGNUM)); > > printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", > (long) read_register (0), > @@ -1593,20 +1282,20 @@ sh_dsp_show_regs (void) > (long) read_register (15)); > > printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n", > - (long) read_register (tdep->A0G_REGNUM) & 0xff, > - (long) read_register (tdep->A0_REGNUM), > - (long) read_register (tdep->M0_REGNUM), > - (long) read_register (tdep->X0_REGNUM), > - (long) read_register (tdep->Y0_REGNUM), > - (long) read_register (tdep->RS_REGNUM), > - (long) read_register (tdep->MOD_REGNUM)); > + (long) read_register (A0G_REGNUM) & 0xff, > + (long) read_register (A0_REGNUM), > + (long) read_register (M0_REGNUM), > + (long) read_register (X0_REGNUM), > + (long) read_register (Y0_REGNUM), > + (long) read_register (RS_REGNUM), > + (long) read_register (MOD_REGNUM)); > printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n", > - (long) read_register (tdep->A1G_REGNUM) & 0xff, > - (long) read_register (tdep->A1_REGNUM), > - (long) read_register (tdep->M1_REGNUM), > - (long) read_register (tdep->X1_REGNUM), > - (long) read_register (tdep->Y1_REGNUM), > - (long) read_register (tdep->RE_REGNUM)); > + (long) read_register (A1G_REGNUM) & 0xff, > + (long) read_register (A1_REGNUM), > + (long) read_register (M1_REGNUM), > + (long) read_register (X1_REGNUM), > + (long) read_register (Y1_REGNUM), > + (long) read_register (RE_REGNUM)); > } > > static void > @@ -1621,11 +1310,9 @@ sh_show_regs_command (char *args, int fr > static struct type * > sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > if ((reg_nr >= FP0_REGNUM > - && (reg_nr <= tdep->FP_LAST_REGNUM)) > - || (reg_nr == tdep->FPUL_REGNUM)) > + && (reg_nr <= FP_LAST_REGNUM)) > + || (reg_nr == FPUL_REGNUM)) > return builtin_type_float; > else > return builtin_type_int; > @@ -1643,17 +1330,15 @@ sh_sh4_build_float_register_type (int hi > static struct type * > sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > - > if ((reg_nr >= FP0_REGNUM > - && (reg_nr <= tdep->FP_LAST_REGNUM)) > - || (reg_nr == tdep->FPUL_REGNUM)) > + && (reg_nr <= FP_LAST_REGNUM)) > + || (reg_nr == FPUL_REGNUM)) > return builtin_type_float; > - else if (reg_nr >= tdep->DR0_REGNUM > - && reg_nr <= tdep->DR_LAST_REGNUM) > + else if (reg_nr >= DR0_REGNUM > + && reg_nr <= DR_LAST_REGNUM) > return builtin_type_double; > - else if (reg_nr >= tdep->FV0_REGNUM > - && reg_nr <= tdep->FV_LAST_REGNUM) > + else if (reg_nr >= FV0_REGNUM > + && reg_nr <= FV_LAST_REGNUM) > return sh_sh4_build_float_register_type (3); > else > return builtin_type_int; > @@ -1695,10 +1380,8 @@ static void > sh_sh4_register_convert_to_virtual (int regnum, struct type *type, > char *from, char *to) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > - if (regnum >= tdep->DR0_REGNUM > - && regnum <= tdep->DR_LAST_REGNUM) > + if (regnum >= DR0_REGNUM > + && regnum <= DR_LAST_REGNUM) > { > DOUBLEST val; > floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val); > @@ -1712,10 +1395,8 @@ static void > sh_sh4_register_convert_to_raw (struct type *type, int regnum, > const void *from, void *to) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > - if (regnum >= tdep->DR0_REGNUM > - && regnum <= tdep->DR_LAST_REGNUM) > + if (regnum >= DR0_REGNUM > + && regnum <= DR_LAST_REGNUM) > { > DOUBLEST val = extract_typed_floating (from, type); > floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to); > @@ -1724,16 +1405,37 @@ sh_sh4_register_convert_to_raw (struct t > error("sh_register_convert_to_raw called with non DR register number"); > } > > +/* For vectors of 4 floating point registers. */ > +static int > +fv_reg_base_num (int fv_regnum) > +{ > + int fp_regnum; > + > + fp_regnum = FP0_REGNUM + > + (fv_regnum - FV0_REGNUM) * 4; > + return fp_regnum; > +} > + > +/* For double precision floating point registers, i.e 2 fp regs.*/ > +static int > +dr_reg_base_num (int dr_regnum) > +{ > + int fp_regnum; > + > + fp_regnum = FP0_REGNUM + > + (dr_regnum - DR0_REGNUM) * 2; > + return fp_regnum; > +} > + > static void > sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, > int reg_nr, void *buffer) > { > int base_regnum, portion; > char temp_buffer[MAX_REGISTER_SIZE]; > - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > > - if (reg_nr >= tdep->DR0_REGNUM > - && reg_nr <= tdep->DR_LAST_REGNUM) > + if (reg_nr >= DR0_REGNUM > + && reg_nr <= DR_LAST_REGNUM) > { > base_regnum = dr_reg_base_num (reg_nr); > > @@ -1748,8 +1450,8 @@ sh_pseudo_register_read (struct gdbarch > gdbarch_register_type (gdbarch, reg_nr), > temp_buffer, buffer); > } > - else if (reg_nr >= tdep->FV0_REGNUM > - && reg_nr <= tdep->FV_LAST_REGNUM) > + else if (reg_nr >= FV0_REGNUM > + && reg_nr <= FV_LAST_REGNUM) > { > base_regnum = fv_reg_base_num (reg_nr); > > @@ -1767,10 +1469,9 @@ sh_pseudo_register_write (struct gdbarch > { > int base_regnum, portion; > char temp_buffer[MAX_REGISTER_SIZE]; > - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > > - if (reg_nr >= tdep->DR0_REGNUM > - && reg_nr <= tdep->DR_LAST_REGNUM) > + if (reg_nr >= DR0_REGNUM > + && reg_nr <= DR_LAST_REGNUM) > { > base_regnum = dr_reg_base_num (reg_nr); > > @@ -1784,8 +1485,8 @@ sh_pseudo_register_write (struct gdbarch > (temp_buffer > + register_size (gdbarch, base_regnum) * portion)); > } > - else if (reg_nr >= tdep->FV0_REGNUM > - && reg_nr <= tdep->FV_LAST_REGNUM) > + else if (reg_nr >= FV0_REGNUM > + && reg_nr <= FV_LAST_REGNUM) > { > base_regnum = fv_reg_base_num (reg_nr); > > @@ -1804,7 +1505,7 @@ do_fv_register_info (struct gdbarch *gdb > { > int first_fp_reg_num = fv_reg_base_num (fv_regnum); > fprintf_filtered (file, "fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", > - fv_regnum - gdbarch_tdep (gdbarch)->FV0_REGNUM, > + fv_regnum - FV0_REGNUM, > (int) read_register (first_fp_reg_num), > (int) read_register (first_fp_reg_num + 1), > (int) read_register (first_fp_reg_num + 2), > @@ -1819,7 +1520,7 @@ do_dr_register_info (struct gdbarch *gdb > int first_fp_reg_num = dr_reg_base_num (dr_regnum); > > fprintf_filtered (file, "dr%d\t0x%08x%08x\n", > - dr_regnum - gdbarch_tdep (gdbarch)->DR0_REGNUM, > + dr_regnum - DR0_REGNUM, > (int) read_register (first_fp_reg_num), > (int) read_register (first_fp_reg_num + 1)); > } > @@ -1828,16 +1529,14 @@ static void > sh_print_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file, > int regnum) > { > - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > - > if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS) > internal_error (__FILE__, __LINE__, > "Invalid pseudo register number %d\n", regnum); > - else if (regnum >= tdep->DR0_REGNUM > - && regnum <= tdep->DR_LAST_REGNUM) > + else if (regnum >= DR0_REGNUM > + && regnum <= DR_LAST_REGNUM) > do_dr_register_info (gdbarch, file, regnum); > - else if (regnum >= tdep->FV0_REGNUM > - && regnum <= tdep->FV_LAST_REGNUM) > + else if (regnum >= FV0_REGNUM > + && regnum <= FV_LAST_REGNUM) > do_fv_register_info (gdbarch, file, regnum); > } > > @@ -1957,7 +1656,7 @@ sh_print_registers_info (struct gdbarch > regnum ++; > } > else > - regnum += (gdbarch_tdep (gdbarch)->FP_LAST_REGNUM - FP0_REGNUM); /* skip FP regs */ > + regnum += (FP_LAST_REGNUM - FP0_REGNUM); /* skip FP regs */ > } > else > { > @@ -2019,86 +1718,317 @@ sh_linux_svr4_fetch_link_map_offsets (vo > } > #endif /* SVR4_SHARED_LIBS */ > > - > -enum > -{ > - DSP_DSR_REGNUM = 24, > - DSP_A0G_REGNUM, > - DSP_A0_REGNUM, > - DSP_A1G_REGNUM, > - DSP_A1_REGNUM, > - DSP_M0_REGNUM, > - DSP_M1_REGNUM, > - DSP_X0_REGNUM, > - DSP_X1_REGNUM, > - DSP_Y0_REGNUM, > - DSP_Y1_REGNUM, > - > - DSP_MOD_REGNUM = 40, > - > - DSP_RS_REGNUM = 43, > - DSP_RE_REGNUM, > - > - DSP_R0_BANK_REGNUM = 51, > - DSP_R7_BANK_REGNUM = DSP_R0_BANK_REGNUM + 7 > -}; > - > static int > sh_dsp_register_sim_regno (int nr) > { > if (legacy_register_sim_regno (nr) < 0) > return legacy_register_sim_regno (nr); > - if (nr >= DSP_DSR_REGNUM && nr <= DSP_Y1_REGNUM) > - return nr - DSP_DSR_REGNUM + SIM_SH_DSR_REGNUM; > - if (nr == DSP_MOD_REGNUM) > + if (nr >= DSR_REGNUM && nr <= Y1_REGNUM) > + return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM; > + if (nr == MOD_REGNUM) > return SIM_SH_MOD_REGNUM; > - if (nr == DSP_RS_REGNUM) > + if (nr == RS_REGNUM) > return SIM_SH_RS_REGNUM; > - if (nr == DSP_RE_REGNUM) > + if (nr == RE_REGNUM) > return SIM_SH_RE_REGNUM; > - if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM) > - return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM; > + if (nr >= R0_BANK_REGNUM && nr <= R7_BANK_REGNUM) > + return nr - R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM; > return nr; > } > - > + > +static struct sh_frame_cache * > +sh_alloc_frame_cache (void) > +{ > + struct sh_frame_cache *cache; > + int i; > + > + cache = FRAME_OBSTACK_ZALLOC (struct sh_frame_cache); > + > + /* Base address. */ > + cache->base = 0; > + cache->saved_sp = 0; > + cache->sp_offset = 0; > + cache->pc = 0; > + > + /* Frameless until proven otherwise. */ > + cache->uses_fp = 0; > + > + /* Saved registers. We initialize these to -1 since zero is a valid > + offset (that's where fp is supposed to be stored). */ > + for (i = 0; i < SH_NUM_REGS; i++) > + { > + cache->saved_regs[i] = -1; > + } > + > + return cache; > +} > + > +static struct sh_frame_cache * > +sh_frame_cache (struct frame_info *next_frame, void **this_cache) > +{ > + struct sh_frame_cache *cache; > + CORE_ADDR current_pc; > + int i; > + > + if (*this_cache) > + return *this_cache; > + > + cache = sh_alloc_frame_cache (); > + *this_cache = cache; > + > + /* In principle, for normal frames, fp holds the frame pointer, > + which holds the base address for the current stack frame. > + However, for functions that don't need it, the frame pointer is > + optional. For these "frameless" functions the frame pointer is > + actually the frame pointer of the calling frame. */ > + cache->base = frame_unwind_register_unsigned (next_frame, FP_REGNUM); > + if (cache->base == 0) > + return cache; > + > + cache->pc = frame_func_unwind (next_frame); > + current_pc = frame_pc_unwind (next_frame); > + if (cache->pc != 0) > + sh_analyze_prologue (cache->pc, current_pc, cache); > + > + if (!cache->uses_fp) > + { > + /* We didn't find a valid frame, which means that CACHE->base > + currently holds the frame pointer for our calling frame. If > + we're at the start of a function, or somewhere half-way its > + prologue, the function's frame probably hasn't been fully > + setup yet. Try to reconstruct the base address for the stack > + frame by looking at the stack pointer. For truly "frameless" > + functions this might work too. */ > + cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM); > + } > + > + /* Now that we have the base address for the stack frame we can > + calculate the value of sp in the calling frame. */ > + cache->saved_sp = cache->base + cache->sp_offset; > + > + /* Adjust all the saved registers such that they contain addresses > + instead of offsets. */ > + for (i = 0; i < SH_NUM_REGS; i++) > + if (cache->saved_regs[i] != -1) > + cache->saved_regs[i] = cache->saved_sp - cache->saved_regs[i] - 4; > + > + return cache; > +} > + > +static void > +sh_frame_prev_register (struct frame_info *next_frame, void **this_cache, > + int regnum, int *optimizedp, > + enum lval_type *lvalp, CORE_ADDR *addrp, > + int *realnump, void *valuep) > +{ > + struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); > + > + gdb_assert (regnum >= 0); > + > + if (regnum == SP_REGNUM && cache->saved_sp) > + { > + *optimizedp = 0; > + *lvalp = not_lval; > + *addrp = 0; > + *realnump = -1; > + if (valuep) > + { > + /* Store the value. */ > + store_unsigned_integer (valuep, 4, cache->saved_sp); > + } > + return; > + } > + > + /* The PC of the previous frame is stored in the PR register of > + the current frame. Frob regnum so that we pull the value from > + the correct place. */ > + if (regnum == PC_REGNUM) > + regnum = PR_REGNUM; > + > + if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1) > + { > + *optimizedp = 0; > + *lvalp = lval_memory; > + *addrp = cache->saved_regs[regnum]; > + *realnump = -1; > + if (valuep) > + { > + /* Read the value in from memory. */ > + read_memory (*addrp, valuep, > + register_size (current_gdbarch, regnum)); > + } > + return; > + } > + > + frame_register_unwind (next_frame, regnum, > + optimizedp, lvalp, addrp, realnump, valuep); > +} > + > +static void > +sh_frame_this_id (struct frame_info *next_frame, void **this_cache, > + struct frame_id *this_id) > +{ > + struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); > + > + /* This marks the outermost frame. */ > + if (cache->base == 0) > + return; > + > + *this_id = frame_id_build (cache->saved_sp, cache->pc); > +} > + > +static const struct frame_unwind sh_frame_unwind = > +{ > + NORMAL_FRAME, > + sh_frame_this_id, > + sh_frame_prev_register > +}; > + > +static const struct frame_unwind * > +sh_frame_sniffer (struct frame_info *next_frame) > +{ > + return &sh_frame_unwind; > +} > + > +static CORE_ADDR > +sh_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) > +{ > + return frame_unwind_register_unsigned (next_frame, SP_REGNUM); > +} > + > +static CORE_ADDR > +sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) > +{ > + return frame_unwind_register_unsigned (next_frame, PC_REGNUM); > +} > + > +static struct frame_id > +sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) > +{ > + return frame_id_build (sh_unwind_sp (gdbarch, next_frame), > + frame_pc_unwind (next_frame)); > +} > + > +static CORE_ADDR > +sh_frame_base_address (struct frame_info *next_frame, void **this_cache) > +{ > + struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); > + > + return cache->base; > +} > + > +static const struct frame_base sh_frame_base = > +{ > + &sh_frame_unwind, > + sh_frame_base_address, > + sh_frame_base_address, > + sh_frame_base_address > +}; > + > +/* The epilogue is defined here as the area at the end of a function, > + either on the `ret' instruction itself or after an instruction which > + destroys the function's stack frame. */ > +static int > +sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) > +{ > + CORE_ADDR func_addr = 0, func_end = 0; > + > + if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) > + { > + ULONGEST inst; > + /* The sh epilogue is max. 14 bytes long. Give another 14 bytes > + for a nop and some fixed data (e.g. big offsets) which are > + unfortunately also treated as part of the function (which > + means, they are below func_end. */ > + CORE_ADDR addr = func_end - 28; > + if (addr < func_addr + 4) > + addr = func_addr + 4; > + if (pc < addr) > + return 0; > + > + /* First search forward until hitting an rts. */ > + while (addr < func_end > + && !IS_RTS (read_memory_unsigned_integer (addr, 2))) > + addr += 2; > + if (addr >= func_end) > + return 0; > + > + /* At this point we should find a mov.l @r15+,r14 instruction, > + either before or after the rts. If not, then the function has > + probably no "normal" epilogue and we bail out here. */ > + inst = read_memory_unsigned_integer (addr - 2, 2); > + if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2))) > + addr -= 2; > + else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2))) > + return 0; > + > + /* Step over possible lds.l @r15+,pr. */ > + inst = read_memory_unsigned_integer (addr - 2, 2); > + if (IS_LDS (inst)) > + { > + addr -= 2; > + inst = read_memory_unsigned_integer (addr - 2, 2); > + } > + > + /* Step over possible mov r14,r15. */ > + if (IS_MOV_FP_SP (inst)) > + { > + addr -= 2; > + inst = read_memory_unsigned_integer (addr - 2, 2); > + } > + > + /* Now check for FP adjustments, using add #imm,r14 or add rX, r14 > + instructions. */ > + while (addr > func_addr + 4 > + && (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst))) > + { > + addr -= 2; > + inst = read_memory_unsigned_integer (addr - 2, 2); > + } > + > + if (pc >= addr) > + return 1; > + } > + return 0; > +} > + > static gdbarch_init_ftype sh_gdbarch_init; > > static struct gdbarch * > sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) > { > struct gdbarch *gdbarch; > - struct gdbarch_tdep *tdep; > > sh_show_regs = sh_generic_show_regs; > switch (info.bfd_arch_info->mach) > { > case bfd_mach_sh2e: > - sh_show_regs = sh2e_show_regs; > - break; > + sh_show_regs = sh2e_show_regs; > + break; > case bfd_mach_sh_dsp: > - sh_show_regs = sh_dsp_show_regs; > - break; > + sh_show_regs = sh_dsp_show_regs; > + break; > > case bfd_mach_sh3: > - sh_show_regs = sh3_show_regs; > - break; > + sh_show_regs = sh3_show_regs; > + break; > > case bfd_mach_sh3e: > - sh_show_regs = sh3e_show_regs; > - break; > + sh_show_regs = sh3e_show_regs; > + break; > > case bfd_mach_sh3_dsp: > - sh_show_regs = sh3_dsp_show_regs; > - break; > + sh_show_regs = sh3_dsp_show_regs; > + break; > > case bfd_mach_sh4: > - sh_show_regs = sh4_show_regs; > - break; > + sh_show_regs = sh4_show_regs; > + break; > > case bfd_mach_sh5: > sh_show_regs = sh64_show_regs; > - /* SH5 is handled entirely in sh64-tdep.c */ > - return sh64_gdbarch_init (info, arches); > + /* SH5 is handled entirely in sh64-tdep.c */ > + return sh64_gdbarch_init (info, arches); > } > > /* If there is already a candidate, use it. */ > @@ -2108,39 +2038,7 @@ sh_gdbarch_init (struct gdbarch_info inf > > /* None found, create a new architecture from the information > provided. */ > - tdep = XMALLOC (struct gdbarch_tdep); > - gdbarch = gdbarch_alloc (&info, tdep); > - > - /* NOTE: cagney/2002-12-06: This can be deleted when this arch is > - ready to unwind the PC first (see frame.c:get_prev_frame()). */ > - set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default); > - > - /* Initialize the register numbers that are not common to all the > - variants to -1, if necessary thse will be overwritten in the case > - statement below. */ > - tdep->FPUL_REGNUM = -1; > - tdep->FPSCR_REGNUM = -1; > - tdep->DSR_REGNUM = -1; > - tdep->FP_LAST_REGNUM = -1; > - tdep->A0G_REGNUM = -1; > - tdep->A0_REGNUM = -1; > - tdep->A1G_REGNUM = -1; > - tdep->A1_REGNUM = -1; > - tdep->M0_REGNUM = -1; > - tdep->M1_REGNUM = -1; > - tdep->X0_REGNUM = -1; > - tdep->X1_REGNUM = -1; > - tdep->Y0_REGNUM = -1; > - tdep->Y1_REGNUM = -1; > - tdep->MOD_REGNUM = -1; > - tdep->RS_REGNUM = -1; > - tdep->RE_REGNUM = -1; > - tdep->SSR_REGNUM = -1; > - tdep->SPC_REGNUM = -1; > - tdep->DR0_REGNUM = -1; > - tdep->DR_LAST_REGNUM = -1; > - tdep->FV0_REGNUM = -1; > - tdep->FV_LAST_REGNUM = -1; > + gdbarch = gdbarch_alloc (&info, NULL); > > set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); > set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); > @@ -2151,13 +2049,16 @@ sh_gdbarch_init (struct gdbarch_info inf > set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); > set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT); > > - set_gdbarch_num_regs (gdbarch, SH_DEFAULT_NUM_REGS); > + set_gdbarch_num_regs (gdbarch, SH_NUM_REGS); > set_gdbarch_sp_regnum (gdbarch, 15); > - set_gdbarch_deprecated_fp_regnum (gdbarch, 14); > set_gdbarch_pc_regnum (gdbarch, 16); > set_gdbarch_fp0_regnum (gdbarch, -1); > set_gdbarch_num_pseudo_regs (gdbarch, 0); > > + set_gdbarch_register_type (gdbarch, sh_default_register_type); > + > + set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > + > set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc); > set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention); > > @@ -2166,164 +2067,84 @@ sh_gdbarch_init (struct gdbarch_info inf > > set_gdbarch_write_pc (gdbarch, generic_target_write_pc); > > + set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > + set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > + set_gdbarch_extract_struct_value_address (gdbarch, > + sh_extract_struct_value_address); > + > set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue); > set_gdbarch_inner_than (gdbarch, core_addr_lessthan); > set_gdbarch_decr_pc_after_break (gdbarch, 0); > set_gdbarch_function_start_offset (gdbarch, 0); > > + set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > + set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > + > set_gdbarch_frame_args_skip (gdbarch, 0); > - set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue); > + set_gdbarch_frameless_function_invocation (gdbarch, > + frameless_look_for_prologue); > set_gdbarch_believe_pcc_promotion (gdbarch, 1); > > - set_gdbarch_deprecated_frame_chain (gdbarch, sh_frame_chain); > - set_gdbarch_deprecated_get_saved_register (gdbarch, deprecated_generic_get_saved_register); > - set_gdbarch_deprecated_init_extra_frame_info (gdbarch, sh_init_extra_frame_info); > - set_gdbarch_deprecated_pop_frame (gdbarch, sh_pop_frame); > - set_gdbarch_deprecated_frame_saved_pc (gdbarch, sh_frame_saved_pc); > - set_gdbarch_deprecated_saved_pc_after_call (gdbarch, sh_saved_pc_after_call); > set_gdbarch_frame_align (gdbarch, sh_frame_align); > + set_gdbarch_unwind_sp (gdbarch, sh_unwind_sp); > + set_gdbarch_unwind_pc (gdbarch, sh_unwind_pc); > + set_gdbarch_unwind_dummy_id (gdbarch, sh_unwind_dummy_id); > + frame_base_set_default (gdbarch, &sh_frame_base); > + > + set_gdbarch_in_function_epilogue_p (gdbarch, > + sh_in_function_epilogue_p); > > switch (info.bfd_arch_info->mach) > { > case bfd_mach_sh: > set_gdbarch_register_name (gdbarch, sh_sh_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > - set_gdbarch_register_type (gdbarch, sh_default_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > - set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > - set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > - set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > + > case bfd_mach_sh2: > set_gdbarch_register_name (gdbarch, sh_sh_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > - set_gdbarch_register_type (gdbarch, sh_default_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > - set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > - set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > - set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > + > case bfd_mach_sh2e: > /* doubles on sh2e and sh3e are actually 4 byte. */ > set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT); > > set_gdbarch_register_name (gdbarch, sh_sh2e_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > set_gdbarch_register_type (gdbarch, sh_sh3e_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > set_gdbarch_fp0_regnum (gdbarch, 25); > set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); > set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - tdep->FPUL_REGNUM = 23; > - tdep->FPSCR_REGNUM = 24; > - tdep->FP_LAST_REGNUM = 40; > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > + > case bfd_mach_sh_dsp: > set_gdbarch_register_name (gdbarch, sh_sh_dsp_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > - set_gdbarch_register_type (gdbarch, sh_default_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno); > - set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > - set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > - set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - tdep->DSR_REGNUM = 24; > - tdep->A0G_REGNUM = 25; > - tdep->A0_REGNUM = 26; > - tdep->A1G_REGNUM = 27; > - tdep->A1_REGNUM = 28; > - tdep->M0_REGNUM = 29; > - tdep->M1_REGNUM = 30; > - tdep->X0_REGNUM = 31; > - tdep->X1_REGNUM = 32; > - tdep->Y0_REGNUM = 33; > - tdep->Y1_REGNUM = 34; > - tdep->MOD_REGNUM = 40; > - tdep->RS_REGNUM = 43; > - tdep->RE_REGNUM = 44; > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > + > case bfd_mach_sh3: > set_gdbarch_register_name (gdbarch, sh_sh3_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > - set_gdbarch_register_type (gdbarch, sh_default_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > - set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > - set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > - set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - tdep->SSR_REGNUM = 41; > - tdep->SPC_REGNUM = 42; > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > + > case bfd_mach_sh3e: > /* doubles on sh2e and sh3e are actually 4 byte. */ > set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT); > > set_gdbarch_register_name (gdbarch, sh_sh3e_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > set_gdbarch_register_type (gdbarch, sh_sh3e_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > set_gdbarch_fp0_regnum (gdbarch, 25); > set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); > set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - tdep->FPUL_REGNUM = 23; > - tdep->FPSCR_REGNUM = 24; > - tdep->FP_LAST_REGNUM = 40; > - tdep->SSR_REGNUM = 41; > - tdep->SPC_REGNUM = 42; > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs); > break; > + > case bfd_mach_sh3_dsp: > set_gdbarch_register_name (gdbarch, sh_sh3_dsp_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > - set_gdbarch_register_type (gdbarch, sh_default_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno); > - set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > - set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > - set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - tdep->DSR_REGNUM = 24; > - tdep->A0G_REGNUM = 25; > - tdep->A0_REGNUM = 26; > - tdep->A1G_REGNUM = 27; > - tdep->A1_REGNUM = 28; > - tdep->M0_REGNUM = 29; > - tdep->M1_REGNUM = 30; > - tdep->X0_REGNUM = 31; > - tdep->X1_REGNUM = 32; > - tdep->Y0_REGNUM = 33; > - tdep->Y1_REGNUM = 34; > - tdep->MOD_REGNUM = 40; > - tdep->RS_REGNUM = 43; > - tdep->RE_REGNUM = 44; > - tdep->SSR_REGNUM = 41; > - tdep->SPC_REGNUM = 42; > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > + > case bfd_mach_sh4: > set_gdbarch_register_name (gdbarch, sh_sh4_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > set_gdbarch_register_type (gdbarch, sh_sh4_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > set_gdbarch_fp0_regnum (gdbarch, 25); > set_gdbarch_num_pseudo_regs (gdbarch, 12); > set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); > @@ -2331,46 +2152,20 @@ sh_gdbarch_init (struct gdbarch_info inf > set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); > set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value); > set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); > - set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); > - tdep->FPUL_REGNUM = 23; > - tdep->FPSCR_REGNUM = 24; > - tdep->FP_LAST_REGNUM = 40; > - tdep->SSR_REGNUM = 41; > - tdep->SPC_REGNUM = 42; > - tdep->DR0_REGNUM = 59; > - tdep->DR_LAST_REGNUM = 66; > - tdep->FV0_REGNUM = 67; > - tdep->FV_LAST_REGNUM = 70; > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs); > break; > + > default: > set_gdbarch_register_name (gdbarch, sh_generic_register_name); > - set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info); > - set_gdbarch_register_type (gdbarch, sh_default_register_type); > - set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code); > - set_gdbarch_store_return_value (gdbarch, sh_default_store_return_value); > - set_gdbarch_extract_return_value (gdbarch, sh_default_extract_return_value); > - > - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs); > break; > } > > /* Hook in ABI-specific overrides, if they have been registered. */ > gdbarch_init_osabi (info, gdbarch); > > - return gdbarch; > -} > - > -static void > -sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) > -{ > - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); > - > - if (tdep == NULL) > - return; > + frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); > + frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer); > > - /* FIXME: dump the rest of gdbarch_tdep. */ > + return gdbarch; > } > > extern initialize_file_ftype _initialize_sh_tdep; /* -Wmissing-prototypes */ > @@ -2380,7 +2175,7 @@ _initialize_sh_tdep (void) > { > struct cmd_list_element *c; > > - gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep); > + gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL); > > add_com ("regs", class_vars, sh_show_regs_command, "Print all registers"); > } > Index: sh-tdep.h > =================================================================== > RCS file: /cvs/src/src/gdb/sh-tdep.h,v > retrieving revision 1.5 > diff -u -p -r1.5 sh-tdep.h > --- sh-tdep.h 8 Sep 2003 11:26:20 -0000 1.5 > +++ sh-tdep.h 8 Sep 2003 16:26:46 -0000 > @@ -24,52 +24,51 @@ > > /* Contributed by Steve Chamberlain sac@cygnus.com */ > > -struct gdbarch_tdep > - { > - int FPUL_REGNUM; /* sh3e, sh4 */ > - int FPSCR_REGNUM; /* sh3e, sh4 */ > - int DSR_REGNUM; /* sh-dsp, sh3-dsp */ > - int FP_LAST_REGNUM; /* sh3e, sh4 */ > - int A0G_REGNUM; /* sh-dsp, sh3-dsp */ > - int A0_REGNUM; /* sh-dsp, sh3-dsp */ > - int A1G_REGNUM; /* sh-dsp, sh3-dsp */ > - int A1_REGNUM; /* sh-dsp, sh3-dsp */ > - int M0_REGNUM; /* sh-dsp, sh3-dsp */ > - int M1_REGNUM; /* sh-dsp, sh3-dsp */ > - int X0_REGNUM; /* sh-dsp, sh3-dsp */ > - int X1_REGNUM; /* sh-dsp, sh3-dsp */ > - int Y0_REGNUM; /* sh-dsp, sh3-dsp */ > - int Y1_REGNUM; /* sh-dsp, sh3-dsp */ > - int MOD_REGNUM; /* sh-dsp, sh3-dsp */ > - int SSR_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */ > - int SPC_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */ > - int RS_REGNUM; /* sh-dsp, sh3-dsp */ > - int RE_REGNUM; /* sh-dsp, sh3-dsp */ > - int DR0_REGNUM; /* sh4 */ > - int DR_LAST_REGNUM; /* sh4 */ > - int FV0_REGNUM; /* sh4 */ > - int FV_LAST_REGNUM; /* sh4 */ > - /* FPP stands for Floating Point Pair, to avoid confusion with > - GDB's FP0_REGNUM, which is the number of the first Floating > - point register. Unfortunately on the sh5, the floating point > - registers are called FR, and the floating point pairs are called FP. */ > - }; > - > -/* Registers common to all the SH variants. */ > +/* Registers for all SH variants. Used also by sh3-rom.c. */ > enum > { > R0_REGNUM = 0, > STRUCT_RETURN_REGNUM = 2, > ARG0_REGNUM = 4, > ARGLAST_REGNUM = 7, > + FP_REGNUM = 14, > PR_REGNUM = 17, > GBR_REGNUM = 18, > VBR_REGNUM = 19, > MACH_REGNUM = 20, > MACL_REGNUM = 21, > SR_REGNUM = 22, > + FPUL_REGNUM = 23, > + /* Floating point registers */ > + FPSCR_REGNUM = 24, > FLOAT_ARG0_REGNUM = 29, > - FLOAT_ARGLAST_REGNUM = 36 > + FLOAT_ARGLAST_REGNUM = 36, > + FP_LAST_REGNUM = 40, > + /* sh3,sh4 registers */ > + SSR_REGNUM = 41, > + SPC_REGNUM = 42, > + /* DSP registers */ > + DSR_REGNUM = 24, > + A0G_REGNUM = 25, > + A0_REGNUM = 26, > + A1G_REGNUM = 27, > + A1_REGNUM = 28, > + M0_REGNUM = 29, > + M1_REGNUM = 30, > + X0_REGNUM = 31, > + X1_REGNUM = 32, > + Y0_REGNUM = 33, > + Y1_REGNUM = 34, > + MOD_REGNUM = 40, > + RS_REGNUM = 43, > + RE_REGNUM = 44, > + R0_BANK_REGNUM = 51, > + R7_BANK_REGNUM = 58, > + /* Floating point pseudo registers */ > + DR0_REGNUM = 59, > + DR_LAST_REGNUM = 66, > + FV0_REGNUM = 67, > + FV_LAST_REGNUM = 70 > }; > > extern gdbarch_init_ftype sh64_gdbarch_init; > Index: sh3-rom.c > =================================================================== > RCS file: /cvs/src/src/gdb/sh3-rom.c,v > retrieving revision 1.15 > diff -u -p -r1.15 sh3-rom.c > --- sh3-rom.c 21 Aug 2003 20:43:10 -0000 1.15 > +++ sh3-rom.c 8 Sep 2003 16:26:46 -0000 > @@ -77,9 +77,9 @@ sh3_supply_register (char *regname, int > break; > case 'S': > if (regname[1] == 'S' && regname[2] == 'R') > - regno = gdbarch_tdep (current_gdbarch)->SSR_REGNUM; > + regno = SSR_REGNUM; > else if (regname[1] == 'P' && regname[2] == 'C') > - regno = gdbarch_tdep (current_gdbarch)->SPC_REGNUM; > + regno = SPC_REGNUM; > break; > } > } > > -- > Corinna Vinschen > Cygwin Developer > Red Hat, Inc.