#include "frame-base.h"
#include "trad-frame.h"
#include "infcall.h"
-#include "floatformat.h"
#include "remote.h"
#include "target-descriptions.h"
#include "dwarf2-frame.h"
#include "user-regs.h"
#include "valprint.h"
#include "ax.h"
+#include "target-float.h"
#include <algorithm>
static const struct objfile_data *mips_pdr_data;
/ gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
}
+/* Max saved register size. */
+#define MAX_MIPS_ABI_REGSIZE 8
+
/* Return the currently configured (or set) saved register size. */
unsigned int
static CORE_ADDR heuristic_proc_start (struct gdbarch *, CORE_ADDR);
-static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
-
/* The list of available "set mips " and "show mips " commands. */
static struct cmd_list_element *setmipscmdlist = NULL;
static int mips64_transfers_32bit_regs_p = 0;
static void
-set_mips64_transfers_32bit_regs (char *args, int from_tty,
+set_mips64_transfers_32bit_regs (const char *args, int from_tty,
struct cmd_list_element *c)
{
struct gdbarch_info info;
static CORE_ADDR
mips_read_pc (struct regcache *regcache)
{
- int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
+ int regnum = gdbarch_pc_regnum (regcache->arch ());
LONGEST pc;
regcache_cooked_read_signed (regcache, regnum, &pc);
void
mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
- int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
+ int regnum = gdbarch_pc_regnum (regcache->arch ());
regcache_cooked_write_unsigned (regcache, regnum, pc);
}
static CORE_ADDR
mips32_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
unsigned long inst;
int op;
inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
static CORE_ADDR
micromips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
ULONGEST insn;
insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
extended_mips16_next_pc (regcache *regcache, CORE_ADDR pc,
unsigned int extension, unsigned int insn)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
int op = (insn >> 11);
switch (op)
{
static CORE_ADDR
mips16_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
unsigned int insn = fetch_mips_16 (gdbarch, pc);
return extended_mips16_next_pc (regcache, pc, 0, insn);
}
static CORE_ADDR
mips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
if (mips_pc_is_mips16 (gdbarch, pc))
return mips16_next_pc (regcache, pc);
std::vector<CORE_ADDR>
mips_software_single_step (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
CORE_ADDR pc, next_pc;
pc = regcache_read_pc (regcache);
int stack_offset = 0;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
- int regsize = mips_abi_regsize (gdbarch);
+ int abi_regsize = mips_abi_regsize (gdbarch);
/* For shared libraries, "t9" needs to point at the function
address. */
than necessary for EABI, because the first few arguments are
passed in registers, but that's OK. */
for (argnum = 0; argnum < nargs; argnum++)
- len += align_up (TYPE_LENGTH (value_type (args[argnum])), regsize);
+ len += align_up (TYPE_LENGTH (value_type (args[argnum])), abi_regsize);
sp -= align_up (len, 16);
if (mips_debug)
for (argnum = 0; argnum < nargs; argnum++)
{
const gdb_byte *val;
- gdb_byte valbuf[MAX_REGISTER_SIZE];
+ /* This holds the address of structures that are passed by
+ reference. */
+ gdb_byte ref_valbuf[MAX_MIPS_ABI_REGSIZE];
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
/* The EABI passes structures that do not fit in a register by
reference. */
- if (len > regsize
+ if (len > abi_regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
- store_unsigned_integer (valbuf, regsize, byte_order,
+ gdb_assert (abi_regsize <= ARRAY_SIZE (ref_valbuf));
+ store_unsigned_integer (ref_valbuf, abi_regsize, byte_order,
value_address (arg));
typecode = TYPE_CODE_PTR;
- len = regsize;
- val = valbuf;
+ len = abi_regsize;
+ val = ref_valbuf;
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " push");
}
up before the check to see if there are any FP registers
left. Non MIPS_EABI targets also pass the FP in the integer
registers so also round up normal registers. */
- if (regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
+ if (abi_regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
{
if ((float_argreg & 1))
float_argreg++;
/* Copy the argument to general registers or the stack in
register-sized pieces. Large arguments are split between
registers and stack. */
- /* Note: structs whose size is not a multiple of regsize
+ /* Note: structs whose size is not a multiple of abi_regsize
are treated specially: Irix cc passes
them in registers where gcc sometimes puts them on the
stack. For maximum compatibility, we will put them in
both places. */
- int odd_sized_struct = (len > regsize && len % regsize != 0);
+ int odd_sized_struct = (len > abi_regsize && len % abi_regsize != 0);
/* Note: Floating-point values that didn't fit into an FP
register are only written to memory. */
{
/* Remember if the argument was written to the stack. */
int stack_used_p = 0;
- int partial_len = (len < regsize ? len : regsize);
+ int partial_len = (len < abi_regsize ? len : abi_regsize);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
stack_used_p = 1;
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- if (regsize == 8
+ if (abi_regsize == 8
&& (typecode == TYPE_CODE_INT
|| typecode == TYPE_CODE_PTR
|| typecode == TYPE_CODE_FLT) && len <= 4)
- longword_offset = regsize - len;
+ longword_offset = abi_regsize - len;
else if ((typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION)
- && TYPE_LENGTH (arg_type) < regsize)
- longword_offset = regsize - len;
+ && TYPE_LENGTH (arg_type) < abi_regsize)
+ longword_offset = abi_regsize - len;
}
if (mips_debug)
if (mips_debug)
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
- phex (regval, regsize));
+ phex (regval, abi_regsize));
regcache_cooked_write_signed (regcache, argreg, regval);
argreg++;
}
only needs to be adjusted when it has been used. */
if (stack_used_p)
- stack_offset += align_up (partial_len, regsize);
+ stack_offset += align_up (partial_len, abi_regsize);
}
}
if (mips_debug)
{ /* Do values for FP (float) regs. */
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte *raw_buffer;
- double doub, flt1; /* Doubles extracted from raw hex data. */
- int inv1, inv2;
+ std::string flt_str, dbl_str;
+
+ const struct type *flt_type = builtin_type (gdbarch)->builtin_float;
+ const struct type *dbl_type = builtin_type (gdbarch)->builtin_double;
raw_buffer
= ((gdb_byte *)
/* 4-byte registers: Print hex and floating. Also print even
numbered registers as doubles. */
mips_read_fp_register_single (frame, regnum, raw_buffer);
- flt1 = unpack_double (builtin_type (gdbarch)->builtin_float,
- raw_buffer, &inv1);
+ flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g");
get_formatted_print_options (&opts, 'x');
print_scalar_formatted (raw_buffer,
builtin_type (gdbarch)->builtin_uint32,
&opts, 'w', file);
- fprintf_filtered (file, " flt: ");
- if (inv1)
- fprintf_filtered (file, " <invalid float> ");
- else
- fprintf_filtered (file, "%-17.9g", flt1);
+ fprintf_filtered (file, " flt: %s", flt_str.c_str ());
if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0)
{
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (builtin_type (gdbarch)->builtin_double,
- raw_buffer, &inv2);
+ dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g");
- fprintf_filtered (file, " dbl: ");
- if (inv2)
- fprintf_filtered (file, "<invalid double>");
- else
- fprintf_filtered (file, "%-24.17g", doub);
+ fprintf_filtered (file, " dbl: %s", dbl_str.c_str ());
}
}
else
/* Eight byte registers: print each one as hex, float and double. */
mips_read_fp_register_single (frame, regnum, raw_buffer);
- flt1 = unpack_double (builtin_type (gdbarch)->builtin_float,
- raw_buffer, &inv1);
+ flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g");
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (builtin_type (gdbarch)->builtin_double,
- raw_buffer, &inv2);
+ dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g");
get_formatted_print_options (&opts, 'x');
print_scalar_formatted (raw_buffer,
builtin_type (gdbarch)->builtin_uint64,
&opts, 'g', file);
- fprintf_filtered (file, " flt: ");
- if (inv1)
- fprintf_filtered (file, "<invalid float>");
- else
- fprintf_filtered (file, "%-17.9g", flt1);
-
- fprintf_filtered (file, " dbl: ");
- if (inv2)
- fprintf_filtered (file, "<invalid double>");
- else
- fprintf_filtered (file, "%-24.17g", doub);
+ fprintf_filtered (file, " flt: %s", flt_str.c_str ());
+ fprintf_filtered (file, " dbl: %s", dbl_str.c_str ());
}
}
value = get_frame_register_value (frame, regnum);
if (value_optimized_out (value)
|| !value_entirely_available (value))
- error (_("can't read register %d (%s)"),
- regnum, gdbarch_register_name (gdbarch, regnum));
+ {
+ fprintf_filtered (file, "%*s ",
+ (int) mips_abi_regsize (gdbarch) * 2,
+ (mips_abi_regsize (gdbarch) == 4 ? "<unavl>"
+ : "<unavailable>"));
+ col++;
+ continue;
+ }
raw_buffer = value_contents_all (value);
/* pad small registers */
for (byte = 0;
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc = get_frame_pc (frame);
- struct address_space *aspace;
enum mips_isa isa;
ULONGEST insn;
int status;
/* _has_delay_slot above will have validated the read. */
insn = mips_fetch_instruction (gdbarch, isa, pc, NULL);
size = mips_insn_size (isa, insn);
- aspace = get_frame_address_space (frame);
+
+ const address_space *aspace = get_frame_address_space (frame);
+
return breakpoint_here_p (aspace, pc + size) != no_breakpoint_here;
}
used for all MIPS-specific commands. */
static void
-show_mips_command (char *args, int from_tty)
+show_mips_command (const char *args, int from_tty)
{
help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout);
}
static void
-set_mips_command (char *args, int from_tty)
+set_mips_command (const char *args, int from_tty)
{
printf_unfiltered
("\"set mips\" must be followed by an appropriate subcommand.\n");
/* Commands to show/set the MIPS FPU type. */
static void
-show_mipsfpu_command (char *args, int from_tty)
+show_mipsfpu_command (const char *args, int from_tty)
{
const char *fpu;
static void
-set_mipsfpu_command (char *args, int from_tty)
+set_mipsfpu_command (const char *args, int from_tty)
{
printf_unfiltered ("\"set mipsfpu\" must be followed by \"double\", "
"\"single\",\"none\" or \"auto\".\n");
}
static void
-set_mipsfpu_single_command (char *args, int from_tty)
+set_mipsfpu_single_command (const char *args, int from_tty)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
}
static void
-set_mipsfpu_double_command (char *args, int from_tty)
+set_mipsfpu_double_command (const char *args, int from_tty)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
}
static void
-set_mipsfpu_none_command (char *args, int from_tty)
+set_mipsfpu_none_command (const char *args, int from_tty)
{
struct gdbarch_info info;
gdbarch_info_init (&info);
}
static void
-set_mipsfpu_auto_command (char *args, int from_tty)
+set_mipsfpu_auto_command (const char *args, int from_tty)
{
mips_fpu_type_auto = 1;
}
callable as an sfunc. */
static void
-reinit_frame_cache_sfunc (char *args, int from_tty,
+reinit_frame_cache_sfunc (const char *args, int from_tty,
struct cmd_list_element *c)
{
reinit_frame_cache ();
register naming conventions specified by the user. */
info->disassembler_options = "gpr-names=32";
- /* Call the appropriate disassembler based on the target endian-ness. */
- if (info->endian == BFD_ENDIAN_BIG)
- return print_insn_big_mips (memaddr, info);
- else
- return print_insn_little_mips (memaddr, info);
+ return default_print_insn (memaddr, info);
}
static int
break;
}
else if (arches != NULL)
- fpu_type = gdbarch_tdep (arches->gdbarch)->mips_fpu_type;
+ fpu_type = MIPS_FPU_TYPE (arches->gdbarch);
else
fpu_type = MIPS_FPU_DOUBLE;
if (gdbarch_debug)
!= mips64_transfers_32bit_regs_p)
continue;
/* Be pedantic about which FPU is selected. */
- if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
+ if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type)
continue;
if (tdesc_data != NULL)
mips_register_g_packet_guesses (gdbarch);
/* Hook in OS ABI-specific overrides, if they have been registered. */
- info.tdep_info = tdesc_data;
+ info.tdesc_data = tdesc_data;
gdbarch_init_osabi (info, gdbarch);
/* The hook may have adjusted num_regs, fetch the final value and
}
static void
-mips_abi_update (char *ignore_args, int from_tty, struct cmd_list_element *c)
+mips_abi_update (const char *ignore_args,
+ int from_tty, struct cmd_list_element *c)
{
struct gdbarch_info info;
value);
}
+/* Return a textual name for MIPS FPU type FPU_TYPE. */
+
+static const char *
+mips_fpu_type_str (enum mips_fpu_type fpu_type)
+{
+ switch (fpu_type)
+ {
+ case MIPS_FPU_NONE:
+ return "none";
+ case MIPS_FPU_SINGLE:
+ return "single";
+ case MIPS_FPU_DOUBLE:
+ return "double";
+ default:
+ return "???";
+ }
+}
+
static void
mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n",
MIPS_DEFAULT_FPU_TYPE,
- (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none"
- : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
- : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
- : "???"));
+ mips_fpu_type_str (MIPS_DEFAULT_FPU_TYPE));
fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n",
MIPS_EABI (gdbarch));
fprintf_unfiltered (file,
"mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
MIPS_FPU_TYPE (gdbarch),
- (MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_NONE ? "none"
- : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_SINGLE ? "single"
- : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_DOUBLE ? "double"
- : "???"));
+ mips_fpu_type_str (MIPS_FPU_TYPE (gdbarch)));
}
-extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */
-
void
_initialize_mips_tdep (void)
{