/* Target-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "record-full.h"
#include "auxv.h"
-#include "libbfd.h" /* for bfd_default_set_arch_mach */
#include "coff/internal.h" /* for libcoff.h */
#include "libcoff.h" /* for xcoff_data */
#include "coff/xcoff.h"
#include "frame-unwind.h"
#include "frame-base.h"
+#include "ax.h"
+#include "ax-gdb.h"
+#include <algorithm>
+
#include "features/rs6000/powerpc-32.c"
#include "features/rs6000/powerpc-altivec32.c"
#include "features/rs6000/powerpc-vsx32.c"
set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum);
/* spefscr is a special-purpose register, so the code below handles it. */
-#ifdef WITH_SIM
+#ifdef WITH_PPC_SIM
/* Now handle all special-purpose registers. Verify that they
haven't mistakenly been assigned numbers by any of the above
code. */
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct ppc_reg_offsets *offsets = regset->regmap;
+ const struct ppc_reg_offsets *offsets
+ = (const struct ppc_reg_offsets *) regset->regmap;
size_t offset;
int regsize;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += gpr_size)
- ppc_supply_reg (regcache, i, gregs, offset, gpr_size);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) gregs, offset,
+ gpr_size);
ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch),
- gregs, offsets->pc_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->pc_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
- gregs, offsets->ps_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->ps_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
- gregs, offsets->lr_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->lr_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
- gregs, offsets->ctr_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
- gregs, offsets->cr_offset, offsets->xr_size);
+ (const gdb_byte *) gregs, offsets->cr_offset,
+ offsets->xr_size);
ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
- gregs, offsets->xer_offset, offsets->xr_size);
+ (const gdb_byte *) gregs, offsets->xer_offset,
+ offsets->xr_size);
ppc_supply_reg (regcache, tdep->ppc_mq_regnum,
- gregs, offsets->mq_offset, offsets->xr_size);
+ (const gdb_byte *) gregs, offsets->mq_offset,
+ offsets->xr_size);
return;
}
offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, ®size);
- ppc_supply_reg (regcache, regnum, gregs, offset, regsize);
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) gregs, offset, regsize);
}
/* Supply register REGNUM in the floating-point register set REGSET
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
- ppc_supply_reg (regcache, i, fpregs, offset, 8);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) fpregs, offset, 8);
ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
- fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+ (const gdb_byte *) fpregs, offsets->fpscr_offset,
+ offsets->fpscr_size);
return;
}
offset = ppc_fpreg_offset (tdep, offsets, regnum);
- ppc_supply_reg (regcache, regnum, fpregs, offset,
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
for (i = tdep->ppc_vsr0_upper_regnum;
i < tdep->ppc_vsr0_upper_regnum + 32;
i++)
- ppc_supply_reg (regcache, i, vsxregs, 0, 8);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, 0, 8);
return;
}
else
- ppc_supply_reg (regcache, regnum, vsxregs, 0, 8);
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
}
/* Supply register REGNUM in the Altivec register set REGSET
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
i < tdep->ppc_vr0_regnum + ppc_num_vrs;
i++, offset += 16)
- ppc_supply_reg (regcache, i, vrregs, offset, 16);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) vrregs, offset, 16);
ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
- vrregs, offsets->vscr_offset, 4);
+ (const gdb_byte *) vrregs, offsets->vscr_offset, 4);
ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
- vrregs, offsets->vrsave_offset, 4);
+ (const gdb_byte *) vrregs, offsets->vrsave_offset, 4);
return;
}
offset = ppc_vrreg_offset (tdep, offsets, regnum);
if (regnum != tdep->ppc_vrsave_regnum
&& regnum != tdep->ppc_vrsave_regnum - 1)
- ppc_supply_reg (regcache, regnum, vrregs, offset, 16);
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) vrregs, offset, 16);
else
ppc_supply_reg (regcache, regnum,
- vrregs, offset, 4);
+ (const gdb_byte *) vrregs, offset, 4);
}
/* Collect register REGNUM in the general-purpose register set
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct ppc_reg_offsets *offsets = regset->regmap;
+ const struct ppc_reg_offsets *offsets
+ = (const struct ppc_reg_offsets *) regset->regmap;
size_t offset;
int regsize;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += gpr_size)
- ppc_collect_reg (regcache, i, gregs, offset, gpr_size);
+ ppc_collect_reg (regcache, i, (gdb_byte *) gregs, offset, gpr_size);
ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch),
- gregs, offsets->pc_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->pc_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
- gregs, offsets->ps_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->ps_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
- gregs, offsets->lr_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->lr_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
- gregs, offsets->ctr_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
- gregs, offsets->cr_offset, offsets->xr_size);
+ (gdb_byte *) gregs, offsets->cr_offset,
+ offsets->xr_size);
ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
- gregs, offsets->xer_offset, offsets->xr_size);
+ (gdb_byte *) gregs, offsets->xer_offset,
+ offsets->xr_size);
ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
- gregs, offsets->mq_offset, offsets->xr_size);
+ (gdb_byte *) gregs, offsets->mq_offset,
+ offsets->xr_size);
return;
}
offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, ®size);
- ppc_collect_reg (regcache, regnum, gregs, offset, regsize);
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) gregs, offset, regsize);
}
/* Collect register REGNUM in the floating-point register set
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
- ppc_collect_reg (regcache, i, fpregs, offset, 8);
+ ppc_collect_reg (regcache, i, (gdb_byte *) fpregs, offset, 8);
ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
- fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+ (gdb_byte *) fpregs, offsets->fpscr_offset,
+ offsets->fpscr_size);
return;
}
offset = ppc_fpreg_offset (tdep, offsets, regnum);
- ppc_collect_reg (regcache, regnum, fpregs, offset,
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
for (i = tdep->ppc_vsr0_upper_regnum;
i < tdep->ppc_vsr0_upper_regnum + 32;
i++)
- ppc_collect_reg (regcache, i, vsxregs, 0, 8);
+ ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, 0, 8);
return;
}
else
- ppc_collect_reg (regcache, regnum, vsxregs, 0, 8);
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
}
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
i < tdep->ppc_vr0_regnum + ppc_num_vrs;
i++, offset += 16)
- ppc_collect_reg (regcache, i, vrregs, offset, 16);
+ ppc_collect_reg (regcache, i, (gdb_byte *) vrregs, offset, 16);
ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
- vrregs, offsets->vscr_offset, 4);
+ (gdb_byte *) vrregs, offsets->vscr_offset, 4);
ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
- vrregs, offsets->vrsave_offset, 4);
+ (gdb_byte *) vrregs, offsets->vrsave_offset, 4);
return;
}
offset = ppc_vrreg_offset (tdep, offsets, regnum);
if (regnum != tdep->ppc_vrsave_regnum
&& regnum != tdep->ppc_vrsave_regnum - 1)
- ppc_collect_reg (regcache, regnum, vrregs, offset, 16);
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) vrregs, offset, 16);
else
ppc_collect_reg (regcache, regnum,
- vrregs, offset, 4);
+ (gdb_byte *) vrregs, offset, 4);
}
\f
return 0;
}
-/* Implementation of gdbarch_in_function_epilogue_p. */
+/* Implement the stack_frame_destroyed_p gdbarch method. */
static int
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+rs6000_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
return rs6000_in_function_epilogue_frame_p (get_current_frame (),
gdbarch, pc);
#define BXL_INSN 0x4c000000
#define BP_INSN 0x7C000008
+/* Instruction masks used during single-stepping of atomic
+ sequences. */
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+
+/* We can't displaced step atomic sequences. Otherwise this is just
+ like simple_displaced_step_copy_insn. */
+
+static struct displaced_step_closure *
+ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
+ CORE_ADDR from, CORE_ADDR to,
+ struct regcache *regs)
+{
+ size_t len = gdbarch_max_insn_length (gdbarch);
+ gdb_byte *buf = (gdb_byte *) xmalloc (len);
+ struct cleanup *old_chain = make_cleanup (xfree, buf);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int insn;
+
+ read_memory (from, buf, len);
+
+ insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
+
+ /* Assume all atomic sequences start with a lwarx/ldarx instruction. */
+ if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
+ || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+ {
+ if (debug_displaced)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "displaced: can't displaced step "
+ "atomic sequence at %s\n",
+ paddress (gdbarch, from));
+ }
+ do_cleanups (old_chain);
+ return NULL;
+ }
+
+ write_memory (to, buf, len);
+
+ if (debug_displaced)
+ {
+ fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
+ paddress (gdbarch, from), paddress (gdbarch, to));
+ displaced_step_dump_bytes (gdb_stdlog, buf, len);
+ }
+
+ discard_cleanups (old_chain);
+ return (struct displaced_step_closure *) buf;
+}
+
/* Fix up the state of registers and memory after having single-stepped
a displaced instruction. */
static void
struct regcache *regs)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- /* Since we use simple_displaced_step_copy_insn, our closure is a
- copy of the instruction. */
+ /* Our closure is a copy of the instruction. */
ULONGEST insn = extract_unsigned_integer ((gdb_byte *) closure,
PPC_INSN_SIZE, byte_order);
ULONGEST opcode = 0;
return 1;
}
-/* Instruction masks used during single-stepping of atomic sequences. */
-#define LWARX_MASK 0xfc0007fe
-#define LWARX_INSTRUCTION 0x7c000028
-#define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
-#define STWCX_INSTRUCTION 0x7c00012d
-#define STDCX_INSTRUCTION 0x7c0001ad
-
/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
instruction and ending with a STWCX/STDCX instruction. If such a sequence
is found, attempt to step through it. A breakpoint is placed at the end of
int index;
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
const int atomic_sequence_length = 16; /* Instruction sequence length. */
- int opcode; /* Branch instruction's OPcode. */
int bc_insn_count = 0; /* Conditional branch instruction count. */
/* Assume all atomic sequences start with a lwarx/ldarx instruction. */
CORE_ADDR post_prologue_pc
= skip_prologue_using_sal (gdbarch, func_addr);
if (post_prologue_pc != 0)
- return max (pc, post_prologue_pc);
+ return std::max (pc, post_prologue_pc);
}
/* Can't determine prologue from the symbol table, need to examine
struct gdbarch *arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
int reg_index;
- gdb_byte *byte_buffer = buffer;
+ gdb_byte *byte_buffer = (gdb_byte *) buffer;
enum register_status status;
gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
static enum register_status
do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
{
- return regcache_raw_read (regcache, regnum, buffer);
+ return regcache_raw_read (regcache, regnum, (gdb_byte *) buffer);
}
static enum register_status
do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
{
- regcache_raw_write (regcache, regnum, buffer);
+ regcache_raw_write (regcache, regnum, (const gdb_byte *) buffer);
return REG_VALID;
}
gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}
+static int
+rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_ev0_regnum;
+ ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index);
+ ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index);
+ }
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index);
+ ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1);
+ }
+ else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ if (reg_index > 31)
+ {
+ ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32);
+ }
+ else
+ {
+ ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index);
+ ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index);
+ }
+ }
+ else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+ ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index);
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ _("rs6000_pseudo_register_collect: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+ return 0;
+}
+
+
+static void
+rs6000_gen_return_address (struct gdbarch *gdbarch,
+ struct agent_expr *ax, struct axs_value *value,
+ CORE_ADDR scope)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ value->type = register_type (gdbarch, tdep->ppc_lr_regnum);
+ value->kind = axs_lvalue_register;
+ value->u.reg = tdep->ppc_lr_regnum;
+}
+
+
/* Convert a DBX STABS register number to a GDB register number. */
static int
rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
{"rs2", "IBM POWER RS2", bfd_arch_rs6000,
bfd_mach_rs6k_rs2, &tdesc_rs6000},
- {0, 0, 0, 0, 0}
+ {0, 0, (enum bfd_architecture) 0, 0, 0}
};
/* Return the variant corresponding to architecture ARCH and machine number
CORE_ADDR base;
CORE_ADDR initial_sp;
struct trad_frame_saved_reg *saved_regs;
+
+ /* Set BASE_P to true if this frame cache is properly initialized.
+ Otherwise set to false because some registers or memory cannot
+ collected. */
+ int base_p;
+ /* Cache PC for building unavailable frame. */
+ CORE_ADDR pc;
};
static struct rs6000_frame_cache *
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct rs6000_framedata fdata;
int wordsize = tdep->wordsize;
- CORE_ADDR func, pc;
+ CORE_ADDR func = 0, pc = 0;
if ((*this_cache) != NULL)
- return (*this_cache);
+ return (struct rs6000_frame_cache *) (*this_cache);
cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
(*this_cache) = cache;
+ cache->pc = 0;
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- func = get_frame_func (this_frame);
- pc = get_frame_pc (this_frame);
- skip_prologue (gdbarch, func, pc, &fdata);
-
- /* Figure out the parent's stack pointer. */
-
- /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
- address of the current frame. Things might be easier if the
- ->frame pointed to the outer-most address of the frame. In
- the mean time, the address of the prev frame is used as the
- base address of this frame. */
- cache->base = get_frame_register_unsigned
- (this_frame, gdbarch_sp_regnum (gdbarch));
+ TRY
+ {
+ func = get_frame_func (this_frame);
+ cache->pc = func;
+ pc = get_frame_pc (this_frame);
+ skip_prologue (gdbarch, func, pc, &fdata);
+
+ /* Figure out the parent's stack pointer. */
+
+ /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
+ address of the current frame. Things might be easier if the
+ ->frame pointed to the outer-most address of the frame. In
+ the mean time, the address of the prev frame is used as the
+ base address of this frame. */
+ cache->base = get_frame_register_unsigned
+ (this_frame, gdbarch_sp_regnum (gdbarch));
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ if (ex.error != NOT_AVAILABLE_ERROR)
+ throw_exception (ex);
+ return (struct rs6000_frame_cache *) (*this_cache);
+ }
+ END_CATCH
/* If the function appears to be frameless, check a couple of likely
indicators that we have simply failed to find the frame setup.
if (!fdata.frameless)
{
/* Frameless really means stackless. */
- LONGEST backchain;
+ ULONGEST backchain;
- if (safe_read_memory_integer (cache->base, wordsize,
- byte_order, &backchain))
+ if (safe_read_memory_unsigned_integer (cache->base, wordsize,
+ byte_order, &backchain))
cache->base = (CORE_ADDR) backchain;
}
cache->initial_sp
= get_frame_register_unsigned (this_frame, fdata.alloca_reg);
+ cache->base_p = 1;
return cache;
}
{
struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
this_cache);
+
+ if (!info->base_p)
+ {
+ (*this_id) = frame_id_build_unavailable_stack (info->pc);
+ return;
+ }
+
/* This marks the outermost frame. */
if (info->base == 0)
return;
static struct rs6000_frame_cache *
rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
{
- volatile struct gdb_exception ex;
struct rs6000_frame_cache *cache;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (*this_cache)
- return *this_cache;
+ return (struct rs6000_frame_cache *) *this_cache;
cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
(*this_cache) = cache;
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- TRY_CATCH (ex, RETURN_MASK_ERROR)
+ TRY
{
/* At this point the stack looks as if we just entered the
function, and the return address is stored in LR. */
trad_frame_set_value (cache->saved_regs,
gdbarch_pc_regnum (gdbarch), lr);
}
- if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ if (ex.error != NOT_AVAILABLE_ERROR)
+ throw_exception (ex);
+ }
+ END_CATCH
return cache;
}
return 0;
size = bfd_get_section_size (sect);
- contents = xmalloc (size);
+ contents = (gdb_byte *) xmalloc (size);
if (!bfd_get_section_contents (abfd, sect, contents, 0, size))
{
xfree (contents);
#define PPC_T(insn) PPC_FIELD (insn, 6, 5)
#define PPC_D(insn) PPC_SEXT (PPC_FIELD (insn, 16, 16), 16)
#define PPC_DS(insn) PPC_SEXT (PPC_FIELD (insn, 16, 14), 14)
+#define PPC_DQ(insn) PPC_SEXT (PPC_FIELD (insn, 16, 12), 12)
#define PPC_BIT(insn,n) ((insn & (1 << (31 - (n)))) ? 1 : 0)
#define PPC_OE(insn) PPC_BIT (insn, 21)
#define PPC_RC(insn) PPC_BIT (insn, 31)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int ext = PPC_FIELD (insn, 21, 11);
+ int vra = PPC_FIELD (insn, 11, 5);
switch (ext & 0x3f)
{
/* FALL-THROUGH */
case 42: /* Vector Select */
case 43: /* Vector Permute */
+ case 59: /* Vector Permute Right-indexed */
case 44: /* Vector Shift Left Double by Octet Immediate */
case 45: /* Vector Permute and Exclusive-OR */
case 60: /* Vector Add Extended Unsigned Quadword Modulo */
case 62: /* Vector Subtract Extended Unsigned Quadword Modulo */
case 63: /* Vector Subtract Extended & write Carry Unsigned Quadword */
case 34: /* Vector Multiply-Low-Add Unsigned Halfword Modulo */
+ case 35: /* Vector Multiply-Sum Unsigned Doubleword Modulo */
case 36: /* Vector Multiply-Sum Unsigned Byte Modulo */
case 37: /* Vector Multiply-Sum Mixed Byte Modulo */
case 38: /* Vector Multiply-Sum Unsigned Halfword Modulo */
record_full_arch_list_add_reg (regcache,
tdep->ppc_vr0_regnum + PPC_VRT (insn));
return 0;
+
+ case 48: /* Multiply-Add High Doubleword */
+ case 49: /* Multiply-Add High Doubleword Unsigned */
+ case 51: /* Multiply-Add Low Doubleword */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
}
switch ((ext & 0x1ff))
{
+ case 385:
+ if (vra != 0 /* Decimal Convert To Signed Quadword */
+ && vra != 2 /* Decimal Convert From Signed Quadword */
+ && vra != 4 /* Decimal Convert To Zoned */
+ && vra != 5 /* Decimal Convert To National */
+ && vra != 6 /* Decimal Convert From Zoned */
+ && vra != 7 /* Decimal Convert From National */
+ && vra != 31) /* Decimal Set Sign */
+ break;
/* 5.16 Decimal Integer Arithmetic Instructions */
case 1: /* Decimal Add Modulo */
case 65: /* Decimal Subtract Modulo */
+ case 193: /* Decimal Shift */
+ case 129: /* Decimal Unsigned Shift */
+ case 449: /* Decimal Shift and Round */
+
+ case 257: /* Decimal Truncate */
+ case 321: /* Decimal Unsigned Truncate */
+
/* Bit-21 should be set. */
if (!PPC_BIT (insn, 21))
break;
case 198: /* Vector Compare Equal To Single-Precision */
case 454: /* Vector Compare Greater Than or Equal To Single-Precision */
case 710: /* Vector Compare Greater Than Single-Precision */
+ case 7: /* Vector Compare Not Equal Byte */
+ case 71: /* Vector Compare Not Equal Halfword */
+ case 135: /* Vector Compare Not Equal Word */
+ case 263: /* Vector Compare Not Equal or Zero Byte */
+ case 327: /* Vector Compare Not Equal or Zero Halfword */
+ case 391: /* Vector Compare Not Equal or Zero Word */
if (PPC_Rc (insn))
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache,
return 0;
}
+ if (ext == 1538)
+ {
+ switch (vra)
+ {
+ case 0: /* Vector Count Leading Zero Least-Significant Bits
+ Byte */
+ case 1: /* Vector Count Trailing Zero Least-Significant Bits
+ Byte */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+
+ case 6: /* Vector Negate Word */
+ case 7: /* Vector Negate Doubleword */
+ case 8: /* Vector Parity Byte Word */
+ case 9: /* Vector Parity Byte Doubleword */
+ case 10: /* Vector Parity Byte Quadword */
+ case 16: /* Vector Extend Sign Byte To Word */
+ case 17: /* Vector Extend Sign Halfword To Word */
+ case 24: /* Vector Extend Sign Byte To Doubleword */
+ case 25: /* Vector Extend Sign Halfword To Doubleword */
+ case 26: /* Vector Extend Sign Word To Doubleword */
+ case 28: /* Vector Count Trailing Zeros Byte */
+ case 29: /* Vector Count Trailing Zeros Halfword */
+ case 30: /* Vector Count Trailing Zeros Word */
+ case 31: /* Vector Count Trailing Zeros Doubleword */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ return 0;
+ }
+ }
+
switch (ext)
{
case 142: /* Vector Pack Unsigned Halfword Unsigned Saturate */
case 1923: /* Vector Population Count Word */
case 1987: /* Vector Population Count Doubleword */
case 1356: /* Vector Bit Permute Quadword */
+ case 1484: /* Vector Bit Permute Doubleword */
+ case 513: /* Vector Multiply-by-10 Unsigned Quadword */
+ case 1: /* Vector Multiply-by-10 & write Carry Unsigned
+ Quadword */
+ case 577: /* Vector Multiply-by-10 Extended Unsigned Quadword */
+ case 65: /* Vector Multiply-by-10 Extended & write Carry
+ Unsigned Quadword */
+ case 1027: /* Vector Absolute Difference Unsigned Byte */
+ case 1091: /* Vector Absolute Difference Unsigned Halfword */
+ case 1155: /* Vector Absolute Difference Unsigned Word */
+ case 1796: /* Vector Shift Right Variable */
+ case 1860: /* Vector Shift Left Variable */
+ case 133: /* Vector Rotate Left Word then Mask Insert */
+ case 197: /* Vector Rotate Left Doubleword then Mask Insert */
+ case 389: /* Vector Rotate Left Word then AND with Mask */
+ case 453: /* Vector Rotate Left Doubleword then AND with Mask */
+ case 525: /* Vector Extract Unsigned Byte */
+ case 589: /* Vector Extract Unsigned Halfword */
+ case 653: /* Vector Extract Unsigned Word */
+ case 717: /* Vector Extract Doubleword */
+ case 781: /* Vector Insert Byte */
+ case 845: /* Vector Insert Halfword */
+ case 909: /* Vector Insert Word */
+ case 973: /* Vector Insert Doubleword */
record_full_arch_list_add_reg (regcache,
tdep->ppc_vr0_regnum + PPC_VRT (insn));
return 0;
+ case 1549: /* Vector Extract Unsigned Byte Left-Indexed */
+ case 1613: /* Vector Extract Unsigned Halfword Left-Indexed */
+ case 1677: /* Vector Extract Unsigned Word Left-Indexed */
+ case 1805: /* Vector Extract Unsigned Byte Right-Indexed */
+ case 1869: /* Vector Extract Unsigned Halfword Right-Indexed */
+ case 1933: /* Vector Extract Unsigned Word Right-Indexed */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+
case 1604: /* Move To Vector Status and Control Register */
record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
return 0;
record_full_arch_list_add_reg (regcache,
tdep->ppc_vr0_regnum + PPC_VRT (insn));
return 0;
+ case 833: /* Decimal Copy Sign */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
}
fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int ext = PPC_EXTOP (insn);
+ switch (ext & 0x01f)
+ {
+ case 2: /* Add PC Immediate Shifted */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+ }
+
switch (ext)
{
case 0: /* Move Condition Register Field */
return 0;
}
+ if ((ext & 0xff) == 170)
+ {
+ /* Add Extended using alternate carry bits */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+ }
+
switch (ext)
{
case 78: /* Determine Leftmost Zero Byte */
case 302: /* Move From Branch History Rolling Buffer */
case 339: /* Move From Special Purpose Register */
case 371: /* Move From Time Base [Phased-Out] */
+ case 309: /* Load Doubleword Monitored Indexed */
+ case 128: /* Set Boolean */
+ case 755: /* Deliver A Random Number */
record_full_arch_list_add_reg (regcache,
tdep->ppc_gp0_regnum + PPC_RT (insn));
return 0;
case 282: /* Convert Declets To Binary Coded Decimal */
case 314: /* Convert Binary Coded Decimal To Declets */
case 508: /* Compare bytes */
+ case 307: /* Move From VSR Lower Doubleword */
record_full_arch_list_add_reg (regcache,
tdep->ppc_gp0_regnum + PPC_RA (insn));
return 0;
case 32: /* Compare logical */
case 144: /* Move To Condition Register Fields */
/* Move To One Condition Register Field */
+ case 192: /* Compare Ranged Byte */
+ case 224: /* Compare Equal Byte */
+ case 576: /* Move XER to CR Extended */
+ case 902: /* Paste (should always fail due to single-stepping and
+ the memory location might not be accessible, so
+ record only CR) */
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
return 0;
case 790: /* Load Halfword Byte-Reverse Indexed */
case 534: /* Load Word Byte-Reverse Indexed */
case 532: /* Load Doubleword Byte-Reverse Indexed */
+ case 582: /* Load Word Atomic */
+ case 614: /* Load Doubleword Atomic */
+ case 265: /* Modulo Unsigned Doubleword */
+ case 777: /* Modulo Signed Doubleword */
+ case 267: /* Modulo Unsigned Word */
+ case 779: /* Modulo Signed Word */
record_full_arch_list_add_reg (regcache,
tdep->ppc_gp0_regnum + PPC_RT (insn));
return 0;
case 844: /* Load VSX Vector Doubleword*2 Indexed */
case 332: /* Load VSX Vector Doubleword & Splat Indexed */
case 780: /* Load VSX Vector Word*4 Indexed */
+ case 268: /* Load VSX Vector Indexed */
+ case 364: /* Load VSX Vector Word & Splat Indexed */
+ case 812: /* Load VSX Vector Halfword*8 Indexed */
+ case 876: /* Load VSX Vector Byte*16 Indexed */
+ case 269: /* Load VSX Vector with Length */
+ case 301: /* Load VSX Vector Left-justified with Length */
+ case 781: /* Load VSX Scalar as Integer Byte & Zero Indexed */
+ case 813: /* Load VSX Scalar as Integer Halfword & Zero Indexed */
+ case 403: /* Move To VSR Word & Splat */
+ case 435: /* Move To VSR Double Doubleword */
ppc_record_vsr (regcache, tdep, PPC_XT (insn));
return 0;
case 922: /* Extend Sign Halfword */
case 954: /* Extend Sign Byte */
case 986: /* Extend Sign Word */
+ case 538: /* Count Trailing Zeros Word */
+ case 570: /* Count Trailing Zeros Doubleword */
+ case 890: /* Extend-Sign Word and Shift Left Immediate (445) */
+ case 890 | 1: /* Extend-Sign Word and Shift Left Immediate (445) */
if (PPC_RC (insn))
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache,
case 727: /* Store Floating-Point Double Indexed */
case 919: /* Store Floating-Point Double Pair Indexed */
case 983: /* Store Floating-Point as Integer Word Indexed */
+ case 396: /* Store VSX Vector Indexed */
+ case 940: /* Store VSX Vector Halfword*8 Indexed */
+ case 1004: /* Store VSX Vector Byte*16 Indexed */
+ case 909: /* Store VSX Scalar as Integer Byte Indexed */
+ case 941: /* Store VSX Scalar as Integer Halfword Indexed */
if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
case 135: /* Store Vector Element Byte Indexed */
case 215: /* Store Byte Indexed */
case 694: /* Store Byte Conditional Indexed */
+ case 909: /* Store VSX Scalar as Integer Byte Indexed */
size = 1;
break;
case 439: /* Store Halfword with Update Indexed */
case 407: /* Store Halfword Indexed */
case 726: /* Store Halfword Conditional Indexed */
case 918: /* Store Halfword Byte-Reverse Indexed */
+ case 941: /* Store VSX Scalar as Integer Halfword Indexed */
size = 2;
break;
case 181: /* Store Doubleword with Update Indexed */
case 231: /* Store Vector Indexed */
case 487: /* Store Vector Indexed LRU */
case 919: /* Store Floating-Point Double Pair Indexed */
+ case 396: /* Store VSX Vector Indexed */
+ case 940: /* Store VSX Vector Halfword*8 Indexed */
+ case 1004: /* Store VSX Vector Byte*16 Indexed */
size = 16;
break;
default:
record_full_arch_list_add_mem (addr, size);
return 0;
+ case 397: /* Store VSX Vector with Length */
+ case 429: /* Store VSX Vector Left-justified with Length */
+ ra = 0;
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+ ea = ra;
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+ /* Store up to 16 bytes. */
+ nb = (rb & 0xff) > 16 ? 16 : (rb & 0xff);
+ if (nb > 0)
+ record_full_arch_list_add_mem (ea, nb);
+ return 0;
+
+ case 710: /* Store Word Atomic */
+ case 742: /* Store Doubleword Atomic */
+ ra = 0;
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+ ea = ra;
+ switch (ext)
+ {
+ case 710: /* Store Word Atomic */
+ size = 8;
+ break;
+ case 742: /* Store Doubleword Atomic */
+ size = 16;
+ break;
+ default:
+ gdb_assert (0);
+ }
+ record_full_arch_list_add_mem (ea, size);
+ return 0;
+
case 725: /* Store String Word Immediate */
ra = 0;
if (PPC_RA (insn) != 0)
- regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
ea += ra;
nb = PPC_NB (insn);
case 661: /* Store String Word Indexed */
ra = 0;
if (PPC_RA (insn) != 0)
- regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
ea += ra;
regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
if (nb != 0)
{
- regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RB (insn),
+ &rb);
ea += rb;
record_full_arch_list_add_mem (ea, nb);
}
case 430: /* Clear BHRB */
case 598: /* Synchronize */
case 62: /* Wait for Interrupt */
+ case 30: /* Wait */
case 22: /* Instruction Cache Block Touch */
case 854: /* Enforce In-order Execution of I/O */
case 246: /* Data Cache Block Touch for Store */
case 278: /* Data Cache Block Touch */
case 758: /* Data Cache Block Allocate */
case 982: /* Instruction Cache Block Invalidate */
+ case 774: /* Copy */
+ case 838: /* CP_Abort */
return 0;
case 654: /* Transaction Begin */
case 686: /* Transaction End */
- case 718: /* Transaction Check */
case 750: /* Transaction Suspend or Resume */
case 782: /* Transaction Abort Word Conditional */
case 814: /* Transaction Abort Doubleword Conditional */
case 846: /* Transaction Abort Word Conditional Immediate */
case 878: /* Transaction Abort Doubleword Conditional Immediate */
case 910: /* Transaction Abort */
- fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
- "%08x at %s, 31-%d.\n",
- insn, paddress (gdbarch, addr), ext);
- return -1;
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+ /* FALL-THROUGH */
+ case 718: /* Transaction Check */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
case 1014: /* Data Cache Block set to Zero */
if (target_auxv_search (¤t_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
|| at_dcsz == 0)
at_dcsz = 128; /* Assume 128-byte cache line size (POWER8) */
+ ra = 0;
if (PPC_RA (insn) != 0)
regcache_raw_read_unsigned (regcache,
tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
case 226: /* DFP Test Data Group */
case 642: /* DFP Compare Unordered */
case 674: /* DFP Test Significance */
+ case 675: /* DFP Test Significance Immediate */
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
return 0;
case 217: /* ditto */
case 104: /* VSX Vector Subtract Double-Precision */
case 72: /* VSX Vector Subtract Single-Precision */
+ case 128: /* VSX Scalar Maximum Type-C Double-Precision */
+ case 136: /* VSX Scalar Minimum Type-C Double-Precision */
+ case 144: /* VSX Scalar Maximum Type-J Double-Precision */
+ case 152: /* VSX Scalar Minimum Type-J Double-Precision */
+ case 3: /* VSX Scalar Compare Equal Double-Precision */
+ case 11: /* VSX Scalar Compare Greater Than Double-Precision */
+ case 19: /* VSX Scalar Compare Greater Than or Equal
+ Double-Precision */
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
case 240: /* VSX Vector Copy Sign Double-Precision */
case 208: /* VSX Vector Copy Sign Single-Precision */
case 130: /* VSX Logical AND */
case 2 | 0x20: /* VSX Shift Left Double by Word Immediate (SHW=1) */
case 2 | 0x40: /* VSX Shift Left Double by Word Immediate (SHW=2) */
case 2 | 0x60: /* VSX Shift Left Double by Word Immediate (SHW=3) */
+ case 216: /* VSX Vector Insert Exponent Single-Precision */
+ case 248: /* VSX Vector Insert Exponent Double-Precision */
+ case 26: /* VSX Vector Permute */
+ case 58: /* VSX Vector Permute Right-indexed */
+ case 213: /* VSX Vector Test Data Class Single-Precision (DC=0) */
+ case 213 | 0x8: /* VSX Vector Test Data Class Single-Precision (DC=1) */
+ case 245: /* VSX Vector Test Data Class Double-Precision (DC=0) */
+ case 245 | 0x8: /* VSX Vector Test Data Class Double-Precision (DC=1) */
ppc_record_vsr (regcache, tdep, PPC_XT (insn));
return 0;
case 35: /* VSX Scalar Compare Unordered Double-Precision */
case 43: /* VSX Scalar Compare Ordered Double-Precision */
+ case 59: /* VSX Scalar Compare Exponents Double-Precision */
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
return 0;
case 203: /* VSX Vector Square Root Double-Precision */
case 139: /* VSX Vector Square Root Single-Precision */
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
case 345: /* VSX Scalar Absolute Value Double-Precision */
case 267: /* VSX Scalar Convert Scalar Single-Precision to
Vector Single-Precision format Non-signalling */
case 505: /* VSX Vector Negate Double-Precision */
case 441: /* VSX Vector Negate Single-Precision */
case 164: /* VSX Splat Word */
+ case 165: /* VSX Vector Extract Unsigned Word */
+ case 181: /* VSX Vector Insert Word */
ppc_record_vsr (regcache, tdep, PPC_XT (insn));
return 0;
+ case 298: /* VSX Scalar Test Data Class Single-Precision */
+ case 362: /* VSX Scalar Test Data Class Double-Precision */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
case 106: /* VSX Scalar Test for software Square Root
Double-Precision */
case 234: /* VSX Vector Test for software Square Root
Single-Precision */
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
return 0;
+
+ case 347:
+ switch (PPC_FIELD (insn, 11, 5))
+ {
+ case 0: /* VSX Scalar Extract Exponent Double-Precision */
+ case 1: /* VSX Scalar Extract Significand Double-Precision */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+ case 16: /* VSX Scalar Convert Half-Precision format to
+ Double-Precision format */
+ case 17: /* VSX Scalar round & Convert Double-Precision format
+ to Half-Precision format */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+ return 0;
+ }
+ break;
+
+ case 475:
+ switch (PPC_FIELD (insn, 11, 5))
+ {
+ case 24: /* VSX Vector Convert Half-Precision format to
+ Single-Precision format */
+ case 25: /* VSX Vector round and Convert Single-Precision format
+ to Half-Precision format */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
+ case 0: /* VSX Vector Extract Exponent Double-Precision */
+ case 1: /* VSX Vector Extract Significand Double-Precision */
+ case 7: /* VSX Vector Byte-Reverse Halfword */
+ case 8: /* VSX Vector Extract Exponent Single-Precision */
+ case 9: /* VSX Vector Extract Significand Single-Precision */
+ case 15: /* VSX Vector Byte-Reverse Word */
+ case 23: /* VSX Vector Byte-Reverse Doubleword */
+ case 31: /* VSX Vector Byte-Reverse Quadword */
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+ return 0;
+ }
+ break;
+ }
+
+ switch (ext)
+ {
+ case 360: /* VSX Vector Splat Immediate Byte */
+ if (PPC_FIELD (insn, 11, 2) == 0)
+ {
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+ return 0;
+ }
+ break;
+ case 918: /* VSX Scalar Insert Exponent Double-Precision */
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+ return 0;
}
if (((ext >> 3) & 0x3) == 3) /* VSX Select */
return -1;
}
+/* Parse and record instructions of primary opcode-61 at ADDR.
+ Return 0 if successful. */
+
+static int
+ppc_process_record_op61 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ ULONGEST ea = 0;
+ int size;
+
+ switch (insn & 0x3)
+ {
+ case 0: /* Store Floating-Point Double Pair */
+ case 2: /* Store VSX Scalar Doubleword */
+ case 3: /* Store VSX Scalar Single */
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn),
+ &ea);
+ ea += PPC_DS (insn) << 2;
+ switch (insn & 0x3)
+ {
+ case 0: /* Store Floating-Point Double Pair */
+ size = 16;
+ break;
+ case 2: /* Store VSX Scalar Doubleword */
+ size = 8;
+ break;
+ case 3: /* Store VSX Scalar Single */
+ size = 4;
+ break;
+ default:
+ gdb_assert (0);
+ }
+ record_full_arch_list_add_mem (ea, size);
+ return 0;
+ }
+
+ switch (insn & 0x7)
+ {
+ case 1: /* Load VSX Vector */
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+ return 0;
+ case 5: /* Store VSX Vector */
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn),
+ &ea);
+ ea += PPC_DQ (insn) << 4;
+ record_full_arch_list_add_mem (ea, 16);
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+ "at %s.\n", insn, paddress (gdbarch, addr));
+ return -1;
+}
+
/* Parse and record instructions of primary opcode-63 at ADDR.
Return 0 if successful. */
tdep->ppc_fp0_regnum + PPC_FRT (insn));
if (PPC_RC (insn))
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
+ }
+
+ switch (ext & 0xff)
+ {
+ case 5: /* VSX Scalar Round to Quad-Precision Integer */
+ case 37: /* VSX Scalar Round Quad-Precision to Double-Extended
+ Precision */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+ return 0;
}
switch (ext)
case 226: /* DFP Test Data Group Quad */
case 642: /* DFP Compare Unordered Quad */
case 674: /* DFP Test Significance Quad */
+ case 675: /* DFP Test Significance Immediate Quad */
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
return 0;
if (PPC_RC (insn))
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
- break;
+ return 0;
case 354: /* DFP Extract Biased Exponent Quad */
record_full_arch_list_add_reg (regcache,
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
return 0;
- case 583: /* Move From FPSCR */
+ case 583:
+ switch (PPC_FIELD (insn, 11, 5))
+ {
+ case 1: /* Move From FPSCR & Clear Enables */
+ case 20: /* Move From FPSCR Control & set DRN */
+ case 21: /* Move From FPSCR Control & set DRN Immediate */
+ case 22: /* Move From FPSCR Control & set RN */
+ case 23: /* Move From FPSCR Control & set RN Immediate */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ case 0: /* Move From FPSCR */
+ case 24: /* Move From FPSCR Lightweight */
+ if (PPC_FIELD (insn, 11, 5) == 0 && PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum
+ + PPC_FRT (insn));
+ return 0;
+ }
+ break;
+
case 8: /* Floating Copy Sign */
case 40: /* Floating Negate */
case 72: /* Floating Move Register */
if (PPC_RC (insn))
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
- break;
+ return 0;
case 0: /* Floating Compare Unordered */
case 32: /* Floating Compare Ordered */
case 64: /* Move to Condition Register from FPSCR */
+ case 132: /* VSX Scalar Compare Ordered Quad-Precision */
+ case 164: /* VSX Scalar Compare Exponents Quad-Precision */
+ case 644: /* VSX Scalar Compare Unordered Quad-Precision */
+ case 708: /* VSX Scalar Test Data Class Quad-Precision */
record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
/* FALL-THROUGH */
case 128: /* Floating Test for software Divide */
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
return 0;
+ case 4: /* VSX Scalar Add Quad-Precision */
+ case 36: /* VSX Scalar Multiply Quad-Precision */
+ case 388: /* VSX Scalar Multiply-Add Quad-Precision */
+ case 420: /* VSX Scalar Multiply-Subtract Quad-Precision */
+ case 452: /* VSX Scalar Negative Multiply-Add Quad-Precision */
+ case 484: /* VSX Scalar Negative Multiply-Subtract
+ Quad-Precision */
+ case 516: /* VSX Scalar Subtract Quad-Precision */
+ case 548: /* VSX Scalar Divide Quad-Precision */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
+ case 100: /* VSX Scalar Copy Sign Quad-Precision */
+ case 868: /* VSX Scalar Insert Exponent Quad-Precision */
+ ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+ return 0;
+
+ case 804:
+ switch (PPC_FIELD (insn, 11, 5))
+ {
+ case 27: /* VSX Scalar Square Root Quad-Precision */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
+ case 0: /* VSX Scalar Absolute Quad-Precision */
+ case 2: /* VSX Scalar Extract Exponent Quad-Precision */
+ case 8: /* VSX Scalar Negative Absolute Quad-Precision */
+ case 16: /* VSX Scalar Negate Quad-Precision */
+ case 18: /* VSX Scalar Extract Significand Quad-Precision */
+ ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+ return 0;
+ }
+ break;
+
+ case 836:
+ switch (PPC_FIELD (insn, 11, 5))
+ {
+ case 1: /* VSX Scalar truncate & Convert Quad-Precision format
+ to Unsigned Word format */
+ case 2: /* VSX Scalar Convert Unsigned Doubleword format to
+ Quad-Precision format */
+ case 9: /* VSX Scalar truncate & Convert Quad-Precision format
+ to Signed Word format */
+ case 10: /* VSX Scalar Convert Signed Doubleword format to
+ Quad-Precision format */
+ case 17: /* VSX Scalar truncate & Convert Quad-Precision format
+ to Unsigned Doubleword format */
+ case 20: /* VSX Scalar round & Convert Quad-Precision format to
+ Double-Precision format */
+ case 22: /* VSX Scalar Convert Double-Precision format to
+ Quad-Precision format */
+ case 25: /* VSX Scalar truncate & Convert Quad-Precision format
+ to Signed Doubleword format */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+ return 0;
+ }
}
fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
- "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
+ "at %s, 63-%d.\n", insn, paddress (gdbarch, addr), ext);
return -1;
}
}
break;
- case 57: /* Load Floating-Point Double Pair */
- if (PPC_FIELD (insn, 30, 2) != 0)
- goto UNKNOWN_OP;
- tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
- record_full_arch_list_add_reg (regcache, tmp);
- record_full_arch_list_add_reg (regcache, tmp + 1);
+ case 57:
+ switch (insn & 0x3)
+ {
+ case 0: /* Load Floating-Point Double Pair */
+ tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
+ record_full_arch_list_add_reg (regcache, tmp);
+ record_full_arch_list_add_reg (regcache, tmp + 1);
+ break;
+ case 2: /* Load VSX Scalar Doubleword */
+ case 3: /* Load VSX Scalar Single */
+ ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+ break;
+ default:
+ goto UNKNOWN_OP;
+ }
break;
case 58: /* Load Doubleword */
return -1;
break;
- case 61: /* Store Floating-Point Double Pair */
+ case 61:
+ if (ppc_process_record_op61 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
case 62: /* Store Doubleword */
/* Store Doubleword with Update */
/* Store Quadword with Update */
int size;
int sub2 = PPC_FIELD (insn, 30, 2);
- if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+ if (sub2 > 2)
goto UNKNOWN_OP;
if (PPC_RA (insn) != 0)
tdep->ppc_gp0_regnum + PPC_RA (insn),
&addr);
- size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+ size = (sub2 == 2) ? 16 : 8;
addr += PPC_DS (insn) << 2;
record_full_arch_list_add_mem (addr, size);
set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
- set_gdbarch_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1);
set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum);
set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch,
rs6000_pseudo_register_write);
+ set_gdbarch_ax_pseudo_register_collect (gdbarch,
+ rs6000_ax_pseudo_register_collect);
}
+ set_gdbarch_gen_return_address (gdbarch, rs6000_gen_return_address);
+
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
/* Select instruction printer. */
set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call);
set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
- set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
+ set_gdbarch_stack_frame_destroyed_p (gdbarch, rs6000_stack_frame_destroyed_p);
set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Setup displaced stepping. */
set_gdbarch_displaced_step_copy_insn (gdbarch,
- simple_displaced_step_copy_insn);
+ ppc_displaced_step_copy_insn);
set_gdbarch_displaced_step_hw_singlestep (gdbarch,
ppc_displaced_step_hw_singlestep);
set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
/* Hook in ABI-specific overrides, if they have been registered. */
info.target_desc = tdesc;
- info.tdep_info = (void *) tdesc_data;
+ info.tdep_info = tdesc_data;
gdbarch_init_osabi (info, gdbarch);
switch (info.osabi)
if (strcmp (powerpc_vector_abi_string,
powerpc_vector_strings[vector_abi]) == 0)
{
- powerpc_vector_abi_global = vector_abi;
+ powerpc_vector_abi_global = (enum powerpc_vector_abi) vector_abi;
break;
}