gdb/sh64-tdep.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "frame.h"
- #include "frame-base.h"
- #include "frame-unwind.h"
- #include "dwarf2-frame.h"
- #include "symtab.h"
- #include "gdbtypes.h"
- #include "gdbcmd.h"
- #include "gdbcore.h"
- #include "value.h"
- #include "dis-asm.h"
- #include "inferior.h"
- #include "arch-utils.h"
- #include "regcache.h"
- #include "osabi.h"
- #include "valprint.h"
- #include "elf-bfd.h"
- #include "elf/sh.h"
- #include "gdb/sim-sh.h"
- #include "language.h"
- #include "sh64-tdep.h"
- enum sh_abi
- {
- SH_ABI_UNKNOWN,
- SH_ABI_32,
- SH_ABI_64
- };
- struct gdbarch_tdep
- {
- enum sh_abi sh_abi;
- };
- struct sh64_frame_cache
- {
-
- CORE_ADDR base;
- LONGEST sp_offset;
- CORE_ADDR pc;
-
- int uses_fp;
- int media_mode;
-
- CORE_ADDR saved_regs[SIM_SH64_NR_REGS];
- CORE_ADDR saved_sp;
- };
- enum
- {
- R0_REGNUM = 0,
- DEFAULT_RETURN_REGNUM = 2,
- STRUCT_RETURN_REGNUM = 2,
- ARG0_REGNUM = 2,
- ARGLAST_REGNUM = 9,
- FLOAT_ARGLAST_REGNUM = 11,
- MEDIA_FP_REGNUM = 14,
- PR_REGNUM = 18,
- SR_REGNUM = 65,
- DR0_REGNUM = 141,
- DR_LAST_REGNUM = 172,
-
- FPP0_REGNUM = 173,
- FPP_LAST_REGNUM = 204,
- FV0_REGNUM = 205,
- FV_LAST_REGNUM = 220,
- R0_C_REGNUM = 221,
- R_LAST_C_REGNUM = 236,
- PC_C_REGNUM = 237,
- GBR_C_REGNUM = 238,
- MACH_C_REGNUM = 239,
- MACL_C_REGNUM = 240,
- PR_C_REGNUM = 241,
- T_C_REGNUM = 242,
- FPSCR_C_REGNUM = 243,
- FPUL_C_REGNUM = 244,
- FP0_C_REGNUM = 245,
- FP_LAST_C_REGNUM = 260,
- DR0_C_REGNUM = 261,
- DR_LAST_C_REGNUM = 268,
- FV0_C_REGNUM = 269,
- FV_LAST_C_REGNUM = 272,
- FPSCR_REGNUM = SIM_SH64_FPCSR_REGNUM,
- SSR_REGNUM = SIM_SH64_SSR_REGNUM,
- SPC_REGNUM = SIM_SH64_SPC_REGNUM,
- TR7_REGNUM = SIM_SH64_TR0_REGNUM + 7,
- FP_LAST_REGNUM = SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS - 1
- };
- static const char *
- sh64_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",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
- "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
- "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
- "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
-
- "pc",
-
- "sr", "ssr", "spc",
-
- "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7",
-
- "fpscr",
-
- "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
- "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
- "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
- "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31",
- "fr32", "fr33", "fr34", "fr35", "fr36", "fr37", "fr38", "fr39",
- "fr40", "fr41", "fr42", "fr43", "fr44", "fr45", "fr46", "fr47",
- "fr48", "fr49", "fr50", "fr51", "fr52", "fr53", "fr54", "fr55",
- "fr56", "fr57", "fr58", "fr59", "fr60", "fr61", "fr62", "fr63",
-
- "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
- "dr16", "dr18", "dr20", "dr22", "dr24", "dr26", "dr28", "dr30",
- "dr32", "dr34", "dr36", "dr38", "dr40", "dr42", "dr44", "dr46",
- "dr48", "dr50", "dr52", "dr54", "dr56", "dr58", "dr60", "dr62",
-
- "fp0", "fp2", "fp4", "fp6", "fp8", "fp10", "fp12", "fp14",
- "fp16", "fp18", "fp20", "fp22", "fp24", "fp26", "fp28", "fp30",
- "fp32", "fp34", "fp36", "fp38", "fp40", "fp42", "fp44", "fp46",
- "fp48", "fp50", "fp52", "fp54", "fp56", "fp58", "fp60", "fp62",
-
- "fv0", "fv4", "fv8", "fv12", "fv16", "fv20", "fv24", "fv28",
- "fv32", "fv36", "fv40", "fv44", "fv48", "fv52", "fv56", "fv60",
-
- "r0_c", "r1_c", "r2_c", "r3_c", "r4_c", "r5_c", "r6_c", "r7_c",
- "r8_c", "r9_c", "r10_c", "r11_c", "r12_c", "r13_c", "r14_c", "r15_c",
- "pc_c",
- "gbr_c", "mach_c", "macl_c", "pr_c", "t_c",
- "fpscr_c", "fpul_c",
- "fr0_c", "fr1_c", "fr2_c", "fr3_c",
- "fr4_c", "fr5_c", "fr6_c", "fr7_c",
- "fr8_c", "fr9_c", "fr10_c", "fr11_c",
- "fr12_c", "fr13_c", "fr14_c", "fr15_c",
- "dr0_c", "dr2_c", "dr4_c", "dr6_c",
- "dr8_c", "dr10_c", "dr12_c", "dr14_c",
- "fv0_c", "fv4_c", "fv8_c", "fv12_c",
- FIXME
- };
- if (reg_nr < 0)
- return NULL;
- if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
- return NULL;
- return register_names[reg_nr];
- }
- #define NUM_PSEUDO_REGS_SH_MEDIA 80
- #define NUM_PSEUDO_REGS_SH_COMPACT 51
- #define MSYMBOL_IS_SPECIAL(msym) \
- MSYMBOL_TARGET_FLAG_1 (msym)
- static void
- sh64_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
- {
- if (msym == NULL)
- return;
- if (((elf_symbol_type *)(sym))->internal_elf_sym.st_other == STO_SH5_ISA32)
- {
- MSYMBOL_TARGET_FLAG_1 (msym) = 1;
- SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
- }
- }
- #define IS_ISA32_ADDR(addr) ((addr) & 1)
- #define MAKE_ISA32_ADDR(addr) ((addr) | 1)
- #define UNMAKE_ISA32_ADDR(addr) ((addr) & ~1)
- static int
- pc_is_isa32 (bfd_vma memaddr)
- {
- struct bound_minimal_symbol sym;
-
- if (IS_ISA32_ADDR (memaddr))
- return 1;
-
- sym = lookup_minimal_symbol_by_pc (memaddr);
- if (sym.minsym)
- return MSYMBOL_IS_SPECIAL (sym.minsym);
- else
- return 0;
- }
- static const unsigned char *
- sh64_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
- {
-
-
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- if (pc_is_isa32 (*pcptr))
- {
- static unsigned char big_breakpoint_media[] = {
- 0x6f, 0xf5, 0xff, 0xf0
- };
- *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
- *lenptr = sizeof (big_breakpoint_media);
- return big_breakpoint_media;
- }
- else
- {
- static unsigned char big_breakpoint_compact[] = {0x0, 0x3b};
- *lenptr = sizeof (big_breakpoint_compact);
- return big_breakpoint_compact;
- }
- }
- else
- {
- if (pc_is_isa32 (*pcptr))
- {
- static unsigned char little_breakpoint_media[] = {
- 0xf0, 0xff, 0xf5, 0x6f
- };
- *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
- *lenptr = sizeof (little_breakpoint_media);
- return little_breakpoint_media;
- }
- else
- {
- static unsigned char little_breakpoint_compact[] = {0x3b, 0x0};
- *lenptr = sizeof (little_breakpoint_compact);
- return little_breakpoint_compact;
- }
- }
- }
- #define IS_PTABSL_R18(x) (((x) & 0xffffff8f) == 0x6bf14a00)
- #define IS_STS_R0(x) ((x) == 0x4022)
- #define IS_STS_PR(x) (((x) & 0xf0ff) == 0x2a)
- #define IS_MOV_TO_R15(x) (((x) & 0xff00) == 0x1f00)
- #define IS_MOV_R14(x) (((x) & 0xfff0) == 0x1fe0)
- #define IS_STQ_R18_R14(x) (((x) & 0xfff003ff) == 0xace00120)
- #define IS_STQ_R18_R15(x) (((x) & 0xfff003ff) == 0xacf00120)
- #define IS_STL_R18_R15(x) (((x) & 0xfff003ff) == 0xa8f00120)
- #define IS_STQ_R14_R15(x) (((x) & 0xfff003ff) == 0xacf000e0)
- #define IS_STL_R14_R15(x) (((x) & 0xfff003ff) == 0xa8f000e0)
- #define IS_ADDIL_SP_MEDIA(x) (((x) & 0xfff003ff) == 0xd4f000f0)
- #define IS_ADDI_SP_MEDIA(x) (((x) & 0xfff003ff) == 0xd0f000f0)
- #define IS_ADDL_SP_FP_MEDIA(x) ((x) == 0x00f8fce0)
- #define IS_ADD_SP_FP_MEDIA(x) ((x) == 0x00f9fce0)
- #define IS_MOV_SP_FP_MEDIA(x) \
- (IS_ADDL_SP_FP_MEDIA(x) || IS_ADD_SP_FP_MEDIA(x))
- #define IS_MOV_R0(x) (((x) & 0xff00) == 0xe000)
- #define IS_MOVL_R0(x) (((x) & 0xff00) == 0xd000)
- #define IS_ADD_SP_R0(x) ((x) == 0x30fc)
- #define IS_MOV_R14_R0(x) ((x) == 0x20e6)
- FIXME
- #define IS_MEDIA_IND_ARG_MOV(x) \
- ((((x) & 0xfc0ffc0f) == 0x0009fc00) \
- && (((x) & 0x03f00000) >= 0x00200000 \
- && ((x) & 0x03f00000) <= 0x00900000))
- #define IS_MEDIA_ARG_MOV(x) \
- (((((x) & 0xfc0ffc0f) == 0xac000000) || (((x) & 0xfc0ffc0f) == 0xa8000000)) \
- && (((x) & 0x000003f0) >= 0x00000020 && ((x) & 0x000003f0) <= 0x00000090))
- #define IS_MEDIA_MOV_TO_R14(x) \
- ((((x) & 0xfffffc0f) == 0xa0e00000) \
- || (((x) & 0xfffffc0f) == 0xa4e00000) \
- || (((x) & 0xfffffc0f) == 0xa8e00000) \
- || (((x) & 0xfffffc0f) == 0xb4e00000) \
- || (((x) & 0xfffffc0f) == 0xbce00000))
- #define IS_COMPACT_IND_ARG_MOV(x) \
- ((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0020) \
- && (((x) & 0x00f0) <= 0x0090))
- #define IS_COMPACT_ARG_MOV(x) \
- (((((x) & 0xff0f) == 0x2e02) && (((x) & 0x00f0) >= 0x0020) \
- && ((x) & 0x00f0) <= 0x0090))
- #define IS_COMPACT_MOV_TO_R14(x) \
- ((((x) & 0xff0f) == 0x2e00) || (((x) & 0xff0f) == 0x2e01))
- #define IS_JSR_R0(x) ((x) == 0x400b)
- #define IS_NOP(x) ((x) == 0x0009)
- #define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
- #define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
- static CORE_ADDR
- after_prologue (CORE_ADDR pc)
- {
- struct symtab_and_line sal;
- CORE_ADDR func_addr, func_end;
-
- if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
- return 0;
-
- sal = find_pc_line (func_addr, 0);
-
- if (sal.end < func_end)
- return sal.end;
- else
- return 0;
- }
- static CORE_ADDR
- look_for_args_moves (struct gdbarch *gdbarch,
- CORE_ADDR start_pc, int media_mode)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR here, end;
- int w;
- int insn_size = (media_mode ? 4 : 2);
- for (here = start_pc, end = start_pc + (insn_size * 28); here < end;)
- {
- if (media_mode)
- {
- w = read_memory_integer (UNMAKE_ISA32_ADDR (here),
- insn_size, byte_order);
- here += insn_size;
- if (IS_MEDIA_IND_ARG_MOV (w))
- {
-
- int next_insn = read_memory_integer (UNMAKE_ISA32_ADDR (here),
- insn_size, byte_order);
- here += insn_size;
- if (IS_MEDIA_MOV_TO_R14 (next_insn))
- start_pc = here;
- }
- else if (IS_MEDIA_ARG_MOV (w))
- {
-
- start_pc = here;
- }
- else
- break;
- }
- else
- {
- w = read_memory_integer (here, insn_size, byte_order);
- w = w & 0xffff;
- here += insn_size;
- if (IS_COMPACT_IND_ARG_MOV (w))
- {
-
- int next_insn = 0xffff & read_memory_integer (here, insn_size,
- byte_order);
- here += insn_size;
- if (IS_COMPACT_MOV_TO_R14 (next_insn))
- start_pc = here;
- }
- else if (IS_COMPACT_ARG_MOV (w))
- {
-
- start_pc = here;
- }
- else if (IS_MOVL_R0 (w))
- {
-
-
- int next_insn = 0xffff & read_memory_integer (here, insn_size,
- byte_order);
- here += insn_size;
- if (IS_JSR_R0 (next_insn))
- {
- next_insn = 0xffff & read_memory_integer (here, insn_size,
- byte_order);
- here += insn_size;
- if (IS_NOP (next_insn))
- start_pc = here;
- }
- }
- else
- break;
- }
- }
- return start_pc;
- }
- static CORE_ADDR
- sh64_skip_prologue_hard_way (struct gdbarch *gdbarch, CORE_ADDR start_pc)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR here, end;
- int updated_fp = 0;
- int insn_size = 4;
- int media_mode = 1;
- if (!start_pc)
- return 0;
- if (pc_is_isa32 (start_pc) == 0)
- {
- insn_size = 2;
- media_mode = 0;
- }
- for (here = start_pc, end = start_pc + (insn_size * 28); here < end;)
- {
- if (media_mode)
- {
- int w = read_memory_integer (UNMAKE_ISA32_ADDR (here),
- insn_size, byte_order);
- here += insn_size;
- if (IS_STQ_R18_R14 (w) || IS_STQ_R18_R15 (w) || IS_STQ_R14_R15 (w)
- || IS_STL_R14_R15 (w) || IS_STL_R18_R15 (w)
- || IS_ADDIL_SP_MEDIA (w) || IS_ADDI_SP_MEDIA (w)
- || IS_PTABSL_R18 (w))
- {
- start_pc = here;
- }
- else if (IS_MOV_SP_FP (w) || IS_MOV_SP_FP_MEDIA(w))
- {
- start_pc = here;
- updated_fp = 1;
- }
- else
- if (updated_fp)
- {
-
- start_pc = look_for_args_moves (gdbarch,
- here - insn_size, media_mode);
- break;
- }
- }
- else
- {
- int w = 0xffff & read_memory_integer (here, insn_size, byte_order);
- here += insn_size;
- if (IS_STS_R0 (w) || IS_STS_PR (w)
- || IS_MOV_TO_R15 (w) || IS_MOV_R14 (w)
- || IS_MOV_R0 (w) || IS_ADD_SP_R0 (w) || IS_MOV_R14_R0 (w))
- {
- start_pc = here;
- }
- else if (IS_MOV_SP_FP (w))
- {
- start_pc = here;
- updated_fp = 1;
- }
- else
- if (updated_fp)
- {
-
- start_pc = look_for_args_moves (gdbarch,
- here - insn_size, media_mode);
- break;
- }
- }
- }
- return start_pc;
- }
- static CORE_ADDR
- sh64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
- CORE_ADDR post_prologue_pc;
-
- post_prologue_pc = after_prologue (pc);
-
- if (post_prologue_pc != 0)
- return max (pc, post_prologue_pc);
- else
- return sh64_skip_prologue_hard_way (gdbarch, pc);
- }
- static int
- sh64_use_struct_convention (struct type *type)
- {
- return (TYPE_LENGTH (type) > 8);
- }
- static int
- sh64_fv_reg_base_num (struct gdbarch *gdbarch, int fv_regnum)
- {
- int fp_regnum;
- fp_regnum = gdbarch_fp0_regnum (gdbarch) + (fv_regnum - FV0_REGNUM) * 4;
- return fp_regnum;
- }
- static int
- sh64_dr_reg_base_num (struct gdbarch *gdbarch, int dr_regnum)
- {
- int fp_regnum;
- fp_regnum = gdbarch_fp0_regnum (gdbarch) + (dr_regnum - DR0_REGNUM) * 2;
- return fp_regnum;
- }
- static int
- sh64_fpp_reg_base_num (struct gdbarch *gdbarch, int fpp_regnum)
- {
- int fp_regnum;
- fp_regnum = gdbarch_fp0_regnum (gdbarch) + (fpp_regnum - FPP0_REGNUM) * 2;
- return fp_regnum;
- }
- static int
- sh64_compact_reg_base_num (struct gdbarch *gdbarch, int reg_nr)
- {
- int base_regnum = reg_nr;
-
- if (reg_nr >= R0_C_REGNUM
- && reg_nr <= R_LAST_C_REGNUM)
- base_regnum = reg_nr - R0_C_REGNUM;
-
- else if (reg_nr >= FP0_C_REGNUM
- && reg_nr <= FP_LAST_C_REGNUM)
- base_regnum = reg_nr - FP0_C_REGNUM + gdbarch_fp0_regnum (gdbarch);
-
- else if (reg_nr >= DR0_C_REGNUM
- && reg_nr <= DR_LAST_C_REGNUM)
- base_regnum = sh64_dr_reg_base_num (gdbarch,
- DR0_REGNUM + reg_nr - DR0_C_REGNUM);
-
- else if (reg_nr >= FV0_C_REGNUM
- && reg_nr <= FV_LAST_C_REGNUM)
- base_regnum = sh64_fv_reg_base_num (gdbarch,
- FV0_REGNUM + reg_nr - FV0_C_REGNUM);
- else if (reg_nr == PC_C_REGNUM)
- base_regnum = gdbarch_pc_regnum (gdbarch);
- else if (reg_nr == GBR_C_REGNUM)
- base_regnum = 16;
- else if (reg_nr == MACH_C_REGNUM
- || reg_nr == MACL_C_REGNUM)
- base_regnum = 17;
- else if (reg_nr == PR_C_REGNUM)
- base_regnum = PR_REGNUM;
- else if (reg_nr == T_C_REGNUM)
- base_regnum = 19;
- else if (reg_nr == FPSCR_C_REGNUM)
- base_regnum = FPSCR_REGNUM;
- else if (reg_nr == FPUL_C_REGNUM)
- base_regnum = gdbarch_fp0_regnum (gdbarch) + 32;
- return base_regnum;
- }
- static int
- sign_extend (int value, int bits)
- {
- value = value & ((1 << bits) - 1);
- return (value & (1 << (bits - 1))
- ? value | (~((1 << bits) - 1))
- : value);
- }
- static void
- sh64_analyze_prologue (struct gdbarch *gdbarch,
- struct sh64_frame_cache *cache,
- CORE_ADDR func_pc,
- CORE_ADDR current_pc)
- {
- int pc;
- int opc;
- int insn;
- int r0_val = 0;
- int insn_size;
- int gdb_register_number;
- int register_number;
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- cache->sp_offset = 0;
-
- pc = func_pc;
- if (cache->media_mode)
- insn_size = 4;
- else
- insn_size = 2;
- opc = pc + (insn_size * 28);
- if (opc > current_pc)
- opc = current_pc;
- for ( ; pc <= opc; pc += insn_size)
- {
- insn = read_memory_integer (cache->media_mode ? UNMAKE_ISA32_ADDR (pc)
- : pc,
- insn_size, byte_order);
- if (!cache->media_mode)
- {
- if (IS_STS_PR (insn))
- {
- int next_insn = read_memory_integer (pc + insn_size,
- insn_size, byte_order);
- if (IS_MOV_TO_R15 (next_insn))
- {
- cache->saved_regs[PR_REGNUM]
- = cache->sp_offset - ((((next_insn & 0xf) ^ 0x8)
- - 0x8) << 2);
- pc += insn_size;
- }
- }
- else if (IS_MOV_R14 (insn))
- cache->saved_regs[MEDIA_FP_REGNUM] =
- cache->sp_offset - ((((insn & 0xf) ^ 0x8) - 0x8) << 2);
- else if (IS_MOV_R0 (insn))
- {
-
- r0_val = ((insn & 0xff) ^ 0x80) - 0x80;
- }
- else if (IS_ADD_SP_R0 (insn))
- {
-
- }
- else if (IS_STS_R0 (insn))
- {
-
- cache->saved_regs[PR_REGNUM] = cache->sp_offset - (r0_val - 4);
- r0_val -= 4;
- }
- else if (IS_MOV_R14_R0 (insn))
- {
-
- cache->saved_regs[MEDIA_FP_REGNUM] = cache->sp_offset
- - (r0_val - 4);
- r0_val -= 4;
- }
- else if (IS_ADD_SP (insn))
- cache->sp_offset -= ((insn & 0xff) ^ 0x80) - 0x80;
- else if (IS_MOV_SP_FP (insn))
- break;
- }
- else
- {
- if (IS_ADDIL_SP_MEDIA (insn) || IS_ADDI_SP_MEDIA (insn))
- cache->sp_offset -=
- sign_extend ((((insn & 0xffc00) ^ 0x80000) - 0x80000) >> 10, 9);
- else if (IS_STQ_R18_R15 (insn))
- cache->saved_regs[PR_REGNUM]
- = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
- 9) << 3);
- else if (IS_STL_R18_R15 (insn))
- cache->saved_regs[PR_REGNUM]
- = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
- 9) << 2);
- else if (IS_STQ_R14_R15 (insn))
- cache->saved_regs[MEDIA_FP_REGNUM]
- = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
- 9) << 3);
- else if (IS_STL_R14_R15 (insn))
- cache->saved_regs[MEDIA_FP_REGNUM]
- = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
- 9) << 2);
- else if (IS_MOV_SP_FP_MEDIA (insn))
- break;
- }
- }
- if (cache->saved_regs[MEDIA_FP_REGNUM] >= 0)
- cache->uses_fp = 1;
- }
- static CORE_ADDR
- sh64_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
- {
- return sp & ~7;
- }
- static CORE_ADDR
- sh64_push_dummy_call (struct gdbarch *gdbarch,
- 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, stack_alloc;
- int int_argreg;
- int float_argreg;
- int double_argreg;
- int float_arg_index = 0;
- int double_arg_index = 0;
- int argnum;
- struct type *type;
- CORE_ADDR regval;
- const gdb_byte *val;
- gdb_byte valbuf[8];
- int len;
- int argreg_size;
- int fp_args[12];
- memset (fp_args, 0, sizeof (fp_args));
-
- sp = sh64_frame_align (gdbarch, sp);
-
- if (struct_return)
- regcache_cooked_write_unsigned (regcache,
- STRUCT_RETURN_REGNUM, struct_addr);
-
- for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
- stack_alloc += ((TYPE_LENGTH (value_type (args[argnum])) + 7) & ~7);
- sp -= stack_alloc;
-
- int_argreg = ARG0_REGNUM;
- float_argreg = gdbarch_fp0_regnum (gdbarch);
- double_argreg = DR0_REGNUM;
- for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
- {
- type = value_type (args[argnum]);
- len = TYPE_LENGTH (type);
- memset (valbuf, 0, sizeof (valbuf));
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
- {
- argreg_size = register_size (gdbarch, int_argreg);
- if (len < argreg_size)
- {
-
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- memcpy (valbuf + argreg_size - len,
- value_contents (args[argnum]), len);
- else
- memcpy (valbuf, value_contents (args[argnum]), len);
- val = valbuf;
- }
- else
- val = value_contents (args[argnum]);
- while (len > 0)
- {
- if (int_argreg > ARGLAST_REGNUM)
- {
-
- write_memory (sp + stack_offset, val, argreg_size);
- stack_offset += 8;
- }
-
- if (int_argreg <= ARGLAST_REGNUM)
- {
-
- regval = extract_unsigned_integer (val, argreg_size,
- byte_order);
- regcache_cooked_write_unsigned (regcache,
- int_argreg, regval);
- }
-
- FIXME
- len -= argreg_size;
- val += argreg_size;
- int_argreg++;
- }
- }
- else
- {
- val = value_contents (args[argnum]);
- if (len == 4)
- {
-
- while (fp_args[float_arg_index])
- float_arg_index ++;
-
- if (float_arg_index <= FLOAT_ARGLAST_REGNUM)
- {
-
- regcache_cooked_write (regcache,
- gdbarch_fp0_regnum (gdbarch)
- + float_arg_index,
- val);
- fp_args[float_arg_index] = 1;
-
- int_argreg ++;
- }
- else
- {
-
- }
- }
- else if (len == 8)
- {
-
- while (fp_args[double_arg_index])
- double_arg_index += 2;
-
- if (double_arg_index < FLOAT_ARGLAST_REGNUM)
- {
-
-
- int double_register_offset = double_arg_index / 2;
- int regnum = DR0_REGNUM + double_register_offset;
- regcache_cooked_write (regcache, regnum, val);
- fp_args[double_arg_index] = 1;
- fp_args[double_arg_index + 1] = 1;
-
- int_argreg ++;
- }
- else
- {
-
- }
- }
- }
- }
-
- regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
-
- regcache_cooked_write_unsigned (regcache,
- gdbarch_sp_regnum (gdbarch), sp);
- return sp;
- }
- static void
- sh64_extract_return_value (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);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- {
- if (len == 4)
- {
-
- regcache_raw_read (regcache,
- gdbarch_fp0_regnum (gdbarch), valbuf);
- }
- else if (len == 8)
- {
-
- DOUBLEST val;
- gdb_byte buf[8];
- regcache_cooked_read (regcache, DR0_REGNUM, buf);
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
- floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
- buf, &val);
- else
- floatformat_to_doublest (&floatformat_ieee_double_big,
- buf, &val);
- store_typed_floating (valbuf, type, val);
- }
- }
- else
- {
- if (len <= 8)
- {
- int offset;
- gdb_byte buf[8];
-
- regcache_raw_read (regcache, DEFAULT_RETURN_REGNUM, buf);
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- offset = register_size (gdbarch, DEFAULT_RETURN_REGNUM)
- - len;
- else
- offset = 0;
- memcpy (valbuf, buf + offset, len);
- }
- else
- error (_("bad size for return value"));
- }
- }
- static void
- sh64_store_return_value (struct type *type, struct regcache *regcache,
- const gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- gdb_byte buf[64];
- int len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- {
- int i, regnum = gdbarch_fp0_regnum (gdbarch);
- for (i = 0; i < len; i += 4)
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
- regcache_raw_write (regcache, regnum++,
- valbuf + len - 4 - i);
- else
- regcache_raw_write (regcache, regnum++, valbuf + i);
- }
- else
- {
- int return_register = DEFAULT_RETURN_REGNUM;
- int offset = 0;
- if (len <= register_size (gdbarch, return_register))
- {
-
- memset (buf, 0, register_size (gdbarch, return_register));
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
- offset = 0;
- else
- offset = register_size (gdbarch, return_register) - len;
- memcpy (buf + offset, valbuf, len);
- regcache_raw_write (regcache, return_register, buf);
- }
- else
- regcache_raw_write (regcache, return_register, valbuf);
- }
- }
- static enum return_value_convention
- sh64_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *type, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
- {
- if (sh64_use_struct_convention (type))
- return RETURN_VALUE_STRUCT_CONVENTION;
- if (writebuf)
- sh64_store_return_value (type, regcache, writebuf);
- else if (readbuf)
- sh64_extract_return_value (type, regcache, readbuf);
- return RETURN_VALUE_REGISTER_CONVENTION;
- }
- static struct type *
- sh64_build_float_register_type (struct gdbarch *gdbarch, int high)
- {
- return lookup_array_range_type (builtin_type (gdbarch)->builtin_float,
- 0, high);
- }
- static struct type *
- sh64_register_type (struct gdbarch *gdbarch, int reg_nr)
- {
- if ((reg_nr >= gdbarch_fp0_regnum (gdbarch)
- && reg_nr <= FP_LAST_REGNUM)
- || (reg_nr >= FP0_C_REGNUM
- && reg_nr <= FP_LAST_C_REGNUM))
- return builtin_type (gdbarch)->builtin_float;
- else if ((reg_nr >= DR0_REGNUM
- && reg_nr <= DR_LAST_REGNUM)
- || (reg_nr >= DR0_C_REGNUM
- && reg_nr <= DR_LAST_C_REGNUM))
- return builtin_type (gdbarch)->builtin_double;
- else if (reg_nr >= FPP0_REGNUM
- && reg_nr <= FPP_LAST_REGNUM)
- return sh64_build_float_register_type (gdbarch, 1);
- else if ((reg_nr >= FV0_REGNUM
- && reg_nr <= FV_LAST_REGNUM)
- ||(reg_nr >= FV0_C_REGNUM
- && reg_nr <= FV_LAST_C_REGNUM))
- return sh64_build_float_register_type (gdbarch, 3);
- else if (reg_nr == FPSCR_REGNUM)
- return builtin_type (gdbarch)->builtin_int;
- else if (reg_nr >= R0_C_REGNUM
- && reg_nr < FP0_C_REGNUM)
- return builtin_type (gdbarch)->builtin_int;
- else
- return builtin_type (gdbarch)->builtin_long_long;
- }
- static void
- sh64_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum,
- struct type *type, gdb_byte *from, gdb_byte *to)
- {
- if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_LITTLE)
- {
-
- memcpy (to, from, register_size (gdbarch, regnum));
- return;
- }
- if ((regnum >= DR0_REGNUM
- && regnum <= DR_LAST_REGNUM)
- || (regnum >= DR0_C_REGNUM
- && regnum <= DR_LAST_C_REGNUM))
- {
- DOUBLEST val;
- floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
- from, &val);
- store_typed_floating (to, type, val);
- }
- else
- error (_("sh64_register_convert_to_virtual "
- "called with non DR register number"));
- }
- static void
- sh64_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type,
- int regnum, const void *from, void *to)
- {
- if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_LITTLE)
- {
-
- memcpy (to, from, register_size (gdbarch, regnum));
- return;
- }
- if ((regnum >= DR0_REGNUM
- && regnum <= DR_LAST_REGNUM)
- || (regnum >= DR0_C_REGNUM
- && regnum <= DR_LAST_C_REGNUM))
- {
- DOUBLEST val = extract_typed_floating (from, type);
- floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword,
- &val, to);
- }
- else
- error (_("sh64_register_convert_to_raw called "
- "with non DR register number"));
- }
- static enum register_status
- pseudo_register_read_portions (struct gdbarch *gdbarch,
- struct regcache *regcache,
- int portions,
- int base_regnum, gdb_byte *buffer)
- {
- int portion;
- for (portion = 0; portion < portions; portion++)
- {
- enum register_status status;
- gdb_byte *b;
- b = buffer + register_size (gdbarch, base_regnum) * portion;
- status = regcache_raw_read (regcache, base_regnum + portion, b);
- if (status != REG_VALID)
- return status;
- }
- return REG_VALID;
- }
- static enum register_status
- sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int reg_nr, gdb_byte *buffer)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int base_regnum;
- int offset = 0;
- gdb_byte temp_buffer[MAX_REGISTER_SIZE];
- enum register_status status;
- if (reg_nr >= DR0_REGNUM
- && reg_nr <= DR_LAST_REGNUM)
- {
- base_regnum = sh64_dr_reg_base_num (gdbarch, reg_nr);
-
-
- status = pseudo_register_read_portions (gdbarch, regcache,
- 2, base_regnum, temp_buffer);
- if (status == REG_VALID)
- {
-
- sh64_register_convert_to_virtual (gdbarch, reg_nr,
- register_type (gdbarch, reg_nr),
- temp_buffer, buffer);
- }
- return status;
- }
- else if (reg_nr >= FPP0_REGNUM
- && reg_nr <= FPP_LAST_REGNUM)
- {
- base_regnum = sh64_fpp_reg_base_num (gdbarch, reg_nr);
-
-
- return pseudo_register_read_portions (gdbarch, regcache,
- 2, base_regnum, buffer);
- }
- else if (reg_nr >= FV0_REGNUM
- && reg_nr <= FV_LAST_REGNUM)
- {
- base_regnum = sh64_fv_reg_base_num (gdbarch, reg_nr);
-
-
- return pseudo_register_read_portions (gdbarch, regcache,
- 4, base_regnum, buffer);
- }
-
- else if (reg_nr >= R0_C_REGNUM
- && reg_nr <= T_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
-
- status = regcache_raw_read (regcache, base_regnum, temp_buffer);
- if (status != REG_VALID)
- return status;
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- offset = 4;
- memcpy (buffer,
- temp_buffer + offset, 4);
- return REG_VALID;
- }
- else if (reg_nr >= FP0_C_REGNUM
- && reg_nr <= FP_LAST_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
-
-
- return regcache_raw_read (regcache, base_regnum, buffer);
- }
- else if (reg_nr >= DR0_C_REGNUM
- && reg_nr <= DR_LAST_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
-
- status = pseudo_register_read_portions (gdbarch, regcache,
- 2, base_regnum, temp_buffer);
- if (status == REG_VALID)
- {
-
- sh64_register_convert_to_virtual (gdbarch, reg_nr,
- register_type (gdbarch, reg_nr),
- temp_buffer, buffer);
- }
- return status;
- }
- else if (reg_nr >= FV0_C_REGNUM
- && reg_nr <= FV_LAST_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
-
-
- return pseudo_register_read_portions (gdbarch, regcache,
- 4, base_regnum, buffer);
- }
- else if (reg_nr == FPSCR_C_REGNUM)
- {
- int fpscr_base_regnum;
- int sr_base_regnum;
- unsigned int fpscr_value;
- unsigned int sr_value;
- unsigned int fpscr_c_value;
- unsigned int fpscr_c_part1_value;
- unsigned int fpscr_c_part2_value;
- fpscr_base_regnum = FPSCR_REGNUM;
- sr_base_regnum = SR_REGNUM;
-
-
-
-
-
-
- status = regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
- if (status != REG_VALID)
- return status;
-
- fpscr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
-
- status = regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
- if (status != REG_VALID)
- return status;
-
- sr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
-
- fpscr_c_part1_value = fpscr_value & 0x3fffd;
- fpscr_c_part2_value = (sr_value & 0x7000) << 6;
- fpscr_c_value = fpscr_c_part1_value | fpscr_c_part2_value;
-
- store_unsigned_integer (buffer, 4, byte_order, fpscr_c_value);
- FIXME
- return REG_VALID;
- }
- else if (reg_nr == FPUL_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
-
- return regcache_raw_read (regcache, base_regnum, buffer);
- }
- else
- gdb_assert_not_reached ("invalid pseudo register number");
- }
- static void
- sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int reg_nr, const gdb_byte *buffer)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int base_regnum, portion;
- int offset;
- gdb_byte temp_buffer[MAX_REGISTER_SIZE];
- if (reg_nr >= DR0_REGNUM
- && reg_nr <= DR_LAST_REGNUM)
- {
- base_regnum = sh64_dr_reg_base_num (gdbarch, reg_nr);
-
- sh64_register_convert_to_raw (gdbarch, register_type (gdbarch, reg_nr),
- reg_nr,
- buffer, temp_buffer);
-
- for (portion = 0; portion < 2; portion++)
- regcache_raw_write (regcache, base_regnum + portion,
- (temp_buffer
- + register_size (gdbarch,
- base_regnum) * portion));
- }
- else if (reg_nr >= FPP0_REGNUM
- && reg_nr <= FPP_LAST_REGNUM)
- {
- base_regnum = sh64_fpp_reg_base_num (gdbarch, reg_nr);
-
- for (portion = 0; portion < 2; portion++)
- regcache_raw_write (regcache, base_regnum + portion,
- (buffer + register_size (gdbarch,
- base_regnum) * portion));
- }
- else if (reg_nr >= FV0_REGNUM
- && reg_nr <= FV_LAST_REGNUM)
- {
- base_regnum = sh64_fv_reg_base_num (gdbarch, reg_nr);
-
- for (portion = 0; portion < 4; portion++)
- regcache_raw_write (regcache, base_regnum + portion,
- (buffer + register_size (gdbarch,
- base_regnum) * portion));
- }
-
- else if (reg_nr >= R0_C_REGNUM
- && reg_nr <= T_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
-
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- offset = 4;
- else
- offset = 0;
-
- regcache_raw_read (regcache, base_regnum, temp_buffer);
-
- memcpy (temp_buffer + offset, buffer, 4);
- regcache_raw_write (regcache, base_regnum, temp_buffer);
- }
-
- else if (reg_nr >= FP0_C_REGNUM
- && reg_nr <= FP_LAST_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
- regcache_raw_write (regcache, base_regnum, buffer);
- }
- else if (reg_nr >= DR0_C_REGNUM
- && reg_nr <= DR_LAST_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
- for (portion = 0; portion < 2; portion++)
- {
-
- sh64_register_convert_to_raw (gdbarch,
- register_type (gdbarch, reg_nr),
- reg_nr,
- buffer, temp_buffer);
- regcache_raw_write (regcache, base_regnum + portion,
- (temp_buffer
- + register_size (gdbarch,
- base_regnum) * portion));
- }
- }
- else if (reg_nr >= FV0_C_REGNUM
- && reg_nr <= FV_LAST_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
- for (portion = 0; portion < 4; portion++)
- {
- regcache_raw_write (regcache, base_regnum + portion,
- (buffer
- + register_size (gdbarch,
- base_regnum) * portion));
- }
- }
- else if (reg_nr == FPSCR_C_REGNUM)
- {
- int fpscr_base_regnum;
- int sr_base_regnum;
- unsigned int fpscr_value;
- unsigned int sr_value;
- unsigned int old_fpscr_value;
- unsigned int old_sr_value;
- unsigned int fpscr_c_value;
- unsigned int fpscr_mask;
- unsigned int sr_mask;
- fpscr_base_regnum = FPSCR_REGNUM;
- sr_base_regnum = SR_REGNUM;
-
-
-
-
-
- fpscr_c_value = extract_unsigned_integer (buffer, 4, byte_order);
-
- fpscr_mask = 0x0003fffd;
- sr_mask = 0x001c0000;
- fpscr_value = fpscr_c_value & fpscr_mask;
- sr_value = (fpscr_value & sr_mask) >> 6;
- regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
- old_fpscr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
- old_fpscr_value &= 0xfffc0002;
- fpscr_value |= old_fpscr_value;
- store_unsigned_integer (temp_buffer, 4, byte_order, fpscr_value);
- regcache_raw_write (regcache, fpscr_base_regnum, temp_buffer);
- regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
- old_sr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
- old_sr_value &= 0xffff8fff;
- sr_value |= old_sr_value;
- store_unsigned_integer (temp_buffer, 4, byte_order, sr_value);
- regcache_raw_write (regcache, sr_base_regnum, temp_buffer);
- }
- else if (reg_nr == FPUL_C_REGNUM)
- {
- base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
- regcache_raw_write (regcache, base_regnum, buffer);
- }
- }
- FIXME
- static void
- sh64_do_cr_c_register_info (struct ui_file *file, struct frame_info *frame,
- int cr_c_regnum)
- {
- switch (cr_c_regnum)
- {
- case PC_C_REGNUM:
- fprintf_filtered (file, "pc_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case GBR_C_REGNUM:
- fprintf_filtered (file, "gbr_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case MACH_C_REGNUM:
- fprintf_filtered (file, "mach_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case MACL_C_REGNUM:
- fprintf_filtered (file, "macl_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case PR_C_REGNUM:
- fprintf_filtered (file, "pr_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case T_C_REGNUM:
- fprintf_filtered (file, "t_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case FPSCR_C_REGNUM:
- fprintf_filtered (file, "fpscr_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- case FPUL_C_REGNUM:
- fprintf_filtered (file, "fpul_c\t0x%08x\n",
- (int) get_frame_register_unsigned (frame, cr_c_regnum));
- break;
- }
- }
- static void
- sh64_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regnum)
- {
- unsigned char *raw_buffer;
- double flt;
- int inv;
- int j;
-
- raw_buffer = (unsigned char *)
- alloca (register_size (gdbarch, gdbarch_fp0_regnum (gdbarch)));
-
- if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
- error (_("can't read register %d (%s)"),
- regnum, gdbarch_register_name (gdbarch, regnum));
-
- flt = unpack_double (builtin_type (gdbarch)->builtin_float,
- raw_buffer, &inv);
-
- fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
- print_spaces_filtered (15 - strlen (gdbarch_register_name
- (gdbarch, regnum)), file);
-
- if (inv)
- fprintf_filtered (file, "<invalid float>");
- else
- fprintf_filtered (file, "%-10.9g", flt);
-
- fprintf_filtered (file, "\t(raw ");
- print_hex_chars (file, raw_buffer,
- register_size (gdbarch, regnum),
- gdbarch_byte_order (gdbarch));
- fprintf_filtered (file, ")");
- fprintf_filtered (file, "\n");
- }
- static void
- sh64_do_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regnum)
- {
-
- if (regnum < gdbarch_num_regs (gdbarch)
- || regnum >= gdbarch_num_regs (gdbarch)
- + NUM_PSEUDO_REGS_SH_MEDIA
- + NUM_PSEUDO_REGS_SH_COMPACT)
- internal_error (__FILE__, __LINE__,
- _("Invalid pseudo register number %d\n"), regnum);
- else if ((regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM))
- {
- int fp_regnum = sh64_dr_reg_base_num (gdbarch, regnum);
- fprintf_filtered (file, "dr%d\t0x%08x%08x\n", regnum - DR0_REGNUM,
- (unsigned) get_frame_register_unsigned (frame, fp_regnum),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 1));
- }
- else if ((regnum >= DR0_C_REGNUM && regnum <= DR_LAST_C_REGNUM))
- {
- int fp_regnum = sh64_compact_reg_base_num (gdbarch, regnum);
- fprintf_filtered (file, "dr%d_c\t0x%08x%08x\n", regnum - DR0_C_REGNUM,
- (unsigned) get_frame_register_unsigned (frame, fp_regnum),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 1));
- }
- else if ((regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM))
- {
- int fp_regnum = sh64_fv_reg_base_num (gdbarch, regnum);
- fprintf_filtered (file, "fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
- regnum - FV0_REGNUM,
- (unsigned) get_frame_register_unsigned (frame, fp_regnum),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 1),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 2),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 3));
- }
- else if ((regnum >= FV0_C_REGNUM && regnum <= FV_LAST_C_REGNUM))
- {
- int fp_regnum = sh64_compact_reg_base_num (gdbarch, regnum);
- fprintf_filtered (file, "fv%d_c\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
- regnum - FV0_C_REGNUM,
- (unsigned) get_frame_register_unsigned (frame, fp_regnum),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 1),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 2),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 3));
- }
- else if (regnum >= FPP0_REGNUM && regnum <= FPP_LAST_REGNUM)
- {
- int fp_regnum = sh64_fpp_reg_base_num (gdbarch, regnum);
- fprintf_filtered (file, "fpp%d\t0x%08x\t0x%08x\n", regnum - FPP0_REGNUM,
- (unsigned) get_frame_register_unsigned (frame, fp_regnum),
- (unsigned) get_frame_register_unsigned (frame, fp_regnum + 1));
- }
- else if (regnum >= R0_C_REGNUM && regnum <= R_LAST_C_REGNUM)
- {
- int c_regnum = sh64_compact_reg_base_num (gdbarch, regnum);
- fprintf_filtered (file, "r%d_c\t0x%08x\n", regnum - R0_C_REGNUM,
- (unsigned) get_frame_register_unsigned (frame, c_regnum));
- }
- else if (regnum >= FP0_C_REGNUM && regnum <= FP_LAST_C_REGNUM)
-
- sh64_do_fp_register (gdbarch, file, frame, regnum);
- else if (regnum >= PC_C_REGNUM && regnum <= FPUL_C_REGNUM)
- sh64_do_cr_c_register_info (file, frame, regnum);
- }
- static void
- sh64_do_register (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regnum)
- {
- unsigned char raw_buffer[MAX_REGISTER_SIZE];
- struct value_print_options opts;
- fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
- print_spaces_filtered (15 - strlen (gdbarch_register_name
- (gdbarch, regnum)), file);
-
- if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
- {
- fprintf_filtered (file, "*value not available*\n");
- return;
- }
- get_formatted_print_options (&opts, 'x');
- opts.deref_ref = 1;
- val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0,
- file, 0, NULL, &opts, current_language);
- fprintf_filtered (file, "\t");
- get_formatted_print_options (&opts, 0);
- opts.deref_ref = 1;
- val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0,
- file, 0, NULL, &opts, current_language);
- fprintf_filtered (file, "\n");
- }
- static void
- sh64_print_register (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regnum)
- {
- if (regnum < 0 || regnum >= gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch))
- internal_error (__FILE__, __LINE__,
- _("Invalid register number %d\n"), regnum);
- else if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
- {
- if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
- sh64_do_fp_register (gdbarch, file, frame, regnum);
- else
- sh64_do_register (gdbarch, file, frame, regnum);
- }
- else if (regnum < gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch))
- sh64_do_pseudo_register (gdbarch, file, frame, regnum);
- }
- static void
- sh64_media_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regnum,
- int fpregs)
- {
- if (regnum != -1)
- {
- if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
- error (_("Not a valid register for the current processor type"));
- sh64_print_register (gdbarch, file, frame, regnum);
- }
- else
-
- {
- regnum = 0;
- while (regnum < gdbarch_num_regs (gdbarch))
- {
-
- if (gdbarch_register_name (gdbarch, regnum) == NULL
- || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
- {
- regnum++;
- continue;
- }
- if (TYPE_CODE (register_type (gdbarch, regnum))
- == TYPE_CODE_FLT)
- {
- if (fpregs)
- {
-
- sh64_do_fp_register (gdbarch, file, frame, regnum);
- regnum ++;
- }
- else
- regnum += FP_LAST_REGNUM - gdbarch_fp0_regnum (gdbarch);
-
- }
- else
- {
- sh64_do_register (gdbarch, file, frame, regnum);
- regnum++;
- }
- }
- if (fpregs)
- while (regnum < gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch))
- {
- sh64_do_pseudo_register (gdbarch, file, frame, regnum);
- regnum++;
- }
- }
- }
- static void
- sh64_compact_print_registers_info (struct gdbarch *gdbarch,
- struct ui_file *file,
- struct frame_info *frame, int regnum,
- int fpregs)
- {
- if (regnum != -1)
- {
- if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
- error (_("Not a valid register for the current processor type"));
- if (regnum >= 0 && regnum < R0_C_REGNUM)
- error (_("Not a valid register for the current processor mode."));
- sh64_print_register (gdbarch, file, frame, regnum);
- }
- else
-
- {
- regnum = R0_C_REGNUM;
- while (regnum < gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch))
- {
- sh64_do_pseudo_register (gdbarch, file, frame, regnum);
- regnum++;
- }
- }
- }
- static void
- sh64_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regnum, int fpregs)
- {
- if (pc_is_isa32 (get_frame_pc (frame)))
- sh64_media_print_registers_info (gdbarch, file, frame, regnum, fpregs);
- else
- sh64_compact_print_registers_info (gdbarch, file, frame, regnum, fpregs);
- }
- static struct sh64_frame_cache *
- sh64_alloc_frame_cache (void)
- {
- struct sh64_frame_cache *cache;
- int i;
- cache = FRAME_OBSTACK_ZALLOC (struct sh64_frame_cache);
-
- cache->base = 0;
- cache->saved_sp = 0;
- cache->sp_offset = 0;
- cache->pc = 0;
-
- cache->uses_fp = 0;
-
- for (i = 0; i < SIM_SH64_NR_REGS; i++)
- {
- cache->saved_regs[i] = -1;
- }
- return cache;
- }
- static struct sh64_frame_cache *
- sh64_frame_cache (struct frame_info *this_frame, void **this_cache)
- {
- struct gdbarch *gdbarch;
- struct sh64_frame_cache *cache;
- CORE_ADDR current_pc;
- int i;
- if (*this_cache)
- return *this_cache;
- gdbarch = get_frame_arch (this_frame);
- cache = sh64_alloc_frame_cache ();
- *this_cache = cache;
- current_pc = get_frame_pc (this_frame);
- cache->media_mode = pc_is_isa32 (current_pc);
-
- cache->base = get_frame_register_unsigned (this_frame, MEDIA_FP_REGNUM);
- if (cache->base == 0)
- return cache;
- cache->pc = get_frame_func (this_frame);
- if (cache->pc != 0)
- sh64_analyze_prologue (gdbarch, cache, cache->pc, current_pc);
- if (!cache->uses_fp)
- {
-
- cache->base = get_frame_register_unsigned
- (this_frame, gdbarch_sp_regnum (gdbarch));
- }
-
- cache->saved_sp = cache->base + cache->sp_offset;
-
- for (i = 0; i < SIM_SH64_NR_REGS; i++)
- if (cache->saved_regs[i] != -1)
- cache->saved_regs[i] = cache->saved_sp - cache->saved_regs[i];
- return cache;
- }
- static struct value *
- sh64_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
- {
- struct sh64_frame_cache *cache = sh64_frame_cache (this_frame, this_cache);
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_assert (regnum >= 0);
- if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp)
- frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
-
- if (regnum == gdbarch_pc_regnum (gdbarch))
- regnum = PR_REGNUM;
- if (regnum < SIM_SH64_NR_REGS && cache->saved_regs[regnum] != -1)
- {
- if (gdbarch_tdep (gdbarch)->sh_abi == SH_ABI_32
- && (regnum == MEDIA_FP_REGNUM || regnum == PR_REGNUM))
- {
- CORE_ADDR val;
- val = read_memory_unsigned_integer (cache->saved_regs[regnum],
- 4, byte_order);
- return frame_unwind_got_constant (this_frame, regnum, val);
- }
- return frame_unwind_got_memory (this_frame, regnum,
- cache->saved_regs[regnum]);
- }
- return frame_unwind_got_register (this_frame, regnum, regnum);
- }
- static void
- sh64_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
- {
- struct sh64_frame_cache *cache = sh64_frame_cache (this_frame, this_cache);
-
- if (cache->base == 0)
- return;
- *this_id = frame_id_build (cache->saved_sp, cache->pc);
- }
- static const struct frame_unwind sh64_frame_unwind = {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- sh64_frame_this_id,
- sh64_frame_prev_register,
- NULL,
- default_frame_sniffer
- };
- static CORE_ADDR
- sh64_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
- {
- return frame_unwind_register_unsigned (next_frame,
- gdbarch_sp_regnum (gdbarch));
- }
- static CORE_ADDR
- sh64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
- {
- return frame_unwind_register_unsigned (next_frame,
- gdbarch_pc_regnum (gdbarch));
- }
- static struct frame_id
- sh64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_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
- sh64_frame_base_address (struct frame_info *this_frame, void **this_cache)
- {
- struct sh64_frame_cache *cache = sh64_frame_cache (this_frame, this_cache);
- return cache->base;
- }
- static const struct frame_base sh64_frame_base = {
- &sh64_frame_unwind,
- sh64_frame_base_address,
- sh64_frame_base_address,
- sh64_frame_base_address
- };
- struct gdbarch *
- sh64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- {
- struct gdbarch *gdbarch;
- struct gdbarch_tdep *tdep;
-
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- tdep = XNEW (struct gdbarch_tdep);
- gdbarch = gdbarch_alloc (&info, tdep);
-
- if (info.abfd && bfd_get_arch_size (info.abfd) == 64)
- {
-
- tdep->sh_abi = SH_ABI_64;
- set_gdbarch_ptr_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- }
- else
- {
-
- tdep->sh_abi = SH_ABI_32;
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- }
- set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
-
- set_gdbarch_num_regs (gdbarch, SIM_SH64_NR_REGS);
- set_gdbarch_sp_regnum (gdbarch, 15);
- set_gdbarch_pc_regnum (gdbarch, 64);
- set_gdbarch_fp0_regnum (gdbarch, SIM_SH64_FR0_REGNUM);
- set_gdbarch_num_pseudo_regs (gdbarch, NUM_PSEUDO_REGS_SH_MEDIA
- + NUM_PSEUDO_REGS_SH_COMPACT);
- set_gdbarch_register_name (gdbarch, sh64_register_name);
- set_gdbarch_register_type (gdbarch, sh64_register_type);
- set_gdbarch_pseudo_register_read (gdbarch, sh64_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, sh64_pseudo_register_write);
- set_gdbarch_breakpoint_from_pc (gdbarch, sh64_breakpoint_from_pc);
- set_gdbarch_print_insn (gdbarch, print_insn_sh);
- set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
- set_gdbarch_return_value (gdbarch, sh64_return_value);
- set_gdbarch_skip_prologue (gdbarch, sh64_skip_prologue);
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_push_dummy_call (gdbarch, sh64_push_dummy_call);
- set_gdbarch_believe_pcc_promotion (gdbarch, 1);
- set_gdbarch_frame_align (gdbarch, sh64_frame_align);
- set_gdbarch_unwind_sp (gdbarch, sh64_unwind_sp);
- set_gdbarch_unwind_pc (gdbarch, sh64_unwind_pc);
- set_gdbarch_dummy_id (gdbarch, sh64_dummy_id);
- frame_base_set_default (gdbarch, &sh64_frame_base);
- set_gdbarch_print_registers_info (gdbarch, sh64_print_registers_info);
- set_gdbarch_elf_make_msymbol_special (gdbarch,
- sh64_elf_make_msymbol_special);
-
- gdbarch_init_osabi (info, gdbarch);
- dwarf2_append_unwinders (gdbarch);
- frame_unwind_append_unwinder (gdbarch, &sh64_frame_unwind);
- return gdbarch;
- }