#include "defs.h"
#include "frame.h"
#include "symtab.h"
#include "symfile.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "value.h"
#include "dis-asm.h"
#include "inferior.h"
#include "gdb_string.h"
#include "arch-utils.h"
#include "floatformat.h"
#include "regcache.h"
#include "doublest.h"
#include "osabi.h"
#include "sh-tdep.h"
#include "elf-bfd.h"
#include "solib-svr4.h"
#include "elf/sh.h"
#include "gdb/sim-sh.h"
void (*sh_show_regs) (void);
CORE_ADDR (*skip_prologue_hard_way) (CORE_ADDR);
void (*do_pseudo_register) (int);
#define SH_DEFAULT_NUM_REGS 59
struct frame_extra_info
{
CORE_ADDR return_pc;
int leaf_function;
int f_offset;
};
static const char *
sh_generic_register_name (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;
if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
return NULL;
return register_names[reg_nr];
}
static const char *
sh_sh_register_name (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",
"", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
};
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_sh3_register_name (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",
"", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"ssr", "spc",
"r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
"r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1"
};
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_sh3e_register_name (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;
if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
return NULL;
return register_names[reg_nr];
}
static const char *
sh_sh_dsp_register_name (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",
"", "dsr",
"a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
"y0", "y1", "", "", "", "", "", "mod",
"", "",
"rs", "re", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
};
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_sh3_dsp_register_name (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",
"", "dsr",
"a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
"y0", "y1", "", "", "", "", "", "mod",
"ssr", "spc",
"rs", "re", "", "", "", "", "", "",
"r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b"
"", "", "", "", "", "", "", "",
};
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_sh4_register_name (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",
"dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
"fv0", "fv4", "fv8", "fv12",
};
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_sh64_register_name (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",
};
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
static const unsigned char *
sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
static unsigned char breakpoint[] = {0xc3, 0xc3};
*lenptr = sizeof (breakpoint);
return breakpoint;
}
#define MSYMBOL_IS_SPECIAL(msym) \
(((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
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_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) | 0x80000000);
SYMBOL_VALUE_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 minimal_symbol *sym;
if (IS_ISA32_ADDR (memaddr))
return 1;
sym = lookup_minimal_symbol_by_pc (memaddr);
if (sym)
return MSYMBOL_IS_SPECIAL (sym);
else
return 0;
}
static const unsigned char *
sh_sh64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
if (TARGET_BYTE_ORDER == 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)
#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_STS(x) ((x) == 0x4f22)
#define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06)
#define GET_PUSHED_REG(x) (((x) >> 4) & 0xf)
#define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
#define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
#define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
#define IS_SHLL_R3(x) ((x) == 0x4300)
#define IS_ADD_R3SP(x) ((x) == 0x3f3c)
#define IS_FMOV(x) (((x) & 0xf00f) == 0xf00b)
#define IS_ARG_MOV(x) \
(((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \
|| ((((x) & 0xf000) == 0x1000) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \
|| ((((x) & 0xf00f) == 0x2002) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)))
#define IS_MOV_TO_R14(x) \
((((x) & 0xff00) == 0x1e) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070))
#define FPSCR_SZ (1 << 20)
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
sh_skip_prologue_hard_way (CORE_ADDR start_pc)
{
CORE_ADDR here, end;
int updated_fp = 0;
if (!start_pc)
return 0;
for (here = start_pc, end = start_pc + (2 * 28); here < end;)
{
int w = read_memory_integer (here, 2);
here += 2;
if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w) || IS_MOV_R3 (w)
|| IS_ADD_R3SP (w) || IS_ADD_SP (w) || IS_SHLL_R3 (w)
|| IS_ARG_MOV (w) || IS_MOV_TO_R14 (w))
{
start_pc = here;
}
else if (IS_MOV_SP_FP (w))
{
start_pc = here;
updated_fp = 1;
}
else
if (updated_fp)
break;
}
return start_pc;
}
static CORE_ADDR
look_for_args_moves (CORE_ADDR start_pc, int media_mode)
{
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);
here += insn_size;
if (IS_MEDIA_IND_ARG_MOV (w))
{
int next_insn = read_memory_integer (UNMAKE_ISA32_ADDR (here),
insn_size);
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);
w = w & 0xffff;
here += insn_size;
if (IS_COMPACT_IND_ARG_MOV (w))
{
int next_insn = 0xffff & read_memory_integer (here, insn_size);
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);
here += insn_size;
if (IS_JSR_R0 (next_insn))
{
next_insn = 0xffff & read_memory_integer (here, insn_size);
here += insn_size;
if (IS_NOP (next_insn))
start_pc = here;
}
}
else
break;
}
}
return start_pc;
}
static CORE_ADDR
sh64_skip_prologue_hard_way (CORE_ADDR start_pc)
{
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);
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 (here - insn_size, media_mode);
break;
}
}
else
{
int w = 0xffff & read_memory_integer (here, insn_size);
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 (here - insn_size, media_mode);
break;
}
}
}
return start_pc;
}
static CORE_ADDR
sh_skip_prologue (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 (skip_prologue_hard_way (pc));
}
static CORE_ADDR
sh_saved_pc_after_call (struct frame_info *frame)
{
return (ADDR_BITS_REMOVE (read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM)));
}
static int
sh_use_struct_convention (int gcc_p, struct type *type)
{
#if 0
return (TYPE_LENGTH (type) > 1);
#else
int len = TYPE_LENGTH (type);
int nelem = TYPE_NFIELDS (type);
return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) &&
(len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4);
#endif
}
static int
sh64_use_struct_convention (int gcc_p, struct type *type)
{
return (TYPE_LENGTH (type) > 8);
}
static void
sh_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
write_register (STRUCT_RETURN_REGNUM, (addr));
}
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_frame_chain (struct frame_info *frame)
{
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
get_frame_base (frame),
get_frame_base (frame)))
return get_frame_base (frame);
if (get_frame_pc (frame) && !inside_entry_file (get_frame_pc (frame)))
return read_memory_integer (get_frame_base (frame)
+ get_frame_extra_info (frame)->f_offset, 4);
else
return 0;
}
static int
translate_insn_rn (int rn, int media_mode)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (media_mode)
return rn;
else
{
#if 0
if ((rn >= 16 && rn <= 63) || (rn >= 93 && rn <= 140))
return rn;
#endif
if (rn >= 0 && rn <= tdep->R0_C_REGNUM)
return tdep->R0_C_REGNUM + rn;
else
return rn;
}
}
static CORE_ADDR
sh64_frame_chain (struct frame_info *frame)
{
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
get_frame_base (frame),
get_frame_base (frame)))
return get_frame_base (frame);
if (get_frame_pc (frame) && !inside_entry_file (get_frame_pc (frame)))
{
int media_mode = pc_is_isa32 (get_frame_pc (frame));
int size;
if (gdbarch_tdep (current_gdbarch)->sh_abi == SH_ABI_32)
size = 4;
else
size = REGISTER_RAW_SIZE (translate_insn_rn (FP_REGNUM, media_mode));
return read_memory_integer (get_frame_base (frame)
+ get_frame_extra_info (frame)->f_offset,
size);
}
else
return 0;
}
static CORE_ADDR
sh_find_callers_reg (struct frame_info *fi, int regnum)
{
for (; fi; fi = get_next_frame (fi))
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
get_frame_base (fi)))
return deprecated_read_register_dummy (get_frame_pc (fi),
get_frame_base (fi), regnum);
else
{
FRAME_INIT_SAVED_REGS (fi);
if (!get_frame_pc (fi))
return 0;
if (get_frame_saved_regs (fi)[regnum] != 0)
return read_memory_integer (get_frame_saved_regs (fi)[regnum],
REGISTER_RAW_SIZE (regnum));
}
return read_register (regnum);
}
static CORE_ADDR
sh64_get_saved_pr (struct frame_info *fi, int pr_regnum)
{
int media_mode = 0;
for (; fi; fi = get_next_frame (fi))
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
get_frame_base (fi)))
return deprecated_read_register_dummy (get_frame_pc (fi),
get_frame_base (fi), pr_regnum);
else
{
FRAME_INIT_SAVED_REGS (fi);
if (!get_frame_pc (fi))
return 0;
media_mode = pc_is_isa32 (get_frame_pc (fi));
if (get_frame_saved_regs (fi)[pr_regnum] != 0)
{
int gdb_reg_num = translate_insn_rn (pr_regnum, media_mode);
int size = ((gdbarch_tdep (current_gdbarch)->sh_abi == SH_ABI_32)
? 4
: REGISTER_RAW_SIZE (gdb_reg_num));
return read_memory_integer (get_frame_saved_regs (fi)[pr_regnum], size);
}
}
return read_register (pr_regnum);
}
static void
sh_nofp_frame_init_saved_regs (struct frame_info *fi)
{
int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof(int));
int rn;
int have_fp = 0;
int depth;
int pc;
int opc;
int insn;
int r3_val = 0;
char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi),
get_frame_base (fi));
if (get_frame_saved_regs (fi) == NULL)
frame_saved_regs_zalloc (fi);
else
memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS);
if (dummy_regs)
{
memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
return;
}
get_frame_extra_info (fi)->leaf_function = 1;
get_frame_extra_info (fi)->f_offset = 0;
for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
where[rn] = -1;
depth = 0;
pc = get_pc_function_start (get_frame_pc (fi));
if (!pc)
{
deprecated_update_frame_pc_hack (fi, 0);
return;
}
for (opc = pc + (2 * 28); pc < opc; pc += 2)
{
insn = read_memory_integer (pc, 2);
if (IS_PUSH (insn))
{
rn = GET_PUSHED_REG (insn);
where[rn] = depth;
depth += 4;
}
else if (IS_STS (insn))
{
where[gdbarch_tdep (current_gdbarch)->PR_REGNUM] = depth;
get_frame_extra_info (fi)->leaf_function = 0;
depth += 4;
}
else if (IS_MOV_R3 (insn))
{
r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
}
else if (IS_SHLL_R3 (insn))
{
r3_val <<= 1;
}
else if (IS_ADD_R3SP (insn))
{
depth += -r3_val;
}
else if (IS_ADD_SP (insn))
{
depth -= ((insn & 0xff) ^ 0x80) - 0x80;
}
else if (IS_MOV_SP_FP (insn))
break;
#if 0
else
break;
#endif
}
for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
{
if (where[rn] >= 0)
{
if (rn == FP_REGNUM)
have_fp = 1;
get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - where[rn] + depth - 4;
}
else
{
get_frame_saved_regs (fi)[rn] = 0;
}
}
if (have_fp)
{
get_frame_saved_regs (fi)[SP_REGNUM] = read_memory_integer (get_frame_saved_regs (fi)[FP_REGNUM], 4);
}
else
{
get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) - 4;
}
get_frame_extra_info (fi)->f_offset = depth - where[FP_REGNUM] - 4;
}
static int
fv_reg_base_num (int fv_regnum)
{
int fp_regnum;
fp_regnum = FP0_REGNUM +
(fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4;
return fp_regnum;
}
static int
dr_reg_base_num (int dr_regnum)
{
int fp_regnum;
fp_regnum = FP0_REGNUM +
(dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2;
return fp_regnum;
}
static int
fpp_reg_base_num (int fpp_regnum)
{
int fp_regnum;
fp_regnum = FP0_REGNUM +
(fpp_regnum - gdbarch_tdep (current_gdbarch)->FPP0_REGNUM) * 2;
return fp_regnum;
}
static int
is_media_pseudo (int rn)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
return (rn >= tdep->DR0_REGNUM
&& rn <= tdep->FV_LAST_REGNUM);
}
int
sh64_get_gdb_regnum (int gcc_regnum, CORE_ADDR pc)
{
return translate_insn_rn (gcc_regnum, pc_is_isa32 (pc));
}
static int
sh64_media_reg_base_num (int reg_nr)
{
int base_regnum = -1;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
base_regnum = dr_reg_base_num (reg_nr);
else if (reg_nr >= tdep->FPP0_REGNUM
&& reg_nr <= tdep->FPP_LAST_REGNUM)
base_regnum = fpp_reg_base_num (reg_nr);
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
base_regnum = fv_reg_base_num (reg_nr);
return base_regnum;
}
static int
sh64_compact_reg_base_num (int reg_nr)
{
int base_regnum = -1;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (reg_nr >= tdep->R0_C_REGNUM
&& reg_nr <= tdep->R_LAST_C_REGNUM)
base_regnum = reg_nr - tdep->R0_C_REGNUM;
else if (reg_nr >= tdep->FP0_C_REGNUM
&& reg_nr <= tdep->FP_LAST_C_REGNUM)
base_regnum = reg_nr - tdep->FP0_C_REGNUM + FP0_REGNUM;
else if (reg_nr >= tdep->DR0_C_REGNUM
&& reg_nr <= tdep->DR_LAST_C_REGNUM)
base_regnum = dr_reg_base_num (tdep->DR0_REGNUM
+ reg_nr - tdep->DR0_C_REGNUM);
else if (reg_nr >= tdep->FV0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM)
base_regnum = fv_reg_base_num (tdep->FV0_REGNUM
+ reg_nr - tdep->FV0_C_REGNUM);
else if (reg_nr == tdep->PC_C_REGNUM)
base_regnum = PC_REGNUM;
else if (reg_nr == tdep->GBR_C_REGNUM)
base_regnum = 16;
else if (reg_nr == tdep->MACH_C_REGNUM
|| reg_nr == tdep->MACL_C_REGNUM)
base_regnum = 17;
else if (reg_nr == tdep->PR_C_REGNUM)
base_regnum = 18;
else if (reg_nr == tdep->T_C_REGNUM)
base_regnum = 19;
else if (reg_nr == tdep->FPSCR_C_REGNUM)
base_regnum = tdep->FPSCR_REGNUM;
else if (reg_nr == tdep->FPUL_C_REGNUM)
base_regnum = FP0_REGNUM + 32;
return base_regnum;
}
static int
translate_rn_to_arch_reg_num (int rn, int media_mode)
{
if (media_mode)
{
if (!is_media_pseudo (rn))
return rn;
else
return sh64_media_reg_base_num (rn);
}
else
return sh64_compact_reg_base_num (rn);
}
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_nofp_frame_init_saved_regs (struct frame_info *fi)
{
int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int));
int rn;
int have_fp = 0;
int fp_regnum;
int sp_regnum;
int depth;
int pc;
int opc;
int insn;
int r0_val = 0;
int media_mode = 0;
int insn_size;
int gdb_register_number;
int register_number;
char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), get_frame_base (fi));
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (get_frame_saved_regs (fi) == NULL)
frame_saved_regs_zalloc (fi);
else
memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS);
if (dummy_regs)
{
memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
return;
}
get_frame_extra_info (fi)->leaf_function = 1;
get_frame_extra_info (fi)->f_offset = 0;
for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
where[rn] = -1;
depth = 0;
pc = get_pc_function_start (get_frame_pc (fi));
if (!pc)
{
deprecated_update_frame_pc_hack (fi, 0);
return;
}
if (pc_is_isa32 (pc))
{
media_mode = 1;
insn_size = 4;
}
else
{
media_mode = 0;
insn_size = 2;
}
fp_regnum = translate_insn_rn (FP_REGNUM, media_mode);
sp_regnum = translate_insn_rn (SP_REGNUM, media_mode);
for (opc = pc + (insn_size * 28); pc < opc; pc += insn_size)
{
insn = read_memory_integer (media_mode ? UNMAKE_ISA32_ADDR (pc) : pc,
insn_size);
if (media_mode == 0)
{
if (IS_STS_PR (insn))
{
int next_insn = read_memory_integer (pc + insn_size, insn_size);
if (IS_MOV_TO_R15 (next_insn))
{
int reg_nr = tdep->PR_C_REGNUM;
where[reg_nr] = depth - ((((next_insn & 0xf) ^ 0x8) - 0x8) << 2);
get_frame_extra_info (fi)->leaf_function = 0;
pc += insn_size;
}
}
else if (IS_MOV_R14 (insn))
{
where[fp_regnum] = depth - ((((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))
{
int reg_nr = tdep->PR_C_REGNUM;
where[reg_nr] = depth - (r0_val - 4);
r0_val -= 4;
get_frame_extra_info (fi)->leaf_function = 0;
}
else if (IS_MOV_R14_R0 (insn))
{
where[fp_regnum] = depth - (r0_val - 4);
r0_val -= 4;
}
else if (IS_ADD_SP (insn))
{
depth -= ((insn & 0xff) ^ 0x80) - 0x80;
}
else if (IS_MOV_SP_FP (insn))
break;
}
else
{
if (IS_ADDIL_SP_MEDIA (insn)
|| IS_ADDI_SP_MEDIA (insn))
{
depth -= sign_extend ((((insn & 0xffc00) ^ 0x80000) - 0x80000) >> 10, 9);
}
else if (IS_STQ_R18_R15 (insn))
{
where[tdep->PR_REGNUM] =
depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
get_frame_extra_info (fi)->leaf_function = 0;
}
else if (IS_STL_R18_R15 (insn))
{
where[tdep->PR_REGNUM] =
depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
get_frame_extra_info (fi)->leaf_function = 0;
}
else if (IS_STQ_R14_R15 (insn))
{
where[fp_regnum] = depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
}
else if (IS_STL_R14_R15 (insn))
{
where[fp_regnum] = depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
}
else if (IS_MOV_SP_FP_MEDIA (insn))
break;
}
}
for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
{
register_number = translate_rn_to_arch_reg_num (rn, media_mode);
if (where[rn] >= 0)
{
if (rn == fp_regnum)
have_fp = 1;
get_frame_saved_regs (fi)[register_number]= get_frame_base (fi) - where[rn] + depth;
}
else
get_frame_saved_regs (fi)[register_number] = 0;
}
if (have_fp)
{
int size;
if (tdep->sh_abi == SH_ABI_32)
size = 4;
else
size = REGISTER_RAW_SIZE (fp_regnum);
get_frame_saved_regs (fi)[sp_regnum] = read_memory_integer (get_frame_saved_regs (fi)[fp_regnum], size);
}
else
get_frame_saved_regs (fi)[sp_regnum] = get_frame_base (fi);
get_frame_extra_info (fi)->f_offset = depth - where[fp_regnum];
}
static void
sh_fp_frame_init_saved_regs (struct frame_info *fi)
{
int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int));
int rn;
int have_fp = 0;
int depth;
int pc;
int opc;
int insn;
int r3_val = 0;
char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), get_frame_base (fi));
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (get_frame_saved_regs (fi) == NULL)
frame_saved_regs_zalloc (fi);
else
memset (get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS);
if (dummy_regs)
{
memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
return;
}
get_frame_extra_info (fi)->leaf_function = 1;
get_frame_extra_info (fi)->f_offset = 0;
for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
where[rn] = -1;
depth = 0;
pc = get_pc_function_start (get_frame_pc (fi));
if (!pc)
{
deprecated_update_frame_pc_hack (fi, 0);
return;
}
for (opc = pc + (2 * 28); pc < opc; pc += 2)
{
insn = read_memory_integer (pc, 2);
if (IS_PUSH (insn))
{
rn = GET_PUSHED_REG (insn);
where[rn] = depth;
depth += 4;
}
else if (IS_STS (insn))
{
where[tdep->PR_REGNUM] = depth;
get_frame_extra_info (fi)->leaf_function = 0;
depth += 4;
}
else if (IS_MOV_R3 (insn))
{
r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
}
else if (IS_SHLL_R3 (insn))
{
r3_val <<= 1;
}
else if (IS_ADD_R3SP (insn))
{
depth += -r3_val;
}
else if (IS_ADD_SP (insn))
{
depth -= ((insn & 0xff) ^ 0x80) - 0x80;
}
else if (IS_FMOV (insn))
{
if (read_register (tdep->FPSCR_REGNUM) & FPSCR_SZ)
{
depth += 8;
}
else
{
depth += 4;
}
}
else if (IS_MOV_SP_FP (insn))
break;
#if 0
else
break;
#endif
}
for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
{
if (where[rn] >= 0)
{
if (rn == FP_REGNUM)
have_fp = 1;
get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - where[rn] + depth - 4;
}
else
{
get_frame_saved_regs (fi)[rn] = 0;
}
}
if (have_fp)
{
get_frame_saved_regs (fi)[SP_REGNUM] =
read_memory_integer (get_frame_saved_regs (fi)[FP_REGNUM], 4);
}
else
{
get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) - 4;
}
get_frame_extra_info (fi)->f_offset = depth - where[FP_REGNUM] - 4;
}
static void
sh_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
if (get_next_frame (fi))
deprecated_update_frame_pc_hack (fi, FRAME_SAVED_PC (get_next_frame (fi)));
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
get_frame_base (fi)))
{
deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi),
SP_REGNUM));
get_frame_extra_info (fi)->return_pc = deprecated_read_register_dummy (get_frame_pc (fi),
get_frame_base (fi),
PC_REGNUM);
get_frame_extra_info (fi)->f_offset = -(CALL_DUMMY_LENGTH + 4);
get_frame_extra_info (fi)->leaf_function = 0;
return;
}
else
{
FRAME_INIT_SAVED_REGS (fi);
get_frame_extra_info (fi)->return_pc =
sh_find_callers_reg (fi, gdbarch_tdep (current_gdbarch)->PR_REGNUM);
}
}
static void
sh64_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
int media_mode = pc_is_isa32 (get_frame_pc (fi));
frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
if (get_next_frame (fi))
deprecated_update_frame_pc_hack (fi, FRAME_SAVED_PC (get_next_frame (fi)));
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
get_frame_base (fi)))
{
deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
get_frame_extra_info (fi)->return_pc =
deprecated_read_register_dummy (get_frame_pc (fi),
get_frame_base (fi), PC_REGNUM);
get_frame_extra_info (fi)->f_offset = -(CALL_DUMMY_LENGTH + 4);
get_frame_extra_info (fi)->leaf_function = 0;
return;
}
else
{
FRAME_INIT_SAVED_REGS (fi);
get_frame_extra_info (fi)->return_pc =
sh64_get_saved_pr (fi, gdbarch_tdep (current_gdbarch)->PR_REGNUM);
}
}
void
sh64_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
struct frame_info *frame, int regnum,
enum lval_type *lval)
{
int media_mode;
int live_regnum = regnum;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (!target_has_registers)
error ("No registers.");
if (optimized != NULL)
*optimized = 0;
if (addrp)
*addrp = 0;
if (raw_buffer)
memset (raw_buffer, 0, sizeof (raw_buffer));
media_mode = pc_is_isa32 (get_frame_pc (frame));
live_regnum = translate_insn_rn (regnum, media_mode);
while (frame && ((frame = get_next_frame (frame)) != NULL))
{
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
get_frame_base (frame),
get_frame_base (frame)))
{
if (lval)
*lval = not_lval;
if (raw_buffer)
memcpy (raw_buffer,
(deprecated_generic_find_dummy_frame (get_frame_pc (frame), get_frame_base (frame))
+ REGISTER_BYTE (regnum)),
REGISTER_RAW_SIZE (regnum));
return;
}
FRAME_INIT_SAVED_REGS (frame);
if (get_frame_saved_regs (frame) != NULL
&& get_frame_saved_regs (frame)[regnum] != 0)
{
if (lval)
*lval = lval_memory;
if (regnum == SP_REGNUM)
{
if (raw_buffer)
store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
get_frame_saved_regs (frame)[regnum]);
}
else
{
if (addrp)
*addrp = get_frame_saved_regs (frame)[regnum];
if (raw_buffer)
{
int size;
if (tdep->sh_abi == SH_ABI_32
&& (live_regnum == FP_REGNUM
|| live_regnum == tdep->PR_REGNUM))
size = 4;
else
size = REGISTER_RAW_SIZE (live_regnum);
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
read_memory (get_frame_saved_regs (frame)[regnum], raw_buffer, size);
else
read_memory (get_frame_saved_regs (frame)[regnum],
raw_buffer
+ REGISTER_RAW_SIZE (live_regnum)
- size,
size);
}
}
return;
}
}
if (lval)
*lval = lval_register;
if (addrp)
*addrp = REGISTER_BYTE (live_regnum);
if (raw_buffer)
deprecated_read_register_gen (live_regnum, raw_buffer);
}
static CORE_ADDR
sh_extract_struct_value_address (char *regbuf)
{
return (extract_address ((regbuf), REGISTER_RAW_SIZE (0)));
}
static CORE_ADDR
sh64_extract_struct_value_address (char *regbuf)
{
return (extract_address ((regbuf + REGISTER_BYTE (STRUCT_RETURN_REGNUM)),
REGISTER_RAW_SIZE (STRUCT_RETURN_REGNUM)));
}
static CORE_ADDR
sh_frame_saved_pc (struct frame_info *frame)
{
return (get_frame_extra_info (frame)->return_pc);
}
static void
sh_pop_frame (void)
{
register struct frame_info *frame = get_current_frame ();
register CORE_ADDR fp;
register int regnum;
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
get_frame_base (frame),
get_frame_base (frame)))
generic_pop_dummy_frame ();
else
{
fp = get_frame_base (frame);
FRAME_INIT_SAVED_REGS (frame);
for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
if (get_frame_saved_regs (frame)[regnum])
write_register (regnum,
read_memory_integer (get_frame_saved_regs (frame)[regnum], 4));
write_register (PC_REGNUM, get_frame_extra_info (frame)->return_pc);
write_register (SP_REGNUM, fp + 4);
}
flush_cached_frames ();
}
static void
sh64_pop_frame (void)
{
register struct frame_info *frame = get_current_frame ();
register CORE_ADDR fp;
register int regnum;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
int media_mode = pc_is_isa32 (get_frame_pc (frame));
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
get_frame_base (frame),
get_frame_base (frame)))
generic_pop_dummy_frame ();
else
{
fp = get_frame_base (frame);
FRAME_INIT_SAVED_REGS (frame);
for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
if (get_frame_saved_regs (frame)[regnum])
{
int size;
if (tdep->sh_abi == SH_ABI_32
&& (regnum == FP_REGNUM
|| regnum == tdep->PR_REGNUM))
size = 4;
else
size = REGISTER_RAW_SIZE (translate_insn_rn (regnum,
media_mode));
write_register (regnum,
read_memory_integer (get_frame_saved_regs (frame)[regnum],
size));
}
write_register (PC_REGNUM, get_frame_extra_info (frame)->return_pc);
write_register (SP_REGNUM, fp + 8);
}
flush_cached_frames ();
}
static CORE_ADDR
sh_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
{
int stack_offset, stack_alloc;
int argreg;
int argnum;
struct type *type;
CORE_ADDR regval;
char *val;
char valbuf[4];
int len;
int odd_sized_struct;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
sp = sp & ~3;
if (struct_return)
write_register (STRUCT_RETURN_REGNUM, struct_addr);
for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
sp -= stack_alloc;
argreg = tdep->ARG0_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 (len < 4)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
memcpy (valbuf + (4 - len),
(char *) VALUE_CONTENTS (args[argnum]), len);
else
memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len);
val = valbuf;
}
else
val = (char *) VALUE_CONTENTS (args[argnum]);
if (len > 4 && (len & 3) != 0)
odd_sized_struct = 1;
else
odd_sized_struct = 0;
while (len > 0)
{
if (argreg > tdep->ARGLAST_REGNUM
|| odd_sized_struct)
{
write_memory (sp + stack_offset, val, 4);
stack_offset += 4;
}
if (argreg <= tdep->ARGLAST_REGNUM)
{
regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
write_register (argreg++, regval);
}
len -= REGISTER_RAW_SIZE (argreg);
val += REGISTER_RAW_SIZE (argreg);
}
}
return sp;
}
static CORE_ADDR
sh64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
{
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;
char *val;
char valbuf[8];
char valbuf_tmp[8];
int len;
int argreg_size;
int fp_args[12];
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
memset (fp_args, 0, sizeof (fp_args));
sp = sp & ~7;
if (struct_return)
write_register (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 = tdep->ARG0_REGNUM;
float_argreg = FP0_REGNUM;
double_argreg = tdep->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_RAW_SIZE (int_argreg);
if (len < argreg_size)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
memcpy (valbuf + argreg_size - len,
(char *) VALUE_CONTENTS (args[argnum]), len);
else
memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len);
val = valbuf;
}
else
val = (char *) VALUE_CONTENTS (args[argnum]);
while (len > 0)
{
if (int_argreg > tdep->ARGLAST_REGNUM)
{
write_memory (sp + stack_offset, val, argreg_size);
stack_offset += 8;
}
if (int_argreg <= tdep->ARGLAST_REGNUM)
{
regval = extract_address (val, argreg_size);
write_register (int_argreg, regval);
}
len -= argreg_size;
val += argreg_size;
int_argreg++;
}
}
else
{
val = (char *) VALUE_CONTENTS (args[argnum]);
if (len == 4)
{
while (fp_args[float_arg_index])
float_arg_index ++;
if (float_arg_index <= tdep->FLOAT_ARGLAST_REGNUM)
{
deprecated_write_register_gen (FP0_REGNUM + 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 < tdep->FLOAT_ARGLAST_REGNUM)
{
int double_register_offset = double_arg_index / 2;
int regnum = tdep->DR0_REGNUM +
double_register_offset;
#if 0
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
{
memset (valbuf_tmp, 0, sizeof (valbuf_tmp));
REGISTER_CONVERT_TO_VIRTUAL (regnum,
type, val, valbuf_tmp);
val = valbuf_tmp;
}
#endif
deprecated_write_register_gen (regnum, val);
fp_args[double_arg_index] = 1;
fp_args[double_arg_index + 1] = 1;
int_argreg ++;
}
else
;
}
}
}
return sp;
}
static CORE_ADDR
sh_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
write_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM,
CALL_DUMMY_ADDRESS ());
return sp;
}
#if 0
void
sh_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
struct value **args, struct type *type, int gcc_p)
{
*(unsigned long *) (dummy + 8) = fun;
}
#endif
static void
sh_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
int len = TYPE_LENGTH (type);
int return_register = R0_REGNUM;
int offset;
if (len <= 4)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = REGISTER_BYTE (return_register) + 4 - len;
else
offset = REGISTER_BYTE (return_register);
memcpy (valbuf, regbuf + offset, len);
}
else if (len <= 8)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = REGISTER_BYTE (return_register) + 8 - len;
else
offset = REGISTER_BYTE (return_register);
memcpy (valbuf, regbuf + offset, len);
}
else
error ("bad size for return value");
}
static void
sh3e_sh4_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
int return_register;
int offset;
int len = TYPE_LENGTH (type);
if (TYPE_CODE (type) == TYPE_CODE_FLT)
return_register = FP0_REGNUM;
else
return_register = R0_REGNUM;
if (len == 8 && TYPE_CODE (type) == TYPE_CODE_FLT)
{
DOUBLEST val;
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
(char *) regbuf + REGISTER_BYTE (return_register),
&val);
else
floatformat_to_doublest (&floatformat_ieee_double_big,
(char *) regbuf + REGISTER_BYTE (return_register),
&val);
store_floating (valbuf, len, val);
}
else if (len <= 4)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = REGISTER_BYTE (return_register) + 4 - len;
else
offset = REGISTER_BYTE (return_register);
memcpy (valbuf, regbuf + offset, len);
}
else if (len <= 8)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = REGISTER_BYTE (return_register) + 8 - len;
else
offset = REGISTER_BYTE (return_register);
memcpy (valbuf, regbuf + offset, len);
}
else
error ("bad size for return value");
}
static void
sh64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
int offset;
int return_register;
int len = TYPE_LENGTH (type);
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
if (len == 4)
{
return_register = FP0_REGNUM;
offset = REGISTER_BYTE (return_register);
memcpy (valbuf, (char *) regbuf + offset, len);
}
else if (len == 8)
{
DOUBLEST val;
return_register = tdep->DR0_REGNUM;
offset = REGISTER_BYTE (return_register);
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
(char *) regbuf + offset, &val);
else
floatformat_to_doublest (&floatformat_ieee_double_big,
(char *) regbuf + offset, &val);
store_floating (valbuf, len, val);
}
}
else
{
if (len <= 8)
{
return_register = tdep->RETURN_REGNUM;
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = REGISTER_BYTE (return_register) +
REGISTER_RAW_SIZE (return_register) - len;
else
offset = REGISTER_BYTE (return_register);
memcpy (valbuf, (char *) regbuf + offset, len);
}
else
error ("bad size for return value");
}
}
static void
sh_default_store_return_value (struct type *type, char *valbuf)
{
char buf[32];
if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (R0_REGNUM))
{
memset (buf, 0, REGISTER_RAW_SIZE (R0_REGNUM));
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
memcpy (buf + REGISTER_RAW_SIZE (R0_REGNUM) - TYPE_LENGTH (type),
valbuf, TYPE_LENGTH (type));
else
memcpy (buf, valbuf, TYPE_LENGTH (type));
deprecated_write_register_bytes (REGISTER_BYTE (R0_REGNUM), buf,
REGISTER_RAW_SIZE (R0_REGNUM));
}
else
deprecated_write_register_bytes (REGISTER_BYTE (R0_REGNUM), valbuf,
TYPE_LENGTH (type));
}
static void
sh3e_sh4_store_return_value (struct type *type, char *valbuf)
{
if (TYPE_CODE (type) == TYPE_CODE_FLT)
deprecated_write_register_bytes (REGISTER_BYTE (FP0_REGNUM),
valbuf, TYPE_LENGTH (type));
else
sh_default_store_return_value (type, valbuf);
}
static void
sh64_store_return_value (struct type *type, char *valbuf)
{
char buf[64];
int len = TYPE_LENGTH (type);
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
if (len == 4)
{
deprecated_write_register_gen (FP0_REGNUM, valbuf);
}
if (len == 8)
{
}
}
else
{
int return_register = gdbarch_tdep (current_gdbarch)->RETURN_REGNUM;
int offset = 0;
if (len <= REGISTER_RAW_SIZE (return_register))
{
memset (buf, 0, REGISTER_RAW_SIZE (return_register));
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
offset = 0;
else
offset = REGISTER_RAW_SIZE (return_register) - len;
memcpy (buf + offset, valbuf, len);
deprecated_write_register_gen (return_register, buf);
}
else
deprecated_write_register_gen (return_register, valbuf);
}
}
static void
sh_generic_show_regs (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (tdep->SR_REGNUM),
(long) read_register (tdep->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 ("\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));
}
static void
sh3_show_regs (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (tdep->SR_REGNUM),
(long) read_register (tdep->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 (tdep->SSR_REGNUM),
(long) read_register (tdep->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));
}
static void
sh3e_show_regs (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (tdep->SR_REGNUM),
(long) read_register (tdep->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 (tdep->SSR_REGNUM),
(long) read_register (tdep->SPC_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx",
(long) read_register (tdep->FPUL_REGNUM),
(long) read_register (tdep->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));
}
static void
sh3_dsp_show_regs (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (tdep->SR_REGNUM),
(long) read_register (tdep->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 (tdep->SSR_REGNUM),
(long) read_register (tdep->SPC_REGNUM));
printf_filtered (" DSR=%08lx",
(long) read_register (tdep->DSR_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 ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
(long) read_register (tdep->A0G_REGNUM) & 0xff,
(long) read_register (tdep->A0_REGNUM),
(long) read_register (tdep->M0_REGNUM),
(long) read_register (tdep->X0_REGNUM),
(long) read_register (tdep->Y0_REGNUM),
(long) read_register (tdep->RS_REGNUM),
(long) read_register (tdep->MOD_REGNUM));
printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
(long) read_register (tdep->A1G_REGNUM) & 0xff,
(long) read_register (tdep->A1_REGNUM),
(long) read_register (tdep->M1_REGNUM),
(long) read_register (tdep->X1_REGNUM),
(long) read_register (tdep->Y1_REGNUM),
(long) read_register (tdep->RE_REGNUM));
}
static void
sh4_show_regs (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
int pr = read_register (tdep->FPSCR_REGNUM) & 0x80000;
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (tdep->SR_REGNUM),
(long) read_register (tdep->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 (tdep->SSR_REGNUM),
(long) read_register (tdep->SPC_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx",
(long) read_register (tdep->FPUL_REGNUM),
(long) read_register (tdep->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));
}
static void
sh_dsp_show_regs (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (tdep->SR_REGNUM),
(long) read_register (tdep->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 (" DSR=%08lx",
(long) read_register (tdep->DSR_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 ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
(long) read_register (tdep->A0G_REGNUM) & 0xff,
(long) read_register (tdep->A0_REGNUM),
(long) read_register (tdep->M0_REGNUM),
(long) read_register (tdep->X0_REGNUM),
(long) read_register (tdep->Y0_REGNUM),
(long) read_register (tdep->RS_REGNUM),
(long) read_register (tdep->MOD_REGNUM));
printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
(long) read_register (tdep->A1G_REGNUM) & 0xff,
(long) read_register (tdep->A1_REGNUM),
(long) read_register (tdep->M1_REGNUM),
(long) read_register (tdep->X1_REGNUM),
(long) read_register (tdep->Y1_REGNUM),
(long) read_register (tdep->RE_REGNUM));
}
static void
sh64_show_media_regs (void)
{
int i;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s SR=%016llx \n",
paddr (read_register (PC_REGNUM)),
(long long) read_register (tdep->SR_REGNUM));
printf_filtered ("SSR=%016llx SPC=%016llx \n",
(long long) read_register (tdep->SSR_REGNUM),
(long long) read_register (tdep->SPC_REGNUM));
printf_filtered ("FPSCR=%016lx\n ",
(long) read_register (tdep->FPSCR_REGNUM));
for (i = 0; i < 64; i = i + 4)
printf_filtered ("\nR%d-R%d %016llx %016llx %016llx %016llx\n",
i, i + 3,
(long long) read_register (i + 0),
(long long) read_register (i + 1),
(long long) read_register (i + 2),
(long long) read_register (i + 3));
printf_filtered ("\n");
for (i = 0; i < 64; i = i + 8)
printf_filtered ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
i, i + 7,
(long) read_register (FP0_REGNUM + i + 0),
(long) read_register (FP0_REGNUM + i + 1),
(long) read_register (FP0_REGNUM + i + 2),
(long) read_register (FP0_REGNUM + i + 3),
(long) read_register (FP0_REGNUM + i + 4),
(long) read_register (FP0_REGNUM + i + 5),
(long) read_register (FP0_REGNUM + i + 6),
(long) read_register (FP0_REGNUM + i + 7));
}
static void
sh64_show_compact_regs (void)
{
int i;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
printf_filtered ("PC=%s \n",
paddr (read_register (tdep->PC_C_REGNUM)));
printf_filtered ("GBR=%08lx MACH=%08lx MACL=%08lx PR=%08lx T=%08lx\n",
(long) read_register (tdep->GBR_C_REGNUM),
(long) read_register (tdep->MACH_C_REGNUM),
(long) read_register (tdep->MACL_C_REGNUM),
(long) read_register (tdep->PR_C_REGNUM),
(long) read_register (tdep->T_C_REGNUM));
printf_filtered ("FPSCR=%08lx FPUL=%08lx\n",
(long) read_register (tdep->FPSCR_REGNUM),
(long) read_register (tdep->FPUL_REGNUM));
for (i = 0; i < 16; i = i + 4)
printf_filtered ("\nR%d-R%d %08lx %08lx %08lx %08lx\n",
i, i + 3,
(long) read_register (i + 0),
(long) read_register (i + 1),
(long) read_register (i + 2),
(long) read_register (i + 3));
printf_filtered ("\n");
for (i = 0; i < 16; i = i + 8)
printf_filtered ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
i, i + 7,
(long) read_register (FP0_REGNUM + i + 0),
(long) read_register (FP0_REGNUM + i + 1),
(long) read_register (FP0_REGNUM + i + 2),
(long) read_register (FP0_REGNUM + i + 3),
(long) read_register (FP0_REGNUM + i + 4),
(long) read_register (FP0_REGNUM + i + 5),
(long) read_register (FP0_REGNUM + i + 6),
(long) read_register (FP0_REGNUM + i + 7));
}
static void
sh64_show_regs (void)
{
if (pc_is_isa32 (get_frame_pc (deprecated_selected_frame)))
sh64_show_media_regs ();
else
sh64_show_compact_regs ();
}
void sh_show_regs_command (char *args, int from_tty)
{
if (sh_show_regs)
(*sh_show_regs)();
}
static int
sh_default_register_byte (int reg_nr)
{
return (reg_nr * 4);
}
static int
sh_sh4_register_byte (int reg_nr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
return (dr_reg_base_num (reg_nr) * 4);
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
return (fv_reg_base_num (reg_nr) * 4);
else
return (reg_nr * 4);
}
static int
sh_sh64_register_byte (int reg_nr)
{
int base_regnum = -1;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
base_regnum = dr_reg_base_num (reg_nr);
else if (reg_nr >= tdep->FPP0_REGNUM
&& reg_nr <= tdep->FPP_LAST_REGNUM)
base_regnum = fpp_reg_base_num (reg_nr);
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
base_regnum = fv_reg_base_num (reg_nr);
else if ((reg_nr >= tdep->R0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM)
&& reg_nr != tdep->FPSCR_C_REGNUM)
base_regnum = sh64_compact_reg_base_num (reg_nr);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
return (base_regnum - FP0_REGNUM + 1) * 4
+ (tdep->TR7_REGNUM + 1) * 8;
if ((reg_nr >= tdep->R0_C_REGNUM
&& reg_nr <= tdep->R_LAST_C_REGNUM))
return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
? base_regnum * 8 + 4
: base_regnum * 8);
if (reg_nr == tdep->PC_C_REGNUM
|| reg_nr == tdep->GBR_C_REGNUM
|| reg_nr == tdep->MACL_C_REGNUM
|| reg_nr == tdep->PR_C_REGNUM)
return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
? base_regnum * 8 + 4
: base_regnum * 8);
if (reg_nr == tdep->MACH_C_REGNUM)
return base_regnum * 8;
if (reg_nr == tdep->T_C_REGNUM)
return base_regnum * 8;
else if (reg_nr >=tdep->FP0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM)
return (base_regnum - FP0_REGNUM) * 4
+ (tdep->TR7_REGNUM + 1) * 8 + 4;
else if (reg_nr == tdep->FPSCR_C_REGNUM)
return (tdep->TR7_REGNUM + 1) * 8;
else if (reg_nr == tdep->FPUL_C_REGNUM)
return ((base_regnum - FP0_REGNUM) * 4 +
(tdep->TR7_REGNUM + 1) * 8 + 4);
else if (reg_nr <= tdep->TR7_REGNUM)
return reg_nr * 8;
else
if (reg_nr == tdep->FPSCR_REGNUM)
return (tdep->FPSCR_REGNUM * 8);
else
return ((tdep->TR7_REGNUM + 1) * 8
+ (reg_nr - FP0_REGNUM + 1) * 4);
}
static int
sh_default_register_raw_size (int reg_nr)
{
return 4;
}
static int
sh_sh4_register_raw_size (int reg_nr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
return 8;
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
return 16;
else
return 4;
}
static int
sh_sh64_register_raw_size (int reg_nr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if ((reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
|| (reg_nr >= tdep->FPP0_REGNUM
&& reg_nr <= tdep->FPP_LAST_REGNUM)
|| (reg_nr >= tdep->DR0_C_REGNUM
&& reg_nr <= tdep->DR_LAST_C_REGNUM)
|| (reg_nr <= tdep->TR7_REGNUM))
return 8;
else if ((reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
|| (reg_nr >= tdep->FV0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM))
return 16;
else
return 4;
}
static int
sh_register_virtual_size (int reg_nr)
{
return 4;
}
static int
sh_sh64_register_virtual_size (int reg_nr)
{
if (reg_nr >= FP0_REGNUM
&& reg_nr <= gdbarch_tdep (current_gdbarch)->FP_LAST_REGNUM)
return 4;
else
return 8;
}
static struct type *
sh_sh3e_register_virtual_type (int reg_nr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if ((reg_nr >= FP0_REGNUM
&& (reg_nr <= tdep->FP_LAST_REGNUM))
|| (reg_nr == tdep->FPUL_REGNUM))
return builtin_type_float;
else
return builtin_type_int;
}
static struct type *
sh_sh4_build_float_register_type (int high)
{
struct type *temp;
temp = create_range_type (NULL, builtin_type_int, 0, high);
return create_array_type (NULL, builtin_type_float, temp);
}
static struct type *
sh_sh4_register_virtual_type (int reg_nr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if ((reg_nr >= FP0_REGNUM
&& (reg_nr <= tdep->FP_LAST_REGNUM))
|| (reg_nr == tdep->FPUL_REGNUM))
return builtin_type_float;
else if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
return builtin_type_double;
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
return sh_sh4_build_float_register_type (3);
else
return builtin_type_int;
}
static struct type *
sh_sh64_register_virtual_type (int reg_nr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if ((reg_nr >= FP0_REGNUM
&& reg_nr <= tdep->FP_LAST_REGNUM)
|| (reg_nr >= tdep->FP0_C_REGNUM
&& reg_nr <= tdep->FP_LAST_C_REGNUM))
return builtin_type_float;
else if ((reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
|| (reg_nr >= tdep->DR0_C_REGNUM
&& reg_nr <= tdep->DR_LAST_C_REGNUM))
return builtin_type_double;
else if (reg_nr >= tdep->FPP0_REGNUM
&& reg_nr <= tdep->FPP_LAST_REGNUM)
return sh_sh4_build_float_register_type (1);
else if ((reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
||(reg_nr >= tdep->FV0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM))
return sh_sh4_build_float_register_type (3);
else if (reg_nr == tdep->FPSCR_REGNUM)
return builtin_type_int;
else if (reg_nr >= tdep->R0_C_REGNUM
&& reg_nr < tdep->FP0_C_REGNUM)
return builtin_type_int;
else
return builtin_type_long_long;
}
static struct type *
sh_default_register_virtual_type (int reg_nr)
{
return builtin_type_int;
}
static void
sh_sh4_register_convert_to_virtual (int regnum, struct type *type,
char *from, char *to)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (regnum >= tdep->DR0_REGNUM
&& regnum <= tdep->DR_LAST_REGNUM)
{
DOUBLEST val;
floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val);
store_floating (to, TYPE_LENGTH (type), val);
}
else
error ("sh_register_convert_to_virtual called with non DR register number");
}
void
sh_sh64_register_convert_to_virtual (int regnum, struct type *type,
char *from, char *to)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
{
memcpy (to, from, REGISTER_RAW_SIZE (regnum));
return;
}
if ((regnum >= tdep->DR0_REGNUM
&& regnum <= tdep->DR_LAST_REGNUM)
|| (regnum >= tdep->DR0_C_REGNUM
&& regnum <= tdep->DR_LAST_C_REGNUM))
{
DOUBLEST val;
floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val);
store_floating(to, TYPE_LENGTH(type), val);
}
else
error("sh_register_convert_to_virtual called with non DR register number");
}
static void
sh_sh4_register_convert_to_raw (struct type *type, int regnum,
const void *from, void *to)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (regnum >= tdep->DR0_REGNUM
&& regnum <= tdep->DR_LAST_REGNUM)
{
DOUBLEST val = extract_floating (from, TYPE_LENGTH(type));
floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to);
}
else
error("sh_register_convert_to_raw called with non DR register number");
}
void
sh_sh64_register_convert_to_raw (struct type *type, int regnum,
const void *from, void *to)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
{
memcpy (to, from, REGISTER_RAW_SIZE (regnum));
return;
}
if ((regnum >= tdep->DR0_REGNUM
&& regnum <= tdep->DR_LAST_REGNUM)
|| (regnum >= tdep->DR0_C_REGNUM
&& regnum <= tdep->DR_LAST_C_REGNUM))
{
DOUBLEST val = extract_floating (from, TYPE_LENGTH(type));
floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to);
}
else
error("sh_register_convert_to_raw called with non DR register number");
}
void
sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, void *buffer)
{
int base_regnum, portion;
char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
{
base_regnum = dr_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
regcache_raw_read (regcache, base_regnum + portion,
(temp_buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
sh_sh4_register_convert_to_virtual (reg_nr,
REGISTER_VIRTUAL_TYPE (reg_nr),
temp_buffer, buffer);
}
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
{
base_regnum = fv_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
regcache_raw_read (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
}
static void
sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, void *buffer)
{
int base_regnum;
int portion;
int offset = 0;
char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
{
base_regnum = dr_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
regcache_raw_read (regcache, base_regnum + portion,
(temp_buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
sh_sh64_register_convert_to_virtual (reg_nr, REGISTER_VIRTUAL_TYPE (reg_nr),
temp_buffer, buffer);
}
else if (reg_nr >= tdep->FPP0_REGNUM
&& reg_nr <= tdep->FPP_LAST_REGNUM)
{
base_regnum = fpp_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
regcache_raw_read (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
{
base_regnum = fv_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
regcache_raw_read (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr >= tdep->R0_C_REGNUM
&& reg_nr <= tdep->T_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
regcache_raw_read (regcache, base_regnum, temp_buffer);
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = 4;
memcpy (buffer, temp_buffer + offset, 4);
}
else if (reg_nr >= tdep->FP0_C_REGNUM
&& reg_nr <= tdep->FP_LAST_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
regcache_raw_read (regcache, base_regnum, buffer);
}
else if (reg_nr >= tdep->DR0_C_REGNUM
&& reg_nr <= tdep->DR_LAST_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
regcache_raw_read (regcache, base_regnum + portion,
(temp_buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
sh_sh64_register_convert_to_virtual (reg_nr, REGISTER_VIRTUAL_TYPE (reg_nr),
temp_buffer, buffer);
}
else if (reg_nr >= tdep->FV0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
regcache_raw_read (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr == tdep->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 = tdep->FPSCR_REGNUM;
sr_base_regnum = tdep->SR_REGNUM;
regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
fpscr_value = extract_unsigned_integer (temp_buffer, 4);
regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
sr_value = extract_unsigned_integer (temp_buffer, 4);
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, fpscr_c_value);
}
else if (reg_nr == tdep->FPUL_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
regcache_raw_read (regcache, base_regnum, buffer);
}
}
void
sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const void *buffer)
{
int base_regnum, portion;
char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
{
base_regnum = dr_reg_base_num (reg_nr);
sh_sh4_register_convert_to_raw (REGISTER_VIRTUAL_TYPE (reg_nr), reg_nr,
buffer, temp_buffer);
for (portion = 0; portion < 2; portion++)
regcache_raw_write (regcache, base_regnum + portion,
(temp_buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
{
base_regnum = fv_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
regcache_raw_write (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
}
void
sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const void *buffer)
{
int base_regnum, portion;
int offset;
char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->DR0_REGNUM
&& reg_nr <= tdep->DR_LAST_REGNUM)
{
base_regnum = dr_reg_base_num (reg_nr);
sh_sh64_register_convert_to_raw (REGISTER_VIRTUAL_TYPE (reg_nr), reg_nr,
buffer, temp_buffer);
for (portion = 0; portion < 2; portion++)
regcache_raw_write (regcache, base_regnum + portion,
(temp_buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr >= tdep->FPP0_REGNUM
&& reg_nr <= tdep->FPP_LAST_REGNUM)
{
base_regnum = fpp_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
regcache_raw_write (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr >= tdep->FV0_REGNUM
&& reg_nr <= tdep->FV_LAST_REGNUM)
{
base_regnum = fv_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
regcache_raw_write (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
else if (reg_nr >= tdep->R0_C_REGNUM
&& reg_nr <= tdep->T_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
if (TARGET_BYTE_ORDER == 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 >= tdep->FP0_C_REGNUM
&& reg_nr <= tdep->FP_LAST_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
regcache_raw_write (regcache, base_regnum, buffer);
}
else if (reg_nr >= tdep->DR0_C_REGNUM
&& reg_nr <= tdep->DR_LAST_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
{
sh_sh64_register_convert_to_raw (REGISTER_VIRTUAL_TYPE (reg_nr), reg_nr,
buffer, temp_buffer);
regcache_raw_write (regcache, base_regnum + portion,
(temp_buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
}
else if (reg_nr >= tdep->FV0_C_REGNUM
&& reg_nr <= tdep->FV_LAST_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
{
regcache_raw_write (regcache, base_regnum + portion,
((char *) buffer
+ REGISTER_RAW_SIZE (base_regnum) * portion));
}
}
else if (reg_nr == tdep->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 = tdep->FPSCR_REGNUM;
sr_base_regnum = tdep->SR_REGNUM;
fpscr_c_value = extract_unsigned_integer (buffer, 4);
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);
old_fpscr_value &= 0xfffc0002;
fpscr_value |= old_fpscr_value;
store_unsigned_integer (temp_buffer, 4, 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);
old_sr_value &= 0xffff8fff;
sr_value |= old_sr_value;
store_unsigned_integer (temp_buffer, 4, sr_value);
regcache_raw_write (regcache, sr_base_regnum, temp_buffer);
}
else if (reg_nr == tdep->FPUL_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (reg_nr);
regcache_raw_write (regcache, base_regnum, buffer);
}
}
static void
do_fv_register_info (int fv_regnum)
{
int first_fp_reg_num = fv_reg_base_num (fv_regnum);
printf_filtered ("fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
fv_regnum - gdbarch_tdep (current_gdbarch)->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));
}
static void
do_fv_c_register_info (int fv_regnum)
{
int first_fp_reg_num = sh64_compact_reg_base_num (fv_regnum);
printf_filtered ("fv%d_c\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_C_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));
}
static void
do_fpp_register_info (int fpp_regnum)
{
int first_fp_reg_num = fpp_reg_base_num (fpp_regnum);
printf_filtered ("fpp%d\t0x%08x\t0x%08x\n",
fpp_regnum - gdbarch_tdep (current_gdbarch)->FPP0_REGNUM,
(int) read_register (first_fp_reg_num),
(int) read_register (first_fp_reg_num + 1));
}
static void
do_dr_register_info (int dr_regnum)
{
int first_fp_reg_num = dr_reg_base_num (dr_regnum);
printf_filtered ("dr%d\t0x%08x%08x\n",
dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM,
(int) read_register (first_fp_reg_num),
(int) read_register (first_fp_reg_num + 1));
}
static void
do_dr_c_register_info (int dr_regnum)
{
int first_fp_reg_num = sh64_compact_reg_base_num (dr_regnum);
printf_filtered ("dr%d_c\t0x%08x%08x\n",
dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_C_REGNUM,
(int) read_register (first_fp_reg_num),
(int) read_register (first_fp_reg_num +1));
}
static void
do_r_c_register_info (int r_c_regnum)
{
int regnum = sh64_compact_reg_base_num (r_c_regnum);
printf_filtered ("r%d_c\t0x%08x\n",
r_c_regnum - gdbarch_tdep (current_gdbarch)->R0_C_REGNUM,
(int) read_register (regnum));
}
static void
do_cr_c_register_info (int cr_c_regnum)
{
switch (cr_c_regnum)
{
case 237: printf_filtered ("pc_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 238: printf_filtered ("gbr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 239: printf_filtered ("mach_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 240: printf_filtered ("macl_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 241: printf_filtered ("pr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 242: printf_filtered ("t_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 243: printf_filtered ("fpscr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
break;
case 244: printf_filtered ("fpul_c\t0x%08x\n", (int)read_register (cr_c_regnum));
break;
}
}
static void
sh_do_pseudo_register (int regnum)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
internal_error (__FILE__, __LINE__,
"Invalid pseudo register number %d\n", regnum);
else if (regnum >= tdep->DR0_REGNUM
&& regnum < tdep->DR_LAST_REGNUM)
do_dr_register_info (regnum);
else if (regnum >= tdep->FV0_REGNUM
&& regnum <= tdep->FV_LAST_REGNUM)
do_fv_register_info (regnum);
}
static void
sh_do_fp_register (int regnum)
{
char *raw_buffer;
double flt;
int inv;
int j;
raw_buffer = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
flt = unpack_double (builtin_type_float, raw_buffer, &inv);
fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), gdb_stdout);
if (inv)
printf_filtered ("<invalid float>");
else
printf_filtered ("%-10.9g", flt);
printf_filtered ("\t(raw 0x");
for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
{
register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
: REGISTER_RAW_SIZE (regnum) - 1 - j;
printf_filtered ("%02x", (unsigned char) raw_buffer[idx]);
}
printf_filtered (")");
printf_filtered ("\n");
}
static void
sh64_do_pseudo_register (int regnum)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (regnum < NUM_REGS
|| regnum >= NUM_REGS + NUM_PSEUDO_REGS_SH_MEDIA + NUM_PSEUDO_REGS_SH_COMPACT)
internal_error (__FILE__, __LINE__,
"Invalid pseudo register number %d\n", regnum);
else if ((regnum >= tdep->DR0_REGNUM
&& regnum <= tdep->DR_LAST_REGNUM))
do_dr_register_info (regnum);
else if ((regnum >= tdep->DR0_C_REGNUM
&& regnum <= tdep->DR_LAST_C_REGNUM))
do_dr_c_register_info (regnum);
else if ((regnum >= tdep->FV0_REGNUM
&& regnum <= tdep->FV_LAST_REGNUM))
do_fv_register_info (regnum);
else if ((regnum >= tdep->FV0_C_REGNUM
&& regnum <= tdep->FV_LAST_C_REGNUM))
do_fv_c_register_info (regnum);
else if (regnum >= tdep->FPP0_REGNUM
&& regnum <= tdep->FPP_LAST_REGNUM)
do_fpp_register_info (regnum);
else if (regnum >= tdep->R0_C_REGNUM
&& regnum <= tdep->R_LAST_C_REGNUM)
do_r_c_register_info (regnum);
else if (regnum >= tdep->FP0_C_REGNUM
&& regnum <= tdep->FP_LAST_C_REGNUM)
sh_do_fp_register (regnum);
else if (regnum >= tdep->PC_C_REGNUM
&& regnum <= tdep->FPUL_C_REGNUM)
do_cr_c_register_info (regnum);
}
static void
sh_do_register (int regnum)
{
char raw_buffer[MAX_REGISTER_RAW_SIZE];
fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), gdb_stdout);
if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
printf_filtered ("*value not available*\n");
val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
gdb_stdout, 'x', 1, 0, Val_pretty_default);
printf_filtered ("\t");
val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
printf_filtered ("\n");
}
static void
sh_print_register (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 (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
sh_do_fp_register (regnum);
else
sh_do_register (regnum);
}
else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
do_pseudo_register (regnum);
}
void
sh_do_registers_info (int regnum, int fpregs)
{
if (regnum != -1)
{
if (*(REGISTER_NAME (regnum)) == '\0')
error ("Not a valid register for the current processor type");
sh_print_register (regnum);
}
else
{
regnum = 0;
while (regnum < NUM_REGS)
{
if (REGISTER_NAME (regnum) == NULL
|| *(REGISTER_NAME (regnum)) == '\0')
{
regnum++;
continue;
}
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
{
if (fpregs)
{
sh_do_fp_register (regnum);
regnum ++;
}
else
regnum += (gdbarch_tdep (current_gdbarch)->FP_LAST_REGNUM - FP0_REGNUM);
}
else
{
sh_do_register (regnum);
regnum++;
}
}
if (fpregs)
while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
do_pseudo_register (regnum);
regnum++;
}
}
}
void
sh_compact_do_registers_info (int regnum, int fpregs)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (regnum != -1)
{
if (*(REGISTER_NAME (regnum)) == '\0')
error ("Not a valid register for the current processor type");
if (regnum >= 0 && regnum < tdep->R0_C_REGNUM)
error ("Not a valid register for the current processor mode.");
sh_print_register (regnum);
}
else
{
regnum = tdep->R0_C_REGNUM;
while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
do_pseudo_register (regnum);
regnum++;
}
}
}
void
sh64_do_registers_info (int regnum, int fpregs)
{
if (pc_is_isa32 (get_frame_pc (deprecated_selected_frame)))
sh_do_registers_info (regnum, fpregs);
else
sh_compact_do_registers_info (regnum, fpregs);
}
#ifdef SVR4_SHARED_LIBS
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;
lmo.r_map_offset = 4;
lmo.r_map_size = 4;
lmo.link_map_size = 20;
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
enum
{
DSP_DSR_REGNUM = 24,
DSP_A0G_REGNUM,
DSP_A0_REGNUM,
DSP_A1G_REGNUM,
DSP_A1_REGNUM,
DSP_M0_REGNUM,
DSP_M1_REGNUM,
DSP_X0_REGNUM,
DSP_X1_REGNUM,
DSP_Y0_REGNUM,
DSP_Y1_REGNUM,
DSP_MOD_REGNUM = 40,
DSP_RS_REGNUM = 43,
DSP_RE_REGNUM,
DSP_R0_BANK_REGNUM = 51,
DSP_R7_BANK_REGNUM = DSP_R0_BANK_REGNUM + 7
};
static int
sh_dsp_register_sim_regno (int nr)
{
if (legacy_register_sim_regno (nr) < 0)
return legacy_register_sim_regno (nr);
if (nr >= DSP_DSR_REGNUM && nr < DSP_Y1_REGNUM)
return nr - DSP_DSR_REGNUM + SIM_SH_DSR_REGNUM;
if (nr == DSP_MOD_REGNUM)
return SIM_SH_MOD_REGNUM;
if (nr == DSP_RS_REGNUM)
return SIM_SH_RS_REGNUM;
if (nr == DSP_RE_REGNUM)
return SIM_SH_RE_REGNUM;
if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM)
return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
return nr;
}
static gdbarch_init_ftype sh_gdbarch_init;
static struct gdbarch *
sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
static LONGEST sh_call_dummy_words[] = {0};
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
gdbarch_register_name_ftype *sh_register_name;
gdbarch_deprecated_store_return_value_ftype *sh_store_return_value;
gdbarch_register_virtual_type_ftype *sh_register_virtual_type;
arches = gdbarch_list_lookup_by_info (arches, &info);
if (arches != NULL)
return arches->gdbarch;
tdep = XMALLOC (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
tdep->FPUL_REGNUM = -1;
tdep->FPSCR_REGNUM = -1;
tdep->PR_REGNUM = 17;
tdep->SR_REGNUM = 22;
tdep->DSR_REGNUM = -1;
tdep->FP_LAST_REGNUM = -1;
tdep->A0G_REGNUM = -1;
tdep->A0_REGNUM = -1;
tdep->A1G_REGNUM = -1;
tdep->A1_REGNUM = -1;
tdep->M0_REGNUM = -1;
tdep->M1_REGNUM = -1;
tdep->X0_REGNUM = -1;
tdep->X1_REGNUM = -1;
tdep->Y0_REGNUM = -1;
tdep->Y1_REGNUM = -1;
tdep->MOD_REGNUM = -1;
tdep->RS_REGNUM = -1;
tdep->RE_REGNUM = -1;
tdep->SSR_REGNUM = -1;
tdep->SPC_REGNUM = -1;
tdep->DR0_REGNUM = -1;
tdep->DR_LAST_REGNUM = -1;
tdep->FV0_REGNUM = -1;
tdep->FV_LAST_REGNUM = -1;
tdep->ARG0_REGNUM = 4;
tdep->ARGLAST_REGNUM = 7;
tdep->RETURN_REGNUM = 0;
tdep->FLOAT_ARGLAST_REGNUM = -1;
tdep->sh_abi = SH_ABI_UNKNOWN;
set_gdbarch_fp0_regnum (gdbarch, -1);
set_gdbarch_num_pseudo_regs (gdbarch, 0);
set_gdbarch_max_register_raw_size (gdbarch, 4);
set_gdbarch_max_register_virtual_size (gdbarch, 4);
set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_num_regs (gdbarch, SH_DEFAULT_NUM_REGS);
set_gdbarch_sp_regnum (gdbarch, 15);
set_gdbarch_fp_regnum (gdbarch, 14);
set_gdbarch_pc_regnum (gdbarch, 16);
set_gdbarch_register_size (gdbarch, 4);
set_gdbarch_register_bytes (gdbarch, SH_DEFAULT_NUM_REGS * 4);
set_gdbarch_deprecated_do_registers_info (gdbarch, sh_do_registers_info);
set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
set_gdbarch_frame_chain (gdbarch, sh_frame_chain);
set_gdbarch_get_saved_register (gdbarch, deprecated_generic_get_saved_register);
set_gdbarch_init_extra_frame_info (gdbarch, sh_init_extra_frame_info);
set_gdbarch_deprecated_extract_return_value (gdbarch, sh_extract_return_value);
set_gdbarch_push_arguments (gdbarch, sh_push_arguments);
set_gdbarch_store_struct_return (gdbarch, sh_store_struct_return);
set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention);
set_gdbarch_deprecated_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
set_gdbarch_pop_frame (gdbarch, sh_pop_frame);
set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
skip_prologue_hard_way = sh_skip_prologue_hard_way;
do_pseudo_register = sh_do_pseudo_register;
switch (info.bfd_arch_info->mach)
{
case bfd_mach_sh:
sh_register_name = sh_sh_register_name;
sh_show_regs = sh_generic_show_regs;
sh_store_return_value = sh_default_store_return_value;
sh_register_virtual_type = sh_default_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
break;
case bfd_mach_sh2:
sh_register_name = sh_sh_register_name;
sh_show_regs = sh_generic_show_regs;
sh_store_return_value = sh_default_store_return_value;
sh_register_virtual_type = sh_default_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
break;
case bfd_mach_sh_dsp:
sh_register_name = sh_sh_dsp_register_name;
sh_show_regs = sh_dsp_show_regs;
sh_store_return_value = sh_default_store_return_value;
sh_register_virtual_type = sh_default_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
tdep->DSR_REGNUM = 24;
tdep->A0G_REGNUM = 25;
tdep->A0_REGNUM = 26;
tdep->A1G_REGNUM = 27;
tdep->A1_REGNUM = 28;
tdep->M0_REGNUM = 29;
tdep->M1_REGNUM = 30;
tdep->X0_REGNUM = 31;
tdep->X1_REGNUM = 32;
tdep->Y0_REGNUM = 33;
tdep->Y1_REGNUM = 34;
tdep->MOD_REGNUM = 40;
tdep->RS_REGNUM = 43;
tdep->RE_REGNUM = 44;
break;
case bfd_mach_sh3:
sh_register_name = sh_sh3_register_name;
sh_show_regs = sh3_show_regs;
sh_store_return_value = sh_default_store_return_value;
sh_register_virtual_type = sh_default_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
tdep->SSR_REGNUM = 41;
tdep->SPC_REGNUM = 42;
break;
case bfd_mach_sh3e:
sh_register_name = sh_sh3e_register_name;
sh_show_regs = sh3e_show_regs;
sh_store_return_value = sh3e_sh4_store_return_value;
sh_register_virtual_type = sh_sh3e_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
set_gdbarch_deprecated_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
set_gdbarch_fp0_regnum (gdbarch, 25);
tdep->FPUL_REGNUM = 23;
tdep->FPSCR_REGNUM = 24;
tdep->FP_LAST_REGNUM = 40;
tdep->SSR_REGNUM = 41;
tdep->SPC_REGNUM = 42;
break;
case bfd_mach_sh3_dsp:
sh_register_name = sh_sh3_dsp_register_name;
sh_show_regs = sh3_dsp_show_regs;
sh_store_return_value = sh_default_store_return_value;
sh_register_virtual_type = sh_default_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
tdep->DSR_REGNUM = 24;
tdep->A0G_REGNUM = 25;
tdep->A0_REGNUM = 26;
tdep->A1G_REGNUM = 27;
tdep->A1_REGNUM = 28;
tdep->M0_REGNUM = 29;
tdep->M1_REGNUM = 30;
tdep->X0_REGNUM = 31;
tdep->X1_REGNUM = 32;
tdep->Y0_REGNUM = 33;
tdep->Y1_REGNUM = 34;
tdep->MOD_REGNUM = 40;
tdep->RS_REGNUM = 43;
tdep->RE_REGNUM = 44;
tdep->SSR_REGNUM = 41;
tdep->SPC_REGNUM = 42;
break;
case bfd_mach_sh4:
sh_register_name = sh_sh4_register_name;
sh_show_regs = sh4_show_regs;
sh_store_return_value = sh3e_sh4_store_return_value;
sh_register_virtual_type = sh_sh4_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
set_gdbarch_deprecated_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
set_gdbarch_fp0_regnum (gdbarch, 25);
set_gdbarch_register_raw_size (gdbarch, sh_sh4_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_sh4_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_sh4_register_byte);
set_gdbarch_num_pseudo_regs (gdbarch, 12);
set_gdbarch_max_register_raw_size (gdbarch, 4 * 4);
set_gdbarch_max_register_virtual_size (gdbarch, 4 * 4);
set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
tdep->FPUL_REGNUM = 23;
tdep->FPSCR_REGNUM = 24;
tdep->FP_LAST_REGNUM = 40;
tdep->SSR_REGNUM = 41;
tdep->SPC_REGNUM = 42;
tdep->DR0_REGNUM = 59;
tdep->DR_LAST_REGNUM = 66;
tdep->FV0_REGNUM = 67;
tdep->FV_LAST_REGNUM = 70;
break;
case bfd_mach_sh5:
tdep->PR_REGNUM = 18;
tdep->SR_REGNUM = 65;
tdep->FPSCR_REGNUM = SIM_SH64_FPCSR_REGNUM;
tdep->FP_LAST_REGNUM = SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS - 1;
tdep->SSR_REGNUM = SIM_SH64_SSR_REGNUM;
tdep->SPC_REGNUM = SIM_SH64_SPC_REGNUM;
tdep->TR7_REGNUM = SIM_SH64_TR0_REGNUM + 7;
tdep->FPP0_REGNUM = 173;
tdep->FPP_LAST_REGNUM = 204;
tdep->DR0_REGNUM = 141;
tdep->DR_LAST_REGNUM = 172;
tdep->FV0_REGNUM = 205;
tdep->FV_LAST_REGNUM = 220;
tdep->R0_C_REGNUM = 221;
tdep->R_LAST_C_REGNUM = 236;
tdep->PC_C_REGNUM = 237;
tdep->GBR_C_REGNUM = 238;
tdep->MACH_C_REGNUM = 239;
tdep->MACL_C_REGNUM = 240;
tdep->PR_C_REGNUM = 241;
tdep->T_C_REGNUM = 242;
tdep->FPSCR_C_REGNUM = 243;
tdep->FPUL_C_REGNUM = 244;
tdep->FP0_C_REGNUM = 245;
tdep->FP_LAST_C_REGNUM = 260;
tdep->DR0_C_REGNUM = 261;
tdep->DR_LAST_C_REGNUM = 268;
tdep->FV0_C_REGNUM = 269;
tdep->FV_LAST_C_REGNUM = 272;
tdep->ARG0_REGNUM = 2;
tdep->ARGLAST_REGNUM = 9;
tdep->RETURN_REGNUM = 2;
tdep->FLOAT_ARGLAST_REGNUM = 11;
set_gdbarch_num_pseudo_regs (gdbarch, NUM_PSEUDO_REGS_SH_MEDIA + NUM_PSEUDO_REGS_SH_COMPACT);
set_gdbarch_fp0_regnum (gdbarch, SIM_SH64_FR0_REGNUM);
set_gdbarch_pc_regnum (gdbarch, 64);
if (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_num_regs (gdbarch, SIM_SH64_NR_REGS);
set_gdbarch_register_size (gdbarch, 8);
set_gdbarch_register_bytes (gdbarch,
((SIM_SH64_NR_FP_REGS + 1) * 4)
+ (SIM_SH64_NR_REGS - SIM_SH64_NR_FP_REGS -1) * 8);
sh_register_name = sh_sh64_register_name;
sh_show_regs = sh64_show_regs;
sh_register_virtual_type = sh_sh64_register_virtual_type;
sh_store_return_value = sh64_store_return_value;
skip_prologue_hard_way = sh64_skip_prologue_hard_way;
do_pseudo_register = sh64_do_pseudo_register;
set_gdbarch_register_raw_size (gdbarch, sh_sh64_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_sh64_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_sh64_register_byte);
set_gdbarch_max_register_raw_size (gdbarch, 4 * 4);
set_gdbarch_max_register_virtual_size (gdbarch, 4 * 4);
set_gdbarch_pseudo_register_read (gdbarch, sh64_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, sh64_pseudo_register_write);
set_gdbarch_deprecated_do_registers_info (gdbarch, sh64_do_registers_info);
set_gdbarch_frame_init_saved_regs (gdbarch, sh64_nofp_frame_init_saved_regs);
set_gdbarch_breakpoint_from_pc (gdbarch, sh_sh64_breakpoint_from_pc);
set_gdbarch_init_extra_frame_info (gdbarch, sh64_init_extra_frame_info);
set_gdbarch_frame_chain (gdbarch, sh64_frame_chain);
set_gdbarch_get_saved_register (gdbarch, sh64_get_saved_register);
set_gdbarch_deprecated_extract_return_value (gdbarch, sh64_extract_return_value);
set_gdbarch_push_arguments (gdbarch, sh64_push_arguments);
set_gdbarch_deprecated_extract_struct_value_address (gdbarch, sh64_extract_struct_value_address);
set_gdbarch_use_struct_convention (gdbarch, sh64_use_struct_convention);
set_gdbarch_pop_frame (gdbarch, sh64_pop_frame);
set_gdbarch_elf_make_msymbol_special (gdbarch,
sh64_elf_make_msymbol_special);
break;
default:
sh_register_name = sh_generic_register_name;
sh_show_regs = sh_generic_show_regs;
sh_store_return_value = sh_default_store_return_value;
sh_register_virtual_type = sh_default_register_virtual_type;
set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
break;
}
set_gdbarch_read_pc (gdbarch, generic_target_read_pc);
set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
set_gdbarch_register_name (gdbarch, sh_register_name);
set_gdbarch_register_virtual_type (gdbarch, sh_register_virtual_type);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_int_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_call_dummy_length (gdbarch, 0);
set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
set_gdbarch_call_dummy_start_offset (gdbarch, 0);
set_gdbarch_call_dummy_words (gdbarch, sh_call_dummy_words);
set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (sh_call_dummy_words));
set_gdbarch_call_dummy_p (gdbarch, 1);
set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
set_gdbarch_push_return_address (gdbarch, sh_push_return_address);
set_gdbarch_deprecated_store_return_value (gdbarch, sh_store_return_value);
set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_decr_pc_after_break (gdbarch, 0);
set_gdbarch_function_start_offset (gdbarch, 0);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
set_gdbarch_frame_saved_pc (gdbarch, sh_frame_saved_pc);
set_gdbarch_saved_pc_after_call (gdbarch, sh_saved_pc_after_call);
set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
gdbarch_init_osabi (info, gdbarch);
return gdbarch;
}
static void
sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (tdep == NULL)
return;
}
void
_initialize_sh_tdep (void)
{
struct cmd_list_element *c;
gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
}