/* 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, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010 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 "target-descriptions.h"
#include "dwarf2-frame.h"
#include "user-regs.h"
+#include "valprint.h"
static const struct objfile_data *mips_pdr_data;
{ "fsr", MIPS_EMBED_FP0_REGNUM + 32 }
};
+const struct register_alias mips_numeric_register_aliases[] = {
+#define R(n) { #n, n }
+ R(0), R(1), R(2), R(3), R(4), R(5), R(6), R(7),
+ R(8), R(9), R(10), R(11), R(12), R(13), R(14), R(15),
+ R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
+ R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
+#undef R
+};
+
#ifndef MIPS_DEFAULT_FPU_TYPE
#define MIPS_DEFAULT_FPU_TYPE MIPS_FPU_DOUBLE
#endif
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
-static struct type *mips_float_register_type (void);
-static struct type *mips_double_register_type (void);
-
/* The list of available "set mips " and "show mips " commands */
static struct cmd_list_element *setmipscmdlist = NULL;
/* The floating-point registers raw, or cooked, always match
mips_isa_regsize(), and also map 1:1, byte for byte. */
if (mips_isa_regsize (gdbarch) == 4)
- return builtin_type_ieee_single;
+ return builtin_type (gdbarch)->builtin_float;
else
- return builtin_type_ieee_double;
+ return builtin_type (gdbarch)->builtin_double;
}
else if (regnum < gdbarch_num_regs (gdbarch))
{
/* The raw or ISA registers. These are all sized according to
the ISA regsize. */
if (mips_isa_regsize (gdbarch) == 4)
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else
- return builtin_type_int64;
+ return builtin_type (gdbarch)->builtin_int64;
}
else
{
&& regnum <= gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM)
/* The pseudo/cooked view of the embedded registers is always
32-bit. The raw view is handled below. */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
/* The target, while possibly using a 64-bit register buffer,
is only transfering 32-bits of each integer register.
Reflect this in the cooked/pseudo (ABI) register value. */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else if (mips_abi_regsize (gdbarch) == 4)
/* The ABI is restricted to 32-bit registers (the ISA could be
32- or 64-bit). */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else
/* 64-bit ABI. */
- return builtin_type_int64;
+ return builtin_type (gdbarch)->builtin_int64;
}
}
the necessary 32 bits, but older versions of GDB expected 64,
so allow the target to provide 64 bits without interfering
with the displayed type. */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
}
/* Use pointer types for registers if we can. For n32 we can not,
if (mips_abi_regsize (gdbarch) == 4 && TYPE_LENGTH (rawtype) == 8
&& rawnum >= MIPS_ZERO_REGNUM && rawnum <= MIPS_EMBED_PC_REGNUM)
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
/* For all other registers, pass through the hardware type. */
return rawtype;
is odd, assume it's a MIPS16 instruction; otherwise MIPS32. */
static ULONGEST
-mips_fetch_instruction (CORE_ADDR addr)
+mips_fetch_instruction (struct gdbarch *gdbarch, CORE_ADDR addr)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[MIPS_INSN32_SIZE];
int instlen;
int status;
status = target_read_memory (addr, buf, instlen);
if (status)
memory_error (status, addr);
- return extract_unsigned_integer (buf, instlen);
+ return extract_unsigned_integer (buf, instlen, byte_order);
}
/* These the fields of 32 bit mips instructions */
static CORE_ADDR
mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
unsigned long inst;
int op;
- inst = mips_fetch_instruction (pc);
+ inst = mips_fetch_instruction (gdbarch, pc);
if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */
{
if (itype_op (inst) >> 2 == 5)
when the offset is to be used in relative addressing. */
static unsigned int
-fetch_mips_16 (CORE_ADDR pc)
+fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[8];
pc &= 0xfffffffe; /* clear the low order bit */
target_read_memory (pc, buf, 2);
- return extract_unsigned_integer (buf, 2);
+ return extract_unsigned_integer (buf, 2, byte_order);
}
static void
-unpack_mips16 (CORE_ADDR pc,
+unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
unsigned int extension,
unsigned int inst,
enum mips16_inst_fmts insn_format, struct upk_mips16 *upk)
unsigned int nexthalf;
value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f);
value = value << 16;
- nexthalf = mips_fetch_instruction (pc + 2); /* low bit still set */
+ nexthalf = mips_fetch_instruction (gdbarch, pc + 2); /* low bit still set */
value |= nexthalf;
offset = value;
regx = -1;
extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
unsigned int extension, unsigned int insn)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
int op = (insn >> 11);
switch (op)
{
{
CORE_ADDR offset;
struct upk_mips16 upk;
- unpack_mips16 (pc, extension, insn, itype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
offset = upk.offset;
if (offset & 0x800)
{
case 3: /* JAL , JALX - Watch out, these are 32 bit instruction */
{
struct upk_mips16 upk;
- unpack_mips16 (pc, extension, insn, jalxtype, &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 */
{
struct upk_mips16 upk;
int reg;
- unpack_mips16 (pc, extension, insn, ritype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
reg = get_frame_register_signed (frame, upk.regx);
if (reg == 0)
pc += (upk.offset << 1) + 2;
{
struct upk_mips16 upk;
int reg;
- unpack_mips16 (pc, extension, insn, ritype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
reg = get_frame_register_signed (frame, upk.regx);
if (reg != 0)
pc += (upk.offset << 1) + 2;
{
struct upk_mips16 upk;
int reg;
- unpack_mips16 (pc, extension, insn, i8type, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, i8type, &upk);
/* upk.regx contains the opcode */
reg = get_frame_register_signed (frame, 24); /* Test register is 24 */
if (((upk.regx == 0) && (reg == 0)) /* BTEZ */
that. */
{
pc += 2;
- pc = extended_mips16_next_pc (frame, pc, insn, fetch_mips_16 (pc));
+ pc = extended_mips16_next_pc (frame, pc, insn,
+ fetch_mips_16 (gdbarch, pc));
break;
}
default:
static CORE_ADDR
mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
- unsigned int insn = fetch_mips_16 (pc);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ unsigned int insn = fetch_mips_16 (gdbarch, pc);
return extended_mips16_next_pc (frame, pc, 0, insn);
}
Return the address of the first instruction past the prologue. */
static CORE_ADDR
-mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+mips16_scan_prologue (struct gdbarch *gdbarch,
+ CORE_ADDR start_pc, CORE_ADDR limit_pc,
struct frame_info *this_frame,
struct mips_frame_cache *this_cache)
{
int extend_bytes = 0;
int prev_extend_bytes;
CORE_ADDR end_prologue_addr = 0;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
/* Can be called when there's no process, and hence when there's no
THIS_FRAME. */
prev_inst = inst;
/* Fetch and decode the instruction. */
- inst = (unsigned short) mips_fetch_instruction (cur_pc);
+ inst = (unsigned short) mips_fetch_instruction (gdbarch, cur_pc);
/* Normally we ignore extend instructions. However, if it is
not followed by a valid prologue instruction, then this
static struct mips_frame_cache *
mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct mips_frame_cache *cache;
if ((*this_cache) != NULL)
find_pc_partial_function (pc, NULL, &start_addr, NULL);
if (start_addr == 0)
- start_addr = heuristic_proc_start (get_frame_arch (this_frame), pc);
+ start_addr = heuristic_proc_start (gdbarch, pc);
/* We can't analyze the prologue if we couldn't find the begining
of the function. */
if (start_addr == 0)
return cache;
- mips16_scan_prologue (start_addr, pc, this_frame, *this_cache);
+ mips16_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
}
/* gdbarch_sp_regnum contains the value and not the address. */
trad_frame_set_value (cache->saved_regs,
- gdbarch_num_regs (get_frame_arch (this_frame))
- + MIPS_SP_REGNUM,
+ gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
cache->base);
return (*this_cache);
{
struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
this_cache);
+ /* This marks the outermost frame. */
+ if (info->base == 0)
+ return;
(*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}
Return the address of the first instruction past the prologue. */
static CORE_ADDR
-mips32_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+mips32_scan_prologue (struct gdbarch *gdbarch,
+ CORE_ADDR start_pc, CORE_ADDR limit_pc,
struct frame_info *this_frame,
struct mips_frame_cache *this_cache)
{
int seen_sp_adjust = 0;
int load_immediate_bytes = 0;
int in_delay_slot = 0;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
int regsize_is_64_bits = (mips_abi_regsize (gdbarch) == 8);
/* Can be called when there's no process, and hence when there's no
int reg;
/* Fetch the instruction. */
- inst = (unsigned long) mips_fetch_instruction (cur_pc);
+ inst = (unsigned long) mips_fetch_instruction (gdbarch, cur_pc);
/* Save some code by pre-extracting some useful fields. */
high_word = (inst >> 16) & 0xffff;
static struct mips_frame_cache *
mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct mips_frame_cache *cache;
if ((*this_cache) != NULL)
find_pc_partial_function (pc, NULL, &start_addr, NULL);
if (start_addr == 0)
- start_addr = heuristic_proc_start (get_frame_arch (this_frame), pc);
+ start_addr = heuristic_proc_start (gdbarch, pc);
/* We can't analyze the prologue if we couldn't find the begining
of the function. */
if (start_addr == 0)
return cache;
- mips32_scan_prologue (start_addr, pc, this_frame, *this_cache);
+ mips32_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
}
/* gdbarch_sp_regnum contains the value and not the address. */
trad_frame_set_value (cache->saved_regs,
- gdbarch_num_regs (get_frame_arch (this_frame))
- + MIPS_SP_REGNUM,
+ gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
cache->base);
return (*this_cache);
{
struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
this_cache);
+ /* This marks the outermost frame. */
+ if (info->base == 0)
+ return;
(*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}
the sequence. */
static int
-deal_with_atomic_sequence (CORE_ADDR pc)
+deal_with_atomic_sequence (struct gdbarch *gdbarch,
+ struct address_space *aspace, CORE_ADDR pc)
{
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
if (pc & 0x01)
return 0;
- insn = mips_fetch_instruction (loc);
+ insn = mips_fetch_instruction (gdbarch, loc);
/* Assume all atomic sequences start with a ll/lld instruction. */
if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
return 0;
{
int is_branch = 0;
loc += MIPS_INSN32_SIZE;
- insn = mips_fetch_instruction (loc);
+ insn = mips_fetch_instruction (gdbarch, loc);
/* Assume that there is at most one branch in the atomic
sequence. If a branch is found, put a breakpoint in its
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (breaks[index]);
+ insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
return 1;
}
int
mips_software_single_step (struct frame_info *frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR pc, next_pc;
pc = get_frame_pc (frame);
- if (deal_with_atomic_sequence (pc))
+ if (deal_with_atomic_sequence (gdbarch, aspace, pc))
return 1;
next_pc = mips_next_pc (frame, pc);
- insert_single_step_breakpoint (next_pc);
+ insert_single_step_breakpoint (gdbarch, aspace, next_pc);
return 1;
}
end of a function. */
static int
-mips_about_to_return (CORE_ADDR pc)
+mips_about_to_return (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips16 (pc))
/* This mips16 case isn't necessarily reliable. Sometimes the compiler
as $a3), then a "jr" using that register. This second case
is almost impossible to distinguish from an indirect jump
used for switch statements, so we don't even try. */
- return mips_fetch_instruction (pc) == 0xe820; /* jr $ra */
+ return mips_fetch_instruction (gdbarch, pc) == 0xe820; /* jr $ra */
else
- return mips_fetch_instruction (pc) == 0x3e00008; /* jr $ra */
+ return mips_fetch_instruction (gdbarch, pc) == 0x3e00008; /* jr $ra */
}
{
static int blurb_printed = 0;
- warning (_("GDB can't find the start of the function at 0x%s."),
- paddr_nz (pc));
+ warning (_("GDB can't find the start of the function at %s."),
+ paddress (gdbarch, pc));
if (!blurb_printed)
{
in that situation enough information to
determine that it's no big deal. */
printf_filtered ("\n\
- GDB is unable to find the start of the function at 0x%s\n\
+ GDB is unable to find the start of the function at %s\n\
and thus can't determine the size of that function's stack frame.\n\
This means that GDB may be unable to access that stack frame, or\n\
the frames below it.\n\
This problem is most likely caused by an invalid program counter or\n\
stack pointer.\n\
However, if you think GDB should simply search farther back\n\
-from 0x%s for code which looks like the beginning of a\n\
+from %s for code which looks like the beginning of a\n\
function, you can increase the range of the search using the `set\n\
-heuristic-fence-post' command.\n", paddr_nz (pc), paddr_nz (pc));
+heuristic-fence-post' command.\n",
+ paddress (gdbarch, pc), paddress (gdbarch, pc));
blurb_printed = 1;
}
}
addiu sp,-n
daddiu sp,-n
extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
- inst = mips_fetch_instruction (start_pc);
+ inst = mips_fetch_instruction (gdbarch, start_pc);
if ((inst & 0xff80) == 0x6480) /* save */
{
if (start_pc - instlen >= fence)
{
- inst = mips_fetch_instruction (start_pc - instlen);
+ inst = mips_fetch_instruction (gdbarch, start_pc - instlen);
if ((inst & 0xf800) == 0xf000) /* extend */
start_pc -= instlen;
}
else
seen_adjsp = 0;
}
- else if (mips_about_to_return (start_pc))
+ else if (mips_about_to_return (gdbarch, start_pc))
{
/* Skip return and its delay slot. */
start_pc += 2 * MIPS_INSN32_SIZE;
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
int regsize = mips_abi_regsize (gdbarch);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_eabi_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_eabi_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "mips_eabi_push_dummy_call: struct_return reg=%d %s\n",
+ argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
if (len > regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
- store_unsigned_integer (valbuf, regsize, VALUE_ADDRESS (arg));
+ store_unsigned_integer (valbuf, regsize, byte_order,
+ value_address (arg));
typecode = TYPE_CODE_PTR;
len = regsize;
val = valbuf;
unsigned long regval;
/* Write the low word of the double to the even register(s). */
- regval = extract_unsigned_integer (val + low_offset, 4);
+ regval = extract_unsigned_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);
/* Write the high word of the double to the odd register(s). */
- regval = extract_unsigned_integer (val + 4 - low_offset, 4);
+ regval = extract_unsigned_integer (val + 4 - low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
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);
+ LONGEST regval = extract_unsigned_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
&& !fp_register_arg_p (gdbarch, typecode, arg_type))
{
LONGEST regval =
- extract_unsigned_integer (val, partial_len);
+ extract_unsigned_integer (val, partial_len, byte_order);
if (mips_debug)
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
/* For shared libraries, "t9" needs to point at the function
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_n32n64_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_n32n64_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "mips_n32n64_push_dummy_call: struct_return reg=%d %s\n",
+ argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
/* This is a floating point value that fits entirely
in a single register or a pair of registers. */
int reglen = (len <= MIPS64_REGSIZE ? len : MIPS64_REGSIZE);
- LONGEST regval = extract_unsigned_integer (val, reglen);
+ LONGEST regval = extract_unsigned_integer (val, reglen, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, reglen));
argreg++;
if (len == 16)
{
- regval = extract_unsigned_integer (val + reglen, reglen);
+ regval = extract_unsigned_integer (val + reglen,
+ reglen, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, reglen));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
|| (partial_len < 4
&& typecode == TYPE_CODE_INT
&& !TYPE_UNSIGNED (arg_type)))
- regval = extract_signed_integer (val, partial_len);
+ regval = extract_signed_integer (val, partial_len,
+ byte_order);
else
- regval = extract_unsigned_integer (val, partial_len);
+ regval = extract_unsigned_integer (val, partial_len,
+ byte_order);
/* A non-floating-point argument being passed in a
general register. If a struct or union, and if
(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;
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
/* For shared libraries, "t9" needs to point at the function
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o32_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_o32_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "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;
}
unsigned long regval;
/* Write the low word of the double to the even register(s). */
- regval = extract_unsigned_integer (val + low_offset, 4);
+ regval = extract_unsigned_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, argreg++, regval);
/* Write the high word of the double to the odd register(s). */
- regval = extract_unsigned_integer (val + 4 - low_offset, 4);
+ regval = extract_unsigned_integer (val + 4 - low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
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);
+ LONGEST regval = extract_unsigned_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
purpose register. */
if (argreg <= MIPS_LAST_ARG_REGNUM (gdbarch))
{
- LONGEST regval = extract_signed_integer (val, partial_len);
+ LONGEST regval = extract_signed_integer (val, partial_len,
+ byte_order);
/* Value may need to be sign extended, because
mips_isa_regsize() != mips_abi_regsize(). */
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
/* For shared libraries, "t9" needs to point at the function
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o64_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_o64_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "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;
}
if (fp_register_arg_p (gdbarch, typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch))
{
- LONGEST regval = extract_unsigned_integer (val, len);
+ LONGEST regval = extract_unsigned_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
purpose register. */
if (argreg <= MIPS_LAST_ARG_REGNUM (gdbarch))
{
- LONGEST regval = extract_signed_integer (val, partial_len);
+ LONGEST regval = extract_signed_integer (val, partial_len,
+ byte_order);
/* Value may need to be sign extended, because
mips_isa_regsize() != mips_abi_regsize(). */
regs could be 32 bits wide in one frame and 64 on the frame above
and below). */
-static struct type *
-mips_float_register_type (void)
-{
- return builtin_type_ieee_single;
-}
-
-static struct type *
-mips_double_register_type (void)
-{
- return builtin_type_ieee_double;
-}
-
/* Copy a 32-bit single-precision value from the current frame
into rare_buffer. */
if (register_size (gdbarch, regnum) == 4 || mips2_fp_compat (frame))
{
+ struct value_print_options opts;
+
/* 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 (mips_float_register_type (), raw_buffer, &inv1);
+ flt1 = unpack_double (builtin_type (gdbarch)->builtin_float, raw_buffer, &inv1);
- print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w',
- file);
+ get_formatted_print_options (&opts, 'x');
+ print_scalar_formatted (raw_buffer,
+ builtin_type (gdbarch)->builtin_uint32,
+ &opts, 'w', file);
fprintf_filtered (file, " flt: ");
if (inv1)
if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0)
{
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (mips_double_register_type (), raw_buffer,
- &inv2);
+ doub = unpack_double (builtin_type (gdbarch)->builtin_double,
+ raw_buffer, &inv2);
fprintf_filtered (file, " dbl: ");
if (inv2)
}
else
{
+ struct value_print_options opts;
+
/* Eight byte registers: print each one as hex, float and double. */
mips_read_fp_register_single (frame, regnum, raw_buffer);
- flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
+ flt1 = unpack_double (builtin_type (gdbarch)->builtin_float,
+ raw_buffer, &inv1);
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2);
+ doub = unpack_double (builtin_type (gdbarch)->builtin_double,
+ raw_buffer, &inv2);
-
- print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g',
- file);
+ get_formatted_print_options (&opts, 'x');
+ print_scalar_formatted (raw_buffer,
+ builtin_type (gdbarch)->builtin_uint64,
+ &opts, 'g', file);
fprintf_filtered (file, " flt: ");
if (inv1)
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
int offset;
+ struct value_print_options opts;
if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
{
else
offset = 0;
+ get_formatted_print_options (&opts, 'x');
print_scalar_formatted (raw_buffer + offset,
- register_type (gdbarch, regnum), 'x', 0,
+ register_type (gdbarch, regnum), &opts, 0,
file);
}
| INSN_COND_BRANCH_LIKELY)));
}
-int
+static int
mips_single_step_through_delay (struct gdbarch *gdbarch,
struct frame_info *frame)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc = get_frame_pc (frame);
gdb_byte buf[MIPS_INSN32_SIZE];
if (mips_pc_is_mips16 (pc))
return 0;
- if (!breakpoint_here_p (pc + 4))
+ if (!breakpoint_here_p (get_frame_address_space (frame), pc + 4))
return 0;
if (!safe_frame_unwind_memory (frame, pc, buf, sizeof buf))
/* If error reading memory, guess that it is not a delayed
branch. */
return 0;
- return is_delayed (extract_unsigned_integer (buf, sizeof buf));
+ return is_delayed (extract_unsigned_integer (buf, sizeof buf, byte_order));
}
/* To skip prologues, I use this predicate. Returns either PC itself
is greater. */
if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
{
- CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr);
+ CORE_ADDR post_prologue_pc
+ = skip_prologue_using_sal (gdbarch, func_addr);
if (post_prologue_pc != 0)
return max (pc, post_prologue_pc);
}
/* Find an upper limit on the function prologue using the debug
information. If the debug information could not be used to provide
that bound, then use an arbitrary large number as the upper bound. */
- limit_pc = skip_prologue_using_sal (pc);
+ limit_pc = skip_prologue_using_sal (gdbarch, pc);
if (limit_pc == 0)
limit_pc = pc + 100; /* Magic. */
if (mips_pc_is_mips16 (pc))
- return mips16_scan_prologue (pc, limit_pc, NULL, NULL);
+ return mips16_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
else
- return mips32_scan_prologue (pc, limit_pc, NULL, NULL);
+ return mips32_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
}
/* Check whether the PC is in a function epilogue (32-bit version).
This is a helper function for mips_in_function_epilogue_p. */
static int
-mips32_in_function_epilogue_p (CORE_ADDR pc)
+mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
unsigned long high_word;
unsigned long inst;
- inst = mips_fetch_instruction (pc);
+ inst = mips_fetch_instruction (gdbarch, pc);
high_word = (inst >> 16) & 0xffff;
if (high_word != 0x27bd /* addiu $sp,$sp,offset */
/* Check whether the PC is in a function epilogue (16-bit version).
This is a helper function for mips_in_function_epilogue_p. */
static int
-mips16_in_function_epilogue_p (CORE_ADDR pc)
+mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
{
unsigned short inst;
- inst = mips_fetch_instruction (pc);
+ inst = mips_fetch_instruction (gdbarch, pc);
if ((inst & 0xf800) == 0xf000) /* extend */
continue;
mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips16 (pc))
- return mips16_in_function_epilogue_p (pc);
+ return mips16_in_function_epilogue_p (gdbarch, pc);
else
- return mips32_in_function_epilogue_p (pc);
+ return mips32_in_function_epilogue_p (gdbarch, pc);
}
/* Root of all "set mips "/"show mips " commands. This will eventually be
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;
}
static CORE_ADDR
mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
char *name;
CORE_ADDR start_addr;
instructions. FIXME. */
for (i = 0, pc = 0; i < 20; i++, target_pc += MIPS_INSN32_SIZE)
{
- inst = mips_fetch_instruction (target_pc);
+ inst = mips_fetch_instruction (gdbarch, target_pc);
if ((inst & 0xffff0000) == 0x3c010000) /* lui $at */
pc = (inst << 16) & 0xffff0000; /* high word */
else if ((inst & 0xffff0000) == 0x24210000) /* addiu $at */
static CORE_ADDR
mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct minimal_symbol *msym;
int i;
gdb_byte stub_code[16];
if (target_read_memory (pc, stub_code, 16) != 0)
return 0;
for (i = 0; i < 4; i++)
- stub_words[i] = extract_unsigned_integer (stub_code + i * 4, 4);
+ stub_words[i] = extract_unsigned_integer (stub_code + i * 4,
+ 4, byte_order);
/* A stub contains these instructions:
lui t9, %hi(target)
mips_integer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
- return (CORE_ADDR) extract_signed_integer (buf, TYPE_LENGTH (type));
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ return extract_signed_integer (buf, TYPE_LENGTH (type), byte_order);
}
/* Dummy virtual frame pointer method. This is no more or less accurate
reg_names = mips_generic_reg_names;
}
/* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been
- replaced by read_pc? */
+ replaced by gdbarch_read_pc? */
set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs);
set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
set_gdbarch_fp0_regnum (gdbarch, regnum->fp0);
else
set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
- /* FIXME: cagney/2003-08-29: The macros HAVE_STEPPABLE_WATCHPOINT,
- HAVE_NONSTEPPABLE_WATCHPOINT, and HAVE_CONTINUABLE_WATCHPOINT
+ /* FIXME: cagney/2003-08-29: The macros target_have_steppable_watchpoint,
+ HAVE_NONSTEPPABLE_WATCHPOINT, and target_have_continuable_watchpoint
need to all be folded into the target vector. Since they are
- being used as guards for STOPPED_BY_WATCHPOINT, why not have
- STOPPED_BY_WATCHPOINT return the type of watchpoint that the code
+ being used as guards for target_stopped_by_watchpoint, why not have
+ target_stopped_by_watchpoint return the type of watchpoint that the code
is sitting on? */
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
user_reg_add (gdbarch, mips_register_aliases[i].name,
value_of_mips_user_reg, &mips_register_aliases[i].regnum);
+ for (i = 0; i < ARRAY_SIZE (mips_numeric_register_aliases); i++)
+ user_reg_add (gdbarch, mips_numeric_register_aliases[i].name,
+ value_of_mips_user_reg,
+ &mips_numeric_register_aliases[i].regnum);
+
return gdbarch;
}