void (*sh_show_regs) (void);
int (*print_sh_insn) (bfd_vma, disassemble_info*);
+CORE_ADDR (*skip_prologue_hard_way) (CORE_ADDR);
+void (*do_pseudo_register) (int);
/* Define other aspects of the stack frame.
we keep a copy of the worked out return pc lying around, since it
/* MOV.L Rm,@(disp,r14) 00011110mmmmdddd
Rm-->(dispx4+r14) where Rm is one of r4,r5,r6,r7 */
-#define IS_MOV_R14(x) \
+#define IS_MOV_TO_R14(x) \
((((x) & 0xff00) == 0x1e) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070))
#define FPSCR_SZ (1 << 20)
where the prologue ends. Unfortunately this is not always
accurate. */
static CORE_ADDR
-skip_prologue_hard_way (CORE_ADDR start_pc)
+sh_skip_prologue_hard_way (CORE_ADDR start_pc)
{
CORE_ADDR here, end;
int updated_fp = 0;
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_R14 (w))
+ || IS_ARG_MOV (w) || IS_MOV_TO_R14 (w))
{
start_pc = here;
}
/* See if we can determine the end of the prologue via the symbol table.
If so, then return either PC, or the PC after the prologue, whichever
is greater. */
-
post_prologue_pc = after_prologue (pc);
/* If after_prologue returned a useful address, then use it. Else
static CORE_ADDR
sh_saved_pc_after_call (struct frame_info *frame)
{
- return (ADDR_BITS_REMOVE(read_register(PR_REGNUM)));
+ return (ADDR_BITS_REMOVE (read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM)));
}
/* Should call_function allocate stack space for a struct return? */
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function.
- We store structs through a pointer passed in R0 */
+ We store structs through a pointer passed in R2 */
static void
sh_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
somehow flag it as invalid if it isn't saved on the stack somewhere. This
would provide a graceful failure mode when trying to get the value of
caller-saves registers for an inner frame. */
-
static CORE_ADDR
sh_find_callers_reg (struct frame_info *fi, int regnum)
{
}
else if (IS_STS (insn))
{
- where[PR_REGNUM] = depth;
+ where[gdbarch_tdep (current_gdbarch)->PR_REGNUM] = depth;
/* If we're storing the pr then this isn't a leaf */
fi->extra_info->leaf_function = 0;
depth += 4;
value */
}
+/* For vectors of 4 floating point registers. */
+static int
+fv_reg_base_num (int fv_regnum)
+{
+ int fp_regnum;
+
+ fp_regnum = FP0_REGNUM +
+ (fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4;
+ return fp_regnum;
+}
+
+/* For double precision floating point registers, i.e 2 fp regs.*/
+static int
+dr_reg_base_num (int dr_regnum)
+{
+ int fp_regnum;
+
+ fp_regnum = FP0_REGNUM +
+ (dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2;
+ return fp_regnum;
+}
+
static void
sh_fp_frame_init_saved_regs (struct frame_info *fi)
{
}
else if (IS_STS (insn))
{
- where[PR_REGNUM] = depth;
+ where[gdbarch_tdep (current_gdbarch)->PR_REGNUM] = depth;
/* If we're storing the pr then this isn't a leaf */
fi->extra_info->leaf_function = 0;
depth += 4;
else
{
FRAME_INIT_SAVED_REGS (fi);
- fi->extra_info->return_pc = sh_find_callers_reg (fi, PR_REGNUM);
+ fi->extra_info->return_pc = sh_find_callers_reg (fi, gdbarch_tdep (current_gdbarch)->PR_REGNUM);
}
}
static CORE_ADDR
sh_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+ int struct_return, CORE_ADDR struct_addr)
{
int stack_offset, stack_alloc;
int argreg;
registers, and push the rest onto the stack. There are 16 bytes
in four registers available. Loop thru args from first to last. */
- argreg = ARG0_REGNUM;
+ argreg = gdbarch_tdep (current_gdbarch)->ARG0_REGNUM;
for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
{
type = VALUE_TYPE (args[argnum]);
odd_sized_struct = 0;
while (len > 0)
{
- if (argreg > ARGLAST_REGNUM || odd_sized_struct)
- { /* must go on the stack */
+ if (argreg > gdbarch_tdep (current_gdbarch)->ARGLAST_REGNUM
+ || odd_sized_struct)
+ {
+ /* must go on the stack */
write_memory (sp + stack_offset, val, 4);
stack_offset += 4;
}
/* NOTE WELL!!!!! This is not an "else if" clause!!!
That's because some *&^%$ things get passed on the stack
AND in the registers! */
- if (argreg <= ARGLAST_REGNUM)
- { /* there's room in a register */
+ if (argreg <= gdbarch_tdep (current_gdbarch)->ARGLAST_REGNUM)
+ {
+ /* there's room in a register */
regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
write_register (argreg++, regval);
}
static CORE_ADDR
sh_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
- write_register (PR_REGNUM, CALL_DUMMY_ADDRESS ());
+ write_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM, CALL_DUMMY_ADDRESS ());
return sp;
}
If the architecture is sh4 or sh3e, store a function's return value
in the R0 general register or in the FP0 floating point register,
depending on the type of the return value. In all the other cases
- the result is stored in r0. */
+ the result is stored in r0, left-justified. */
static void
sh_default_store_return_value (struct type *type, char *valbuf)
{
sh_default_store_return_value (type, valbuf);
}
-
/* Print the registers in a form similar to the E7000 */
static void
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
- (long) read_register (PR_REGNUM),
+ (long) read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
- (long) read_register (PR_REGNUM),
+ (long) read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
- (long) read_register (PR_REGNUM),
+ (long) read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
- (long) read_register (PR_REGNUM),
+ (long) read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
- (long) read_register (PR_REGNUM),
+ (long) read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
paddr (read_register (PC_REGNUM)),
(long) read_register (gdbarch_tdep (current_gdbarch)->SR_REGNUM),
- (long) read_register (PR_REGNUM),
+ (long) read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM),
(long) read_register (MACH_REGNUM),
(long) read_register (MACL_REGNUM));
(*sh_show_regs)();
}
-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;
-}
-
/* Index within `registers' of the first byte of the space for
register N. */
static int
/* Return the GDB type object for the "standard" data type
of data in register N. */
-
static struct type *
sh_sh3e_register_virtual_type (int reg_nr)
{
{
DOUBLEST val;
floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val);
- store_floating(to, TYPE_LENGTH(type), val);
+ store_floating (to, TYPE_LENGTH (type), val);
}
else
- error("sh_register_convert_to_virtual called with non DR register number");
+ error ("sh_register_convert_to_virtual called with non DR register number");
}
void
for (portion = 0; portion < 4; portion++)
if (!register_cached (base_regnum + portion))
target_fetch_registers (base_regnum + portion);
-
}
register_valid [reg_nr] = 1;
}
}
}
+/* Floating point vector of 4 float registers. */
static void
do_fv_register_info (int fv_regnum)
{
(int) read_register (first_fp_reg_num + 3));
}
+/* Double precision registers. */
static void
do_dr_register_info (int dr_regnum)
{
do_fv_register_info (regnum);
}
-
static void
sh_do_fp_register (int regnum)
{ /* do values for FP (float) regs */
}
else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
- sh_do_pseudo_register (regnum);
+ do_pseudo_register (regnum);
}
void
if (fpregs)
while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
- sh_do_pseudo_register (regnum);
+ do_pseudo_register (regnum);
regnum++;
}
}
statement below. */
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->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;
set_gdbarch_fp0_regnum (gdbarch, -1);
set_gdbarch_num_pseudo_regs (gdbarch, 0);
set_gdbarch_store_pseudo_register (gdbarch, sh_store_pseudo_register);
set_gdbarch_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, generic_get_saved_register);
+ set_gdbarch_init_extra_frame_info (gdbarch, sh_init_extra_frame_info);
set_gdbarch_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_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
+ set_gdbarch_pop_frame (gdbarch, sh_pop_frame);
print_sh_insn = gdb_print_insn_sh;
+ skip_prologue_hard_way = sh_skip_prologue_hard_way;
+ do_pseudo_register = sh_do_pseudo_register;
switch (info.bfd_arch_info->mach)
{
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_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
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_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
set_gdbarch_fp0_regnum (gdbarch, 25);
tdep->FPUL_REGNUM = 23;
tdep->FPSCR_REGNUM = 24;
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_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
+ set_gdbarch_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_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_get_saved_register (gdbarch, generic_get_saved_register);
set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
set_gdbarch_coerce_float_to_double (gdbarch,
sh_coerce_float_to_double);
- set_gdbarch_push_arguments (gdbarch, sh_push_arguments);
set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
set_gdbarch_push_return_address (gdbarch, sh_push_return_address);
- set_gdbarch_store_struct_return (gdbarch, sh_store_struct_return);
set_gdbarch_store_return_value (gdbarch, sh_store_return_value);
- set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
- set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention);
- set_gdbarch_init_extra_frame_info (gdbarch, sh_init_extra_frame_info);
- set_gdbarch_pop_frame (gdbarch, sh_pop_frame);
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_frame_args_skip (gdbarch, 0);
set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
- set_gdbarch_frame_chain (gdbarch, sh_frame_chain);
set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
set_gdbarch_frame_saved_pc (gdbarch, sh_frame_saved_pc);
set_gdbarch_frame_args_address (gdbarch, default_frame_address);