/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
#include "gdbtypes.h"
#include "target.h"
#include "arch-utils.h"
+#include "regcache.h"
#include "opcode/mips.h"
#include "elf/mips.h"
all registers should be sign extended for simplicity? */
static CORE_ADDR
-mips_read_pc (int pid)
+mips_read_pc (ptid_t ptid)
{
- return read_signed_register_pid (PC_REGNUM, pid);
+ return read_signed_register_pid (PC_REGNUM, ptid);
}
/* This returns the PC of the first inst after the prologue. If we can't
/* mips_addr_bits_remove - remove useless address bits */
-CORE_ADDR
+static CORE_ADDR
mips_addr_bits_remove (CORE_ADDR addr)
{
if (GDB_TARGET_IS_MIPS64)
return addr;
}
-void
+static void
mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
{
CORE_ADDR pc, tmp;
don't use float registers for arguments. This duplication of
arguments in general registers can't hurt non-MIPS16 functions
because those registers are normally skipped. */
- /* MIPS_EABI squeeses a struct that contains a single floating
- point value into an FP register instead of pusing it onto the
+ /* MIPS_EABI squeezes a struct that contains a single floating
+ point value into an FP register instead of pushing it onto the
stack. */
if (fp_register_arg_p (typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
{
struct return_value_word lo;
struct return_value_word hi;
- return_value_location (valtype, &lo, &hi);
+ return_value_location (valtype, &hi, &lo);
memcpy (valbuf + lo.buf_offset,
regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
char raw_buffer[MAX_REGISTER_RAW_SIZE];
struct return_value_word lo;
struct return_value_word hi;
- return_value_location (valtype, &lo, &hi);
+ return_value_location (valtype, &hi, &lo);
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
static void
show_mipsfpu_command (char *args, int from_tty)
{
- char *msg;
char *fpu;
switch (MIPS_FPU_TYPE)
{
case MIPS_FPU_NONE:
fpu = "absent (none)";
break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
}
if (mips_fpu_type_auto)
printf_unfiltered ("The MIPS floating-point coprocessor is set automatically (currently %s)\n",
int
mips_set_processor_type (char *str)
{
- int i, j;
+ int i;
if (str == NULL)
return 0;
{
if (pc_is_mips16 (*pcptr))
{
- static char mips16_big_breakpoint[] = MIPS16_BIG_BREAKPOINT;
+ static unsigned char mips16_big_breakpoint[] =
+ MIPS16_BIG_BREAKPOINT;
*pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
*lenptr = sizeof (mips16_big_breakpoint);
return mips16_big_breakpoint;
}
else
{
- static char big_breakpoint[] = BIG_BREAKPOINT;
- static char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT;
- static char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT;
+ static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
+ static unsigned char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT;
+ static unsigned char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT;
*lenptr = sizeof (big_breakpoint);
{
if (pc_is_mips16 (*pcptr))
{
- static char mips16_little_breakpoint[] = MIPS16_LITTLE_BREAKPOINT;
+ static unsigned char mips16_little_breakpoint[] =
+ MIPS16_LITTLE_BREAKPOINT;
*pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
*lenptr = sizeof (mips16_little_breakpoint);
return mips16_little_breakpoint;
}
else
{
- static char little_breakpoint[] = LITTLE_BREAKPOINT;
- static char pmon_little_breakpoint[] = PMON_LITTLE_BREAKPOINT;
- static char idt_little_breakpoint[] = IDT_LITTLE_BREAKPOINT;
+ static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
+ static unsigned char pmon_little_breakpoint[] =
+ PMON_LITTLE_BREAKPOINT;
+ static unsigned char idt_little_breakpoint[] =
+ IDT_LITTLE_BREAKPOINT;
*lenptr = sizeof (little_breakpoint);
int elf_flags;
enum mips_abi mips_abi;
+ /* Reset the disassembly info, in case it was set to something
+ non-default. */
+ tm_print_insn_info.flavour = bfd_target_unknown_flavour;
+ tm_print_insn_info.arch = bfd_arch_unknown;
+ tm_print_insn_info.mach = 0;
+
/* Extract the elf_flags if available */
if (info.abfd != NULL
&& bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
case bfd_mach_mips5000:
mips_abi = MIPS_ABI_EABI64;
break;
+ case bfd_mach_mips8000:
+ case bfd_mach_mips10000:
+ mips_abi = MIPS_ABI_N32;
+ break;
}
}
#ifdef MIPS_DEFAULT_ABI
set_gdbarch_double_bit (gdbarch, 64);
set_gdbarch_long_double_bit (gdbarch, 64);
tdep->mips_abi = mips_abi;
+
switch (mips_abi)
{
case MIPS_ABI_O32:
set_gdbarch_long_long_bit (gdbarch, 64);
break;
case MIPS_ABI_EABI64:
- tdep->mips_abi_string = "eabi64";
+ tdep->mips_abi_string = "eabi64";
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
set_gdbarch_long_bit (gdbarch, 32);
set_gdbarch_ptr_bit (gdbarch, 32);
set_gdbarch_long_long_bit (gdbarch, 64);
+
+ /* Set up the disassembler info, so that we get the right
+ register names from libopcodes. */
+ tm_print_insn_info.flavour = bfd_target_elf_flavour;
+ tm_print_insn_info.arch = bfd_arch_mips;
+ if (info.bfd_arch_info != NULL
+ && info.bfd_arch_info->arch == bfd_arch_mips
+ && info.bfd_arch_info->mach)
+ tm_print_insn_info.mach = info.bfd_arch_info->mach;
+ else
+ tm_print_insn_info.mach = bfd_mach_mips8000;
break;
default:
tdep->mips_abi_string = "default";
set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+ /* Add/remove bits from an address. The MIPS needs be careful to
+ ensure that all 32 bit addresses are sign extended to 64 bits. */
+ set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove);
+
+ /* There's a mess in stack frame creation. See comments in
+ blockframe.c near reference to INIT_FRAME_PC_FIRST. */
+ set_gdbarch_init_frame_pc_first (gdbarch, mips_init_frame_pc_first);
+ set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
+
/* Map debug register numbers onto internal register numbers. */
set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum);
set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_ecoff_reg_to_regnum);
ef_mips_arch = 3;
break;
case E_MIPS_ARCH_4:
- ef_mips_arch = 0;
+ ef_mips_arch = 4;
break;
default:
+ ef_mips_arch = 0;
break;
}
/* determine the size of a pointer */
fprintf_unfiltered (file,
"mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
XSTRING (IGNORE_HELPER_CALL (PC)));
- fprintf_unfiltered (file,
- "mips_dump_tdep: INIT_FRAME_PC # %s\n",
- XSTRING (INIT_FRAME_PC (FROMLEAF, PREV)));
- fprintf_unfiltered (file,
- "mips_dump_tdep: INIT_FRAME_PC_FIRST # %s\n",
- XSTRING (INIT_FRAME_PC_FIRST (FROMLEAF, PREV)));
fprintf_unfiltered (file,
"mips_dump_tdep: IN_SIGTRAMP # %s\n",
XSTRING (IN_SIGTRAMP (PC, NAME)));
"mips_dump_tdep: SOFTWARE_SINGLE_STEP # %s\n",
XSTRING (SOFTWARE_SINGLE_STEP (SIG, BP_P)));
fprintf_unfiltered (file,
- "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P = %d\n",
- SOFTWARE_SINGLE_STEP_P);
- fprintf_unfiltered (file,
- "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P = %d\n",
- SOFTWARE_SINGLE_STEP_P);
+ "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P () = %d\n",
+ SOFTWARE_SINGLE_STEP_P ());
fprintf_unfiltered (file,
"mips_dump_tdep: STAB_REG_TO_REGNUM # %s\n",
XSTRING (STAB_REG_TO_REGNUM (REGNUM)));