/* 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, 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"
static void mips_print_register (int, int);
static mips_extra_func_info_t
-heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *);
+heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *, int);
static CORE_ADDR heuristic_proc_start (CORE_ADDR);
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
static mips_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame);
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame);
static CORE_ADDR after_prologue (CORE_ADDR pc,
mips_extra_func_info_t proc_desc);
{
if (mips64_transfers_32bit_regs_p)
return REGISTER_VIRTUAL_SIZE (reg_nr);
+ else if (reg_nr >= FP0_REGNUM && reg_nr < FP0_REGNUM + 32
+ && FP_REGISTER_DOUBLE)
+ /* For MIPS_ABI_N32 (for example) we need 8 byte floating point
+ registers. */
+ return 8;
else
return MIPS_REGSIZE;
}
case CMD_AUTO_BOOLEAN_AUTO:
return MIPS_DEFAULT_MASK_ADDRESS_P;
default:
- internal_error ("mips_mask_address_p: bad switch");
+ internal_error (__FILE__, __LINE__,
+ "mips_mask_address_p: bad switch");
return -1;
}
}
mips_mask_address_p () ? "enabled" : "disabled");
break;
default:
- internal_error ("show_mask_address: bad switch");
+ internal_error (__FILE__, __LINE__,
+ "show_mask_address: bad switch");
break;
}
}
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
struct symtab_and_line sal;
CORE_ADDR func_addr, func_end;
+ /* Pass cur_frame == 0 to find_proc_desc. We should not attempt
+ to read the stack pointer from the current machine state, because
+ the current machine state has nothing to do with the information
+ we need from the proc_desc; and the process may or may not exist
+ right now. */
if (!proc_desc)
- proc_desc = find_proc_desc (pc, NULL);
+ proc_desc = find_proc_desc (pc, NULL, 0);
if (proc_desc)
{
/* These the fields of 32 bit mips instructions */
-#define mips32_op(x) (x >> 25)
-#define itype_op(x) (x >> 25)
-#define itype_rs(x) ((x >> 21)& 0x1f)
+#define mips32_op(x) (x >> 26)
+#define itype_op(x) (x >> 26)
+#define itype_rs(x) ((x >> 21) & 0x1f)
#define itype_rt(x) ((x >> 16) & 0x1f)
-#define itype_immediate(x) ( x & 0xffff)
+#define itype_immediate(x) (x & 0xffff)
-#define jtype_op(x) (x >> 25)
-#define jtype_target(x) ( x & 0x03fffff)
+#define jtype_op(x) (x >> 26)
+#define jtype_target(x) (x & 0x03ffffff)
-#define rtype_op(x) (x >>25)
-#define rtype_rs(x) ((x>>21) & 0x1f)
-#define rtype_rt(x) ((x>>16) & 0x1f)
-#define rtype_rd(x) ((x>>11) & 0x1f)
-#define rtype_shamt(x) ((x>>6) & 0x1f)
-#define rtype_funct(x) (x & 0x3f )
+#define rtype_op(x) (x >> 26)
+#define rtype_rs(x) ((x >> 21) & 0x1f)
+#define rtype_rt(x) ((x >> 16) & 0x1f)
+#define rtype_rd(x) ((x >> 11) & 0x1f)
+#define rtype_shamt(x) ((x >> 6) & 0x1f)
+#define rtype_funct(x) (x & 0x3f)
static CORE_ADDR
mips32_relative_offset (unsigned long inst)
unsigned long inst;
int op;
inst = mips_fetch_instruction (pc);
- if ((inst & 0xe0000000) != 0) /* Not a special, junp or branch instruction */
+ if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */
{
- if ((inst >> 27) == 5) /* BEQL BNEZ BLEZL BGTZE , bits 0101xx */
+ if (itype_op (inst) >> 2 == 5)
+ /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
{
- op = ((inst >> 25) & 0x03);
+ op = (itype_op (inst) & 0x03);
switch (op)
{
- case 0:
- goto equal_branch; /* BEQL */
- case 1:
- goto neq_branch; /* BNEZ */
- case 2:
- goto less_branch; /* BLEZ */
- case 3:
- goto greater_branch; /* BGTZ */
+ case 0: /* BEQL */
+ goto equal_branch;
+ case 1: /* BNEL */
+ goto neq_branch;
+ case 2: /* BLEZL */
+ goto less_branch;
+ case 3: /* BGTZ */
+ goto greater_branch;
default:
pc += 4;
}
}
+ else if (itype_op (inst) == 17 && itype_rs (inst) == 8)
+ /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
+ {
+ int tf = itype_rt (inst) & 0x01;
+ int cnum = itype_rt (inst) >> 2;
+ int fcrcs = read_signed_register (FCRCS_REGNUM);
+ int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
+
+ if (((cond >> cnum) & 0x01) == tf)
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8;
+ }
else
pc += 4; /* Not a branch, next instruction is easy */
}
{ /* This gets way messy */
/* Further subdivide into SPECIAL, REGIMM and other */
- switch (op = ((inst >> 26) & 0x07)) /* extract bits 28,27,26 */
+ switch (op = itype_op (inst) & 0x07) /* extract bits 28,27,26 */
{
case 0: /* SPECIAL */
op = rtype_funct (inst);
pc += 4;
}
- break; /* end special */
+ break; /* end SPECIAL */
case 1: /* REGIMM */
{
- op = jtype_op (inst); /* branch condition */
- switch (jtype_op (inst))
+ op = itype_rt (inst); /* branch condition */
+ switch (op)
{
case 0: /* BLTZ */
- case 2: /* BLTXL */
- case 16: /* BLTZALL */
+ case 2: /* BLTZL */
+ case 16: /* BLTZAL */
case 18: /* BLTZALL */
less_branch:
if (read_signed_register (itype_rs (inst)) < 0)
else
pc += 8; /* after the delay slot */
break;
- case 1: /* GEZ */
+ case 1: /* BGEZ */
case 3: /* BGEZL */
case 17: /* BGEZAL */
case 19: /* BGEZALL */
else
pc += 8; /* after the delay slot */
break;
- /* All of the other intructions in the REGIMM catagory */
+ /* All of the other instructions in the REGIMM category */
default:
pc += 4;
}
}
- break; /* end REGIMM */
+ break; /* end REGIMM */
case 2: /* J */
case 3: /* JAL */
{
unsigned long reg;
reg = jtype_target (inst) << 2;
+ /* Upper four bits get never changed... */
pc = reg + ((pc + 4) & 0xf0000000);
- /* Whats this mysterious 0xf000000 adjustment ??? */
}
break;
/* FIXME case JALX : */
/* Add 1 to indicate 16 bit mode - Invert ISA mode */
}
break; /* The new PC will be alternate mode */
- case 4: /* BEQ , BEQL */
+ case 4: /* BEQ, BEQL */
equal_branch:
if (read_signed_register (itype_rs (inst)) ==
read_signed_register (itype_rt (inst)))
else
pc += 8;
break;
- case 5: /* BNE , BNEL */
+ case 5: /* BNE, BNEL */
neq_branch:
if (read_signed_register (itype_rs (inst)) !=
- read_signed_register (itype_rs (inst)))
+ read_signed_register (itype_rt (inst)))
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
break;
- case 6: /* BLEZ , BLEZL */
+ case 6: /* BLEZ, BLEZL */
less_zero_branch:
if (read_signed_register (itype_rs (inst) <= 0))
pc += mips32_relative_offset (inst) + 4;
pc += 8;
break;
case 7:
- greater_branch: /* BGTZ BGTZL */
+ default:
+ greater_branch: /* BGTZ, BGTZL */
if (read_signed_register (itype_rs (inst) > 0))
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
break;
- default:
- pc += 8;
} /* switch */
} /* else */
return pc;
break;
}
default:
- internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+ internal_error (__FILE__, __LINE__,
+ "bad switch");
}
upk->offset = offset;
upk->regx = regx;
/* 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;
}
+/* mips_software_single_step() is called just before we want to resume
+ the inferior, if we want to single-step it but there is no hardware
+ or kernel single-step support (MIPS on Linux for example). We find
+ the target of the coming instruction and breakpoint it.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
void
+mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ static CORE_ADDR next_pc;
+ typedef char binsn_quantum[BREAKPOINT_MAX];
+ static binsn_quantum break_mem;
+ CORE_ADDR pc;
+
+ if (insert_breakpoints_p)
+ {
+ pc = read_register (PC_REGNUM);
+ next_pc = mips_next_pc (pc);
+
+ target_insert_breakpoint (next_pc, break_mem);
+ }
+ else
+ target_remove_breakpoint (next_pc, break_mem);
+}
+
+static void
mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
{
CORE_ADDR pc, tmp;
static mips_extra_func_info_t
heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
- struct frame_info *next_frame)
+ struct frame_info *next_frame, int cur_frame)
{
- CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ CORE_ADDR sp;
+
+ if (cur_frame)
+ sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ else
+ sp = 0;
if (start_pc == 0)
return NULL;
static mips_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame)
{
mips_extra_func_info_t proc_desc;
CORE_ADDR startaddr;
{
mips_extra_func_info_t found_heuristic =
heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
- pc, next_frame);
+ pc, next_frame, cur_frame);
if (found_heuristic)
proc_desc = found_heuristic;
}
startaddr = heuristic_proc_start (pc);
proc_desc =
- heuristic_proc_desc (startaddr, pc, next_frame);
+ heuristic_proc_desc (startaddr, pc, next_frame, cur_frame);
}
return proc_desc;
}
saved_pc = tmp;
/* Look up the procedure descriptor for this PC. */
- proc_desc = find_proc_desc (saved_pc, frame);
+ proc_desc = find_proc_desc (saved_pc, frame, 1);
if (!proc_desc)
return 0;
/* Use proc_desc calculated in frame_chain */
mips_extra_func_info_t proc_desc =
- fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next);
+ fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next, 1);
fci->extra_info = (struct frame_extra_info *)
frame_obstack_alloc (sizeof (struct frame_extra_info));
&& MIPS_FPU_TYPE != MIPS_FPU_NONE);
}
+/* On o32, argument passing in GPRs depends on the alignment of the type being
+ passed. Return 1 if this type must be aligned to a doubleword boundary. */
+
+static int
+mips_type_needs_double_align (struct type *type)
+{
+ enum type_code typecode = TYPE_CODE (type);
+
+ if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
+ return 1;
+ else if (typecode == TYPE_CODE_STRUCT)
+ {
+ if (TYPE_NFIELDS (type) < 1)
+ return 0;
+ return mips_type_needs_double_align (TYPE_FIELD_TYPE (type, 0));
+ }
+ else if (typecode == TYPE_CODE_UNION)
+ {
+ int i, n;
+
+ n = TYPE_NFIELDS (type);
+ for (i = 0; i < n; i++)
+ if (mips_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
+ return 1;
+ return 0;
+ }
+ return 0;
+}
+
CORE_ADDR
mips_push_arguments (int nargs,
- value_ptr *args,
+ struct value **args,
CORE_ADDR sp,
int struct_return,
CORE_ADDR struct_addr)
{
char *val;
char valbuf[MAX_REGISTER_RAW_SIZE];
- value_ptr arg = args[argnum];
+ struct value *arg = args[argnum];
struct type *arg_type = check_typedef (VALUE_TYPE (arg));
int len = TYPE_LENGTH (arg_type);
enum type_code typecode = TYPE_CODE (arg_type);
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)
compatibility, we will put them in both places. */
int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
(len % MIPS_SAVED_REGSIZE != 0));
+ /* Structures should be aligned to eight bytes (even arg registers)
+ on MIPS_ABI_O32 if their first member has double precision. */
+ if (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_O32
+ && mips_type_needs_double_align (arg_type))
+ {
+ if ((argreg & 1))
+ argreg++;
+ }
/* Note: Floating-point values that didn't fit into an FP
register are only written to memory. */
while (len > 0)
same for integral types.
Also don't do this adjustment on EABI and O64
- binaries. */
+ binaries.
+
+ cagney/2001-07-23: gdb/179: Also, GCC, when
+ outputting LE O32 with sizeof (struct) <
+ MIPS_SAVED_REGSIZE, generates a left shift as
+ part of storing the argument in a register a
+ register (the left shift isn't generated when
+ sizeof (struct) >= MIPS_SAVED_REGSIZE). Since it
+ is quite possible that this is GCC contradicting
+ the LE/O32 ABI, GDB has not been adjusted to
+ accommodate this. Either someone needs to
+ demonstrate that the LE/O32 ABI specifies such a
+ left shift OR this new ABI gets identified as
+ such and GDB gets tweaked accordingly. */
if (!MIPS_EABI
&& MIPS_SAVED_REGSIZE < 8
flt2 = unpack_double (builtin_type_float, raw_buffer[LO], &inv2);
doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
- printf_filtered (inv1 ? " %-5s: <invalid float>" :
- " %-5s%-17.9g", REGISTER_NAME (regnum), flt1);
- printf_filtered (inv2 ? " %-5s: <invalid float>" :
- " %-5s%-17.9g", REGISTER_NAME (regnum + 1), flt2);
- printf_filtered (inv3 ? " dbl: <invalid double>\n" :
- " dbl: %-24.17g\n", doub);
+ printf_filtered (" %-5s", REGISTER_NAME (regnum));
+ if (inv1)
+ printf_filtered (": <invalid float>");
+ else
+ printf_filtered ("%-17.9g", flt1);
+
+ printf_filtered (" %-5s", REGISTER_NAME (regnum + 1));
+ if (inv2)
+ printf_filtered (": <invalid float>");
+ else
+ printf_filtered ("%-17.9g", flt2);
+
+ printf_filtered (" dbl: ");
+ if (inv3)
+ printf_filtered ("<invalid double>");
+ else
+ printf_filtered ("%-24.17g", doub);
+ printf_filtered ("\n");
+
/* may want to do hex display here (future enhancement) */
regnum += 2;
}
&raw_buffer[HI][offset], &inv1);
doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
- printf_filtered (inv1 ? " %-5s: <invalid float>" :
- " %-5s flt: %-17.9g", REGISTER_NAME (regnum), flt1);
- printf_filtered (inv3 ? " dbl: <invalid double>\n" :
- " dbl: %-24.17g\n", doub);
+ printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
+ if (inv1)
+ printf_filtered ("<invalid float>");
+ else
+ printf_filtered ("flt: %-17.9g", flt1);
+
+ printf_filtered (" dbl: ");
+ if (inv3)
+ printf_filtered ("<invalid double>");
+ else
+ printf_filtered ("%-24.17g", doub);
+
+ printf_filtered ("\n");
/* may want to do hex display here (future enhancement) */
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",
printf_unfiltered ("%s\n", mips_processor_type_table[i].name);
/* Restore the value. */
- tmp_mips_processor_type = strsave (mips_processor_type);
+ tmp_mips_processor_type = xstrdup (mips_processor_type);
return;
}
{
error ("Unknown processor type `%s'.", tmp_mips_processor_type);
/* Restore its value. */
- tmp_mips_processor_type = strsave (mips_processor_type);
+ tmp_mips_processor_type = xstrdup (mips_processor_type);
}
}
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);
return num + FP0_REGNUM - 32;
}
+/* Convert an integer into an address. By first converting the value
+ into a pointer and then extracting it signed, the address is
+ guarenteed to be correctly sign extended. */
+
+static CORE_ADDR
+mips_integer_to_address (struct type *type, void *buf)
+{
+ char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
+ LONGEST val = unpack_long (type, buf);
+ store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
+ return extract_signed_integer (tmp,
+ TYPE_LENGTH (builtin_type_void_data_ptr));
+}
+
static struct gdbarch *
mips_gdbarch_init (struct gdbarch_info info,
struct gdbarch_list *arches)
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);
set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
set_gdbarch_saved_pc_after_call (gdbarch, mips_saved_pc_after_call);
+ set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
+ set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
+ set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
return gdbarch;
}
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)));
c = add_show_from_set (c, &showlist);
c->function.cfunc = mips_show_processor_type_command;
- tmp_mips_processor_type = strsave (DEFAULT_MIPS_TYPE);
- mips_set_processor_type_command (strsave (DEFAULT_MIPS_TYPE), 0);
+ tmp_mips_processor_type = xstrdup (DEFAULT_MIPS_TYPE);
+ mips_set_processor_type_command (xstrdup (DEFAULT_MIPS_TYPE), 0);
#endif
/* We really would like to have both "0" and "unlimited" work, but