#include "defs.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "dwarf2-frame.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "value.h"
#include "dis-asm.h"
#include "inferior.h"
#include "gdb_string.h"
#include "gdb_assert.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"
static void (*sh_show_regs) (void);
#define SH_NUM_REGS 67
struct sh_frame_cache
{
CORE_ADDR base;
LONGEST sp_offset;
CORE_ADDR pc;
int uses_fp;
CORE_ADDR saved_regs[SH_NUM_REGS];
CORE_ADDR saved_sp;
};
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_sh2e_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",
"", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
};
if (reg_nr < 0)
return NULL;
if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
return NULL;
return register_names[reg_nr];
}
static const char *
sh_sh2a_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",
"", "",
"r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b",
"machb", "ivnb", "prb", "gbrb", "maclb",
"",
"ibcr", "ibnr", "tbr",
"bank",
"dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
};
if (reg_nr < 0)
return NULL;
if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
return NULL;
return register_names[reg_nr];
}
static const char *
sh_sh2a_nofpu_register_name (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",
"", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "",
"r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b",
"machb", "ivnb", "prb", "gbrb", "maclb",
"",
"ibcr", "ibnr", "tbr",
"bank",
"", "", "", "", "", "", "", "",
};
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_sh4_nofpu_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_sh4al_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 unsigned char *
sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
static unsigned char breakpoint[] = { 0xc3, 0xc3 };
*lenptr = sizeof (breakpoint);
return breakpoint;
}
#define GET_SOURCE_REG(x) (((x) >> 4) & 0xf)
#define GET_TARGET_REG(x) (((x) >> 8) & 0xf)
#define IS_JSR(x) (((x) & 0xf0ff) == 0x400b)
#define IS_STS(x) ((x) == 0x4f22)
#define IS_MACL_STS(x) ((x) == 0x4f12)
#define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06)
#define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
#define IS_ADD_IMM_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_FPUSH(x) (((x) & 0xff0f) == 0xff0b)
#define IS_MOV_ARG_TO_REG(x) \
(((x) & 0xf00f) == 0x6003 && \
((x) & 0x00f0) >= 0x0040 && \
((x) & 0x00f0) <= 0x0070)
#define IS_MOV_ARG_TO_IND_R14(x) \
(((x) & 0xff0f) == 0x2e02 && \
((x) & 0x00f0) >= 0x0040 && \
((x) & 0x00f0) <= 0x0070)
#define IS_MOV_ARG_TO_IND_R14_WITH_DISP(x) \
(((x) & 0xff00) == 0x1e00 && \
((x) & 0x00f0) >= 0x0040 && \
((x) & 0x00f0) <= 0x0070)
#define IS_MOVW_PCREL_TO_REG(x) (((x) & 0xf000) == 0x9000)
#define IS_MOVL_PCREL_TO_REG(x) (((x) & 0xf000) == 0xd000)
#define IS_MOVI20(x) (((x) & 0xf00f) == 0x0000)
#define IS_SUB_REG_FROM_SP(x) (((x) & 0xff0f) == 0x3f08)
#define FPSCR_SZ (1 << 20)
#define IS_RESTORE_FP(x) ((x) == 0x6ef6)
#define IS_RTS(x) ((x) == 0x000b)
#define IS_LDS(x) ((x) == 0x4f26)
#define IS_MACL_LDS(x) ((x) == 0x4f16)
#define IS_MOV_FP_SP(x) ((x) == 0x6fe3)
#define IS_ADD_REG_TO_FP(x) (((x) & 0xff0f) == 0x3e0c)
#define IS_ADD_IMM_FP(x) (((x) & 0xff00) == 0x7e00)
static int
gdb_print_insn_sh (bfd_vma memaddr, disassemble_info * info)
{
info->endian = TARGET_BYTE_ORDER;
return print_insn_sh (memaddr, info);
}
static CORE_ADDR
sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
struct sh_frame_cache *cache)
{
ULONGEST inst;
CORE_ADDR opc;
int offset;
int sav_offset = 0;
int r3_val = 0;
int reg, sav_reg = -1;
if (pc >= current_pc)
return current_pc;
cache->uses_fp = 0;
for (opc = pc + (2 * 28); pc < opc; pc += 2)
{
inst = read_memory_unsigned_integer (pc, 2);
if (IS_PUSH (inst))
{
cache->saved_regs[GET_SOURCE_REG (inst)] = cache->sp_offset;
cache->sp_offset += 4;
}
else if (IS_STS (inst))
{
cache->saved_regs[PR_REGNUM] = cache->sp_offset;
cache->sp_offset += 4;
}
else if (IS_MACL_STS (inst))
{
cache->saved_regs[MACL_REGNUM] = cache->sp_offset;
cache->sp_offset += 4;
}
else if (IS_MOV_R3 (inst))
{
r3_val = ((inst & 0xff) ^ 0x80) - 0x80;
}
else if (IS_SHLL_R3 (inst))
{
r3_val <<= 1;
}
else if (IS_ADD_R3SP (inst))
{
cache->sp_offset += -r3_val;
}
else if (IS_ADD_IMM_SP (inst))
{
offset = ((inst & 0xff) ^ 0x80) - 0x80;
cache->sp_offset -= offset;
}
else if (IS_MOVW_PCREL_TO_REG (inst))
{
if (sav_reg < 0)
{
reg = GET_TARGET_REG (inst);
if (reg < 14)
{
sav_reg = reg;
offset = (inst & 0xff) << 1;
sav_offset =
read_memory_integer ((pc + 4) + offset, 2);
}
}
}
else if (IS_MOVL_PCREL_TO_REG (inst))
{
if (sav_reg < 0)
{
reg = GET_TARGET_REG (inst);
if (reg < 14)
{
sav_reg = reg;
offset = (inst & 0xff) << 2;
sav_offset =
read_memory_integer (((pc & 0xfffffffc) + 4) + offset, 4);
}
}
}
else if (IS_MOVI20 (inst))
{
if (sav_reg < 0)
{
reg = GET_TARGET_REG (inst);
if (reg < 14)
{
sav_reg = reg;
sav_offset = GET_SOURCE_REG (inst) << 16;
pc += 2;
sav_offset |= read_memory_unsigned_integer (pc, 2);
if (sav_offset & 0x00080000)
sav_offset |= 0xfff00000;
}
}
}
else if (IS_SUB_REG_FROM_SP (inst))
{
reg = GET_SOURCE_REG (inst);
if (sav_reg > 0 && reg == sav_reg)
{
sav_reg = -1;
}
cache->sp_offset += sav_offset;
}
else if (IS_FPUSH (inst))
{
if (read_register (FPSCR_REGNUM) & FPSCR_SZ)
{
cache->sp_offset += 8;
}
else
{
cache->sp_offset += 4;
}
}
else if (IS_MOV_SP_FP (inst))
{
cache->uses_fp = 1;
pc += 2;
for (opc = pc + 12; pc < opc; pc += 2)
{
inst = read_memory_integer (pc, 2);
if (IS_MOV_ARG_TO_IND_R14 (inst))
{
reg = GET_SOURCE_REG (inst);
if (cache->sp_offset > 0)
cache->saved_regs[reg] = cache->sp_offset;
}
else if (IS_MOV_ARG_TO_IND_R14_WITH_DISP (inst))
{
reg = GET_SOURCE_REG (inst);
offset = (inst & 0xf) * 4;
if (cache->sp_offset > offset)
cache->saved_regs[reg] = cache->sp_offset - offset;
}
else if (IS_MOV_ARG_TO_REG (inst))
continue;
else
break;
}
break;
}
else if (IS_JSR (inst))
{
inst = read_memory_integer (pc + 2, 2);
if (IS_MOV_SP_FP (inst))
cache->uses_fp = 1;
break;
}
#if 0
else
break;
#endif
}
return pc;
}
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 (CORE_ADDR start_pc)
{
CORE_ADDR pc;
struct sh_frame_cache cache;
pc = after_prologue (start_pc);
if (pc)
return max (pc, start_pc);
cache.sp_offset = -4;
pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache);
if (!cache.uses_fp)
return start_pc;
return pc;
}
static int
sh_use_struct_convention (int gcc_p, struct type *type)
{
int len = TYPE_LENGTH (type);
int nelem = TYPE_NFIELDS (type);
if (len != 1 && len != 2 && len != 4 && len != 8)
return 1;
if (nelem <= 1)
return 0;
if (TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == len)
return 0;
if (len == 8 && TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == 4)
return 0;
return 1;
}
static CORE_ADDR
sh_extract_struct_value_address (struct regcache *regcache)
{
ULONGEST addr;
regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
return addr;
}
static CORE_ADDR
sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
{
return sp & ~3;
}
static char *
sh_justify_value_in_reg (struct value *val, int len)
{
static char valbuf[4];
memset (valbuf, 0, sizeof (valbuf));
if (len < 4)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
memcpy (valbuf + (4 - len), (char *) value_contents (val), len);
else
memcpy (valbuf, (char *) value_contents (val), len);
return valbuf;
}
return (char *) value_contents (val);
}
static CORE_ADDR
sh_stack_allocsize (int nargs, struct value **args)
{
int stack_alloc = 0;
while (nargs-- > 0)
stack_alloc += ((TYPE_LENGTH (value_type (args[nargs])) + 3) & ~3);
return stack_alloc;
}
static int flt_argreg_array[FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM + 1];
static void
sh_init_flt_argreg (void)
{
memset (flt_argreg_array, 0, sizeof flt_argreg_array);
}
static int
sh_next_flt_argreg (int len)
{
int argreg;
for (argreg = 0; argreg <= FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM;
++argreg)
if (!flt_argreg_array[argreg])
break;
if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM)
return FLOAT_ARGLAST_REGNUM + 1;
if (len == 8)
{
if (argreg & 1)
{
flt_argreg_array[argreg] = 1;
++argreg;
if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM)
return FLOAT_ARGLAST_REGNUM + 1;
}
flt_argreg_array[argreg + 1] = 1;
}
else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
{
if (!flt_argreg_array[argreg + 1])
++argreg;
}
flt_argreg_array[argreg] = 1;
return FLOAT_ARG0_REGNUM + argreg;
}
static int
sh_treat_as_flt_p (struct type *type)
{
int len = TYPE_LENGTH (type);
if (TYPE_CODE (type) == TYPE_CODE_FLT)
return 1;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
return 0;
if (TYPE_NFIELDS (type) != 1)
return 0;
if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
return 1;
return 0;
}
static CORE_ADDR
sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
struct value *function,
struct regcache *regcache,
CORE_ADDR bp_addr, int nargs,
struct value **args,
CORE_ADDR sp, int struct_return,
CORE_ADDR struct_addr)
{
int stack_offset = 0;
int argreg = ARG0_REGNUM;
int flt_argreg = 0;
int argnum;
struct type *type;
CORE_ADDR regval;
char *val;
int len, reg_size = 0;
int pass_on_stack = 0;
int treat_as_flt;
sp = sh_frame_align (gdbarch, sp);
if (struct_return)
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
sp -= sh_stack_allocsize (nargs, args);
sh_init_flt_argreg ();
for (argnum = 0; argnum < nargs; argnum++)
{
type = value_type (args[argnum]);
len = TYPE_LENGTH (type);
val = sh_justify_value_in_reg (args[argnum], len);
pass_on_stack = 0;
treat_as_flt = sh_treat_as_flt_p (type);
if (treat_as_flt)
flt_argreg = sh_next_flt_argreg (len);
else if (len > ((ARGLAST_REGNUM - argreg + 1) * 4))
pass_on_stack = 1;
while (len > 0)
{
if ((treat_as_flt && flt_argreg > FLOAT_ARGLAST_REGNUM)
|| (!treat_as_flt && (argreg > ARGLAST_REGNUM
|| pass_on_stack)))
{
reg_size = (len + 3) & ~3;
write_memory (sp + stack_offset, val, reg_size);
stack_offset += reg_size;
}
else if (treat_as_flt && flt_argreg <= FLOAT_ARGLAST_REGNUM)
{
reg_size = register_size (gdbarch, flt_argreg);
regval = extract_unsigned_integer (val, reg_size);
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE
&& TYPE_LENGTH (type) == 2 * reg_size)
{
regcache_cooked_write_unsigned (regcache, flt_argreg + 1,
regval);
val += reg_size;
len -= reg_size;
regval = extract_unsigned_integer (val, reg_size);
}
regcache_cooked_write_unsigned (regcache, flt_argreg++, regval);
}
else if (!treat_as_flt && argreg <= ARGLAST_REGNUM)
{
reg_size = register_size (gdbarch, argreg);
regval = extract_unsigned_integer (val, reg_size);
regcache_cooked_write_unsigned (regcache, argreg++, regval);
}
len -= reg_size;
val += reg_size;
}
}
regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp);
return sp;
}
static CORE_ADDR
sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
struct value *function,
struct regcache *regcache,
CORE_ADDR bp_addr,
int nargs, struct value **args,
CORE_ADDR sp, int struct_return,
CORE_ADDR struct_addr)
{
int stack_offset = 0;
int argreg = ARG0_REGNUM;
int argnum;
struct type *type;
CORE_ADDR regval;
char *val;
int len, reg_size;
sp = sh_frame_align (gdbarch, sp);
if (struct_return)
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
sp -= sh_stack_allocsize (nargs, args);
for (argnum = 0; argnum < nargs; argnum++)
{
type = value_type (args[argnum]);
len = TYPE_LENGTH (type);
val = sh_justify_value_in_reg (args[argnum], len);
while (len > 0)
{
if (argreg > ARGLAST_REGNUM)
{
reg_size = (len + 3) & ~3;
write_memory (sp + stack_offset, val, reg_size);
stack_offset += reg_size;
}
else if (argreg <= ARGLAST_REGNUM)
{
reg_size = register_size (gdbarch, argreg);
regval = extract_unsigned_integer (val, reg_size);
regcache_cooked_write_unsigned (regcache, argreg++, regval);
}
len -= reg_size;
val += reg_size;
}
}
regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp);
return sp;
}
static void
sh_extract_return_value_nofpu (struct type *type, struct regcache *regcache,
void *valbuf)
{
int len = TYPE_LENGTH (type);
int return_register = R0_REGNUM;
int offset;
if (len <= 4)
{
ULONGEST c;
regcache_cooked_read_unsigned (regcache, R0_REGNUM, &c);
store_unsigned_integer (valbuf, len, c);
}
else if (len == 8)
{
int i, regnum = R0_REGNUM;
for (i = 0; i < len; i += 4)
regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
}
else
error (_("bad size for return value"));
}
static void
sh_extract_return_value_fpu (struct type *type, struct regcache *regcache,
void *valbuf)
{
if (sh_treat_as_flt_p (type))
{
int len = TYPE_LENGTH (type);
int i, regnum = FP0_REGNUM;
for (i = 0; i < len; i += 4)
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
regcache_raw_read (regcache, regnum++, (char *) valbuf + len - 4 - i);
else
regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
}
else
sh_extract_return_value_nofpu (type, regcache, valbuf);
}
static void
sh_store_return_value_nofpu (struct type *type, struct regcache *regcache,
const void *valbuf)
{
ULONGEST val;
int len = TYPE_LENGTH (type);
if (len <= 4)
{
val = extract_unsigned_integer (valbuf, len);
regcache_cooked_write_unsigned (regcache, R0_REGNUM, val);
}
else
{
int i, regnum = R0_REGNUM;
for (i = 0; i < len; i += 4)
regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
}
}
static void
sh_store_return_value_fpu (struct type *type, struct regcache *regcache,
const void *valbuf)
{
if (sh_treat_as_flt_p (type))
{
int len = TYPE_LENGTH (type);
int i, regnum = FP0_REGNUM;
for (i = 0; i < len; i += 4)
if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
regcache_raw_write (regcache, regnum++,
(char *) valbuf + len - 4 - i);
else
regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
}
else
sh_store_return_value_nofpu (type, regcache, valbuf);
}
static enum return_value_convention
sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache,
void *readbuf, const void *writebuf)
{
if (sh_use_struct_convention (0, type))
return RETURN_VALUE_STRUCT_CONVENTION;
if (writebuf)
sh_store_return_value_nofpu (type, regcache, writebuf);
else if (readbuf)
sh_extract_return_value_nofpu (type, regcache, readbuf);
return RETURN_VALUE_REGISTER_CONVENTION;
}
static enum return_value_convention
sh_return_value_fpu (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache,
void *readbuf, const void *writebuf)
{
if (sh_use_struct_convention (0, type))
return RETURN_VALUE_STRUCT_CONVENTION;
if (writebuf)
sh_store_return_value_fpu (type, regcache, writebuf);
else if (readbuf)
sh_extract_return_value_fpu (type, regcache, readbuf);
return RETURN_VALUE_REGISTER_CONVENTION;
}
static void
sh_generic_show_regs (void)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered
("\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)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" SSR=%08lx SPC=%08lx",
(long) read_register (SSR_REGNUM),
(long) read_register (SPC_REGNUM));
printf_filtered
("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (0), (long) read_register (1),
(long) read_register (2), (long) read_register (3),
(long) read_register (4), (long) read_register (5),
(long) read_register (6), (long) read_register (7));
printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (8), (long) read_register (9),
(long) read_register (10), (long) read_register (11),
(long) read_register (12), (long) read_register (13),
(long) read_register (14), (long) read_register (15));
}
static void
sh2e_show_regs (void)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx",
(long) read_register (FPUL_REGNUM),
(long) read_register (FPSCR_REGNUM));
printf_filtered
("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (0), (long) read_register (1),
(long) read_register (2), (long) read_register (3),
(long) read_register (4), (long) read_register (5),
(long) read_register (6), (long) read_register (7));
printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (8), (long) read_register (9),
(long) read_register (10), (long) read_register (11),
(long) read_register (12), (long) read_register (13),
(long) read_register (14), (long) read_register (15));
printf_filtered (("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7));
printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15));
}
static void
sh2a_show_regs (void)
{
int pr = read_register (FPSCR_REGNUM) & 0x80000;
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx TBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM),
(long) read_register (TBR_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx\n",
(long) read_register (FPUL_REGNUM),
(long) read_register (FPSCR_REGNUM));
printf_filtered ("R0-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));
printf_filtered ("BANK=%-3d\n", (int) read_register (BANK_REGNUM));
printf_filtered ("R0b - R7b %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (R0_BANK0_REGNUM + 0),
(long) read_register (R0_BANK0_REGNUM + 1),
(long) read_register (R0_BANK0_REGNUM + 2),
(long) read_register (R0_BANK0_REGNUM + 3),
(long) read_register (R0_BANK0_REGNUM + 4),
(long) read_register (R0_BANK0_REGNUM + 5),
(long) read_register (R0_BANK0_REGNUM + 6),
(long) read_register (R0_BANK0_REGNUM + 7));
printf_filtered ("R8b - R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (R0_BANK0_REGNUM + 8),
(long) read_register (R0_BANK0_REGNUM + 9),
(long) read_register (R0_BANK0_REGNUM + 10),
(long) read_register (R0_BANK0_REGNUM + 11),
(long) read_register (R0_BANK0_REGNUM + 12),
(long) read_register (R0_BANK0_REGNUM + 13),
(long) read_register (R0_BANK0_REGNUM + 14));
printf_filtered ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n",
(long) read_register (R0_BANK0_REGNUM + 15),
(long) read_register (R0_BANK0_REGNUM + 16),
(long) read_register (R0_BANK0_REGNUM + 17),
(long) read_register (R0_BANK0_REGNUM + 18),
(long) read_register (R0_BANK0_REGNUM + 19));
}
static void
sh2a_nofpu_show_regs (void)
{
int pr = read_register (FPSCR_REGNUM) & 0x80000;
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx TBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM),
(long) read_register (TBR_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx\n",
(long) read_register (FPUL_REGNUM),
(long) read_register (FPSCR_REGNUM));
printf_filtered ("R0-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 ("BANK=%-3d\n", (int) read_register (BANK_REGNUM));
printf_filtered ("R0b - R7b %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (R0_BANK0_REGNUM + 0),
(long) read_register (R0_BANK0_REGNUM + 1),
(long) read_register (R0_BANK0_REGNUM + 2),
(long) read_register (R0_BANK0_REGNUM + 3),
(long) read_register (R0_BANK0_REGNUM + 4),
(long) read_register (R0_BANK0_REGNUM + 5),
(long) read_register (R0_BANK0_REGNUM + 6),
(long) read_register (R0_BANK0_REGNUM + 7));
printf_filtered ("R8b - R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (R0_BANK0_REGNUM + 8),
(long) read_register (R0_BANK0_REGNUM + 9),
(long) read_register (R0_BANK0_REGNUM + 10),
(long) read_register (R0_BANK0_REGNUM + 11),
(long) read_register (R0_BANK0_REGNUM + 12),
(long) read_register (R0_BANK0_REGNUM + 13),
(long) read_register (R0_BANK0_REGNUM + 14));
printf_filtered ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n",
(long) read_register (R0_BANK0_REGNUM + 15),
(long) read_register (R0_BANK0_REGNUM + 16),
(long) read_register (R0_BANK0_REGNUM + 17),
(long) read_register (R0_BANK0_REGNUM + 18),
(long) read_register (R0_BANK0_REGNUM + 19));
}
static void
sh3e_show_regs (void)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" SSR=%08lx SPC=%08lx",
(long) read_register (SSR_REGNUM),
(long) read_register (SPC_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx",
(long) read_register (FPUL_REGNUM),
(long) read_register (FPSCR_REGNUM));
printf_filtered
("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (0), (long) read_register (1),
(long) read_register (2), (long) read_register (3),
(long) read_register (4), (long) read_register (5),
(long) read_register (6), (long) read_register (7));
printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (8), (long) read_register (9),
(long) read_register (10), (long) read_register (11),
(long) read_register (12), (long) read_register (13),
(long) read_register (14), (long) read_register (15));
printf_filtered (("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7));
printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15));
}
static void
sh3_dsp_show_regs (void)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" SSR=%08lx SPC=%08lx",
(long) read_register (SSR_REGNUM),
(long) read_register (SPC_REGNUM));
printf_filtered (" DSR=%08lx", (long) read_register (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 (A0G_REGNUM) & 0xff,
(long) read_register (A0_REGNUM), (long) read_register (M0_REGNUM),
(long) read_register (X0_REGNUM), (long) read_register (Y0_REGNUM),
(long) read_register (RS_REGNUM), (long) read_register (MOD_REGNUM));
printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
(long) read_register (A1G_REGNUM) & 0xff,
(long) read_register (A1_REGNUM),
(long) read_register (M1_REGNUM),
(long) read_register (X1_REGNUM),
(long) read_register (Y1_REGNUM),
(long) read_register (RE_REGNUM));
}
static void
sh4_show_regs (void)
{
int pr = read_register (FPSCR_REGNUM) & 0x80000;
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" SSR=%08lx SPC=%08lx",
(long) read_register (SSR_REGNUM),
(long) read_register (SPC_REGNUM));
printf_filtered (" FPUL=%08lx FPSCR=%08lx",
(long) read_register (FPUL_REGNUM),
(long) read_register (FPSCR_REGNUM));
printf_filtered
("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (0), (long) read_register (1),
(long) read_register (2), (long) read_register (3),
(long) read_register (4), (long) read_register (5),
(long) read_register (6), (long) read_register (7));
printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (8), (long) read_register (9),
(long) read_register (10), (long) read_register (11),
(long) read_register (12), (long) read_register (13),
(long) read_register (14), (long) read_register (15));
printf_filtered ((pr
? "DR0-DR6 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n"
:
"FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
(long) read_register (FP0_REGNUM + 0),
(long) read_register (FP0_REGNUM + 1),
(long) read_register (FP0_REGNUM + 2),
(long) read_register (FP0_REGNUM + 3),
(long) read_register (FP0_REGNUM + 4),
(long) read_register (FP0_REGNUM + 5),
(long) read_register (FP0_REGNUM + 6),
(long) read_register (FP0_REGNUM + 7));
printf_filtered ((pr ?
"DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" :
"FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
(long) read_register (FP0_REGNUM + 8),
(long) read_register (FP0_REGNUM + 9),
(long) read_register (FP0_REGNUM + 10),
(long) read_register (FP0_REGNUM + 11),
(long) read_register (FP0_REGNUM + 12),
(long) read_register (FP0_REGNUM + 13),
(long) read_register (FP0_REGNUM + 14),
(long) read_register (FP0_REGNUM + 15));
}
static void
sh4_nofpu_show_regs (void)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" SSR=%08lx SPC=%08lx",
(long) read_register (SSR_REGNUM),
(long) read_register (SPC_REGNUM));
printf_filtered
("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (0), (long) read_register (1),
(long) read_register (2), (long) read_register (3),
(long) read_register (4), (long) read_register (5),
(long) read_register (6), (long) read_register (7));
printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
(long) read_register (8), (long) read_register (9),
(long) read_register (10), (long) read_register (11),
(long) read_register (12), (long) read_register (13),
(long) read_register (14), (long) read_register (15));
}
static void
sh_dsp_show_regs (void)
{
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (SR_REGNUM),
(long) read_register (PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("GBR=%08lx VBR=%08lx",
(long) read_register (GBR_REGNUM),
(long) read_register (VBR_REGNUM));
printf_filtered (" DSR=%08lx", (long) read_register (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 (A0G_REGNUM) & 0xff,
(long) read_register (A0_REGNUM), (long) read_register (M0_REGNUM),
(long) read_register (X0_REGNUM), (long) read_register (Y0_REGNUM),
(long) read_register (RS_REGNUM), (long) read_register (MOD_REGNUM));
printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
(long) read_register (A1G_REGNUM) & 0xff,
(long) read_register (A1_REGNUM),
(long) read_register (M1_REGNUM),
(long) read_register (X1_REGNUM),
(long) read_register (Y1_REGNUM),
(long) read_register (RE_REGNUM));
}
static void
sh_show_regs_command (char *args, int from_tty)
{
if (sh_show_regs)
(*sh_show_regs) ();
}
static struct type *
sh_sh2a_register_type (struct gdbarch *gdbarch, int reg_nr)
{
if ((reg_nr >= FP0_REGNUM
&& (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
return builtin_type_float;
else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
return builtin_type_double;
else
return builtin_type_int;
}
static struct type *
sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr)
{
if ((reg_nr >= FP0_REGNUM
&& (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == 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_type (struct gdbarch *gdbarch, int reg_nr)
{
if ((reg_nr >= FP0_REGNUM
&& (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
return builtin_type_float;
else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
return builtin_type_double;
else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
return sh_sh4_build_float_register_type (3);
else
return builtin_type_int;
}
static struct type *
sh_default_register_type (struct gdbarch *gdbarch, int reg_nr)
{
return builtin_type_int;
}
static void
sh_register_convert_to_virtual (int regnum, struct type *type,
char *from, char *to)
{
if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
{
DOUBLEST val;
floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
from, &val);
store_typed_floating (to, type, val);
}
else
error
("sh_register_convert_to_virtual called with non DR register number");
}
static void
sh_register_convert_to_raw (struct type *type, int regnum,
const void *from, void *to)
{
if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
{
DOUBLEST val = extract_typed_floating (from, type);
floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword,
&val, to);
}
else
error (_("sh_register_convert_to_raw called with non DR register number"));
}
static int
fv_reg_base_num (int fv_regnum)
{
int fp_regnum;
fp_regnum = FP0_REGNUM + (fv_regnum - FV0_REGNUM) * 4;
return fp_regnum;
}
static int
dr_reg_base_num (int dr_regnum)
{
int fp_regnum;
fp_regnum = FP0_REGNUM + (dr_regnum - DR0_REGNUM) * 2;
return fp_regnum;
}
static void
sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, void *buffer)
{
int base_regnum, portion;
char temp_buffer[MAX_REGISTER_SIZE];
if (reg_nr == PSEUDO_BANK_REGNUM)
regcache_raw_read (regcache, BANK_REGNUM, buffer);
else
if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
{
base_regnum = dr_reg_base_num (reg_nr);
for (portion = 0; portion < 2; portion++)
regcache_raw_read (regcache, base_regnum + portion,
(temp_buffer
+ register_size (gdbarch,
base_regnum) * portion));
sh_register_convert_to_virtual (reg_nr,
gdbarch_register_type (gdbarch, reg_nr),
temp_buffer, buffer);
}
else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
{
base_regnum = fv_reg_base_num (reg_nr);
for (portion = 0; portion < 4; portion++)
regcache_raw_read (regcache, base_regnum + portion,
((char *) buffer
+ register_size (gdbarch,
base_regnum) * portion));
}
}
static void
sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const void *buffer)
{
int base_regnum, portion;
char temp_buffer[MAX_REGISTER_SIZE];
if (reg_nr == PSEUDO_BANK_REGNUM)
{
int bregnum;
regcache_raw_write (regcache, BANK_REGNUM, buffer);
for (bregnum = R0_BANK0_REGNUM; bregnum < MACLB_REGNUM; ++bregnum)
set_register_cached (bregnum, 0);
}
else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
{
base_regnum = dr_reg_base_num (reg_nr);
sh_register_convert_to_raw (gdbarch_register_type (gdbarch, reg_nr),
reg_nr, buffer, temp_buffer);
for (portion = 0; portion < 2; portion++)
regcache_raw_write (regcache, base_regnum + portion,
(temp_buffer
+ register_size (gdbarch,
base_regnum) * portion));
}
else if (reg_nr >= FV0_REGNUM && reg_nr <= 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_size (gdbarch,
base_regnum) * portion));
}
}
static void
do_fv_register_info (struct gdbarch *gdbarch, struct ui_file *file,
int fv_regnum)
{
int first_fp_reg_num = fv_reg_base_num (fv_regnum);
fprintf_filtered (file, "fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
fv_regnum - FV0_REGNUM,
(int) read_register (first_fp_reg_num),
(int) read_register (first_fp_reg_num + 1),
(int) read_register (first_fp_reg_num + 2),
(int) read_register (first_fp_reg_num + 3));
}
static void
do_dr_register_info (struct gdbarch *gdbarch, struct ui_file *file,
int dr_regnum)
{
int first_fp_reg_num = dr_reg_base_num (dr_regnum);
fprintf_filtered (file, "dr%d\t0x%08x%08x\n",
dr_regnum - DR0_REGNUM,
(int) read_register (first_fp_reg_num),
(int) read_register (first_fp_reg_num + 1));
}
static void
do_bank_register_info (struct gdbarch *gdbarch, struct ui_file *file)
{
fprintf_filtered (file, "bank %d\n",
(int) read_register (BANK_REGNUM));
}
static void
sh_print_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file,
int regnum)
{
if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
internal_error (__FILE__, __LINE__,
_("Invalid pseudo register number %d\n"), regnum);
else if (regnum == PSEUDO_BANK_REGNUM)
do_bank_register_info (gdbarch, file);
else if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
do_dr_register_info (gdbarch, file, regnum);
else if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM)
do_fv_register_info (gdbarch, file, regnum);
}
static void
sh_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
{
char *raw_buffer;
double flt;
int inv;
int j;
raw_buffer = (char *) alloca (register_size (gdbarch, FP0_REGNUM));
if (!frame_register_read (get_selected_frame (NULL), 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), file);
print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
if (inv)
fprintf_filtered (file, "<invalid float>");
else
fprintf_filtered (file, "%-10.9g", flt);
fprintf_filtered (file, "\t(raw 0x");
for (j = 0; j < register_size (gdbarch, regnum); j++)
{
int idx = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
? j
: register_size (gdbarch, regnum) - 1 - j);
fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]);
}
fprintf_filtered (file, ")");
fprintf_filtered (file, "\n");
}
static void
sh_do_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
{
char raw_buffer[MAX_REGISTER_SIZE];
fputs_filtered (REGISTER_NAME (regnum), file);
print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
if (!frame_register_read (get_selected_frame (NULL), regnum, raw_buffer))
fprintf_filtered (file, "*value not available*\n");
val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
file, 'x', 1, 0, Val_pretty_default);
fprintf_filtered (file, "\t");
val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
file, 0, 1, 0, Val_pretty_default);
fprintf_filtered (file, "\n");
}
static void
sh_print_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
{
if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
internal_error (__FILE__, __LINE__,
_("Invalid register number %d\n"), regnum);
else if (regnum >= 0 && regnum < NUM_REGS)
{
if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
sh_do_fp_register (gdbarch, file, regnum);
else
sh_do_register (gdbarch, file, regnum);
}
else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
sh_print_pseudo_register (gdbarch, file, regnum);
}
}
static void
sh_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
struct frame_info *frame, int regnum, int fpregs)
{
if (regnum != -1)
{
if (*(REGISTER_NAME (regnum)) == '\0')
error (_("Not a valid register for the current processor type"));
sh_print_register (gdbarch, file, regnum);
}
else
{
for (regnum = 0; regnum < NUM_REGS; ++regnum)
{
if (REGISTER_NAME (regnum) == NULL
|| *(REGISTER_NAME (regnum)) == '\0')
continue;
if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
{
if (fpregs)
sh_do_fp_register (gdbarch, file, regnum);
}
else
sh_do_register (gdbarch, file, regnum);
}
if (regnum == PSEUDO_BANK_REGNUM
&& REGISTER_NAME (regnum)
&& *REGISTER_NAME (regnum))
sh_print_pseudo_register (gdbarch, file, regnum++);
if (fpregs)
while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
sh_print_pseudo_register (gdbarch, file, regnum);
regnum++;
}
}
}
static int
sh_dsp_register_sim_regno (int nr)
{
if (legacy_register_sim_regno (nr) < 0)
return legacy_register_sim_regno (nr);
if (nr >= DSR_REGNUM && nr <= Y1_REGNUM)
return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM;
if (nr == MOD_REGNUM)
return SIM_SH_MOD_REGNUM;
if (nr == RS_REGNUM)
return SIM_SH_RS_REGNUM;
if (nr == RE_REGNUM)
return SIM_SH_RE_REGNUM;
if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM)
return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
return nr;
}
static int
sh_sh2a_register_sim_regno (int nr)
{
switch (nr)
{
case TBR_REGNUM:
return SIM_SH_TBR_REGNUM;
case IBNR_REGNUM:
return SIM_SH_IBNR_REGNUM;
case IBCR_REGNUM:
return SIM_SH_IBCR_REGNUM;
case BANK_REGNUM:
return SIM_SH_BANK_REGNUM;
case MACLB_REGNUM:
return SIM_SH_BANK_MACL_REGNUM;
case GBRB_REGNUM:
return SIM_SH_BANK_GBR_REGNUM;
case PRB_REGNUM:
return SIM_SH_BANK_PR_REGNUM;
case IVNB_REGNUM:
return SIM_SH_BANK_IVN_REGNUM;
case MACHB_REGNUM:
return SIM_SH_BANK_MACH_REGNUM;
default:
break;
}
return legacy_register_sim_regno (nr);
}
static struct sh_frame_cache *
sh_alloc_frame_cache (void)
{
struct sh_frame_cache *cache;
int i;
cache = FRAME_OBSTACK_ZALLOC (struct sh_frame_cache);
cache->base = 0;
cache->saved_sp = 0;
cache->sp_offset = 0;
cache->pc = 0;
cache->uses_fp = 0;
for (i = 0; i < SH_NUM_REGS; i++)
{
cache->saved_regs[i] = -1;
}
return cache;
}
static struct sh_frame_cache *
sh_frame_cache (struct frame_info *next_frame, void **this_cache)
{
struct sh_frame_cache *cache;
CORE_ADDR current_pc;
int i;
if (*this_cache)
return *this_cache;
cache = sh_alloc_frame_cache ();
*this_cache = cache;
cache->base = frame_unwind_register_unsigned (next_frame, FP_REGNUM);
if (cache->base == 0)
return cache;
cache->pc = frame_func_unwind (next_frame);
current_pc = frame_pc_unwind (next_frame);
if (cache->pc != 0)
sh_analyze_prologue (cache->pc, current_pc, cache);
if (!cache->uses_fp)
{
cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
}
cache->saved_sp = cache->base + cache->sp_offset;
for (i = 0; i < SH_NUM_REGS; i++)
if (cache->saved_regs[i] != -1)
cache->saved_regs[i] = cache->saved_sp - cache->saved_regs[i] - 4;
return cache;
}
static void
sh_frame_prev_register (struct frame_info *next_frame, void **this_cache,
int regnum, enum opt_state *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnump, void *valuep)
{
struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
gdb_assert (regnum >= 0);
if (regnum == SP_REGNUM && cache->saved_sp)
{
*optimizedp = opt_okay;
*lvalp = not_lval;
*addrp = 0;
*realnump = -1;
if (valuep)
{
store_unsigned_integer (valuep, 4, cache->saved_sp);
}
return;
}
if (regnum == PC_REGNUM)
regnum = PR_REGNUM;
if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
{
*optimizedp = opt_okay;
*lvalp = lval_memory;
*addrp = cache->saved_regs[regnum];
*realnump = -1;
if (valuep)
{
read_memory (*addrp, valuep,
register_size (current_gdbarch, regnum));
}
return;
}
*optimizedp = opt_okay;
*lvalp = lval_register;
*addrp = 0;
*realnump = regnum;
if (valuep)
frame_unwind_register (next_frame, (*realnump), valuep);
}
static void
sh_frame_this_id (struct frame_info *next_frame, void **this_cache,
struct frame_id *this_id)
{
struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
if (cache->base == 0)
return;
*this_id = frame_id_build (cache->saved_sp, cache->pc);
}
static const struct frame_unwind sh_frame_unwind = {
NORMAL_FRAME,
sh_frame_this_id,
sh_frame_prev_register
};
static const struct frame_unwind *
sh_frame_sniffer (struct frame_info *next_frame)
{
return &sh_frame_unwind;
}
static CORE_ADDR
sh_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
return frame_unwind_register_unsigned (next_frame, SP_REGNUM);
}
static CORE_ADDR
sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
return frame_unwind_register_unsigned (next_frame, PC_REGNUM);
}
static struct frame_id
sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
return frame_id_build (sh_unwind_sp (gdbarch, next_frame),
frame_pc_unwind (next_frame));
}
static CORE_ADDR
sh_frame_base_address (struct frame_info *next_frame, void **this_cache)
{
struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
return cache->base;
}
static const struct frame_base sh_frame_base = {
&sh_frame_unwind,
sh_frame_base_address,
sh_frame_base_address,
sh_frame_base_address
};
static int
sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
{
ULONGEST inst;
CORE_ADDR addr = func_end - 28;
if (addr < func_addr + 4)
addr = func_addr + 4;
if (pc < addr)
return 0;
while (addr < func_end
&& !IS_RTS (read_memory_unsigned_integer (addr, 2)))
addr += 2;
if (addr >= func_end)
return 0;
inst = read_memory_unsigned_integer (addr - 2, 2);
if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2)))
addr -= 2;
else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2)))
return 0;
inst = read_memory_unsigned_integer (addr - 2, 2);
if (IS_MACL_LDS (inst))
{
addr -= 2;
inst = read_memory_unsigned_integer (addr - 2, 2);
}
if (IS_LDS (inst))
{
addr -= 2;
inst = read_memory_unsigned_integer (addr - 2, 2);
}
if (IS_MOV_FP_SP (inst))
{
addr -= 2;
inst = read_memory_unsigned_integer (addr - 2, 2);
}
while (addr > func_addr + 4
&& (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst)))
{
addr -= 2;
inst = read_memory_unsigned_integer (addr - 2, 2);
}
if ((gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a
|| gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a_nofpu)
&& addr > func_addr + 6
&& IS_MOVI20 (read_memory_unsigned_integer (addr - 4, 2)))
addr -= 4;
if (pc >= addr)
return 1;
}
return 0;
}
static struct gdbarch *
sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
sh_show_regs = sh_generic_show_regs;
switch (info.bfd_arch_info->mach)
{
case bfd_mach_sh2e:
sh_show_regs = sh2e_show_regs;
break;
case bfd_mach_sh2a:
sh_show_regs = sh2a_show_regs;
break;
case bfd_mach_sh2a_nofpu:
sh_show_regs = sh2a_nofpu_show_regs;
break;
case bfd_mach_sh_dsp:
sh_show_regs = sh_dsp_show_regs;
break;
case bfd_mach_sh3:
sh_show_regs = sh3_show_regs;
break;
case bfd_mach_sh3e:
sh_show_regs = sh3e_show_regs;
break;
case bfd_mach_sh3_dsp:
case bfd_mach_sh4al_dsp:
sh_show_regs = sh3_dsp_show_regs;
break;
case bfd_mach_sh4:
case bfd_mach_sh4a:
sh_show_regs = sh4_show_regs;
break;
case bfd_mach_sh4_nofpu:
case bfd_mach_sh4a_nofpu:
sh_show_regs = sh4_nofpu_show_regs;
break;
case bfd_mach_sh5:
sh_show_regs = sh64_show_regs;
return sh64_gdbarch_init (info, arches);
}
arches = gdbarch_list_lookup_by_info (arches, &info);
if (arches != NULL)
return arches->gdbarch;
gdbarch = gdbarch_alloc (&info, NULL);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_num_regs (gdbarch, SH_NUM_REGS);
set_gdbarch_sp_regnum (gdbarch, 15);
set_gdbarch_pc_regnum (gdbarch, 16);
set_gdbarch_fp0_regnum (gdbarch, -1);
set_gdbarch_num_pseudo_regs (gdbarch, 0);
set_gdbarch_register_type (gdbarch, sh_default_register_type);
set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
set_gdbarch_return_value (gdbarch, sh_return_value_nofpu);
set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
sh_extract_struct_value_address);
set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
set_gdbarch_frame_align (gdbarch, sh_frame_align);
set_gdbarch_unwind_sp (gdbarch, sh_unwind_sp);
set_gdbarch_unwind_pc (gdbarch, sh_unwind_pc);
set_gdbarch_unwind_dummy_id (gdbarch, sh_unwind_dummy_id);
frame_base_set_default (gdbarch, &sh_frame_base);
set_gdbarch_in_function_epilogue_p (gdbarch, sh_in_function_epilogue_p);
switch (info.bfd_arch_info->mach)
{
case bfd_mach_sh:
set_gdbarch_register_name (gdbarch, sh_sh_register_name);
break;
case bfd_mach_sh2:
set_gdbarch_register_name (gdbarch, sh_sh_register_name);
break;
case bfd_mach_sh2e:
set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_register_name (gdbarch, sh_sh2e_register_name);
set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
set_gdbarch_fp0_regnum (gdbarch, 25);
set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
break;
case bfd_mach_sh2a:
set_gdbarch_register_name (gdbarch, sh_sh2a_register_name);
set_gdbarch_register_type (gdbarch, sh_sh2a_register_type);
set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno);
set_gdbarch_fp0_regnum (gdbarch, 25);
set_gdbarch_num_pseudo_regs (gdbarch, 9);
set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
break;
case bfd_mach_sh2a_nofpu:
set_gdbarch_register_name (gdbarch, sh_sh2a_nofpu_register_name);
set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno);
set_gdbarch_num_pseudo_regs (gdbarch, 1);
set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
break;
case bfd_mach_sh_dsp:
set_gdbarch_register_name (gdbarch, sh_sh_dsp_register_name);
set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
break;
case bfd_mach_sh3:
set_gdbarch_register_name (gdbarch, sh_sh3_register_name);
break;
case bfd_mach_sh3e:
set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_register_name (gdbarch, sh_sh3e_register_name);
set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
set_gdbarch_fp0_regnum (gdbarch, 25);
set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
break;
case bfd_mach_sh3_dsp:
set_gdbarch_register_name (gdbarch, sh_sh3_dsp_register_name);
set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
break;
case bfd_mach_sh4:
case bfd_mach_sh4a:
set_gdbarch_register_name (gdbarch, sh_sh4_register_name);
set_gdbarch_register_type (gdbarch, sh_sh4_register_type);
set_gdbarch_fp0_regnum (gdbarch, 25);
set_gdbarch_num_pseudo_regs (gdbarch, 13);
set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
break;
case bfd_mach_sh4_nofpu:
case bfd_mach_sh4a_nofpu:
set_gdbarch_register_name (gdbarch, sh_sh4_nofpu_register_name);
break;
case bfd_mach_sh4al_dsp:
set_gdbarch_register_name (gdbarch, sh_sh4al_dsp_register_name);
set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
break;
default:
set_gdbarch_register_name (gdbarch, sh_sh_register_name);
break;
}
gdbarch_init_osabi (info, gdbarch);
frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer);
return gdbarch;
}
extern initialize_file_ftype _initialize_sh_tdep;
void
_initialize_sh_tdep (void)
{
struct cmd_list_element *c;
gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
add_com ("regs", class_vars, sh_show_regs_command, _("Print all registers"));
}