/* Target-dependent code for Hitachi Super-H, for GDB.
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of GDB.
#include "frame.h"
#include "obstack.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" /* for BEFORE_TEXT_END etc. */
-
-extern int remote_write_size; /* in remote.c */
-
-/* Default to the original SH. */
-
-#define DEFAULT_SH_TYPE "sh"
-
-/* This value is the model of SH in use. */
-
-char *sh_processor_type;
-
-char *tmp_sh_processor_type;
+#include "gdb_string.h"
/* A set of original names, to be used when restoring back to generic
registers from a specific set. */
};
struct {
- char *name;
char **regnames;
+ int mach;
} sh_processor_type_table[] = {
- { "sh", sh_reg_names },
- { "sh3", sh3_reg_names },
- { "sh3e", sh3e_reg_names },
- { NULL, NULL }
+ { sh_reg_names, bfd_mach_sh },
+ { sh3_reg_names, bfd_mach_sh3 },
+ { sh3e_reg_names, bfd_mach_sh3e },
+ { sh3e_reg_names, bfd_mach_sh4 },
+ { NULL, 0 }
};
/* Prologue looks like
#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 FPSCR_SZ (1 << 20)
/* Skip any prologue before the guts of a function */
w = read_memory_integer (start_pc, 2);
while (IS_STS (w)
+ || IS_FMOV (w)
|| IS_PUSH (w)
|| IS_MOV_SP_FP (w)
|| IS_MOV_R3 (w)
depth = 0;
- /* Loop around examining the prologue insns, but give up
- after 15 of them, since we're getting silly then */
- while (pc < opc + 15 * 2)
+ /* Loop around examining the prologue insns until we find something
+ that does not appear to be part of the prologue. But give up
+ after 20 of them, since we're getting silly then. */
+
+ while (pc < opc + 20 * 2)
{
/* See where the registers will be saved to */
if (IS_PUSH (insn))
}
else if (IS_MOV_R3 (insn))
{
- r3_val = (char) (insn & 0xff);
+ r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
pc += 2;
insn = read_memory_integer (pc, 2);
}
else if (IS_ADD_SP (insn))
{
pc += 2;
- depth += -((char) (insn & 0xff));
+ depth -= ((insn & 0xff) ^ 0x80) - 0x80;
insn = read_memory_integer (pc, 2);
}
+ else if (IS_FMOV (insn))
+ {
+ pc += 2;
+ insn = read_memory_integer (pc, 2);
+ if (read_register (FPSCR_REGNUM) & FPSCR_SZ)
+ {
+ depth += 8;
+ }
+ else
+ {
+ depth += 4;
+ }
+ }
else
break;
}
<destination>
*/
-int
+#if 0
+void
sh_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
char *dummy;
CORE_ADDR pc;
{
*(unsigned long *) (dummy + 8) = fun;
}
+#endif
/* Function: get_saved_register
Just call the generic_get_saved_register function. */
}
-/* Command to set the processor type. */
-
-void
-sh_set_processor_type_command (args, from_tty)
- char *args;
- int from_tty;
-{
- int i;
- char *temp;
-
- /* The `set' commands work by setting the value, then calling the hook,
- so we let the general command modify a scratch location, then decide
- here if we really want to modify the processor type. */
- if (tmp_sh_processor_type == NULL || *tmp_sh_processor_type == '\0')
- {
- printf_unfiltered ("The known SH processor types are as follows:\n\n");
- for (i = 0; sh_processor_type_table[i].name != NULL; ++i)
- printf_unfiltered ("%s\n", sh_processor_type_table[i].name);
-
- /* Restore the value. */
- tmp_sh_processor_type = strsave (sh_processor_type);
-
- return;
- }
-
- if (!sh_set_processor_type (tmp_sh_processor_type))
- {
- /* Restore to a valid value before erroring out. */
- temp = tmp_sh_processor_type;
- tmp_sh_processor_type = strsave (sh_processor_type);
- error ("Unknown processor type `%s'.", temp);
- }
-}
-
-/* This is a dummy not actually run. */
-
-static void
-sh_show_processor_type_command (args, from_tty)
- char *args;
- int from_tty;
-{
-}
-
/* Modify the actual processor type. */
int
-sh_set_processor_type (str)
- char *str;
+sh_target_architecture_hook (ap)
+ const bfd_arch_info_type *ap;
{
int i, j;
- if (str == NULL)
+ if (ap->arch != bfd_arch_sh)
return 0;
- for (i = 0; sh_processor_type_table[i].name != NULL; ++i)
+ for (i = 0; sh_processor_type_table[i].regnames != NULL; i++)
{
- if (strcasecmp (str, sh_processor_type_table[i].name) == 0)
+ if (sh_processor_type_table[i].mach == ap->mach)
{
- sh_processor_type = str;
-
for (j = 0; j < NUM_REGS; ++j)
reg_names[j] = sh_processor_type_table[i].regnames[j];
-
return 1;
}
}
- return 0;
+ fatal ("Architecture `%s' unreconized", ap->printable_name);
}
/* Print the registers in a form similar to the E7000 */
char *args;
int from_tty;
{
+ int cpu;
+ if (target_architecture->arch == bfd_arch_sh)
+ cpu = target_architecture->mach;
+ else
+ cpu = 0;
+ /* FIXME: sh4 has more registers */
+ if (cpu == bfd_mach_sh4)
+ cpu = bfd_mach_sh3;
+
printf_filtered ("PC=%08x SR=%08x PR=%08x MACH=%08x MACHL=%08x\n",
read_register (PC_REGNUM),
read_register (SR_REGNUM),
read_register (MACH_REGNUM),
read_register (MACL_REGNUM));
- printf_filtered ("R0-R7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ printf_filtered ("GBR=%08x VBR=%08x",
+ read_register (GBR_REGNUM),
+ read_register (VBR_REGNUM));
+ if (cpu == bfd_mach_sh3 || cpu == bfd_mach_sh3e)
+ {
+ printf_filtered (" SSR=%08x SPC=%08x",
+ read_register (SSR_REGNUM),
+ read_register (SPC_REGNUM));
+ if (cpu == bfd_mach_sh3e)
+ {
+ printf_filtered (" FPUL=%08x FPSCR=%08x",
+ read_register (FPUL_REGNUM),
+ read_register (FPSCR_REGNUM));
+ }
+ }
+
+ printf_filtered ("\nR0-R7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
read_register (0),
read_register (1),
read_register (2),
read_register (13),
read_register (14),
read_register (15));
+ if (cpu == bfd_mach_sh3e)
+ {
+ printf_filtered ("FP0-FP7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ read_register (FP0_REGNUM + 0),
+ read_register (FP0_REGNUM + 1),
+ read_register (FP0_REGNUM + 2),
+ read_register (FP0_REGNUM + 3),
+ read_register (FP0_REGNUM + 4),
+ read_register (FP0_REGNUM + 5),
+ read_register (FP0_REGNUM + 6),
+ read_register (FP0_REGNUM + 7));
+ printf_filtered ("FP8-FP15 %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ read_register (FP0_REGNUM + 8),
+ read_register (FP0_REGNUM + 9),
+ read_register (FP0_REGNUM + 10),
+ read_register (FP0_REGNUM + 11),
+ read_register (FP0_REGNUM + 12),
+ read_register (FP0_REGNUM + 13),
+ read_register (FP0_REGNUM + 14),
+ read_register (FP0_REGNUM + 15));
+ }
}
/* Function: extract_return_value
tm_print_insn = gdb_print_insn_sh;
- c = add_set_cmd ("processor", class_support, var_string_noescape,
- (char *) &tmp_sh_processor_type,
- "Set the type of SH processor in use.\n\
-Set this to be able to access processor-type-specific registers.\n\
-",
- &setlist);
- c->function.cfunc = sh_set_processor_type_command;
- c = add_show_from_set (c, &showlist);
- c->function.cfunc = sh_show_processor_type_command;
-
- tmp_sh_processor_type = strsave (DEFAULT_SH_TYPE);
- sh_set_processor_type_command (strsave (DEFAULT_SH_TYPE), 0);
+ target_architecture_hook = sh_target_architecture_hook;
add_com ("regs", class_vars, sh_show_regs, "Print all registers");
-
- /* Reduce the remote write size because some CMONs can't take
- more than 400 bytes in a packet. 300 seems like a safe bet. */
- remote_write_size = 300;
}
-