/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
+ Copyright (C) 1988-2017 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 "symcat.h"
#include "sim-regno.h"
#include "dis-asm.h"
+#include "disasm.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "infcall.h"
-#include "floatformat.h"
#include "remote.h"
#include "target-descriptions.h"
#include "dwarf2-frame.h"
NULL
};
+/* Enum describing the different kinds of breakpoints. */
+
+enum mips_breakpoint_kind
+{
+ /* 16-bit MIPS16 mode breakpoint. */
+ MIPS_BP_KIND_MIPS16 = 2,
+
+ /* 16-bit microMIPS mode breakpoint. */
+ MIPS_BP_KIND_MICROMIPS16 = 3,
+
+ /* 32-bit standard MIPS mode breakpoint. */
+ MIPS_BP_KIND_MIPS32 = 4,
+
+ /* 32-bit microMIPS mode breakpoint. */
+ MIPS_BP_KIND_MICROMIPS32 = 5,
+};
+
/* For backwards compatibility we default to MIPS16. This flag is
overridden as soon as unambiguous ELF file flags tell us the
compressed ISA encoding used. */
/ gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
}
+/* Max saved register size. */
+#define MAX_MIPS_ABI_REGSIZE 8
+
/* Return the currently configured (or set) saved register size. */
unsigned int
"fsr", "fir",
};
-/* Names of IDT R3041 registers. */
-
-static const char *mips_r3041_reg_names[] = {
- "sr", "lo", "hi", "bad", "cause", "pc",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "fsr", "fir", "", /*"fp" */ "",
- "", "", "bus", "ccfg", "", "", "", "",
- "", "", "port", "cmp", "", "", "epc", "prid",
-};
-
/* Names of tx39 registers. */
static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
"", "", "config", "cache", "debug", "depc", "epc",
};
-/* Names of IRIX registers. */
-static const char *mips_irix_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "pc", "cause", "bad", "hi", "lo", "fsr", "fir"
-};
-
/* Names of registers with Linux kernels. */
static const char *mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
"sr", "lo", "hi", "bad", "cause", "pc",
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* GPR names for all ABIs other than n32/n64. */
- static char *mips_gpr_names[] = {
+ static const char *mips_gpr_names[] = {
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
};
/* GPR names for n32 and n64 ABIs. */
- static char *mips_n32_n64_gpr_names[] = {
+ static const char *mips_n32_n64_gpr_names[] = {
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
"a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
if (rawnum == mips_regnum (gdbarch)->fp_control_status
|| rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
return builtin_type (gdbarch)->builtin_int32;
- else if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
- && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
+ else if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
&& rawnum >= MIPS_FIRST_EMBED_REGNUM
&& rawnum <= MIPS_LAST_EMBED_REGNUM)
/* The pseudo/cooked view of the embedded registers is always
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. */
- if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
- && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
+ if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
&& rawnum >= MIPS_FIRST_EMBED_REGNUM
&& rawnum <= MIPS_LAST_EMBED_REGNUM)
return builtin_type (gdbarch)->builtin_int32;
static CORE_ADDR
mips_read_pc (struct regcache *regcache)
{
- int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
+ int regnum = gdbarch_pc_regnum (regcache->arch ());
LONGEST pc;
regcache_cooked_read_signed (regcache, regnum, &pc);
void
mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
- int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
+ int regnum = gdbarch_pc_regnum (regcache->arch ());
regcache_cooked_write_unsigned (regcache, regnum, pc);
}
number of the floating condition bits tested by the branch. */
static CORE_ADDR
-mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+mips32_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache,
ULONGEST inst, CORE_ADDR pc, int count)
{
int fcsr = mips_regnum (gdbarch)->fp_control_status;
/* No way to handle; it'll most likely trap anyway. */
return pc;
- fcs = get_frame_register_unsigned (frame, fcsr);
+ fcs = regcache_raw_get_unsigned (regcache, fcsr);
cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
if (((cond >> cnum) & mask) != mask * !tf)
branch prediction. */
static CORE_ADDR
-mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
+mips32_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
unsigned long inst;
int op;
inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
}
else if (op == 17 && itype_rs (inst) == 8)
/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
- pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 1);
+ pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 1);
else if (op == 17 && itype_rs (inst) == 9
&& (itype_rt (inst) & 2) == 0)
/* BC1ANY2F, BC1ANY2T: 010001 01001 xxx0x */
- pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 2);
+ pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 2);
else if (op == 17 && itype_rs (inst) == 10
&& (itype_rt (inst) & 2) == 0)
/* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */
- pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 4);
+ pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 4);
else if (op == 29)
/* JALX: 011101 */
/* The new PC will be alternate mode. */
if (op == 54 || op == 62)
bit += 32;
- if (((get_frame_register_signed (frame,
- itype_rs (inst)) >> bit) & 1)
+ if (((regcache_raw_get_signed (regcache,
+ itype_rs (inst)) >> bit) & 1)
== branch_if)
pc += mips32_relative_offset (inst) + 4;
else
case 8: /* JR */
case 9: /* JALR */
/* Set PC to that address. */
- pc = get_frame_register_signed (frame, rtype_rs (inst));
+ pc = regcache_raw_get_signed (regcache, rtype_rs (inst));
break;
case 12: /* SYSCALL */
{
struct gdbarch_tdep *tdep;
- tdep = gdbarch_tdep (get_frame_arch (frame));
+ tdep = gdbarch_tdep (gdbarch);
if (tdep->syscall_next_pc != NULL)
- pc = tdep->syscall_next_pc (frame);
+ pc = tdep->syscall_next_pc (get_current_frame ());
else
pc += 4;
}
case 16: /* BLTZAL */
case 18: /* BLTZALL */
less_branch:
- if (get_frame_register_signed (frame, itype_rs (inst)) < 0)
+ if (regcache_raw_get_signed (regcache, itype_rs (inst)) < 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8; /* after the delay slot */
case 3: /* BGEZL */
case 17: /* BGEZAL */
case 19: /* BGEZALL */
- if (get_frame_register_signed (frame, itype_rs (inst)) >= 0)
+ if (regcache_raw_get_signed (regcache, itype_rs (inst)) >= 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8; /* after the delay slot */
/* No way to handle; it'll most likely trap anyway. */
break;
- if ((get_frame_register_unsigned (frame,
- dspctl) & 0x7f) >= pos)
+ if ((regcache_raw_get_unsigned (regcache,
+ dspctl) & 0x7f) >= pos)
pc += mips32_relative_offset (inst);
else
pc += 4;
break;
case 4: /* BEQ, BEQL */
equal_branch:
- if (get_frame_register_signed (frame, itype_rs (inst)) ==
- get_frame_register_signed (frame, itype_rt (inst)))
+ if (regcache_raw_get_signed (regcache, itype_rs (inst)) ==
+ regcache_raw_get_signed (regcache, itype_rt (inst)))
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
break;
case 5: /* BNE, BNEL */
neq_branch:
- if (get_frame_register_signed (frame, itype_rs (inst)) !=
- get_frame_register_signed (frame, itype_rt (inst)))
+ if (regcache_raw_get_signed (regcache, itype_rs (inst)) !=
+ regcache_raw_get_signed (regcache, itype_rt (inst)))
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
break;
case 6: /* BLEZ, BLEZL */
- if (get_frame_register_signed (frame, itype_rs (inst)) <= 0)
+ if (regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
case 7:
default:
greater_branch: /* BGTZ, BGTZL */
- if (get_frame_register_signed (frame, itype_rs (inst)) > 0)
+ if (regcache_raw_get_signed (regcache, itype_rs (inst)) > 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
examined by the branch. */
static CORE_ADDR
-micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+micromips_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache,
ULONGEST insn, CORE_ADDR pc, int count)
{
int fcsr = mips_regnum (gdbarch)->fp_control_status;
/* No way to handle; it'll most likely trap anyway. */
return pc;
- fcs = get_frame_register_unsigned (frame, fcsr);
+ fcs = regcache_raw_get_unsigned (regcache, fcsr);
cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
if (((cond >> cnum) & mask) != mask * !tf)
after the instruction at the address PC. */
static CORE_ADDR
-micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
+micromips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
ULONGEST insn;
insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
&& (b6s10_ext (insn) & 0x2bf) == 0x3c)
/* JALR, JALR.HB: 000000 000x111100 111100 */
/* JALRS, JALRS.HB: 000000 010x111100 111100 */
- pc = get_frame_register_signed (frame, b0s5_reg (insn >> 16));
+ pc = regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16));
break;
case 0x10: /* POOL32I: bits 010000 */
case 0x00: /* BLTZ: bits 010000 00000 */
case 0x01: /* BLTZAL: bits 010000 00001 */
case 0x11: /* BLTZALS: bits 010000 10001 */
- if (get_frame_register_signed (frame,
- b0s5_reg (insn >> 16)) < 0)
+ if (regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) < 0)
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
case 0x02: /* BGEZ: bits 010000 00010 */
case 0x03: /* BGEZAL: bits 010000 00011 */
case 0x13: /* BGEZALS: bits 010000 10011 */
- if (get_frame_register_signed (frame,
- b0s5_reg (insn >> 16)) >= 0)
+ if (regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) >= 0)
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
case 0x04: /* BLEZ: bits 010000 00100 */
- if (get_frame_register_signed (frame,
- b0s5_reg (insn >> 16)) <= 0)
+ if (regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) <= 0)
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
case 0x05: /* BNEZC: bits 010000 00101 */
- if (get_frame_register_signed (frame,
- b0s5_reg (insn >> 16)) != 0)
+ if (regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) != 0)
pc += micromips_relative_offset16 (insn);
break;
case 0x06: /* BGTZ: bits 010000 00110 */
- if (get_frame_register_signed (frame,
- b0s5_reg (insn >> 16)) > 0)
+ if (regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) > 0)
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
case 0x07: /* BEQZC: bits 010000 00111 */
- if (get_frame_register_signed (frame,
- b0s5_reg (insn >> 16)) == 0)
+ if (regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) == 0)
pc += micromips_relative_offset16 (insn);
break;
/* No way to handle; it'll most likely trap anyway. */
break;
- if ((get_frame_register_unsigned (frame,
- dspctl) & 0x7f) >= pos)
+ if ((regcache_raw_get_unsigned (regcache,
+ dspctl) & 0x7f) >= pos)
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
case 0x1d: /* BC1T: bits 010000 11101 xxx00 */
/* BC1ANY2T: bits 010000 11101 xxx01 */
if (((insn >> 16) & 0x2) == 0x0)
- pc = micromips_bc1_pc (gdbarch, frame, insn, pc,
+ pc = micromips_bc1_pc (gdbarch, regcache, insn, pc,
((insn >> 16) & 0x1) + 1);
break;
case 0x1e: /* BC1ANY4F: bits 010000 11110 xxx01 */
case 0x1f: /* BC1ANY4T: bits 010000 11111 xxx01 */
if (((insn >> 16) & 0x3) == 0x1)
- pc = micromips_bc1_pc (gdbarch, frame, insn, pc, 4);
+ pc = micromips_bc1_pc (gdbarch, regcache, insn, pc, 4);
break;
}
break;
break;
case 0x25: /* BEQ: bits 100101 */
- if (get_frame_register_signed (frame, b0s5_reg (insn >> 16))
- == get_frame_register_signed (frame, b5s5_reg (insn >> 16)))
+ if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
+ == regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
case 0x2d: /* BNE: bits 101101 */
- if (get_frame_register_signed (frame, b0s5_reg (insn >> 16))
- != get_frame_register_signed (frame, b5s5_reg (insn >> 16)))
+ if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
+ != regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
pc += micromips_relative_offset16 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
case 0x11: /* POOL16C: bits 010001 */
if ((b5s5_op (insn) & 0x1c) == 0xc)
/* JR16, JRC, JALR16, JALRS16: 010001 011xx */
- pc = get_frame_register_signed (frame, b0s5_reg (insn));
+ pc = regcache_raw_get_signed (regcache, b0s5_reg (insn));
else if (b5s5_op (insn) == 0x18)
/* JRADDIUSP: bits 010001 11000 */
- pc = get_frame_register_signed (frame, MIPS_RA_REGNUM);
+ pc = regcache_raw_get_signed (regcache, MIPS_RA_REGNUM);
break;
case 0x23: /* BEQZ16: bits 100011 */
{
int rs = mips_reg3_to_reg[b7s3_reg (insn)];
- if (get_frame_register_signed (frame, rs) == 0)
+ if (regcache_raw_get_signed (regcache, rs) == 0)
pc += micromips_relative_offset7 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
{
int rs = mips_reg3_to_reg[b7s3_reg (insn)];
- if (get_frame_register_signed (frame, rs) != 0)
+ if (regcache_raw_get_signed (regcache, rs) != 0)
pc += micromips_relative_offset7 (insn);
else
pc += micromips_pc_insn_size (gdbarch, pc);
}
static CORE_ADDR
-extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
+extended_mips16_next_pc (regcache *regcache, CORE_ADDR pc,
unsigned int extension, unsigned int insn)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
int op = (insn >> 11);
switch (op)
{
struct upk_mips16 upk;
int reg;
unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
- reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
+ reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]);
if (reg == 0)
pc = add_offset_16 (pc, upk.offset);
else
struct upk_mips16 upk;
int reg;
unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
- reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
+ reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]);
if (reg != 0)
pc = add_offset_16 (pc, upk.offset);
else
int reg;
unpack_mips16 (gdbarch, pc, extension, insn, i8type, &upk);
/* upk.regx contains the opcode */
- reg = get_frame_register_signed (frame, 24); /* Test register is 24 */
+ /* Test register is 24 */
+ reg = regcache_raw_get_signed (regcache, 24);
if (((upk.regx == 0) && (reg == 0)) /* BTEZ */
|| ((upk.regx == 1) && (reg != 0))) /* BTNEZ */
pc = add_offset_16 (pc, upk.offset);
reg = mips_reg3_to_reg[upk.regx];
else
reg = 31; /* Function return instruction. */
- pc = get_frame_register_signed (frame, reg);
+ pc = regcache_raw_get_signed (regcache, reg);
}
else
pc += 2;
that. */
{
pc += 2;
- pc = extended_mips16_next_pc (frame, pc, insn,
+ pc = extended_mips16_next_pc (regcache, pc, insn,
fetch_mips_16 (gdbarch, pc));
break;
}
}
static CORE_ADDR
-mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
+mips16_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
unsigned int insn = fetch_mips_16 (gdbarch, pc);
- return extended_mips16_next_pc (frame, pc, 0, insn);
+ return extended_mips16_next_pc (regcache, pc, 0, insn);
}
/* The mips_next_pc function supports single_step when the remote
branch will go. This isn't hard because all the data is available.
The MIPS32, MIPS16 and microMIPS variants are quite different. */
static CORE_ADDR
-mips_next_pc (struct frame_info *frame, CORE_ADDR pc)
+mips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
if (mips_pc_is_mips16 (gdbarch, pc))
- return mips16_next_pc (frame, pc);
+ return mips16_next_pc (regcache, pc);
else if (mips_pc_is_micromips (gdbarch, pc))
- return micromips_next_pc (frame, pc);
+ return micromips_next_pc (regcache, pc);
else
- return mips32_next_pc (frame, pc);
+ return mips32_next_pc (regcache, pc);
}
/* Return non-zero if the MIPS16 instruction INSN is a compact branch
#define SC_OPCODE 0x38
#define SCD_OPCODE 0x3c
-static int
-mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
- struct address_space *aspace, CORE_ADDR pc)
+static std::vector<CORE_ADDR>
+mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);
/* Assume all atomic sequences start with a ll/lld instruction. */
if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
- return 0;
+ return {};
/* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */
{
case 0: /* SPECIAL */
if (rtype_funct (insn) >> 1 == 4) /* JR, JALR */
- return 0; /* fallback to the standard single-step code. */
+ return {}; /* fallback to the standard single-step code. */
break;
case 1: /* REGIMM */
is_branch = ((itype_rt (insn) & 0xc) == 0 /* B{LT,GE}Z* */
break;
case 2: /* J */
case 3: /* JAL */
- return 0; /* fallback to the standard single-step code. */
+ return {}; /* fallback to the standard single-step code. */
case 4: /* BEQ */
case 5: /* BNE */
case 6: /* BLEZ */
{
branch_bp = loc + mips32_relative_offset (insn) + 4;
if (last_breakpoint >= 1)
- return 0; /* More than one branch found, fallback to the
- standard single-step code. */
+ return {}; /* More than one branch found, fallback to the
+ standard single-step code. */
breaks[1] = branch_bp;
last_breakpoint++;
}
/* Assume that the atomic sequence ends with a sc/scd instruction. */
if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
- return 0;
+ return {};
loc += MIPS_INSN32_SIZE;
if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
last_breakpoint = 0;
+ std::vector<CORE_ADDR> next_pcs;
+
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+ next_pcs.push_back (breaks[index]);
- return 1;
+ return next_pcs;
}
-static int
+static std::vector<CORE_ADDR>
micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
- struct address_space *aspace,
CORE_ADDR pc)
{
const int atomic_sequence_length = 16; /* Instruction sequence length. */
/* Assume all atomic sequences start with a ll/lld instruction. */
insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
if (micromips_op (insn) != 0x18) /* POOL32C: bits 011000 */
- return 0;
+ return {};
loc += MIPS_INSN16_SIZE;
insn <<= 16;
insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
if ((b12s4_op (insn) & 0xb) != 0x3) /* LL, LLD: bits 011000 0x11 */
- return 0;
+ return {};
loc += MIPS_INSN16_SIZE;
/* Assume all atomic sequences end with an sc/scd instruction. Assume
case 0x35: /* J: bits 110101 */
case 0x3d: /* JAL: bits 111101 */
case 0x3c: /* JALX: bits 111100 */
- return 0; /* Fall back to the standard single-step code. */
+ return {}; /* Fall back to the standard single-step code. */
case 0x18: /* POOL32C: bits 011000 */
if ((b12s4_op (insn) & 0xb) == 0xb)
&& b5s5_op (insn) != 0x18)
/* JRADDIUSP: bits 010001 11000 */
break;
- return 0; /* Fall back to the standard single-step code. */
+ return {}; /* Fall back to the standard single-step code. */
case 0x33: /* B16: bits 110011 */
- return 0; /* Fall back to the standard single-step code. */
+ return {}; /* Fall back to the standard single-step code. */
}
break;
}
if (is_branch)
{
if (last_breakpoint >= 1)
- return 0; /* More than one branch found, fallback to the
- standard single-step code. */
+ return {}; /* More than one branch found, fallback to the
+ standard single-step code. */
breaks[1] = branch_bp;
last_breakpoint++;
}
}
if (!sc_found)
- return 0;
+ return {};
/* Insert a breakpoint right after the end of the atomic sequence. */
breaks[0] = loc;
if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
last_breakpoint = 0;
+ std::vector<CORE_ADDR> next_pcs;
+
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+ next_pcs.push_back (breaks[index]);
- return 1;
+ return next_pcs;
}
-static int
-deal_with_atomic_sequence (struct gdbarch *gdbarch,
- struct address_space *aspace, CORE_ADDR pc)
+static std::vector<CORE_ADDR>
+deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips (pc))
- return mips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+ return mips_deal_with_atomic_sequence (gdbarch, pc);
else if (mips_pc_is_micromips (gdbarch, pc))
- return micromips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+ return micromips_deal_with_atomic_sequence (gdbarch, pc);
else
- return 0;
+ return {};
}
/* mips_software_single_step() is called just before we want to resume
or kernel single-step support (MIPS on GNU/Linux for example). We find
the target of the coming instruction and breakpoint it. */
-int
-mips_software_single_step (struct frame_info *frame)
+std::vector<CORE_ADDR>
+mips_software_single_step (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct address_space *aspace = get_frame_address_space (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
CORE_ADDR pc, next_pc;
- pc = get_frame_pc (frame);
- if (deal_with_atomic_sequence (gdbarch, aspace, pc))
- return 1;
+ pc = regcache_read_pc (regcache);
+ std::vector<CORE_ADDR> next_pcs = deal_with_atomic_sequence (gdbarch, pc);
- next_pc = mips_next_pc (frame, pc);
+ if (!next_pcs.empty ())
+ return next_pcs;
- insert_single_step_breakpoint (gdbarch, aspace, next_pc);
- return 1;
+ next_pc = mips_next_pc (regcache, pc);
+
+ return {next_pc};
}
/* Test whether the PC points to the return instruction at the
int stack_offset = 0;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
- int regsize = mips_abi_regsize (gdbarch);
+ int abi_regsize = mips_abi_regsize (gdbarch);
/* For shared libraries, "t9" needs to point at the function
address. */
than necessary for EABI, because the first few arguments are
passed in registers, but that's OK. */
for (argnum = 0; argnum < nargs; argnum++)
- len += align_up (TYPE_LENGTH (value_type (args[argnum])), regsize);
+ len += align_up (TYPE_LENGTH (value_type (args[argnum])), abi_regsize);
sp -= align_up (len, 16);
if (mips_debug)
for (argnum = 0; argnum < nargs; argnum++)
{
const gdb_byte *val;
- gdb_byte valbuf[MAX_REGISTER_SIZE];
+ /* This holds the address of structures that are passed by
+ reference. */
+ gdb_byte ref_valbuf[MAX_MIPS_ABI_REGSIZE];
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
/* The EABI passes structures that do not fit in a register by
reference. */
- if (len > regsize
+ if (len > abi_regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
- store_unsigned_integer (valbuf, regsize, byte_order,
+ gdb_assert (abi_regsize <= ARRAY_SIZE (ref_valbuf));
+ store_unsigned_integer (ref_valbuf, abi_regsize, byte_order,
value_address (arg));
typecode = TYPE_CODE_PTR;
- len = regsize;
- val = valbuf;
+ len = abi_regsize;
+ val = ref_valbuf;
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " push");
}
up before the check to see if there are any FP registers
left. Non MIPS_EABI targets also pass the FP in the integer
registers so also round up normal registers. */
- if (regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
+ if (abi_regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
{
if ((float_argreg & 1))
float_argreg++;
/* Copy the argument to general registers or the stack in
register-sized pieces. Large arguments are split between
registers and stack. */
- /* Note: structs whose size is not a multiple of regsize
+ /* Note: structs whose size is not a multiple of abi_regsize
are treated specially: Irix cc passes
them in registers where gcc sometimes puts them on the
stack. For maximum compatibility, we will put them in
both places. */
- int odd_sized_struct = (len > regsize && len % regsize != 0);
+ int odd_sized_struct = (len > abi_regsize && len % abi_regsize != 0);
/* Note: Floating-point values that didn't fit into an FP
register are only written to memory. */
{
/* Remember if the argument was written to the stack. */
int stack_used_p = 0;
- int partial_len = (len < regsize ? len : regsize);
+ int partial_len = (len < abi_regsize ? len : abi_regsize);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
stack_used_p = 1;
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- if (regsize == 8
+ if (abi_regsize == 8
&& (typecode == TYPE_CODE_INT
|| typecode == TYPE_CODE_PTR
|| typecode == TYPE_CODE_FLT) && len <= 4)
- longword_offset = regsize - len;
+ longword_offset = abi_regsize - len;
else if ((typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION)
- && TYPE_LENGTH (arg_type) < regsize)
- longword_offset = regsize - len;
+ && TYPE_LENGTH (arg_type) < abi_regsize)
+ longword_offset = abi_regsize - len;
}
if (mips_debug)
if (mips_debug)
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
- phex (regval, regsize));
+ phex (regval, abi_regsize));
regcache_cooked_write_signed (regcache, argreg, regval);
argreg++;
}
only needs to be adjusted when it has been used. */
if (stack_used_p)
- stack_offset += align_up (partial_len, regsize);
+ stack_offset += align_up (partial_len, abi_regsize);
}
}
if (mips_debug)
/* A struct that contains one or two floats. Each value is part
in the least significant part of their floating point
register.. */
- gdb_byte reg[MAX_REGISTER_SIZE];
int regnum;
int field;
for (field = 0, regnum = mips_regnum (gdbarch)->fp0;
{ /* 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. */
- int inv1, inv2;
+ std::string flt_str, dbl_str;
+
+ const struct floatformat *flt_fmt
+ = floatformat_from_type (builtin_type (gdbarch)->builtin_float);
+ const struct floatformat *dbl_fmt
+ = floatformat_from_type (builtin_type (gdbarch)->builtin_double);
raw_buffer
= ((gdb_byte *)
/* 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);
+ flt_str = floatformat_to_string (flt_fmt, raw_buffer, "%-17.9g");
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)
- fprintf_filtered (file, " <invalid float> ");
- else
- fprintf_filtered (file, "%-17.9g", flt1);
+ fprintf_filtered (file, " flt: %s", flt_str.c_str ());
if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0)
{
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (builtin_type (gdbarch)->builtin_double,
- raw_buffer, &inv2);
+ dbl_str = floatformat_to_string (dbl_fmt, raw_buffer, "%-24.17g");
- fprintf_filtered (file, " dbl: ");
- if (inv2)
- fprintf_filtered (file, "<invalid double>");
- else
- fprintf_filtered (file, "%-24.17g", doub);
+ fprintf_filtered (file, " dbl: %s", dbl_str.c_str ());
}
}
else
/* Eight byte registers: print each one as hex, float and double. */
mips_read_fp_register_single (frame, regnum, raw_buffer);
- flt1 = unpack_double (builtin_type (gdbarch)->builtin_float,
- raw_buffer, &inv1);
+ flt_str = floatformat_to_string (flt_fmt, raw_buffer, "%-17.9g");
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (builtin_type (gdbarch)->builtin_double,
- raw_buffer, &inv2);
+ dbl_str = floatformat_to_string (dbl_fmt, raw_buffer, "%-24.17g");
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)
- fprintf_filtered (file, "<invalid float>");
- else
- fprintf_filtered (file, "%-17.9g", flt1);
-
- fprintf_filtered (file, " dbl: ");
- if (inv2)
- fprintf_filtered (file, "<invalid double>");
- else
- fprintf_filtered (file, "%-24.17g", doub);
+ fprintf_filtered (file, " flt: %s", flt_str.c_str ());
+ fprintf_filtered (file, " dbl: %s", dbl_str.c_str ());
}
}
get_formatted_print_options (&opts, 'x');
val_print_scalar_formatted (value_type (val),
- value_contents_for_printing (val),
value_embedded_offset (val),
val,
&opts, 0, file);
{
struct gdbarch *gdbarch = get_frame_arch (frame);
/* Do values for GP (int) regs. */
- gdb_byte raw_buffer[MAX_REGISTER_SIZE];
+ const gdb_byte *raw_buffer;
+ struct value *value;
int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8); /* display cols
per row. */
int col, byte;
break; /* End row: large register. */
/* OK: get the data in raw format. */
- if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
- error (_("can't read register %d (%s)"),
- regnum, gdbarch_register_name (gdbarch, regnum));
+ value = get_frame_register_value (frame, regnum);
+ if (value_optimized_out (value)
+ || !value_entirely_available (value))
+ {
+ fprintf_filtered (file, "%*s ",
+ (int) mips_abi_regsize (gdbarch) * 2,
+ (mips_abi_regsize (gdbarch) == 4 ? "<unavl>"
+ : "<unavailable>"));
+ col++;
+ continue;
+ }
+ raw_buffer = value_contents_all (value);
/* pad small registers */
for (byte = 0;
byte < (mips_abi_regsize (gdbarch)
- register_size (gdbarch, regnum)); byte++)
- printf_filtered (" ");
+ fprintf_filtered (file, " ");
/* Now print the register value in hex, endian order. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
for (byte =
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc = get_frame_pc (frame);
- struct address_space *aspace;
enum mips_isa isa;
ULONGEST insn;
int status;
/* _has_delay_slot above will have validated the read. */
insn = mips_fetch_instruction (gdbarch, isa, pc, NULL);
size = mips_insn_size (isa, insn);
- aspace = get_frame_address_space (frame);
+
+ const address_space *aspace = get_frame_address_space (frame);
+
return breakpoint_here_p (aspace, pc + size) != no_breakpoint_here;
}
used for all MIPS-specific commands. */
static void
-show_mips_command (char *args, int from_tty)
+show_mips_command (const char *args, int from_tty)
{
help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout);
}
static void
-set_mips_command (char *args, int from_tty)
+set_mips_command (const char *args, int from_tty)
{
printf_unfiltered
("\"set mips\" must be followed by an appropriate subcommand.\n");
/* Commands to show/set the MIPS FPU type. */
static void
-show_mipsfpu_command (char *args, int from_tty)
+show_mipsfpu_command (const char *args, int from_tty)
{
- char *fpu;
+ const char *fpu;
if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_mips)
{
static void
-set_mipsfpu_command (char *args, int from_tty)
+set_mipsfpu_command (const char *args, int from_tty)
{
printf_unfiltered ("\"set mipsfpu\" must be followed by \"double\", "
"\"single\",\"none\" or \"auto\".\n");
}
static void
-set_mipsfpu_single_command (char *args, int from_tty)
+set_mipsfpu_single_command (const char *args, int from_tty)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
}
static void
-set_mipsfpu_double_command (char *args, int from_tty)
+set_mipsfpu_double_command (const char *args, int from_tty)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
}
static void
-set_mipsfpu_none_command (char *args, int from_tty)
+set_mipsfpu_none_command (const char *args, int from_tty)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
}
static void
-set_mipsfpu_auto_command (char *args, int from_tty)
+set_mipsfpu_auto_command (const char *args, int from_tty)
{
mips_fpu_type_auto = 1;
}
static int
gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
{
- struct gdbarch *gdbarch = (struct gdbarch *) info->application_data;
+ gdb_disassembler *di
+ = static_cast<gdb_disassembler *>(info->application_data);
+ struct gdbarch *gdbarch = di->arch ();
/* FIXME: cagney/2003-06-26: Is this even necessary? The
disassembler needs to be able to locally determine the ISA, and
register naming conventions specified by the user. */
info->disassembler_options = "gpr-names=32";
- /* Call the appropriate disassembler based on the target endian-ness. */
- if (info->endian == BFD_ENDIAN_BIG)
- return print_insn_big_mips (memaddr, info);
- else
- return print_insn_little_mips (memaddr, info);
+ return default_print_insn (memaddr, info);
}
static int
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. */
+/* Implement the breakpoint_kind_from_pc gdbarch method. */
-static const gdb_byte *
-mips_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+static int
+mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
CORE_ADDR pc = *pcptr;
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ if (mips_pc_is_mips16 (gdbarch, pc))
{
- if (mips_pc_is_mips16 (gdbarch, pc))
- {
- static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
- *pcptr = unmake_compact_addr (pc);
- *lenptr = sizeof (mips16_big_breakpoint);
- return mips16_big_breakpoint;
- }
- else if (mips_pc_is_micromips (gdbarch, pc))
- {
- static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
- static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
- ULONGEST insn;
- int err;
- int size;
-
- insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &err);
- size = err ? 2 : mips_insn_size (ISA_MICROMIPS, insn);
- *pcptr = unmake_compact_addr (pc);
- *lenptr = size;
- return (size == 2) ? micromips16_big_breakpoint
- : micromips32_big_breakpoint;
- }
- else
- {
- /* The IDT board uses an unusual breakpoint value, and
- sometimes gets confused when it sees the usual MIPS
- breakpoint instruction. */
- 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);
-
- if (strcmp (target_shortname, "mips") == 0)
- return idt_big_breakpoint;
- else if (strcmp (target_shortname, "ddb") == 0
- || 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;
- }
+ *pcptr = unmake_compact_addr (pc);
+ return MIPS_BP_KIND_MIPS16;
}
- else
+ else if (mips_pc_is_micromips (gdbarch, pc))
{
- if (mips_pc_is_mips16 (gdbarch, pc))
- {
- static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
- *pcptr = unmake_compact_addr (pc);
- *lenptr = sizeof (mips16_little_breakpoint);
- return mips16_little_breakpoint;
- }
- else if (mips_pc_is_micromips (gdbarch, pc))
- {
- static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };
- static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };
- ULONGEST insn;
- int err;
- int size;
-
- insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &err);
- size = err ? 2 : mips_insn_size (ISA_MICROMIPS, insn);
- *pcptr = unmake_compact_addr (pc);
- *lenptr = size;
- return (size == 2) ? micromips16_little_breakpoint
- : micromips32_little_breakpoint;
- }
+ ULONGEST insn;
+ int status;
+
+ *pcptr = unmake_compact_addr (pc);
+ insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
+ if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2))
+ return MIPS_BP_KIND_MICROMIPS16;
else
- {
- static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
- static gdb_byte pmon_little_breakpoint[] = { 0xd, 0, 0, 0 };
- static gdb_byte idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 };
-
- *lenptr = sizeof (little_breakpoint);
-
- if (strcmp (target_shortname, "mips") == 0)
- return idt_little_breakpoint;
- else if (strcmp (target_shortname, "ddb") == 0
- || strcmp (target_shortname, "pmon") == 0
- || strcmp (target_shortname, "lsi") == 0)
- return pmon_little_breakpoint;
- else
- return little_breakpoint;
- }
+ return MIPS_BP_KIND_MICROMIPS32;
}
+ else
+ return MIPS_BP_KIND_MIPS32;
}
-/* Determine the remote breakpoint kind suitable for the PC. The following
- kinds are used:
+/* Implement the sw_breakpoint_from_kind gdbarch method. */
- * 2 -- 16-bit MIPS16 mode breakpoint,
+static const gdb_byte *
+mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
- * 3 -- 16-bit microMIPS mode breakpoint,
+ switch (kind)
+ {
+ case MIPS_BP_KIND_MIPS16:
+ {
+ static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
+ static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
- * 4 -- 32-bit standard MIPS mode breakpoint,
+ *size = 2;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return mips16_big_breakpoint;
+ else
+ return mips16_little_breakpoint;
+ }
+ case MIPS_BP_KIND_MICROMIPS16:
+ {
+ static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
+ static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };
- * 5 -- 32-bit microMIPS mode breakpoint. */
+ *size = 2;
-static void
-mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *kindptr)
-{
- CORE_ADDR pc = *pcptr;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return micromips16_big_breakpoint;
+ else
+ return micromips16_little_breakpoint;
+ }
+ case MIPS_BP_KIND_MICROMIPS32:
+ {
+ static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
+ static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };
- if (mips_pc_is_mips16 (gdbarch, pc))
- {
- *pcptr = unmake_compact_addr (pc);
- *kindptr = 2;
- }
- else if (mips_pc_is_micromips (gdbarch, pc))
- {
- ULONGEST insn;
- int status;
- int size;
+ *size = 4;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return micromips32_big_breakpoint;
+ else
+ return micromips32_little_breakpoint;
+ }
+ case MIPS_BP_KIND_MIPS32:
+ {
+ static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
+ static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
- insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
- size = status ? 2 : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4;
- *pcptr = unmake_compact_addr (pc);
- *kindptr = size | 1;
- }
- else
- *kindptr = 4;
+ *size = 4;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return big_breakpoint;
+ else
+ return little_breakpoint;
+ }
+ default:
+ gdb_assert_not_reached ("unexpected mips breakpoint kind");
+ };
}
/* Return non-zero if the standard MIPS instruction INST has a branch
int dspctl;
/* Fill in the OS dependent register numbers and names. */
- if (info.osabi == GDB_OSABI_IRIX)
- {
- mips_regnum.fp0 = 32;
- mips_regnum.pc = 64;
- mips_regnum.cause = 65;
- mips_regnum.badvaddr = 66;
- mips_regnum.hi = 67;
- mips_regnum.lo = 68;
- mips_regnum.fp_control_status = 69;
- mips_regnum.fp_implementation_revision = 70;
- mips_regnum.dspacc = dspacc = -1;
- mips_regnum.dspctl = dspctl = -1;
- num_regs = 71;
- reg_names = mips_irix_reg_names;
- }
- else if (info.osabi == GDB_OSABI_LINUX)
+ if (info.osabi == GDB_OSABI_LINUX)
{
mips_regnum.fp0 = 38;
mips_regnum.pc = 37;
break;
}
else if (arches != NULL)
- fpu_type = gdbarch_tdep (arches->gdbarch)->mips_fpu_type;
+ fpu_type = MIPS_FPU_TYPE (arches->gdbarch);
else
fpu_type = MIPS_FPU_DOUBLE;
if (gdbarch_debug)
!= mips64_transfers_32bit_regs_p)
continue;
/* Be pedantic about which FPU is selected. */
- if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
+ if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type)
continue;
if (tdesc_data != NULL)
}
/* Need a new architecture. Fill in a target specific vector. */
- tdep = XNEW (struct gdbarch_tdep);
+ tdep = XCNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
tdep->elf_flags = elf_flags;
tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc);
- set_gdbarch_remote_breakpoint_from_pc (gdbarch,
- mips_remote_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, mips_breakpoint_kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, mips_sw_breakpoint_from_kind);
set_gdbarch_adjust_breakpoint_address (gdbarch,
mips_adjust_breakpoint_address);
mips_register_g_packet_guesses (gdbarch);
/* Hook in OS ABI-specific overrides, if they have been registered. */
- info.tdep_info = tdesc_data;
+ info.tdesc_data = tdesc_data;
gdbarch_init_osabi (info, gdbarch);
/* The hook may have adjusted num_regs, fetch the final value and
value);
}
+/* Return a textual name for MIPS FPU type FPU_TYPE. */
+
+static const char *
+mips_fpu_type_str (enum mips_fpu_type fpu_type)
+{
+ switch (fpu_type)
+ {
+ case MIPS_FPU_NONE:
+ return "none";
+ case MIPS_FPU_SINGLE:
+ return "single";
+ case MIPS_FPU_DOUBLE:
+ return "double";
+ default:
+ return "???";
+ }
+}
+
static void
mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n",
MIPS_DEFAULT_FPU_TYPE,
- (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none"
- : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
- : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
- : "???"));
+ mips_fpu_type_str (MIPS_DEFAULT_FPU_TYPE));
fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n",
MIPS_EABI (gdbarch));
fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
MIPS_FPU_TYPE (gdbarch),
- (MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_NONE ? "none"
- : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_SINGLE ? "single"
- : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_DOUBLE ? "double"
- : "???"));
+ mips_fpu_type_str (MIPS_FPU_TYPE (gdbarch)));
}
-extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */
-
void
_initialize_mips_tdep (void)
{