@@ -434,7 +434,8 @@ powerpc*-*-linux*)
ppc64-tdep.o solib-svr4.o solib-spu.o \
spu-multiarch.o \
glibc-tdep.o symfile-mem.o linux-tdep.o \
- ravenscar-thread.o ppc-ravenscar-thread.o"
+ ravenscar-thread.o ppc-ravenscar-thread.o \
+ linux-record.o "
gdb_sim=../sim/ppc/libsim.a
build_gdbserver=yes
;;
@@ -49,6 +49,9 @@
#include "spu-tdep.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "linux-record.h"
+#include "record-full.h"
+#include "infrun.h"
#include "stap-probe.h"
#include "ax.h"
@@ -298,6 +301,23 @@ powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
|| strcmp (MSYMBOL_LINKAGE_NAME (sym.minsym),
"__glink_PLTresolve") == 0))
return 1;
+ else if (sym.minsym != NULL && execution_direction == EXEC_REVERSE)
+ {
+ /* When reverse stepping, gdb needs to know whether PC lies in
+ the dynamic symbol resolve code, so it can keep going until
+ reaching some user code.
+ Using insns-match-pattern is not suitable, because we had to
+ look both ahead and behind to check where we are in the middle
+ of one of trampline sequences. */
+#define SUBSTRCMP(sym, stub) (memcmp (sym + 8, stub, sizeof (stub) - 1) == 0)
+ if (SUBSTRCMP (MSYMBOL_LINKAGE_NAME (sym.minsym), ".plt_call."))
+ return 1;
+ if (SUBSTRCMP (MSYMBOL_LINKAGE_NAME (sym.minsym), ".plt_branch."))
+ return 1;
+ if (SUBSTRCMP (MSYMBOL_LINKAGE_NAME (sym.minsym), ".plt_branch_r2off."))
+ return 1;
+#undef SUBSTRCMP
+ }
return 0;
}
@@ -764,6 +784,165 @@ ppc_linux_get_syscall_number (struct gdbarch *gdbarch,
return ret;
}
+/* PPC process record-replay */
+
+struct linux_record_tdep ppc_linux_record_tdep;
+
+static enum gdb_syscall
+ppc_canonicalize_syscall (int syscall)
+{
+ /* See arch/powerpc/include/uapi/asm/unistd.h */
+
+ if (syscall <= 165)
+ return syscall;
+ else if (syscall >= 167 && syscall <= 190) /* Skip query_module 166 */
+ return syscall + 1;
+ else if (syscall >= 192 && syscall <= 197) /* mmap2 */
+ return syscall;
+ else if (syscall == 208) /* tkill */
+ return gdb_sys_tkill;
+ else if (syscall >= 207 && syscall <= 220) /* gettid */
+ return syscall + 224 - 207;
+ else if (syscall >= 234 && syscall <= 239) /* exit_group */
+ return syscall + 252 - 234;
+ else if (syscall >= 240 && syscall <=248) /* timer_create */
+ return syscall += 259 - 240;
+ else if (syscall >= 250 && syscall <=251) /* tgkill */
+ return syscall + 270 - 250;
+ else if (syscall == 336)
+ return gdb_sys_recv;
+ else if (syscall == 337)
+ return gdb_sys_recvfrom;
+ else if (syscall == 342)
+ return gdb_sys_recvmsg;
+ return -1;
+}
+
+/* Record all registers but PC register for process-record. */
+
+static int
+ppc_all_but_pc_registers_record (struct regcache *regcache)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ for (i = 0; i < 32; i++)
+ {
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i))
+ return -1;
+ }
+
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+ return -1;
+
+ return 0;
+}
+
+static int
+ppc_linux_syscall_record (struct regcache *regcache)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ ULONGEST scnum;
+ enum gdb_syscall syscall_gdb;
+ int ret;
+
+ regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum, &scnum);
+ syscall_gdb = ppc_canonicalize_syscall (scnum);
+
+ if (syscall_gdb < 0)
+ {
+ printf_unfiltered (_("Process record and replay target doesn't "
+ "support syscall number %d\n"),
+ (int) scnum);
+ return 0;
+ }
+
+ if (syscall_gdb == gdb_sys_sigreturn
+ || syscall_gdb == gdb_sys_rt_sigreturn)
+ {
+ if (ppc_all_but_pc_registers_record (regcache))
+ return -1;
+ return 0;
+ }
+
+ ret = record_linux_system_call (syscall_gdb, regcache,
+ &ppc_linux_record_tdep);
+ if (ret != 0)
+ return ret;
+
+ /* Record registers clobbered during syscall. */
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 0))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 3))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 4))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 5))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 6))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 7))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 8))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 9))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 10))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 11))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 12))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+ return -1;
+
+ return 0;
+}
+
+static int
+ppc64_linux_record_signal (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ enum gdb_signal signal)
+{
+ /* See arch/powerpc/kernel/signal_64.c
+ arch/powerpc/include/asm/ptrace.h
+ for details. */
+ const int SIGNAL_FRAMESIZE = 128;
+ const int sizeof_rt_sigframe = 1440 * 2 + 8 * 2 + 4 * 6 + 8 + 8 + 128 + 512;
+ ULONGEST sp;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (ppc_all_but_pc_registers_record (regcache))
+ return -1;
+
+ if (record_full_arch_list_add_reg (regcache, gdbarch_pc_regnum (gdbarch)))
+ return -1;
+
+ /* Record the change in the stack.
+ frame-size = sizeof (struct rt_sigframe) + SIGNAL_FRAMESIZE */
+ regcache_raw_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &sp);
+ sp -= SIGNAL_FRAMESIZE;
+ sp -= sizeof_rt_sigframe;
+
+ if (record_full_arch_list_add_mem (sp, SIGNAL_FRAMESIZE + sizeof_rt_sigframe))
+ return -1;
+
+ if (record_full_arch_list_add_end ())
+ return -1;
+
+ return 0;
+}
+
static void
ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
@@ -1345,6 +1524,15 @@ ppc_linux_init_abi (struct gdbarch_info info,
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_lp64_fetch_link_map_offsets);
+ if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
+ {
+ powerpc_so_ops = svr4_so_ops;
+ /* Override dynamic resolve function. */
+ powerpc_so_ops.in_dynsym_resolve_code =
+ powerpc_linux_in_dynsym_resolve_code;
+ }
+ set_solib_ops (gdbarch, &powerpc_so_ops);
+
/* Setting the correct XML syscall filename. */
set_xml_syscall_file_name (XML_SYSCALL_FILENAME_PPC64);
@@ -1414,6 +1602,171 @@ ppc_linux_init_abi (struct gdbarch_info info,
}
set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
+
+ /* Support reverse debugging. */
+ set_gdbarch_process_record (gdbarch, ppc64_process_record);
+ set_gdbarch_process_record_signal (gdbarch, ppc64_linux_record_signal);
+ tdep->syscall_record = ppc_linux_syscall_record;
+
+ /* Initialize the ppc_linux_record_tdep. */
+ /* These values are the size of the type that will be used in a system
+ call. They are obtained from Linux Kernel source.
+
+ See arch/powerpc/include/uapi/asm/ioctls.h. */
+ ppc_linux_record_tdep.size_pointer
+ = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+ ppc_linux_record_tdep.size__old_kernel_stat = 32;
+ ppc_linux_record_tdep.size_tms = 32;
+ ppc_linux_record_tdep.size_loff_t = 8;
+ ppc_linux_record_tdep.size_flock = 32;
+ ppc_linux_record_tdep.size_oldold_utsname = 45;
+ ppc_linux_record_tdep.size_ustat = 32;
+ ppc_linux_record_tdep.size_old_sigaction = 152;
+ ppc_linux_record_tdep.size_old_sigset_t = 128;
+ ppc_linux_record_tdep.size_rlimit = 16;
+ ppc_linux_record_tdep.size_rusage = 144;
+ ppc_linux_record_tdep.size_timeval = 16;
+ ppc_linux_record_tdep.size_timezone = 8;
+ ppc_linux_record_tdep.size_old_gid_t = 2;
+ ppc_linux_record_tdep.size_old_uid_t = 2;
+ ppc_linux_record_tdep.size_fd_set = 128;
+ ppc_linux_record_tdep.size_dirent = 280;
+ ppc_linux_record_tdep.size_dirent64 = 280;
+ ppc_linux_record_tdep.size_statfs = 120;
+ ppc_linux_record_tdep.size_statfs64 = 120;
+ ppc_linux_record_tdep.size_sockaddr = 16;
+ ppc_linux_record_tdep.size_int
+ = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
+ ppc_linux_record_tdep.size_long
+ = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+ ppc_linux_record_tdep.size_ulong
+ = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+ ppc_linux_record_tdep.size_msghdr = 56;
+ ppc_linux_record_tdep.size_itimerval = 32;
+ ppc_linux_record_tdep.size_stat = 144;
+ ppc_linux_record_tdep.size_old_utsname = 325;
+ ppc_linux_record_tdep.size_sysinfo = 112;
+ ppc_linux_record_tdep.size_msqid_ds = 120;
+ ppc_linux_record_tdep.size_shmid_ds = 112;
+ ppc_linux_record_tdep.size_new_utsname = 390;
+ ppc_linux_record_tdep.size_timex = 208;
+ ppc_linux_record_tdep.size_mem_dqinfo = 24;
+ ppc_linux_record_tdep.size_if_dqblk = 72;
+ ppc_linux_record_tdep.size_fs_quota_stat = 80;
+ ppc_linux_record_tdep.size_timespec = 16;
+ ppc_linux_record_tdep.size_pollfd = 8;
+ ppc_linux_record_tdep.size_NFS_FHSIZE = 32;
+ ppc_linux_record_tdep.size_knfsd_fh = 132;
+ ppc_linux_record_tdep.size_TASK_COMM_LEN = 32;
+ ppc_linux_record_tdep.size_sigaction = 152;
+ ppc_linux_record_tdep.size_sigset_t = 128;
+ ppc_linux_record_tdep.size_siginfo_t = 128;
+ ppc_linux_record_tdep.size_cap_user_data_t = 8;
+ ppc_linux_record_tdep.size_stack_t = 24;
+ ppc_linux_record_tdep.size_off_t = 8;
+ ppc_linux_record_tdep.size_stat64 = 144;
+ ppc_linux_record_tdep.size_gid_t = 4;
+ ppc_linux_record_tdep.size_uid_t = 4;
+ ppc_linux_record_tdep.size_PAGE_SIZE = 4096;
+ ppc_linux_record_tdep.size_flock64 = 32;
+ ppc_linux_record_tdep.size_user_desc = 16;
+ ppc_linux_record_tdep.size_io_event = 32;
+ ppc_linux_record_tdep.size_iocb = 64;
+ ppc_linux_record_tdep.size_epoll_event = 12;
+ ppc_linux_record_tdep.size_itimerspec = 32;
+ ppc_linux_record_tdep.size_mq_attr = 64;
+ ppc_linux_record_tdep.size_siginfo = 128;
+ ppc_linux_record_tdep.size_termios = 60;
+ ppc_linux_record_tdep.size_termios2 = 44;
+ ppc_linux_record_tdep.size_pid_t = 4;
+ ppc_linux_record_tdep.size_winsize = 8;
+ ppc_linux_record_tdep.size_serial_struct = 72;
+ ppc_linux_record_tdep.size_serial_icounter_struct = 80;
+ ppc_linux_record_tdep.size_hayes_esp_config = 12;
+ ppc_linux_record_tdep.size_size_t = 8;
+ ppc_linux_record_tdep.size_iovec = 16;
+
+ /* These values are the second argument of system call "sys_fcntl"
+ and "sys_fcntl64". They are obtained from Linux Kernel source. */
+ ppc_linux_record_tdep.fcntl_F_GETLK = 5;
+ ppc_linux_record_tdep.fcntl_F_GETLK64 = 12;
+ ppc_linux_record_tdep.fcntl_F_SETLK64 = 13;
+ ppc_linux_record_tdep.fcntl_F_SETLKW64 = 14;
+
+ ppc_linux_record_tdep.arg1 = PPC_R0_REGNUM + 3;
+ ppc_linux_record_tdep.arg2 = PPC_R0_REGNUM + 4;
+ ppc_linux_record_tdep.arg3 = PPC_R0_REGNUM + 5;
+ ppc_linux_record_tdep.arg4 = PPC_R0_REGNUM + 6;
+ ppc_linux_record_tdep.arg5 = PPC_R0_REGNUM + 7;
+ ppc_linux_record_tdep.arg6 = PPC_R0_REGNUM + 8;
+
+ /* These values are the second argument of system call "sys_ioctl".
+ They are obtained from Linux Kernel source. */
+ ppc_linux_record_tdep.ioctl_TCGETS = 0x5401;
+ ppc_linux_record_tdep.ioctl_TCSETS = 0x5402;
+ ppc_linux_record_tdep.ioctl_TCSETSW = 0x5403;
+ ppc_linux_record_tdep.ioctl_TCSETSF = 0x5404;
+ ppc_linux_record_tdep.ioctl_TCGETA = 0x5405;
+ ppc_linux_record_tdep.ioctl_TCSETA = 0x5406;
+ ppc_linux_record_tdep.ioctl_TCSETAW = 0x5407;
+ ppc_linux_record_tdep.ioctl_TCSETAF = 0x5408;
+ ppc_linux_record_tdep.ioctl_TCSBRK = 0x5409;
+ ppc_linux_record_tdep.ioctl_TCXONC = 0x540A;
+ ppc_linux_record_tdep.ioctl_TCFLSH = 0x540B;
+ ppc_linux_record_tdep.ioctl_TIOCEXCL = 0x540C;
+ ppc_linux_record_tdep.ioctl_TIOCNXCL = 0x540D;
+ ppc_linux_record_tdep.ioctl_TIOCSCTTY = 0x540E;
+ ppc_linux_record_tdep.ioctl_TIOCGPGRP = 0x540F;
+ ppc_linux_record_tdep.ioctl_TIOCSPGRP = 0x5410;
+ ppc_linux_record_tdep.ioctl_TIOCOUTQ = 0x5411;
+ ppc_linux_record_tdep.ioctl_TIOCSTI = 0x5412;
+ ppc_linux_record_tdep.ioctl_TIOCGWINSZ = 0x5413;
+ ppc_linux_record_tdep.ioctl_TIOCSWINSZ = 0x5414;
+ ppc_linux_record_tdep.ioctl_TIOCMGET = 0x5415;
+ ppc_linux_record_tdep.ioctl_TIOCMBIS = 0x5416;
+ ppc_linux_record_tdep.ioctl_TIOCMBIC = 0x5417;
+ ppc_linux_record_tdep.ioctl_TIOCMSET = 0x5418;
+ ppc_linux_record_tdep.ioctl_TIOCGSOFTCAR = 0x5419;
+ ppc_linux_record_tdep.ioctl_TIOCSSOFTCAR = 0x541A;
+ ppc_linux_record_tdep.ioctl_FIONREAD = 0x541B;
+ ppc_linux_record_tdep.ioctl_TIOCINQ = ppc_linux_record_tdep.ioctl_FIONREAD;
+ ppc_linux_record_tdep.ioctl_TIOCLINUX = 0x541C;
+ ppc_linux_record_tdep.ioctl_TIOCCONS = 0x541D;
+ ppc_linux_record_tdep.ioctl_TIOCGSERIAL = 0x541E;
+ ppc_linux_record_tdep.ioctl_TIOCSSERIAL = 0x541F;
+ ppc_linux_record_tdep.ioctl_TIOCPKT = 0x5420;
+ ppc_linux_record_tdep.ioctl_FIONBIO = 0x5421;
+ ppc_linux_record_tdep.ioctl_TIOCNOTTY = 0x5422;
+ ppc_linux_record_tdep.ioctl_TIOCSETD = 0x5423;
+ ppc_linux_record_tdep.ioctl_TIOCGETD = 0x5424;
+ ppc_linux_record_tdep.ioctl_TCSBRKP = 0x5425;
+ ppc_linux_record_tdep.ioctl_TIOCTTYGSTRUCT = 0x5426;
+ ppc_linux_record_tdep.ioctl_TIOCSBRK = 0x5427;
+ ppc_linux_record_tdep.ioctl_TIOCCBRK = 0x5428;
+ ppc_linux_record_tdep.ioctl_TIOCGSID = 0x5429;
+ ppc_linux_record_tdep.ioctl_TCGETS2 = 0x802c542a;
+ ppc_linux_record_tdep.ioctl_TCSETS2 = 0x402c542b;
+ ppc_linux_record_tdep.ioctl_TCSETSW2 = 0x402c542c;
+ ppc_linux_record_tdep.ioctl_TCSETSF2 = 0x402c542d;
+ ppc_linux_record_tdep.ioctl_TIOCGPTN = 0x80045430;
+ ppc_linux_record_tdep.ioctl_TIOCSPTLCK = 0x40045431;
+ ppc_linux_record_tdep.ioctl_FIONCLEX = 0x5450;
+ ppc_linux_record_tdep.ioctl_FIOCLEX = 0x5451;
+ ppc_linux_record_tdep.ioctl_FIOASYNC = 0x5452;
+ ppc_linux_record_tdep.ioctl_TIOCSERCONFIG = 0x5453;
+ ppc_linux_record_tdep.ioctl_TIOCSERGWILD = 0x5454;
+ ppc_linux_record_tdep.ioctl_TIOCSERSWILD = 0x5455;
+ ppc_linux_record_tdep.ioctl_TIOCGLCKTRMIOS = 0x5456;
+ ppc_linux_record_tdep.ioctl_TIOCSLCKTRMIOS = 0x5457;
+ ppc_linux_record_tdep.ioctl_TIOCSERGSTRUCT = 0x5458;
+ ppc_linux_record_tdep.ioctl_TIOCSERGETLSR = 0x5459;
+ ppc_linux_record_tdep.ioctl_TIOCSERGETMULTI = 0x545A;
+ ppc_linux_record_tdep.ioctl_TIOCSERSETMULTI = 0x545B;
+ ppc_linux_record_tdep.ioctl_TIOCMIWAIT = 0x545C;
+ ppc_linux_record_tdep.ioctl_TIOCGICOUNT = 0x545D;
+ ppc_linux_record_tdep.ioctl_TIOCGHAYESESP = 0x545E;
+ ppc_linux_record_tdep.ioctl_TIOCSHAYESESP = 0x545F;
+ ppc_linux_record_tdep.ioctl_FIOQSIZE = 0x5460;
}
/* Provide a prototype to silence -Wmissing-prototypes. */
@@ -259,6 +259,8 @@ struct gdbarch_tdep
/* ISA-specific types. */
struct type *ppc_builtin_type_vec64;
struct type *ppc_builtin_type_vec128;
+
+ int (* syscall_record) (struct regcache *regcache);
};
@@ -318,6 +320,9 @@ extern CORE_ADDR ppc_insn_d_field (unsigned int insn);
extern CORE_ADDR ppc_insn_ds_field (unsigned int insn);
+extern int ppc64_process_record (struct gdbarch *gdbarch,
+ struct regcache *regcache, CORE_ADDR addr);
+
/* Instruction size. */
#define PPC_INSN_SIZE 4
@@ -40,6 +40,8 @@
#include "dwarf2-frame.h"
#include "target-descriptions.h"
#include "user-regs.h"
+#include "record-full.h"
+#include "auxv.h"
#include "libbfd.h" /* for bfd_default_set_arch_mach */
#include "coff/internal.h" /* for libcoff.h */
@@ -872,14 +874,14 @@ insn_changes_sp_or_jumps (unsigned long insn)
limit for the size of an epilogue. */
static int
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
+ struct gdbarch *gdbarch, CORE_ADDR pc)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
bfd_byte insn_buf[PPC_INSN_SIZE];
CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
unsigned long insn;
- struct frame_info *curfrm;
/* Find the search limits based on function boundaries and hard limit. */
@@ -892,8 +894,6 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE;
if (epilogue_end > func_end) epilogue_end = func_end;
- curfrm = get_current_frame ();
-
/* Scan forward until next 'blr'. */
for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE)
@@ -934,6 +934,15 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
return 0;
}
+/* Implementation of gdbarch_in_function_epilogue_p. */
+
+static int
+rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ return rs6000_in_function_epilogue_frame_p (get_current_frame (),
+ gdbarch, pc);
+}
+
/* Get the ith function argument for the current function. */
static CORE_ADDR
rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
@@ -3339,6 +3348,89 @@ static const struct frame_unwind rs6000_frame_unwind =
NULL,
default_frame_sniffer
};
+
+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);
+ CORE_ADDR sp;
+
+ if (*this_cache)
+ return *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)
+ {
+ /* At this point the stack looks as if we just entered the
+ function, and the return address is stored in LR. */
+ CORE_ADDR sp, lr;
+
+ sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
+ lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum);
+
+ cache->base = sp;
+ cache->initial_sp = sp;
+
+ trad_frame_set_value (cache->saved_regs,
+ gdbarch_pc_regnum (gdbarch), lr);
+ }
+ if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+ throw_exception (ex);
+
+ return cache;
+}
+
+static void
+rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ CORE_ADDR pc;
+ struct rs6000_frame_cache *info =
+ rs6000_epilogue_frame_cache (this_frame, this_cache);
+
+ pc = get_frame_func (this_frame);
+ if (info->base == 0)
+ (*this_id) = frame_id_build_unavailable_stack (pc);
+ else
+ (*this_id) = frame_id_build (info->base, pc);
+}
+
+static struct value *
+rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct rs6000_frame_cache *info =
+ rs6000_epilogue_frame_cache (this_frame, this_cache);
+ return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+}
+
+static int
+rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ if (frame_relative_level (this_frame) == 0)
+ return rs6000_in_function_epilogue_frame_p (this_frame,
+ get_frame_arch (this_frame),
+ get_frame_pc (this_frame));
+ else
+ return 0;
+}
+
+static const struct frame_unwind rs6000_epilogue_frame_unwind =
+{
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
+ NULL,
+ rs6000_epilogue_frame_sniffer
+};
static CORE_ADDR
@@ -3543,6 +3635,1420 @@ bfd_uses_spe_extensions (bfd *abfd)
return success;
}
+/* These are macros for parsing instruction fields (I.1.6.28) */
+
+#define PPC_FIELD(value, from, len) \
+ (((value) >> (32 - (from) - (len))) & ((1 << (len)) - 1))
+#define PPC_SEXT(v, bs) \
+ ((((CORE_ADDR) (v) & (((CORE_ADDR) 1 << (bs)) - 1)) \
+ ^ ((CORE_ADDR) 1 << ((bs) - 1))) \
+ - ((CORE_ADDR) 1 << ((bs) - 1)))
+#define PPC_OP6(insn) PPC_FIELD (insn, 0, 6)
+#define PPC_EXTOP(insn) PPC_FIELD (insn, 21, 10)
+#define PPC_RT(insn) PPC_FIELD (insn, 6, 5)
+#define PPC_RS(insn) PPC_FIELD (insn, 6, 5)
+#define PPC_RA(insn) PPC_FIELD (insn, 11, 5)
+#define PPC_RB(insn) PPC_FIELD (insn, 16, 5)
+#define PPC_NB(insn) PPC_FIELD (insn, 16, 5)
+#define PPC_VRT(insn) PPC_FIELD (insn, 6, 5)
+#define PPC_FRT(insn) PPC_FIELD (insn, 6, 5)
+#define PPC_SPR(insn) (PPC_FIELD (insn, 11, 5) \
+ | (PPC_FIELD (insn, 16, 5) << 5))
+#define PPC_BF(insn) PPC_FIELD (insn, 6, 3)
+#define PPC_BO(insn) PPC_FIELD (insn, 6, 5)
+#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_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)
+#define PPC_Rc(insn) PPC_BIT (insn, 21)
+#define PPC_LK(insn) PPC_BIT (insn, 31)
+#define PPC_TX(insn) PPC_BIT (insn, 31)
+
+#define PPC_XT(insn) ((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XER_NB(xer) (xer & 0x7f)
+
+/* Record Vector-Scalar Registers. */
+
+static int
+ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr,
+ int size)
+{
+ if (vsr < 0 || vsr >= 64)
+ return -1;
+
+ if (vsr >= 32)
+ {
+ if (tdep->ppc_vr0_regnum >= 0)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + vsr);
+ }
+ else
+ {
+ if (tdep->ppc_fp0_regnum >= 0)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum + vsr);
+ if (size > 8 && tdep->ppc_vsr0_upper_regnum >= 0)
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vsr0_upper_regnum + vsr);
+ }
+
+ return 0;
+}
+
+/* Parse instructions of primary opcode-4. */
+
+static int
+ppc64_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int ext = PPC_FIELD (insn, 21, 11);
+
+ if ((ext & 0x3f) == 45)
+ {
+ /* Vector Permute and Exclusive-OR */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ return 0;
+ }
+
+ switch ((ext & 0x1ff))
+ {
+ /* 5.16 Decimal Integer Arithmetic Instructions */
+ case 1: /* Decimal Add Modulo */
+ case 65: /* Decimal Subtract Modulo */
+
+ /* Bit-21 should be set. */
+ if (!PPC_BIT (insn, 21))
+ break;
+
+ 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;
+ }
+
+ /* Bit-21 is used for RC */
+ switch (ext & 0x3ff)
+ {
+ case 6: /* Vector Compare Equal To Unsigned Byte */
+ case 70: /* Vector Compare Equal To Unsigned Halfword */
+ case 134: /* Vector Compare Equal To Unsigned Word */
+ case 199: /* Vector Compare Equal To Unsigned Doubleword */
+ case 774: /* Vector Compare Greater Than Signed Byte */
+ case 838: /* Vector Compare Greater Than Signed Halfword */
+ case 902: /* Vector Compare Greater Than Signed Word */
+ case 967: /* Vector Compare Greater Than Signed Doubleword */
+ case 518: /* Vector Compare Greater Than Unsigned Byte */
+ case 646: /* Vector Compare Greater Than Unsigned Word */
+ case 582: /* Vector Compare Greater Than Unsigned Halfword */
+ case 711: /* Vector Compare Greater Than Unsigned Doubleword */
+ case 966: /* Vector Compare Bounds Single-Precision */
+ 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 */
+ if (PPC_Rc (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ return 0;
+ }
+
+ switch (ext)
+ {
+ /* 5.8 Vector Permute and Formatting Instructions */
+ case 142: /* Vector Pack Unsigned Halfword Unsigned Saturate */
+ case 206: /* Vector Pack Unsigned Word Unsigned Saturate */
+ case 270: /* Vector Pack Signed Halfword Unsigned Saturate */
+ case 334: /* Vector Pack Signed Word Unsigned Saturate */
+ case 398: /* Vector Pack Signed Halfword Signed Saturate */
+ case 462: /* Vector Pack Signed Word Signed Saturate */
+ case 1230: /* Vector Pack Unsigned Doubleword Unsigned Saturate */
+ case 1358: /* Vector Pack Signed Doubleword Unsigned Saturate */
+ case 1486: /* Vector Pack Signed Doubleword Signed Saturate */
+ /* 5.9 Vector Integer Instructions */
+ case 512: /* Vector Add Unsigned Byte Saturate */
+ case 576: /* Vector Add Unsigned Halfword Saturate */
+ case 640: /* Vector Add Unsigned Word Saturate */
+ case 786: /* Vector Add Signed Byte Saturate */
+ case 832: /* Vector Add Signed Halfword Saturate */
+ case 896: /* Vector Add Signed Word Saturate */
+ case 1536: /* Vector Subtract Unsigned Byte Saturate */
+ case 1600: /* Vector Subtract Unsigned Halfword Saturate */
+ case 1664: /* Vector Subtract Unsigned Word Saturate */
+ case 1792: /* Vector Subtract Signed Byte Saturate */
+ case 1856: /* Vector Subtract Signed Halfword Saturate */
+ case 1920: /* Vector Subtract Signed Word Saturate */
+ case 32: /* Vector Multiply-High-Add Signed Halfword Saturate */
+ case 33: /* Vector Multiply-High-Round-Add Signed Halfword Saturate */
+ case 39: /* Vector Multiply-Sum Unsigned Halfword Saturate */
+ case 41: /* Vector Multiply-Sum Signed Halfword Saturate */
+ case 1544: /* Vector Sum across Quarter Unsigned Byte Saturate */
+ case 1800: /* Vector Sum across Quarter Signed Byte Saturate */
+ case 1608: /* Vector Sum across Quarter Signed Halfword Saturate */
+ case 1672: /* Vector Sum across Half Signed Word Saturate */
+ case 1928: /* Vector Sum across Signed Word Saturate */
+ /* 5.10 Vector Floating-Point Instruction Set */
+ case 970: /* Vector Convert To Signed Fixed-Point Word Saturate */
+ case 906: /* Vector Convert To Unsigned Fixed-Point Word Saturate */
+ record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+ /* FALL-THROUGH */
+ /* 5.8 Vector Permute and Formatting Instructions */
+ case 12: /* Vector Merge High Byte */
+ case 14: /* Vector Pack Unsigned Halfword Unsigned Modulo */
+ case 42: /* Vector Select */
+ case 43: /* Vector Permute */
+ case 76: /* Vector Merge High Halfword */
+ case 78: /* Vector Pack Unsigned Word Unsigned Modulo */
+ case 140: /* Vector Merge High Word */
+ case 268: /* Vector Merge Low Byte */
+ case 332: /* Vector Merge Low Halfword */
+ case 396: /* Vector Merge Low Word */
+ case 526: /* Vector Unpack High Signed Byte */
+ case 590: /* Vector Unpack High Signed Halfword */
+ case 654: /* Vector Unpack Low Signed Byte */
+ case 718: /* Vector Unpack Low Signed Halfword */
+ case 782: /* Vector Pack Pixel */
+ case 846: /* Vector Unpack High Pixel */
+ case 974: /* Vector Unpack Low Pixel */
+ case 1102: /* Vector Pack Unsigned Doubleword Unsigned Modulo */
+ case 1614: /* Vector Unpack High Signed Word */
+ case 1676: /* Vector Merge Odd Word */
+ case 1742: /* Vector Unpack Low Signed Word */
+ case 1932: /* Vector Merge Even Word */
+ case 524: /* Vector Splat Byte */
+ case 588: /* Vector Splat Halfword */
+ case 652: /* Vector Splat Word */
+ case 780: /* Vector Splat Immediate Signed Byte */
+ case 844: /* Vector Splat Immediate Signed Halfword */
+ case 908: /* Vector Splat Immediate Signed Word */
+ case 44: /* Vector Shift Left Double by Octet Immediate */
+ case 452: /* Vector Shift Left */
+ case 708: /* Vector Shift Right */
+ case 1036: /* Vector Shift Left by Octet */
+ case 1100: /* Vector Shift Right by Octet */
+ /* 5.9 Vector Integer Instructions */
+ case 60: /* Vector Add Extended Unsigned Quadword Modulo */
+ case 61: /* Vector Add Extended & write Carry Unsigned Quadword */
+ case 62: /* Vector Subtract Extended Unsigned Quadword Modulo */
+ case 63: /* Vector Subtract Extended & write Carry Unsigned Quadword */
+ case 0: /* Vector Add Unsigned Byte Modulo */
+ case 64: /* Vector Add Unsigned Halfword Modulo */
+ case 128: /* Vector Add Unsigned Word Modulo */
+ case 192: /* Vector Add Unsigned Doubleword Modulo */
+ case 256: /* Vector Add Unsigned Quadword Modulo */
+ case 320: /* Vector Add & write Carry Unsigned Quadword */
+ case 384: /* Vector Add and Write Carry-Out Unsigned Word */
+ case 8: /* Vector Multiply Odd Unsigned Byte */
+ case 72: /* Vector Multiply Odd Unsigned Halfword */
+ case 136: /* Vector Multiply Odd Unsigned Word */
+ case 264: /* Vector Multiply Odd Signed Byte */
+ case 328: /* Vector Multiply Odd Signed Halfword */
+ case 392: /* Vector Multiply Odd Signed Word */
+ case 520: /* Vector Multiply Even Unsigned Byte */
+ case 584: /* Vector Multiply Even Unsigned Halfword */
+ case 648: /* Vector Multiply Even Unsigned Word */
+ case 776: /* Vector Multiply Even Signed Byte */
+ case 840: /* Vector Multiply Even Signed Halfword */
+ case 940: /* Vector Multiply Even Signed Word */
+ case 137: /* Vector Multiply Unsigned Word Modulo */
+ case 1024: /* Vector Subtract Unsigned Byte Modulo */
+ case 1088: /* Vector Subtract Unsigned Halfword Modulo */
+ case 1152: /* Vector Subtract Unsigned Word Modulo */
+ case 1216: /* Vector Subtract Unsigned Doubleword Modulo */
+ case 1280: /* Vector Subtract Unsigned Quadword Modulo */
+ case 1344: /* Vector Subtract & write Carry Unsigned Quadword */
+ case 1408: /* Vector Subtract and Write Carry-Out Unsigned Word */
+ case 34: /* Vector Multiply-Low-Add Unsigned Halfword 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 */
+ case 40: /* Vector Multiply-Sum Signed Halfword Modulo */
+ case 1282: /* Vector Average Signed Byte */
+ case 1346: /* Vector Average Signed Halfword */
+ case 1410: /* Vector Average Signed Word */
+ case 1026: /* Vector Average Unsigned Byte */
+ case 1090: /* Vector Average Unsigned Halfword */
+ case 1154: /* Vector Average Unsigned Word */
+ case 258: /* Vector Maximum Signed Byte */
+ case 322: /* Vector Maximum Signed Halfword */
+ case 386: /* Vector Maximum Signed Word */
+ case 450: /* Vector Maximum Signed Doubleword */
+ case 2: /* Vector Maximum Unsigned Byte */
+ case 66: /* Vector Maximum Unsigned Halfword */
+ case 130: /* Vector Maximum Unsigned Word */
+ case 194: /* Vector Maximum Unsigned Doubleword */
+ case 770: /* Vector Minimum Signed Byte */
+ case 834: /* Vector Minimum Signed Halfword */
+ case 898: /* Vector Minimum Signed Word */
+ case 962: /* Vector Minimum Signed Doubleword */
+ case 514: /* Vector Minimum Unsigned Byte */
+ case 578: /* Vector Minimum Unsigned Halfword */
+ case 642: /* Vector Minimum Unsigned Word */
+ case 706: /* Vector Minimum Unsigned Doubleword */
+ case 1028: /* Vector Logical AND */
+ case 1668: /* Vector Logical Equivalent */
+ case 1092: /* Vector Logical AND with Complement */
+ case 1412: /* Vector Logical NAND */
+ case 1348: /* Vector Logical OR with Complement */
+ case 1156: /* Vector Logical OR */
+ case 1284: /* Vector Logical NOR */
+ case 1220: /* Vector Logical XOR */
+ case 4: /* Vector Rotate Left Byte */
+ case 132: /* Vector Rotate Left Word VX-form */
+ case 68: /* Vector Rotate Left Halfword */
+ case 196: /* Vector Rotate Left Doubleword */
+ case 260: /* Vector Shift Left Byte */
+ case 388: /* Vector Shift Left Word */
+ case 324: /* Vector Shift Left Halfword */
+ case 1476: /* Vector Shift Left Doubleword */
+ case 516: /* Vector Shift Right Byte */
+ case 644: /* Vector Shift Right Word */
+ case 580: /* Vector Shift Right Halfword */
+ case 1732: /* Vector Shift Right Doubleword */
+ case 772: /* Vector Shift Right Algebraic Byte */
+ case 900: /* Vector Shift Right Algebraic Word */
+ case 836: /* Vector Shift Right Algebraic Halfword */
+ case 864: /* Vector Shift Right Algebraic Doubleword */
+ /* 5.10 Vector Floating-Point Instruction Set */
+ case 10: /* Vector Add Single-Precision */
+ case 74: /* Vector Subtract Single-Precision */
+ case 46: /* Vector Multiply-Add Single-Precision */
+ case 47: /* Vector Negative Multiply-Subtract Single-Precision */
+ case 1034: /* Vector Maximum Single-Precision */
+ case 1098: /* Vector Minimum Single-Precision */
+ case 842: /* Vector Convert From Signed Fixed-Point Word */
+ case 778: /* Vector Convert From Unsigned Fixed-Point Word */
+ case 714: /* Vector Round to Single-Precision Integer toward -Infinity */
+ case 522: /* Vector Round to Single-Precision Integer Nearest */
+ case 650: /* Vector Round to Single-Precision Integer toward +Infinity */
+ case 586: /* Vector Round to Single-Precision Integer toward Zero */
+ case 394: /* Vector 2 Raised to the Exponent Estimate Floating-Point */
+ case 458: /* Vector Log Base 2 Estimate Floating-Point */
+ case 266: /* Vector Reciprocal Estimate Single-Precision */
+ case 330: /* Vector Reciprocal Square Root Estimate Single-Precision */
+ /* 5.11 Vector Exclusive-OR-based Instructions */
+ case 1288: /* Vector AES Cipher */
+ case 1289: /* Vector AES Cipher Last */
+ case 1352: /* Vector AES Inverse Cipher */
+ case 1353: /* Vector AES Inverse Cipher Last */
+ case 1480: /* Vector AES SubBytes */
+ case 1730: /* Vector SHA-512 Sigma Doubleword */
+ case 1666: /* Vector SHA-256 Sigma Word */
+ case 1032: /* Vector Polynomial Multiply-Sum Byte */
+ case 1160: /* Vector Polynomial Multiply-Sum Word */
+ case 1096: /* Vector Polynomial Multiply-Sum Halfword */
+ case 1224: /* Vector Polynomial Multiply-Sum Doubleword */
+ /* 5.12 Vector Gather Instruction */
+ case 1292: /* Vector Gather Bits by Bytes by Doubleword */
+ /* 5.13 Vector Count Leading Zeros Instructions */
+ case 1794: /* Vector Count Leading Zeros Byte */
+ case 1858: /* Vector Count Leading Zeros Halfword */
+ case 1922: /* Vector Count Leading Zeros Word */
+ case 1986: /* Vector Count Leading Zeros Doubleword */
+ /* 5.14 Vector Population Count Instructions */
+ case 1795: /* Vector Population Count Byte */
+ case 1859: /* Vector Population Count Halfword */
+ case 1923: /* Vector Population Count Word */
+ case 1987: /* Vector Population Count Doubleword */
+ /* 5.15 Vector Bit Permute Instruction */
+ case 1356: /* Vector Bit Permute Quadword */
+ /* 5.16 Decimal Integer Arithmetic Instructions */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ return 0;
+
+ /* 5.17 Vector Status and Control Register Instructions */
+ case 1604: /* Move To Vector Status and Control Register */
+ record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+ return 0;
+ case 1540: /* Move From Vector Status and Control Register */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+ "%08x at %08lx, 4-%d.\n", insn, addr, ext);
+ return -1;
+}
+
+/* Parse instructions of primary opcode-19. */
+
+static int
+ppc64_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int ext = PPC_EXTOP (insn);
+
+ switch (ext)
+ {
+ case 0: /* Move Condition Register Field */
+ case 33: /* Condition Register NOR */
+ case 129: /* Condition Register AND with Complement */
+ case 193: /* Condition Register XOR */
+ case 225: /* Condition Register NAND */
+ case 257: /* Condition Register AND */
+ case 289: /* Condition Register Equivalent */
+ case 417: /* Condition Register OR with Complement */
+ case 449: /* Condition Register OR */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
+
+ case 16: /* Branch Conditional */
+ case 560: /* Branch Conditional to Branch Target Address Register */
+ if (PPC_BO (insn) & 0x2)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+ /* FALL-THROUGH */
+ case 528: /* Branch Conditional to Count Register */
+ if (PPC_LK (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+ return 0;
+
+ case 150: /* Instruction Synchronize */
+ /* Do nothing. */
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+ "%08x at %08lx, 19-%d.\n", insn, addr, ext);
+ return -1;
+}
+
+/* Parse instructions of primary opcode-31. */
+
+static int
+ppc64_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int ext = PPC_EXTOP (insn);
+ int tmp, nr, nb, i;
+ CORE_ADDR at_dcsz, at_icsz, ea = 0;
+ ULONGEST rb, ra, xer;
+ int size = 0;
+
+ /* These instructions have OE bit. */
+ switch (ext & 0x1ff)
+ {
+ /* These write RT and XER. Update CR if RC is set. */
+ case 8: /* Subtract from carrying */
+ case 10: /* Add carrying */
+ case 136: /* Subtract from extended */
+ case 138: /* Add extended */
+ case 200: /* Subtract from zero extended */
+ case 202: /* Add to zero extended */
+ case 232: /* Subtract from minus one extended */
+ case 234: /* Add to minus one extended */
+ /* CA is always altered, but SO/OV are only altered when OE=1.
+ In any case, XER is always altered. */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+
+ /* These write RT. Update CR if RC is set and update XER if OE is set. */
+ case 40: /* Subtract from */
+ case 104: /* Negate */
+ case 233: /* Multiply low doubleword */
+ case 235: /* Multiply low word */
+ case 266: /* Add */
+ case 393: /* Divide Doubleword Extended Unsigned */
+ case 395: /* Divide Word Extended Unsigned */
+ case 425: /* Divide Doubleword Extended */
+ case 427: /* Divide Word Extended */
+ case 457: /* Divide Doubleword Unsigned */
+ case 459: /* Divide Word Unsigned */
+ case 489: /* Divide Doubleword */
+ case 491: /* Divide Word */
+ if (PPC_OE (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ /* FALL-THROUGH */
+ case 9: /* Multiply High Doubleword Unsigned */
+ case 11: /* Multiply High Word Unsigned */
+ case 73: /* Multiply High Doubleword */
+ case 75: /* Multiply High Word */
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+ }
+
+ if ((ext & 0x1f) == 15)
+ {
+ /* Integer Select. bit[16:20] is used for BC. */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+ }
+
+ switch (ext)
+ {
+ case 78: /* Determine Leftmost Zero Byte */
+ /* CA is always altered, but SO/OV are only altered when OE=1.
+ In any case, XER is always altered. */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+
+ /* These only write RT. */
+ case 19: /* Move from condition register */
+ /* Move From One Condition Register Field */
+ case 74: /* Add and Generate Sixes */
+ case 74 | 0x200: /* Add and Generate Sixes (bit-21 dont-care) */
+ case 302: /* Move From Branch History Rolling Buffer */
+ case 334: /* Move From Performance Monitor Register */
+ case 339: /* Move From Special Purpose Register */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+
+ /* These only write to RA. */
+ case 51: /* Move From VSR Doubleword */
+ case 115: /* Move From VSR Word and Zero */
+ case 122: /* Population count bytes */
+ case 378: /* Population count words */
+ case 506: /* Population count doublewords */
+ case 154: /* Parity Word */
+ case 186: /* Parity Doubleword */
+ case 252: /* Bit Permute Doubleword */
+ case 282: /* Convert Declets To Binary Coded Decimal */
+ case 314: /* Convert Binary Coded Decimal To Declets */
+ case 508: /* Compare bytes */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ return 0;
+
+ /* These write CR and optional RA. */
+ case 792: /* Shift Right Algebraic Word */
+ case 794: /* Shift Right Algebraic Doubleword */
+ case 824: /* Shift Right Algebraic Word Immediate */
+ case 826: /* Shift Right Algebraic Doubleword Immediate (413) */
+ case 826 | 1: /* Shift Right Algebraic Doubleword Immediate (413) */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 0: /* Compare */
+ case 32: /* Compare logical */
+ case 144: /* Move To Condition Register Fields */
+ /* Move To One Condition Register Field */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
+
+ /* These write to RT. Update RA if 'update indexed.' */
+ case 53: /* Load Doubleword with Update Indexed */
+ case 119: /* Load Byte and Zero with Update Indexed */
+ case 311: /* Load Halfword and Zero with Update Indexed */
+ case 55: /* Load Word and Zero with Update Indexed */
+ case 375: /* Load Halfword Algebraic with Update Indexed */
+ case 373: /* Load Word Algebraic with Update Indexed */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 21: /* Load Doubleword Indexed */
+ case 52: /* Load Byte And Reserve Indexed */
+ case 116: /* Load Halfword And Reserve Indexed */
+ case 20: /* Load Word And Reserve Indexed */
+ case 84: /* Load Doubleword And Reserve Indexed */
+ case 87: /* Load Byte and Zero Indexed */
+ case 279: /* Load Halfword and Zero Indexed */
+ case 23: /* Load Word and Zero Indexed */
+ case 343: /* Load Halfword Algebraic Indexed */
+ case 341: /* Load Word Algebraic Indexed */
+ case 790: /* Load Halfword Byte-Reverse Indexed */
+ case 534: /* Load Word Byte-Reverse Indexed */
+ case 532: /* Load Doubleword Byte-Reverse Indexed */
+ case 853: /* Load Byte and Zero Caching Inhibited Indexed */
+ case 821: /* Load Halfword and Zero Caching Inhibited Indexed */
+ case 789: /* Load Word and Zero Caching Inhibited Indexed */
+ case 885: /* Load Doubleword Caching Inhibited Indexed */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ return 0;
+
+ case 597: /* Load String Word Immediate */
+ case 533: /* Load String Word Indexed */
+ if (ext == 597)
+ nr = PPC_NB (insn);
+ else
+ {
+ regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
+ nr = PPC_XER_NB (xer);
+ }
+
+ nr = (nr + 3) >> 2;
+
+ for (i = 0; i < nr; i++)
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum
+ + ((PPC_RT (insn) + i) & 0x1f));
+ return 0;
+
+ case 276: /* Load Quadword And Reserve Indexed */
+ tmp = (tdep->ppc_gp0_regnum + PPC_RT (insn)) & ~1;
+ record_full_arch_list_add_reg (regcache, tmp);
+ record_full_arch_list_add_reg (regcache, tmp | 1);
+ return 0;
+
+ /* These write VRT. */
+ case 6: /* Load Vector for Shift Left Indexed */
+ case 38: /* Load Vector for Shift Right Indexed */
+ case 7: /* Load Vector Element Byte Indexed */
+ case 39: /* Load Vector Element Halfword Indexed */
+ case 71: /* Load Vector Element Word Indexed */
+ case 103: /* Load Vector Indexed */
+ case 359: /* Load Vector Indexed LRU */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_vr0_regnum + PPC_VRT (insn));
+ return 0;
+
+ /* These write FRT. Update RA if 'update indexed.' */
+ case 567: /* Load Floating-Point Single with Update Indexed */
+ case 631: /* Load Floating-Point Double with Update Indexed */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 535: /* Load Floating-Point Single Indexed */
+ case 599: /* Load Floating-Point Double Indexed */
+ case 855: /* Load Floating-Point as Integer Word Algebraic Indexed */
+ case 887: /* Load Floating-Point as Integer Word and Zero Indexed */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ return 0;
+
+ case 791: /* Load Floating-Point Double Pair Indexed */
+ tmp = (tdep->ppc_fp0_regnum + PPC_FRT (insn)) & ~1;
+ record_full_arch_list_add_reg (regcache, tmp);
+ record_full_arch_list_add_reg (regcache, tmp | 1);
+ return 0;
+
+ /* These write VSR of size 8. */
+ case 588: /* Load VSX Scalar Doubleword Indexed */
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn), 8);
+ return 0;
+
+ /* These write VSR of size 16. */
+ case 179: /* Move To VSR Doubleword */
+ case 211: /* Move To VSR Word Algebraic */
+ case 243: /* Move To VSR Word and Zero */
+ case 524: /* Load VSX Scalar Single-Precision Indexed */
+ case 76: /* Load VSX Scalar as Integer Word Algebraic Indexed */
+ case 12: /* Load VSX Scalar as Integer Word and Zero Indexed */
+ case 844: /* Load VSX Vector Doubleword*2 Indexed */
+ case 332: /* Load VSX Vector Doubleword & Splat Indexed */
+ case 780: /* Load VSX Vector Word*4 Indexed */
+ ppc_record_vsr (regcache, tdep, PPC_XT (insn), 16);
+ return 0;
+
+ /* These write RA. Update CR if RC is set. */
+ case 24: /* Shift Left Word */
+ case 26: /* Count Leading Zeros Word */
+ case 27: /* Shift Left Doubleword */
+ case 28: /* AND */
+ case 58: /* Count Leading Zeros Doubleword */
+ case 60: /* AND with Complement */
+ case 124: /* NOR */
+ case 284: /* Equivalent */
+ case 316: /* XOR */
+ case 476: /* NAND */
+ case 412: /* OR with Complement */
+ case 444: /* OR */
+ case 536: /* Shift Right Word */
+ case 539: /* Shift Right Doubleword */
+ case 922: /* Extend Sign Halfword */
+ case 954: /* Extend Sign Byte */
+ case 986: /* Extend Sign Word */
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ return 0;
+
+ /* Store memory. */
+ case 181: /* Store Doubleword with Update Indexed */
+ case 183: /* Store Word with Update Indexed */
+ case 247: /* Store Byte with Update Indexed */
+ case 439: /* Store Half Word with Update Indexed */
+ case 695: /* Store Floating-Point Single with Update Indexed */
+ case 759: /* Store Floating-Point Double with Update Indexed */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 135: /* Store Vector Element Byte Indexed */
+ case 167: /* Store Vector Element Halfword Indexed */
+ case 199: /* Store Vector Element Word Indexed */
+ case 231: /* Store Vector Indexed */
+ case 487: /* Store Vector Indexed LRU */
+ case 716: /* Store VSX Scalar Doubleword Indexed */
+ case 140: /* Store VSX Scalar as Integer Word Indexed */
+ case 652: /* Store VSX Scalar Single-Precision Indexed */
+ case 972: /* Store VSX Vector Doubleword*2 Indexed */
+ case 908: /* Store VSX Vector Word*4 Indexed */
+ case 149: /* Store Doubleword Indexed */
+ case 151: /* Store Word Indexed */
+ case 215: /* Store Byte Indexed */
+ case 407: /* Store Half Word Indexed */
+ case 694: /* Store Byte Conditional Indexed */
+ case 726: /* Store Halfword Conditional Indexed */
+ case 150: /* Store Word Conditional Indexed */
+ case 214: /* Store Doubleword Conditional Indexed */
+ case 182: /* Store Quadword Conditional Indexed */
+ case 662: /* Store Word Byte-Reverse Indexed */
+ case 918: /* Store Halfword Byte-Reverse Indexed */
+ case 660: /* Store Doubleword Byte-Reverse Indexed */
+ case 663: /* Store Floating-Point Single Indexed */
+ case 727: /* Store Floating-Point Double Indexed */
+ case 981: /* Store Byte Caching Inhibited Indexed */
+ case 949: /* Store Halfword Caching Inhibited Indexed */
+ case 917: /* Store Word Caching Inhibited Indexed */
+ case 1013: /* Store Doubleword Caching Inhibited Indexed */
+ case 919: /* Store Floating-Point Double Pair Indexed */
+ case 983: /* Store Floating-Point as Integer Word Indexed */
+ if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+
+ ra = 0;
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+ ea = ra + rb;
+
+ switch (ext)
+ {
+ case 183: /* Store Word with Update Indexed */
+ case 199: /* Store Vector Element Word Indexed */
+ case 140: /* Store VSX Scalar as Integer Word Indexed */
+ case 652: /* Store VSX Scalar Single-Precision Indexed */
+ case 151: /* Store Word Indexed */
+ case 150: /* Store Word Conditional Indexed */
+ case 917: /* Store Word Caching Inhibited Indexed */
+ case 663: /* Store Floating-Point Single Indexed */
+ case 695: /* Store Floating-Point Single with Update Indexed */
+ case 983: /* Store Floating-Point as Integer Word Indexed */
+ size = 4;
+ break;
+ case 247: /* Store Byte with Update Indexed */
+ case 135: /* Store Vector Element Byte Indexed */
+ case 215: /* Store Byte Indexed */
+ case 694: /* Store Byte Conditional Indexed */
+ case 662: /* Store Word Byte-Reverse Indexed */
+ case 981: /* Store Byte Caching Inhibited Indexed */
+ size = 1;
+ break;
+ case 439: /* Store Half Word with Update Indexed */
+ case 167: /* Store Vector Element Halfword Indexed */
+ case 407: /* Store Half Word Indexed */
+ case 726: /* Store Halfword Conditional Indexed */
+ case 918: /* Store Halfword Byte-Reverse Indexed */
+ case 949: /* Store Halfword Caching Inhibited Indexed */
+ size = 2;
+ break;
+ case 181: /* Store Doubleword with Update Indexed */
+ case 716: /* Store VSX Scalar Doubleword Indexed */
+ case 149: /* Store Doubleword Indexed */
+ case 214: /* Store Doubleword Conditional Indexed */
+ case 660: /* Store Doubleword Byte-Reverse Indexed */
+ case 1013: /* Store Doubleword Caching Inhibited Indexed */
+ size = 8;
+ break;
+ case 972: /* Store VSX Vector Doubleword*2 Indexed */
+ case 908: /* Store VSX Vector Word*4 Indexed */
+ case 182: /* Store Quadword Conditional Indexed */
+ case 231: /* Store Vector Indexed */
+ case 487: /* Store Vector Indexed LRU */
+ case 919: /* Store Floating-Point Double Pair Indexed */
+ size = 16;
+ break;
+ }
+
+ /* Align address for Store Vector instructions. */
+ if ((ext & 0x1f) == 0x7)
+ {
+ if ((ext & 0x3) < 3)
+ addr = (addr >> (ext & 0x3)) << (ext & 0x3);
+ else
+ addr = addr & ~0x7ULL;
+ }
+
+ record_full_arch_list_add_mem (addr, size);
+ return 0;
+
+ case 725: /* Store String Word Immediate */
+ case 661: /* Store String Word Indexed */
+ ra = 0;
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+ ea += ra;
+
+ if (ext == 725)
+ nb = PPC_NB (insn);
+ else
+ {
+ regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
+ nb = PPC_XER_NB (xer);
+
+ regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
+ ea += rb;
+ }
+
+ record_full_arch_list_add_mem (ea, nb);
+ return 0;
+
+ case 467: /* Move To Special Purpose Register */
+ switch (PPC_SPR (insn))
+ {
+ case 1: /* XER */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ return 0;
+ case 8: /* LR */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+ return 0;
+ case 9: /* CTR */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+ return 0;
+ }
+
+ goto UNKNOWN_OP;
+
+ case 147: /* Move To Split Little Endian */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+ return 0;
+
+ case 512: /* Move to Condition Register from XER */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ return 0;
+
+ case 4: /* Trap Word */
+ case 68: /* Trap Doubleword */
+ case 430: /* Clear BHRB */
+ case 598: /* Synchronize */
+ case 62: /* Wait for Interrupt */
+ case 22: /* Instruction Cache Block Touch */
+ case 854: /* Enforce In-order Execution of I/O */
+ case 246: /* Data Cache Block Touch for Store */
+ case 54: /* Data Cache Block Store */
+ case 86: /* Data Cache Block Flush */
+ case 278: /* Data Cache Block Touch */
+ case 758: /* Data Cache Block Allocate */
+ return 0;
+
+ case 18: /* TLB Invalidate Local Indexed */
+ case 326: /* Data Cache Read */
+ case 63: /* Data Cache Block Store by External PID */
+ case 127: /* Data Cache Block Flush by External PID */
+ case 134: /* Data Cache Block Touch for Store and Lock Set */
+ case 166: /* Data Cache Block Touch and Lock Set */
+ case 255: /* Data Cache Block Touch for Store by External PID */
+ case 319: /* Data Cache Block Touch by External PID */
+ case 390: /* Data Cache Block Lock Clear */
+ case 422: /* Data Cache Block Lock Query */
+ case 454: /* Data Cache Invalidate */
+ case 998: /* Instruction Cache Read */
+ case 966: /* Instruction Cache Invalidate */
+ case 982: /* Instruction Cache Block Invalidate */
+ case 198: /* Instruction Cache Block Lock Query */
+ case 230: /* Instruction Cache Block Lock Clear */
+ case 486: /* Instruction Cache Block Touch and Lock Set */
+ case 206: /* Message Send */
+ case 238: /* Message Clear */
+ case 142: /* Message Send Privileged */
+ case 174: /* Message Clear Privileged */
+ case 131: /* Write MSR External Enable */
+ case 163: /* Write MSR External Enable Immediate */
+ case 270: /* Embedded Hypervisor Privilege */
+ case 462: /* Move To Performance Monitor Register */
+ case 494: /* Move To Thread Management Register */
+ case 807: /* Store Vector by External Process ID Indexed */
+ case 775: /* Store Vector by External Process ID Indexed LRU */
+ case 95: /* Load Byte by External Process ID Indexed */
+ case 287: /* Load Halfword by External Process ID Indexed */
+ case 31: /* Load Word by External Process ID Indexed */
+ case 29: /* Load Doubleword by External Process ID Indexed */
+ case 295: /* Load Vector by External Process ID Indexed */
+ case 263: /* Load Vector by External Process ID Indexed LRU */
+ case 259: /* Move From Device Control Register Indexed */
+ case 323: /* Move From Device Control Register */
+ case 146: /* Move To Machine State Register */
+ case 178: /* Move To Machine State Register Doubleword */
+ case 387: /* Move To Device Control Register Indexed */
+ case 419: /* Move To Device Control Register User-mode Indexed */
+ case 291: /* Move From Device Control Register User-mode Indexed */
+ case 451: /* Move To Device Control Register */
+ /* Privileged instructions. */
+ fprintf_unfiltered (gdb_stdlog, "Cannot record privileged instructions. "
+ "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+ return -1;
+
+ 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 */
+ case 942: /* Transaction Reclaim */
+ case 1006: /* Transaction Recheckpoint */
+ fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
+ "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+ return -1;
+
+ 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) */
+
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+ ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
+ record_full_arch_list_add_mem (ea, at_dcsz);
+ return 0;
+ }
+
+UNKNOWN_OP:
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+ "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+ return -1;
+}
+
+/* Parse instructions of primary opcode-59. */
+
+static int
+ppc64_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int ext = PPC_EXTOP (insn);
+
+ switch (ext & 0x1f)
+ {
+ case 18: /* Floating Divide */
+ case 20: /* Floating Subtract */
+ case 21: /* Floating Add */
+ case 22: /* Floating Square Root */
+ case 24: /* Floating Reciprocal Estimate */
+ case 25: /* Floating Multiply */
+ case 26: /* Floating Reciprocal Square Root Estimate */
+ case 28: /* Floating Multiply-Subtract */
+ case 29: /* Floating Multiply-Add */
+ case 30: /* Floating Negative Multiply-Subtract */
+ case 31: /* Floating Negative Multiply-Add */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ 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);
+
+ return 0;
+ }
+
+ switch (ext)
+ {
+ case 2: /* DFP Add */
+ case 3: /* DFP Quantize */
+ case 34: /* DFP Multiply */
+ case 35: /* DFP Reround */
+ case 67: /* DFP Quantize Immediate */
+ case 99: /* DFP Round To FP Integer With Inexact */
+ case 227: /* DFP Round To FP Integer Without Inexact */
+ case 258: /* DFP Convert To DFP Long! */
+ case 290: /* DFP Convert To Fixed */
+ case 514: /* DFP Subtract */
+ case 546: /* DFP Divide */
+ case 770: /* DFP Round To DFP Short! */
+ case 802: /* DFP Convert From Fixed */
+ case 834: /* DFP Encode BCD To DPD */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ /* FALL-THROUGH */
+ case 130: /* DFP Compare Ordered */
+ case 162: /* DFP Test Exponent */
+ case 194: /* DFP Test Data Class */
+ case 226: /* DFP Test Data Group */
+ case 642: /* DFP Compare Unordered */
+ case 674: /* DFP Test Significance */
+ 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);
+ return 0;
+
+ case 66: /* DFP Shift Significand Left Immediate */
+ case 98: /* DFP Shift Significand Right Immediate */
+ case 322: /* DFP Decode DPD To BCD */
+ case 354: /* DFP Extract Biased Exponent */
+ case 866: /* DFP Insert Biased Exponent */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
+
+ case 846: /* Floating Convert From Integer Doubleword Single */
+ case 974: /* Floating Convert From Integer Doubleword Unsigned
+ Single */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ 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);
+
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+ "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+ return -1;
+}
+
+/* Parse instructions of primary opcode-60. */
+
+static int
+ppc64_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ int ext = PPC_EXTOP (insn);
+
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+ "%08x at %08lx, 60-%d.\n", insn, addr, ext);
+ return -1;
+}
+
+/* Parse instructions of primary opcode-63. */
+
+static int
+ppc64_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr, uint32_t insn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int ext = PPC_EXTOP (insn);
+ int tmp;
+
+ switch (ext & 0x1f)
+ {
+ case 18: /* Floating Divide */
+ case 20: /* Floating Subtract */
+ case 21: /* Floating Add */
+ case 22: /* Floating Square Root */
+ case 24: /* Floating Reciprocal Estimate */
+ case 25: /* Floating Multiply */
+ case 26: /* Floating Reciprocal Square Root Estimate */
+ case 28: /* Floating Multiply-Subtract */
+ case 29: /* Floating Multiply-Add */
+ case 30: /* Floating Negative Multiply-Subtract */
+ case 31: /* Floating Negative Multiply-Add */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ 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);
+ return 0;
+ }
+
+ switch (ext)
+ {
+ case 2: /* DFP Add */
+ case 3: /* DFP Quantize */
+ case 34: /* DFP Multiply */
+ case 35: /* DFP Reround */
+ case 67: /* DFP Quantize Immediate */
+ case 99: /* DFP Round To FP Integer With Inexact */
+ case 227: /* DFP Round To FP Integer Without Inexact */
+ case 258: /* DFP Convert To DFP Extended */
+ case 290: /* DFP Convert To Fixed */
+ case 514: /* DFP Subtract */
+ case 546: /* DFP Divide */
+ case 770: /* DFP Round To DFP Long */
+ case 802: /* DFP Convert From Fixed */
+ case 834: /* DFP Encode BCD To DPD */
+ tmp = (tdep->ppc_fp0_regnum + PPC_FRT (insn)) & ~1;
+ record_full_arch_list_add_reg (regcache, tmp);
+ record_full_arch_list_add_reg (regcache, tmp | 1);
+ /* FALL-THROUGH */
+ case 130: /* DFP Compare Ordered */
+ case 162: /* DFP Test Exponent */
+ case 194: /* DFP Test Data Class */
+ case 226: /* DFP Test Data Group */
+ case 642: /* DFP Compare Unordered */
+ case 674: /* DFP Test Significance */
+ 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);
+ return 0;
+
+ case 66: /* DFP Shift Significand Left Immediate */
+ case 98: /* DFP Shift Significand Right Immediate */
+ case 322: /* DFP Decode DPD To BCD */
+ case 354: /* DFP Extract Biased Exponent */
+ case 866: /* DFP Insert Biased Exponent */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
+
+ case 12: /* Floating Round to Single-Precision */
+ case 14: /* Floating Convert To Integer Word */
+ case 15: /* Floating Convert To Integer Word
+ with round toward Zero */
+ case 142: /* Floating Convert To Integer Word Unsigned */
+ case 143: /* Floating Convert To Integer Word Unsigned
+ with round toward Zero */
+ case 392: /* Floating Round to Integer Nearest */
+ case 424: /* Floating Round to Integer Toward Zero */
+ case 456: /* Floating Round to Integer Plus */
+ case 488: /* Floating Round to Integer Minus */
+ case 814: /* Floating Convert To Integer Doubleword */
+ case 815: /* Floating Convert To Integer Doubleword
+ with round toward Zero */
+ case 846: /* Floating Convert From Integer Doubleword */
+ case 942: /* Floating Convert To Integer Doubleword Unsigned */
+ case 943: /* Floating Convert To Integer Doubleword Unsigned
+ with round toward Zero */
+ case 974: /* Floating Convert From Integer Doubleword Unsigned */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ 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);
+ return 0;
+
+ case 8: /* Floating Copy Sign */
+ case 40: /* Floating Negate */
+ case 72: /* Floating Move Register */
+ case 136: /* Floating Negative Absolute Value */
+ case 264: /* Floating Absolute Value */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ if (PPC_RC (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ return 0;
+
+ case 838: /* Floating Merge Odd Word */
+ case 966: /* Floating Merge Even Word */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ return 0;
+
+ case 0: /* Floating Compare Unordered */
+ case 32: /* Floating Compare Ordered */
+ case 38: /* Move To FPSCR Bit 1 */
+ case 64: /* Move to Condition Register from FPSCR */
+ case 70: /* Move To FPSCR Bit 0 */
+ case 134: /* Move To FPSCR Field Immediate */
+ case 711: /* Move To FPSCR Fields */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+ /* FALL-THROUGH */
+ case 23: /* Floating Select */
+ case 128: /* Floating Test for software Divide */
+ case 160: /* Floating Test for software Square Root */
+ case 583: /* Move From FPSCR */
+ 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 at %08lx, 59-%d.\n", insn, addr, ext);
+ return -1;
+}
+
+/* Parse the current instruction and record the values of the registers and
+ memory that will be changed in current instruction to "record_arch_list".
+ Return -1 if something wrong. */
+
+int
+ppc64_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
+ CORE_ADDR addr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ uint32_t insn;
+ int op6, tmp, i;
+
+ insn = read_memory_unsigned_integer (addr, 4, byte_order);
+ op6 = PPC_OP6 (insn);
+
+ switch (op6)
+ {
+ case 2: /* Trap Doubleword Immediate */
+ case 3: /* Trap Word Immediate */
+ /* Do nothing. */
+ break;
+
+ case 4:
+ if (ppc64_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
+ case 17: /* System call */
+ if (tdep->syscall_record != NULL)
+ {
+ if (tdep->syscall_record (regcache) != 0)
+ return -1;
+ }
+ else
+ {
+ printf_unfiltered (_("no syscall record support\n"));
+ return -1;
+ }
+ break;
+
+ case 7: /* Multiply Low Immediate */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ break;
+
+ case 8: /* Subtract From Immediate Carrying */
+ 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));
+ break;
+
+ case 10: /* Compare Logical Immediate */
+ case 11: /* Compare Immediate */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ break;
+
+ case 13: /* Add Immediate Carrying and Record */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ /* FALL-THROUGH */
+ case 12: /* Add Immediate Carrying */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+ /* FALL-THROUGH */
+ case 14: /* Add Immediate */
+ case 15: /* Add Immediate Shifted */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ break;
+
+ case 16: /* Branch Conditional */
+ if (PPC_BO (insn) & 0x2)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+ /* FALL-THROUGH */
+ case 18: /* Branch */
+ if (PPC_LK (insn))
+ record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+ break;
+
+ case 19:
+ if (ppc64_process_record_op19 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
+ case 20: /* Rotate Left Word Immediate then Mask Insert */
+ case 21: /* Rotate Left Word Immediate then AND with Mask */
+ case 23: /* Rotate Left Word then AND with Mask */
+ case 30: /* Rotate Left Doubleword Immediate then Clear Left */
+ /* Rotate Left Doubleword Immediate then Clear Right */
+ /* Rotate Left Doubleword Immediate then Clear */
+ /* Rotate Left Doubleword then Clear Left */
+ /* Rotate Left Doubleword then Clear Right */
+ /* Rotate Left Doubleword Immediate then Mask Insert */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+ break;
+
+ case 24: /* OR Immediate */
+ case 25: /* OR Immediate Shifted */
+ case 26: /* XOR Immediate */
+ case 27: /* XOR Immediate Shifted */
+ case 28: /* AND Immediate */
+ case 29: /* AND Immediate Shifted */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ break;
+
+ case 31:
+ if (ppc64_process_record_op31 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
+ case 33: /* Load Word and Zero with Update */
+ case 35: /* Load Byte and Zero with Update */
+ case 41: /* Load Halfword and Zero with Update */
+ case 43: /* Load Halfword Algebraic with Update */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 32: /* Load Word and Zero */
+ case 34: /* Load Byte and Zero */
+ case 40: /* Load Halfword and Zero */
+ case 42: /* Load Halfword Algebraic */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ break;
+
+ case 46: /* Load Multiple Word */
+ for (i = PPC_RT (insn); i < 32; i++)
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ break;
+
+ case 56: /* Load Quadword */
+ tmp = (tdep->ppc_gp0_regnum + PPC_RT (insn)) & ~1;
+ record_full_arch_list_add_reg (regcache, tmp);
+ record_full_arch_list_add_reg (regcache, tmp | 1);
+ break;
+
+ case 49: /* Load Floating-Point Single with Update */
+ case 51: /* Load Floating-Point Double with Update */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 48: /* Load Floating-Point Single */
+ case 50: /* Load Floating-Point Double */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_fp0_regnum + PPC_FRT (insn));
+ break;
+
+ case 47: /* Store Multiple Word */
+ {
+ ULONGEST addr = 0;
+ int size;
+
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn),
+ &addr);
+
+ addr += PPC_D (insn);
+
+ for (i = PPC_RS (insn); i < 32; i++)
+ record_full_arch_list_add_mem (addr + i * 4, 4);
+ }
+ break;
+
+ case 37: /* Store Word with Update */
+ case 39: /* Store Byte with Update */
+ case 45: /* Store Halfword with Update */
+ case 53: /* Store Floating-Point Single with Update */
+ case 55: /* Store Floating-Point Double with Update */
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ /* FALL-THROUGH */
+ case 36: /* Store Word */
+ case 38: /* Store Byte */
+ case 44: /* Store Halfword */
+ case 52: /* Store Floating-Point Single */
+ case 54: /* Store Floating-Point Double */
+ {
+ ULONGEST addr = 0;
+ int size = -1;
+
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn),
+ &addr);
+ addr += PPC_D (insn);
+
+ if (op6 == 36 || op6 == 37 || op6 == 52 || op6 == 53)
+ size = 4;
+ else if (op6 == 54 || op6 == 55)
+ size = 8;
+ else if (op6 == 44 || op6 == 45)
+ size = 2;
+ else if (op6 == 38 || op6 == 39)
+ size = 1;
+ else
+ gdb_assert (0);
+
+ record_full_arch_list_add_mem (addr, size);
+ }
+ break;
+
+ case 57: /* 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 58: /* Load Doubleword */
+ /* Load Doubleword with Update */
+ /* Load Doubleword Algebraic */
+ if (PPC_FIELD (insn, 30, 2) > 2)
+ goto UNKNOWN_OP;
+
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RT (insn));
+ if (PPC_BIT (insn, 31))
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn));
+ break;
+
+ case 59:
+ if (ppc64_process_record_op59 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
+ case 60:
+ if (ppc64_process_record_op60 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
+ case 61: /* Store Floating-Point Double Pair */
+ case 62: /* Store Doubleword */
+ /* Store Doubleword with Update */
+ /* Store Quadword with Update */
+ {
+ ULONGEST addr = 0;
+ int size;
+ int sub2 = PPC_FIELD (insn, 30, 2);
+
+ if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+ goto UNKNOWN_OP;
+
+ if (PPC_RA (insn) != 0)
+ regcache_raw_read_unsigned (regcache,
+ tdep->ppc_gp0_regnum + PPC_RA (insn),
+ &addr);
+
+ size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+
+ addr += PPC_DS (insn) << 2;
+ record_full_arch_list_add_mem (addr, size);
+
+ if (op6 == 62 && sub2 == 1)
+ record_full_arch_list_add_reg (regcache,
+ tdep->ppc_gp0_regnum +
+ PPC_RA (insn));
+
+ break;
+ }
+
+ case 63:
+ if (ppc64_process_record_op63 (gdbarch, regcache, addr, insn) != 0)
+ return -1;
+ break;
+
+ default:
+UNKNOWN_OP:
+ fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+ "%08x at %08lx, %d.\n", insn, addr, op6);
+ return -1;
+ }
+
+ if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+ return -1;
+ if (record_full_arch_list_add_end ())
+ return -1;
+ return 0;
+}
+
/* Initialize the current architecture based on INFO. If possible, re-use an
architecture from ARCHES, which is a list of architectures already created
during this debugging session.
@@ -4154,6 +5660,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
case GDB_OSABI_NETBSD_ELF:
case GDB_OSABI_UNKNOWN:
set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
+ frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
@@ -4162,6 +5669,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
+ frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
@@ -1881,7 +1881,8 @@ proc supports_process_record {} {
}
if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
- || [istarget "i\[34567\]86-*-linux*"] } {
+ || [istarget "i\[34567\]86-*-linux*"]
+ || [istarget "powerpc*-linux*"] } {
return 1
}
@@ -1897,7 +1898,8 @@ proc supports_reverse {} {
}
if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
- || [istarget "i\[34567\]86-*-linux*"] } {
+ || [istarget "i\[34567\]86-*-linux*"]
+ || [istarget "powerpc*-linux*"] } {
return 1
}