#include "remote.h"
#include "target-descriptions.h"
#include "dwarf2-frame.h"
+#include "user-regs.h"
static const struct objfile_data *mips_pdr_data;
NULL
};
+/* The standard register names, and all the valid aliases for them. */
+struct register_alias
+{
+ const char *name;
+ int regnum;
+};
+
+/* Aliases for o32 and most other ABIs. */
+const struct register_alias mips_o32_aliases[] = {
+ { "ta0", 12 },
+ { "ta1", 13 },
+ { "ta2", 14 },
+ { "ta3", 15 }
+};
+
+/* Aliases for n32 and n64. */
+const struct register_alias mips_n32_n64_aliases[] = {
+ { "ta0", 8 },
+ { "ta1", 9 },
+ { "ta2", 10 },
+ { "ta3", 11 }
+};
+
+/* Aliases for ABI-independent registers. */
+const struct register_alias mips_register_aliases[] = {
+ /* The architecture manuals specify these ABI-independent names for
+ the GPRs. */
+#define R(n) { "r" #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
+
+ /* k0 and k1 are sometimes called these instead (for "kernel
+ temp"). */
+ { "kt0", 26 },
+ { "kt1", 27 },
+
+ /* This is the traditional GDB name for the CP0 status register. */
+ { "sr", MIPS_PS_REGNUM },
+
+ /* This is the traditional GDB name for the CP0 BadVAddr register. */
+ { "bad", MIPS_EMBED_BADVADDR_REGNUM },
+
+ /* This is the traditional GDB name for the FCSR. */
+ { "fsr", MIPS_EMBED_FP0_REGNUM + 32 }
+};
+
/* Some MIPS boards don't support floating point while others only
support single-precision floating-point operations. */
return ((addr) & ~(CORE_ADDR) 1);
}
-/* Return the contents of register REGNUM as a signed integer. */
-
-static LONGEST
-read_signed_register (int regnum)
-{
- LONGEST val;
- regcache_cooked_read_signed (current_regcache, regnum, &val);
- return val;
-}
-
-static LONGEST
-read_signed_register_pid (int regnum, ptid_t ptid)
-{
- ptid_t save_ptid;
- LONGEST retval;
-
- if (ptid_equal (ptid, inferior_ptid))
- return read_signed_register (regnum);
-
- save_ptid = inferior_ptid;
-
- inferior_ptid = ptid;
-
- retval = read_signed_register (regnum);
-
- inferior_ptid = save_ptid;
-
- return retval;
-}
-
/* Return the MIPS ABI associated with GDBARCH. */
enum mips_abi
mips_abi (struct gdbarch *gdbarch)
marks it as 16-bit function. The MSB of the minimal symbol's
"info" field is used for this purpose.
- ELF_MAKE_MSYMBOL_SPECIAL tests whether an ELF symbol is "special",
+ gdbarch_elf_make_msymbol_special tests whether an ELF symbol is "special",
i.e. refers to a 16-bit function, and sets a "special" bit in a
minimal symbol to mark it as a 16-bit function
const gdb_byte *out, int buf_offset)
{
int reg_offset = 0;
- gdb_assert (reg_num >= NUM_REGS);
+ gdb_assert (reg_num >= gdbarch_num_regs (current_gdbarch));
/* Need to transfer the left or right part of the register, based on
the targets byte order. */
switch (endian)
physical 64-bit registers, but should treat them as 32-bit registers. */
static int
-mips2_fp_compat (void)
+mips2_fp_compat (struct frame_info *frame)
{
/* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
meaningful. */
/* Otherwise check the FR bit in the status register - it controls
the FP compatiblity mode. If it is clear we are in compatibility
mode. */
- if ((read_register (MIPS_PS_REGNUM) & ST0_FR) == 0)
+ if ((get_frame_register_unsigned (frame, MIPS_PS_REGNUM) & ST0_FR) == 0)
return 1;
#endif
static CORE_ADDR heuristic_proc_start (CORE_ADDR);
-static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
-
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
static struct type *mips_float_register_type (void);
enum mips_abi abi = mips_abi (current_gdbarch);
- /* Map [NUM_REGS .. 2*NUM_REGS) onto the raw registers, but then
- don't make the raw register names visible. */
- int rawnum = regno % NUM_REGS;
- if (regno < NUM_REGS)
+ /* Map [gdbarch_num_regs .. 2*gdbarch_num_regs) onto the raw registers,
+ but then don't make the raw register names visible. */
+ int rawnum = regno % gdbarch_num_regs (current_gdbarch);
+ if (regno < gdbarch_num_regs (current_gdbarch))
return "";
/* The MIPS integer registers are always mapped from 0 to 31. The
else
return mips_gpr_names[rawnum];
}
- else if (32 <= rawnum && rawnum < NUM_REGS)
+ else if (tdesc_has_registers (gdbarch_target_desc (current_gdbarch)))
+ return tdesc_register_name (rawnum);
+ else if (32 <= rawnum && rawnum < gdbarch_num_regs (current_gdbarch))
{
gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
return tdep->mips_processor_reg_names[rawnum - 32];
int vector_p;
int float_p;
int raw_p;
- int rawnum = regnum % NUM_REGS;
- int pseudo = regnum / NUM_REGS;
+ int rawnum = regnum % gdbarch_num_regs (current_gdbarch);
+ int pseudo = regnum / gdbarch_num_regs (current_gdbarch);
if (reggroup == all_reggroup)
return pseudo;
vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
/* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
(gdbarch), as not all architectures are multi-arch. */
- raw_p = rawnum < NUM_REGS;
- if (REGISTER_NAME (regnum) == NULL || REGISTER_NAME (regnum)[0] == '\0')
+ raw_p = rawnum < gdbarch_num_regs (current_gdbarch);
+ if (gdbarch_register_name (current_gdbarch, regnum) == NULL
+ || gdbarch_register_name (current_gdbarch, regnum)[0] == '\0')
return 0;
if (reggroup == float_reggroup)
return float_p && pseudo;
return 0;
}
+/* Return the groups that a MIPS register can be categorised into.
+ This version is only used if we have a target description which
+ describes real registers (and their groups). */
+
+static int
+mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *reggroup)
+{
+ int rawnum = regnum % gdbarch_num_regs (gdbarch);
+ int pseudo = regnum / gdbarch_num_regs (gdbarch);
+ int ret;
+
+ /* Only save, restore, and display the pseudo registers. Need to
+ make certain that any code extracting register values from a
+ saved register cache also uses pseudo registers.
+
+ Note: saving and restoring the pseudo registers is slightly
+ strange; if we have 64 bits, we should save and restore all
+ 64 bits. But this is hard and has little benefit. */
+ if (!pseudo)
+ return 0;
+
+ ret = tdesc_register_in_reggroup_p (gdbarch, rawnum, reggroup);
+ if (ret != -1)
+ return ret;
+
+ return mips_register_reggroup_p (gdbarch, regnum, reggroup);
+}
+
/* Map the symbol table registers which live in the range [1 *
- NUM_REGS .. 2 * NUM_REGS) back onto the corresponding raw
+ gdbarch_num_regs .. 2 * gdbarch_num_regs) back onto the corresponding raw
registers. Take care of alignment and size problems. */
static void
mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int cookednum, gdb_byte *buf)
{
- int rawnum = cookednum % NUM_REGS;
- gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+ int rawnum = cookednum % gdbarch_num_regs (current_gdbarch);
+ gdb_assert (cookednum >= gdbarch_num_regs (current_gdbarch)
+ && cookednum < 2 * gdbarch_num_regs (current_gdbarch));
if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
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
- || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
else
regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
struct regcache *regcache, int cookednum,
const gdb_byte *buf)
{
- int rawnum = cookednum % NUM_REGS;
- gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+ int rawnum = cookednum % gdbarch_num_regs (current_gdbarch);
+ gdb_assert (cookednum >= gdbarch_num_regs (current_gdbarch)
+ && cookednum < 2 * gdbarch_num_regs (current_gdbarch));
if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
regcache_raw_write (regcache, rawnum, buf);
else if (register_size (gdbarch, rawnum) >
register_size (gdbarch, cookednum))
{
if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
- || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
else
regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
static int
mips_convert_register_p (int regnum, struct type *type)
{
- return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ return (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
&& register_size (current_gdbarch, regnum) == 4
- && (regnum % NUM_REGS) >= mips_regnum (current_gdbarch)->fp0
- && (regnum % NUM_REGS) < mips_regnum (current_gdbarch)->fp0 + 32
+ && (regnum % gdbarch_num_regs (current_gdbarch))
+ >= mips_regnum (current_gdbarch)->fp0
+ && (regnum % gdbarch_num_regs (current_gdbarch))
+ < mips_regnum (current_gdbarch)->fp0 + 32
&& TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8);
}
static struct type *
mips_register_type (struct gdbarch *gdbarch, int regnum)
{
- gdb_assert (regnum >= 0 && regnum < 2 * NUM_REGS);
- if ((regnum % NUM_REGS) >= mips_regnum (current_gdbarch)->fp0
- && (regnum % NUM_REGS) < mips_regnum (current_gdbarch)->fp0 + 32)
+ gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (current_gdbarch));
+ if ((regnum % gdbarch_num_regs (current_gdbarch))
+ >= mips_regnum (current_gdbarch)->fp0
+ && (regnum % gdbarch_num_regs (current_gdbarch))
+ < mips_regnum (current_gdbarch)->fp0 + 32)
{
/* The floating-point registers raw, or cooked, always match
mips_isa_regsize(), and also map 1:1, byte for byte. */
else
return builtin_type_ieee_double;
}
- else if (regnum < NUM_REGS)
+ else if (regnum < gdbarch_num_regs (current_gdbarch))
{
/* The raw or ISA registers. These are all sized according to
the ISA regsize. */
{
/* The cooked or ABI registers. These are sized according to
the ABI (with a few complications). */
- if (regnum >= (NUM_REGS
+ if (regnum >= (gdbarch_num_regs (current_gdbarch)
+ mips_regnum (current_gdbarch)->fp_control_status)
- && regnum <= NUM_REGS + MIPS_LAST_EMBED_REGNUM)
+ && regnum <= gdbarch_num_regs (current_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 the GDB type for the pseudo register REGNUM, which is the
+ ABI-level view. This function is only called if there is a target
+ description which includes registers, so we know precisely the
+ types of hardware registers. */
+
+static struct type *
+mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
+{
+ const int num_regs = gdbarch_num_regs (gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int rawnum = regnum % num_regs;
+ struct type *rawtype;
+
+ gdb_assert (regnum >= num_regs && regnum < 2 * num_regs);
+
+ /* Absent registers are still absent. */
+ rawtype = gdbarch_register_type (gdbarch, rawnum);
+ if (TYPE_LENGTH (rawtype) == 0)
+ return rawtype;
+
+ if (rawnum >= MIPS_EMBED_FP0_REGNUM && rawnum < MIPS_EMBED_FP0_REGNUM + 32)
+ /* Present the floating point registers however the hardware did;
+ do not try to convert between FPU layouts. */
+ return rawtype;
+
+ if (rawnum >= MIPS_EMBED_FP0_REGNUM + 32 && rawnum <= MIPS_LAST_EMBED_REGNUM)
+ {
+ /* The pseudo/cooked view of embedded registers is always
+ 32-bit, even if the target transfers 64-bit values for them.
+ New targets relying on XML descriptions should only transfer
+ 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;
+ }
+
+ /* Use pointer types for registers if we can. For n32 we can not,
+ since we do not have a 64-bit pointer type. */
+ if (mips_abi_regsize (gdbarch) == TYPE_LENGTH (builtin_type_void_data_ptr))
+ {
+ if (rawnum == MIPS_SP_REGNUM || rawnum == MIPS_EMBED_BADVADDR_REGNUM)
+ return builtin_type_void_data_ptr;
+ else if (rawnum == MIPS_EMBED_PC_REGNUM)
+ return builtin_type_void_func_ptr;
+ }
+
+ if (mips_abi_regsize (gdbarch) == 4 && TYPE_LENGTH (rawtype) == 8
+ && rawnum >= MIPS_ZERO_REGNUM && rawnum <= MIPS_EMBED_PC_REGNUM)
+ return builtin_type_int32;
+
+ /* For all other registers, pass through the hardware type. */
+ return rawtype;
+}
/* Should the upper word of 64-bit addresses be zeroed? */
enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO;
all registers should be sign extended for simplicity? */
static CORE_ADDR
-mips_read_pc (ptid_t ptid)
+mips_read_pc (struct regcache *regcache)
{
- return read_signed_register_pid (mips_regnum (current_gdbarch)->pc, ptid);
+ ULONGEST pc;
+ int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
+ regcache_cooked_read_signed (regcache, regnum, &pc);
+ return pc;
}
static CORE_ADDR
mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
return frame_unwind_register_signed (next_frame,
- NUM_REGS + mips_regnum (gdbarch)->pc);
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (gdbarch)->pc);
}
static CORE_ADDR
mips_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- return frame_unwind_register_signed (next_frame, NUM_REGS + MIPS_SP_REGNUM);
+ return frame_unwind_register_signed (next_frame,
+ gdbarch_num_regs (current_gdbarch)
+ + MIPS_SP_REGNUM);
}
/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
static struct frame_id
mips_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- return frame_id_build (frame_unwind_register_signed (next_frame, NUM_REGS + MIPS_SP_REGNUM),
- frame_pc_unwind (next_frame));
+ return frame_id_build
+ (frame_unwind_register_signed (next_frame,
+ gdbarch_num_regs (current_gdbarch)
+ + MIPS_SP_REGNUM),
+ frame_pc_unwind (next_frame));
}
static void
-mips_write_pc (CORE_ADDR pc, ptid_t ptid)
+mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
- write_register_pid (mips_regnum (current_gdbarch)->pc, pc, ptid);
+ int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
+ regcache_cooked_write_unsigned (regcache, regnum, pc);
}
/* Fetch and return instruction from the specified location. If the PC
/* Determine where to set a single step breakpoint while considering
branch prediction. */
static CORE_ADDR
-mips32_next_pc (CORE_ADDR pc)
+mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
unsigned long inst;
int op;
int tf = itype_rt (inst) & 0x01;
int cnum = itype_rt (inst) >> 2;
int fcrcs =
- read_signed_register (mips_regnum (current_gdbarch)->
- fp_control_status);
+ get_frame_register_signed (frame, mips_regnum (current_gdbarch)->
+ fp_control_status);
int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
if (((cond >> cnum) & 0x01) == tf)
case 8: /* JR */
case 9: /* JALR */
/* Set PC to that address */
- pc = read_signed_register (rtype_rs (inst));
+ pc = get_frame_register_signed (frame, rtype_rs (inst));
break;
default:
pc += 4;
case 16: /* BLTZAL */
case 18: /* BLTZALL */
less_branch:
- if (read_signed_register (itype_rs (inst)) < 0)
+ if (get_frame_register_signed (frame, 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 (read_signed_register (itype_rs (inst)) >= 0)
+ if (get_frame_register_signed (frame, itype_rs (inst)) >= 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8; /* after the delay slot */
break; /* The new PC will be alternate mode */
case 4: /* BEQ, BEQL */
equal_branch:
- if (read_signed_register (itype_rs (inst)) ==
- read_signed_register (itype_rt (inst)))
+ if (get_frame_register_signed (frame, itype_rs (inst)) ==
+ get_frame_register_signed (frame, itype_rt (inst)))
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
break;
case 5: /* BNE, BNEL */
neq_branch:
- if (read_signed_register (itype_rs (inst)) !=
- read_signed_register (itype_rt (inst)))
+ if (get_frame_register_signed (frame, itype_rs (inst)) !=
+ get_frame_register_signed (frame, itype_rt (inst)))
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
break;
case 6: /* BLEZ, BLEZL */
- if (read_signed_register (itype_rs (inst)) <= 0)
+ if (get_frame_register_signed (frame, itype_rs (inst)) <= 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
case 7:
default:
greater_branch: /* BGTZ, BGTZL */
- if (read_signed_register (itype_rs (inst)) > 0)
+ if (get_frame_register_signed (frame, itype_rs (inst)) > 0)
pc += mips32_relative_offset (inst) + 4;
else
pc += 8;
}
static CORE_ADDR
-extended_mips16_next_pc (CORE_ADDR pc,
+extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
unsigned int extension, unsigned int insn)
{
int op = (insn >> 11);
struct upk_mips16 upk;
int reg;
unpack_mips16 (pc, extension, insn, ritype, &upk);
- reg = read_signed_register (upk.regx);
+ reg = get_frame_register_signed (frame, upk.regx);
if (reg == 0)
pc += (upk.offset << 1) + 2;
else
struct upk_mips16 upk;
int reg;
unpack_mips16 (pc, extension, insn, ritype, &upk);
- reg = read_signed_register (upk.regx);
+ reg = get_frame_register_signed (frame, upk.regx);
if (reg != 0)
pc += (upk.offset << 1) + 2;
else
int reg;
unpack_mips16 (pc, extension, insn, i8type, &upk);
/* upk.regx contains the opcode */
- reg = read_signed_register (24); /* Test register is 24 */
+ reg = get_frame_register_signed (frame, 24); /* Test register is 24 */
if (((upk.regx == 0) && (reg == 0)) /* BTEZ */
|| ((upk.regx == 1) && (reg != 0))) /* BTNEZ */
/* pc = add_offset_16(pc,upk.offset) ; */
reg = 31;
break; /* BOGUS Guess */
}
- pc = read_signed_register (reg);
+ pc = get_frame_register_signed (frame, reg);
}
else
pc += 2;
that. */
{
pc += 2;
- pc = extended_mips16_next_pc (pc, insn, fetch_mips_16 (pc));
+ pc = extended_mips16_next_pc (frame, pc, insn, fetch_mips_16 (pc));
break;
}
default:
}
static CORE_ADDR
-mips16_next_pc (CORE_ADDR pc)
+mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
unsigned int insn = fetch_mips_16 (pc);
- return extended_mips16_next_pc (pc, 0, insn);
+ return extended_mips16_next_pc (frame, pc, 0, insn);
}
/* The mips_next_pc function supports single_step when the remote
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 (CORE_ADDR pc)
+mips_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
if (pc & 0x01)
- return mips16_next_pc (pc);
+ return mips16_next_pc (frame, pc);
else
- return mips32_next_pc (pc);
+ return mips32_next_pc (frame, pc);
}
struct mips_frame_cache
way we will only recognize the first save of a given register in a
function prologue.
- For simplicity, save the address in both [0 .. NUM_REGS) and
- [NUM_REGS .. 2*NUM_REGS). Strictly speaking, only the second range
- is used as it is only second range (the ABI instead of ISA
- registers) that comes into play when finding saved registers in a
- frame. */
+ For simplicity, save the address in both [0 .. gdbarch_num_regs) and
+ [gdbarch_num_regs .. 2*gdbarch_num_regs).
+ Strictly speaking, only the second range is used as it is only second
+ range (the ABI instead of ISA registers) that comes into play when finding
+ saved registers in a frame. */
static void
set_reg_offset (struct mips_frame_cache *this_cache, int regnum,
if (this_cache != NULL
&& this_cache->saved_regs[regnum].addr == -1)
{
- this_cache->saved_regs[regnum + 0 * NUM_REGS].addr = offset;
- this_cache->saved_regs[regnum + 1 * NUM_REGS].addr = offset;
+ this_cache->saved_regs[regnum
+ + 0 * gdbarch_num_regs (current_gdbarch)].addr
+ = offset;
+ this_cache->saved_regs[regnum
+ + 1 * gdbarch_num_regs (current_gdbarch)].addr
+ = offset;
}
}
/* Can be called when there's no process, and hence when there's no
NEXT_FRAME. */
if (next_frame != NULL)
- sp = read_next_frame_reg (next_frame, NUM_REGS + MIPS_SP_REGNUM);
+ sp = frame_unwind_register_signed (next_frame,
+ gdbarch_num_regs (current_gdbarch)
+ + MIPS_SP_REGNUM);
else
sp = 0;
if (this_cache != NULL)
{
this_cache->base =
- (frame_unwind_register_signed (next_frame, NUM_REGS + frame_reg)
+ (frame_unwind_register_signed (next_frame,
+ gdbarch_num_regs (current_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
still needed for now. */
- this_cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
- = this_cache->saved_regs[NUM_REGS + MIPS_RA_REGNUM];
+ this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->pc]
+ = this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+ + MIPS_RA_REGNUM];
}
/* If we didn't reach the end of the prologue when scanning the function
mips16_scan_prologue (start_addr, pc, next_frame, *this_cache);
}
- /* SP_REGNUM, contains the value and not the address. */
- trad_frame_set_value (cache->saved_regs, NUM_REGS + MIPS_SP_REGNUM, cache->base);
+ /* gdbarch_sp_regnum contains the value and not the address. */
+ trad_frame_set_value (cache->saved_regs, gdbarch_num_regs (current_gdbarch)
+ + MIPS_SP_REGNUM, cache->base);
return (*this_cache);
}
return;
{
- const int num_regs = NUM_REGS;
+ const int num_regs = gdbarch_num_regs (current_gdbarch);
int i;
for (i = 0; i < num_regs; i++)
/* Can be called when there's no process, and hence when there's no
NEXT_FRAME. */
if (next_frame != NULL)
- sp = read_next_frame_reg (next_frame, NUM_REGS + MIPS_SP_REGNUM);
+ sp = frame_unwind_register_signed (next_frame,
+ gdbarch_num_regs (current_gdbarch)
+ + MIPS_SP_REGNUM);
else
sp = 0;
/* Old gcc frame, r30 is virtual frame pointer. */
if ((long) low_word != frame_offset)
frame_addr = sp + low_word;
- else if (frame_reg == MIPS_SP_REGNUM)
+ else if (next_frame && frame_reg == MIPS_SP_REGNUM)
{
unsigned alloca_adjust;
frame_reg = 30;
- frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
+ frame_addr = frame_unwind_register_signed
+ (next_frame,
+ gdbarch_num_regs (current_gdbarch) + 30);
+
alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
if (alloca_adjust > 0)
{
else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d)
{
/* New gcc frame, virtual frame pointer is at r30 + frame_size. */
- if (frame_reg == MIPS_SP_REGNUM)
+ if (next_frame && frame_reg == MIPS_SP_REGNUM)
{
unsigned alloca_adjust;
frame_reg = 30;
- frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
+ frame_addr = frame_unwind_register_signed
+ (next_frame,
+ gdbarch_num_regs (current_gdbarch) + 30);
+
alloca_adjust = (unsigned) (frame_addr - sp);
if (alloca_adjust > 0)
{
if (this_cache != NULL)
{
this_cache->base =
- (frame_unwind_register_signed (next_frame, NUM_REGS + frame_reg)
+ (frame_unwind_register_signed (next_frame,
+ gdbarch_num_regs (current_gdbarch)
+ + frame_reg)
+ frame_offset);
/* FIXME: brobecker/2004-09-15: We should be able to get rid of
this assignment below, eventually. But it's still needed
for now. */
- this_cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
- = this_cache->saved_regs[NUM_REGS + MIPS_RA_REGNUM];
+ this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->pc]
+ = this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+ + MIPS_RA_REGNUM];
}
/* If we didn't reach the end of the prologue when scanning the function
mips32_scan_prologue (start_addr, pc, next_frame, *this_cache);
}
- /* SP_REGNUM, contains the value and not the address. */
- trad_frame_set_value (cache->saved_regs, NUM_REGS + MIPS_SP_REGNUM, cache->base);
+ /* gdbarch_sp_regnum contains the value and not the address. */
+ trad_frame_set_value (cache->saved_regs,
+ gdbarch_num_regs (current_gdbarch) + MIPS_SP_REGNUM,
+ cache->base);
return (*this_cache);
}
(*this_cache) = this_trad_cache;
/* The return address is in the link register. */
- trad_frame_set_reg_realreg (this_trad_cache, PC_REGNUM, MIPS_RA_REGNUM);
+ trad_frame_set_reg_realreg (this_trad_cache,
+ gdbarch_pc_regnum (current_gdbarch),
+ MIPS_RA_REGNUM);
/* Frame ID, since it's a frameless / stackless function, no stack
space is allocated and SP on entry is the current SP. */
return NULL;
}
-static CORE_ADDR
-read_next_frame_reg (struct frame_info *fi, int regno)
-{
- /* Always a pseudo. */
- gdb_assert (regno >= NUM_REGS);
- if (fi == NULL)
- {
- LONGEST val;
- regcache_cooked_read_signed (current_regcache, regno, &val);
- return val;
- }
- else
- return frame_unwind_register_signed (fi, regno);
-
-}
-
/* mips_addr_bits_remove - remove useless address bits */
static CORE_ADDR
the target of the coming instruction and breakpoint it. */
int
-mips_software_single_step (struct regcache *regcache)
+mips_software_single_step (struct frame_info *frame)
{
CORE_ADDR pc, next_pc;
- pc = read_register (mips_regnum (current_gdbarch)->pc);
- next_pc = mips_next_pc (pc);
+ pc = get_frame_pc (frame);
+ next_pc = mips_next_pc (frame, pc);
insert_single_step_breakpoint (next_pc);
return 1;
int instlen;
int seen_adjsp = 0;
- pc = ADDR_BITS_REMOVE (pc);
+ pc = gdbarch_addr_bits_remove (current_gdbarch, pc);
start_pc = pc;
fence = start_pc - heuristic_fence_post;
if (start_pc == 0)
fprintf_unfiltered (gdb_stdlog,
"mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n",
argreg, paddr_nz (struct_addr));
- write_register (argreg++, struct_addr);
+ regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
/* Now load as many as possible of the first arguments into
making the ABI determination. */
if (len == 8 && mips_abi (gdbarch) == MIPS_ABI_EABI32)
{
- int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+ int low_offset = gdbarch_byte_order (current_gdbarch)
+ == BFD_ENDIAN_BIG ? 4 : 0;
unsigned long regval;
/* Write the low word of the double to the even register(s). */
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- write_register (float_argreg++, regval);
+ 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);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- write_register (float_argreg++, regval);
+ regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
}
else
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- write_register (float_argreg++, regval);
+ regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
}
}
else
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
if (regsize == 8
&& (typecode == TYPE_CODE_INT
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
phex (regval, regsize));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
}
fprintf_unfiltered (gdb_stdlog,
"mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n",
argreg, paddr_nz (struct_addr));
- write_register (argreg++, struct_addr);
+ regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
/* Now load as many as possible of the first arguments into
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- write_register (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, len));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg += 1;
}
else
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
if ((typecode == TYPE_CODE_INT
|| typecode == TYPE_CODE_PTR
It does not seem to be necessary to do the
same for integral types. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
&& partial_len < MIPS64_REGSIZE
&& (typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION))
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
phex (regval, MIPS64_REGSIZE));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
}
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $f0 and $f2\n");
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0,
- 8, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0,
+ 8, gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 0);
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 2,
- 8, TARGET_BYTE_ORDER, readbuf ? readbuf + 8 : readbuf,
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0 + 2,
+ 8, gdbarch_byte_order (current_gdbarch),
+ readbuf ? readbuf + 8 : readbuf,
writebuf ? writebuf + 8 : writebuf, 0);
return RETURN_VALUE_REGISTER_CONVENTION;
}
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0,
TYPE_LENGTH (type),
- TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 0);
return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n",
offset);
- mips_xfer_register (regcache, NUM_REGS + regnum,
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum,
TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
- TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
}
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
offset, xfer, regnum);
- mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum, xfer,
BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
offset, xfer, regnum);
- mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
- TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum, xfer,
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
}
fprintf_unfiltered (gdb_stdlog,
"mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n",
argreg, paddr_nz (struct_addr));
- write_register (argreg++, struct_addr);
+ regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
stack_offset += MIPS32_REGSIZE;
}
{
if (register_size (gdbarch, float_argreg) < 8 && len == 8)
{
- int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+ int low_offset = gdbarch_byte_order (current_gdbarch)
+ == BFD_ENDIAN_BIG ? 4 : 0;
unsigned long regval;
/* Write the low word of the double to the even register(s). */
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- write_register (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));
- write_register (argreg++, regval);
+ 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);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- write_register (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));
- write_register (argreg++, regval);
+ regcache_cooked_write_unsigned (regcache, argreg++, regval);
}
else
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- write_register (float_argreg++, regval);
+ regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
/* CAGNEY: 32 bit MIPS ABI's always reserve two FP
registers for each argument. The below is (my
guess) to ensure that the corresponding integer
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
argreg, phex (regval, len));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg += 2;
}
/* Reserve space for the FP register. */
identified as such and GDB gets tweaked
accordingly. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
&& partial_len < MIPS32_REGSIZE
&& (typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION))
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
phex (regval, MIPS32_REGSIZE));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
/* Prevent subsequent floating point arguments from
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0,
TYPE_LENGTH (type),
- TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 0);
return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_FLT
FP0. */
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n");
- switch (TARGET_BYTE_ORDER)
+ switch (gdbarch_byte_order (current_gdbarch))
{
case BFD_ENDIAN_LITTLE:
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
- 0, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0 +
+ 0, 4, gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 0);
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
- 1, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0 + 1,
+ 4, gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 4);
break;
case BFD_ENDIAN_BIG:
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
- 1, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0 + 1,
+ 4, gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 0);
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
- 0, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0 + 0,
+ 4, gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 4);
break;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n",
offset);
- mips_xfer_register (regcache, NUM_REGS + regnum,
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum,
TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
- TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
}
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
offset, xfer, regnum);
- mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum, xfer,
BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
offset, xfer, regnum);
- mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
- TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum, xfer,
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
}
fprintf_unfiltered (gdb_stdlog,
"mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n",
argreg, paddr_nz (struct_addr));
- write_register (argreg++, struct_addr);
+ regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
stack_offset += MIPS64_REGSIZE;
}
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- write_register (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, len));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
/* Reserve space for the FP register. */
stack_offset += align_up (len, MIPS64_REGSIZE);
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
if ((typecode == TYPE_CODE_INT
|| typecode == TYPE_CODE_PTR
It does not seem to be necessary to do the
same for integral types. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
&& partial_len < MIPS64_REGSIZE
&& (typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION))
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
phex (regval, MIPS64_REGSIZE));
- write_register (argreg, regval);
+ regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
/* Prevent subsequent floating point arguments from
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
mips_xfer_register (regcache,
- NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ gdbarch_num_regs (current_gdbarch)
+ + mips_regnum (current_gdbarch)->fp0,
TYPE_LENGTH (type),
- TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, 0);
return RETURN_VALUE_REGISTER_CONVENTION;
}
else
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
offset, xfer, regnum);
- mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
- TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+ + regnum, xfer,
+ gdbarch_byte_order (current_gdbarch),
+ readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
}
gdb_byte *raw_buffer = alloca (raw_size);
if (!frame_register_read (frame, regno, raw_buffer))
- error (_("can't read register %d (%s)"), regno, REGISTER_NAME (regno));
+ error (_("can't read register %d (%s)"),
+ regno, gdbarch_register_name (current_gdbarch, regno));
if (raw_size == 8)
{
/* We have a 64-bit value for this register. Find the low-order
32 bits. */
int offset;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
offset = 4;
else
offset = 0;
{
int raw_size = register_size (current_gdbarch, regno);
- if (raw_size == 8 && !mips2_fp_compat ())
+ if (raw_size == 8 && !mips2_fp_compat (frame))
{
/* We have a 64-bit value for this register, and we should use
all 64 bits. */
if (!frame_register_read (frame, regno, rare_buffer))
- error (_("can't read register %d (%s)"), regno, REGISTER_NAME (regno));
+ error (_("can't read register %d (%s)"),
+ regno, gdbarch_register_name (current_gdbarch, regno));
}
else
{
/* mips_read_fp_register_single will find the correct 32 bits from
each register. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
mips_read_fp_register_single (frame, regno, rare_buffer + 4);
mips_read_fp_register_single (frame, regno + 1, rare_buffer);
raw_buffer = alloca (2 * register_size (current_gdbarch,
mips_regnum (current_gdbarch)->fp0));
- fprintf_filtered (file, "%s:", REGISTER_NAME (regnum));
- fprintf_filtered (file, "%*s", 4 - (int) strlen (REGISTER_NAME (regnum)),
+ fprintf_filtered (file, "%s:",
+ gdbarch_register_name (current_gdbarch, regnum));
+ fprintf_filtered (file, "%*s",
+ 4 - (int) strlen (gdbarch_register_name
+ (current_gdbarch, regnum)),
"");
- if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat ())
+ if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat (frame))
{
/* 4-byte registers: Print hex and floating. Also print even
numbered registers as doubles. */
static void
mips_print_register (struct ui_file *file, struct frame_info *frame,
- int regnum, int all)
+ int regnum)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
/* Get the data in raw format. */
if (!frame_register_read (frame, regnum, raw_buffer))
{
- fprintf_filtered (file, "%s: [Invalid]", REGISTER_NAME (regnum));
+ fprintf_filtered (file, "%s: [Invalid]",
+ gdbarch_register_name (current_gdbarch, regnum));
return;
}
- fputs_filtered (REGISTER_NAME (regnum), file);
+ fputs_filtered (gdbarch_register_name (current_gdbarch, regnum), file);
/* The problem with printing numeric register names (r26, etc.) is that
the user can't use them on input. Probably the best solution is to
else
fprintf_filtered (file, ": ");
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
offset =
register_size (current_gdbarch,
regnum) - register_size (current_gdbarch, regnum);
/* For GP registers, we print a separate row of names above the vals */
for (col = 0, regnum = start_regnum;
- col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ col < ncols && regnum < gdbarch_num_regs (current_gdbarch)
+ + gdbarch_num_pseudo_regs (current_gdbarch);
+ regnum++)
{
- if (*REGISTER_NAME (regnum) == '\0')
+ if (*gdbarch_register_name (current_gdbarch, regnum) == '\0')
continue; /* unused register */
if (TYPE_CODE (register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
break; /* end the row: reached FP register */
+ /* Large registers are handled separately. */
+ if (register_size (current_gdbarch, regnum)
+ > mips_abi_regsize (current_gdbarch))
+ {
+ if (col > 0)
+ break; /* End the row before this register. */
+
+ /* Print this register on a row by itself. */
+ mips_print_register (file, frame, regnum);
+ fprintf_filtered (file, "\n");
+ return regnum + 1;
+ }
if (col == 0)
fprintf_filtered (file, " ");
fprintf_filtered (file,
mips_abi_regsize (current_gdbarch) == 8 ? "%17s" : "%9s",
- REGISTER_NAME (regnum));
+ gdbarch_register_name (current_gdbarch, regnum));
col++;
}
return regnum;
/* print the R0 to R31 names */
- if ((start_regnum % NUM_REGS) < MIPS_NUMREGS)
- fprintf_filtered (file, "\n R%-4d", start_regnum % NUM_REGS);
+ if ((start_regnum % gdbarch_num_regs (current_gdbarch)) < MIPS_NUMREGS)
+ fprintf_filtered (file, "\n R%-4d",
+ start_regnum % gdbarch_num_regs (current_gdbarch));
else
fprintf_filtered (file, "\n ");
/* now print the values in hex, 4 or 8 to the row */
for (col = 0, regnum = start_regnum;
- col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ col < ncols && regnum < gdbarch_num_regs (current_gdbarch)
+ + gdbarch_num_pseudo_regs (current_gdbarch);
+ regnum++)
{
- if (*REGISTER_NAME (regnum) == '\0')
+ if (*gdbarch_register_name (current_gdbarch, regnum) == '\0')
continue; /* unused register */
if (TYPE_CODE (register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
break; /* end row: reached FP register */
+ if (register_size (current_gdbarch, regnum)
+ > mips_abi_regsize (current_gdbarch))
+ break; /* End row: large register. */
+
/* OK: get the data in raw format. */
if (!frame_register_read (frame, regnum, raw_buffer))
- error (_("can't read register %d (%s)"), regnum, REGISTER_NAME (regnum));
+ error (_("can't read register %d (%s)"),
+ regnum, gdbarch_register_name (current_gdbarch, regnum));
/* pad small registers */
for (byte = 0;
byte < (mips_abi_regsize (current_gdbarch)
- register_size (current_gdbarch, regnum)); byte++)
printf_filtered (" ");
/* Now print the register value in hex, endian order. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
for (byte =
register_size (current_gdbarch,
regnum) - register_size (current_gdbarch, regnum);
{
if (regnum != -1) /* do one specified register */
{
- gdb_assert (regnum >= NUM_REGS);
- if (*(REGISTER_NAME (regnum)) == '\0')
+ gdb_assert (regnum >= gdbarch_num_regs (current_gdbarch));
+ if (*(gdbarch_register_name (current_gdbarch, regnum)) == '\0')
error (_("Not a valid register for the current processor type"));
- mips_print_register (file, frame, regnum, 0);
+ mips_print_register (file, frame, regnum);
fprintf_filtered (file, "\n");
}
else
/* do all (or most) registers */
{
- regnum = NUM_REGS;
- while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ regnum = gdbarch_num_regs (current_gdbarch);
+ while (regnum < gdbarch_num_regs (current_gdbarch)
+ + gdbarch_num_pseudo_regs (current_gdbarch))
{
if (TYPE_CODE (register_type (gdbarch, regnum)) ==
TYPE_CODE_FLT)
deprecated_mips_set_processor_regs_hack (void)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- CORE_ADDR prid;
-
- prid = read_register (MIPS_PRID_REGNUM);
+ ULONGEST prid;
+ regcache_cooked_read_unsigned (get_current_regcache (),
+ MIPS_PRID_REGNUM, &prid);
if ((prid & ~0xf) == 0x700)
tdep->mips_processor_reg_names = mips_r3041_reg_names;
}
info->disassembler_options = "gpr-names=32";
/* Call the appropriate disassembler based on the target endian-ness. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
return print_insn_big_mips (memaddr, info);
else
return print_insn_little_mips (memaddr, info);
}
-/* This function implements the BREAKPOINT_FROM_PC macro. 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 (CORE_ADDR *pcptr, int *lenptr)
{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
if (mips_pc_is_mips16 (*pcptr))
{
gory details. */
static CORE_ADDR
-mips_skip_trampoline_code (CORE_ADDR pc)
+mips_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
char *name;
CORE_ADDR start_addr;
target PC is in $31 ($ra). */
if (strcmp (name, "__mips16_ret_sf") == 0
|| strcmp (name, "__mips16_ret_df") == 0)
- return read_signed_register (MIPS_RA_REGNUM);
+ return get_frame_register_signed (frame, MIPS_RA_REGNUM);
if (strncmp (name, "__mips16_call_stub_", 19) == 0)
{
/* If the PC is in __mips16_call_stub_{1..10}, this is a call stub
and the target PC is in $2. */
if (name[19] >= '0' && name[19] <= '9')
- return read_signed_register (2);
+ return get_frame_register_signed (frame, 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
So scan down to the lui/addi and extract the target
address from those two instructions. */
- CORE_ADDR target_pc = read_signed_register (2);
+ CORE_ADDR target_pc = get_frame_register_signed (frame, 2);
ULONGEST inst;
int i;
else
/* This is the 'return' part of a call stub. The return
address is in $r18. */
- return read_signed_register (18);
+ return get_frame_register_signed (frame, 18);
}
}
return 0; /* not a stub */
}
/* Convert a dbx stab register number (from `r' declaration) to a GDB
- [1 * NUM_REGS .. 2 * NUM_REGS) REGNUM. */
+ [1 * gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM. */
static int
mips_stab_reg_to_regnum (int num)
else
/* This will hopefully (eventually) provoke a warning. Should
we be calling complaint() here? */
- return NUM_REGS + NUM_PSEUDO_REGS;
- return NUM_REGS + regnum;
+ return gdbarch_num_regs (current_gdbarch)
+ + gdbarch_num_pseudo_regs (current_gdbarch);
+ return gdbarch_num_regs (current_gdbarch) + regnum;
}
/* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 *
- NUM_REGS .. 2 * NUM_REGS) REGNUM. */
+ gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM. */
static int
mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
else
/* This will hopefully (eventually) provoke a warning. Should we
be calling complaint() here? */
- return NUM_REGS + NUM_PSEUDO_REGS;
- return NUM_REGS + regnum;
+ return gdbarch_num_regs (current_gdbarch)
+ + gdbarch_num_pseudo_regs (current_gdbarch);
+ return gdbarch_num_regs (current_gdbarch) + regnum;
}
static int
mips_register_sim_regno (int regnum)
{
/* Only makes sense to supply raw registers. */
- gdb_assert (regnum >= 0 && regnum < NUM_REGS);
+ gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch));
/* FIXME: cagney/2002-05-13: Need to look at the pseudo register to
decide if it is valid. Should instead define a standard sim/gdb
register numbering scheme. */
- if (REGISTER_NAME (NUM_REGS + regnum) != NULL
- && REGISTER_NAME (NUM_REGS + regnum)[0] != '\0')
+ if (gdbarch_register_name (current_gdbarch,
+ gdbarch_num_regs
+ (current_gdbarch) + regnum) != NULL
+ && gdbarch_register_name (current_gdbarch,
+ gdbarch_num_regs
+ (current_gdbarch) + regnum)[0] != '\0')
return regnum;
else
return LEGACY_SIM_REGNO_IGNORE;
/* Otherwise we don't have a useful guess. */
}
+static struct value *
+value_of_mips_user_reg (struct frame_info *frame, const void *baton)
+{
+ const int *reg_p = baton;
+ return value_of_register (*reg_p, frame);
+}
+
static struct gdbarch *
mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch_tdep *tdep;
int elf_flags;
enum mips_abi mips_abi, found_abi, wanted_abi;
- int num_regs;
+ int i, num_regs;
enum mips_fpu_type fpu_type;
+ struct tdesc_arch_data *tdesc_data = NULL;
+
+ /* Check any target description for validity. */
+ if (tdesc_has_registers (info.target_desc))
+ {
+ static const char *const mips_gprs[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
+ };
+ static const char *const mips_fprs[] = {
+ "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",
+ };
+
+ const struct tdesc_feature *feature;
+ int valid_p;
+
+ feature = tdesc_find_feature (info.target_desc,
+ "org.gnu.gdb.mips.cpu");
+ if (feature == NULL)
+ return NULL;
+
+ tdesc_data = tdesc_data_alloc ();
+
+ valid_p = 1;
+ for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+ mips_gprs[i]);
+
+
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_LO_REGNUM, "lo");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_HI_REGNUM, "hi");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_PC_REGNUM, "pc");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ feature = tdesc_find_feature (info.target_desc,
+ "org.gnu.gdb.mips.cp0");
+ if (feature == NULL)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ valid_p = 1;
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_BADVADDR_REGNUM,
+ "badvaddr");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_PS_REGNUM, "status");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_CAUSE_REGNUM, "cause");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ /* FIXME drow/2007-05-17: The FPU should be optional. The MIPS
+ backend is not prepared for that, though. */
+ feature = tdesc_find_feature (info.target_desc,
+ "org.gnu.gdb.mips.fpu");
+ if (feature == NULL)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ valid_p = 1;
+ for (i = 0; i < 32; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ i + MIPS_EMBED_FP0_REGNUM,
+ mips_fprs[i]);
+
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_FP0_REGNUM + 32, "fcsr");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_EMBED_FP0_REGNUM + 33, "fir");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ /* It would be nice to detect an attempt to use a 64-bit ABI
+ when only 32-bit registers are provided. */
+ }
/* First of all, extract the elf_flags, if available. */
if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
&& tdesc_property (info.target_desc, PROPERTY_GP32) != NULL
&& mips_abi != MIPS_ABI_EABI32
&& mips_abi != MIPS_ABI_O32)
- return NULL;
+ {
+ if (tdesc_data != NULL)
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
/* try to find a pre-existing architecture */
for (arches = gdbarch_list_lookup_by_info (arches, &info);
/* Be pedantic about which FPU is selected. */
if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
continue;
+
+ if (tdesc_data != NULL)
+ tdesc_data_cleanup (tdesc_data);
return arches->gdbarch;
}
const char **reg_names;
struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch,
struct mips_regnum);
- if (info.osabi == GDB_OSABI_IRIX)
+ if (tdesc_has_registers (info.target_desc))
+ {
+ regnum->lo = MIPS_EMBED_LO_REGNUM;
+ regnum->hi = MIPS_EMBED_HI_REGNUM;
+ regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
+ regnum->cause = MIPS_EMBED_CAUSE_REGNUM;
+ regnum->pc = MIPS_EMBED_PC_REGNUM;
+ regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
+ regnum->fp_control_status = 70;
+ regnum->fp_implementation_revision = 71;
+ num_regs = MIPS_LAST_EMBED_REGNUM + 1;
+ reg_names = NULL;
+ }
+ else if (info.osabi == GDB_OSABI_IRIX)
{
regnum->fp0 = 32;
regnum->pc = 64;
else
reg_names = mips_generic_reg_names;
}
- /* FIXME: cagney/2003-11-15: For MIPS, hasn't PC_REGNUM been
+ /* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been
replaced by read_pc? */
set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs);
set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
mips_register_g_packet_guesses (gdbarch);
/* Hook in OS ABI-specific overrides, if they have been registered. */
+ info.tdep_info = (void *) tdesc_data;
gdbarch_init_osabi (info, gdbarch);
/* Unwind the frame. */
frame_base_append_sniffer (gdbarch, mips_insn16_frame_base_sniffer);
frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);
+ if (tdesc_data)
+ {
+ set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);
+ tdesc_use_registers (gdbarch, tdesc_data);
+
+ /* 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);
+
+ num_regs = gdbarch_num_regs (gdbarch);
+ set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
+ set_gdbarch_pc_regnum (gdbarch, tdep->regnum->pc + num_regs);
+ set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
+ }
+
+ /* Add ABI-specific aliases for the registers. */
+ if (mips_abi == MIPS_ABI_N32 || mips_abi == MIPS_ABI_N64)
+ for (i = 0; i < ARRAY_SIZE (mips_n32_n64_aliases); i++)
+ user_reg_add (gdbarch, mips_n32_n64_aliases[i].name,
+ value_of_mips_user_reg, &mips_n32_n64_aliases[i].regnum);
+ else
+ for (i = 0; i < ARRAY_SIZE (mips_o32_aliases); i++)
+ user_reg_add (gdbarch, mips_o32_aliases[i].name,
+ value_of_mips_user_reg, &mips_o32_aliases[i].regnum);
+
+ /* Add some other standard aliases. */
+ for (i = 0; i < ARRAY_SIZE (mips_register_aliases); i++)
+ user_reg_add (gdbarch, mips_register_aliases[i].name,
+ value_of_mips_user_reg, &mips_register_aliases[i].regnum);
+
return gdbarch;
}