/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
static CORE_ADDR
unmake_mips16_addr (CORE_ADDR addr)
{
- return ((addr) & ~1);
+ return ((addr) & ~(CORE_ADDR) 1);
}
/* Return the contents of register REGNUM as a signed integer. */
}
else
instlen = MIPS_INSN32_SIZE;
- status = deprecated_read_memory_nobpt (addr, buf, instlen);
+ status = read_memory_nobpt (addr, buf, instlen);
if (status)
memory_error (status, addr);
return extract_unsigned_integer (buf, instlen);
return ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 2;
}
-/* Determine whate to set a single step breakpoint while considering
- branch prediction */
+/* Determine where to set a single step breakpoint while considering
+ branch prediction. */
static CORE_ADDR
mips32_next_pc (CORE_ADDR pc)
{
unsigned long reg;
reg = jtype_target (inst) << 2;
/* Upper four bits get never changed... */
- pc = reg + ((pc + 4) & 0xf0000000);
+ pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
}
break;
/* FIXME case JALX : */
{
unsigned long reg;
reg = jtype_target (inst) << 2;
- pc = reg + ((pc + 4) & 0xf0000000) + 1; /* yes, +1 */
+ pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff) + 1; /* yes, +1 */
/* Add 1 to indicate 16 bit mode - Invert ISA mode */
}
break; /* The new PC will be alternate mode */
static CORE_ADDR
add_offset_16 (CORE_ADDR pc, int offset)
{
- return ((offset << 2) | ((pc + 2) & (0xf0000000)));
+ return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)));
}
static CORE_ADDR
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;
+ CORE_ADDR pc, next_pc;
if (insert_breakpoints_p)
{
pc = read_register (mips_regnum (current_gdbarch)->pc);
next_pc = mips_next_pc (pc);
- target_insert_breakpoint (next_pc, break_mem);
+ insert_single_step_breakpoint (next_pc);
}
else
- target_remove_breakpoint (next_pc, break_mem);
+ remove_single_step_breakpoints ();
}
/* Test whether the PC points to the return instruction at the
/* According to the current ABI, should the type be passed in a
floating-point register (assuming that there is space)? When there
- is no FPU, FP are not even considered as possibile candidates for
+ is no FPU, FP are not even considered as possible candidates for
FP registers and, consequently this returns false - forces FP
arguments into integer registers. */
&& (typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION)
&& TYPE_NFIELDS (arg_type) == 1
- && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT))
+ && TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (arg_type, 0)))
+ == TYPE_CODE_FLT))
&& MIPS_FPU_TYPE != MIPS_FPU_NONE);
}
if (fp_register_arg_p (typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
{
- if (mips_abi_regsize (gdbarch) < 8 && len == 8)
+ if (register_size (gdbarch, float_argreg) < 8 && len == 8)
{
int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
unsigned long regval;
return sp;
}
-/* Determin the return value convention being used. */
+/* Determine the return value convention being used. */
static enum return_value_convention
mips_eabi_return_value (struct gdbarch *gdbarch,
|| TYPE_CODE (type) == TYPE_CODE_ARRAY
|| TYPE_LENGTH (type) > 2 * mips_abi_regsize (gdbarch))
return RETURN_VALUE_STRUCT_CONVENTION;
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (type) == 16
+ && tdep->mips_fpu_type != MIPS_FPU_NONE)
+ {
+ /* A 128-bit floating-point value fills both $f0 and $f2. The
+ two registers are used in the same as memory order, so the
+ eight bytes with the lower memory address are in $f0. */
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stderr, "Return float in $f0 and $f2\n");
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ 8, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 2,
+ 8, TARGET_BYTE_ORDER, readbuf ? readbuf + 8 : readbuf,
+ writebuf ? writebuf + 8 : writebuf, 0);
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
else if (TYPE_CODE (type) == TYPE_CODE_FLT
&& tdep->mips_fpu_type != MIPS_FPU_NONE)
{
if (fp_register_arg_p (typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
{
- if (mips_abi_regsize (gdbarch) < 8 && len == 8)
+ if (register_size (gdbarch, float_argreg) < 8 && len == 8)
{
int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
unsigned long regval;
big endian targets.
It does not seem to be necessary to do the
- same for integral types.
-
- Also don't do this adjustment on O64 binaries.
-
- cagney/2001-07-23: gdb/179: Also, GCC, when
- outputting LE O32 with sizeof (struct) <
- mips_abi_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_abi_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. */
+ same for integral types. */
- if (mips_abi_regsize (gdbarch) < 8
- && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& partial_len < mips_abi_regsize (gdbarch)
&& (typecode == TYPE_CODE_STRUCT ||
typecode == TYPE_CODE_UNION))
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
- return RETURN_VALUE_STRUCT_CONVENTION;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else if (fp_register_arg_p (TYPE_CODE (type), type))
+ {
+ /* A floating-point value. It fits in the least significant
+ part of FP0. */
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ TYPE_LENGTH (type),
+ TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ else
+ {
+ /* A scalar extract each part but least-significant-byte
+ justified. */
+ int offset;
+ int regnum;
+ for (offset = 0, regnum = MIPS_V0_REGNUM;
+ offset < TYPE_LENGTH (type);
+ offset += mips_stack_argsize (gdbarch), regnum++)
+ {
+ int xfer = mips_stack_argsize (gdbarch);
+ if (offset + xfer > TYPE_LENGTH (type))
+ xfer = TYPE_LENGTH (type) - offset;
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
+ offset, xfer, regnum);
+ mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+ TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
}
/* Floating point register management.
int regnum;
/* For GP registers, we print a separate row of names above the vals */
- fprintf_filtered (file, " ");
for (col = 0, regnum = start_regnum;
col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
{
if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
break; /* end the row: reached FP register */
+ if (col == 0)
+ fprintf_filtered (file, " ");
fprintf_filtered (file,
mips_abi_regsize (current_gdbarch) == 8 ? "%17s" : "%9s",
REGISTER_NAME (regnum));
col++;
}
+
+ if (col == 0)
+ return regnum;
+
/* print the R0 to R31 names */
if ((start_regnum % NUM_REGS) < MIPS_NUMREGS)
fprintf_filtered (file, "\n R%-4d", start_regnum % NUM_REGS);
}
-/* 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. */
+/* Convert an integer into an address. Extracting the value signed
+ guarantees a correctly sign extended address. */
static CORE_ADDR
mips_integer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
- gdb_byte *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));
+ return (CORE_ADDR) extract_signed_integer (buf, TYPE_LENGTH (type));
}
static void
warning (_("unsupported ABI %s."), name + 8);
}
+static void
+mips_find_long_section (bfd *abfd, asection *sect, void *obj)
+{
+ int *lbp = (int *) obj;
+ const char *name = bfd_get_section_name (abfd, sect);
+
+ if (strncmp (name, ".gcc_compiled_long32", 20) == 0)
+ *lbp = 32;
+ else if (strncmp (name, ".gcc_compiled_long64", 20) == 0)
+ *lbp = 64;
+ else if (strncmp (name, ".gcc_compiled_long", 18) == 0)
+ warning (_("unrecognized .gcc_compiled_longXX"));
+}
+
static enum mips_abi
global_mips_abi (void)
{
}
}
+ /* Default 64-bit objects to N64 instead of O32. */
+ if (found_abi == MIPS_ABI_UNKNOWN
+ && info.abfd != NULL
+ && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
+ && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
+ found_abi = MIPS_ABI_N64;
+
if (gdbarch_debug)
fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: found_abi = %d\n",
found_abi);
internal_error (__FILE__, __LINE__, _("unknown ABI in switch"));
}
+ /* GCC creates a pseudo-section whose name specifies the size of
+ longs, since -mlong32 or -mlong64 may be used independent of
+ other options. How those options affect pointer sizes is ABI and
+ architecture dependent, so use them to override the default sizes
+ set by the ABI. This table shows the relationship between ABI,
+ -mlongXX, and size of pointers:
+
+ ABI -mlongXX ptr bits
+ --- -------- --------
+ o32 32 32
+ o32 64 32
+ n32 32 32
+ n32 64 64
+ o64 32 32
+ o64 64 64
+ n64 32 32
+ n64 64 64
+ eabi32 32 32
+ eabi32 64 32
+ eabi64 32 32
+ eabi64 64 64
+
+ Note that for o32 and eabi32, pointers are always 32 bits
+ regardless of any -mlongXX option. For all others, pointers and
+ longs are the same, as set by -mlongXX or set by defaults.
+ */
+
+ if (info.abfd != NULL)
+ {
+ int long_bit = 0;
+
+ bfd_map_over_sections (info.abfd, mips_find_long_section, &long_bit);
+ if (long_bit)
+ {
+ set_gdbarch_long_bit (gdbarch, long_bit);
+ switch (mips_abi)
+ {
+ case MIPS_ABI_O32:
+ case MIPS_ABI_EABI32:
+ break;
+ case MIPS_ABI_N32:
+ case MIPS_ABI_O64:
+ case MIPS_ABI_N64:
+ case MIPS_ABI_EABI64:
+ set_gdbarch_ptr_bit (gdbarch, long_bit);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, _("unknown ABI in switch"));
+ }
+ }
+ }
+
/* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
that could indicate -gp32 BUT gas/config/tc-mips.c contains the
comment:
{
int ef_mips_arch;
int ef_mips_32bitmode;
- /* determine the ISA */
+ /* Determine the ISA. */
switch (tdep->elf_flags & EF_MIPS_ARCH)
{
case E_MIPS_ARCH_1:
ef_mips_arch = 0;
break;
}
- /* determine the size of a pointer */
+ /* Determine the size of a pointer. */
ef_mips_32bitmode = (tdep->elf_flags & EF_MIPS_32BITMODE);
fprintf_unfiltered (file,
"mips_dump_tdep: tdep->elf_flags = 0x%x\n",