Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010 Free Software Foundation, Inc.
+ 2010, 2011 Free Software Foundation, Inc.
#include "dwarf2-frame.h"
#include "user-regs.h"
#include "valprint.h"
+#include "ax.h"
static const struct objfile_data *mips_pdr_data;
== MIPS_ABI_EABI32 \
|| gdbarch_tdep (gdbarch)->mips_abi == MIPS_ABI_EABI64)
-#define MIPS_LAST_FP_ARG_REGNUM(gdbarch) (gdbarch_tdep (gdbarch)->mips_last_fp_arg_regnum)
+#define MIPS_LAST_FP_ARG_REGNUM(gdbarch) \
+ (gdbarch_tdep (gdbarch)->mips_last_fp_arg_regnum)
-#define MIPS_LAST_ARG_REGNUM(gdbarch) (gdbarch_tdep (gdbarch)->mips_last_arg_regnum)
+#define MIPS_LAST_ARG_REGNUM(gdbarch) \
+ (gdbarch_tdep (gdbarch)->mips_last_arg_regnum)
#define MIPS_FPU_TYPE(gdbarch) (gdbarch_tdep (gdbarch)->mips_fpu_type)
return ((addr) & ~(CORE_ADDR) 1);
}
+static CORE_ADDR
+make_mips16_addr (CORE_ADDR addr)
+{
+ return ((addr) | (CORE_ADDR) 1);
+}
+
/* Return the MIPS ABI associated with GDBARCH. */
enum mips_abi
mips_abi (struct gdbarch *gdbarch)
/ gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
}
-/* Return the currently configured (or set) saved register size. */
+/* Return the currently configured (or set) saved register size. */
unsigned int
mips_abi_regsize (struct gdbarch *gdbarch)
if (((elf_symbol_type *) (sym))->internal_elf_sym.st_other == STO_MIPS16)
{
MSYMBOL_TARGET_FLAG_1 (msym) = 1;
- SYMBOL_VALUE_ADDRESS (msym) |= 1;
}
}
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
-/* The list of available "set mips " and "show mips " commands */
+/* The list of available "set mips " and "show mips " commands. */
static struct cmd_list_element *setmipscmdlist = NULL;
static struct cmd_list_element *showmipscmdlist = NULL;
enum mips_abi abi = mips_abi (gdbarch);
/* Map [gdbarch_num_regs .. 2*gdbarch_num_regs) onto the raw registers,
- but then don't make the raw register names visible. */
+ but then don't make the raw register names visible. This (upper)
+ range of user visible register numbers are the pseudo-registers.
+
+ This approach was adopted accommodate the following scenario:
+ It is possible to debug a 64-bit device using a 32-bit
+ programming model. In such instances, the raw registers are
+ configured to be 64-bits wide, while the pseudo registers are
+ configured to be 32-bits wide. The registers that the user
+ sees - the pseudo registers - match the users expectations
+ given the programming model being used. */
int rawnum = regno % gdbarch_num_regs (gdbarch);
if (regno < gdbarch_num_regs (gdbarch))
return "";
gdbarch_num_regs .. 2 * gdbarch_num_regs) back onto the corresponding raw
registers. Take care of alignment and size problems. */
-static void
+static enum register_status
mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int cookednum, gdb_byte *buf)
{
gdb_assert (cookednum >= gdbarch_num_regs (gdbarch)
&& cookednum < 2 * gdbarch_num_regs (gdbarch));
if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
- regcache_raw_read (regcache, rawnum, buf);
+ return regcache_raw_read (regcache, rawnum, buf);
else if (register_size (gdbarch, rawnum) >
register_size (gdbarch, cookednum))
{
- if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
- || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
- regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
+ if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
+ return regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
else
- regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
+ {
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ LONGEST regval;
+ enum register_status status;
+
+ status = regcache_raw_read_signed (regcache, rawnum, ®val);
+ if (status == REG_VALID)
+ store_signed_integer (buf, 4, byte_order, regval);
+ return status;
+ }
}
else
internal_error (__FILE__, __LINE__, _("bad register size"));
else if (register_size (gdbarch, rawnum) >
register_size (gdbarch, cookednum))
{
- if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
- || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+ if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
else
- regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
+ {
+ /* Sign extend the shortened version of the register prior
+ to placing it in the raw register. This is required for
+ some mips64 parts in order to avoid unpredictable behavior. */
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ LONGEST regval = extract_signed_integer (buf, 4, byte_order);
+ regcache_raw_write_signed (regcache, rawnum, regval);
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__, _("bad register size"));
+}
+
+static int
+mips_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = reg % gdbarch_num_regs (gdbarch);
+ gdb_assert (reg >= gdbarch_num_regs (gdbarch)
+ && reg < 2 * gdbarch_num_regs (gdbarch));
+
+ ax_reg_mask (ax, rawnum);
+
+ return 0;
+}
+
+static int
+mips_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = reg % gdbarch_num_regs (gdbarch);
+ gdb_assert (reg >= gdbarch_num_regs (gdbarch)
+ && reg < 2 * gdbarch_num_regs (gdbarch));
+ if (register_size (gdbarch, rawnum) >= register_size (gdbarch, reg))
+ {
+ ax_reg (ax, rawnum);
+
+ if (register_size (gdbarch, rawnum) > register_size (gdbarch, reg))
+ {
+ if (!gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
+ || gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
+ {
+ ax_const_l (ax, 32);
+ ax_simple (ax, aop_lsh);
+ }
+ ax_const_l (ax, 32);
+ ax_simple (ax, aop_rsh_signed);
+ }
}
else
internal_error (__FILE__, __LINE__, _("bad register size"));
+
+ return 0;
}
/* Table to translate MIPS16 register field to actual register number. */
/* Convert to/from a register and the corresponding memory value. */
+/* This predicate tests for the case of an 8 byte floating point
+ value that is being transferred to or from a pair of floating point
+ registers each of which are (or are considered to be) only 4 bytes
+ wide. */
static int
-mips_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
+mips_convert_register_float_case_p (struct gdbarch *gdbarch, int regnum,
+ struct type *type)
{
return (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
&& register_size (gdbarch, regnum) == 4
&& TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8);
}
-static void
+/* This predicate tests for the case of a value of less than 8
+ bytes in width that is being transfered to or from an 8 byte
+ general purpose register. */
+static int
+mips_convert_register_gpreg_case_p (struct gdbarch *gdbarch, int regnum,
+ struct type *type)
+{
+ int num_regs = gdbarch_num_regs (gdbarch);
+
+ return (register_size (gdbarch, regnum) == 8
+ && regnum % num_regs > 0 && regnum % num_regs < 32
+ && TYPE_LENGTH (type) < 8);
+}
+
+static int
+mips_convert_register_p (struct gdbarch *gdbarch,
+ int regnum, struct type *type)
+{
+ return mips_convert_register_float_case_p (gdbarch, regnum, type)
+ || mips_convert_register_gpreg_case_p (gdbarch, regnum, type);
+}
+
+static int
mips_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to)
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
- get_frame_register (frame, regnum + 0, to + 4);
- get_frame_register (frame, regnum + 1, to + 0);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+
+ if (mips_convert_register_float_case_p (gdbarch, regnum, type))
+ {
+ get_frame_register (frame, regnum + 0, to + 4);
+ get_frame_register (frame, regnum + 1, to + 0);
+
+ if (!get_frame_register_bytes (frame, regnum + 0, 0, 4, to + 4,
+ optimizedp, unavailablep))
+ return 0;
+
+ if (!get_frame_register_bytes (frame, regnum + 1, 0, 4, to + 0,
+ optimizedp, unavailablep))
+ return 0;
+ *optimizedp = *unavailablep = 0;
+ return 1;
+ }
+ else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
+ {
+ int len = TYPE_LENGTH (type);
+ CORE_ADDR offset;
+
+ offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 8 - len : 0;
+ if (!get_frame_register_bytes (frame, regnum, offset, len, to,
+ optimizedp, unavailablep))
+ return 0;
+
+ *optimizedp = *unavailablep = 0;
+ return 1;
+ }
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ _("mips_register_to_value: unrecognized case"));
+ }
}
static void
mips_value_to_register (struct frame_info *frame, int regnum,
struct type *type, const gdb_byte *from)
{
- put_frame_register (frame, regnum + 0, from + 4);
- put_frame_register (frame, regnum + 1, from + 0);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+
+ if (mips_convert_register_float_case_p (gdbarch, regnum, type))
+ {
+ put_frame_register (frame, regnum + 0, from + 4);
+ put_frame_register (frame, regnum + 1, from + 0);
+ }
+ else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
+ {
+ gdb_byte fill[8];
+ int len = TYPE_LENGTH (type);
+
+ /* Sign extend values, irrespective of type, that are stored to
+ a 64-bit general purpose register. (32-bit unsigned values
+ are stored as signed quantities within a 64-bit register.
+ When performing an operation, in compiled code, that combines
+ a 32-bit unsigned value with a signed 64-bit value, a type
+ conversion is first performed that zeroes out the high 32 bits.) */
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ {
+ if (from[0] & 0x80)
+ store_signed_integer (fill, 8, BFD_ENDIAN_BIG, -1);
+ else
+ store_signed_integer (fill, 8, BFD_ENDIAN_BIG, 0);
+ put_frame_register_bytes (frame, regnum, 0, 8 - len, fill);
+ put_frame_register_bytes (frame, regnum, 8 - len, len, from);
+ }
+ else
+ {
+ if (from[len-1] & 0x80)
+ store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, -1);
+ else
+ store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, 0);
+ put_frame_register_bytes (frame, regnum, 0, len, from);
+ put_frame_register_bytes (frame, regnum, len, 8 - len, fill);
+ }
+ }
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ _("mips_value_to_register: unrecognized case"));
+ }
}
/* Return the GDB type object for the "standard" data type of data in
return rawtype;
}
-/* Should the upper word of 64-bit addresses be zeroed? */
+/* Should the upper word of 64-bit addresses be zeroed? */
enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO;
static int
case AUTO_BOOLEAN_AUTO:
return tdep->default_mask_address_p;
default:
- internal_error (__FILE__, __LINE__, _("mips_mask_address_p: bad switch"));
+ internal_error (__FILE__, __LINE__,
+ _("mips_mask_address_p: bad switch"));
return -1;
}
}
{
struct minimal_symbol *sym;
- /* If bit 0 of the address is set, assume this is a MIPS16 address. */
+ /* If bit 0 of the address is set, assume this is a MIPS16 address. */
if (is_mips16_addr (memaddr))
return 1;
}
/* MIPS believes that the PC has a sign extended value. Perhaps the
- all registers should be sign extended for simplicity? */
+ all registers should be sign extended for simplicity? */
static CORE_ADDR
mips_read_pc (struct regcache *regcache)
ULONGEST pc;
int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
regcache_cooked_read_signed (regcache, regnum, &pc);
+ if (is_mips16_addr (pc))
+ pc = unmake_mips16_addr (pc);
return pc;
}
static CORE_ADDR
mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- return frame_unwind_register_signed
- (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc);
+ ULONGEST pc;
+
+ pc = frame_unwind_register_signed
+ (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc);
+ if (is_mips16_addr (pc))
+ pc = unmake_mips16_addr (pc);
+ return pc;
}
static CORE_ADDR
mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
- regcache_cooked_write_unsigned (regcache, regnum, pc);
+ if (mips_pc_is_mips16 (pc))
+ regcache_cooked_write_unsigned (regcache, regnum, make_mips16_addr (pc));
+ else
+ regcache_cooked_write_unsigned (regcache, regnum, pc);
}
/* Fetch and return instruction from the specified location. If the PC
return extract_unsigned_integer (buf, instlen, byte_order);
}
-/* These the fields of 32 bit mips instructions */
+/* These are the fields of 32 bit mips instructions. */
#define mips32_op(x) (x >> 26)
#define itype_op(x) (x >> 26)
#define itype_rs(x) ((x >> 21) & 0x1f)
unsigned long inst;
int op;
inst = mips_fetch_instruction (gdbarch, pc);
- if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */
+ if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch
+ instruction. */
{
if (itype_op (inst) >> 2 == 5)
/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
pc += 8;
}
else
- pc += 4; /* Not a branch, next instruction is easy */
+ pc += 4; /* Not a branch, next instruction is easy. */
}
else
- { /* This gets way messy */
+ { /* This gets way messy. */
- /* Further subdivide into SPECIAL, REGIMM and other */
- switch (op = itype_op (inst) & 0x07) /* extract bits 28,27,26 */
+ /* Further subdivide into SPECIAL, REGIMM and other. */
+ switch (op = itype_op (inst) & 0x07) /* Extract bits 28,27,26. */
{
case 0: /* SPECIAL */
op = rtype_funct (inst);
{
case 8: /* JR */
case 9: /* JALR */
- /* Set PC to that address */
+ /* Set PC to that address. */
pc = get_frame_register_signed (frame, rtype_rs (inst));
break;
case 12: /* SYSCALL */
}
break; /* end SPECIAL */
- case 1: /* REGIMM */
+ case 1: /* REGIMM */
{
op = itype_rt (inst); /* branch condition */
switch (op)
{
unsigned long reg;
reg = jtype_target (inst) << 2;
- /* Upper four bits get never changed... */
+ /* Upper four bits get never changed... */
pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
}
break;
{
unsigned long reg;
reg = jtype_target (inst) << 2;
- pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff) + 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 */
} /* mips32_next_pc */
/* Decoding the next place to set a breakpoint is irregular for the
- mips 16 variant, but fortunately, there fewer instructions. We have to cope
- ith extensions for 16 bit instructions and a pair of actual 32 bit instructions.
- We dont want to set a single step instruction on the extend instruction
- either.
- */
+ mips 16 variant, but fortunately, there fewer instructions. We have
+ to cope ith extensions for 16 bit instructions and a pair of actual
+ 32 bit instructions. We dont want to set a single step instruction
+ on the extend instruction either. */
/* Lots of mips16 instruction formats */
/* Predicting jumps requires itype,ritype,i8type
- and their extensions extItype,extritype,extI8type
- */
+ and their extensions extItype,extritype,extI8type. */
enum mips16_inst_fmts
{
itype, /* 0 immediate 5,10 */
extshift64type /* 21 5,5,1,1,1,1,1,1,5,1,1,1,3,5 */
};
/* I am heaping all the fields of the formats into one structure and
- then, only the fields which are involved in instruction extension */
+ then, only the fields which are involved in instruction extension. */
struct upk_mips16
{
CORE_ADDR offset;
- unsigned int regx; /* Function in i8 type */
+ unsigned int regx; /* Function in i8 type. */
unsigned int regy;
};
CORE_ADDR value;
value = (extension >> 21) & 0x3f; /* * extract 15:11 */
value = value << 6;
- value |= (extension >> 16) & 0x1f; /* extrace 10:5 */
+ value |= (extension >> 16) & 0x1f; /* extract 10:5 */
value = value << 5;
value |= extension & 0x01f; /* extract 4:0 */
return value;
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[8];
- pc &= 0xfffffffe; /* clear the low order bit */
+ pc &= 0xfffffffe; /* Clear the low order bit. */
target_read_memory (pc, buf, 2);
return extract_unsigned_integer (buf, 2, byte_order);
}
else
{
value = inst & 0x7ff;
- /* FIXME : Consider sign extension */
+ /* FIXME : Consider sign extension. */
}
offset = value;
regx = -1;
break;
case ritype:
case i8type:
- { /* A register identifier and an offset */
+ { /* A register identifier and an offset. */
/* Most of the fields are the same as I type but the
- immediate value is of a different length */
+ immediate value is of a different length. */
CORE_ADDR value;
if (extension)
{
value = extended_offset (extension);
- value = value << 8; /* from the original instruction */
+ value = value << 8; /* from the original instruction */
value |= inst & 0xff; /* eleven bits from instruction */
regx = (extension >> 8) & 0x07; /* or i8 funct */
- if (value & 0x4000) /* test the sign bit , bit 26 */
+ if (value & 0x4000) /* Test the sign bit, bit 26. */
{
- value &= ~0x3fff; /* remove the sign bit */
+ value &= ~0x3fff; /* Remove the sign bit. */
value = -value;
}
}
{
value = inst & 0xff; /* 8 bits */
regx = (inst >> 8) & 0x07; /* or i8 funct */
- /* FIXME: Do sign extension , this format needs it */
- if (value & 0x80) /* THIS CONFUSES ME */
+ /* FIXME: Do sign extension, this format needs it. */
+ if (value & 0x80) /* THIS CONFUSES ME. */
{
- value &= 0xef; /* remove the sign bit */
+ value &= 0xef; /* Remove the sign bit. */
value = -value;
}
}
unsigned int nexthalf;
value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f);
value = value << 16;
- nexthalf = mips_fetch_instruction (gdbarch, pc + 2); /* low bit still set */
+ nexthalf = mips_fetch_instruction (gdbarch, pc + 2); /* low bit
+ still set. */
value |= nexthalf;
offset = value;
regx = -1;
pc += (offset << 1) + 2;
break;
}
- case 3: /* JAL , JALX - Watch out, these are 32 bit instruction */
+ case 3: /* JAL , JALX - Watch out, these are 32 bit
+ instructions. */
{
struct upk_mips16 upk;
unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
pc = add_offset_16 (pc, upk.offset);
if ((insn >> 10) & 0x01) /* Exchange mode */
- pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode */
+ pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode. */
else
pc |= 0x01;
break;
break;
case 1:
reg = 31;
- break; /* Function return instruction */
+ break; /* Function return instruction. */
case 2:
reg = upk.regx;
break;
case 30:
/* This is an instruction extension. Fetch the real instruction
(which follows the extension) and decode things based on
- that. */
+ that. */
{
pc += 2;
pc = extended_mips16_next_pc (frame, pc, insn,
/* The mips_next_pc function supports single_step when the remote
target monitor or stub is not developed enough to do a single_step.
It works by decoding the current instruction and predicting where a
- branch will go. This isnt hard because all the data is available.
+ branch will go. This isnt hard because all the data is available.
The MIPS32 and MIPS16 variants are quite different. */
static CORE_ADDR
mips_next_pc (struct frame_info *frame, CORE_ADDR pc)
unsigned short inst, /* current instruction */
int nbits, /* number of bits in imm field */
int scale, /* scale factor to be applied to imm */
- int is_signed) /* is the imm field signed? */
+ int is_signed) /* is the imm field signed? */
{
int offset;
struct mips_frame_cache *this_cache)
{
CORE_ADDR cur_pc;
- CORE_ADDR frame_addr = 0; /* Value of $r17, used as frame pointer */
+ CORE_ADDR frame_addr = 0; /* Value of $r17, used as frame pointer. */
CORE_ADDR sp;
long frame_offset = 0; /* Size of stack frame. */
long frame_adjust = 0; /* Offset of FP from SP. */
int frame_reg = MIPS_SP_REGNUM;
- unsigned short prev_inst = 0; /* saved copy of previous instruction */
+ unsigned short prev_inst = 0; /* saved copy of previous instruction. */
unsigned inst = 0; /* current instruction */
unsigned entry_inst = 0; /* the entry instruction */
unsigned save_inst = 0; /* the save instruction */
the immediate offset extension from it in mips16_get_imm. */
prev_inst = inst;
- /* Fetch and decode the instruction. */
+ /* Fetch and decode the instruction. */
inst = (unsigned short) mips_fetch_instruction (gdbarch, cur_pc);
/* Normally we ignore extend instructions. However, if it is
|| (inst & 0xff00) == 0xfb00) /* daddiu sp */
{
offset = mips16_get_imm (prev_inst, inst, 8, 8, 1);
- if (offset < 0) /* negative stack adjustment? */
+ if (offset < 0) /* Negative stack adjustment? */
frame_offset -= offset;
else
/* Exit loop if a positive stack adjustment is found, which
}
else if ((inst & 0xf81f) == 0xe809
&& (inst & 0x700) != 0x700) /* entry */
- entry_inst = inst; /* save for later processing */
+ entry_inst = inst; /* Save for later processing. */
else if ((inst & 0xff80) == 0x6480) /* save */
{
- save_inst = inst; /* save for later processing */
+ save_inst = inst; /* Save for later processing. */
if (prev_extend_bytes) /* extend */
save_inst |= prev_inst << 16;
}
(before the prologue). But the value of the sp parameter to this
function is the new SP (after the prologue has been executed). So we
can't calculate those offsets until we've seen the entire prologue,
- and can calculate what the old SP must have been. */
+ and can calculate what the old SP must have been. */
if (entry_inst != 0)
{
int areg_count = (entry_inst >> 8) & 7;
gdbarch_num_regs (gdbarch) + frame_reg)
+ frame_offset - frame_adjust);
/* FIXME: brobecker/2004-10-10: Just as in the mips32 case, we should
- be able to get rid of the assignment below, evetually. But it's
+ be able to get rid of the assignment below, evetually. But it's
still needed for now. */
this_cache->saved_regs[gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->pc]
static const struct frame_unwind mips_insn16_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
mips_insn16_frame_this_id,
mips_insn16_frame_prev_register,
NULL,
}
}
-/* Analyze the function prologue from START_PC to LIMIT_PC. Builds
+/* Analyze the function prologue from START_PC to LIMIT_PC. Builds
the associated FRAME_CACHE if not null.
Return the address of the first instruction past the prologue. */
struct mips_frame_cache *this_cache)
{
CORE_ADDR cur_pc;
- CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for frame-pointer */
+ CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for
+ frame-pointer. */
CORE_ADDR sp;
long frame_offset;
int frame_reg = MIPS_SP_REGNUM;
unsigned long inst, high_word, low_word;
int reg;
- /* Fetch the instruction. */
+ /* Fetch the instruction. */
inst = (unsigned long) mips_fetch_instruction (gdbarch, cur_pc);
/* Save some code by pre-extracting some useful fields. */
low_word = inst & 0xffff;
reg = high_word & 0x1f;
- if (high_word == 0x27bd /* addiu $sp,$sp,-i */
+ if (high_word == 0x27bd /* addiu $sp,$sp,-i */
|| high_word == 0x23bd /* addi $sp,$sp,-i */
|| high_word == 0x67bd) /* daddiu $sp,$sp,-i */
{
- if (low_word & 0x8000) /* negative stack adjustment? */
+ if (low_word & 0x8000) /* Negative stack adjustment? */
frame_offset += 0x10000 - low_word;
else
/* Exit loop if a positive stack adjustment is found, which
alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
if (alloca_adjust > 0)
{
- /* FP > SP + frame_size. This may be because of
+ /* FP > SP + frame_size. This may be because of
an alloca or somethings similar. Fix sp to
"pre-alloca" value, and try again. */
sp += alloca_adjust;
alloca_adjust = (unsigned) (frame_addr - sp);
if (alloca_adjust > 0)
{
- /* FP > SP + frame_size. This may be because of
+ /* FP > SP + frame_size. This may be because of
an alloca or somethings similar. Fix sp to
"pre-alloca" value, and try again. */
sp = frame_addr;
}
/* The instructions below load $at or $t0 with an immediate
value in preparation for a stack adjustment via
- subu $sp,$sp,[$at,$t0]. These instructions could also
+ subu $sp,$sp,[$at,$t0]. These instructions could also
initialize a local variable, so we accept them only before
a stack adjustment instruction was seen. */
else if (!seen_sp_adjust
end_prologue_addr = cur_pc;
/* In a frameless function, we might have incorrectly
- skipped some load immediate instructions. Undo the skipping
+ skipped some load immediate instructions. Undo the skipping
if the load immediate was not followed by a stack adjustment. */
if (load_immediate_bytes && !seen_sp_adjust)
end_prologue_addr -= load_immediate_bytes;
static const struct frame_unwind mips_insn32_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
mips_insn32_frame_this_id,
mips_insn32_frame_prev_register,
NULL,
static const struct frame_unwind mips_stub_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
mips_stub_frame_this_id,
mips_stub_frame_prev_register,
NULL,
mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (is_mips16_addr (addr))
+ addr = unmake_mips16_addr (addr);
+
if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
/* This hack is a work-around for existing boards using PMON, the
simulator, and any other 64-bit targets that doesn't have true
{
case 0: /* SPECIAL */
if (rtype_funct (insn) >> 1 == 4) /* JR, JALR */
- return 0; /* fallback to the standard single-step code. */
+ return 0; /* fallback to the standard single-step code. */
break;
case 1: /* REGIMM */
is_branch = ((itype_rt (insn) & 0xc0) == 0); /* B{LT,GE}Z* */
break;
case 2: /* J */
case 3: /* JAL */
- return 0; /* fallback to the standard single-step code. */
+ return 0; /* fallback to the standard single-step code. */
case 4: /* BEQ */
case 5: /* BNE */
case 6: /* BLEZ */
breaks[0] = loc;
/* Check for duplicated breakpoints. Check also for a breakpoint
- placed (branch instruction's destination) in the atomic sequence */
+ placed (branch instruction's destination) in the atomic sequence. */
if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
last_breakpoint = 0;
}
/* Test whether the PC points to the return instruction at the
- end of a function. */
+ end of a function. */
static int
mips_about_to_return (struct gdbarch *gdbarch, CORE_ADDR pc)
inf = current_inferior ();
- /* search back for previous return */
+ /* Search back for previous return. */
for (start_pc -= instlen;; start_pc -= instlen)
if (start_pc < fence)
{
stop_soon, but with this test, at least we
don't print out warnings for every child forked (eg, on
- if (inf->stop_soon == NO_STOP_QUIETLY)
+ if (inf->control.stop_soon == NO_STOP_QUIETLY)
{
static int blurb_printed = 0;
entry
addiu sp,-n
daddiu sp,-n
- extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
+ extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n'. */
inst = mips_fetch_instruction (gdbarch, start_pc);
if ((inst & 0xff80) == 0x6480) /* save */
{
floating-point register (assuming that there is space)? When there
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. */
+ arguments into integer registers. */
static int
fp_register_arg_p (struct gdbarch *gdbarch, enum type_code typecode,
}
/* 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. */
+ passed. Return 1 if this type must be aligned to a doubleword boundary. */
static int
mips_type_needs_double_align (struct type *type)
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_eabi_push_dummy_call: struct_return reg=%d %s\n",
+ "mips_eabi_push_dummy_call: "
+ "struct_return reg=%d %s\n",
argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
"mips_eabi_push_dummy_call: %d len=%d type=%d",
argnum + 1, len, (int) typecode);
+ /* Function pointer arguments to mips16 code need to be made into
+ mips16 pointers. */
+ if (typecode == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
+ {
+ CORE_ADDR addr = extract_signed_integer (value_contents (arg),
+ len, byte_order);
+ if (mips_pc_is_mips16 (addr))
+ {
+ store_signed_integer (valbuf, len, byte_order,
+ make_mips16_addr (addr));
+ val = valbuf;
+ }
+ else
+ val = value_contents (arg);
+ }
/* The EABI passes structures that do not fit in a register by
reference. */
- if (len > regsize
+ else if (len > regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
store_unsigned_integer (valbuf, regsize, byte_order,
{
int low_offset = gdbarch_byte_order (gdbarch)
== BFD_ENDIAN_BIG ? 4 : 0;
- unsigned long regval;
+ long regval;
/* Write the low word of the double to the even register(s). */
- regval = extract_unsigned_integer (val + low_offset,
- 4, byte_order);
+ regval = extract_signed_integer (val + low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_signed (regcache, float_argreg++, regval);
/* Write the high word of the double to the odd register(s). */
- regval = extract_unsigned_integer (val + 4 - low_offset,
- 4, byte_order);
+ regval = extract_signed_integer (val + 4 - low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_signed (regcache, float_argreg++, regval);
}
else
{
in a single register. */
/* On 32 bit ABI's the float_argreg is further adjusted
above to ensure that it is even register aligned. */
- LONGEST regval = extract_unsigned_integer (val, len, byte_order);
+ LONGEST regval = extract_signed_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_signed (regcache, float_argreg++, regval);
}
}
else
|| fp_register_arg_p (gdbarch, typecode, arg_type))
{
/* Should shorter than int integer values be
- promoted to int before being stored? */
+ promoted to int before being stored? */
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
&& !fp_register_arg_p (gdbarch, typecode, arg_type))
{
LONGEST regval =
- extract_unsigned_integer (val, partial_len, byte_order);
+ extract_signed_integer (val, partial_len, byte_order);
if (mips_debug)
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
phex (regval, regsize));
- regcache_cooked_write_unsigned (regcache, argreg, regval);
+ regcache_cooked_write_signed (regcache, argreg, regval);
argreg++;
}
len -= partial_len;
val += partial_len;
- /* Compute the the offset into the stack at which we
- will copy the next parameter.
+ /* Compute the offset into the stack at which we will
+ copy the next parameter.
In the new EABI (and the NABI32), the stack_offset
only needs to be adjusted when it has been used. */
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_n32n64_push_dummy_call: struct_return reg=%d %s\n",
+ "mips_n32n64_push_dummy_call: "
+ "struct_return reg=%d %s\n",
argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
if (argreg > MIPS_LAST_ARG_REGNUM (gdbarch))
{
/* Should shorter than int integer values be
- promoted to int before being stored? */
+ promoted to int before being stored? */
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
len -= partial_len;
val += partial_len;
- /* Compute the the offset into the stack at which we
- will copy the next parameter.
+ /* Compute the offset into the stack at which we will
+ copy the next parameter.
In N32 (N64?), the stack_offset only needs to be
adjusted when it has been used. */
(and $f2 if necessary). This is a generalization of the Fortran COMPLEX
case.
- * Any other struct or union results of at most 128 bits are returned in
+ * Any other composite results of at most 128 bits are returned in
$2 (first 64 bits) and $3 (remainder, if necessary).
* Larger composite results are handled by converting the function to a
specific exception to return COMPLEX results in the floating point
registers.] */
- if (TYPE_CODE (type) == TYPE_CODE_ARRAY
- || TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
+ if (TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
return RETURN_VALUE_STRUCT_CONVENTION;
else if (TYPE_CODE (type) == TYPE_CODE_FLT
&& TYPE_LENGTH (type) == 16
return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION)
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
- /* A structure or union. Extract the left justified value,
+ /* A composite type. Extract the left justified value,
regardless of the byte order. I.e. DO NOT USE
mips_xfer_lower. */
int offset;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o32_push_dummy_call: struct_return reg=%d %s\n",
+ "mips_o32_push_dummy_call: "
+ "struct_return reg=%d %s\n",
argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
stack_offset += MIPS32_REGSIZE;
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_unsigned (regcache,
+ float_argreg++, regval);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
argreg, phex (regval, 4));
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_unsigned (regcache,
+ float_argreg++, regval);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_unsigned (regcache,
+ float_argreg++, regval);
/* Although two FP registers are reserved for each
argument, only one corresponding integer register is
reserved. */
|| odd_sized_struct)
{
/* Should shorter than int integer values be
- promoted to int before being stored? */
+ promoted to int before being stored? */
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
len -= partial_len;
val += partial_len;
- /* Compute the the offset into the stack at which we
- will copy the next parameter.
+ /* Compute the offset into the stack at which we will
+ copy the next parameter.
In older ABIs, the caller reserved space for
registers that contained arguments. This was loosely
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o64_push_dummy_call: struct_return reg=%d %s\n",
+ "mips_o64_push_dummy_call: "
+ "struct_return reg=%d %s\n",
argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
stack_offset += MIPS64_REGSIZE;
for (argnum = 0; argnum < nargs; argnum++)
{
const gdb_byte *val;
+ gdb_byte valbuf[MAX_REGISTER_SIZE];
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
val = value_contents (arg);
+ /* Function pointer arguments to mips16 code need to be made into
+ mips16 pointers. */
+ if (typecode == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
+ {
+ CORE_ADDR addr = extract_signed_integer (value_contents (arg),
+ len, byte_order);
+ if (mips_pc_is_mips16 (addr))
+ {
+ store_signed_integer (valbuf, len, byte_order,
+ make_mips16_addr (addr));
+ val = valbuf;
+ }
+ }
+
/* Floating point arguments passed in registers have to be
treated specially. On 32-bit architectures, doubles
are passed in register pairs; the even register gets
|| odd_sized_struct)
{
/* Should shorter than int integer values be
- promoted to int before being stored? */
+ promoted to int before being stored? */
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
big endian targets.
It does not seem to be necessary to do the
- same for integral types. */
+ same for integral types. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
&& partial_len < MIPS64_REGSIZE
len -= partial_len;
val += partial_len;
- /* Compute the the offset into the stack at which we
- will copy the next parameter.
+ /* Compute the offset into the stack at which we will
+ copy the next parameter.
In older ABIs, the caller reserved space for
registers that contained arguments. This was loosely
else
{
/* A scalar extract each part but least-significant-byte
- justified. */
+ justified. */
int offset;
int regnum;
for (offset = 0, regnum = MIPS_V0_REGNUM;
Note that this code only deals with "live" registers at the top of the
stack. We will attempt to deal with saved registers later, when
- the raw/cooked register interface is in place. (We need a general
+ the raw/cooked register interface is in place. (We need a general
interface that can deal with dynamic saved register sizes -- fp
regs could be 32 bits wide in one frame and 64 on the frame above
and below). */
static void
mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
int regnum)
-{ /* do values for FP (float) regs */
+{ /* Do values for FP (float) regs. */
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte *raw_buffer;
- double doub, flt1; /* doubles extracted from raw hex data */
+ double doub, flt1; /* Doubles extracted from raw hex data. */
int inv1, inv2;
- raw_buffer = alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0));
+ raw_buffer = alloca (2 * register_size (gdbarch,
+ mips_regnum (gdbarch)->fp0));
fprintf_filtered (file, "%s:", gdbarch_register_name (gdbarch, regnum));
fprintf_filtered (file, "%*s",
/* 4-byte registers: Print hex and floating. Also print even
numbered registers as doubles. */
mips_read_fp_register_single (frame, regnum, raw_buffer);
- flt1 = unpack_double (builtin_type (gdbarch)->builtin_float, raw_buffer, &inv1);
+ flt1 = unpack_double (builtin_type (gdbarch)->builtin_float,
+ raw_buffer, &inv1);
get_formatted_print_options (&opts, 'x');
print_scalar_formatted (raw_buffer,
int regnum)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte raw_buffer[MAX_REGISTER_SIZE];
int offset;
struct value_print_options opts;
+ struct value *val;
if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
{
return;
}
- /* Get the data in raw format. */
- if (!frame_register_read (frame, regnum, raw_buffer))
+ val = get_frame_register_value (frame, regnum);
+ if (value_optimized_out (val))
{
fprintf_filtered (file, "%s: [Invalid]",
gdbarch_register_name (gdbarch, regnum));
else
fprintf_filtered (file, ": ");
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- offset =
- register_size (gdbarch, regnum) - register_size (gdbarch, regnum);
- else
- offset = 0;
-
get_formatted_print_options (&opts, 'x');
- print_scalar_formatted (raw_buffer + offset,
- register_type (gdbarch, regnum), &opts, 0,
- file);
+ val_print_scalar_formatted (value_type (val),
+ value_contents_for_printing (val),
+ value_embedded_offset (val),
+ val,
+ &opts, 0, file);
}
/* Replacement for generic do_registers_info.
}
-/* Print a row's worth of GP (int) registers, with name labels above */
+/* Print a row's worth of GP (int) registers, with name labels above. */
static int
print_gp_register_row (struct ui_file *file, struct frame_info *frame,
int start_regnum)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- /* do values for GP (int) regs */
+ /* Do values for GP (int) regs. */
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
- int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8); /* display cols per row */
+ int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8); /* display cols
+ per row. */
int col, byte;
int regnum;
- /* For GP registers, we print a separate row of names above the vals */
+ /* For GP registers, we print a separate row of names above the vals. */
for (col = 0, regnum = start_regnum;
col < ncols && regnum < gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch);
continue; /* unused register */
if (TYPE_CODE (register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
- break; /* end the row: reached FP register */
+ break; /* End the row: reached FP register. */
/* Large registers are handled separately. */
if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch))
{
if (col == 0)
return regnum;
- /* print the R0 to R31 names */
+ /* Print the R0 to R31 names. */
if ((start_regnum % gdbarch_num_regs (gdbarch)) < MIPS_NUMREGS)
fprintf_filtered (file, "\n R%-4d",
start_regnum % gdbarch_num_regs (gdbarch));
else
fprintf_filtered (file, "\n ");
- /* now print the values in hex, 4 or 8 to the row */
+ /* Now print the values in hex, 4 or 8 to the row. */
for (col = 0, regnum = start_regnum;
col < ncols && regnum < gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch);
continue; /* unused register */
if (TYPE_CODE (register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
- break; /* end row: reached FP register */
+ break; /* End row: reached FP register. */
if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch))
break; /* End row: large register. */
byte < (mips_abi_regsize (gdbarch)
- register_size (gdbarch, regnum)); byte++)
printf_filtered (" ");
- /* Now print the register value in hex, endian order. */
+ /* Now print the register value in hex, endian order. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
for (byte =
register_size (gdbarch, regnum) - register_size (gdbarch, regnum);
fprintf_filtered (file, " ");
col++;
}
- if (col > 0) /* ie. if we actually printed anything... */
+ if (col > 0) /* ie. if we actually printed anything... */
fprintf_filtered (file, "\n");
return regnum;
}
-/* MIPS_DO_REGISTERS_INFO(): called by "info register" command */
+/* MIPS_DO_REGISTERS_INFO(): called by "info register" command. */
static void
mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
struct frame_info *frame, int regnum, int all)
{
- if (regnum != -1) /* do one specified register */
+ if (regnum != -1) /* Do one specified register. */
{
gdb_assert (regnum >= gdbarch_num_regs (gdbarch));
if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
fprintf_filtered (file, "\n");
}
else
- /* do all (or most) registers */
+ /* Do all (or most) registers. */
{
regnum = gdbarch_num_regs (gdbarch);
while (regnum < gdbarch_num_regs (gdbarch)
if (TYPE_CODE (register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
{
- if (all) /* true for "INFO ALL-REGISTERS" command */
+ if (all) /* True for "INFO ALL-REGISTERS" command. */
regnum = print_fp_register_row (file, frame, regnum);
else
- regnum += MIPS_NUMREGS; /* skip floating point regs */
+ regnum += MIPS_NUMREGS; /* Skip floating point regs. */
}
else
regnum = print_gp_register_row (file, frame, regnum);
return mips32_in_function_epilogue_p (gdbarch, pc);
}
-/* Root of all "set mips "/"show mips " commands. This will eventually be
+/* Root of all "set mips "/"show mips " commands. This will eventually be
used for all MIPS-specific commands. */
static void
internal_error (__FILE__, __LINE__, _("bad switch"));
}
if (mips_fpu_type_auto)
- printf_unfiltered
- ("The MIPS floating-point coprocessor is set automatically (currently %s)\n",
- fpu);
+ printf_unfiltered ("The MIPS floating-point coprocessor "
+ "is set automatically (currently %s)\n",
+ fpu);
else
printf_unfiltered
("The MIPS floating-point coprocessor is assumed to be %s\n", fpu);
static void
set_mipsfpu_command (char *args, int from_tty)
{
- printf_unfiltered
- ("\"set mipsfpu\" must be followed by \"double\", \"single\",\"none\" or \"auto\".\n");
+ printf_unfiltered ("\"set mipsfpu\" must be followed by \"double\", "
+ "\"single\",\"none\" or \"auto\".\n");
show_mipsfpu_command (args, from_tty);
}
return gdb_print_insn_mips (memaddr, info);
}
-/* This function implements gdbarch_breakpoint_from_pc. It uses the program
- counter value to determine whether a 16- or 32-bit breakpoint should be used.
- It returns a pointer to a string of bytes that encode a breakpoint
- instruction, stores the length of the string to *lenptr, and adjusts pc (if
- necessary) to point to the actual memory location where the breakpoint
- should be inserted. */
+/* This function implements gdbarch_breakpoint_from_pc. It uses the
+ program counter value to determine whether a 16- or 32-bit breakpoint
+ should be used. It returns a pointer to a string of bytes that encode a
+ breakpoint instruction, stores the length of the string to *lenptr, and
+ adjusts pc (if necessary) to point to the actual memory location where
+ the breakpoint should be inserted. */
static const gdb_byte *
-mips_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+mips_breakpoint_from_pc (struct gdbarch *gdbarch,
+ CORE_ADDR *pcptr, int *lenptr)
{
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
static gdb_byte pmon_big_breakpoint[] = { 0, 0, 0, 0xd };
static gdb_byte idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd };
+ /* Likewise, IRIX appears to expect a different breakpoint,
+ although this is not apparent until you try to use pthreads. */
+ static gdb_byte irix_big_breakpoint[] = { 0, 0, 0, 0xd };
*lenptr = sizeof (big_breakpoint);
|| strcmp (target_shortname, "pmon") == 0
|| strcmp (target_shortname, "lsi") == 0)
return pmon_big_breakpoint;
+ else if (gdbarch_osabi (gdbarch) == GDB_OSABI_IRIX)
+ return irix_big_breakpoint;
else
return big_breakpoint;
}
and the target PC is in $2.
* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
before the jal instruction, this is effectively a call stub
- and the the target PC is in $2. Otherwise this is effectively
+ and the target PC is in $2. Otherwise this is effectively
a return stub and the target PC is in $18.
See the source code for the stubs in gcc/config/mips/mips16.S for
/* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
before the jal instruction, this is effectively a call stub
- and the the target PC is in $2. Otherwise this is effectively
+ and the target PC is in $2. Otherwise this is effectively
a return stub and the target PC is in $18. */
else if (name[19] == 's' || name[19] == 'd')
{
{
inst = mips_fetch_instruction (gdbarch, target_pc);
if ((inst & 0xffff0000) == 0x3c010000) /* lui $at */
- pc = (inst << 16) & 0xffff0000; /* high word */
+ pc = (inst << 16) & 0xffff0000; /* high word */
else if ((inst & 0xffff0000) == 0x24210000) /* addiu $at */
- return pc | (inst & 0xffff); /* low word */
+ return pc | (inst & 0xffff); /* low word */
}
/* Couldn't find the lui/addui pair, so return stub address. */
if (gdbarch_register_name (gdbarch,
gdbarch_num_regs (gdbarch) + regnum) != NULL
&& gdbarch_register_name (gdbarch,
- gdbarch_num_regs (gdbarch) + regnum)[0] != '\0')
+ gdbarch_num_regs (gdbarch)
+ + regnum)[0] != '\0')
return regnum;
else
return LEGACY_SIM_REGNO_IGNORE;
/* Also used when doing an architecture lookup. */
if (gdbarch_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_gdbarch_init: mips64_transfers_32bit_regs_p = %d\n",
+ "mips_gdbarch_init: "
+ "mips64_transfers_32bit_regs_p = %d\n",
mips64_transfers_32bit_regs_p);
/* Determine the MIPS FPU type. */
return NULL;
}
- /* try to find a pre-existing architecture */
+ /* Try to find a pre-existing architecture. */
for (arches = gdbarch_list_lookup_by_info (arches, &info);
arches != NULL;
arches = gdbarch_list_lookup_by_info (arches->next, &info))
tdep->mips_fpu_type = fpu_type;
tdep->register_size_valid_p = 0;
tdep->register_size = 0;
+ tdep->gregset = NULL;
+ tdep->gregset64 = NULL;
+ tdep->fpregset = NULL;
+ tdep->fpregset64 = NULL;
if (info.target_desc)
{
set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
+ set_gdbarch_ax_pseudo_register_collect (gdbarch,
+ mips_ax_pseudo_register_collect);
+ set_gdbarch_ax_pseudo_register_push_stack
+ (gdbarch, mips_ax_pseudo_register_push_stack);
+
set_gdbarch_elf_make_msymbol_special (gdbarch,
mips_elf_make_msymbol_special);
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.
- */
+ longs are the same, as set by -mlongXX or set by defaults. */
if (info.abfd != NULL)
{
mips_dwarf_dwarf2_ecoff_reg_to_regnum);
set_gdbarch_register_sim_regno (gdbarch, mips_register_sim_regno);
- /* MIPS version of CALL_DUMMY */
+ /* MIPS version of CALL_DUMMY. */
/* NOTE: cagney/2003-08-05: Eventually call dummy location will be
replaced by a command, and all targets will default to on stack
set_gdbarch_skip_trampoline_code (gdbarch, mips_skip_trampoline_code);
- set_gdbarch_single_step_through_delay (gdbarch, mips_single_step_through_delay);
+ set_gdbarch_single_step_through_delay (gdbarch,
+ mips_single_step_through_delay);
/* Virtual tables. */
set_gdbarch_vbit_in_delta (gdbarch, 1);
/* Override the normal target description methods to handle our
dual real and pseudo registers. */
set_gdbarch_register_name (gdbarch, mips_register_name);
- set_gdbarch_register_reggroup_p (gdbarch, mips_tdesc_register_reggroup_p);
+ set_gdbarch_register_reggroup_p (gdbarch,
+ mips_tdesc_register_reggroup_p);
num_regs = gdbarch_num_regs (gdbarch);
set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
else
{
/* Probably shouldn't happen... */
- fprintf_filtered
- (file,
- "The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n",
+ fprintf_filtered (file,
+ "The (auto detected) MIPS ABI \"%s\" is in use "
+ "even though the user setting was \"%s\".\n",
actual_abi_str, mips_abi_strings[global_abi]);
}
}
"mips_dump_tdep: tdep->mips_abi = %d (%s)\n",
tdep->mips_abi, mips_abi_strings[tdep->mips_abi]);
fprintf_unfiltered (file,
- "mips_dump_tdep: mips_mask_address_p() %d (default %d)\n",
+ "mips_dump_tdep: "
+ "mips_mask_address_p() %d (default %d)\n",
mips_mask_address_p (tdep),
tdep->default_mask_address_p);
}
: "???"));
}
-extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */
void
_initialize_mips_tdep (void)
mips_tdesc_gp64 = allocate_target_description ();
set_tdesc_property (mips_tdesc_gp64, PROPERTY_GP64, "");
- /* Add root prefix command for all "set mips"/"show mips" commands */
+ /* Add root prefix command for all "set mips"/"show mips" commands. */
add_prefix_cmd ("mips", no_class, set_mips_command,
_("Various MIPS specific commands."),
&setmipscmdlist, "set mips ", 0, &setlist);
_("Various MIPS specific commands."),
&showmipscmdlist, "show mips ", 0, &showlist);
- /* Allow the user to override the ABI. */
+ /* Allow the user to override the ABI. */
add_setshow_enum_cmd ("abi", class_obscure, mips_abi_strings,
&mips_abi_string, _("\
Set the MIPS ABI used by this program."), _("\
program for the start of a function. This command sets the distance of the\n\
search. The only need to set it is when debugging a stripped executable."),
reinit_frame_cache_sfunc,
- NULL, /* FIXME: i18n: The distance searched for the start of a function is %s. */
+ NULL, /* FIXME: i18n: The distance searched for
+ the start of a function is %s. */
&setlist, &showlist);
/* Allow the user to control whether the upper bits of 64-bit
&mask_address_var, _("\
Set zeroing of upper 32 bits of 64-bit addresses."), _("\
Show zeroing of upper 32 bits of 64-bit addresses."), _("\
-Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to \n\
+Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to\n\
allow GDB to determine the correct value."),
NULL, show_mask_address,
&setmipscmdlist, &showmipscmdlist);
that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
64 bits for others. Use \"off\" to disable compatibility mode"),
set_mips64_transfers_32bit_regs,
- NULL, /* FIXME: i18n: Compatibility with 64-bit MIPS target that transfers 32-bit quantities is %s. */
+ NULL, /* FIXME: i18n: Compatibility with 64-bit
+ MIPS target that transfers 32-bit
+ quantities is %s. */
&setlist, &showlist);
- /* Debug this files internals. */
+ /* Debug this files internals. */
add_setshow_zinteger_cmd ("mips", class_maintenance,
&mips_debug, _("\
Set mips debugging."), _("\
Show mips debugging."), _("\
When non-zero, mips specific debugging is enabled."),
NULL,
- NULL, /* FIXME: i18n: Mips debugging is currently %s. */
+ NULL, /* FIXME: i18n: Mips debugging is
+ currently %s. */
&setdebuglist, &showdebuglist);
}