aboutsummaryrefslogtreecommitdiff
path: root/gdb/mips-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r--gdb/mips-tdep.c1063
1 files changed, 480 insertions, 583 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index c0d8b08..2c3e8c2 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -134,10 +134,30 @@ struct gdbarch_tdep
int mips_default_saved_regsize;
int mips_fp_register_double;
int mips_default_stack_argsize;
- int gdb_target_is_mips64;
int default_mask_address_p;
+ /* Is the target using 64-bit raw integer registers but only
+ storing a left-aligned 32-bit value in each? */
+ int mips64_transfers_32bit_regs_p;
+ /* Indexes for various registers. IRIX and embedded have
+ different values. This contains the "public" fields. Don't
+ add any that do not need to be public. */
+ const struct mips_regnum *regnum;
+ /* Register names table for the current register set. */
+ const char **mips_processor_reg_names;
};
+const struct mips_regnum *
+mips_regnum (struct gdbarch *gdbarch)
+{
+ return gdbarch_tdep (gdbarch)->regnum;
+}
+
+static int
+mips_fpa0_regnum (struct gdbarch *gdbarch)
+{
+ return mips_regnum (gdbarch)->fp0 + 12;
+}
+
#define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
|| gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
@@ -181,9 +201,9 @@ unmake_mips16_addr (CORE_ADDR addr)
static LONGEST
read_signed_register (int regnum)
{
- void *buf = alloca (DEPRECATED_REGISTER_RAW_SIZE (regnum));
+ void *buf = alloca (register_size (current_gdbarch, regnum));
deprecated_read_register_gen (regnum, buf);
- return (extract_signed_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (regnum)));
+ return (extract_signed_integer (buf, register_size (current_gdbarch, regnum)));
}
static LONGEST
@@ -213,6 +233,13 @@ mips_abi (struct gdbarch *gdbarch)
return gdbarch_tdep (gdbarch)->mips_abi;
}
+int
+mips_regsize (struct gdbarch *gdbarch)
+{
+ return (gdbarch_bfd_arch_info (gdbarch)->bits_per_word
+ / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
+}
+
static unsigned int
mips_saved_regsize (void)
{
@@ -226,17 +253,13 @@ mips_saved_regsize (void)
/* Functions for setting and testing a bit in a minimal symbol that
marks it as 16-bit function. The MSB of the minimal symbol's
- "info" field is used for this purpose. This field is already
- being used to store the symbol size, so the assumption is
- that the symbol size cannot exceed 2^31.
+ "info" field is used for this purpose.
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
- MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol
- MSYMBOL_SIZE returns the size of the minimal symbol, i.e.
- the "info" field with the "special" bit masked out */
+ MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol */
static void
mips_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
@@ -255,12 +278,6 @@ msymbol_is_special (struct minimal_symbol *msym)
return (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0);
}
-static long
-msymbol_size (struct minimal_symbol *msym)
-{
- return ((long) MSYMBOL_INFO (msym) & 0x7fffffff);
-}
-
/* XFER a value from the big/little/left end of the register.
Depending on the size of the value it might occupy the entire
register or just part of it. Make an allowance for this, aligning
@@ -279,7 +296,7 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length,
switch (endian)
{
case BFD_ENDIAN_BIG:
- reg_offset = DEPRECATED_REGISTER_RAW_SIZE (reg_num) - length;
+ reg_offset = register_size (current_gdbarch, reg_num) - length;
break;
case BFD_ENDIAN_LITTLE:
reg_offset = 0;
@@ -325,7 +342,7 @@ mips2_fp_compat (void)
{
/* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
meaningful. */
- if (DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
+ if (register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == 4)
return 0;
#if 0
@@ -343,9 +360,7 @@ mips2_fp_compat (void)
/* Indicate that the ABI makes use of double-precision registers
provided by the FPU (rather than combining pairs of registers to
- form double-precision values). Do not use "TARGET_IS_MIPS64" to
- determine if the ABI is using double-precision registers. See also
- MIPS_FPU_TYPE. */
+ form double-precision values). See also MIPS_FPU_TYPE. */
#define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double)
/* The amount of space reserved on the stack for registers. This is
@@ -369,8 +384,6 @@ mips_stack_argsize (void)
return 4;
}
-#define GDB_TARGET_IS_MIPS64 (gdbarch_tdep (current_gdbarch)->gdb_target_is_mips64 + 0)
-
#define MIPS_DEFAULT_MASK_ADDRESS_P (gdbarch_tdep (current_gdbarch)->default_mask_address_p)
#define VM_MIN_ADDRESS (CORE_ADDR)0x400000
@@ -382,10 +395,6 @@ static CORE_ADDR heuristic_proc_start (CORE_ADDR);
static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
-static int mips_set_processor_type (char *);
-
-static void mips_show_processor_type_command (char *, int);
-
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
static mips_extra_func_info_t find_proc_desc (CORE_ADDR pc,
@@ -398,32 +407,71 @@ static CORE_ADDR after_prologue (CORE_ADDR pc,
static struct type *mips_float_register_type (void);
static struct type *mips_double_register_type (void);
-/* This value is the model of MIPS in use. It is derived from the value
- of the PrID register. */
-
-char *mips_processor_type;
-
-char *tmp_mips_processor_type;
-
/* The list of available "set mips " and "show mips " commands */
static struct cmd_list_element *setmipscmdlist = NULL;
static struct cmd_list_element *showmipscmdlist = NULL;
-/* A set of original names, to be used when restoring back to generic
- registers from a specific set. */
-static char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES;
-
/* Integer registers 0 thru 31 are handled explicitly by
mips_register_name(). Processor specific registers 32 and above
- are listed in the sets of register names assigned to
- mips_processor_reg_names. */
-static char **mips_processor_reg_names = mips_generic_reg_names;
+ are listed in the followign tables. */
+
+enum { NUM_MIPS_PROCESSOR_REGS = (90 - 32) };
+
+/* Generic MIPS. */
+
+static const char *mips_generic_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
+ "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"*/, "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+};
+
+/* 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] = {
+ "sr", "lo", "hi", "bad", "cause","pc",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "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"
+};
+
/* Return the name of the register corresponding to REGNO. */
static const char *
mips_register_name (int regno)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
/* GPR names for all ABIs other than n32/n64. */
static char *mips_gpr_names[] = {
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
@@ -459,79 +507,15 @@ mips_register_name (int regno)
return mips_gpr_names[rawnum];
}
else if (32 <= rawnum && rawnum < NUM_REGS)
- return mips_processor_reg_names[rawnum - 32];
+ {
+ gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
+ return tdep->mips_processor_reg_names[rawnum - 32];
+ }
else
internal_error (__FILE__, __LINE__,
"mips_register_name: bad register number %d", rawnum);
}
-/* *INDENT-OFF* */
-/* Names of IDT R3041 registers. */
-
-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 IDT R3051 registers. */
-
-char *mips_r3051_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"*/, "",
- "inx", "rand", "elo", "", "ctxt", "", "", "",
- "", "", "ehi", "", "", "", "epc", "prid",
-};
-
-/* Names of IDT R3081 registers. */
-
-char *mips_r3081_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"*/, "",
- "inx", "rand", "elo", "cfg", "ctxt", "", "", "",
- "", "", "ehi", "", "", "", "epc", "prid",
-};
-
-/* Names of LSI 33k registers. */
-
-char *mips_lsi33k_reg_names[] = {
- "epc", "hi", "lo", "sr", "cause","badvaddr",
- "dcic", "bpc", "bda", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
-};
-
-struct {
- char *name;
- char **regnames;
-} mips_processor_type_table[] = {
- { "generic", mips_generic_reg_names },
- { "r3041", mips_r3041_reg_names },
- { "r3051", mips_r3051_reg_names },
- { "r3071", mips_r3081_reg_names },
- { "r3081", mips_r3081_reg_names },
- { "lsi33k", mips_lsi33k_reg_names },
- { NULL, NULL }
-};
-/* *INDENT-ON* */
-
/* Return the groups that a MIPS register can be categorised into. */
static int
@@ -572,22 +556,46 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
/* Map the symbol table registers which live in the range [1 *
NUM_REGS .. 2 * NUM_REGS) back onto the corresponding raw
- registers. */
+ registers. Take care of alignment and size problems. */
static void
mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int cookednum, void *buf)
{
+ int rawnum = cookednum % NUM_REGS;
gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
- return regcache_raw_read (regcache, cookednum % NUM_REGS, buf);
+ if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
+ return regcache_raw_read (regcache, rawnum, buf);
+ else if (register_size (gdbarch, rawnum) > register_size (gdbarch, cookednum))
+ {
+ if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
+ || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
+ else
+ regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "bad register size");
}
static void
mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int cookednum, const void *buf)
{
+ int rawnum = cookednum % NUM_REGS;
gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
- return regcache_raw_write (regcache, cookednum % NUM_REGS, buf);
+ if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
+ return 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)
+ regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
+ else
+ regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "bad register size");
}
/* Table to translate MIPS16 register field to actual register number. */
@@ -625,124 +633,35 @@ struct linked_proc_info
*linked_proc_desc_table = NULL;
/* Number of bytes of storage in the actual machine representation for
- register N. NOTE: This indirectly defines the register size
- transfered by the GDB protocol. */
+ register N. NOTE: This defines the pseudo register type so need to
+ rebuild the architecture vector. */
static int mips64_transfers_32bit_regs_p = 0;
-static int
-mips_register_raw_size (int regnum)
-{
- gdb_assert (regnum >= 0);
- if (regnum < NUM_REGS)
- {
- /* For compatibility with old code, implemnt the broken register raw
- size map for the raw registers.
-
- NOTE: cagney/2003-06-15: This is so bogus. The register's
- raw size is changing according to the ABI
- (FP_REGISTER_DOUBLE). Also, GDB's protocol is defined by a
- combination of DEPRECATED_REGISTER_RAW_SIZE and DEPRECATED_REGISTER_BYTE. */
- if (mips64_transfers_32bit_regs_p)
- return DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum);
- else if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM + 32
- && FP_REGISTER_DOUBLE)
- /* For MIPS_ABI_N32 (for example) we need 8 byte floating point
- registers. */
- return 8;
- else
- return MIPS_REGSIZE;
- }
- else if (regnum < 2 * NUM_REGS)
- {
- /* For the moment map [NUM_REGS .. 2*NUM_REGS) onto the same raw
- registers, but always return the virtual size. */
- int rawnum = regnum % NUM_REGS;
- return TYPE_LENGTH (gdbarch_register_type (current_gdbarch, rawnum));
- }
- else
- internal_error (__FILE__, __LINE__, "Register %d out of range", regnum);
-}
-
-/* Register offset in a buffer for each register.
-
- FIXME: cagney/2003-06-15: This is so bogus. Instead REGISTER_TYPE
- should strictly return the layout of the buffer. Unfortunately
- remote.c and the MIPS have come to rely on a custom layout that
- doesn't 1:1 map onto the register type. */
-
-static int
-mips_register_byte (int regnum)
+static void
+set_mips64_transfers_32bit_regs (char *args, int from_tty,
+ struct cmd_list_element *c)
{
- gdb_assert (regnum >= 0);
- if (regnum < NUM_REGS)
- /* Pick up the relevant per-tm file register byte method. */
- return MIPS_REGISTER_BYTE (regnum);
- else if (regnum < 2 * NUM_REGS)
+ struct gdbarch_info info;
+ gdbarch_info_init (&info);
+ /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
+ instead of relying on globals. Doing that would let generic code
+ handle the search for this specific architecture. */
+ if (!gdbarch_update_p (info))
{
- int reg;
- int byte;
- /* Start with the end of the raw register buffer - assum that
- MIPS_REGISTER_BYTE (NUM_REGS) returns that end. */
- byte = MIPS_REGISTER_BYTE (NUM_REGS);
- /* Add space for all the proceeding registers based on their
- real size. */
- for (reg = NUM_REGS; reg < regnum; reg++)
- byte += TYPE_LENGTH (gdbarch_register_type (current_gdbarch,
- (reg % NUM_REGS)));
- return byte;
+ mips64_transfers_32bit_regs_p = 0;
+ error ("32-bit compatibility mode not supported");
}
- else
- internal_error (__FILE__, __LINE__, "Register %d out of range", regnum);
}
-/* Convert between RAW and VIRTUAL registers. The RAW register size
- defines the remote-gdb packet. */
-
-static int
-mips_register_convertible (int reg_nr)
-{
- if (mips64_transfers_32bit_regs_p)
- return 0;
- else
- return (DEPRECATED_REGISTER_RAW_SIZE (reg_nr) > DEPRECATED_REGISTER_VIRTUAL_SIZE (reg_nr));
-}
-
-static void
-mips_register_convert_to_virtual (int n, struct type *virtual_type,
- char *raw_buf, char *virt_buf)
-{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- memcpy (virt_buf,
- raw_buf + (DEPRECATED_REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
- TYPE_LENGTH (virtual_type));
- else
- memcpy (virt_buf,
- raw_buf,
- TYPE_LENGTH (virtual_type));
-}
-
-static void
-mips_register_convert_to_raw (struct type *virtual_type, int n,
- const char *virt_buf, char *raw_buf)
-{
- memset (raw_buf, 0, DEPRECATED_REGISTER_RAW_SIZE (n));
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- memcpy (raw_buf + (DEPRECATED_REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
- virt_buf,
- TYPE_LENGTH (virtual_type));
- else
- memcpy (raw_buf,
- virt_buf,
- TYPE_LENGTH (virtual_type));
-}
+/* Convert to/from a register and the corresponding memory value. */
static int
mips_convert_register_p (int regnum, struct type *type)
{
return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && DEPRECATED_REGISTER_RAW_SIZE (regnum) == 4
- && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
+ && register_size (current_gdbarch, regnum) == 4
+ && (regnum) >= mips_regnum (current_gdbarch)->fp0 && (regnum) < mips_regnum (current_gdbarch)->fp0 + 32
&& TYPE_CODE(type) == TYPE_CODE_FLT
&& TYPE_LENGTH(type) == 8);
}
@@ -769,35 +688,46 @@ mips_value_to_register (struct frame_info *frame, int regnum,
static struct type *
mips_register_type (struct gdbarch *gdbarch, int regnum)
{
- /* For moment, map [NUM_REGS .. 2*NUM_REGS) onto the same raw
- registers. Even return the same type. */
- int rawnum = regnum % NUM_REGS;
- gdb_assert (rawnum >= 0 && rawnum < NUM_REGS);
-#ifdef MIPS_REGISTER_TYPE
- return MIPS_REGISTER_TYPE (rawnum);
-#else
- if (FP0_REGNUM <= rawnum && rawnum < FP0_REGNUM + 32)
+ 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)
{
- /* Floating point registers... */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- return builtin_type_ieee_double_big;
- else
- return builtin_type_ieee_double_little;
+ /* The floating-point registers raw, or cooked, always match
+ mips_regsize(), and also map 1:1, byte for byte. */
+ switch (gdbarch_byte_order (gdbarch))
+ {
+ case BFD_ENDIAN_BIG:
+ if (mips_regsize (gdbarch) == 4)
+ return builtin_type_ieee_single_big;
+ else
+ return builtin_type_ieee_double_big;
+ case BFD_ENDIAN_LITTLE:
+ if (mips_regsize (gdbarch) == 4)
+ return builtin_type_ieee_single_little;
+ else
+ return builtin_type_ieee_double_little;
+ case BFD_ENDIAN_UNKNOWN:
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
}
- else if (rawnum == PS_REGNUM /* CR */)
- return builtin_type_uint32;
- else if (FCRCS_REGNUM <= rawnum && rawnum <= LAST_EMBED_REGNUM)
- return builtin_type_uint32;
+ else if (regnum >= (NUM_REGS + mips_regnum (current_gdbarch)->fp_control_status)
+ && regnum <= NUM_REGS + 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;
+ else if (regnum >= NUM_REGS && mips_regsize (gdbarch)
+ && gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
+ /* The target, while using a 64-bit register buffer, is only
+ transfering 32-bits of each integer register. Reflect this in
+ the cooked/pseudo register value. */
+ return builtin_type_int32;
+ else if (mips_regsize (gdbarch) == 8)
+ /* 64-bit ISA. */
+ return builtin_type_int64;
else
- {
- /* Everything else...
- Return type appropriate for width of register. */
- if (MIPS_REGSIZE == TYPE_LENGTH (builtin_type_uint64))
- return builtin_type_uint64;
- else
- return builtin_type_uint32;
- }
-#endif
+ /* 32-bit ISA. */
+ return builtin_type_int32;
}
/* TARGET_READ_SP -- Remove useless bits from the stack pointer. */
@@ -860,12 +790,6 @@ mips_eabi_use_struct_convention (int gcc_p, struct type *type)
return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
}
-static int
-mips_n32n64_use_struct_convention (int gcc_p, struct type *type)
-{
- return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
-}
-
/* Should call_function pass struct by reference?
For each architecture, structs are passed either by
value or by reference, depending on their size. */
@@ -1109,7 +1033,7 @@ mips32_next_pc (CORE_ADDR pc)
{
int tf = itype_rt (inst) & 0x01;
int cnum = itype_rt (inst) >> 2;
- int fcrcs = read_signed_register (FCRCS_REGNUM);
+ int fcrcs = read_signed_register (mips_regnum (current_gdbarch)->fp_control_status);
int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
if (((cond >> cnum) & 0x01) == tf)
@@ -1569,31 +1493,27 @@ mips_find_saved_regs (struct frame_info *fci)
#ifndef SIGFRAME_BASE
/* To satisfy alignment restrictions, sigcontext is located 4 bytes
above the sigtramp frame. */
-#define SIGFRAME_BASE MIPS_REGSIZE
+#define SIGFRAME_BASE mips_regsize (current_gdbarch)
/* FIXME! Are these correct?? */
-#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * MIPS_REGSIZE)
-#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 3 * MIPS_REGSIZE)
+#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * mips_regsize (current_gdbarch))
+#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 3 * mips_regsize (current_gdbarch))
#define SIGFRAME_FPREGSAVE_OFF \
- (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * MIPS_REGSIZE + 3 * MIPS_REGSIZE)
-#endif
-#ifndef SIGFRAME_REG_SIZE
- /* FIXME! Is this correct?? */
-#define SIGFRAME_REG_SIZE MIPS_REGSIZE
+ (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * mips_regsize (current_gdbarch) + 3 * mips_regsize (current_gdbarch))
#endif
if ((get_frame_type (fci) == SIGTRAMP_FRAME))
{
for (ireg = 0; ireg < MIPS_NUMREGS; ireg++)
{
CORE_ADDR reg_position = (get_frame_base (fci) + SIGFRAME_REGSAVE_OFF
- + ireg * SIGFRAME_REG_SIZE);
+ + ireg * mips_regsize (current_gdbarch));
set_reg_offset (saved_regs, ireg, reg_position);
}
for (ireg = 0; ireg < MIPS_NUMREGS; ireg++)
{
CORE_ADDR reg_position = (get_frame_base (fci)
+ SIGFRAME_FPREGSAVE_OFF
- + ireg * SIGFRAME_REG_SIZE);
- set_reg_offset (saved_regs, FP0_REGNUM + ireg, reg_position);
+ + ireg * mips_regsize (current_gdbarch));
+ set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg, reg_position);
}
set_reg_offset (saved_regs, PC_REGNUM, get_frame_base (fci) + SIGFRAME_PC_OFF);
@@ -1741,14 +1661,14 @@ mips_find_saved_regs (struct frame_info *fci)
reg_position is decremented each time through the
loop). */
if ((ireg & 1))
- set_reg_offset (saved_regs, FP0_REGNUM + ireg,
+ set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg,
reg_position - MIPS_SAVED_REGSIZE);
else
- set_reg_offset (saved_regs, FP0_REGNUM + ireg,
+ set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg,
reg_position + MIPS_SAVED_REGSIZE);
}
else
- set_reg_offset (saved_regs, FP0_REGNUM + ireg, reg_position);
+ set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg, reg_position);
reg_position -= MIPS_SAVED_REGSIZE;
}
@@ -1786,40 +1706,26 @@ read_next_frame_reg (struct frame_info *fi, int regno)
static CORE_ADDR
mips_addr_bits_remove (CORE_ADDR addr)
{
- if (GDB_TARGET_IS_MIPS64)
- {
- if (mips_mask_address_p () && (addr >> 32 == (CORE_ADDR) 0xffffffff))
- {
- /* This hack is a work-around for existing boards using
- PMON, the simulator, and any other 64-bit targets that
- doesn't have true 64-bit addressing. On these targets,
- the upper 32 bits of addresses are ignored by the
- hardware. Thus, the PC or SP are likely to have been
- sign extended to all 1s by instruction sequences that
- load 32-bit addresses. For example, a typical piece of
- code that loads an address is this:
- lui $r2, <upper 16 bits>
- ori $r2, <lower 16 bits>
- But the lui sign-extends the value such that the upper 32
- bits may be all 1s. The workaround is simply to mask off
- these bits. In the future, gcc may be changed to support
- true 64-bit addressing, and this masking will have to be
- disabled. */
- addr &= (CORE_ADDR) 0xffffffff;
- }
- }
- else if (mips_mask_address_p ())
- {
- /* FIXME: This is wrong! mips_addr_bits_remove() shouldn't be
- masking off bits, instead, the actual target should be asking
- for the address to be converted to a valid pointer. */
- /* Even when GDB is configured for some 32-bit targets
- (e.g. mips-elf), BFD is configured to handle 64-bit targets,
- so CORE_ADDR is 64 bits. So we still have to mask off
- useless bits from addresses. */
- addr &= (CORE_ADDR) 0xffffffff;
- }
- return addr;
+ if (mips_mask_address_p ()
+ && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
+ /* This hack is a work-around for existing boards using PMON, the
+ simulator, and any other 64-bit targets that doesn't have true
+ 64-bit addressing. On these targets, the upper 32 bits of
+ addresses are ignored by the hardware. Thus, the PC or SP are
+ likely to have been sign extended to all 1s by instruction
+ sequences that load 32-bit addresses. For example, a typical
+ piece of code that loads an address is this:
+
+ lui $r2, <upper 16 bits>
+ ori $r2, <lower 16 bits>
+
+ But the lui sign-extends the value such that the upper 32 bits
+ may be all 1s. The workaround is simply to mask off these
+ bits. In the future, gcc may be changed to support true 64-bit
+ addressing, and this masking will have to be disabled. */
+ return addr &= 0xffffffffUL;
+ else
+ return addr;
}
/* mips_software_single_step() is called just before we want to resume
@@ -1871,10 +1777,8 @@ mips_frame_saved_pc (struct frame_info *frame)
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0))
{
- LONGEST tmp;
/* Always unwind the cooked PC register value. */
- frame_unwind_signed_register (frame, NUM_REGS + PC_REGNUM, &tmp);
- saved_pc = tmp;
+ saved_pc = frame_unwind_register_signed (frame, NUM_REGS + PC_REGNUM);
}
else
{
@@ -2262,7 +2166,7 @@ restart:
but the register size used is only 32 bits. Make the address
for the saved register point to the lower 32 bits. */
PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
- set_reg_offset (temp_saved_regs, reg, sp + low_word + 8 - MIPS_REGSIZE);
+ set_reg_offset (temp_saved_regs, reg, sp + low_word + 8 - mips_regsize (current_gdbarch));
}
else if (high_word == 0x27be) /* addiu $30,$sp,size */
{
@@ -2611,9 +2515,6 @@ mips_frame_chain (struct frame_info *frame)
CORE_ADDR tmp;
CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame);
- if (saved_pc == 0 || deprecated_inside_entry_file (saved_pc))
- return 0;
-
/* Check if the PC is inside a call stub. If it is, fetch the
PC of the caller of that stub. */
if ((tmp = SKIP_TRAMPOLINE_CODE (saved_pc)) != 0)
@@ -2672,7 +2573,6 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
frame_extra_info_zalloc (fci, sizeof (struct frame_extra_info));
- deprecated_set_frame_saved_regs_hack (fci, NULL);
get_frame_extra_info (fci)->proc_desc =
proc_desc == &temp_proc_desc ? 0 : proc_desc;
if (proc_desc)
@@ -2862,7 +2762,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* Initialize the integer and float register pointers. */
argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ float_argreg = mips_fpa0_regnum (current_gdbarch);
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -2970,10 +2870,11 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* 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 MIPS_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. */
+ /* Note: structs whose size is not a multiple of
+ mips_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 > MIPS_SAVED_REGSIZE) &&
(len % MIPS_SAVED_REGSIZE != 0));
@@ -3122,7 +3023,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* Initialize the integer and float register pointers. */
argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ float_argreg = mips_fpa0_regnum (current_gdbarch);
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -3177,10 +3078,11 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* 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 MIPS_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. */
+ /* Note: structs whose size is not a multiple of
+ mips_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 > MIPS_SAVED_REGSIZE) &&
(len % MIPS_SAVED_REGSIZE != 0));
/* Note: Floating-point values that didn't fit into an FP
@@ -3353,7 +3255,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* Initialize the integer and float register pointers. */
argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ float_argreg = mips_fpa0_regnum (current_gdbarch);
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -3467,10 +3369,11 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* 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 MIPS_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. */
+ /* Note: structs whose size is not a multiple of
+ mips_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 > MIPS_SAVED_REGSIZE) &&
(len % MIPS_SAVED_REGSIZE != 0));
/* Structures should be aligned to eight bytes (even arg registers)
@@ -3546,8 +3449,8 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
&& !fp_register_arg_p (typecode, arg_type))
{
LONGEST regval = extract_signed_integer (val, partial_len);
- /* Value may need to be sign extended, because
- MIPS_REGSIZE != MIPS_SAVED_REGSIZE. */
+ /* Value may need to be sign extended, because
+ mips_regsize() != MIPS_SAVED_REGSIZE. */
/* A non-floating-point argument being passed in a
general register. If a struct or union, and if
@@ -3661,7 +3564,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* Initialize the integer and float register pointers. */
argreg = A0_REGNUM;
- float_argreg = FPA0_REGNUM;
+ float_argreg = mips_fpa0_regnum (current_gdbarch);
/* The struct_return pointer occupies the first parameter-passing reg. */
if (struct_return)
@@ -3775,10 +3678,11 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
/* 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 MIPS_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. */
+ /* Note: structs whose size is not a multiple of
+ mips_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 > MIPS_SAVED_REGSIZE) &&
(len % MIPS_SAVED_REGSIZE != 0));
/* Structures should be aligned to eight bytes (even arg registers)
@@ -3854,8 +3758,8 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
&& !fp_register_arg_p (typecode, arg_type))
{
LONGEST regval = extract_signed_integer (val, partial_len);
- /* Value may need to be sign extended, because
- MIPS_REGSIZE != MIPS_SAVED_REGSIZE. */
+ /* Value may need to be sign extended, because
+ mips_regsize() != MIPS_SAVED_REGSIZE. */
/* A non-floating-point argument being passed in a
general register. If a struct or union, and if
@@ -3950,7 +3854,7 @@ mips_pop_frame (void)
/* Floating point registers must not be sign extended,
in case MIPS_SAVED_REGSIZE = 4 but sizeof (FP0_REGNUM) == 8. */
- if (FP0_REGNUM <= regnum && regnum < FP0_REGNUM + 32)
+ if (mips_regnum (current_gdbarch)->fp0 <= regnum && regnum < mips_regnum (current_gdbarch)->fp0 + 32)
write_register (regnum,
read_memory_unsigned_integer (deprecated_get_frame_saved_regs (frame)[regnum],
MIPS_SAVED_REGSIZE));
@@ -3985,14 +3889,14 @@ mips_pop_frame (void)
xfree (pi_ptr);
- write_register (HI_REGNUM,
+ write_register (mips_regnum (current_gdbarch)->hi,
read_memory_integer (new_sp - 2 * MIPS_SAVED_REGSIZE,
MIPS_SAVED_REGSIZE));
- write_register (LO_REGNUM,
+ write_register (mips_regnum (current_gdbarch)->lo,
read_memory_integer (new_sp - 3 * MIPS_SAVED_REGSIZE,
MIPS_SAVED_REGSIZE));
if (MIPS_FPU_TYPE != MIPS_FPU_NONE)
- write_register (FCRCS_REGNUM,
+ write_register (mips_regnum (current_gdbarch)->fp_control_status,
read_memory_integer (new_sp - 4 * MIPS_SAVED_REGSIZE,
MIPS_SAVED_REGSIZE));
}
@@ -4053,7 +3957,7 @@ static void
mips_read_fp_register_single (struct frame_info *frame, int regno,
char *rare_buffer)
{
- int raw_size = DEPRECATED_REGISTER_RAW_SIZE (regno);
+ int raw_size = register_size (current_gdbarch, regno);
char *raw_buffer = alloca (raw_size);
if (!frame_register_read (frame, regno, raw_buffer))
@@ -4085,7 +3989,7 @@ static void
mips_read_fp_register_double (struct frame_info *frame, int regno,
char *rare_buffer)
{
- int raw_size = DEPRECATED_REGISTER_RAW_SIZE (regno);
+ int raw_size = register_size (current_gdbarch, regno);
if (raw_size == 8 && !mips2_fp_compat ())
{
@@ -4096,7 +4000,7 @@ mips_read_fp_register_double (struct frame_info *frame, int regno,
}
else
{
- if ((regno - FP0_REGNUM) & 1)
+ if ((regno - mips_regnum (current_gdbarch)->fp0) & 1)
internal_error (__FILE__, __LINE__,
"mips_read_fp_register_double: bad access to "
"odd-numbered FP register");
@@ -4124,13 +4028,13 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
double doub, flt1, flt2; /* doubles extracted from raw hex data */
int inv1, inv2, namelen;
- raw_buffer = (char *) alloca (2 * DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM));
+ raw_buffer = (char *) 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)),
"");
- if (DEPRECATED_REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
+ if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat ())
{
/* 4-byte registers: Print hex and floating. Also print even
numbered registers as doubles. */
@@ -4217,7 +4121,7 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
fprintf_filtered (file, ": ");
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- offset = DEPRECATED_REGISTER_RAW_SIZE (regnum) - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum);
+ offset = register_size (current_gdbarch, regnum) - register_size (current_gdbarch, regnum);
else
offset = 0;
@@ -4248,7 +4152,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
struct gdbarch *gdbarch = get_frame_arch (frame);
/* do values for GP (int) regs */
char raw_buffer[MAX_REGISTER_SIZE];
- int ncols = (MIPS_REGSIZE == 8 ? 4 : 8); /* display cols per row */
+ int ncols = (mips_regsize (gdbarch) == 8 ? 4 : 8); /* display cols per row */
int col, byte;
int regnum;
@@ -4262,7 +4166,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
continue; /* unused register */
if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
break; /* end the row: reached FP register */
- fprintf_filtered (file, MIPS_REGSIZE == 8 ? "%17s" : "%9s",
+ fprintf_filtered (file, mips_regsize (current_gdbarch) == 8 ? "%17s" : "%9s",
REGISTER_NAME (regnum));
col++;
}
@@ -4285,16 +4189,19 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
if (!frame_register_read (frame, regnum, raw_buffer))
error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
/* pad small registers */
- for (byte = 0; byte < (MIPS_REGSIZE - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); byte++)
+ for (byte = 0;
+ byte < (mips_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)
- for (byte = DEPRECATED_REGISTER_RAW_SIZE (regnum) - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum);
- byte < DEPRECATED_REGISTER_RAW_SIZE (regnum);
+ for (byte = register_size (current_gdbarch, regnum) - register_size (current_gdbarch, regnum);
+ byte < register_size (current_gdbarch, regnum);
byte++)
fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
else
- for (byte = DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum) - 1;
+ for (byte = register_size (current_gdbarch, regnum) - 1;
byte >= 0;
byte--)
fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
@@ -4375,6 +4282,61 @@ mips_step_skips_delay (CORE_ADDR pc)
}
+/* Given PC at the function's start address, attempt to find the
+ prologue end using SAL information. Return zero if the skip fails.
+
+ A non-optimized prologue traditionally has one SAL for the function
+ and a second for the function body. A single line function has
+ them both pointing at the same line.
+
+ An optimized prologue is similar but the prologue may contain
+ instructions (SALs) from the instruction body. Need to skip those
+ while not getting into the function body.
+
+ The functions end point and an increasing SAL line are used as
+ indicators of the prologue's endpoint.
+
+ This code is based on the function refine_prologue_limit (versions
+ found in both ia64 and ppc). */
+
+static CORE_ADDR
+skip_prologue_using_sal (CORE_ADDR func_addr)
+{
+ struct symtab_and_line prologue_sal;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
+
+ /* Get an initial range for the function. */
+ find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+ start_pc += FUNCTION_START_OFFSET;
+
+ prologue_sal = find_pc_line (start_pc, 0);
+ if (prologue_sal.line != 0)
+ {
+ while (prologue_sal.end < end_pc)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (prologue_sal.end, 0);
+ if (sal.line == 0)
+ break;
+ /* Assume that a consecutive SAL for the same (or larger)
+ line mark the prologue -> body transition. */
+ if (sal.line >= prologue_sal.line)
+ break;
+ /* The case in which compiler's optimizer/scheduler has
+ moved instructions into the prologue. We look ahead in
+ the function looking for address ranges whose
+ corresponding line number is less the first one that we
+ found for the function. This is more conservative then
+ refine_prologue_limit which scans a large number of SALs
+ looking for any in the prologue */
+ prologue_sal = sal;
+ }
+ }
+ return prologue_sal.end;
+}
+
/* Skip the PC past function prologue instructions (32-bit version).
This is a helper function for mips_skip_prologue. */
@@ -4386,10 +4348,15 @@ mips32_skip_prologue (CORE_ADDR pc)
int seen_sp_adjust = 0;
int load_immediate_bytes = 0;
+ /* Find an upper bound on the prologue. */
+ end_pc = skip_prologue_using_sal (pc);
+ if (end_pc == 0)
+ end_pc = pc + 100; /* Magic. */
+
/* Skip the typical prologue instructions. These are the stack adjustment
instruction and the instructions that save registers on the stack
or in the gcc frame. */
- for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
+ for (; pc < end_pc; pc += MIPS_INSTLEN)
{
unsigned long high_word;
@@ -4531,10 +4498,15 @@ mips16_skip_prologue (CORE_ADDR pc)
} /* end of table marker */
};
+ /* Find an upper bound on the prologue. */
+ end_pc = skip_prologue_using_sal (pc);
+ if (end_pc == 0)
+ end_pc = pc + 100; /* Magic. */
+
/* Skip the typical prologue instructions. These are the stack adjustment
instruction and the instructions that save registers on the stack
or in the gcc frame. */
- for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
+ for (; pc < end_pc; pc += MIPS16_INSTLEN)
{
unsigned short inst;
int i;
@@ -4629,11 +4601,11 @@ return_value_location (struct type *valtype,
lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4;
lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) == 8)
+ && register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == 8)
? 4 : 0);
hi->reg_offset = lo->reg_offset;
- lo->reg = FP0_REGNUM + 0;
- hi->reg = FP0_REGNUM + 1;
+ lo->reg = mips_regnum (current_gdbarch)->fp0 + 0;
+ hi->reg = mips_regnum (current_gdbarch)->fp0 + 1;
lo->len = 4;
hi->len = 4;
}
@@ -4642,10 +4614,10 @@ return_value_location (struct type *valtype,
/* The floating point value fits in a single floating-point
register. */
lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) == 8
+ && register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == 8
&& len == 4)
? 4 : 0);
- lo->reg = FP0_REGNUM;
+ lo->reg = mips_regnum (current_gdbarch)->fp0;
lo->len = len;
lo->buf_offset = 0;
hi->len = 0;
@@ -4698,7 +4670,7 @@ return_value_location (struct type *valtype,
}
}
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && DEPRECATED_REGISTER_RAW_SIZE (regnum) == 8
+ && register_size (current_gdbarch, regnum) == 8
&& MIPS_SAVED_REGSIZE == 4)
{
/* Account for the fact that only the least-signficant part
@@ -4724,12 +4696,12 @@ mips_eabi_extract_return_value (struct type *valtype,
return_value_location (valtype, &hi, &lo);
memcpy (valbuf + lo.buf_offset,
- regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) + lo.reg_offset,
+ regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + lo.reg_offset,
lo.len);
if (hi.len > 0)
memcpy (valbuf + hi.buf_offset,
- regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) + hi.reg_offset,
+ regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + hi.reg_offset,
hi.len);
}
@@ -4743,12 +4715,12 @@ mips_o64_extract_return_value (struct type *valtype,
return_value_location (valtype, &hi, &lo);
memcpy (valbuf + lo.buf_offset,
- regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) + lo.reg_offset,
+ regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + lo.reg_offset,
lo.len);
if (hi.len > 0)
memcpy (valbuf + hi.buf_offset,
- regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) + hi.reg_offset,
+ regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + hi.reg_offset,
hi.len);
}
@@ -4766,14 +4738,14 @@ mips_eabi_store_return_value (struct type *valtype, char *valbuf)
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), raw_buffer,
- DEPRECATED_REGISTER_RAW_SIZE (lo.reg));
+ register_size (current_gdbarch, lo.reg));
if (hi.len > 0)
{
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len);
deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), raw_buffer,
- DEPRECATED_REGISTER_RAW_SIZE (hi.reg));
+ register_size (current_gdbarch, hi.reg));
}
}
@@ -4788,35 +4760,43 @@ mips_o64_store_return_value (struct type *valtype, char *valbuf)
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), raw_buffer,
- DEPRECATED_REGISTER_RAW_SIZE (lo.reg));
+ register_size (current_gdbarch, lo.reg));
if (hi.len > 0)
{
memset (raw_buffer, 0, sizeof (raw_buffer));
memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len);
deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), raw_buffer,
- DEPRECATED_REGISTER_RAW_SIZE (hi.reg));
+ register_size (current_gdbarch, hi.reg));
}
}
/* O32 ABI stuff. */
-static void
-mips_o32_xfer_return_value (struct type *type,
- struct regcache *regcache,
- bfd_byte *in, const bfd_byte *out)
+static enum return_value_convention
+mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache,
+ void *readbuf, const void *writebuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- if (TYPE_CODE (type) == TYPE_CODE_FLT
- && TYPE_LENGTH (type) == 4
- && tdep->mips_fpu_type != MIPS_FPU_NONE)
+
+ if (TYPE_CODE (type)== TYPE_CODE_STRUCT
+ || TYPE_CODE (type)== TYPE_CODE_UNION
+ || TYPE_CODE (type)== TYPE_CODE_ARRAY)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (type) == 4
+ && tdep->mips_fpu_type != MIPS_FPU_NONE)
{
/* A single-precision floating-point value. It fits in the
least significant part of FP0. */
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
- mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type),
- TARGET_BYTE_ORDER, in, out, 0);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ TYPE_LENGTH (type),
+ TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_FLT
&& TYPE_LENGTH (type) == 8
@@ -4830,20 +4810,25 @@ mips_o32_xfer_return_value (struct type *type,
switch (TARGET_BYTE_ORDER)
{
case BFD_ENDIAN_LITTLE:
- mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4,
- TARGET_BYTE_ORDER, in, out, 0);
- mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 1, 4,
- TARGET_BYTE_ORDER, in, out, 4);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 0,
+ 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 1,
+ 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
break;
case BFD_ENDIAN_BIG:
- mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 1, 4,
- TARGET_BYTE_ORDER, in, out, 0);
- mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4,
- TARGET_BYTE_ORDER, in, out, 4);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 1,
+ 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 0,
+ 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
break;
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
#if 0
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -4865,7 +4850,7 @@ mips_o32_xfer_return_value (struct type *type,
bfd_byte reg[MAX_REGISTER_SIZE];
int regnum;
int field;
- for (field = 0, regnum = FP0_REGNUM;
+ for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0;
field < TYPE_NFIELDS (type);
field++, regnum += 2)
{
@@ -4875,8 +4860,9 @@ mips_o32_xfer_return_value (struct type *type,
fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
mips_xfer_register (regcache, NUM_REGS + regnum,
TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
- TARGET_BYTE_ORDER, in, out, offset);
+ TARGET_BYTE_ORDER, readbuf, writebuf, offset);
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
#endif
#if 0
@@ -4890,17 +4876,18 @@ mips_o32_xfer_return_value (struct type *type,
int regnum;
for (offset = 0, regnum = V0_REGNUM;
offset < TYPE_LENGTH (type);
- offset += DEPRECATED_REGISTER_RAW_SIZE (regnum), regnum++)
+ offset += register_size (current_gdbarch, regnum), regnum++)
{
- int xfer = DEPRECATED_REGISTER_RAW_SIZE (regnum);
+ int xfer = register_size (current_gdbarch, regnum);
if (offset + xfer > TYPE_LENGTH (type))
xfer = TYPE_LENGTH (type) - offset;
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,
- BFD_ENDIAN_UNKNOWN, in, out, offset);
+ BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
#endif
else
@@ -4922,42 +4909,37 @@ mips_o32_xfer_return_value (struct type *type,
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, in, out, offset);
+ TARGET_BYTE_ORDER, readbuf, writebuf, offset);
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
}
-static void
-mips_o32_extract_return_value (struct type *type,
- struct regcache *regcache,
- void *valbuf)
-{
- mips_o32_xfer_return_value (type, regcache, valbuf, NULL);
-}
-
-static void
-mips_o32_store_return_value (struct type *type, char *valbuf)
-{
- mips_o32_xfer_return_value (type, current_regcache, NULL, valbuf);
-}
-
/* N32/N44 ABI stuff. */
-static void
-mips_n32n64_xfer_return_value (struct type *type,
- struct regcache *regcache,
- bfd_byte *in, const bfd_byte *out)
+static enum return_value_convention
+mips_n32n64_return_value (struct gdbarch *gdbarch,
+ struct type *type, struct regcache *regcache,
+ void *readbuf, const void *writebuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- if (TYPE_CODE (type) == TYPE_CODE_FLT
- && tdep->mips_fpu_type != MIPS_FPU_NONE)
+ if (TYPE_CODE (type)== TYPE_CODE_STRUCT
+ || TYPE_CODE (type)== TYPE_CODE_UNION
+ || TYPE_CODE (type)== TYPE_CODE_ARRAY
+ || TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && tdep->mips_fpu_type != MIPS_FPU_NONE)
{
/* A floating-point value belongs in the least significant part
of FP0. */
if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
- mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type),
- TARGET_BYTE_ORDER, in, out, 0);
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ TYPE_LENGTH (type),
+ TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
&& TYPE_NFIELDS (type) <= 2
@@ -4978,7 +4960,7 @@ mips_n32n64_xfer_return_value (struct type *type,
bfd_byte reg[MAX_REGISTER_SIZE];
int regnum;
int field;
- for (field = 0, regnum = FP0_REGNUM;
+ for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0;
field < TYPE_NFIELDS (type);
field++, regnum += 2)
{
@@ -4988,8 +4970,9 @@ mips_n32n64_xfer_return_value (struct type *type,
fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
mips_xfer_register (regcache, NUM_REGS + regnum,
TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
- TARGET_BYTE_ORDER, in, out, offset);
+ TARGET_BYTE_ORDER, readbuf, writebuf, offset);
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION)
@@ -5001,17 +4984,18 @@ mips_n32n64_xfer_return_value (struct type *type,
int regnum;
for (offset = 0, regnum = V0_REGNUM;
offset < TYPE_LENGTH (type);
- offset += DEPRECATED_REGISTER_RAW_SIZE (regnum), regnum++)
+ offset += register_size (current_gdbarch, regnum), regnum++)
{
- int xfer = DEPRECATED_REGISTER_RAW_SIZE (regnum);
+ int xfer = register_size (current_gdbarch, regnum);
if (offset + xfer > TYPE_LENGTH (type))
xfer = TYPE_LENGTH (type) - offset;
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,
- BFD_ENDIAN_UNKNOWN, in, out, offset);
+ BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
else
{
@@ -5021,9 +5005,9 @@ mips_n32n64_xfer_return_value (struct type *type,
int regnum;
for (offset = 0, regnum = V0_REGNUM;
offset < TYPE_LENGTH (type);
- offset += DEPRECATED_REGISTER_RAW_SIZE (regnum), regnum++)
+ offset += register_size (current_gdbarch, regnum), regnum++)
{
- int xfer = DEPRECATED_REGISTER_RAW_SIZE (regnum);
+ int xfer = register_size (current_gdbarch, regnum);
int pos = 0;
if (offset + xfer > TYPE_LENGTH (type))
xfer = TYPE_LENGTH (type) - offset;
@@ -5031,25 +5015,12 @@ mips_n32n64_xfer_return_value (struct type *type,
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, in, out, offset);
+ TARGET_BYTE_ORDER, readbuf, writebuf, offset);
}
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
}
-static void
-mips_n32n64_extract_return_value (struct type *type,
- struct regcache *regcache,
- void *valbuf)
-{
- mips_n32n64_xfer_return_value (type, regcache, valbuf, NULL);
-}
-
-static void
-mips_n32n64_store_return_value (struct type *type, char *valbuf)
-{
- mips_n32n64_xfer_return_value (type, current_regcache, NULL, valbuf);
-}
-
static CORE_ADDR
mips_extract_struct_value_address (struct regcache *regcache)
{
@@ -5154,76 +5125,22 @@ set_mipsfpu_auto_command (char *args, int from_tty)
mips_fpu_type_auto = 1;
}
-/* Command to set the processor type. */
-
-void
-mips_set_processor_type_command (char *args, int from_tty)
-{
- int i;
-
- if (tmp_mips_processor_type == NULL || *tmp_mips_processor_type == '\0')
- {
- printf_unfiltered ("The known MIPS processor types are as follows:\n\n");
- for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
- printf_unfiltered ("%s\n", mips_processor_type_table[i].name);
-
- /* Restore the value. */
- tmp_mips_processor_type = xstrdup (mips_processor_type);
-
- return;
- }
-
- if (!mips_set_processor_type (tmp_mips_processor_type))
- {
- error ("Unknown processor type `%s'.", tmp_mips_processor_type);
- /* Restore its value. */
- tmp_mips_processor_type = xstrdup (mips_processor_type);
- }
-}
-
-static void
-mips_show_processor_type_command (char *args, int from_tty)
-{
-}
-
-/* Modify the actual processor type. */
-
-static int
-mips_set_processor_type (char *str)
-{
- int i;
-
- if (str == NULL)
- return 0;
-
- for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
- {
- if (strcasecmp (str, mips_processor_type_table[i].name) == 0)
- {
- mips_processor_type = str;
- mips_processor_reg_names = mips_processor_type_table[i].regnames;
- return 1;
- /* FIXME tweak fpu flag too */
- }
- }
-
- return 0;
-}
-
/* Attempt to identify the particular processor model by reading the
- processor id. */
+ processor id. NOTE: cagney/2003-11-15: Firstly it isn't clear that
+ the relevant processor still exists (it dates back to '94) and
+ secondly this is not the way to do this. The processor type should
+ be set by forcing an architecture change. */
-char *
-mips_read_processor_type (void)
+void
+deprecated_mips_set_processor_regs_hack (void)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
CORE_ADDR prid;
prid = read_register (PRID_REGNUM);
if ((prid & ~0xf) == 0x700)
- return savestring ("r3041", strlen ("r3041"));
-
- return NULL;
+ tdep->mips_processor_reg_names = mips_r3041_reg_names;
}
/* Just like reinit_frame_cache, but with the right arguments to be
@@ -5612,11 +5529,11 @@ mips_stab_reg_to_regnum (int num)
if (num >= 0 && num < 32)
regnum = num;
else if (num >= 38 && num < 70)
- regnum = num + FP0_REGNUM - 38;
+ regnum = num + mips_regnum (current_gdbarch)->fp0 - 38;
else if (num == 70)
- regnum = HI_REGNUM;
+ regnum = mips_regnum (current_gdbarch)->hi;
else if (num == 71)
- regnum = LO_REGNUM;
+ regnum = mips_regnum (current_gdbarch)->lo;
else
/* This will hopefully (eventually) provoke a warning. Should
we be calling complaint() here? */
@@ -5635,11 +5552,11 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
if (num >= 0 && num < 32)
regnum = num;
else if (num >= 32 && num < 64)
- regnum = num + FP0_REGNUM - 32;
+ regnum = num + mips_regnum (current_gdbarch)->fp0 - 32;
else if (num == 64)
- regnum = HI_REGNUM;
+ regnum = mips_regnum (current_gdbarch)->hi;
else if (num == 65)
- regnum = LO_REGNUM;
+ regnum = mips_regnum (current_gdbarch)->lo;
else
/* This will hopefully (eventually) provoke a warning. Should we
be calling complaint() here? */
@@ -5831,6 +5748,11 @@ mips_gdbarch_init (struct gdbarch_info info,
continue;
if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi)
continue;
+ /* Need to be pedantic about which register virtual size is
+ used. */
+ if (gdbarch_tdep (arches->gdbarch)->mips64_transfers_32bit_regs_p
+ != mips64_transfers_32bit_regs_p)
+ continue;
return arches->gdbarch;
}
@@ -5838,6 +5760,7 @@ mips_gdbarch_init (struct gdbarch_info info,
tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
tdep->elf_flags = elf_flags;
+ tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
/* Initially set everything according to the default ABI/ISA. */
set_gdbarch_short_bit (gdbarch, 16);
@@ -5845,8 +5768,6 @@ mips_gdbarch_init (struct gdbarch_info info,
set_gdbarch_float_bit (gdbarch, 32);
set_gdbarch_double_bit (gdbarch, 64);
set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_deprecated_register_raw_size (gdbarch, mips_register_raw_size);
- set_gdbarch_deprecated_register_byte (gdbarch, mips_register_byte);
set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p);
set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
@@ -5856,34 +5777,59 @@ mips_gdbarch_init (struct gdbarch_info info,
set_gdbarch_elf_make_msymbol_special (gdbarch,
mips_elf_make_msymbol_special);
-
- if (info.osabi == GDB_OSABI_IRIX)
- num_regs = 71;
- else
- num_regs = 90;
- set_gdbarch_num_regs (gdbarch, num_regs);
- set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
+ /* Fill in the OS dependant register numbers. */
+ {
+ struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch,
+ struct mips_regnum);
+ tdep->regnum = regnum;
+ if (info.osabi == GDB_OSABI_IRIX)
+ {
+ regnum->fp0 = 32;
+ regnum->pc = 64;
+ regnum->cause = 65;
+ regnum->badvaddr = 66;
+ regnum->hi = 67;
+ regnum->lo = 68;
+ regnum->fp_control_status = 69;
+ regnum->fp_implementation_revision = 70;
+ num_regs = 71;
+ }
+ else
+ {
+ 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 = 90;
+ }
+ /* FIXME: cagney/2003-11-15: For MIPS, hasn't PC_REGNUM been
+ replaced by read_pc? */
+ set_gdbarch_pc_regnum (gdbarch, regnum->pc);
+ set_gdbarch_fp0_regnum (gdbarch, regnum->fp0);
+ set_gdbarch_num_regs (gdbarch, num_regs);
+ set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
+ }
switch (mips_abi)
{
case MIPS_ABI_O32:
set_gdbarch_push_dummy_call (gdbarch, mips_o32_push_dummy_call);
- set_gdbarch_deprecated_store_return_value (gdbarch, mips_o32_store_return_value);
- set_gdbarch_extract_return_value (gdbarch, mips_o32_extract_return_value);
+ set_gdbarch_return_value (gdbarch, mips_o32_return_value);
tdep->mips_default_saved_regsize = 4;
tdep->mips_default_stack_argsize = 4;
tdep->mips_fp_register_double = 0;
tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
- tdep->gdb_target_is_mips64 = 0;
+ tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
set_gdbarch_ptr_bit (gdbarch, 32);
set_gdbarch_long_long_bit (gdbarch, 64);
set_gdbarch_deprecated_reg_struct_has_addr
(gdbarch, mips_o32_reg_struct_has_addr);
- set_gdbarch_use_struct_convention (gdbarch,
- always_use_struct_convention);
break;
case MIPS_ABI_O64:
set_gdbarch_push_dummy_call (gdbarch, mips_o64_push_dummy_call);
@@ -5893,8 +5839,7 @@ mips_gdbarch_init (struct gdbarch_info info,
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
- tdep->gdb_target_is_mips64 = 1;
+ tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
set_gdbarch_ptr_bit (gdbarch, 32);
@@ -5911,8 +5856,7 @@ mips_gdbarch_init (struct gdbarch_info info,
tdep->mips_default_stack_argsize = 4;
tdep->mips_fp_register_double = 0;
tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
- tdep->gdb_target_is_mips64 = 0;
+ tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
set_gdbarch_ptr_bit (gdbarch, 32);
@@ -5930,8 +5874,7 @@ mips_gdbarch_init (struct gdbarch_info info,
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
- tdep->gdb_target_is_mips64 = 1;
+ tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 64);
set_gdbarch_ptr_bit (gdbarch, 64);
@@ -5943,39 +5886,31 @@ mips_gdbarch_init (struct gdbarch_info info,
break;
case MIPS_ABI_N32:
set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
- set_gdbarch_deprecated_store_return_value (gdbarch, mips_n32n64_store_return_value);
- set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
+ set_gdbarch_return_value (gdbarch, mips_n32n64_return_value);
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
- tdep->gdb_target_is_mips64 = 1;
+ tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 32);
set_gdbarch_ptr_bit (gdbarch, 32);
set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_use_struct_convention (gdbarch,
- mips_n32n64_use_struct_convention);
set_gdbarch_deprecated_reg_struct_has_addr
(gdbarch, mips_n32n64_reg_struct_has_addr);
break;
case MIPS_ABI_N64:
set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
- set_gdbarch_deprecated_store_return_value (gdbarch, mips_n32n64_store_return_value);
- set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
+ set_gdbarch_return_value (gdbarch, mips_n32n64_return_value);
tdep->mips_default_saved_regsize = 8;
tdep->mips_default_stack_argsize = 8;
tdep->mips_fp_register_double = 1;
tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
- tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
- tdep->gdb_target_is_mips64 = 1;
+ tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
tdep->default_mask_address_p = 0;
set_gdbarch_long_bit (gdbarch, 64);
set_gdbarch_ptr_bit (gdbarch, 64);
set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_use_struct_convention (gdbarch,
- mips_n32n64_use_struct_convention);
set_gdbarch_deprecated_reg_struct_has_addr
(gdbarch, mips_n32n64_reg_struct_has_addr);
break;
@@ -6027,11 +5962,14 @@ mips_gdbarch_init (struct gdbarch_info info,
else
tdep->mips_fpu_type = MIPS_FPU_DOUBLE;
- /* MIPS version of register names. NOTE: At present the MIPS
- register name management is part way between the old -
- #undef/#define MIPS_REGISTER_NAMES and the new REGISTER_NAME(nr).
- Further work on it is required. */
+ /* MIPS version of register names. */
set_gdbarch_register_name (gdbarch, mips_register_name);
+ if (info.osabi == GDB_OSABI_IRIX)
+ tdep->mips_processor_reg_names = mips_irix_reg_names;
+ else if (info.bfd_arch_info != NULL && info.bfd_arch_info->mach == bfd_mach_mips3900)
+ tdep->mips_processor_reg_names = mips_tx39_reg_names;
+ else
+ tdep->mips_processor_reg_names = mips_generic_reg_names;
set_gdbarch_read_pc (gdbarch, mips_read_pc);
set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
set_gdbarch_deprecated_target_read_fp (gdbarch, mips_read_sp); /* Draft FRAME base. */
@@ -6065,9 +6003,6 @@ mips_gdbarch_init (struct gdbarch_info info,
set_gdbarch_deprecated_pop_frame (gdbarch, mips_pop_frame);
set_gdbarch_frame_align (gdbarch, mips_frame_align);
set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
- set_gdbarch_deprecated_register_convertible (gdbarch, mips_register_convertible);
- set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, mips_register_convert_to_virtual);
- set_gdbarch_deprecated_register_convert_to_raw (gdbarch, mips_register_convert_to_raw);
set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
set_gdbarch_frameless_function_invocation (gdbarch,
@@ -6224,10 +6159,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
"mips_dump_tdep: MIPS_EABI = %d\n",
MIPS_EABI);
fprintf_unfiltered (file,
- "mips_dump_tdep: MIPS_LAST_FP_ARG_REGNUM = %d (%d regs)\n",
- MIPS_LAST_FP_ARG_REGNUM,
- MIPS_LAST_FP_ARG_REGNUM - FPA0_REGNUM + 1);
- fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
MIPS_FPU_TYPE,
(MIPS_FPU_TYPE == MIPS_FPU_NONE ? "none"
@@ -6247,9 +6178,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
"mips_dump_tdep: MIPS_STACK_ARGSIZE = %d\n",
MIPS_STACK_ARGSIZE);
fprintf_unfiltered (file,
- "mips_dump_tdep: MIPS_REGSIZE = %d\n",
- MIPS_REGSIZE);
- fprintf_unfiltered (file,
"mips_dump_tdep: A0_REGNUM = %d\n",
A0_REGNUM);
fprintf_unfiltered (file,
@@ -6259,36 +6187,15 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
"mips_dump_tdep: ATTACH_DETACH # %s\n",
XSTRING (ATTACH_DETACH));
fprintf_unfiltered (file,
- "mips_dump_tdep: BADVADDR_REGNUM = %d\n",
- BADVADDR_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: CAUSE_REGNUM = %d\n",
- CAUSE_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n",
XSTRING (DWARF_REG_TO_REGNUM (REGNUM)));
fprintf_unfiltered (file,
"mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n",
XSTRING (ECOFF_REG_TO_REGNUM (REGNUM)));
fprintf_unfiltered (file,
- "mips_dump_tdep: FCRCS_REGNUM = %d\n",
- FCRCS_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: FCRIR_REGNUM = %d\n",
- FCRIR_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n",
FIRST_EMBED_REGNUM);
fprintf_unfiltered (file,
- "mips_dump_tdep: FPA0_REGNUM = %d\n",
- FPA0_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n",
- GDB_TARGET_IS_MIPS64);
- fprintf_unfiltered (file,
- "mips_dump_tdep: HI_REGNUM = %d\n",
- HI_REGNUM);
- fprintf_unfiltered (file,
"mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
XSTRING (IGNORE_HELPER_CALL (PC)));
fprintf_unfiltered (file,
@@ -6300,9 +6207,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"mips_dump_tdep: LAST_EMBED_REGNUM = %d\n",
LAST_EMBED_REGNUM);
- fprintf_unfiltered (file,
- "mips_dump_tdep: LO_REGNUM = %d\n",
- LO_REGNUM);
#ifdef MACHINE_CPROC_FP_OFFSET
fprintf_unfiltered (file,
"mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n",
@@ -6336,15 +6240,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
"mips_dump_tdep: MIPS_NUMREGS = %d\n",
MIPS_NUMREGS);
fprintf_unfiltered (file,
- "mips_dump_tdep: MIPS_REGISTER_NAMES = delete?\n");
- fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_SAVED_REGSIZE = %d\n",
MIPS_SAVED_REGSIZE);
fprintf_unfiltered (file,
- "mips_dump_tdep: OP_LDFPR = used?\n");
- fprintf_unfiltered (file,
- "mips_dump_tdep: OP_LDGPR = used?\n");
- fprintf_unfiltered (file,
"mips_dump_tdep: PRID_REGNUM = %d\n",
PRID_REGNUM);
fprintf_unfiltered (file,
@@ -6410,9 +6308,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
"mips_dump_tdep: SIGFRAME_REGSAVE_OFF = %d\n",
SIGFRAME_REGSAVE_OFF);
fprintf_unfiltered (file,
- "mips_dump_tdep: SIGFRAME_REG_SIZE = %d\n",
- SIGFRAME_REG_SIZE);
- fprintf_unfiltered (file,
"mips_dump_tdep: SKIP_TRAMPOLINE_CODE # %s\n",
XSTRING (SKIP_TRAMPOLINE_CODE (PC)));
fprintf_unfiltered (file,
@@ -6614,16 +6509,18 @@ Show zeroing of upper 32 bits of 64-bit addresses.",
/* Allow the user to control the size of 32 bit registers within the
raw remote packet. */
- add_show_from_set (add_set_cmd ("remote-mips64-transfers-32bit-regs",
- class_obscure,
- var_boolean,
- (char *)&mips64_transfers_32bit_regs_p, "\
-Set compatibility with MIPS targets that transfers 32 and 64 bit quantities.\n\
+ add_setshow_cmd ("remote-mips64-transfers-32bit-regs", class_obscure,
+ var_boolean, &mips64_transfers_32bit_regs_p, "\
+Set compatibility with 64-bit MIPS targets that transfer 32-bit quantities.\n\
+Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
+that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
+64 bits for others. Use \"off\" to disable compatibility mode", "\
+Show compatibility with 64-bit MIPS targets that transfer 32-bit quantities.\n\
Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
64 bits for others. Use \"off\" to disable compatibility mode",
- &setlist),
- &showlist);
+ set_mips64_transfers_32bit_regs, NULL,
+ &setlist, &showlist);
/* Debug this files internals. */
add_show_from_set (add_set_cmd ("mips", class_maintenance, var_zinteger,