/* Target-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "arch-utils.h"
#include "regcache.h"
#include "regset.h"
-#include "doublest.h"
+#include "target-float.h"
#include "value.h"
#include "parser-defs.h"
#include "osabi.h"
&& (regnum) >= (tdep)->ppc_efpr0_regnum \
&& (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs)
+/* Holds the current set of options to be passed to the disassembler. */
+static char *powerpc_disassembler_options;
+
/* The list of available "set powerpc ..." and "show powerpc ..."
commands. */
static struct cmd_list_element *setpowerpccmdlist = NULL;
&& tdep->ppc_fpscr_regnum >= 0);
}
-/* Return non-zero if the architecture described by GDBARCH has
- VSX registers (vsr0 --- vsr63). */
-static int
-ppc_vsx_support_p (struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- return tdep->ppc_vsr0_regnum >= 0;
-}
-
/* Return non-zero if the architecture described by GDBARCH has
Altivec registers (vr0 --- vr31, vrsave and vscr). */
int
{
if (regsize > 4)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
int gdb_regsize = register_size (gdbarch, regnum);
if (gdb_regsize < regsize
&& gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
offset += regsize - gdb_regsize;
}
- regcache_raw_supply (regcache, regnum, regs + offset);
+ regcache->raw_supply (regnum, regs + offset);
}
}
{
if (regsize > 4)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
int gdb_regsize = register_size (gdbarch, regnum);
if (gdb_regsize < regsize)
{
regsize - gdb_regsize);
}
}
- regcache_raw_collect (regcache, regnum, regs + offset);
+ regcache->raw_collect (regnum, regs + offset);
}
}
return -1;
}
-static int
-ppc_vrreg_offset (struct gdbarch_tdep *tdep,
- const struct ppc_reg_offsets *offsets,
- int regnum)
-{
- if (regnum >= tdep->ppc_vr0_regnum
- && regnum < tdep->ppc_vr0_regnum + ppc_num_vrs)
- return offsets->vr0_offset + (regnum - tdep->ppc_vr0_regnum) * 16;
-
- if (regnum == tdep->ppc_vrsave_regnum - 1)
- return offsets->vscr_offset;
-
- if (regnum == tdep->ppc_vrsave_regnum)
- return offsets->vrsave_offset;
-
- return -1;
-}
-
/* Supply register REGNUM in the general-purpose register set REGSET
from the buffer specified by GREGS and LEN to register cache
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *gregs, size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct ppc_reg_offsets *offsets
= (const struct ppc_reg_offsets *) regset->regmap;
ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *fpregs, size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep;
const struct ppc_reg_offsets *offsets;
size_t offset;
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
-/* Supply register REGNUM in the VSX register set REGSET
- from the buffer specified by VSXREGS and LEN to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-void
-ppc_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
- int regnum, const void *vsxregs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep;
-
- if (!ppc_vsx_support_p (gdbarch))
- return;
-
- tdep = gdbarch_tdep (gdbarch);
-
- if (regnum == -1)
- {
- int i;
-
- for (i = tdep->ppc_vsr0_upper_regnum;
- i < tdep->ppc_vsr0_upper_regnum + 32;
- i++)
- ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, 0, 8);
-
- return;
- }
- else
- ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
-}
-
-/* Supply register REGNUM in the Altivec register set REGSET
- from the buffer specified by VRREGS and LEN to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-void
-ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache,
- int regnum, const void *vrregs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep;
- const struct ppc_reg_offsets *offsets;
- size_t offset;
-
- if (!ppc_altivec_support_p (gdbarch))
- return;
-
- tdep = gdbarch_tdep (gdbarch);
- 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, (const gdb_byte *) vrregs, offset, 16);
-
- ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
- (const gdb_byte *) vrregs, offsets->vscr_offset, 4);
-
- ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
- (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, (const gdb_byte *) vrregs, offset, 16);
- else
- ppc_supply_reg (regcache, regnum,
- (const gdb_byte *) vrregs, offset, 4);
-}
-
/* Collect register REGNUM in the general-purpose register set
REGSET from register cache REGCACHE into the buffer specified by
GREGS and LEN. If REGNUM is -1, do this for all registers in
const struct regcache *regcache,
int regnum, void *gregs, size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct ppc_reg_offsets *offsets
= (const struct ppc_reg_offsets *) regset->regmap;
const struct regcache *regcache,
int regnum, void *fpregs, size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep;
const struct ppc_reg_offsets *offsets;
size_t offset;
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
-/* Collect register REGNUM in the VSX register set
- REGSET from register cache REGCACHE into the buffer specified by
- VSXREGS and LEN. If REGNUM is -1, do this for all registers in
- REGSET. */
-
-void
-ppc_collect_vsxregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *vsxregs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep;
-
- if (!ppc_vsx_support_p (gdbarch))
- return;
-
- tdep = gdbarch_tdep (gdbarch);
-
- if (regnum == -1)
- {
- int i;
-
- for (i = tdep->ppc_vsr0_upper_regnum;
- i < tdep->ppc_vsr0_upper_regnum + 32;
- i++)
- ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, 0, 8);
-
- return;
- }
- else
- ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
-}
-
-
-/* Collect register REGNUM in the Altivec register set
- REGSET from register cache REGCACHE into the buffer specified by
- VRREGS and LEN. If REGNUM is -1, do this for all registers in
- REGSET. */
-
-void
-ppc_collect_vrregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *vrregs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep;
- const struct ppc_reg_offsets *offsets;
- size_t offset;
-
- if (!ppc_altivec_support_p (gdbarch))
- return;
-
- tdep = gdbarch_tdep (gdbarch);
- 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, (gdb_byte *) vrregs, offset, 16);
-
- ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
- (gdb_byte *) vrregs, offsets->vscr_offset, 4);
-
- ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
- (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, (gdb_byte *) vrregs, offset, 16);
- else
- ppc_collect_reg (regcache, regnum,
- (gdb_byte *) vrregs, offset, 4);
-}
-\f
-
static int
insn_changes_sp_or_jumps (unsigned long insn)
{
|| (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \
|| (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION)
-/* We can't displaced step atomic sequences. Otherwise this is just
- like simple_displaced_step_copy_insn. */
+typedef buf_displaced_step_closure ppc_displaced_step_closure;
+
+/* We can't displaced step atomic sequences. */
static struct displaced_step_closure *
ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
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);
+ std::unique_ptr<ppc_displaced_step_closure> closure
+ (new ppc_displaced_step_closure (len));
+ gdb_byte *buf = closure->buf.data ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int insn;
"atomic sequence at %s\n",
paddress (gdbarch, from));
}
- do_cleanups (old_chain);
+
return NULL;
}
displaced_step_dump_bytes (gdb_stdlog, buf, len);
}
- discard_cleanups (old_chain);
- return (struct displaced_step_closure *) buf;
+ return closure.release ();
}
/* Fix up the state of registers and memory after having single-stepped
a displaced instruction. */
static void
ppc_displaced_step_fixup (struct gdbarch *gdbarch,
- struct displaced_step_closure *closure,
+ struct displaced_step_closure *closure_,
CORE_ADDR from, CORE_ADDR to,
struct regcache *regs)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Our closure is a copy of the instruction. */
- ULONGEST insn = extract_unsigned_integer ((gdb_byte *) closure,
- PPC_INSN_SIZE, byte_order);
+ ppc_displaced_step_closure *closure = (ppc_displaced_step_closure *) closure_;
+ ULONGEST insn = extract_unsigned_integer (closure->buf.data (),
+ PPC_INSN_SIZE, byte_order);
ULONGEST opcode = 0;
/* Offset for non PC-relative instructions. */
LONGEST offset = PPC_INSN_SIZE;
Load And Reserve instruction and ending with a Store Conditional
instruction. If such a sequence is found, attempt to step through it.
A breakpoint is placed at the end of the sequence. */
-VEC (CORE_ADDR) *
+std::vector<CORE_ADDR>
ppc_deal_with_atomic_sequence (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc = regcache_read_pc (regcache);
- CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
CORE_ADDR loc = pc;
CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence. */
int insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
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 Load And Reserve instruction. */
if (!IS_LOAD_AND_RESERVE_INSN (insn))
- return NULL;
+ return {};
/* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */
int absolute = insn & 2;
if (bc_insn_count >= 1)
- return 0; /* More than one conditional branch found, fallback
- to the standard single-step code. */
+ return {}; /* More than one conditional branch found, fallback
+ to the standard single-step code. */
if (absolute)
breaks[1] = immediate;
/* Assume that the atomic sequence ends with a Store Conditional
instruction. */
if (!IS_STORE_CONDITIONAL_INSN (insn))
- return NULL;
+ return {};
closing_insn = loc;
loc += PPC_INSN_SIZE;
- insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
/* Insert a breakpoint right after the end of the atomic sequence. */
breaks[0] = loc;
|| (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;
}
return 0;
}
+/* Return true if OP is a stw or std instruction with
+ register operands RS and RA and any immediate offset.
+
+ If WITH_UPDATE is true, also return true if OP is
+ a stwu or stdu instruction with the same operands.
+
+ Return false otherwise.
+ */
+static bool
+store_insn_p (unsigned long op, unsigned long rs,
+ unsigned long ra, bool with_update)
+{
+ rs = rs << 21;
+ ra = ra << 16;
+
+ if (/* std RS, SIMM(RA) */
+ ((op & 0xffff0003) == (rs | ra | 0xf8000000)) ||
+ /* stw RS, SIMM(RA) */
+ ((op & 0xffff0000) == (rs | ra | 0x90000000)))
+ return true;
+
+ if (with_update)
+ {
+ if (/* stdu RS, SIMM(RA) */
+ ((op & 0xffff0003) == (rs | ra | 0xf8000001)) ||
+ /* stwu RS, SIMM(RA) */
+ ((op & 0xffff0000) == (rs | ra | 0x94000000)))
+ return true;
+ }
+
+ return false;
+}
+
/* Masks for decoding a branch-and-link (bl) instruction.
BL_MASK and BL_INSTRUCTION are used in combination with each other.
gdb_byte buf[4];
unsigned long op;
long offset = 0;
+ long alloca_reg_offset = 0;
long vr_saved_offset = 0;
int lr_reg = -1;
int cr_reg = -1;
}
else if ((op & 0xfc1fffff) == 0x7c000026)
{ /* mfcr Rx */
- cr_reg = (op & 0x03e00000);
+ cr_reg = (op & 0x03e00000) >> 21;
if (cr_reg == 0)
r0_contains_arg = 0;
continue;
}
else if (lr_reg >= 0 &&
- /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
- (((op & 0xffff0000) == (lr_reg | 0xf8010000)) ||
- /* stw Rx, NUM(r1) */
- ((op & 0xffff0000) == (lr_reg | 0x90010000)) ||
- /* stwu Rx, NUM(r1) */
- ((op & 0xffff0000) == (lr_reg | 0x94010000))))
- { /* where Rx == lr */
- fdata->lr_offset = offset;
+ ((store_insn_p (op, lr_reg, 1, true)) ||
+ (framep &&
+ (store_insn_p (op, lr_reg,
+ fdata->alloca_reg - tdep->ppc_gp0_regnum,
+ false)))))
+ {
+ if (store_insn_p (op, lr_reg, 1, true))
+ fdata->lr_offset = offset;
+ else /* LR save through frame pointer. */
+ fdata->lr_offset = alloca_reg_offset;
+
fdata->nosavedpc = 0;
/* Invalidate lr_reg, but don't set it to -1.
That would mean that it had never been set. */
}
else if (cr_reg >= 0 &&
- /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
- (((op & 0xffff0000) == (cr_reg | 0xf8010000)) ||
- /* stw Rx, NUM(r1) */
- ((op & 0xffff0000) == (cr_reg | 0x90010000)) ||
- /* stwu Rx, NUM(r1) */
- ((op & 0xffff0000) == (cr_reg | 0x94010000))))
- { /* where Rx == cr */
+ (store_insn_p (op, cr_reg, 1, true)))
+ {
fdata->cr_offset = offset;
/* Invalidate cr_reg, but don't set it to -1.
That would mean that it had never been set. */
offset = fdata->offset;
continue;
}
- else if ((op & 0xfc1f016a) == 0x7c01016e)
- { /* stwux rX,r1,rY */
+ else if ((op & 0xfc1f07fa) == 0x7c01016a)
+ { /* stwux rX,r1,rY || stdux rX,r1,rY */
/* No way to figure out what r1 is going to be. */
fdata->frameless = 0;
offset = fdata->offset;
offset = fdata->offset;
continue;
}
- else if ((op & 0xfc1f016a) == 0x7c01016a)
- { /* stdux rX,r1,rY */
- /* No way to figure out what r1 is going to be. */
- fdata->frameless = 0;
- offset = fdata->offset;
- continue;
- }
else if ((op & 0xffff0000) == 0x38210000)
{ /* addi r1,r1,SIMM */
fdata->frameless = 0;
fdata->frameless = 0;
framep = 1;
fdata->alloca_reg = (tdep->ppc_gp0_regnum + 29);
+ alloca_reg_offset = offset;
continue;
/* Another way to set up the frame pointer. */
fdata->frameless = 0;
framep = 1;
fdata->alloca_reg = (tdep->ppc_gp0_regnum + 31);
+ alloca_reg_offset = offset;
continue;
/* Another way to set up the frame pointer. */
framep = 1;
fdata->alloca_reg = (tdep->ppc_gp0_regnum
+ ((op & ~0x38010000) >> 21));
+ alloca_reg_offset = offset;
continue;
}
/* AltiVec related instructions. */
int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte from[MAX_REGISTER_SIZE];
+ gdb_byte from[PPC_MAX_REGISTER_SIZE];
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
from, optimizedp, unavailablep))
return 0;
- convert_typed_floating (from, builtin_type (gdbarch)->builtin_double,
- to, type);
+ target_float_convert (from, builtin_type (gdbarch)->builtin_double,
+ to, type);
*optimizedp = *unavailablep = 0;
return 1;
}
const gdb_byte *from)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte to[MAX_REGISTER_SIZE];
+ gdb_byte to[PPC_MAX_REGISTER_SIZE];
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
- convert_typed_floating (from, type,
- to, builtin_type (gdbarch)->builtin_double);
+ target_float_convert (from, type,
+ to, builtin_type (gdbarch)->builtin_double);
put_frame_register (frame, regnum, to);
}
e500_move_ev_register (move_ev_register_func move,
struct regcache *regcache, int ev_reg, void *buffer)
{
- struct gdbarch *arch = get_regcache_arch (regcache);
+ struct gdbarch *arch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
int reg_index;
gdb_byte *byte_buffer = (gdb_byte *) buffer;
return status;
}
-static enum register_status
-do_regcache_raw_read (struct regcache *regcache, int regnum, void *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, (const gdb_byte *) buffer);
+ regcache->raw_write (regnum, (const gdb_byte *) buffer);
return REG_VALID;
}
static enum register_status
-e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int reg_nr, gdb_byte *buffer)
+e500_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
+ int ev_reg, gdb_byte *buffer)
{
- return e500_move_ev_register (do_regcache_raw_read, regcache, reg_nr, buffer);
+ struct gdbarch *arch = regcache->arch ();
+ struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+ int reg_index;
+ enum register_status status;
+
+ gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
+
+ reg_index = ev_reg - tdep->ppc_ev0_regnum;
+
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
+ {
+ status = regcache->raw_read (tdep->ppc_ev0_upper_regnum + reg_index,
+ buffer);
+ if (status == REG_VALID)
+ status = regcache->raw_read (tdep->ppc_gp0_regnum + reg_index,
+ buffer + 4);
+ }
+ else
+ {
+ status = regcache->raw_read (tdep->ppc_gp0_regnum + reg_index, buffer);
+ if (status == REG_VALID)
+ status = regcache->raw_read (tdep->ppc_ev0_upper_regnum + reg_index,
+ buffer + 4);
+ }
+
+ return status;
+
}
static void
/* Read method for DFP pseudo-registers. */
static enum register_status
-dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+dfp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Read two FP registers to form a whole dl register. */
- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
+ status = regcache->raw_read (tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
if (status == REG_VALID)
- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
+ status = regcache->raw_read (tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
}
else
{
- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer);
+ status = regcache->raw_read (tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer);
if (status == REG_VALID)
- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer + 8);
+ status = regcache->raw_read (tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer + 8);
}
return status;
{
/* Write each half of the dl register into a separate
FP register. */
- regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ regcache->raw_write (tdep->ppc_fp0_regnum +
2 * reg_index, buffer);
- regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ regcache->raw_write (tdep->ppc_fp0_regnum +
2 * reg_index + 1, buffer + 8);
}
else
{
- regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ regcache->raw_write (tdep->ppc_fp0_regnum +
2 * reg_index + 1, buffer);
- regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ regcache->raw_write (tdep->ppc_fp0_regnum +
2 * reg_index, buffer + 8);
}
}
/* Read method for POWER7 VSX pseudo-registers. */
static enum register_status
-vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* Read the portion that overlaps the VMX registers. */
if (reg_index > 31)
- status = regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
- reg_index - 32, buffer);
+ status = regcache->raw_read (tdep->ppc_vr0_regnum +
+ reg_index - 32, buffer);
else
/* Read the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- reg_index, buffer);
+ status = regcache->raw_read (tdep->ppc_fp0_regnum +
+ reg_index, buffer);
if (status == REG_VALID)
- status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer + 8);
+ status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum +
+ reg_index, buffer + 8);
}
else
{
- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- reg_index, buffer + 8);
+ status = regcache->raw_read (tdep->ppc_fp0_regnum +
+ reg_index, buffer + 8);
if (status == REG_VALID)
- status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer);
+ status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum +
+ reg_index, buffer);
}
return status;
/* Write the portion that overlaps the VMX registers. */
if (reg_index > 31)
- regcache_raw_write (regcache, tdep->ppc_vr0_regnum +
+ regcache->raw_write (tdep->ppc_vr0_regnum +
reg_index - 32, buffer);
else
/* Write the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ regcache->raw_write (tdep->ppc_fp0_regnum +
reg_index, buffer);
- regcache_raw_write (regcache, tdep->ppc_vsr0_upper_regnum +
+ regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
reg_index, buffer + 8);
}
else
{
- regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ regcache->raw_write (tdep->ppc_fp0_regnum +
reg_index, buffer + 8);
- regcache_raw_write (regcache, tdep->ppc_vsr0_upper_regnum +
+ regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
reg_index, buffer);
}
}
/* Read method for POWER7 Extended FP pseudo-registers. */
static enum register_status
-efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+efpr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
/* Read the portion that overlaps the VMX register. */
- return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index,
- offset, register_size (gdbarch, reg_nr),
- buffer);
+ return regcache->raw_read_part (tdep->ppc_vr0_regnum + reg_index,
+ offset, register_size (gdbarch, reg_nr),
+ buffer);
}
/* Write method for POWER7 Extended FP pseudo-registers. */
int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
/* Write the portion that overlaps the VMX register. */
- regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index,
- offset, register_size (gdbarch, reg_nr),
- buffer);
+ regcache->raw_write_part (tdep->ppc_vr0_regnum + reg_index, offset,
+ register_size (gdbarch, reg_nr), buffer);
}
static enum register_status
rs6000_pseudo_register_read (struct gdbarch *gdbarch,
- struct regcache *regcache,
+ readable_regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
- struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+ struct gdbarch *regcache_arch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
gdb_assert (regcache_arch == gdbarch);
struct regcache *regcache,
int reg_nr, const gdb_byte *buffer)
{
- struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+ struct gdbarch *regcache_arch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
gdb_assert (regcache_arch == gdbarch);
struct variant
{
/* Name of this variant. */
- char *name;
+ const char *name;
/* English description of the variant. */
- char *description;
+ const char *description;
/* bfd_arch_info.arch corresponding to variant. */
enum bfd_architecture arch;
return NULL;
}
-static int
-gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
-{
- if (info->endian == BFD_ENDIAN_BIG)
- return print_insn_big_powerpc (memaddr, info);
- else
- return print_insn_little_powerpc (memaddr, info);
-}
\f
static CORE_ADDR
rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
bfd_size_type size;
gdb_byte *ptr;
int success = 0;
- int vector_abi;
if (!abfd)
return 0;
/* Using Tag_GNU_Power_ABI_Vector here is a bit of a hack, as the user
could be using the SPE vector abi without actually using any spe
bits whatsoever. But it's close enough for now. */
- vector_abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_GNU,
- Tag_GNU_Power_ABI_Vector);
+ int vector_abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_GNU,
+ Tag_GNU_Power_ABI_Vector);
if (vector_abi == 3)
return 1;
#endif
&& vra != 7 /* Decimal Convert From National */
&& vra != 31) /* Decimal Set Sign */
break;
+ /* Fall through. */
/* 5.16 Decimal Integer Arithmetic Instructions */
case 1: /* Decimal Add Modulo */
case 65: /* Decimal Subtract Modulo */
return 0;
case 1014: /* Data Cache Block set to Zero */
- if (target_auxv_search (¤t_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
+ if (target_auxv_search (current_top_target (), AT_DCACHEBSIZE, &at_dcsz) <= 0
|| at_dcsz == 0)
at_dcsz = 128; /* Assume 128-byte cache line size (POWER8) */
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);
+ /* Fall through. */
case 0: /* Move From FPSCR */
case 24: /* Move From FPSCR Lightweight */
if (PPC_FIELD (insn, 11, 5) == 0 && PPC_RC (insn))
bfd abfd;
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
int soft_float;
+ enum powerpc_long_double_abi long_double_abi = POWERPC_LONG_DOUBLE_AUTO;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM,
"mq");
- tdesc_wordsize = tdesc_register_size (feature, "pc") / 8;
+ tdesc_wordsize = tdesc_register_bitsize (feature, "pc") / 8;
if (wordsize == -1)
wordsize = tdesc_wordsize;
return NULL;
}
have_fpu = 1;
+
+ /* The fpscr register was expanded in isa 2.05 to 64 bits
+ along with the addition of the decimal floating point
+ facility. */
+ if (tdesc_register_bitsize (feature, "fpscr") > 32)
+ have_dfp = 1;
}
else
have_fpu = 0;
- /* The DFP pseudo-registers will be available when there are floating
- point registers. */
- have_dfp = have_fpu;
-
feature = tdesc_find_feature (tdesc,
"org.gnu.gdb.power.altivec");
if (feature != NULL)
if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec)
{
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
- Tag_GNU_Power_ABI_FP))
+ Tag_GNU_Power_ABI_FP) & 3)
{
case 1:
soft_float_flag = AUTO_BOOLEAN_FALSE;
}
}
+ if (long_double_abi == POWERPC_LONG_DOUBLE_AUTO && from_elf_exec)
+ {
+ switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
+ Tag_GNU_Power_ABI_FP) >> 2)
+ {
+ case 1:
+ long_double_abi = POWERPC_LONG_DOUBLE_IBM128;
+ break;
+ case 3:
+ long_double_abi = POWERPC_LONG_DOUBLE_IEEE128;
+ break;
+ default:
+ break;
+ }
+ }
+
if (vector_abi == POWERPC_VEC_AUTO && from_elf_exec)
{
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
continue;
if (tdep && tdep->soft_float != soft_float)
continue;
+ if (tdep && tdep->long_double_abi != long_double_abi)
+ continue;
if (tdep && tdep->vector_abi != vector_abi)
continue;
if (tdep && tdep->wordsize == wordsize)
tdep->wordsize = wordsize;
tdep->elf_abi = elf_abi;
tdep->soft_float = soft_float;
+ tdep->long_double_abi = long_double_abi;
tdep->vector_abi = vector_abi;
gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
- /* Select instruction printer. */
- if (arch == bfd_arch_rs6000)
- set_gdbarch_print_insn (gdbarch, print_insn_rs6000);
- else
- set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
-
set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS);
if (have_spe)
set_gdbarch_displaced_step_hw_singlestep (gdbarch,
ppc_displaced_step_hw_singlestep);
set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
- set_gdbarch_displaced_step_free_closure (gdbarch,
- simple_displaced_step_free_closure);
set_gdbarch_displaced_step_location (gdbarch,
displaced_step_at_entry_point);
/* Hook in ABI-specific overrides, if they have been registered. */
info.target_desc = tdesc;
- info.tdep_info = tdesc_data;
+ info.tdesc_data = tdesc_data;
gdbarch_init_osabi (info, gdbarch);
switch (info.osabi)
else
register_ppc_ravenscar_ops (gdbarch);
+ set_gdbarch_disassembler_options (gdbarch, &powerpc_disassembler_options);
+ set_gdbarch_valid_disassembler_options (gdbarch,
+ disassembler_options_powerpc ());
+
return gdbarch;
}
/* PowerPC-specific commands. */
static void
-set_powerpc_command (char *args, int from_tty)
+set_powerpc_command (const char *args, int from_tty)
{
printf_unfiltered (_("\
\"set powerpc\" must be followed by an appropriate subcommand.\n"));
}
static void
-show_powerpc_command (char *args, int from_tty)
+show_powerpc_command (const char *args, int from_tty)
{
cmd_show_list (showpowerpccmdlist, from_tty, "");
}
static void
-powerpc_set_soft_float (char *args, int from_tty,
+powerpc_set_soft_float (const char *args, int from_tty,
struct cmd_list_element *c)
{
struct gdbarch_info info;
}
static void
-powerpc_set_vector_abi (char *args, int from_tty,
+powerpc_set_vector_abi (const char *args, int from_tty,
struct cmd_list_element *c)
{
struct gdbarch_info info;
'struct ppc_insn_pattern' objects, terminated by an entry whose
mask is zero.
- When the match is successful, fill INSN[i] with what PATTERN[i]
+ When the match is successful, fill INSNS[i] with what PATTERN[i]
matched. If PATTERN[i] is optional, and the instruction wasn't
- present, set INSN[i] to 0 (which is not a valid PPC instruction).
- INSN should have as many elements as PATTERN. Note that, if
- PATTERN contains optional instructions which aren't present in
- memory, then INSN will have holes, so INSN[i] isn't necessarily the
- i'th instruction in memory. */
+ present, set INSNS[i] to 0 (which is not a valid PPC instruction).
+ INSNS should have as many elements as PATTERN, minus the terminator.
+ Note that, if PATTERN contains optional instructions which aren't
+ present in memory, then INSNS will have holes, so INSNS[i] isn't
+ necessarily the i'th instruction in memory. */
int
ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
- struct ppc_insn_pattern *pattern,
+ const struct ppc_insn_pattern *pattern,
unsigned int *insns)
{
int i;
/* Initialization code. */
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_rs6000_tdep;
-
void
_initialize_rs6000_tdep (void)
{