X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsh-tdep.c;h=e3fa62f32f9b908c05a0c41bbd05e753fb8faeb9;hb=d9b76ff95d9cc3471b46fdae062c5a1d302f5ee7;hp=827876ee4ebfd6b2dc1dca3eba654d26035e4fcd;hpb=9ab9195f183692346cff01bbe15e77774ef1d608;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 827876ee4e..e3fa62f32f 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -1,12 +1,13 @@ /* Target-dependent code for Renesas Super-H, for GDB. - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004 Free Software Foundation, Inc. + + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,9 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ /* Contributed by Steve Chamberlain @@ -43,6 +42,8 @@ #include "regcache.h" #include "doublest.h" #include "osabi.h" +#include "reggroups.h" +#include "regset.h" #include "sh-tdep.h" @@ -51,12 +52,27 @@ /* sh flags */ #include "elf/sh.h" +#include "dwarf2.h" /* registers numbers shared with the simulator */ #include "gdb/sim-sh.h" -static void (*sh_show_regs) (void); +/* List of "set sh ..." and "show sh ..." commands. */ +static struct cmd_list_element *setshcmdlist = NULL; +static struct cmd_list_element *showshcmdlist = NULL; + +static const char sh_cc_gcc[] = "gcc"; +static const char sh_cc_renesas[] = "renesas"; +static const char *sh_cc_enum[] = { + sh_cc_gcc, + sh_cc_renesas, + NULL +}; + +static const char *sh_active_calling_convention = sh_cc_gcc; -#define SH_NUM_REGS 59 +static void (*sh_show_regs) (struct frame_info *); + +#define SH_NUM_REGS 67 struct sh_frame_cache { @@ -73,19 +89,28 @@ struct sh_frame_cache CORE_ADDR saved_sp; }; +static int +sh_is_renesas_calling_convention (struct type *func_type) +{ + return ((func_type + && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh) + || sh_active_calling_convention == sh_cc_renesas); +} + static const char * -sh_generic_register_name (int reg_nr) +sh_sh_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "pc", "pr", "gbr", "vbr", "mach", "macl", "sr", - "fpul", "fpscr", - "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", - "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", - "ssr", "spc", - "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0", - "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1", + "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", }; if (reg_nr < 0) return NULL; @@ -95,7 +120,7 @@ sh_generic_register_name (int reg_nr) } static const char * -sh_sh_register_name (int reg_nr) +sh_sh3_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -104,8 +129,9 @@ sh_sh_register_name (int reg_nr) "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", - "", "", "", "", "", "", "", "", + "ssr", "spc", + "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0", + "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1" "", "", "", "", "", "", "", "", }; if (reg_nr < 0) @@ -116,18 +142,19 @@ sh_sh_register_name (int reg_nr) } static const char * -sh_sh3_register_name (int reg_nr) +sh_sh3e_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "pc", "pr", "gbr", "vbr", "mach", "macl", "sr", - "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", + "fpul", "fpscr", + "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", + "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", "ssr", "spc", "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0", - "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1" + "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1", + "", "", "", "", "", "", "", "", }; if (reg_nr < 0) return NULL; @@ -137,7 +164,7 @@ sh_sh3_register_name (int reg_nr) } static const char * -sh_sh3e_register_name (int reg_nr) +sh_sh2e_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -146,9 +173,10 @@ sh_sh3e_register_name (int reg_nr) "fpul", "fpscr", "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", - "ssr", "spc", - "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0", - "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1", + "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", }; if (reg_nr < 0) return NULL; @@ -158,17 +186,76 @@ sh_sh3e_register_name (int reg_nr) } static const char * -sh_sh2e_register_name (int reg_nr) +sh_sh2a_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { + /* general registers 0-15 */ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + /* 16 - 22 */ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr", + /* 23, 24 */ "fpul", "fpscr", + /* floating point registers 25 - 40 */ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", + /* 41, 42 */ "", "", + /* 43 - 62. Banked registers. The bank number used is determined by + the bank register (63). */ + "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b", + "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", + "machb", "ivnb", "prb", "gbrb", "maclb", + /* 63: register bank number, not a real register but used to + communicate the register bank currently get/set. This register + is hidden to the user, who manipulates it using the pseudo + register called "bank" (67). See below. */ + "", + /* 64 - 66 */ + "ibcr", "ibnr", "tbr", + /* 67: register bank number, the user visible pseudo register. */ + "bank", + /* double precision (pseudo) 68 - 75 */ + "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14", + }; + if (reg_nr < 0) + return NULL; + if (reg_nr >= (sizeof (register_names) / sizeof (*register_names))) + return NULL; + return register_names[reg_nr]; +} + +static const char * +sh_sh2a_nofpu_register_name (struct gdbarch *gdbarch, int reg_nr) +{ + static char *register_names[] = { + /* general registers 0-15 */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + /* 16 - 22 */ + "pc", "pr", "gbr", "vbr", "mach", "macl", "sr", + /* 23, 24 */ + "", "", + /* floating point registers 25 - 40 */ + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + /* 41, 42 */ + "", "", + /* 43 - 62. Banked registers. The bank number used is determined by + the bank register (63). */ + "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b", + "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", + "machb", "ivnb", "prb", "gbrb", "maclb", + /* 63: register bank number, not a real register but used to + communicate the register bank currently get/set. This register + is hidden to the user, who manipulates it using the pseudo + register called "bank" (67). See below. */ + "", + /* 64 - 66 */ + "ibcr", "ibnr", "tbr", + /* 67: register bank number, the user visible pseudo register. */ + "bank", + /* double precision (pseudo) 68 - 75 */ "", "", "", "", "", "", "", "", }; if (reg_nr < 0) @@ -179,7 +266,7 @@ sh_sh2e_register_name (int reg_nr) } static const char * -sh_sh_dsp_register_name (int reg_nr) +sh_sh_dsp_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -191,6 +278,7 @@ sh_sh_dsp_register_name (int reg_nr) "", "", "rs", "re", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", }; if (reg_nr < 0) return NULL; @@ -200,7 +288,7 @@ sh_sh_dsp_register_name (int reg_nr) } static const char * -sh_sh3_dsp_register_name (int reg_nr) +sh_sh3_dsp_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -213,6 +301,7 @@ sh_sh3_dsp_register_name (int reg_nr) "rs", "re", "", "", "", "", "", "", "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", }; if (reg_nr < 0) return NULL; @@ -222,7 +311,7 @@ sh_sh3_dsp_register_name (int reg_nr) } static const char * -sh_sh4_register_name (int reg_nr) +sh_sh4_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { /* general registers 0-15 */ @@ -241,6 +330,9 @@ sh_sh4_register_name (int reg_nr) "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0", /* bank 1 51 - 58 */ "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1", + "", "", "", "", "", "", "", "", + /* pseudo bank register. */ + "", /* double precision (pseudo) 59 - 66 */ "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14", /* vectors (pseudo) 67 - 70 */ @@ -256,7 +348,7 @@ sh_sh4_register_name (int reg_nr) } static const char * -sh_sh4_nofpu_register_name (int reg_nr) +sh_sh4_nofpu_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { /* general registers 0-15 */ @@ -275,6 +367,9 @@ sh_sh4_nofpu_register_name (int reg_nr) "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0", /* bank 1 51 - 58 */ "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1", + "", "", "", "", "", "", "", "", + /* pseudo bank register. */ + "", /* double precision (pseudo) 59 - 66 -- not for nofpu target */ "", "", "", "", "", "", "", "", /* vectors (pseudo) 67 - 70 -- not for nofpu target */ @@ -288,7 +383,7 @@ sh_sh4_nofpu_register_name (int reg_nr) } static const char * -sh_sh4al_dsp_register_name (int reg_nr) +sh_sh4al_dsp_register_name (struct gdbarch *gdbarch, int reg_nr) { static char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -301,6 +396,7 @@ sh_sh4al_dsp_register_name (int reg_nr) "rs", "re", "", "", "", "", "", "", "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", }; if (reg_nr < 0) return NULL; @@ -310,11 +406,29 @@ sh_sh4al_dsp_register_name (int reg_nr) } static const unsigned char * -sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) { /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */ static unsigned char breakpoint[] = { 0xc3, 0xc3 }; + /* For remote stub targets, trapa #20 is used. */ + if (strcmp (target_shortname, "remote") == 0) + { + static unsigned char big_remote_breakpoint[] = { 0xc3, 0x20 }; + static unsigned char little_remote_breakpoint[] = { 0x20, 0xc3 }; + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + *lenptr = sizeof (big_remote_breakpoint); + return big_remote_breakpoint; + } + else + { + *lenptr = sizeof (little_remote_breakpoint); + return little_remote_breakpoint; + } + } + *lenptr = sizeof (breakpoint); return breakpoint; } @@ -332,10 +446,17 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) #define GET_SOURCE_REG(x) (((x) >> 4) & 0xf) #define GET_TARGET_REG(x) (((x) >> 8) & 0xf) +/* JSR @Rm 0100mmmm00001011 */ +#define IS_JSR(x) (((x) & 0xf0ff) == 0x400b) + /* STS.L PR,@-r15 0100111100100010 r15-4-->r15, PR-->(r15) */ #define IS_STS(x) ((x) == 0x4f22) +/* STS.L MACL,@-r15 0100111100010010 + r15-4-->r15, MACL-->(r15) */ +#define IS_MACL_STS(x) ((x) == 0x4f12) + /* MOV.L Rm,@-r15 00101111mmmm0110 r15-4-->r15, Rm-->(R15) */ #define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06) @@ -383,6 +504,8 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) #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) +/* MOVI20 #imm20,Rn 0000nnnniiii0000 */ +#define IS_MOVI20(x) (((x) & 0xf00f) == 0x0000) /* SUB Rn,R15 00111111nnnn1000 */ #define IS_SUB_REG_FROM_SP(x) (((x) & 0xff0f) == 0x3f08) @@ -392,22 +515,17 @@ sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) #define IS_RESTORE_FP(x) ((x) == 0x6ef6) #define IS_RTS(x) ((x) == 0x000b) #define IS_LDS(x) ((x) == 0x4f26) +#define IS_MACL_LDS(x) ((x) == 0x4f16) #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 -gdb_print_insn_sh (bfd_vma memaddr, disassemble_info * info) -{ - info->endian = TARGET_BYTE_ORDER; - return print_insn_sh (memaddr, info); -} - static CORE_ADDR -sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, - struct sh_frame_cache *cache) +sh_analyze_prologue (struct gdbarch *gdbarch, + CORE_ADDR pc, CORE_ADDR current_pc, + struct sh_frame_cache *cache, ULONGEST fpscr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST inst; CORE_ADDR opc; int offset; @@ -421,7 +539,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, cache->uses_fp = 0; for (opc = pc + (2 * 28); pc < opc; pc += 2) { - inst = read_memory_unsigned_integer (pc, 2); + inst = read_memory_unsigned_integer (pc, 2, byte_order); /* See where the registers will be saved to */ if (IS_PUSH (inst)) { @@ -433,6 +551,11 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, cache->saved_regs[PR_REGNUM] = cache->sp_offset; cache->sp_offset += 4; } + else if (IS_MACL_STS (inst)) + { + cache->saved_regs[MACL_REGNUM] = cache->sp_offset; + cache->sp_offset += 4; + } else if (IS_MOV_R3 (inst)) { r3_val = ((inst & 0xff) ^ 0x80) - 0x80; @@ -458,9 +581,9 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, if (reg < 14) { sav_reg = reg; - offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1; + offset = (inst & 0xff) << 1; sav_offset = - read_memory_integer (((pc + 4) & ~3) + offset, 2); + read_memory_integer ((pc + 4) + offset, 2, byte_order); } } } @@ -468,13 +591,34 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, { if (sav_reg < 0) { - reg = (inst & 0x0f00) >> 8; + reg = GET_TARGET_REG (inst); if (reg < 14) { sav_reg = reg; - offset = (((inst & 0xff) ^ 0x80) - 0x80) << 1; + offset = (inst & 0xff) << 2; sav_offset = - read_memory_integer (((pc + 4) & ~3) + offset, 4); + read_memory_integer (((pc & 0xfffffffc) + 4) + offset, + 4, byte_order); + } + } + } + else if (IS_MOVI20 (inst)) + { + if (sav_reg < 0) + { + reg = GET_TARGET_REG (inst); + if (reg < 14) + { + sav_reg = reg; + sav_offset = GET_SOURCE_REG (inst) << 16; + /* MOVI20 is a 32 bit instruction! */ + pc += 2; + sav_offset + |= read_memory_unsigned_integer (pc, 2, byte_order); + /* Now sav_offset contains an unsigned 20 bit value. + It must still get sign extended. */ + if (sav_offset & 0x00080000) + sav_offset |= 0xfff00000; } } } @@ -489,7 +633,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, } else if (IS_FPUSH (inst)) { - if (read_register (FPSCR_REGNUM) & FPSCR_SZ) + if (fpscr & FPSCR_SZ) { cache->sp_offset += 8; } @@ -500,8 +644,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, } else if (IS_MOV_SP_FP (inst)) { - if (!cache->uses_fp) - cache->uses_fp = 1; + 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 @@ -510,7 +653,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, pc += 2; for (opc = pc + 12; pc < opc; pc += 2) { - inst = read_memory_integer (pc, 2); + inst = read_memory_integer (pc, 2, byte_order); if (IS_MOV_ARG_TO_IND_R14 (inst)) { reg = GET_SOURCE_REG (inst); @@ -531,6 +674,20 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, } break; } + else if (IS_JSR (inst)) + { + /* We have found a jsr that has been scheduled into the prologue. + If we continue the scan and return a pc someplace after this, + then setting a breakpoint on this function will cause it to + appear to be called after the function it is calling via the + jsr, which will be very confusing. Most likely the next + instruction is going to be IS_MOV_SP_FP in the delay slot. If + so, note that before returning the current pc. */ + inst = read_memory_integer (pc + 2, 2, byte_order); + if (IS_MOV_SP_FP (inst)) + cache->uses_fp = 1; + 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. */ @@ -573,7 +730,7 @@ after_prologue (CORE_ADDR pc) } static CORE_ADDR -sh_skip_prologue (CORE_ADDR start_pc) +sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) { CORE_ADDR pc; struct sh_frame_cache cache; @@ -589,7 +746,7 @@ sh_skip_prologue (CORE_ADDR start_pc) return max (pc, start_pc); cache.sp_offset = -4; - pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache); + pc = sh_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache, 0); if (!cache.uses_fp) return start_pc; @@ -646,11 +803,16 @@ sh_skip_prologue (CORE_ADDR start_pc) */ static int -sh_use_struct_convention (int gcc_p, struct type *type) +sh_use_struct_convention (int renesas_abi, struct type *type) { int len = TYPE_LENGTH (type); int nelem = TYPE_NFIELDS (type); + /* The Renesas ABI returns aggregate types always on stack. */ + if (renesas_abi && (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION)) + return 1; + /* Non-power of 2 length types and types bigger than 8 bytes (which don't fit in two registers anyway) use struct convention. */ if (len != 1 && len != 2 && len != 4 && len != 8) @@ -676,16 +838,13 @@ sh_use_struct_convention (int gcc_p, struct type *type) return 1; } -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ -static CORE_ADDR -sh_extract_struct_value_address (struct regcache *regcache) +static int +sh_use_struct_convention_nofpu (int renesas_abi, struct type *type) { - ULONGEST addr; - - regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr); - return addr; + /* The Renesas ABI returns long longs/doubles etc. always on stack. */ + if (renesas_abi && TYPE_NFIELDS (type) == 0 && TYPE_LENGTH (type) >= 8) + return 1; + return sh_use_struct_convention (renesas_abi, type); } static CORE_ADDR @@ -748,7 +907,7 @@ sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp) /* Helper function to justify value in register according to endianess. */ static char * -sh_justify_value_in_reg (struct value *val, int len) +sh_justify_value_in_reg (struct gdbarch *gdbarch, struct value *val, int len) { static char valbuf[4]; @@ -756,13 +915,13 @@ sh_justify_value_in_reg (struct value *val, int len) if (len < 4) { /* value gets right-justified in the register or stack word */ - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - memcpy (valbuf + (4 - len), (char *) VALUE_CONTENTS (val), len); + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + memcpy (valbuf + (4 - len), (char *) value_contents (val), len); else - memcpy (valbuf, (char *) VALUE_CONTENTS (val), len); + memcpy (valbuf, (char *) value_contents (val), len); return valbuf; } - return (char *) VALUE_CONTENTS (val); + return (char *) value_contents (val); } /* Helper function to eval number of bytes to allocate on stack. */ @@ -771,7 +930,7 @@ sh_stack_allocsize (int nargs, struct value **args) { int stack_alloc = 0; while (nargs-- > 0) - stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[nargs])) + 3) & ~3); + stack_alloc += ((TYPE_LENGTH (value_type (args[nargs])) + 3) & ~3); return stack_alloc; } @@ -799,7 +958,7 @@ sh_init_flt_argreg (void) 29) the parity of the register number is preserved, which is important for the double register passing test (see the "argreg & 1" test below). */ static int -sh_next_flt_argreg (int len) +sh_next_flt_argreg (struct gdbarch *gdbarch, int len, struct type *func_type) { int argreg; @@ -818,7 +977,10 @@ sh_next_flt_argreg (int len) /* Doubles are always starting in a even register number. */ if (argreg & 1) { - flt_argreg_array[argreg] = 1; + /* In gcc ABI, the skipped register is lost for further argument + passing now. Not so in Renesas ABI. */ + if (!sh_is_renesas_calling_convention (func_type)) + flt_argreg_array[argreg] = 1; ++argreg; @@ -829,7 +991,8 @@ sh_next_flt_argreg (int len) /* Also mark the next register as used. */ flt_argreg_array[argreg + 1] = 1; } - else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE + && !sh_is_renesas_calling_convention (func_type)) { /* In little endian, gcc passes floats like this: f5, f4, f7, f6, ... */ if (!flt_argreg_array[argreg + 1]) @@ -890,31 +1053,37 @@ sh_treat_as_flt_p (struct type *type) static CORE_ADDR sh_push_dummy_call_fpu (struct gdbarch *gdbarch, - CORE_ADDR func_addr, + struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int stack_offset = 0; int argreg = ARG0_REGNUM; int flt_argreg = 0; int argnum; + struct type *func_type = value_type (function); struct type *type; CORE_ADDR regval; char *val; int len, reg_size = 0; int pass_on_stack = 0; int treat_as_flt; + int last_reg_arg = INT_MAX; + + /* The Renesas ABI expects all varargs arguments, plus the last + non-vararg argument to be on the stack, no matter how many + registers have been used so far. */ + if (sh_is_renesas_calling_convention (func_type) + && TYPE_VARARGS (func_type)) + last_reg_arg = TYPE_NFIELDS (func_type) - 2; /* first force sp to a 4-byte alignment */ sp = sh_frame_align (gdbarch, sp); - if (struct_return) - regcache_cooked_write_unsigned (regcache, - STRUCT_RETURN_REGNUM, struct_addr); - /* make room on stack for args */ sp -= sh_stack_allocsize (nargs, args); @@ -926,9 +1095,9 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, in four registers available. Loop thru args from first to last. */ for (argnum = 0; argnum < nargs; argnum++) { - type = VALUE_TYPE (args[argnum]); + type = value_type (args[argnum]); len = TYPE_LENGTH (type); - val = sh_justify_value_in_reg (args[argnum], len); + val = sh_justify_value_in_reg (gdbarch, args[argnum], len); /* Some decisions have to be made how various types are handled. This also differs in different ABIs. */ @@ -937,7 +1106,14 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, /* Find out the next register to use for a floating point value. */ treat_as_flt = sh_treat_as_flt_p (type); if (treat_as_flt) - flt_argreg = sh_next_flt_argreg (len); + flt_argreg = sh_next_flt_argreg (gdbarch, len, func_type); + /* In Renesas ABI, long longs and aggregate types are always passed + on stack. */ + else if (sh_is_renesas_calling_convention (func_type) + && ((TYPE_CODE (type) == TYPE_CODE_INT && len == 8) + || TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION)) + pass_on_stack = 1; /* In contrast to non-FPU CPUs, arguments are never split between registers and stack. If an argument doesn't fit in the remaining registers it's always pushed entirely on the stack. */ @@ -948,7 +1124,8 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, { if ((treat_as_flt && flt_argreg > FLOAT_ARGLAST_REGNUM) || (!treat_as_flt && (argreg > ARGLAST_REGNUM - || pass_on_stack))) + || pass_on_stack)) + || argnum > last_reg_arg) { /* The data goes entirely on the stack, 4-byte aligned. */ reg_size = (len + 3) & ~3; @@ -959,7 +1136,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, { /* Argument goes in a float argument register. */ reg_size = register_size (gdbarch, flt_argreg); - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); /* In little endian mode, float types taking two registers (doubles on sh4, long doubles on sh2e, sh3e and sh4) must be stored swapped in the argument registers. The below @@ -967,14 +1144,14 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, register, increments the val and len values accordingly and then proceeds as normal by writing the second 32 bits into the next register. */ - if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE && TYPE_LENGTH (type) == 2 * reg_size) { regcache_cooked_write_unsigned (regcache, flt_argreg + 1, regval); val += reg_size; len -= reg_size; - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); } regcache_cooked_write_unsigned (regcache, flt_argreg++, regval); } @@ -982,7 +1159,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, { /* there's room in a register */ reg_size = register_size (gdbarch, argreg); - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, regval); } /* Store the value one register at a time or in one step on stack. */ @@ -991,39 +1168,60 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, } } + if (struct_return) + { + if (sh_is_renesas_calling_convention (func_type)) + /* If the function uses the Renesas ABI, subtract another 4 bytes from + the stack and store the struct return address there. */ + write_memory_unsigned_integer (sp -= 4, 4, byte_order, struct_addr); + else + /* Using the gcc ABI, the "struct return pointer" pseudo-argument has + its own dedicated register. */ + regcache_cooked_write_unsigned (regcache, + STRUCT_RETURN_REGNUM, struct_addr); + } + /* Store return address. */ regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr); /* Update stack pointer. */ - regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp); + regcache_cooked_write_unsigned (regcache, + gdbarch_sp_regnum (gdbarch), sp); return sp; } static CORE_ADDR sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, - CORE_ADDR func_addr, + struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int stack_offset = 0; int argreg = ARG0_REGNUM; int argnum; + struct type *func_type = value_type (function); struct type *type; CORE_ADDR regval; char *val; - int len, reg_size; + int len, reg_size = 0; + int pass_on_stack = 0; + int last_reg_arg = INT_MAX; + + /* The Renesas ABI expects all varargs arguments, plus the last + non-vararg argument to be on the stack, no matter how many + registers have been used so far. */ + if (sh_is_renesas_calling_convention (func_type) + && TYPE_VARARGS (func_type)) + last_reg_arg = TYPE_NFIELDS (func_type) - 2; /* first force sp to a 4-byte alignment */ sp = sh_frame_align (gdbarch, sp); - if (struct_return) - regcache_cooked_write_unsigned (regcache, - STRUCT_RETURN_REGNUM, struct_addr); - /* make room on stack for args */ sp -= sh_stack_allocsize (nargs, args); @@ -1032,13 +1230,25 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, in four registers available. Loop thru args from first to last. */ for (argnum = 0; argnum < nargs; argnum++) { - type = VALUE_TYPE (args[argnum]); + type = value_type (args[argnum]); len = TYPE_LENGTH (type); - val = sh_justify_value_in_reg (args[argnum], len); + val = sh_justify_value_in_reg (gdbarch, args[argnum], len); + /* Some decisions have to be made how various types are handled. + This also differs in different ABIs. */ + pass_on_stack = 0; + /* Renesas ABI pushes doubles and long longs entirely on stack. + Same goes for aggregate types. */ + if (sh_is_renesas_calling_convention (func_type) + && ((TYPE_CODE (type) == TYPE_CODE_INT && len >= 8) + || (TYPE_CODE (type) == TYPE_CODE_FLT && len >= 8) + || TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION)) + pass_on_stack = 1; while (len > 0) { - if (argreg > ARGLAST_REGNUM) + if (argreg > ARGLAST_REGNUM || pass_on_stack + || argnum > last_reg_arg) { /* The remainder of the data goes entirely on the stack, 4-byte aligned. */ @@ -1050,7 +1260,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, { /* there's room in a register */ reg_size = register_size (gdbarch, argreg); - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, regval); } /* Store the value reg_size bytes at a time. This means that things @@ -1061,11 +1271,25 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, } } + if (struct_return) + { + if (sh_is_renesas_calling_convention (func_type)) + /* If the function uses the Renesas ABI, subtract another 4 bytes from + the stack and store the struct return address there. */ + write_memory_unsigned_integer (sp -= 4, 4, byte_order, struct_addr); + else + /* Using the gcc ABI, the "struct return pointer" pseudo-argument has + its own dedicated register. */ + regcache_cooked_write_unsigned (regcache, + STRUCT_RETURN_REGNUM, struct_addr); + } + /* Store return address. */ regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr); /* Update stack pointer. */ - regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp); + regcache_cooked_write_unsigned (regcache, + gdbarch_sp_regnum (gdbarch), sp); return sp; } @@ -1075,9 +1299,11 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, containing the (raw) register state a function return value of type TYPE, and copy that, in virtual format, into VALBUF. */ static void -sh_default_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) +sh_extract_return_value_nofpu (struct type *type, struct regcache *regcache, + void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int len = TYPE_LENGTH (type); int return_register = R0_REGNUM; int offset; @@ -1087,7 +1313,7 @@ sh_default_extract_return_value (struct type *type, struct regcache *regcache, ULONGEST c; regcache_cooked_read_unsigned (regcache, R0_REGNUM, &c); - store_unsigned_integer (valbuf, len, c); + store_unsigned_integer (valbuf, len, byte_order, c); } else if (len == 8) { @@ -1096,25 +1322,26 @@ sh_default_extract_return_value (struct type *type, struct regcache *regcache, regcache_raw_read (regcache, regnum++, (char *) valbuf + i); } else - error ("bad size for return value"); + error (_("bad size for return value")); } static void -sh3e_sh4_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) +sh_extract_return_value_fpu (struct type *type, struct regcache *regcache, + void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); if (sh_treat_as_flt_p (type)) { int len = TYPE_LENGTH (type); - int i, regnum = FP0_REGNUM; + int i, regnum = gdbarch_fp0_regnum (gdbarch); for (i = 0; i < len; i += 4) - if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) regcache_raw_read (regcache, regnum++, (char *) valbuf + len - 4 - i); else regcache_raw_read (regcache, regnum++, (char *) valbuf + i); } else - sh_default_extract_return_value (type, regcache, valbuf); + sh_extract_return_value_nofpu (type, regcache, valbuf); } /* Write into appropriate registers a function return value @@ -1124,15 +1351,17 @@ sh3e_sh4_extract_return_value (struct type *type, struct regcache *regcache, depending on the type of the return value. In all the other cases the result is stored in r0, left-justified. */ static void -sh_default_store_return_value (struct type *type, struct regcache *regcache, - const void *valbuf) +sh_store_return_value_nofpu (struct type *type, struct regcache *regcache, + const void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST val; int len = TYPE_LENGTH (type); if (len <= 4) { - val = extract_unsigned_integer (valbuf, len); + val = extract_unsigned_integer (valbuf, len, byte_order); regcache_cooked_write_unsigned (regcache, R0_REGNUM, val); } else @@ -1144,332 +1373,773 @@ sh_default_store_return_value (struct type *type, struct regcache *regcache, } static void -sh3e_sh4_store_return_value (struct type *type, struct regcache *regcache, - const void *valbuf) +sh_store_return_value_fpu (struct type *type, struct regcache *regcache, + const void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); if (sh_treat_as_flt_p (type)) { int len = TYPE_LENGTH (type); - int i, regnum = FP0_REGNUM; + int i, regnum = gdbarch_fp0_regnum (gdbarch); for (i = 0; i < len; i += 4) - regcache_raw_write (regcache, regnum++, (char *) valbuf + i); + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) + regcache_raw_write (regcache, regnum++, + (char *) valbuf + len - 4 - i); + else + regcache_raw_write (regcache, regnum++, (char *) valbuf + i); } else - sh_default_store_return_value (type, regcache, valbuf); + sh_store_return_value_nofpu (type, regcache, valbuf); +} + +static enum return_value_convention +sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *func_type, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) +{ + if (sh_use_struct_convention_nofpu ( + sh_is_renesas_calling_convention (func_type), type)) + return RETURN_VALUE_STRUCT_CONVENTION; + if (writebuf) + sh_store_return_value_nofpu (type, regcache, writebuf); + else if (readbuf) + sh_extract_return_value_nofpu (type, regcache, readbuf); + return RETURN_VALUE_REGISTER_CONVENTION; +} + +static enum return_value_convention +sh_return_value_fpu (struct gdbarch *gdbarch, struct type *func_type, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) +{ + if (sh_use_struct_convention ( + sh_is_renesas_calling_convention (func_type), type)) + return RETURN_VALUE_STRUCT_CONVENTION; + if (writebuf) + sh_store_return_value_fpu (type, regcache, writebuf); + else if (readbuf) + sh_extract_return_value_fpu (type, regcache, readbuf); + return RETURN_VALUE_REGISTER_CONVENTION; } /* Print the registers in a form similar to the E7000 */ static void -sh_generic_show_regs (void) +sh_generic_show_regs (struct frame_info *frame) { - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); printf_filtered - ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (0), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); } static void -sh3_show_regs (void) +sh3_show_regs (struct frame_info *frame) { - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); - printf_filtered (" SSR=%08lx SPC=%08lx", - (long) read_register (SSR_REGNUM), - (long) read_register (SPC_REGNUM)); + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM)); printf_filtered - ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (0), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); } +static void +sh2e_show_regs (struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); + + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx FPUL %08lx FPSCR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, FPUL_REGNUM), + (long) get_frame_register_unsigned (frame, FPSCR_REGNUM)); + + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); + + printf_filtered + ("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 0), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 1), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 2), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 3), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 4), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 5), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 6), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 7)); + printf_filtered + ("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 8), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 9), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 10), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 11), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 12), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 13), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 14), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 15)); +} static void -sh2e_show_regs (void) -{ - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); - - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); - printf_filtered (" FPUL=%08lx FPSCR=%08lx", - (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), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); - - printf_filtered (("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7)); - printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15)); +sh2a_show_regs (struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int pr = get_frame_register_unsigned (frame, FPSCR_REGNUM) & 0x80000; + + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); + + printf_filtered + (" GBR %08lx VBR %08lx TBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, TBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx FPUL %08lx FPSCR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, FPUL_REGNUM), + (long) get_frame_register_unsigned (frame, FPSCR_REGNUM)); + + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); + + printf_filtered + (pr ? "DR0-DR6 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" + : "FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 0), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 1), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 2), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 3), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 4), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 5), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 6), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 7)); + printf_filtered + (pr ? "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" + : "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 8), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 9), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 10), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 11), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 12), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 13), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 14), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 15)); + printf_filtered + ("BANK=%-3d\n", (int) get_frame_register_unsigned (frame, BANK_REGNUM)); + printf_filtered + ("R0b-R7b %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 0), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 1), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 2), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 3), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 4), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 5), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 6), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 7)); + printf_filtered + ("R8b-R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 8), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 9), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 10), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 11), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 12), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 13), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 14)); + printf_filtered + ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n", + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 15), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 16), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 17), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 18), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 19)); } static void -sh3e_show_regs (void) -{ - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); - - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); - printf_filtered (" SSR=%08lx SPC=%08lx", - (long) read_register (SSR_REGNUM), - (long) read_register (SPC_REGNUM)); - printf_filtered (" FPUL=%08lx FPSCR=%08lx", - (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), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); - - printf_filtered (("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7)); - printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15)); +sh2a_nofpu_show_regs (struct frame_info *frame) +{ + int pr = get_frame_register_unsigned (frame, FPSCR_REGNUM) & 0x80000; + + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); + + printf_filtered + (" GBR %08lx VBR %08lx TBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, TBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx FPUL %08lx FPSCR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, FPUL_REGNUM), + (long) get_frame_register_unsigned (frame, FPSCR_REGNUM)); + + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); + + printf_filtered + ("BANK=%-3d\n", (int) get_frame_register_unsigned (frame, BANK_REGNUM)); + printf_filtered + ("R0b-R7b %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 0), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 1), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 2), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 3), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 4), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 5), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 6), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 7)); + printf_filtered + ("R8b-R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 8), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 9), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 10), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 11), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 12), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 13), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 14)); + printf_filtered + ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n", + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 15), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 16), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 17), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 18), + (long) get_frame_register_unsigned (frame, R0_BANK0_REGNUM + 19)); } static void -sh3_dsp_show_regs (void) +sh3e_show_regs (struct frame_info *frame) { - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); + struct gdbarch *gdbarch = get_frame_arch (frame); + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx FPUL %08lx FPSCR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, FPUL_REGNUM), + (long) get_frame_register_unsigned (frame, FPSCR_REGNUM)); - printf_filtered (" SSR=%08lx SPC=%08lx", - (long) read_register (SSR_REGNUM), - (long) read_register (SPC_REGNUM)); + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); - printf_filtered (" DSR=%08lx", (long) read_register (DSR_REGNUM)); + printf_filtered + ("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 0), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 1), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 2), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 3), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 4), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 5), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 6), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 7)); + printf_filtered + ("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 8), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 9), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 10), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 11), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 12), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 13), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 14), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 15)); +} + +static void +sh3_dsp_show_regs (struct frame_info *frame) +{ + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); + + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); printf_filtered - ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (0), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); + (" SSR %08lx SPC %08lx DSR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, DSR_REGNUM)); + + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n", - (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 (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)); + (long) get_frame_register_unsigned (frame, A0G_REGNUM) & 0xff, + (long) get_frame_register_unsigned (frame, A0_REGNUM), + (long) get_frame_register_unsigned (frame, M0_REGNUM), + (long) get_frame_register_unsigned (frame, X0_REGNUM), + (long) get_frame_register_unsigned (frame, Y0_REGNUM), + (long) get_frame_register_unsigned (frame, RS_REGNUM), + (long) get_frame_register_unsigned (frame, MOD_REGNUM)); + printf_filtered + ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n", + (long) get_frame_register_unsigned (frame, A1G_REGNUM) & 0xff, + (long) get_frame_register_unsigned (frame, A1_REGNUM), + (long) get_frame_register_unsigned (frame, M1_REGNUM), + (long) get_frame_register_unsigned (frame, X1_REGNUM), + (long) get_frame_register_unsigned (frame, Y1_REGNUM), + (long) get_frame_register_unsigned (frame, RE_REGNUM)); } static void -sh4_show_regs (void) -{ - 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), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); - - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); - printf_filtered (" SSR=%08lx SPC=%08lx", - (long) read_register (SSR_REGNUM), - (long) read_register (SPC_REGNUM)); - printf_filtered (" FPUL=%08lx FPSCR=%08lx", - (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), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); - - printf_filtered ((pr - ? "DR0-DR6 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" - : - "FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), - (long) read_register (FP0_REGNUM + 0), - (long) read_register (FP0_REGNUM + 1), - (long) read_register (FP0_REGNUM + 2), - (long) read_register (FP0_REGNUM + 3), - (long) read_register (FP0_REGNUM + 4), - (long) read_register (FP0_REGNUM + 5), - (long) read_register (FP0_REGNUM + 6), - (long) read_register (FP0_REGNUM + 7)); - printf_filtered ((pr ? - "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" : - "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), - (long) read_register (FP0_REGNUM + 8), - (long) read_register (FP0_REGNUM + 9), - (long) read_register (FP0_REGNUM + 10), - (long) read_register (FP0_REGNUM + 11), - (long) read_register (FP0_REGNUM + 12), - (long) read_register (FP0_REGNUM + 13), - (long) read_register (FP0_REGNUM + 14), - (long) read_register (FP0_REGNUM + 15)); +sh4_show_regs (struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int pr = get_frame_register_unsigned (frame, FPSCR_REGNUM) & 0x80000; + + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); + + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx FPUL %08lx FPSCR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, FPUL_REGNUM), + (long) get_frame_register_unsigned (frame, FPSCR_REGNUM)); + + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); + + printf_filtered + (pr ? "DR0-DR6 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" + : "FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 0), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 1), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 2), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 3), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 4), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 5), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 6), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 7)); + printf_filtered + (pr ? "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" + : "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 8), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 9), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 10), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 11), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 12), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 13), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 14), + (long) get_frame_register_unsigned + (frame, gdbarch_fp0_regnum (gdbarch) + 15)); } static void -sh4_nofpu_show_regs (void) -{ - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); - - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); - printf_filtered (" SSR=%08lx SPC=%08lx", - (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), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); +sh4_nofpu_show_regs (struct frame_info *frame) +{ + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); + + printf_filtered + (" GBR %08lx VBR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); + printf_filtered + (" SSR %08lx SPC %08lx FPUL %08lx FPSCR %08lx\n", + (long) get_frame_register_unsigned (frame, SSR_REGNUM), + (long) get_frame_register_unsigned (frame, SPC_REGNUM), + (long) get_frame_register_unsigned (frame, FPUL_REGNUM), + (long) get_frame_register_unsigned (frame, FPSCR_REGNUM)); + + printf_filtered + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); } static void -sh_dsp_show_regs (void) +sh_dsp_show_regs (struct frame_info *frame) { - printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n", - paddr (read_register (PC_REGNUM)), - (long) read_register (SR_REGNUM), - (long) read_register (PR_REGNUM), - (long) read_register (MACH_REGNUM), - (long) read_register (MACL_REGNUM)); - - printf_filtered ("GBR=%08lx VBR=%08lx", - (long) read_register (GBR_REGNUM), - (long) read_register (VBR_REGNUM)); + printf_filtered + (" PC %s SR %08lx PR %08lx MACH %08lx\n", + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), + (long) get_frame_register_unsigned (frame, SR_REGNUM), + (long) get_frame_register_unsigned (frame, PR_REGNUM), + (long) get_frame_register_unsigned (frame, MACH_REGNUM)); - printf_filtered (" DSR=%08lx", (long) read_register (DSR_REGNUM)); + printf_filtered + (" GBR %08lx VBR %08lx DSR %08lx MACL %08lx\n", + (long) get_frame_register_unsigned (frame, GBR_REGNUM), + (long) get_frame_register_unsigned (frame, VBR_REGNUM), + (long) get_frame_register_unsigned (frame, DSR_REGNUM), + (long) get_frame_register_unsigned (frame, MACL_REGNUM)); printf_filtered - ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (0), (long) read_register (1), - (long) read_register (2), (long) read_register (3), - (long) read_register (4), (long) read_register (5), - (long) read_register (6), (long) read_register (7)); - printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (long) read_register (8), (long) read_register (9), - (long) read_register (10), (long) read_register (11), - (long) read_register (12), (long) read_register (13), - (long) read_register (14), (long) read_register (15)); + ("R0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 0), + (long) get_frame_register_unsigned (frame, 1), + (long) get_frame_register_unsigned (frame, 2), + (long) get_frame_register_unsigned (frame, 3), + (long) get_frame_register_unsigned (frame, 4), + (long) get_frame_register_unsigned (frame, 5), + (long) get_frame_register_unsigned (frame, 6), + (long) get_frame_register_unsigned (frame, 7)); + printf_filtered + ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + (long) get_frame_register_unsigned (frame, 8), + (long) get_frame_register_unsigned (frame, 9), + (long) get_frame_register_unsigned (frame, 10), + (long) get_frame_register_unsigned (frame, 11), + (long) get_frame_register_unsigned (frame, 12), + (long) get_frame_register_unsigned (frame, 13), + (long) get_frame_register_unsigned (frame, 14), + (long) get_frame_register_unsigned (frame, 15)); printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n", - (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)); + (long) get_frame_register_unsigned (frame, A0G_REGNUM) & 0xff, + (long) get_frame_register_unsigned (frame, A0_REGNUM), + (long) get_frame_register_unsigned (frame, M0_REGNUM), + (long) get_frame_register_unsigned (frame, X0_REGNUM), + (long) get_frame_register_unsigned (frame, Y0_REGNUM), + (long) get_frame_register_unsigned (frame, RS_REGNUM), + (long) get_frame_register_unsigned (frame, MOD_REGNUM)); printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n", - (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)); + (long) get_frame_register_unsigned (frame, A1G_REGNUM) & 0xff, + (long) get_frame_register_unsigned (frame, A1_REGNUM), + (long) get_frame_register_unsigned (frame, M1_REGNUM), + (long) get_frame_register_unsigned (frame, X1_REGNUM), + (long) get_frame_register_unsigned (frame, Y1_REGNUM), + (long) get_frame_register_unsigned (frame, RE_REGNUM)); } static void sh_show_regs_command (char *args, int from_tty) { if (sh_show_regs) - (*sh_show_regs) (); + (*sh_show_regs) (get_current_frame ()); +} + +static struct type * +sh_sh2a_register_type (struct gdbarch *gdbarch, int reg_nr) +{ + if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) + && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) + return builtin_type (gdbarch)->builtin_float; + else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) + return builtin_type (gdbarch)->builtin_double; + else + return builtin_type (gdbarch)->builtin_int; } /* Return the GDB type object for the "standard" data type @@ -1477,40 +2147,79 @@ sh_show_regs_command (char *args, int from_tty) static struct type * sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr) { - if ((reg_nr >= FP0_REGNUM + if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) - return builtin_type_float; + return builtin_type (gdbarch)->builtin_float; else - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } static struct type * -sh_sh4_build_float_register_type (int high) +sh_sh4_build_float_register_type (struct gdbarch *gdbarch, int high) { - struct type *temp; - - temp = create_range_type (NULL, builtin_type_int, 0, high); - return create_array_type (NULL, builtin_type_float, temp); + return lookup_array_range_type (builtin_type (gdbarch)->builtin_float, + 0, high); } static struct type * sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr) { - if ((reg_nr >= FP0_REGNUM + if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) - return builtin_type_float; + return builtin_type (gdbarch)->builtin_float; else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) - return builtin_type_double; + return builtin_type (gdbarch)->builtin_double; else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM) - return sh_sh4_build_float_register_type (3); + return sh_sh4_build_float_register_type (gdbarch, 3); else - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } static struct type * sh_default_register_type (struct gdbarch *gdbarch, int reg_nr) { - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; +} + +/* Is a register in a reggroup? + The default code in reggroup.c doesn't identify system registers, some + float registers or any of the vector registers. + TODO: sh2a and dsp registers. */ +static int +sh_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *reggroup) +{ + if (gdbarch_register_name (gdbarch, regnum) == NULL + || *gdbarch_register_name (gdbarch, regnum) == '\0') + return 0; + + if (reggroup == float_reggroup + && (regnum == FPUL_REGNUM + || regnum == FPSCR_REGNUM)) + return 1; + + if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM) + { + if (reggroup == vector_reggroup || reggroup == float_reggroup) + return 1; + if (reggroup == general_reggroup) + return 0; + } + + if (regnum == VBR_REGNUM + || regnum == SR_REGNUM + || regnum == FPSCR_REGNUM + || regnum == SSR_REGNUM + || regnum == SPC_REGNUM) + { + if (reggroup == system_reggroup) + return 1; + if (reggroup == general_reggroup) + return 0; + } + + /* The default code can cope with any other registers. */ + return default_register_reggroup_p (gdbarch, regnum, reggroup); } /* On the sh4, the DRi pseudo registers are problematic if the target @@ -1540,8 +2249,8 @@ sh_default_register_type (struct gdbarch *gdbarch, int reg_nr) because they are stored as 4 individual FP elements. */ static void -sh_sh4_register_convert_to_virtual (int regnum, struct type *type, - char *from, char *to) +sh_register_convert_to_virtual (int regnum, struct type *type, + char *from, char *to) { if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM) { @@ -1556,8 +2265,8 @@ sh_sh4_register_convert_to_virtual (int regnum, struct type *type, } static void -sh_sh4_register_convert_to_raw (struct type *type, int regnum, - const void *from, void *to) +sh_register_convert_to_raw (struct type *type, int regnum, + const void *from, void *to) { if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM) { @@ -1566,39 +2275,44 @@ sh_sh4_register_convert_to_raw (struct type *type, int regnum, &val, to); } else - error ("sh_register_convert_to_raw called with non DR register number"); + 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) +fv_reg_base_num (struct gdbarch *gdbarch, int fv_regnum) { int fp_regnum; - fp_regnum = FP0_REGNUM + (fv_regnum - FV0_REGNUM) * 4; + fp_regnum = gdbarch_fp0_regnum (gdbarch) + + (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) +dr_reg_base_num (struct gdbarch *gdbarch, int dr_regnum) { int fp_regnum; - fp_regnum = FP0_REGNUM + (dr_regnum - DR0_REGNUM) * 2; + fp_regnum = gdbarch_fp0_regnum (gdbarch) + + (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 reg_nr, gdb_byte *buffer) { int base_regnum, portion; char temp_buffer[MAX_REGISTER_SIZE]; + if (reg_nr == PSEUDO_BANK_REGNUM) + regcache_raw_read (regcache, BANK_REGNUM, buffer); + else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) { - base_regnum = dr_reg_base_num (reg_nr); + base_regnum = dr_reg_base_num (gdbarch, reg_nr); /* Build the value in the provided buffer. */ /* Read the real regs for which this one is an alias. */ @@ -1608,14 +2322,13 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + register_size (gdbarch, base_regnum) * portion)); /* We must pay attention to the endiannes. */ - sh_sh4_register_convert_to_virtual (reg_nr, - gdbarch_register_type (gdbarch, - reg_nr), - temp_buffer, buffer); + sh_register_convert_to_virtual (reg_nr, + register_type (gdbarch, reg_nr), + temp_buffer, buffer); } else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM) { - base_regnum = fv_reg_base_num (reg_nr); + base_regnum = fv_reg_base_num (gdbarch, reg_nr); /* Read the real regs for which this one is an alias. */ for (portion = 0; portion < 4; portion++) @@ -1628,18 +2341,30 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, static void sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, - int reg_nr, const void *buffer) + int reg_nr, const gdb_byte *buffer) { int base_regnum, portion; char temp_buffer[MAX_REGISTER_SIZE]; - if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) + if (reg_nr == PSEUDO_BANK_REGNUM) + { + /* When the bank register is written to, the whole register bank + is switched and all values in the bank registers must be read + from the target/sim again. We're just invalidating the regcache + so that a re-read happens next time it's necessary. */ + int bregnum; + + regcache_raw_write (regcache, BANK_REGNUM, buffer); + for (bregnum = R0_BANK0_REGNUM; bregnum < MACLB_REGNUM; ++bregnum) + regcache_invalidate (regcache, bregnum); + } + else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) { - base_regnum = dr_reg_base_num (reg_nr); + base_regnum = dr_reg_base_num (gdbarch, reg_nr); /* We must pay attention to the endiannes. */ - sh_sh4_register_convert_to_raw (gdbarch_register_type (gdbarch, reg_nr), - reg_nr, buffer, temp_buffer); + sh_register_convert_to_raw (register_type (gdbarch, reg_nr), + reg_nr, buffer, temp_buffer); /* Write the real regs for which this one is an alias. */ for (portion = 0; portion < 2; portion++) @@ -1650,7 +2375,7 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, } else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM) { - base_regnum = fv_reg_base_num (reg_nr); + base_regnum = fv_reg_base_num (gdbarch, reg_nr); /* Write the real regs for which this one is an alias. */ for (portion = 0; portion < 4; portion++) @@ -1661,232 +2386,11 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, } } -/* Floating point vector of 4 float registers. */ -static void -do_fv_register_info (struct gdbarch *gdbarch, struct ui_file *file, - int fv_regnum) -{ - 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 - 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), - (int) read_register (first_fp_reg_num + 3)); -} - -/* Double precision registers. */ -static void -do_dr_register_info (struct gdbarch *gdbarch, struct ui_file *file, - int dr_regnum) -{ - int first_fp_reg_num = dr_reg_base_num (dr_regnum); - - fprintf_filtered (file, "dr%d\t0x%08x%08x\n", - dr_regnum - DR0_REGNUM, - (int) read_register (first_fp_reg_num), - (int) read_register (first_fp_reg_num + 1)); -} - -static void -sh_print_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file, - int regnum) -{ - if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS) - internal_error (__FILE__, __LINE__, - "Invalid pseudo register number %d\n", regnum); - else if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM) - do_dr_register_info (gdbarch, file, regnum); - else if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM) - do_fv_register_info (gdbarch, file, regnum); -} - -static void -sh_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum) -{ /* do values for FP (float) regs */ - char *raw_buffer; - double flt; /* double extracted from raw hex data */ - int inv; - int j; - - /* Allocate space for the float. */ - raw_buffer = (char *) alloca (register_size (gdbarch, FP0_REGNUM)); - - /* Get the data in raw format. */ - if (!frame_register_read (get_selected_frame (), regnum, raw_buffer)) - error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum)); - - /* Get the register as a number */ - flt = unpack_double (builtin_type_float, raw_buffer, &inv); - - /* Print the name and some spaces. */ - fputs_filtered (REGISTER_NAME (regnum), file); - print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file); - - /* Print the value. */ - if (inv) - fprintf_filtered (file, ""); - else - fprintf_filtered (file, "%-10.9g", flt); - - /* Print the fp register as hex. */ - fprintf_filtered (file, "\t(raw 0x"); - for (j = 0; j < register_size (gdbarch, regnum); j++) - { - int idx = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - ? j - : register_size (gdbarch, regnum) - 1 - j); - fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]); - } - fprintf_filtered (file, ")"); - fprintf_filtered (file, "\n"); -} - -static void -sh_do_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum) -{ - char raw_buffer[MAX_REGISTER_SIZE]; - - fputs_filtered (REGISTER_NAME (regnum), file); - print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file); - - /* Get the data in raw format. */ - if (!frame_register_read (get_selected_frame (), regnum, raw_buffer)) - fprintf_filtered (file, "*value not available*\n"); - - val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0, - file, 'x', 1, 0, Val_pretty_default); - fprintf_filtered (file, "\t"); - val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0, - file, 0, 1, 0, Val_pretty_default); - fprintf_filtered (file, "\n"); -} - -static void -sh_print_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum) -{ - if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS) - internal_error (__FILE__, __LINE__, - "Invalid register number %d\n", regnum); - - else if (regnum >= 0 && regnum < NUM_REGS) - { - if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == - TYPE_CODE_FLT) - sh_do_fp_register (gdbarch, file, regnum); /* FP regs */ - else - sh_do_register (gdbarch, file, regnum); /* All other regs */ - } - - else if (regnum < NUM_REGS + NUM_PSEUDO_REGS) - { - sh_print_pseudo_register (gdbarch, file, regnum); - } -} - -static void -sh_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, - struct frame_info *frame, int regnum, int fpregs) -{ - if (regnum != -1) /* do one specified register */ - { - if (*(REGISTER_NAME (regnum)) == '\0') - error ("Not a valid register for the current processor type"); - - sh_print_register (gdbarch, file, regnum); - } - else - /* do all (or most) registers */ - { - regnum = 0; - while (regnum < NUM_REGS) - { - /* If the register name is empty, it is undefined for this - processor, so don't display anything. */ - if (REGISTER_NAME (regnum) == NULL - || *(REGISTER_NAME (regnum)) == '\0') - { - regnum++; - continue; - } - - if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == - TYPE_CODE_FLT) - { - if (fpregs) - { - /* true for "INFO ALL-REGISTERS" command */ - sh_do_fp_register (gdbarch, file, regnum); /* FP regs */ - regnum++; - } - else - regnum += (FP_LAST_REGNUM - FP0_REGNUM); /* skip FP regs */ - } - else - { - sh_do_register (gdbarch, file, regnum); /* All other regs */ - regnum++; - } - } - - if (fpregs) - while (regnum < NUM_REGS + NUM_PSEUDO_REGS) - { - sh_print_pseudo_register (gdbarch, file, regnum); - regnum++; - } - } -} - -#ifdef SVR4_SHARED_LIBS - -/* Fetch (and possibly build) an appropriate link_map_offsets structure - for native i386 linux targets using the struct offsets defined in - link.h (but without actual reference to that file). - - This makes it possible to access i386-linux shared libraries from - a gdb that was not built on an i386-linux host (for cross debugging). - */ - -struct link_map_offsets * -sh_linux_svr4_fetch_link_map_offsets (void) -{ - static struct link_map_offsets lmo; - static struct link_map_offsets *lmp = 0; - - if (lmp == 0) - { - lmp = &lmo; - - lmo.r_debug_size = 8; /* 20 not actual size but all we need */ - - lmo.r_map_offset = 4; - lmo.r_map_size = 4; - - lmo.link_map_size = 20; /* 552 not actual size but all we need */ - - lmo.l_addr_offset = 0; - lmo.l_addr_size = 4; - - lmo.l_name_offset = 4; - lmo.l_name_size = 4; - - lmo.l_next_offset = 12; - lmo.l_next_size = 4; - - lmo.l_prev_offset = 16; - lmo.l_prev_size = 4; - } - - return lmp; -} -#endif /* SVR4_SHARED_LIBS */ - static int -sh_dsp_register_sim_regno (int nr) +sh_dsp_register_sim_regno (struct gdbarch *gdbarch, int nr) { - if (legacy_register_sim_regno (nr) < 0) - return legacy_register_sim_regno (nr); + if (legacy_register_sim_regno (gdbarch, nr) < 0) + return legacy_register_sim_regno (gdbarch, nr); if (nr >= DSR_REGNUM && nr <= Y1_REGNUM) return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM; if (nr == MOD_REGNUM) @@ -1895,11 +2399,92 @@ sh_dsp_register_sim_regno (int nr) return SIM_SH_RS_REGNUM; if (nr == RE_REGNUM) return SIM_SH_RE_REGNUM; - if (nr >= R0_BANK_REGNUM && nr <= R7_BANK_REGNUM) - return nr - R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM; + if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM) + return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM; return nr; } +static int +sh_sh2a_register_sim_regno (struct gdbarch *gdbarch, int nr) +{ + switch (nr) + { + case TBR_REGNUM: + return SIM_SH_TBR_REGNUM; + case IBNR_REGNUM: + return SIM_SH_IBNR_REGNUM; + case IBCR_REGNUM: + return SIM_SH_IBCR_REGNUM; + case BANK_REGNUM: + return SIM_SH_BANK_REGNUM; + case MACLB_REGNUM: + return SIM_SH_BANK_MACL_REGNUM; + case GBRB_REGNUM: + return SIM_SH_BANK_GBR_REGNUM; + case PRB_REGNUM: + return SIM_SH_BANK_PR_REGNUM; + case IVNB_REGNUM: + return SIM_SH_BANK_IVN_REGNUM; + case MACHB_REGNUM: + return SIM_SH_BANK_MACH_REGNUM; + default: + break; + } + return legacy_register_sim_regno (gdbarch, nr); +} + +/* Set up the register unwinding such that call-clobbered registers are + not displayed in frames >0 because the true value is not certain. + The 'undefined' registers will show up as 'not available' unless the + CFI says otherwise. + + This function is currently set up for SH4 and compatible only. */ + +static void +sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg, + struct frame_info *this_frame) +{ + /* Mark the PC as the destination for the return address. */ + if (regnum == gdbarch_pc_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_RA; + + /* Mark the stack pointer as the call frame address. */ + else if (regnum == gdbarch_sp_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_CFA; + + /* The above was taken from the default init_reg in dwarf2-frame.c + while the below is SH specific. */ + + /* Caller save registers. */ + else if ((regnum >= R0_REGNUM && regnum <= R0_REGNUM+7) + || (regnum >= FR0_REGNUM && regnum <= FR0_REGNUM+11) + || (regnum >= DR0_REGNUM && regnum <= DR0_REGNUM+5) + || (regnum >= FV0_REGNUM && regnum <= FV0_REGNUM+2) + || (regnum == MACH_REGNUM) + || (regnum == MACL_REGNUM) + || (regnum == FPUL_REGNUM) + || (regnum == SR_REGNUM)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; + + /* Callee save registers. */ + else if ((regnum >= R0_REGNUM+8 && regnum <= R0_REGNUM+15) + || (regnum >= FR0_REGNUM+12 && regnum <= FR0_REGNUM+15) + || (regnum >= DR0_REGNUM+6 && regnum <= DR0_REGNUM+8) + || (regnum == FV0_REGNUM+3)) + reg->how = DWARF2_FRAME_REG_SAME_VALUE; + + /* Other registers. These are not in the ABI and may or may not + mean anything in frames >0 so don't show them. */ + else if ((regnum >= R0_BANK0_REGNUM && regnum <= R0_BANK0_REGNUM+15) + || (regnum == GBR_REGNUM) + || (regnum == VBR_REGNUM) + || (regnum == FPSCR_REGNUM) + || (regnum == SSR_REGNUM) + || (regnum == SPC_REGNUM)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; +} + static struct sh_frame_cache * sh_alloc_frame_cache (void) { @@ -1928,8 +2513,9 @@ sh_alloc_frame_cache (void) } static struct sh_frame_cache * -sh_frame_cache (struct frame_info *next_frame, void **this_cache) +sh_frame_cache (struct frame_info *this_frame, void **this_cache) { + struct gdbarch *gdbarch = get_frame_arch (this_frame); struct sh_frame_cache *cache; CORE_ADDR current_pc; int i; @@ -1945,14 +2531,18 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache) 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); + cache->base = get_frame_register_unsigned (this_frame, FP_REGNUM); if (cache->base == 0) return cache; - cache->pc = frame_func_unwind (next_frame); - current_pc = frame_pc_unwind (next_frame); + cache->pc = get_frame_func (this_frame); + current_pc = get_frame_pc (this_frame); if (cache->pc != 0) - sh_analyze_prologue (cache->pc, current_pc, cache); + { + ULONGEST fpscr; + fpscr = get_frame_register_unsigned (this_frame, FPSCR_REGNUM); + sh_analyze_prologue (gdbarch, cache->pc, current_pc, cache, fpscr); + } if (!cache->uses_fp) { @@ -1963,7 +2553,8 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache) 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); + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); } /* Now that we have the base address for the stack frame we can @@ -1979,60 +2570,36 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache) 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) +static struct value * +sh_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) { - struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); + struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct sh_frame_cache *cache = sh_frame_cache (this_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; - } + if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp) + return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp); /* 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) + if (regnum == gdbarch_pc_regnum (gdbarch)) 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; - } + return frame_unwind_got_memory (this_frame, regnum, + cache->saved_regs[regnum]); - frame_register_unwind (next_frame, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + return frame_unwind_got_register (this_frame, regnum, regnum); } static void -sh_frame_this_id (struct frame_info *next_frame, void **this_cache, +sh_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { - struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); + struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache); /* This marks the outermost frame. */ if (cache->base == 0) @@ -2044,38 +2611,37 @@ sh_frame_this_id (struct frame_info *next_frame, void **this_cache, static const struct frame_unwind sh_frame_unwind = { NORMAL_FRAME, sh_frame_this_id, - sh_frame_prev_register + sh_frame_prev_register, + NULL, + default_frame_sniffer }; -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); + return frame_unwind_register_unsigned (next_frame, + gdbarch_sp_regnum (gdbarch)); } static CORE_ADDR sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return frame_unwind_register_unsigned (next_frame, PC_REGNUM); + return frame_unwind_register_unsigned (next_frame, + gdbarch_pc_regnum (gdbarch)); } static struct frame_id -sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +sh_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) { - return frame_id_build (sh_unwind_sp (gdbarch, next_frame), - frame_pc_unwind (next_frame)); + CORE_ADDR sp = get_frame_register_unsigned (this_frame, + gdbarch_sp_regnum (gdbarch)); + return frame_id_build (sp, get_frame_pc (this_frame)); } static CORE_ADDR -sh_frame_base_address (struct frame_info *next_frame, void **this_cache) +sh_frame_base_address (struct frame_info *this_frame, void **this_cache) { - struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); + struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache); return cache->base; } @@ -2093,6 +2659,7 @@ static const struct frame_base sh_frame_base = { static int sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = 0, func_end = 0; if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) @@ -2110,7 +2677,7 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) /* First search forward until hitting an rts. */ while (addr < func_end - && !IS_RTS (read_memory_unsigned_integer (addr, 2))) + && !IS_RTS (read_memory_unsigned_integer (addr, 2, byte_order))) addr += 2; if (addr >= func_end) return 0; @@ -2118,25 +2685,35 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) /* 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))) + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); + if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2, + byte_order))) addr -= 2; - else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2))) + else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2, + byte_order))) return 0; + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); + + /* Step over possible lds.l @r15+,macl. */ + if (IS_MACL_LDS (inst)) + { + addr -= 2; + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); + } + /* 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); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } /* Step over possible mov r14,r15. */ if (IS_MOV_FP_SP (inst)) { addr -= 2; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } /* Now check for FP adjustments, using add #imm,r14 or add rX, r14 @@ -2145,21 +2722,115 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) && (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst))) { addr -= 2; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } + /* On SH2a check if the previous instruction was perhaps a MOVI20. + That's allowed for the epilogue. */ + if ((gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a + || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a_nofpu) + && addr > func_addr + 6 + && IS_MOVI20 (read_memory_unsigned_integer (addr - 4, 2, + byte_order))) + addr -= 4; + if (pc >= addr) return 1; } return 0; } -static gdbarch_init_ftype sh_gdbarch_init; + +/* Supply register REGNUM from the buffer specified by REGS and LEN + in the register set REGSET to register cache REGCACHE. + REGTABLE specifies where each register can be found in REGS. + If REGNUM is -1, do this for all registers in REGSET. */ + +void +sh_corefile_supply_regset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *regs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset + ? tdep->core_gregmap + : tdep->core_fpregmap); + int i; + + for (i = 0; regmap[i].regnum != -1; i++) + { + if ((regnum == -1 || regnum == regmap[i].regnum) + && regmap[i].offset + 4 <= len) + regcache_raw_supply (regcache, regmap[i].regnum, + (char *)regs + regmap[i].offset); + } +} + +/* Collect register REGNUM in the register set REGSET from register cache + REGCACHE into the buffer specified by REGS and LEN. + REGTABLE specifies where each register can be found in REGS. + If REGNUM is -1, do this for all registers in REGSET. */ + +void +sh_corefile_collect_regset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *regs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset + ? tdep->core_gregmap + : tdep->core_fpregmap); + int i; + + for (i = 0; regmap[i].regnum != -1; i++) + { + if ((regnum == -1 || regnum == regmap[i].regnum) + && regmap[i].offset + 4 <= len) + regcache_raw_collect (regcache, regmap[i].regnum, + (char *)regs + regmap[i].offset); + } +} + +/* The following two regsets have the same contents, so it is tempting to + unify them, but they are distiguished by their address, so don't. */ + +struct regset sh_corefile_gregset = +{ + NULL, + sh_corefile_supply_regset, + sh_corefile_collect_regset +}; + +static struct regset sh_corefile_fpregset = +{ + NULL, + sh_corefile_supply_regset, + sh_corefile_collect_regset +}; + +static const struct regset * +sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, + size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep->core_gregmap && strcmp (sect_name, ".reg") == 0) + return &sh_corefile_gregset; + + if (tdep->core_fpregmap && strcmp (sect_name, ".reg2") == 0) + return &sh_corefile_fpregset; + + return NULL; +} + 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) @@ -2167,15 +2838,24 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case bfd_mach_sh2e: sh_show_regs = sh2e_show_regs; break; + case bfd_mach_sh2a: + sh_show_regs = sh2a_show_regs; + break; + case bfd_mach_sh2a_nofpu: + sh_show_regs = sh2a_nofpu_show_regs; + break; case bfd_mach_sh_dsp: sh_show_regs = sh_dsp_show_regs; break; case bfd_mach_sh3: + case bfd_mach_sh3_nommu: + case bfd_mach_sh2a_nofpu_or_sh3_nommu: sh_show_regs = sh3_show_regs; break; case bfd_mach_sh3e: + case bfd_mach_sh2a_or_sh3e: sh_show_regs = sh3e_show_regs; break; @@ -2186,11 +2866,14 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case bfd_mach_sh4: case bfd_mach_sh4a: + case bfd_mach_sh2a_or_sh4: sh_show_regs = sh4_show_regs; break; case bfd_mach_sh4_nofpu: + case bfd_mach_sh4_nommu_nofpu: case bfd_mach_sh4a_nofpu: + case bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu: sh_show_regs = sh4_nofpu_show_regs; break; @@ -2207,7 +2890,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - gdbarch = gdbarch_alloc (&info, NULL); + tdep = XZALLOC (struct gdbarch_tdep); + gdbarch = gdbarch_alloc (&info, tdep); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); @@ -2225,38 +2909,34 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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_register_reggroup_p (gdbarch, sh_register_reggroup_p); set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc); - set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention); - set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh); + set_gdbarch_print_insn (gdbarch, print_insn_sh); set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno); - 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_deprecated_extract_struct_value_address (gdbarch, sh_extract_struct_value_address); + set_gdbarch_return_value (gdbarch, sh_return_value_nofpu); set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu); - set_gdbarch_frameless_function_invocation (gdbarch, - frameless_look_for_prologue); set_gdbarch_believe_pcc_promotion (gdbarch, 1); 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); + set_gdbarch_dummy_id (gdbarch, sh_dummy_id); frame_base_set_default (gdbarch, &sh_frame_base); set_gdbarch_in_function_epilogue_p (gdbarch, sh_in_function_epilogue_p); + dwarf2_frame_set_init_reg (gdbarch, sh_dwarf2_frame_init_reg); + + set_gdbarch_regset_from_core_section (gdbarch, sh_regset_from_core_section); + switch (info.bfd_arch_info->mach) { case bfd_mach_sh: @@ -2274,31 +2954,52 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, sh_sh2e_register_name); set_gdbarch_register_type (gdbarch, sh_sh3e_register_type); 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_return_value (gdbarch, sh_return_value_fpu); + set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); + break; + + case bfd_mach_sh2a: + set_gdbarch_register_name (gdbarch, sh_sh2a_register_name); + set_gdbarch_register_type (gdbarch, sh_sh2a_register_type); + set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno); + + set_gdbarch_fp0_regnum (gdbarch, 25); + set_gdbarch_num_pseudo_regs (gdbarch, 9); + set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write); + set_gdbarch_return_value (gdbarch, sh_return_value_fpu); set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); break; + case bfd_mach_sh2a_nofpu: + set_gdbarch_register_name (gdbarch, sh_sh2a_nofpu_register_name); + set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno); + + set_gdbarch_num_pseudo_regs (gdbarch, 1); + set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write); + break; + case bfd_mach_sh_dsp: set_gdbarch_register_name (gdbarch, sh_sh_dsp_register_name); set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno); break; case bfd_mach_sh3: + case bfd_mach_sh3_nommu: + case bfd_mach_sh2a_nofpu_or_sh3_nommu: set_gdbarch_register_name (gdbarch, sh_sh3_register_name); break; case bfd_mach_sh3e: + case bfd_mach_sh2a_or_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_register_type (gdbarch, sh_sh3e_register_type); 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_return_value (gdbarch, sh_return_value_fpu); set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); break; @@ -2309,20 +3010,21 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case bfd_mach_sh4: case bfd_mach_sh4a: + case bfd_mach_sh2a_or_sh4: set_gdbarch_register_name (gdbarch, sh_sh4_register_name); set_gdbarch_register_type (gdbarch, sh_sh4_register_type); set_gdbarch_fp0_regnum (gdbarch, 25); - set_gdbarch_num_pseudo_regs (gdbarch, 12); + set_gdbarch_num_pseudo_regs (gdbarch, 13); set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write); - set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value); - set_gdbarch_extract_return_value (gdbarch, - sh3e_sh4_extract_return_value); + set_gdbarch_return_value (gdbarch, sh_return_value_fpu); set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); break; case bfd_mach_sh4_nofpu: case bfd_mach_sh4a_nofpu: + case bfd_mach_sh4_nommu_nofpu: + case bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu: set_gdbarch_register_name (gdbarch, sh_sh4_nofpu_register_name); break; @@ -2332,19 +3034,33 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; default: - set_gdbarch_register_name (gdbarch, sh_generic_register_name); + set_gdbarch_register_name (gdbarch, sh_sh_register_name); break; } /* Hook in ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); - frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); - frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer); + dwarf2_append_unwinders (gdbarch); + frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind); return gdbarch; } +static void +show_sh_command (char *args, int from_tty) +{ + help_list (showshcmdlist, "show sh ", all_commands, gdb_stdout); +} + +static void +set_sh_command (char *args, int from_tty) +{ + printf_unfiltered + ("\"set sh\" must be followed by an appropriate subcommand.\n"); + help_list (setshcmdlist, "set sh ", all_commands, gdb_stdout); +} + extern initialize_file_ftype _initialize_sh_tdep; /* -Wmissing-prototypes */ void @@ -2354,5 +3070,21 @@ _initialize_sh_tdep (void) gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL); - add_com ("regs", class_vars, sh_show_regs_command, "Print all registers"); + add_com ("regs", class_vars, sh_show_regs_command, _("Print all registers")); + + add_prefix_cmd ("sh", no_class, set_sh_command, "SH specific commands.", + &setshcmdlist, "set sh ", 0, &setlist); + add_prefix_cmd ("sh", no_class, show_sh_command, "SH specific commands.", + &showshcmdlist, "show sh ", 0, &showlist); + + add_setshow_enum_cmd ("calling-convention", class_vars, sh_cc_enum, + &sh_active_calling_convention, + _("Set calling convention used when calling target " + "functions from GDB."), + _("Show calling convention used when calling target " + "functions from GDB."), + _("gcc - Use GCC calling convention (default).\n" + "renesas - Enforce Renesas calling convention."), + NULL, NULL, + &setshcmdlist, &showshcmdlist); }