/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
#include "elf-bfd.h"
#include "symcat.h"
+/* A useful bit in the CP0 status register (PS_REGNUM). */
+/* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */
+#define ST0_FR (1 << 26)
+
/* The sizes of floating point registers. */
enum
return 4;
}
+/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
+ compatiblity mode. A return value of 1 means that we have
+ physical 64-bit registers, but should treat them as 32-bit registers. */
+
+static int
+mips2_fp_compat (void)
+{
+ /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
+ meaningful. */
+ if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
+ return 0;
+
+#if 0
+ /* FIXME drow 2002-03-10: This is disabled until we can do it consistently,
+ in all the places we deal with FP registers. PR gdb/413. */
+ /* 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 (PS_REGNUM) & ST0_FR) == 0)
+ return 1;
+#endif
+
+ return 0;
+}
+
/* 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
static void mips_print_register (int, int);
static mips_extra_func_info_t
-heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *);
+heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *, int);
static CORE_ADDR heuristic_proc_start (CORE_ADDR);
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
static mips_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame);
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame);
static CORE_ADDR after_prologue (CORE_ADDR pc,
mips_extra_func_info_t proc_desc);
+static void mips_read_fp_register_single (int regno, char *rare_buffer);
+static void mips_read_fp_register_double (int regno, char *rare_buffer);
+
+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. */
paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
}
-/* Convert between RAW and VIRTUAL registers. The RAW register size
- defines the remote-gdb packet. */
+/* 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. */
static int mips64_transfers_32bit_regs_p = 0;
return MIPS_REGSIZE;
}
+/* Convert between RAW and VIRTUAL registers. The RAW register size
+ defines the remote-gdb packet. */
+
int
mips_register_convertible (int reg_nr)
{
mips_register_convert_to_virtual (int n, struct type *virtual_type,
char *raw_buf, char *virt_buf)
{
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
memcpy (virt_buf,
raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
TYPE_LENGTH (virtual_type));
char *virt_buf, char *raw_buf)
{
memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
virt_buf,
TYPE_LENGTH (virtual_type));
internal_error (__FILE__, __LINE__,
"mips_mask_address_p: bad switch");
return -1;
- }
+ }
}
static void
internal_error (__FILE__, __LINE__,
"show_mask_address: bad switch");
break;
- }
+ }
}
/* Should call_function allocate stack space for a struct return? */
struct symtab_and_line sal;
CORE_ADDR func_addr, func_end;
+ /* Pass cur_frame == 0 to find_proc_desc. We should not attempt
+ to read the stack pointer from the current machine state, because
+ the current machine state has nothing to do with the information
+ we need from the proc_desc; and the process may or may not exist
+ right now. */
if (!proc_desc)
- proc_desc = find_proc_desc (pc, NULL);
+ proc_desc = find_proc_desc (pc, NULL, 0);
if (proc_desc)
{
/* mips_software_single_step() is called just before we want to resume
the inferior, if we want to single-step it but there is no hardware
- or kernel single-step support (MIPS on Linux for example). We find
+ or kernel single-step support (MIPS on GNU/Linux for example). We find
the target of the coming instruction and breakpoint it.
single_step is also called just after the inferior stops. If we had
static mips_extra_func_info_t
heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
- struct frame_info *next_frame)
+ struct frame_info *next_frame, int cur_frame)
{
- CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ CORE_ADDR sp;
+
+ if (cur_frame)
+ sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ else
+ sp = 0;
if (start_pc == 0)
return NULL;
static mips_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame)
{
mips_extra_func_info_t proc_desc;
CORE_ADDR startaddr;
{
mips_extra_func_info_t found_heuristic =
heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
- pc, next_frame);
+ pc, next_frame, cur_frame);
if (found_heuristic)
proc_desc = found_heuristic;
}
startaddr = heuristic_proc_start (pc);
proc_desc =
- heuristic_proc_desc (startaddr, pc, next_frame);
+ heuristic_proc_desc (startaddr, pc, next_frame, cur_frame);
}
return proc_desc;
}
saved_pc = tmp;
/* Look up the procedure descriptor for this PC. */
- proc_desc = find_proc_desc (saved_pc, frame);
+ proc_desc = find_proc_desc (saved_pc, frame, 1);
if (!proc_desc)
return 0;
/* Use proc_desc calculated in frame_chain */
mips_extra_func_info_t proc_desc =
- fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next);
+ fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next, 1);
fci->extra_info = (struct frame_extra_info *)
frame_obstack_alloc (sizeof (struct frame_extra_info));
We can't use fci->signal_handler_caller, it is not yet set. */
find_pc_partial_function (fci->pc, &name,
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (!IN_SIGTRAMP (fci->pc, name))
+ if (!PC_IN_SIGTRAMP (fci->pc, name))
{
frame_saved_regs_zalloc (fci);
memcpy (fci->saved_regs, temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
we basically have to look at symbol information for the function
that we stopped in, which tells us *which* register (if any) is
the base of the frame pointer, and what offset from that register
- the frame itself is at.
+ the frame itself is at.
This presents a problem when trying to examine a stack in memory
(that isn't executing at the moment), using the "frame" command. We
mips_type_needs_double_align (struct type *type)
{
enum type_code typecode = TYPE_CODE (type);
-
+
if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
return 1;
else if (typecode == TYPE_CODE_STRUCT)
}
else if (typecode == TYPE_CODE_UNION)
{
- int i, n;
+ int i, n;
n = TYPE_NFIELDS (type);
for (i = 0; i < n; i++)
{
if (!FP_REGISTER_DOUBLE && len == 8)
{
- int low_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0;
+ int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
unsigned long regval;
/* Write the low word of the double to the even register(s). */
int longword_offset = 0;
CORE_ADDR addr;
stack_used_p = 1;
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
if (MIPS_STACK_ARGSIZE == 8 &&
(typecode == TYPE_CODE_INT ||
fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%lx",
(long) longword_offset);
}
-
+
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
LONGEST regval = extract_unsigned_integer (val, partial_len);
- /* A non-floating-point argument being passed in a
+ /* A non-floating-point argument being passed in a
general register. If a struct or union, and if
the remaining length is smaller than the register
size, we have to adjust the register value on
same for integral types.
Also don't do this adjustment on EABI and O64
- binaries. */
+ binaries.
+
+ cagney/2001-07-23: gdb/179: Also, GCC, when
+ outputting LE O32 with sizeof (struct) <
+ MIPS_SAVED_REGSIZE, generates a left shift as
+ part of storing the argument in a register a
+ register (the left shift isn't generated when
+ sizeof (struct) >= MIPS_SAVED_REGSIZE). Since it
+ is quite possible that this is GCC contradicting
+ the LE/O32 ABI, GDB has not been adjusted to
+ accommodate this. Either someone needs to
+ demonstrate that the LE/O32 ABI specifies such a
+ left shift OR this new ABI gets identified as
+ such and GDB gets tweaked accordingly. */
if (!MIPS_EABI
&& MIPS_SAVED_REGSIZE < 8
- && TARGET_BYTE_ORDER == BIG_ENDIAN
+ && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& partial_len < MIPS_SAVED_REGSIZE
&& (typecode == TYPE_CODE_STRUCT ||
typecode == TYPE_CODE_UNION))
if (MIPS_SAVED_REGSIZE < REGISTER_RAW_SIZE (regno))
{
regsize = MIPS_SAVED_REGSIZE;
- offset = (TARGET_BYTE_ORDER == BIG_ENDIAN
+ offset = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
? REGISTER_RAW_SIZE (regno) - MIPS_SAVED_REGSIZE
: 0);
}
* procedure calls. Dest_Reg (see tm-mips.h) must also be saved.
* In addition, we must save the PC, PUSH_FP_REGNUM, MMLO/-HI
* and FP Control/Status registers.
- *
+ *
*
* Dummy frame layout:
* (high memory)
}
}
+/* Floating point register management.
+
+ Background: MIPS1 & 2 fp registers are 32 bits wide. To support
+ 64bit operations, these early MIPS cpus treat fp register pairs
+ (f0,f1) as a single register (d0). Later MIPS cpu's have 64 bit fp
+ registers and offer a compatibility mode that emulates the MIPS2 fp
+ model. When operating in MIPS2 fp compat mode, later cpu's split
+ double precision floats into two 32-bit chunks and store them in
+ consecutive fp regs. To display 64-bit floats stored in this
+ fashion, we have to combine 32 bits from f0 and 32 bits from f1.
+ Throw in user-configurable endianness and you have a real mess.
+
+ The way this works is:
+ - If we are in 32-bit mode or on a 32-bit processor, then a 64-bit
+ double-precision value will be split across two logical registers.
+ The lower-numbered logical register will hold the low-order bits,
+ regardless of the processor's endianness.
+ - If we are on a 64-bit processor, and we are looking for a
+ single-precision value, it will be in the low ordered bits
+ of a 64-bit GPR (after mfc1, for example) or a 64-bit register
+ save slot in memory.
+ - If we are in 64-bit mode, everything is straightforward.
+
+ Note that this code only deals with "live" registers at the top of the
+ stack. We will attempt to deal with saved registers later, when
+ the raw/cooked register interface is in place. (We need a general
+ interface that can deal with dynamic saved register sizes -- fp
+ regs could be 32 bits wide in one frame and 64 on the frame above
+ and below). */
+
+static struct type *
+mips_float_register_type (void)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return builtin_type_ieee_single_big;
+ else
+ return builtin_type_ieee_single_little;
+}
+
+static struct type *
+mips_double_register_type (void)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return builtin_type_ieee_double_big;
+ else
+ return builtin_type_ieee_double_little;
+}
+
+/* Copy a 32-bit single-precision value from the current frame
+ into rare_buffer. */
+
+static void
+mips_read_fp_register_single (int regno, char *rare_buffer)
+{
+ int raw_size = REGISTER_RAW_SIZE (regno);
+ char *raw_buffer = alloca (raw_size);
+
+ if (!frame_register_read (selected_frame, regno, raw_buffer))
+ error ("can't read register %d (%s)", regno, REGISTER_NAME (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)
+ offset = 4;
+ else
+ offset = 0;
+
+ memcpy (rare_buffer, raw_buffer + offset, 4);
+ }
+ else
+ {
+ memcpy (rare_buffer, raw_buffer, 4);
+ }
+}
+
+/* Copy a 64-bit double-precision value from the current frame into
+ rare_buffer. This may include getting half of it from the next
+ register. */
+
+static void
+mips_read_fp_register_double (int regno, char *rare_buffer)
+{
+ int raw_size = REGISTER_RAW_SIZE (regno);
+
+ if (raw_size == 8 && !mips2_fp_compat ())
+ {
+ /* We have a 64-bit value for this register, and we should use
+ all 64 bits. */
+ if (!frame_register_read (selected_frame, regno, rare_buffer))
+ error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+ }
+ else
+ {
+ if ((regno - FP0_REGNUM) & 1)
+ internal_error (__FILE__, __LINE__,
+ "mips_read_fp_register_double: bad access to "
+ "odd-numbered FP register");
+
+ /* mips_read_fp_register_single will find the correct 32 bits from
+ each register. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ mips_read_fp_register_single (regno, rare_buffer + 4);
+ mips_read_fp_register_single (regno + 1, rare_buffer);
+ }
+ else
+ {
+ mips_read_fp_register_single (regno, rare_buffer);
+ mips_read_fp_register_single (regno + 1, rare_buffer + 4);
+ }
+ }
+}
+
static void
mips_print_register (int regnum, int all)
{
char raw_buffer[MAX_REGISTER_RAW_SIZE];
/* Get the data in raw format. */
- if (read_relative_register_raw_bytes (regnum, raw_buffer))
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
{
printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
return;
}
- /* If an even floating point register, also print as double. */
+ /* If we have a actual 32-bit floating point register (or we are in
+ 32-bit compatibility mode), and the register is even-numbered,
+ also print it as a double (spanning two registers). */
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
+ && (REGISTER_RAW_SIZE (regnum) == 4
+ || mips2_fp_compat ())
&& !((regnum - FP0_REGNUM) & 1))
- if (REGISTER_RAW_SIZE (regnum) == 4) /* this would be silly on MIPS64 or N32 (Irix 6) */
- {
- char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
+ {
+ char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
- read_relative_register_raw_bytes (regnum, dbuffer);
- read_relative_register_raw_bytes (regnum + 1, dbuffer + MIPS_REGSIZE);
- REGISTER_CONVERT_TO_TYPE (regnum, builtin_type_double, dbuffer);
+ mips_read_fp_register_double (regnum, dbuffer);
- printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
- val_print (builtin_type_double, dbuffer, 0, 0,
- gdb_stdout, 0, 1, 0, Val_pretty_default);
- printf_filtered ("); ");
- }
+ printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
+ val_print (mips_double_register_type (), dbuffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ printf_filtered ("); ");
+ }
fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
/* The problem with printing numeric register names (r26, etc.) is that
/* If virtual format is floating, print it that way. */
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
- if (FP_REGISTER_DOUBLE)
- { /* show 8-byte floats as float AND double: */
- int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);
+ if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ())
+ {
+ /* We have a meaningful 64-bit value in this register. Show
+ it as a 32-bit float and a 64-bit double. */
+ int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
printf_filtered (" (float) ");
- val_print (builtin_type_float, raw_buffer + offset, 0, 0,
+ val_print (mips_float_register_type (), raw_buffer + offset, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
printf_filtered (", (double) ");
- val_print (builtin_type_double, raw_buffer, 0, 0,
+ val_print (mips_double_register_type (), raw_buffer, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
}
else
{
int offset;
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
else
offset = 0;
-
+
print_scalar_formatted (raw_buffer + offset,
REGISTER_VIRTUAL_TYPE (regnum),
'x', 0, gdb_stdout);
}
}
-/* Replacement for generic do_registers_info.
+/* Replacement for generic do_registers_info.
Print regs in pretty columns. */
static int
do_fp_register_row (int regnum)
{ /* do values for FP (float) regs */
- char *raw_buffer[2];
- char *dbl_buffer;
- /* use HI and LO to control the order of combining two flt regs */
- int HI = (TARGET_BYTE_ORDER == BIG_ENDIAN);
- int LO = (TARGET_BYTE_ORDER != BIG_ENDIAN);
+ char *raw_buffer;
double doub, flt1, flt2; /* doubles extracted from raw hex data */
int inv1, inv2, inv3;
- raw_buffer[0] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
- raw_buffer[1] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
- dbl_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
+ raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
- /* Get the data in raw format. */
- if (read_relative_register_raw_bytes (regnum, raw_buffer[HI]))
- error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
- if (REGISTER_RAW_SIZE (regnum) == 4)
+ if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
{
- /* 4-byte registers: we can fit two registers per row. */
- /* Also print every pair of 4-byte regs as an 8-byte double. */
- if (read_relative_register_raw_bytes (regnum + 1, raw_buffer[LO]))
- error ("can't read register %d (%s)",
- regnum + 1, REGISTER_NAME (regnum + 1));
-
- /* copy the two floats into one double, and unpack both */
- memcpy (dbl_buffer, raw_buffer, 2 * REGISTER_RAW_SIZE (FP0_REGNUM));
- flt1 = unpack_double (builtin_type_float, raw_buffer[HI], &inv1);
- flt2 = unpack_double (builtin_type_float, raw_buffer[LO], &inv2);
- doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
+ /* 4-byte registers: we can fit two registers per row. */
+ /* Also print every pair of 4-byte regs as an 8-byte double. */
+ mips_read_fp_register_single (regnum, raw_buffer);
+ flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
+
+ mips_read_fp_register_single (regnum + 1, raw_buffer);
+ flt2 = unpack_double (mips_float_register_type (), raw_buffer, &inv2);
+
+ mips_read_fp_register_double (regnum, raw_buffer);
+ doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
printf_filtered (" %-5s", REGISTER_NAME (regnum));
if (inv1)
regnum += 2;
}
else
- { /* eight byte registers: print each one as float AND as double. */
- int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);
+ {
+ /* Eight byte registers: print each one as float AND as double. */
+ mips_read_fp_register_single (regnum, raw_buffer);
+ flt1 = unpack_double (mips_double_register_type (), raw_buffer, &inv1);
- memcpy (dbl_buffer, raw_buffer[HI], 2 * REGISTER_RAW_SIZE (FP0_REGNUM));
- flt1 = unpack_double (builtin_type_float,
- &raw_buffer[HI][offset], &inv1);
- doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
+ mips_read_fp_register_double (regnum, raw_buffer);
+ doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
if (inv1)
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
break; /* end row: reached FP register */
/* OK: get the data in raw format. */
- if (read_relative_register_raw_bytes (regnum, raw_buffer))
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
/* pad small registers */
for (byte = 0; byte < (MIPS_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
printf_filtered (" ");
/* Now print the register value in hex, endian order. */
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
byte < REGISTER_RAW_SIZE (regnum);
byte++)
{
/* We need to break a 64bit float in two 32 bit halves and
spread them across a floating-point register pair. */
- lo->buf_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0;
- hi->buf_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 0 : 4;
- lo->reg_offset = ((TARGET_BYTE_ORDER == BIG_ENDIAN
+ 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
&& REGISTER_RAW_SIZE (FP0_REGNUM) == 8)
? 4 : 0);
hi->reg_offset = lo->reg_offset;
{
/* The floating point value fits in a single floating-point
register. */
- lo->reg_offset = ((TARGET_BYTE_ORDER == BIG_ENDIAN
+ lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& REGISTER_RAW_SIZE (FP0_REGNUM) == 8
&& len == 4)
? 4 : 0);
int regnum = 2;
lo->reg = regnum + 0;
hi->reg = regnum + 1;
- if (TARGET_BYTE_ORDER == BIG_ENDIAN
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& len < MIPS_SAVED_REGSIZE)
{
/* "un-left-justify" the value in the low register */
hi->reg_offset = 0;
hi->len = 0;
}
- else if (TARGET_BYTE_ORDER == BIG_ENDIAN
+ else if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& len > MIPS_SAVED_REGSIZE /* odd-size structs */
&& len < MIPS_SAVED_REGSIZE * 2
&& (TYPE_CODE (valtype) == TYPE_CODE_STRUCT ||
hi->len = 0;
}
}
- if (TARGET_BYTE_ORDER == BIG_ENDIAN
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& REGISTER_RAW_SIZE (regnum) == 8
&& MIPS_SAVED_REGSIZE == 4)
{
it's definitely a 16-bit function. Otherwise, we have to just
guess that if the address passed in is odd, it's 16-bits. */
if (proc_desc)
- info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ?
+ info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ?
bfd_mach_mips16 : TM_PRINT_INSN_MACH;
else
- info->mach = pc_is_mips16 (memaddr) ?
+ info->mach = pc_is_mips16 (memaddr) ?
bfd_mach_mips16 : TM_PRINT_INSN_MACH;
/* Round down the instruction address to the appropriate boundary. */
memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3);
/* Call the appropriate disassembler based on the target endian-ness. */
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
return print_insn_big_mips (memaddr, info);
else
return print_insn_little_mips (memaddr, info);
(if necessary) to point to the actual memory location where the
breakpoint should be inserted. */
-unsigned char *
+const unsigned char *
mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
{
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
if (pc_is_mips16 (*pcptr))
{
{
if (num < 32)
return num;
- else
+ else
return num + FP0_REGNUM - 38;
}
return num + FP0_REGNUM - 32;
}
+/* Convert an integer into an address. By first converting the value
+ into a pointer and then extracting it signed, the address is
+ guarenteed to be correctly sign extended. */
+
+static CORE_ADDR
+mips_integer_to_address (struct type *type, void *buf)
+{
+ char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
+ LONGEST val = unpack_long (type, buf);
+ store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
+ return extract_signed_integer (tmp,
+ TYPE_LENGTH (builtin_type_void_data_ptr));
+}
+
static struct gdbarch *
mips_gdbarch_init (struct gdbarch_info info,
struct gdbarch_list *arches)
gdbarch = gdbarch_alloc (&info, tdep);
tdep->elf_flags = elf_flags;
- /* Initially set everything according to the ABI. */
+ /* Initially set everything according to the default ABI/ISA. */
set_gdbarch_short_bit (gdbarch, 16);
set_gdbarch_int_bit (gdbarch, 32);
set_gdbarch_float_bit (gdbarch, 32);
set_gdbarch_double_bit (gdbarch, 64);
set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size);
tdep->mips_abi = mips_abi;
switch (mips_abi)
tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
tdep->mips_regs_have_home_p = 1;
tdep->gdb_target_is_mips64 = 1;
- tdep->default_mask_address_p = 0;
+ 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);
flag in object files because to do so would make it impossible to
link with libraries compiled without "-gp32". This is
unnecessarily restrictive.
-
+
We could solve this problem by adding "-gp32" multilibs to gcc,
but to set this flag before gcc is built with such multilibs will
break too many systems.''
set_gdbarch_read_pc (gdbarch, mips_read_pc);
set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
- set_gdbarch_write_fp (gdbarch, generic_target_write_fp);
set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc);
set_gdbarch_decr_pc_after_break (gdbarch, 0);
- set_gdbarch_ieee_float (gdbarch, 1);
set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
set_gdbarch_saved_pc_after_call (gdbarch, mips_saved_pc_after_call);
+ set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
+ set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
+ set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
return gdbarch;
}
fprintf_unfiltered (file,
"mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
XSTRING (IGNORE_HELPER_CALL (PC)));
- fprintf_unfiltered (file,
- "mips_dump_tdep: IN_SIGTRAMP # %s\n",
- XSTRING (IN_SIGTRAMP (PC, NAME)));
fprintf_unfiltered (file,
"mips_dump_tdep: IN_SOLIB_CALL_TRAMPOLINE # %s\n",
XSTRING (IN_SOLIB_CALL_TRAMPOLINE (PC, NAME)));
Set this to be able to access processor-type-specific registers.\n\
",
&setlist);
- c->function.cfunc = mips_set_processor_type_command;
+ set_cmd_cfunc (c, mips_set_processor_type_command);
c = add_show_from_set (c, &showlist);
- c->function.cfunc = mips_show_processor_type_command;
+ set_cmd_cfunc (c, mips_show_processor_type_command);
tmp_mips_processor_type = xstrdup (DEFAULT_MIPS_TYPE);
mips_set_processor_type_command (xstrdup (DEFAULT_MIPS_TYPE), 0);
&setlist);
/* We need to throw away the frame cache when we set this, since it
might change our ability to get backtraces. */
- c->function.sfunc = reinit_frame_cache_sfunc;
+ set_cmd_sfunc (c, reinit_frame_cache_sfunc);
add_show_from_set (c, &showlist);
/* Allow the user to control whether the upper bits of 64-bit
When non-zero, mips specific debugging is enabled.", &setdebuglist),
&showdebuglist);
}
-