/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
- Copyright (C) 1993-2016 Free Software Foundation, Inc.
+ Copyright (C) 1993-2018 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "doublest.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
/* The alpha needs a conversion between register and memory format if the
register is a floating point register and memory format is float, as the
register format must be double or memory format is an integer with 4
- bytes or less, as the representation of integers in floating point
+ bytes, as the representation of integers in floating point
registers is different. */
static int
struct type *type)
{
return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31
- && TYPE_LENGTH (type) != 8);
+ && TYPE_LENGTH (type) == 4);
}
static int
int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte in[MAX_REGISTER_SIZE];
+ struct value *value = get_frame_register_value (frame, regnum);
- /* Convert to TYPE. */
- if (!get_frame_register_bytes (frame, regnum, 0,
- register_size (gdbarch, regnum),
- in, optimizedp, unavailablep))
- return 0;
+ gdb_assert (value != NULL);
+ *optimizedp = value_optimized_out (value);
+ *unavailablep = !value_entirely_available (value);
- if (TYPE_LENGTH (valtype) == 4)
+ if (*optimizedp || *unavailablep)
{
- alpha_sts (gdbarch, out, in);
- *optimizedp = *unavailablep = 0;
- return 1;
+ release_value (value);
+ return 0;
}
- error (_("Cannot retrieve value from floating point register"));
+ /* Convert to VALTYPE. */
+
+ gdb_assert (TYPE_LENGTH (valtype) == 4);
+ alpha_sts (gdbarch, out, value_contents_all (value));
+
+ release_value (value);
+ return 1;
}
static void
alpha_value_to_register (struct frame_info *frame, int regnum,
struct type *valtype, const gdb_byte *in)
{
- gdb_byte out[MAX_REGISTER_SIZE];
+ gdb_byte out[ALPHA_REGISTER_SIZE];
+
+ gdb_assert (TYPE_LENGTH (valtype) == 4);
+ gdb_assert (register_size (get_frame_arch (frame), regnum)
+ <= ALPHA_REGISTER_SIZE);
+ alpha_lds (get_frame_arch (frame), out, in);
- switch (TYPE_LENGTH (valtype))
- {
- case 4:
- alpha_lds (get_frame_arch (frame), out, in);
- break;
- default:
- error (_("Cannot store value in floating point register"));
- }
put_frame_register (frame, regnum, out);
}
alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
ULONGEST l;
alpha_store_return_value (struct type *valtype, struct regcache *regcache,
const gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
ULONGEST l;
is found, attempt to step through it. A breakpoint is placed at the end of
the sequence. */
-static VEC (CORE_ADDR) *
-alpha_deal_with_atomic_sequence (struct regcache *regcache)
+static std::vector<CORE_ADDR>
+alpha_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- CORE_ADDR pc = regcache_read_pc (regcache);
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence. */
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
const int atomic_sequence_length = 16; /* Instruction sequence length. */
int bc_insn_count = 0; /* Conditional branch instruction count. */
- VEC (CORE_ADDR) *next_pcs = NULL;
/* Assume all atomic sequences start with a LDL_L/LDQ_L instruction. */
if (INSN_OPCODE (insn) != ldl_l_opcode
&& INSN_OPCODE (insn) != ldq_l_opcode)
- return NULL;
+ return {};
/* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */
immediate = (immediate ^ 0x400000) - 0x400000;
if (bc_insn_count >= 1)
- return NULL; /* More than one branch found, fallback
- to the standard single-step code. */
+ return {}; /* More than one branch found, fallback
+ to the standard single-step code. */
breaks[1] = loc + ALPHA_INSN_SIZE + immediate;
/* Assume that the atomic sequence ends with a STL_C/STQ_C instruction. */
if (INSN_OPCODE (insn) != stl_c_opcode
&& INSN_OPCODE (insn) != stq_c_opcode)
- return NULL;
+ return {};
closing_insn = loc;
loc += ALPHA_INSN_SIZE;
|| (breaks[1] >= pc && breaks[1] <= closing_insn)))
last_breakpoint = 0;
+ std::vector<CORE_ADDR> next_pcs;
+
for (index = 0; index <= last_breakpoint; index++)
- VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]);
+ next_pcs.push_back (breaks[index]);
return next_pcs;
}
callable as an sfunc. Used by the "set heuristic-fence-post" command. */
static void
-reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
+reinit_frame_cache_sfunc (const char *args,
+ int from_tty, struct cmd_list_element *c)
{
reinit_frame_cache ();
}
static CORE_ADDR
alpha_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
unsigned int insn;
unsigned int op;
int regno;
return (pc + ALPHA_INSN_SIZE);
}
-VEC (CORE_ADDR) *
+std::vector<CORE_ADDR>
alpha_software_single_step (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- CORE_ADDR pc;
- VEC (CORE_ADDR) *next_pcs = NULL;
+ struct gdbarch *gdbarch = regcache->arch ();
- pc = regcache_read_pc (regcache);
+ CORE_ADDR pc = regcache_read_pc (regcache);
- VEC_safe_push (CORE_ADDR, next_pcs, alpha_next_pc (regcache, pc));
- return next_pcs;
+ std::vector<CORE_ADDR> next_pcs
+ = alpha_deal_with_atomic_sequence (gdbarch, pc);
+ if (!next_pcs.empty ())
+ return next_pcs;
+
+ CORE_ADDR next_pc = alpha_next_pc (regcache, pc);
+ return {next_pc};
}
\f
if (arches != NULL)
return arches->gdbarch;
- tdep = XNEW (struct gdbarch_tdep);
+ tdep = XCNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
/* Lowest text address. This is used by heuristic_proc_start()
set_gdbarch_int_bit (gdbarch, 32);
set_gdbarch_long_bit (gdbarch, 64);
set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_wchar_bit (gdbarch, 64);
+ set_gdbarch_wchar_signed (gdbarch, 0);
set_gdbarch_float_bit (gdbarch, 32);
set_gdbarch_double_bit (gdbarch, 64);
set_gdbarch_long_double_bit (gdbarch, 64);
/* Prologue heuristics. */
set_gdbarch_skip_prologue (gdbarch, alpha_skip_prologue);
- /* Disassembler. */
- set_gdbarch_print_insn (gdbarch, print_insn_alpha);
-
/* Call info. */
set_gdbarch_return_value (gdbarch, alpha_return_value);
set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
/* Handles single stepping of atomic sequences. */
- set_gdbarch_software_single_step (gdbarch, alpha_deal_with_atomic_sequence);
+ set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
}
-extern initialize_file_ftype _initialize_alpha_tdep; /* -Wmissing-prototypes */
-
void
_initialize_alpha_tdep (void)
{